Update ooo320-m1
[ooovba.git] / dbaccess / source / ui / browser / brwctrlr.cxx
blob147d55a8de8ec202b6e479be0124d22808fe0fc6
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: brwctrlr.cxx,v $
10 * $Revision: 1.105.6.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dbaccess.hxx"
35 #ifndef _SBA_BWRCTRLR_HXX
36 #include "brwctrlr.hxx"
37 #endif
38 #ifndef _SBX_BRWVIEW_HXX
39 #include "brwview.hxx"
40 #endif
41 #ifndef _OSL_MUTEX_HXX_ //autogen wg. MutexGuard
42 #include <osl/mutex.hxx>
43 #endif
44 #ifndef _SFXAPP_HXX //autogen wg. SFX_APP
45 #include <sfx2/app.hxx>
46 #endif
47 #ifndef _COM_SUN_STAR_UNO_TYPECLASS_HPP_
48 #include <com/sun/star/uno/TypeClass.hpp>
49 #endif
50 #ifndef _DBAUI_SQLMESSAGE_HXX_
51 #include "sqlmessage.hxx"
52 #endif
53 #ifndef _COM_SUN_STAR_FORM_XFORMCONTROLLER_HPP_
54 #include <com/sun/star/form/XFormController.hpp>
55 #endif
56 #ifndef _COM_SUN_STAR_SDB_COMMANDTYPE_HPP_
57 #include <com/sun/star/sdb/CommandType.hpp>
58 #endif
59 #ifndef _COM_SUN_STAR_SDBC_XROWSETLISTENER_HPP_
60 #include <com/sun/star/sdbc/XRowSetListener.hpp>
61 #endif
62 #ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
63 #include <com/sun/star/sdbc/XConnection.hpp>
64 #endif
65 #ifndef _COM_SUN_STAR_SDBCX_XROWLOCATE_HPP_
66 #include <com/sun/star/sdbcx/XRowLocate.hpp>
67 #endif
68 #ifndef _COM_SUN_STAR_SDBC_XRESULTSETUPDATE_HPP_
69 #include <com/sun/star/sdbc/XResultSetUpdate.hpp>
70 #endif
71 #ifndef _COM_SUN_STAR_SDB_XSQLERRORBROADCASTER_HPP_
72 #include <com/sun/star/sdb/XSQLErrorBroadcaster.hpp>
73 #endif
74 #ifndef _COM_SUN_STAR_SDB_XSINGLESELECTQUERYCOMPOSER_HPP_
75 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
76 #endif
77 #ifndef _COM_SUN_STAR_FORM_XLOADABLE_HPP_
78 #include <com/sun/star/form/XLoadable.hpp>
79 #endif
80 #ifndef _COM_SUN_STAR_SDB_SQLCONTEXT_HPP_
81 #include <com/sun/star/sdb/SQLContext.hpp>
82 #endif
83 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
84 #include <com/sun/star/beans/PropertyAttribute.hpp>
85 #endif
86 #ifndef _COM_SUN_STAR_FORM_FORMBUTTONTYPE_HPP_
87 #include <com/sun/star/form/FormButtonType.hpp>
88 #endif
89 #ifndef _COM_SUN_STAR_FORM_XCHANGELISTENER_HPP_
90 #include <com/sun/star/form/XChangeListener.hpp>
91 #endif
92 #ifndef _COM_SUN_STAR_FORM_FORMSUBMITENCODING_HPP_
93 #include <com/sun/star/form/FormSubmitEncoding.hpp>
94 #endif
95 #ifndef _COM_SUN_STAR_FORM_FORMSUBMITMETHOD_HPP_
96 #include <com/sun/star/form/FormSubmitMethod.hpp>
97 #endif
98 #ifndef _COM_SUN_STAR_FORM_XSUBMITLISTENER_HPP_
99 #include <com/sun/star/form/XSubmitListener.hpp>
100 #endif
101 #ifndef _COM_SUN_STAR_FORM_XRESET_HPP_
102 #include <com/sun/star/form/XReset.hpp>
103 #endif
104 #ifndef _COM_SUN_STAR_FORM_XSUBMIT_HPP_
105 #include <com/sun/star/form/XSubmit.hpp>
106 #endif
107 #ifndef _COM_SUN_STAR_FORM_XAPPROVEACTIONBROADCASTER_HPP_
108 #include <com/sun/star/form/XApproveActionBroadcaster.hpp>
109 #endif
110 #ifndef _COM_SUN_STAR_FORM_XCHANGEBROADCASTER_HPP_
111 #include <com/sun/star/form/XChangeBroadcaster.hpp>
112 #endif
113 #ifndef _COM_SUN_STAR_FORM_XRESETLISTENER_HPP_
114 #include <com/sun/star/form/XResetListener.hpp>
115 #endif
116 #ifndef _COM_SUN_STAR_UTIL_XCANCELLABLE_HPP_
117 #include <com/sun/star/util/XCancellable.hpp>
118 #endif
119 #ifndef _COM_SUN_STAR_FORM_XDATABASEPARAMETERBROADCASTER_HPP_
120 #include <com/sun/star/form/XDatabaseParameterBroadcaster.hpp>
121 #endif
122 #ifndef _COM_SUN_STAR_FORM_XBOUNDCONTROL_HPP_
123 #include <com/sun/star/form/XBoundControl.hpp>
124 #endif
125 #ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
126 #include <com/sun/star/container/XNameContainer.hpp>
127 #endif
128 #ifndef _COM_SUN_STAR_CONTAINER_XNAMED_HPP_
129 #include <com/sun/star/container/XNamed.hpp>
130 #endif
131 #ifndef _COM_SUN_STAR_SDBCX_PRIVILEGE_HPP_
132 #include <com/sun/star/sdbcx/Privilege.hpp>
133 #endif
134 #ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
135 #include <cppuhelper/typeprovider.hxx>
136 #endif
137 #ifndef _CPPUHELPER_EXC_HLP_HXX_
138 #include <cppuhelper/exc_hlp.hxx>
139 #endif
140 #ifndef _SV_MSGBOX_HXX //autogen
141 #include <vcl/msgbox.hxx>
142 #endif
143 #ifndef _FMSEARCH_HXX
144 #include <svx/fmsearch.hxx>
145 #endif
146 #ifndef _SV_WAITOBJ_HXX
147 #include <vcl/waitobj.hxx>
148 #endif
149 #ifndef _TOOLS_COLOR_HXX
150 #include <tools/color.hxx>
151 #endif
152 #ifndef TOOLS_DIAGNOSE_EX_H
153 #include <tools/diagnose_ex.h>
154 #endif
155 #ifndef _COMPHELPER_SEQUENCE_HXX_
156 #include <comphelper/sequence.hxx>
157 #endif
158 #ifndef _CONNECTIVITY_DBTOOLS_HXX_
159 #include <connectivity/dbtools.hxx>
160 #endif
161 #ifndef _DBHELPER_DBEXCEPTION_HXX_
162 #include <connectivity/dbexception.hxx>
163 #endif
164 #ifndef _CPPUHELPER_IMPLBASE2_HXX_
165 #include <cppuhelper/implbase2.hxx>
166 #endif
167 #ifndef _DBU_BRW_HRC_
168 #include "dbu_brw.hrc"
169 #endif
170 #ifndef _SFX_HRC
171 #include <sfx2/sfx.hrc>
172 #endif
173 #ifndef DBACCESS_UI_BROWSER_ID_HXX
174 #include "browserids.hxx"
175 #endif
176 #ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
177 #include "dbustrings.hrc"
178 #endif
179 #ifndef _COMPHELPER_INTERACTION_HXX_
180 #include <comphelper/interaction.hxx>
181 #endif
182 #ifndef _DBHELPER_DBEXCEPTION_HXX_
183 #include <connectivity/dbexception.hxx>
184 #endif
185 #ifndef CONNECTIVITY_SQLERROR_HXX
186 #include <connectivity/sqlerror.hxx>
187 #endif
188 #ifndef _COMPHELPER_EXTRACT_HXX_
189 #include <comphelper/extract.hxx>
190 #endif
191 #ifndef _COM_SUN_STAR_SDB_XINTERACTIONSUPPLYPARAMETERS_HPP_
192 #include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
193 #endif
194 #ifndef _COM_SUN_STAR_SDB_PARAMETERSREQUEST_HPP_
195 #include <com/sun/star/sdb/ParametersRequest.hpp>
196 #endif
197 #ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_
198 #include <com/sun/star/task/XInteractionHandler.hpp>
199 #endif
200 #ifndef INCLUDED_COM_SUN_STAR_SDBC_XWARNINGSSUPPLIER_HPP
201 #include <com/sun/star/sdbc/XWarningsSupplier.hpp>
202 #endif
203 #ifndef INCLUDED_COM_SUN_STAR_SDB_ERRORCONDITION_HPP
204 #include <com/sun/star/sdb/ErrorCondition.hpp>
205 #endif
206 #ifndef DBAUI_QUERYFILTER_HXX
207 #include "queryfilter.hxx"
208 #endif
209 #ifndef DBAUI_QUERYORDER_HXX
210 #include "queryorder.hxx"
211 #endif
212 #include <rtl/logfile.hxx>
214 #include <svx/svxdlg.hxx> //CHINA001
215 //#include <svx/fmresids.hrc> //CHINA001
217 using namespace ::com::sun::star::uno;
218 using namespace ::com::sun::star::awt;
219 using namespace ::com::sun::star::sdb;
220 using namespace ::com::sun::star::sdbc;
221 using namespace ::com::sun::star::sdbcx;
222 using namespace ::com::sun::star::task;
223 using namespace ::com::sun::star::beans;
224 using namespace ::com::sun::star::frame;
225 using namespace ::com::sun::star::form;
226 using namespace ::com::sun::star::util;
227 using namespace ::com::sun::star::lang;
228 using namespace ::com::sun::star::container;
229 using namespace ::dbtools;
230 using namespace ::comphelper;
231 using namespace ::svt;
233 #define HANDLE_SQL_ERRORS( action, successflag, context, message ) \
234 try \
236 successflag = sal_False; \
237 action; \
238 successflag = sal_True; \
240 catch(SQLException& e) \
242 SQLException aError = ::dbtools::prependErrorInfo(e, *this, context); \
243 ::com::sun::star::sdb::SQLErrorEvent aEvent; \
244 aEvent.Reason <<= aError; \
245 errorOccured(aEvent); \
247 catch(Exception&) \
249 DBG_UNHANDLED_EXCEPTION(); \
252 #define DO_SAFE( action, message ) try { action; } catch(Exception&) { DBG_ERROR(message); } ;
254 //..................................................................
255 namespace dbaui
257 //..................................................................
259 //==================================================================
260 // OParameterContinuation
261 //==================================================================
262 class OParameterContinuation : public OInteraction< XInteractionSupplyParameters >
264 Sequence< PropertyValue > m_aValues;
266 public:
267 OParameterContinuation() { }
269 Sequence< PropertyValue > getValues() const { return m_aValues; }
271 // XInteractionSupplyParameters
272 virtual void SAL_CALL setParameters( const Sequence< PropertyValue >& _rValues ) throw(RuntimeException);
275 //------------------------------------------------------------------
276 void SAL_CALL OParameterContinuation::setParameters( const Sequence< PropertyValue >& _rValues ) throw(RuntimeException)
278 m_aValues = _rValues;
282 //==============================================================================
283 // a helper class implementing a ::com::sun::star::form::XFormController, will be aggregated by SbaXDataBrowserController
284 // (we can't derive from ::com::sun::star::form::XFormController as it's base class is ::com::sun::star::awt::XTabController and the ::com::sun::star::awt::XTabController::getModel collides
285 // with the ::com::sun::star::frame::XController::getModel implemented in our base class SbaXDataBrowserController)
286 class SbaXDataBrowserController::FormControllerImpl
287 : public ::cppu::WeakAggImplHelper2< ::com::sun::star::form::XFormController,
288 ::com::sun::star::frame::XFrameActionListener>
290 friend class SbaXDataBrowserController;
291 ::cppu::OInterfaceContainerHelper m_aActivateListeners;
292 SbaXDataBrowserController* m_pOwner;
294 public:
295 FormControllerImpl(SbaXDataBrowserController* pOwner);
297 // ::com::sun::star::form::XFormController
298 virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > SAL_CALL getCurrentControl(void) throw( ::com::sun::star::uno::RuntimeException );
299 virtual void SAL_CALL addActivateListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormControllerListener > & l) throw( ::com::sun::star::uno::RuntimeException );
300 virtual void SAL_CALL removeActivateListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormControllerListener > & l) throw( ::com::sun::star::uno::RuntimeException );
302 // ::com::sun::star::awt::XTabController
303 virtual void SAL_CALL setModel(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabControllerModel > & Model) throw( ::com::sun::star::uno::RuntimeException );
304 virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabControllerModel > SAL_CALL getModel(void) throw( ::com::sun::star::uno::RuntimeException );
305 virtual void SAL_CALL setContainer(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > & _Container) throw( ::com::sun::star::uno::RuntimeException );
306 virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > SAL_CALL getContainer(void) throw( ::com::sun::star::uno::RuntimeException );
307 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 );
308 virtual void SAL_CALL autoTabOrder(void) throw( ::com::sun::star::uno::RuntimeException );
309 virtual void SAL_CALL activateTabOrder(void) throw( ::com::sun::star::uno::RuntimeException );
310 virtual void SAL_CALL activateFirst(void) throw( ::com::sun::star::uno::RuntimeException );
311 virtual void SAL_CALL activateLast(void) throw( ::com::sun::star::uno::RuntimeException );
313 // ::com::sun::star::frame::XFrameActionListener
314 virtual void SAL_CALL frameAction(const ::com::sun::star::frame::FrameActionEvent& aEvent) throw( ::com::sun::star::uno::RuntimeException );
316 // ::com::sun::star::lang::XEventListener
317 virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw( ::com::sun::star::uno::RuntimeException );
319 protected:
320 ~FormControllerImpl();
324 DBG_NAME(FormControllerImpl)
325 //------------------------------------------------------------------
326 SbaXDataBrowserController::FormControllerImpl::FormControllerImpl(SbaXDataBrowserController* _pOwner)
327 :m_aActivateListeners(_pOwner->getMutex())
328 ,m_pOwner(_pOwner)
330 DBG_CTOR(FormControllerImpl,NULL);
332 OSL_ENSURE(m_pOwner, "SbaXDataBrowserController::FormControllerImpl::FormControllerImpl : invalid Owner !");
335 //------------------------------------------------------------------
336 SbaXDataBrowserController::FormControllerImpl::~FormControllerImpl()
339 DBG_DTOR(FormControllerImpl,NULL);
342 //------------------------------------------------------------------
343 Reference< ::com::sun::star::awt::XControl > SbaXDataBrowserController::FormControllerImpl::getCurrentControl(void) throw( RuntimeException )
345 return m_pOwner->getBrowserView() ? m_pOwner->getBrowserView()->getGridControl() : Reference< ::com::sun::star::awt::XControl > ();
348 //------------------------------------------------------------------
349 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addActivateListener(const Reference< ::com::sun::star::form::XFormControllerListener > & l) throw( RuntimeException )
351 m_aActivateListeners.addInterface(l);
354 //------------------------------------------------------------------
355 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeActivateListener(const Reference< ::com::sun::star::form::XFormControllerListener > & l) throw( RuntimeException )
357 m_aActivateListeners.removeInterface(l);
360 //------------------------------------------------------------------
361 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setModel(const Reference< ::com::sun::star::awt::XTabControllerModel > & /*Model*/) throw( RuntimeException )
363 OSL_ENSURE(sal_False, "SbaXDataBrowserController::FormControllerImpl::setModel : invalid call, can't change my model !");
366 //------------------------------------------------------------------
367 Reference< ::com::sun::star::awt::XTabControllerModel > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getModel(void) throw( RuntimeException )
369 return Reference< XTabControllerModel >(m_pOwner->getRowSet(), UNO_QUERY);
372 //------------------------------------------------------------------
373 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setContainer(const Reference< ::com::sun::star::awt::XControlContainer > & /*_Container*/) throw( RuntimeException )
375 OSL_ENSURE(sal_False, "SbaXDataBrowserController::FormControllerImpl::setContainer : invalid call, can't change my container !");
378 //------------------------------------------------------------------
379 Reference< ::com::sun::star::awt::XControlContainer > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getContainer(void) throw( RuntimeException )
381 if (m_pOwner->getBrowserView())
382 return m_pOwner->getBrowserView()->getContainer();
383 return Reference< ::com::sun::star::awt::XControlContainer > ();
386 //------------------------------------------------------------------
387 Sequence< Reference< ::com::sun::star::awt::XControl > > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getControls(void) throw( RuntimeException )
389 if (m_pOwner->getBrowserView())
391 Reference< ::com::sun::star::awt::XControl > xGrid = m_pOwner->getBrowserView()->getGridControl();
392 return Sequence< Reference< ::com::sun::star::awt::XControl > >(&xGrid, 1);
394 return Sequence< Reference< ::com::sun::star::awt::XControl > >();
397 //------------------------------------------------------------------
398 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::autoTabOrder(void) throw( RuntimeException )
400 OSL_ENSURE(sal_False, "SbaXDataBrowserController::FormControllerImpl::autoTabOrder : nothing to do (always have only one control) !");
403 //------------------------------------------------------------------
404 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::activateTabOrder(void) throw( RuntimeException )
406 OSL_ENSURE(sal_False, "SbaXDataBrowserController::FormControllerImpl::activateTabOrder : nothing to do (always have only one control) !");
409 //------------------------------------------------------------------
410 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::activateFirst(void) throw( RuntimeException )
412 if (m_pOwner->getBrowserView())
413 m_pOwner->getBrowserView()->getVclControl()->ActivateCell();
416 //------------------------------------------------------------------
417 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::activateLast(void) throw( RuntimeException )
419 if (m_pOwner->getBrowserView())
420 m_pOwner->getBrowserView()->getVclControl()->ActivateCell();
423 //------------------------------------------------------------------
424 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::frameAction(const ::com::sun::star::frame::FrameActionEvent& /*aEvent*/) throw( RuntimeException )
428 //------------------------------------------------------------------
429 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::disposing(const ::com::sun::star::lang::EventObject& /*Source*/) throw( RuntimeException )
431 // nothing to do
432 // we don't add ourself as listener to any broadcasters, so we are not resposible for removing us
435 //==================================================================
436 //= SbaXDataBrowserController
437 //==================================================================
438 //------------------------------------------------------------------
439 Sequence< Type > SAL_CALL SbaXDataBrowserController::getTypes( ) throw (RuntimeException)
441 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::getTypes" );
442 return ::comphelper::concatSequences(
443 SbaXDataBrowserController_Base::getTypes(),
444 m_pFormControllerImpl->getTypes()
448 //------------------------------------------------------------------
449 Sequence< sal_Int8 > SAL_CALL SbaXDataBrowserController::getImplementationId( ) throw (RuntimeException)
451 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::getImplementationId" );
452 static ::cppu::OImplementationId * pId = 0;
453 if (! pId)
455 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
456 if (! pId)
458 static ::cppu::OImplementationId aId;
459 pId = &aId;
462 return pId->getImplementationId();
465 //------------------------------------------------------------------
466 Any SAL_CALL SbaXDataBrowserController::queryInterface(const Type& _rType) throw (RuntimeException)
468 //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::queryInterface" );
469 // check for our additional interfaces
470 Any aRet = SbaXDataBrowserController_Base::queryInterface(_rType);
472 // check for the base controllers interfaces
473 if (!aRet.hasValue())
475 // check for our aggregate (implementing the XFormController)
476 if (!aRet.hasValue())
478 aRet = m_xFormControllerImpl->queryAggregation(_rType);
482 // no more to offer
483 return aRet;
486 DBG_NAME(SbaXDataBrowserController)
487 //------------------------------------------------------------------------------
488 SbaXDataBrowserController::SbaXDataBrowserController(const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM)
489 :SbaXDataBrowserController_Base(_rM)
490 ,m_pClipbordNotifier( NULL )
491 ,m_aAsyncGetCellFocus(LINK(this, SbaXDataBrowserController, OnAsyncGetCellFocus))
492 ,m_aAsyncDisplayError( LINK( this, SbaXDataBrowserController, OnAsyncDisplayError ) )
493 ,m_sStateSaveRecord(ModuleRes(RID_STR_SAVE_CURRENT_RECORD))
494 ,m_sStateUndoRecord(ModuleRes(RID_STR_UNDO_MODIFY_RECORD))
495 ,m_sModuleIdentifier( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.DataSourceBrowser" ) ) )
496 ,m_pLoadThread(NULL)
497 ,m_pFormControllerImpl(NULL)
498 ,m_nPendingLoadFinished(0)
499 ,m_nFormActionNestingLevel(0)
500 ,m_bLoadCanceled( sal_False )
501 ,m_bClosingKillOpen( sal_False )
502 ,m_bCannotSelectUnfiltered( true )
504 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::SbaXDataBrowserController" );
505 DBG_CTOR(SbaXDataBrowserController,NULL);
507 // create the form controller aggregate
508 ::comphelper::increment(m_refCount);
510 m_pFormControllerImpl = new FormControllerImpl(this);
511 m_xFormControllerImpl = m_pFormControllerImpl;
512 m_xFormControllerImpl->setDelegator(*this);
514 ::comphelper::decrement(m_refCount);
516 m_aInvalidateClipboard.SetTimeoutHdl(LINK(this, SbaXDataBrowserController, OnInvalidateClipboard));
517 m_aInvalidateClipboard.SetTimeout(300);
520 //------------------------------------------------------------------------------
521 SbaXDataBrowserController::~SbaXDataBrowserController()
523 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::~SbaXDataBrowserController" );
524 // deleteView();
525 // release the aggregated form controller
526 if (m_xFormControllerImpl.is())
528 Reference< XInterface > xEmpty;
529 m_xFormControllerImpl->setDelegator(xEmpty);
532 DBG_DTOR(SbaXDataBrowserController,NULL);
535 // -----------------------------------------------------------------------
536 void SbaXDataBrowserController::startFrameListening( const Reference< XFrame >& _rxFrame )
538 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::startFrameListening" );
539 SbaXDataBrowserController_Base::startFrameListening( _rxFrame );
541 Reference< XFrameActionListener > xAggListener;
542 if ( m_xFormControllerImpl.is() )
543 m_xFormControllerImpl->queryAggregation( XFrameActionListener::static_type() ) >>= xAggListener;
545 if ( _rxFrame.is() && xAggListener.is() )
546 _rxFrame->addFrameActionListener( xAggListener );
549 // -----------------------------------------------------------------------
550 void SbaXDataBrowserController::stopFrameListening( const Reference< XFrame >& _rxFrame )
552 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::stopFrameListening" );
553 SbaXDataBrowserController_Base::stopFrameListening( _rxFrame );
555 Reference< XFrameActionListener > xAggListener;
556 if ( m_xFormControllerImpl.is() )
557 m_xFormControllerImpl->queryAggregation( XFrameActionListener::static_type() ) >>= xAggListener;
559 if ( _rxFrame.is() && xAggListener.is() )
560 _rxFrame->removeFrameActionListener( xAggListener );
563 // -----------------------------------------------------------------------------
564 void SbaXDataBrowserController::onStartLoading( const Reference< XLoadable >& _rxLoadable )
566 m_bLoadCanceled = sal_False;
567 m_bCannotSelectUnfiltered = false;
569 Reference< XWarningsSupplier > xWarnings( _rxLoadable, UNO_QUERY );
570 if ( xWarnings.is() )
571 xWarnings->clearWarnings();
574 // -----------------------------------------------------------------------------
575 void SbaXDataBrowserController::impl_checkForCannotSelectUnfiltered( const SQLExceptionInfo& _rError )
577 ::connectivity::SQLError aError( getORB() );
578 ::connectivity::ErrorCode nErrorCode( aError.getErrorCode( ErrorCondition::DATA_CANNOT_SELECT_UNFILTERED ) );
579 if ( ((const SQLException*)_rError)->ErrorCode == nErrorCode )
581 m_bCannotSelectUnfiltered = true;
582 InvalidateFeature( ID_BROWSER_FILTERCRIT );
586 // -----------------------------------------------------------------------------
587 sal_Bool SbaXDataBrowserController::reloadForm( const Reference< XLoadable >& _rxLoadable )
589 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::reloadForm" );
590 WaitObject aWO(getBrowserView());
592 onStartLoading( _rxLoadable );
594 FormErrorHelper aReportError(this);
595 if (_rxLoadable->isLoaded())
596 _rxLoadable->reload();
597 else
598 _rxLoadable->load();
600 Reference< XWarningsSupplier > xWarnings( _rxLoadable, UNO_QUERY );
601 if ( xWarnings.is() )
603 SQLExceptionInfo aInfo( xWarnings->getWarnings() );
604 if ( aInfo.isValid() )
606 showError( aInfo );
607 impl_checkForCannotSelectUnfiltered( aInfo );
611 return _rxLoadable->isLoaded();
614 // -----------------------------------------------------------------------------
615 void SbaXDataBrowserController::initFormatter()
617 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::initFormatter" );
618 // ---------------------------------------------------------------
619 // create a formatter working with the connections format supplier
620 Reference< ::com::sun::star::util::XNumberFormatsSupplier > xSupplier(::dbtools::getNumberFormats(::dbtools::getConnection(m_xRowSet), sal_True,getORB()));
622 if(xSupplier.is())
624 // create a new formatter
625 m_xFormatter = Reference< ::com::sun::star::util::XNumberFormatter > (
626 getORB()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatter")), UNO_QUERY);
627 if (m_xFormatter.is())
628 m_xFormatter->attachNumberFormatsSupplier(xSupplier);
630 else // clear the formatter
631 m_xFormatter = NULL;
633 // -----------------------------------------------------------------------------
634 void SbaXDataBrowserController::describeSupportedFeatures()
636 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::describeSupportedFeatures" );
637 SbaXDataBrowserController_Base::describeSupportedFeatures();
638 implDescribeSupportedFeature( ".uno:FormSlots/undoRecord", ID_BROWSER_UNDORECORD, CommandGroup::CONTROLS );
639 implDescribeSupportedFeature( ".uno:FormController/undoRecord", ID_BROWSER_UNDORECORD, CommandGroup::CONTROLS );
640 implDescribeSupportedFeature( ".uno:RecUndo", ID_BROWSER_UNDORECORD, CommandGroup::CONTROLS );
641 implDescribeSupportedFeature( ".uno:FormSlots/saveRecord", ID_BROWSER_SAVERECORD, CommandGroup::CONTROLS );
642 implDescribeSupportedFeature( ".uno:FormController/saveRecord", ID_BROWSER_SAVERECORD, CommandGroup::CONTROLS );
643 implDescribeSupportedFeature( ".uno:RecSave", ID_BROWSER_SAVERECORD, CommandGroup::CONTROLS );
644 implDescribeSupportedFeature( ".uno:Save", ID_BROWSER_SAVERECORD, CommandGroup::DOCUMENT );
645 implDescribeSupportedFeature( ".uno:RecSearch", SID_FM_SEARCH, CommandGroup::CONTROLS );
646 implDescribeSupportedFeature( ".uno:AutoFilter", SID_FM_AUTOFILTER, CommandGroup::CONTROLS );
647 implDescribeSupportedFeature( ".uno:Refresh", SID_FM_REFRESH, CommandGroup::CONTROLS );
648 implDescribeSupportedFeature( ".uno:OrderCrit", SID_FM_ORDERCRIT, CommandGroup::CONTROLS );
649 implDescribeSupportedFeature( ".uno:RemoveFilterSort", SID_FM_REMOVE_FILTER_SORT,CommandGroup::CONTROLS );
650 implDescribeSupportedFeature( ".uno:FormFiltered", SID_FM_FORM_FILTERED, CommandGroup::CONTROLS );
651 implDescribeSupportedFeature( ".uno:FilterCrit", SID_FM_FILTERCRIT, CommandGroup::CONTROLS );
652 implDescribeSupportedFeature( ".uno:Sortup", ID_BROWSER_SORTUP, CommandGroup::CONTROLS );
653 implDescribeSupportedFeature( ".uno:SortDown", ID_BROWSER_SORTDOWN, CommandGroup::CONTROLS );
654 implDescribeSupportedFeature( ".uno:FormSlots/deleteRecord", SID_FM_DELETEROWS, CommandGroup::EDIT );
655 implDescribeSupportedFeature( ".uno:FormSlots/insertRecord", ID_BROWSER_INSERT_ROW, CommandGroup::INSERT );
657 //------------------------------------------------------------------------------
658 sal_Bool SbaXDataBrowserController::Construct(Window* pParent)
660 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::Construct" );
661 // ---------------------------------------------
662 // create/initialize the form and the grid model
663 m_xRowSet = CreateForm();
664 if (!m_xRowSet.is())
665 return sal_False;
667 m_xColumnsSupplier.set(m_xRowSet,UNO_QUERY);
668 m_xLoadable.set(m_xRowSet,UNO_QUERY);
670 if (!InitializeForm(m_xRowSet))
671 return sal_False;
673 m_xGridModel = CreateGridModel();
674 if (!m_xGridModel.is())
675 return sal_False;
677 // set the formatter if available
678 initFormatter();
679 // ---------------------------------------------------------------
681 // we want to have a grid with a "flat" border
682 Reference< XPropertySet > xGridSet(m_xGridModel, UNO_QUERY);
683 if ( xGridSet.is() )
684 xGridSet->setPropertyValue(PROPERTY_BORDER, makeAny((sal_Int16)2));
686 // ----------
687 // marry them
688 Reference< ::com::sun::star::container::XNameContainer > xNameCont(m_xRowSet, UNO_QUERY);
690 String sText(ModuleRes(STR_DATASOURCE_GRIDCONTROL_NAME));
691 xNameCont->insertByName(::rtl::OUString(sText), makeAny(m_xGridModel));
694 // ---------------
695 // create the view
696 m_pView = new UnoDataBrowserView( pParent, *this, getORB() );
697 if (!getBrowserView())
698 return sal_False;
700 // late construction
701 sal_Bool bSuccess = sal_False;
704 getBrowserView()->Construct(getControlModel());
705 bSuccess = sal_True;
707 catch(SQLException&)
710 catch(Exception&)
712 DBG_ERROR("SbaXDataBrowserController::Construct : the construction of UnoDataBrowserView failed !");
715 if (!bSuccess)
717 // deleteView();
718 return sal_False;
721 // now that we have a view we can create the clipboard listener
722 m_aSystemClipboard = TransferableDataHelper::CreateFromSystemClipboard( getView() );
723 m_aSystemClipboard.StartClipboardListening( );
725 m_pClipbordNotifier = new TransferableClipboardListener( LINK( this, SbaXDataBrowserController, OnClipboardChanged ) );
726 m_pClipbordNotifier->acquire();
727 m_pClipbordNotifier->AddRemoveListener( getView(), sal_True );
729 // this call create the toolbox
730 SbaXDataBrowserController_Base::Construct(pParent);
732 getBrowserView()->Show();
734 // set the callbacks for the grid control
735 SbaGridControl* pVclGrid = getBrowserView()->getVclControl();
736 DBG_ASSERT(pVclGrid, "SbaXDataBrowserController::Construct : have no VCL control !");
737 pVclGrid->SetMasterListener(this);
739 // --------------------------
740 // add listeners ...
742 // ... to the form model
743 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
744 if (xFormSet.is())
746 xFormSet->addPropertyChangeListener(PROPERTY_ISNEW, static_cast<XPropertyChangeListener*>(this));
747 xFormSet->addPropertyChangeListener(PROPERTY_ISMODIFIED, static_cast<XPropertyChangeListener*>(this));
748 xFormSet->addPropertyChangeListener(PROPERTY_ROWCOUNT, static_cast<XPropertyChangeListener*>(this));
749 xFormSet->addPropertyChangeListener(PROPERTY_ACTIVECOMMAND, static_cast<XPropertyChangeListener*>(this));
750 xFormSet->addPropertyChangeListener(PROPERTY_ORDER, static_cast<XPropertyChangeListener*>(this));
751 xFormSet->addPropertyChangeListener(PROPERTY_FILTER, static_cast<XPropertyChangeListener*>(this));
752 xFormSet->addPropertyChangeListener(PROPERTY_HAVING_CLAUSE, static_cast<XPropertyChangeListener*>(this));
753 xFormSet->addPropertyChangeListener(PROPERTY_APPLYFILTER, static_cast<XPropertyChangeListener*>(this));
755 Reference< ::com::sun::star::sdb::XSQLErrorBroadcaster > xFormError(getRowSet(), UNO_QUERY);
756 if (xFormError.is())
757 xFormError->addSQLErrorListener((::com::sun::star::sdb::XSQLErrorListener*)this);
759 if (m_xLoadable.is())
760 m_xLoadable->addLoadListener(this);
762 Reference< ::com::sun::star::form::XDatabaseParameterBroadcaster > xFormParameter(getRowSet(), UNO_QUERY);
763 if (xFormParameter.is())
764 xFormParameter->addParameterListener((::com::sun::star::form::XDatabaseParameterListener*)this);
766 addModelListeners(getControlModel());
767 addControlListeners(getBrowserView()->getGridControl());
769 // -------------
770 // load the form
771 return LoadForm();
774 //------------------------------------------------------------------------------
775 sal_Bool SbaXDataBrowserController::LoadForm()
777 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::LoadForm" );
778 reloadForm( m_xLoadable );
779 return sal_True;
781 //------------------------------------------------------------------------------
782 void SbaXDataBrowserController::AddColumnListener(const Reference< XPropertySet > & /*xCol*/)
784 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::AddColumnListener" );
785 // we're not interested in any column properties ...
788 //------------------------------------------------------------------------------
789 void SbaXDataBrowserController::RemoveColumnListener(const Reference< XPropertySet > & /*xCol*/)
791 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::RemoveColumnListener" );
793 //------------------------------------------------------------------------------
794 Reference< XRowSet > SbaXDataBrowserController::CreateForm()
796 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::CreateForm" );
797 return Reference< XRowSet > (getORB()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.form.component.Form")), UNO_QUERY);
800 //------------------------------------------------------------------------------
801 Reference< ::com::sun::star::form::XFormComponent > SbaXDataBrowserController::CreateGridModel()
803 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::CreateGridModel" );
804 return Reference< ::com::sun::star::form::XFormComponent > (getORB()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.form.component.GridControl")), UNO_QUERY);
807 // -------------------------------------------------------------------------
808 void SbaXDataBrowserController::addModelListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel)
810 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::addModelListeners" );
811 // ... all the grid columns
812 addColumnListeners(_xGridControlModel);
814 // (we are interested in all columns the grid has (and only in these) so we have to listen to the container, too)
815 Reference< ::com::sun::star::container::XContainer > xColContainer(_xGridControlModel, UNO_QUERY);
816 if (xColContainer.is())
817 xColContainer->addContainerListener((::com::sun::star::container::XContainerListener*)this);
819 Reference< ::com::sun::star::form::XReset > xReset(_xGridControlModel, UNO_QUERY);
820 if (xReset.is())
821 xReset->addResetListener((::com::sun::star::form::XResetListener*)this);
824 // -------------------------------------------------------------------------
825 void SbaXDataBrowserController::removeModelListeners(const Reference< XControlModel > & _xGridControlModel)
827 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::removeModelListeners" );
828 // every single column model
829 Reference< XIndexContainer > xColumns(_xGridControlModel, UNO_QUERY);
830 if (xColumns.is())
832 sal_Int32 nCount = xColumns->getCount();
833 for (sal_uInt16 i=0; i < nCount; ++i)
835 Reference< XPropertySet > xCol(xColumns->getByIndex(i),UNO_QUERY);
836 RemoveColumnListener(xCol);
840 Reference< XContainer > xColContainer(_xGridControlModel, UNO_QUERY);
841 if (xColContainer.is())
842 xColContainer->removeContainerListener( this );
844 Reference< XReset > xReset(_xGridControlModel, UNO_QUERY);
845 if (xReset.is())
846 xReset->removeResetListener( this );
849 // -------------------------------------------------------------------------
850 void SbaXDataBrowserController::addControlListeners(const Reference< ::com::sun::star::awt::XControl > & _xGridControl)
852 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::addControlListeners" );
853 // to ge the 'modified' for the current cell
854 Reference< XModifyBroadcaster > xBroadcaster(getBrowserView()->getGridControl(), UNO_QUERY);
855 if (xBroadcaster.is())
856 xBroadcaster->addModifyListener(static_cast<XModifyListener*>(this));
858 // introduce ourself as dispatch provider for the grid
859 Reference< XDispatchProviderInterception > xInterception(getBrowserView()->getGridControl(), UNO_QUERY);
860 if (xInterception.is())
861 xInterception->registerDispatchProviderInterceptor(static_cast<XDispatchProviderInterceptor*>(this));
863 // add as focus listener to the control (needed for the form controller functionality)
864 Reference< XWindow > xWindow(_xGridControl, UNO_QUERY);
865 if (xWindow.is())
866 xWindow->addFocusListener(this);
869 // -------------------------------------------------------------------------
870 void SbaXDataBrowserController::removeControlListeners(const Reference< ::com::sun::star::awt::XControl > & _xGridControl)
872 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::removeControlListeners" );
873 Reference< XModifyBroadcaster > xBroadcaster(_xGridControl, UNO_QUERY);
874 if (xBroadcaster.is())
875 xBroadcaster->removeModifyListener(static_cast<XModifyListener*>(this));
877 Reference< XDispatchProviderInterception > xInterception(_xGridControl, UNO_QUERY);
878 if (xInterception.is())
879 xInterception->releaseDispatchProviderInterceptor(static_cast<XDispatchProviderInterceptor*>(this));
881 Reference< XWindow > xWindow(_xGridControl, UNO_QUERY);
882 if (xWindow.is())
883 xWindow->removeFocusListener(this);
886 //------------------------------------------------------------------
887 void SAL_CALL SbaXDataBrowserController::focusGained(const FocusEvent& /*e*/) throw( RuntimeException )
889 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::focusGained" );
890 // notify our activate listeners (registered on the form controller aggregate)
891 EventObject aEvt(*this);
892 ::cppu::OInterfaceIteratorHelper aIter(m_pFormControllerImpl->m_aActivateListeners);
893 while (aIter.hasMoreElements())
894 static_cast<XFormControllerListener*>(aIter.next())->formActivated(aEvt);
897 //------------------------------------------------------------------
898 void SAL_CALL SbaXDataBrowserController::focusLost(const FocusEvent& e) throw( RuntimeException )
900 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::focusLost" );
901 // some general checks
902 if (!getBrowserView() || !getBrowserView()->getGridControl().is())
903 return;
904 Reference< XVclWindowPeer > xMyGridPeer(getBrowserView()->getGridControl()->getPeer(), UNO_QUERY);
905 if (!xMyGridPeer.is())
906 return;
907 Reference< XWindowPeer > xNextControlPeer(e.NextFocus, UNO_QUERY);
908 if (!xNextControlPeer.is())
909 return;
911 // don't do a notification if it remains in the family (i.e. a child of the grid control gets the focus)
912 if (xMyGridPeer->isChild(xNextControlPeer))
913 return;
915 if (xMyGridPeer == xNextControlPeer)
916 return;
918 // notify the listeners that the "form" we represent has been deactivated
919 EventObject aEvt(*this);
920 ::cppu::OInterfaceIteratorHelper aIter(m_pFormControllerImpl->m_aActivateListeners);
921 while (aIter.hasMoreElements())
922 static_cast<XFormControllerListener*>(aIter.next())->formDeactivated(aEvt);
924 // commit the changes of the grid control (as we're deactivated)
925 Reference< XBoundComponent > xCommitable(getBrowserView()->getGridControl(), UNO_QUERY);
926 if (xCommitable.is())
927 xCommitable->commit();
928 else
929 OSL_ENSURE(sal_False, "SbaXDataBrowserController::focusLost : why is my control not commitable ?");
932 // -------------------------------------------------------------------------
933 void SbaXDataBrowserController::disposingGridControl(const ::com::sun::star::lang::EventObject& /*Source*/)
935 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::disposingGridControl" );
936 removeControlListeners(getBrowserView()->getGridControl());
939 // -------------------------------------------------------------------------
940 void SbaXDataBrowserController::disposingGridModel(const ::com::sun::star::lang::EventObject& /*Source*/)
942 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::disposingGridModel" );
943 removeModelListeners(getControlModel());
946 // -------------------------------------------------------------------------
947 void SbaXDataBrowserController::disposingFormModel(const ::com::sun::star::lang::EventObject& Source)
949 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::disposingFormModel" );
950 Reference< XPropertySet > xSourceSet(Source.Source, UNO_QUERY);
951 if (xSourceSet.is())
953 xSourceSet->removePropertyChangeListener(PROPERTY_ISNEW, static_cast<XPropertyChangeListener*>(this));
954 xSourceSet->removePropertyChangeListener(PROPERTY_ISMODIFIED, static_cast<XPropertyChangeListener*>(this));
955 xSourceSet->removePropertyChangeListener(PROPERTY_ROWCOUNT, static_cast<XPropertyChangeListener*>(this));
956 xSourceSet->removePropertyChangeListener(PROPERTY_ACTIVECOMMAND, static_cast<XPropertyChangeListener*>(this));
957 xSourceSet->removePropertyChangeListener(PROPERTY_ORDER, static_cast<XPropertyChangeListener*>(this));
958 xSourceSet->removePropertyChangeListener(PROPERTY_FILTER, static_cast<XPropertyChangeListener*>(this));
959 xSourceSet->removePropertyChangeListener(PROPERTY_HAVING_CLAUSE, static_cast<XPropertyChangeListener*>(this));
960 xSourceSet->removePropertyChangeListener(PROPERTY_APPLYFILTER, static_cast<XPropertyChangeListener*>(this));
963 Reference< ::com::sun::star::sdb::XSQLErrorBroadcaster > xFormError(Source.Source, UNO_QUERY);
964 if (xFormError.is())
965 xFormError->removeSQLErrorListener((::com::sun::star::sdb::XSQLErrorListener*)this);
967 if (m_xLoadable.is())
968 m_xLoadable->removeLoadListener(this);
970 Reference< ::com::sun::star::form::XDatabaseParameterBroadcaster > xFormParameter(Source.Source, UNO_QUERY);
971 if (xFormParameter.is())
972 xFormParameter->removeParameterListener((::com::sun::star::form::XDatabaseParameterListener*)this);
975 // -------------------------------------------------------------------------
976 void SbaXDataBrowserController::disposingColumnModel(const ::com::sun::star::lang::EventObject& Source)
978 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::disposingColumnModel" );
979 RemoveColumnListener(Reference< XPropertySet > (Source.Source, UNO_QUERY));
982 // -------------------------------------------------------------------------
983 void SbaXDataBrowserController::disposing(const EventObject& Source) throw( RuntimeException )
985 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::disposing" );
986 // if it's a component other than our aggregate, forward it to the aggregate
987 if ( m_xFormControllerImpl != Source.Source )
989 Reference< XEventListener > xAggListener;
990 m_xFormControllerImpl->queryAggregation( ::getCppuType( &xAggListener ) ) >>= xAggListener;
991 if ( xAggListener.is( ))
992 xAggListener->disposing( Source );
995 // is it the grid control ?
996 if (getBrowserView())
998 Reference< ::com::sun::star::awt::XControl > xSourceControl(Source.Source, UNO_QUERY);
999 if (xSourceControl == getBrowserView()->getGridControl())
1000 disposingGridControl(Source);
1003 // it's model (the container of the columns) ?
1004 if (getControlModel() == Source.Source)
1005 disposingGridModel(Source);
1007 // the form's model ?
1008 if ((getRowSet() == Source.Source))
1009 disposingFormModel(Source);
1011 // from a single column model ?
1012 Reference< XPropertySet > xSourceSet(Source.Source, UNO_QUERY);
1013 if (xSourceSet.is())
1015 Reference< XPropertySetInfo > xInfo = xSourceSet->getPropertySetInfo();
1016 // we assume that columns have a Width property and all other sets we are listening to don't have
1017 if (xInfo->hasPropertyByName(PROPERTY_WIDTH))
1018 disposingColumnModel(Source);
1020 SbaXDataBrowserController_Base::OGenericUnoController::disposing( Source );
1023 // -----------------------------------------------------------------------
1024 void SAL_CALL SbaXDataBrowserController::setIdentifier( const ::rtl::OUString& _Identifier ) throw (RuntimeException)
1026 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::setIdentifier" );
1027 ::osl::MutexGuard aGuard( getMutex() );
1028 m_sModuleIdentifier = _Identifier;
1031 // -----------------------------------------------------------------------
1032 ::rtl::OUString SAL_CALL SbaXDataBrowserController::getIdentifier( ) throw (RuntimeException)
1034 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::getIdentifier" );
1035 ::osl::MutexGuard aGuard( getMutex() );
1036 return m_sModuleIdentifier;
1039 // -----------------------------------------------------------------------
1040 void SbaXDataBrowserController::propertyChange(const PropertyChangeEvent& evt) throw ( RuntimeException )
1042 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::propertyChange" );
1043 Reference< XPropertySet > xSource(evt.Source, UNO_QUERY);
1044 if (!xSource.is())
1045 return;
1047 ::vos::OGuard aGuard(Application::GetSolarMutex());
1048 // the IsModified changed to sal_False ?
1049 if ( (evt.PropertyName.equals(PROPERTY_ISMODIFIED))
1050 && (::comphelper::getBOOL(evt.NewValue) == sal_False)
1052 { // -> the current field isn't modified anymore, too
1053 setCurrentModified( sal_False );
1056 // switching to a new record ?
1057 if ( (evt.PropertyName.equals(PROPERTY_ISNEW))
1058 && (::comphelper::getBOOL(evt.NewValue) == sal_True)
1061 if (::comphelper::getINT32(xSource->getPropertyValue(PROPERTY_ROWCOUNT)) == 0)
1062 // if we're switching to a new record and didn't have any records before we need to invalidate
1063 // all slots (as the cursor was invalid before the mode change and so the slots were disabled)
1064 InvalidateAll();
1068 // the filter or the sort criterias have changed ? -> update our parser
1069 if (evt.PropertyName.equals(PROPERTY_ACTIVECOMMAND))
1071 if (m_xParser.is())
1072 DO_SAFE( m_xParser->setElementaryQuery(::comphelper::getString(evt.NewValue)), "SbaXDataBrowserController::propertyChange : could not forward the new query to my parser !" );
1074 else if (evt.PropertyName.equals(PROPERTY_FILTER))
1076 if ( m_xParser.is() && m_xParser->getFilter() != ::comphelper::getString(evt.NewValue))
1078 DO_SAFE( m_xParser->setFilter(::comphelper::getString(evt.NewValue)), "SbaXDataBrowserController::propertyChange : could not forward the new filter to my parser !" );
1080 InvalidateFeature(ID_BROWSER_REMOVEFILTER);
1082 else if (evt.PropertyName.equals(PROPERTY_HAVING_CLAUSE))
1084 if ( m_xParser.is() && m_xParser->getHavingClause() != ::comphelper::getString(evt.NewValue))
1086 DO_SAFE( m_xParser->setHavingClause(::comphelper::getString(evt.NewValue)), "SbaXDataBrowserController::propertyChange : could not forward the new filter to my parser !" );
1088 InvalidateFeature(ID_BROWSER_REMOVEFILTER);
1090 else if (evt.PropertyName.equals(PROPERTY_ORDER))
1092 if ( m_xParser.is() && m_xParser->getOrder() != ::comphelper::getString(evt.NewValue))
1094 DO_SAFE( m_xParser->setOrder(::comphelper::getString(evt.NewValue)), "SbaXDataBrowserController::propertyChange : could not forward the new order to my parser !" );
1096 InvalidateFeature(ID_BROWSER_REMOVEFILTER);
1099 // a new record count ? -> may be our search availability has changed
1100 if (evt.PropertyName.equals(PROPERTY_ROWCOUNT))
1102 sal_Int32 nNewValue = 0, nOldValue = 0;
1103 evt.NewValue >>= nNewValue;
1104 evt.OldValue >>= nOldValue;
1105 if((nOldValue == 0 && nNewValue != 0) || (nOldValue != 0 && nNewValue == 0))
1106 InvalidateAll();
1110 //------------------------------------------------------------------------
1111 void SbaXDataBrowserController::modified(const ::com::sun::star::lang::EventObject& /*aEvent*/) throw( RuntimeException )
1113 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::modified" );
1114 setCurrentModified( sal_True );
1117 // -----------------------------------------------------------------------
1118 void SbaXDataBrowserController::elementInserted(const ::com::sun::star::container::ContainerEvent& evt) throw( RuntimeException )
1120 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::elementInserted" );
1121 DBG_ASSERT(Reference< XInterface >(evt.Source, UNO_QUERY).get() == Reference< XInterface >(getControlModel(), UNO_QUERY).get(),
1122 "SbaXDataBrowserController::elementInserted: where did this come from (not from the grid model)?!");
1123 Reference< XPropertySet > xNewColumn(evt.Element,UNO_QUERY);
1124 if ( xNewColumn.is() )
1125 AddColumnListener(xNewColumn);
1128 // -----------------------------------------------------------------------
1129 void SbaXDataBrowserController::elementRemoved(const ::com::sun::star::container::ContainerEvent& evt) throw( RuntimeException )
1131 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::elementRemoved" );
1132 DBG_ASSERT(Reference< XInterface >(evt.Source, UNO_QUERY).get() == Reference< XInterface >(getControlModel(), UNO_QUERY).get(),
1133 "SbaXDataBrowserController::elementRemoved: where did this come from (not from the grid model)?!");
1134 Reference< XPropertySet > xOldColumn(evt.Element,UNO_QUERY);
1135 if ( xOldColumn.is() )
1136 RemoveColumnListener(xOldColumn);
1139 // -----------------------------------------------------------------------
1140 void SbaXDataBrowserController::elementReplaced(const ::com::sun::star::container::ContainerEvent& evt) throw( RuntimeException )
1142 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::elementReplaced" );
1143 DBG_ASSERT(Reference< XInterface >(evt.Source, UNO_QUERY).get() == Reference< XInterface >(getControlModel(), UNO_QUERY).get(),
1144 "SbaXDataBrowserController::elementReplaced: where did this come from (not from the grid model)?!");
1145 Reference< XPropertySet > xOldColumn(evt.ReplacedElement,UNO_QUERY);
1146 if ( xOldColumn.is() )
1147 RemoveColumnListener(xOldColumn);
1149 Reference< XPropertySet > xNewColumn(evt.Element,UNO_QUERY);
1150 if ( xNewColumn.is() )
1151 AddColumnListener(xNewColumn);
1154 // -----------------------------------------------------------------------
1155 sal_Bool SbaXDataBrowserController::suspend(sal_Bool /*bSuspend*/) throw( RuntimeException )
1157 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::suspend" );
1158 // have a pending open operation ?
1159 if (PendingLoad())
1161 ::vos::OGuard aGuard(Application::GetSolarMutex());
1162 if (m_nPendingLoadFinished != 0)
1163 { // clean up directly. Otherwise there may be a pending asynchronous call
1164 // to OnOpenFinishedMainThread, which won't be executed before we leave
1165 // this method. Sounds like a classic infinite loop.
1166 Application::RemoveUserEvent(m_nPendingLoadFinished);
1167 LINK(this, SbaXDataBrowserController, OnOpenFinishedMainThread).Call(NULL);
1169 else
1170 { // set m_bClosingKillOpen to ensure that the our termination handler reacts according
1171 // it's context
1172 m_bClosingKillOpen = sal_True;
1174 // normally we would now just wait for termination of the load thread, but there is a small problem :
1175 // In the current thread the global solar mutex is locked (that's for sure). If the loading of the
1176 // form tries to acquire (blocking) the solar mutex, too, and we loop waiting for the other thread
1177 // we have a classic deadlock. And bet your ass that ANYBODY in the foreign thread tries to lock
1178 // the solar mutex. Almost all the UNO-capsules around normal C++ classes use the solar mutex for
1179 // "thread safety" (which doesn't deserve that name anymore ;), e.g. the XNumberFormatter-implementation
1180 // does.
1181 // So we have to do a fake : we tell the loading thread that we aren't interested in the results anymore
1182 // and the thread deletes itself (and the data source) as soon as it is done. As it holds the last
1183 // references to the form (and thus, indirectly, to the grid) they will be cleared as soon as the thread dies.
1184 // So all is fine. Except the small flaw that the form is still loading in the background while the
1185 // window that should display it is already dead.
1186 // If we could release the solar mutex in this thread and block it 'til the loader is finished we could
1187 // solve it in a less dirty way, but uinfortunatelly we don't know how often this thread acquired the mutex.
1188 // With high effort we could reach this with releasing the mutex until a third thread - which has to be
1189 // created - can acquire it.Then we block, the third thread releases the mutex (and dies) and the loader
1190 // thread would be able to finish. But that sounds difficult and fault-prone, so I think it's not worth it ...
1191 ((LoadFormThread*)m_pLoadThread)->SetTerminationHdl(Link());
1192 // and of course we tell the thread to stop ....
1193 ((LoadFormThread*)m_pLoadThread)->StopIt();
1197 DBG_ASSERT(m_nPendingLoadFinished == 0, "SbaXDataBrowserController::suspend : there shouldn't be a pending load !");
1199 m_aAsyncGetCellFocus.CancelCall();
1200 m_aAsyncDisplayError.CancelCall();
1201 m_aAsyncInvalidateAll.CancelCall();
1203 sal_Bool bSuccess = SaveModified();
1204 return bSuccess;
1206 // -----------------------------------------------------------------------
1207 void SbaXDataBrowserController::disposing()
1209 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::disposing" );
1210 // and dispose the aggregate
1211 if (m_xFormControllerImpl.is())
1213 Reference< XComponent > xAggComp;
1214 m_xFormControllerImpl->queryAggregation(::getCppuType(&xAggComp)) >>= xAggComp;
1215 if (xAggComp.is())
1216 xAggComp->dispose();
1219 // the base class
1220 SbaXDataBrowserController_Base::OGenericUnoController::disposing();
1222 if (!PendingLoad())
1224 // don't do the removeXxxListener calls if there is a pending load, this may lead to a deadlock :
1225 // as in this thread the SolarMutex is locked (that's for sure) and removeXxxListener locks
1226 // the form's mutex. But in the loading thread both mutexes are acquired in reverse order.
1227 // That's no problem that we don't remove ourself here, as the load thread is responsible for the form
1228 // at the moment. So if the loading is finished, the form will be disposed (by the load thread), and
1229 // we get the "disposing" event where we can do the removeXxxListener calls.
1230 // The alternative for this handling would be that the form has two mutexes : one for handling it's
1231 // listeners and properties and so on, on for it's pure cursor actions
1233 // the data source
1234 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
1235 if (xFormSet.is())
1237 xFormSet->removePropertyChangeListener(PROPERTY_ISNEW, static_cast<XPropertyChangeListener*>(this));
1238 xFormSet->removePropertyChangeListener(PROPERTY_ISMODIFIED, static_cast<XPropertyChangeListener*>(this));
1239 xFormSet->removePropertyChangeListener(PROPERTY_ROWCOUNT, static_cast<XPropertyChangeListener*>(this));
1240 xFormSet->removePropertyChangeListener(PROPERTY_ACTIVECOMMAND, static_cast<XPropertyChangeListener*>(this));
1241 xFormSet->removePropertyChangeListener(PROPERTY_ORDER, static_cast<XPropertyChangeListener*>(this));
1242 xFormSet->removePropertyChangeListener(PROPERTY_FILTER, static_cast<XPropertyChangeListener*>(this));
1243 xFormSet->removePropertyChangeListener(PROPERTY_HAVING_CLAUSE, static_cast<XPropertyChangeListener*>(this));
1244 xFormSet->removePropertyChangeListener(PROPERTY_APPLYFILTER, static_cast<XPropertyChangeListener*>(this));
1247 Reference< ::com::sun::star::sdb::XSQLErrorBroadcaster > xFormError(getRowSet(), UNO_QUERY);
1248 if (xFormError.is())
1249 xFormError->removeSQLErrorListener((::com::sun::star::sdb::XSQLErrorListener*)this);
1251 if (m_xLoadable.is())
1252 m_xLoadable->removeLoadListener(this);
1254 Reference< ::com::sun::star::form::XDatabaseParameterBroadcaster > xFormParameter(getRowSet(), UNO_QUERY);
1255 if (xFormParameter.is())
1256 xFormParameter->removeParameterListener((::com::sun::star::form::XDatabaseParameterListener*)this);
1259 removeModelListeners(getControlModel());
1261 if ( getView() && m_pClipbordNotifier )
1263 m_pClipbordNotifier->ClearCallbackLink();
1264 m_pClipbordNotifier->AddRemoveListener( getView(), sal_False );
1265 m_pClipbordNotifier->release();
1266 m_pClipbordNotifier = NULL;
1269 if (getBrowserView())
1271 removeControlListeners(getBrowserView()->getGridControl());
1272 // don't delete explicitly, this is done by the owner (and user) of this controller (me hopes ...)
1273 m_pView = NULL;
1276 if(m_aInvalidateClipboard.IsActive())
1277 m_aInvalidateClipboard.Stop();
1279 // dispose the data source
1280 // if there is a pending load we decided to give the responsibility for the data source to the open thread
1281 // (see ::suspend)
1282 if (!PendingLoad())
1286 ::comphelper::disposeComponent(m_xRowSet);
1288 m_xRowSet = NULL;
1289 m_xColumnsSupplier = NULL;
1290 m_xLoadable = NULL;
1292 catch(Exception&)
1294 OSL_ENSURE(0,"Exception thrown by dispose");
1299 ::comphelper::disposeComponent(m_xParser);
1301 catch(Exception&)
1303 OSL_ENSURE(0,"Exception thrown by dispose");
1306 //------------------------------------------------------------------------------
1307 void SbaXDataBrowserController::frameAction(const ::com::sun::star::frame::FrameActionEvent& aEvent) throw( RuntimeException )
1309 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::frameAction" );
1310 ::osl::MutexGuard aGuard( getMutex() );
1312 SbaXDataBrowserController_Base::frameAction( aEvent );
1314 if ( aEvent.Source == getFrame() )
1315 switch ( aEvent.Action )
1317 case FrameAction_FRAME_ACTIVATED:
1318 case FrameAction_FRAME_UI_ACTIVATED:
1319 // ensure that the active cell (if any) has the focus
1320 m_aAsyncGetCellFocus.Call();
1321 // start the clipboard timer
1322 if (getBrowserView() && getBrowserView()->getVclControl() && !m_aInvalidateClipboard.IsActive())
1324 m_aInvalidateClipboard.Start();
1325 OnInvalidateClipboard( NULL );
1327 break;
1328 case FrameAction_FRAME_DEACTIVATING:
1329 case FrameAction_FRAME_UI_DEACTIVATING:
1330 // stop the clipboard invalidator
1331 if (getBrowserView() && getBrowserView()->getVclControl() && m_aInvalidateClipboard.IsActive())
1333 m_aInvalidateClipboard.Stop();
1334 OnInvalidateClipboard( NULL );
1336 // remove the "get cell focus"-event
1337 m_aAsyncGetCellFocus.CancelCall();
1338 break;
1339 default:
1340 break;
1344 //------------------------------------------------------------------------------
1345 IMPL_LINK( SbaXDataBrowserController, OnAsyncDisplayError, void*, /* _pNotInterestedIn */ )
1347 if ( m_aCurrentError.isValid() )
1349 OSQLMessageBox aDlg( getBrowserView(), m_aCurrentError );
1350 aDlg.Execute();
1352 return 0L;
1355 //------------------------------------------------------------------------------
1356 void SbaXDataBrowserController::errorOccured(const ::com::sun::star::sdb::SQLErrorEvent& aEvent) throw( RuntimeException )
1358 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::errorOccured" );
1359 ::osl::MutexGuard aGuard( getMutex() );
1361 SQLExceptionInfo aInfo( aEvent.Reason );
1362 if ( !aInfo.isValid() )
1363 return;
1365 if ( m_nFormActionNestingLevel )
1367 OSL_ENSURE( !m_aCurrentError.isValid(), "SbaXDataBrowserController::errorOccured: can handle one error per transaction only!" );
1368 m_aCurrentError = aInfo;
1370 else
1371 m_aAsyncDisplayError.Call();
1374 //------------------------------------------------------------------------------
1375 sal_Bool SbaXDataBrowserController::approveParameter(const ::com::sun::star::form::DatabaseParameterEvent& aEvent) throw( RuntimeException )
1377 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::approveParameter" );
1378 if (aEvent.Source != getRowSet())
1380 // not my data source -> allow anything
1381 DBG_ERROR("SbaXDataBrowserController::approveParameter : invalid event source !");
1382 return sal_True;
1385 Reference< ::com::sun::star::container::XIndexAccess > xParameters = aEvent.Parameters;
1386 ::vos::OGuard aSolarGuard(Application::GetSolarMutex());
1387 // this may be executed in a non-main thread and we want to use vcl ...
1388 Window* pParent = Application::GetDefDialogParent();
1389 // don't use the content as parent if it isn't visible
1390 // (and don't use NULL as parent : this may be displayed in the beamer and really shouldn't be task-local)
1391 // 69297 - FS - 25.10.99
1392 if (getBrowserView() && getBrowserView()->IsVisible())
1393 pParent = getBrowserView();
1395 // default handling: instantiate an interaction handler and let it handle the parameter request
1398 // two continuations allowed: OK and Cancel
1399 OParameterContinuation* pParamValues = new OParameterContinuation;
1400 OInteractionAbort* pAbort = new OInteractionAbort;
1401 // the request
1402 ParametersRequest aRequest;
1403 aRequest.Parameters = xParameters;
1404 aRequest.Connection = getConnection(Reference< XRowSet >(aEvent.Source, UNO_QUERY));
1405 OInteractionRequest* pParamRequest = new OInteractionRequest(makeAny(aRequest));
1406 Reference< XInteractionRequest > xParamRequest(pParamRequest);
1407 // some knittings
1408 pParamRequest->addContinuation(pParamValues);
1409 pParamRequest->addContinuation(pAbort);
1411 // create the handler, let it handle the request
1412 Reference< XInteractionHandler > xHandler(getORB()->createInstance(SERVICE_SDB_INTERACTION_HANDLER), UNO_QUERY);
1413 if (xHandler.is())
1414 xHandler->handle(xParamRequest);
1416 if (!pParamValues->wasSelected())
1417 { // canceled
1418 setLoadingCancelled();
1419 return sal_False;
1422 // transfer the values into the parameter supplier
1423 Sequence< PropertyValue > aFinalValues = pParamValues->getValues();
1424 if (aFinalValues.getLength() != aRequest.Parameters->getCount())
1426 DBG_ERROR("SbaXDataBrowserController::approveParameter: the InteractionHandler returned nonsense!");
1427 setLoadingCancelled();
1428 return sal_False;
1430 const PropertyValue* pFinalValues = aFinalValues.getConstArray();
1431 for (sal_Int32 i=0; i<aFinalValues.getLength(); ++i, ++pFinalValues)
1433 Reference< XPropertySet > xParam;
1434 ::cppu::extractInterface(xParam, aRequest.Parameters->getByIndex(i));
1435 DBG_ASSERT(xParam.is(), "SbaXDataBrowserController::approveParameter: one of the parameters is no property set!");
1436 if (xParam.is())
1438 #ifdef DBG_UTIL
1439 ::rtl::OUString sName;
1440 xParam->getPropertyValue(PROPERTY_NAME) >>= sName;
1441 DBG_ASSERT(sName.equals(pFinalValues->Name), "SbaXDataBrowserController::approveParameter: suspicious value names!");
1442 #endif
1443 try { xParam->setPropertyValue(PROPERTY_VALUE, pFinalValues->Value); }
1444 catch(Exception&)
1446 DBG_ERROR("SbaXDataBrowserController::approveParameter: setting one of the properties failed!");
1451 catch( const Exception& )
1453 DBG_UNHANDLED_EXCEPTION();
1456 return sal_True;
1460 //------------------------------------------------------------------------------
1461 sal_Bool SbaXDataBrowserController::approveReset(const ::com::sun::star::lang::EventObject& /*rEvent*/) throw( RuntimeException )
1463 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::approveReset" );
1464 return sal_True;
1467 //------------------------------------------------------------------------------
1468 void SbaXDataBrowserController::resetted(const ::com::sun::star::lang::EventObject& rEvent) throw( RuntimeException )
1470 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::resetted" );
1471 DBG_ASSERT(rEvent.Source == getControlModel(), "SbaXDataBrowserController::resetted : where did this come from ?");
1472 (void)rEvent;
1473 setCurrentModified( sal_False );
1476 //------------------------------------------------------------------------------
1477 sal_Bool SbaXDataBrowserController::confirmDelete(const ::com::sun::star::sdb::RowChangeEvent& /*aEvent*/) throw( RuntimeException )
1479 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::confirmDelete" );
1480 if (QueryBox(getBrowserView(), ModuleRes(QUERY_BRW_DELETE_ROWS)).Execute() != RET_YES)
1481 return sal_False;
1483 return sal_True;
1485 //------------------------------------------------------------------------------
1486 FeatureState SbaXDataBrowserController::GetState(sal_uInt16 nId) const
1488 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::GetState" );
1489 FeatureState aReturn;
1490 // (disabled automatically)
1494 // no chance without a view
1495 if (!getBrowserView() || !getBrowserView()->getVclControl())
1496 return aReturn;
1498 switch (nId)
1500 case ID_BROWSER_REMOVEFILTER:
1501 if (!m_xParser.is())
1503 aReturn.bEnabled = false;
1504 return aReturn;
1506 // any filter or sort order set ?
1507 aReturn.bEnabled = m_xParser->getFilter().getLength() || m_xParser->getHavingClause().getLength() || m_xParser->getOrder().getLength();
1508 return aReturn;
1510 // no chance while loading the form
1511 if (PendingLoad())
1512 return aReturn;
1513 // no chance without valid models
1514 if (isValid() && !isValidCursor())
1515 return aReturn;
1517 switch (nId)
1519 case ID_BROWSER_SEARCH:
1521 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
1522 sal_Int32 nCount = ::comphelper::getINT32(xFormSet->getPropertyValue(PROPERTY_ROWCOUNT));
1523 aReturn.bEnabled = nCount != 0;
1525 break;
1526 case ID_BROWSER_INSERT_ROW:
1528 // check if it is available
1529 Reference< XPropertySet > xDataSourceSet(getRowSet(), UNO_QUERY);
1530 if (!xDataSourceSet.is())
1531 break; // no datasource -> no edit mode
1533 sal_Int32 nDataSourcePrivileges = ::comphelper::getINT32(xDataSourceSet->getPropertyValue(PROPERTY_PRIVILEGES));
1534 aReturn.bEnabled = ((nDataSourcePrivileges & ::com::sun::star::sdbcx::Privilege::INSERT) != 0) && ::comphelper::getBOOL(xDataSourceSet->getPropertyValue(::rtl::OUString::createFromAscii("AllowInserts")));
1536 break;
1537 case SID_FM_DELETEROWS:
1539 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
1540 sal_Int32 nCount = ::comphelper::getINT32(xFormSet->getPropertyValue(PROPERTY_ROWCOUNT));
1541 sal_Bool bNew = sal_False;
1542 xFormSet->getPropertyValue(PROPERTY_ISNEW) >>= bNew;
1543 aReturn.bEnabled = nCount != 0 && !bNew;
1545 break;
1547 case ID_BROWSER_COPY:
1548 if ( getBrowserView()->getVclControl()->GetSelectRowCount() )
1550 aReturn.bEnabled = m_aCurrentFrame.isActive();
1551 break;
1553 // run through
1554 case ID_BROWSER_PASTE:
1555 case ID_BROWSER_CUT:
1557 CellControllerRef xCurrentController = getBrowserView()->getVclControl()->Controller();
1558 if (xCurrentController.Is() && xCurrentController->ISA(EditCellController))
1560 Edit& rEdit = (Edit&)xCurrentController->GetWindow();
1561 sal_Bool bHasLen = (rEdit.GetSelection().Len() != 0);
1562 sal_Bool bIsReadOnly = rEdit.IsReadOnly();
1563 switch (nId)
1565 case ID_BROWSER_CUT: aReturn.bEnabled = m_aCurrentFrame.isActive() && bHasLen && !bIsReadOnly; break;
1566 case SID_COPY : aReturn.bEnabled = m_aCurrentFrame.isActive() && bHasLen; break;
1567 case ID_BROWSER_PASTE:
1568 aReturn.bEnabled = m_aCurrentFrame.isActive() && !bIsReadOnly;
1569 if(aReturn.bEnabled)
1571 aReturn.bEnabled = aReturn.bEnabled && IsFormatSupported( m_aSystemClipboard.GetDataFlavorExVector(), FORMAT_STRING );
1573 break;
1577 break;
1579 case ID_BROWSER_SORTUP:
1580 case ID_BROWSER_SORTDOWN:
1581 case ID_BROWSER_AUTOFILTER:
1583 // a native statement can't be filtered or sorted
1584 const Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
1585 if ( !::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)))
1586 break;
1588 Reference< XPropertySet > xCurrentField = getBoundField();
1589 if (!xCurrentField.is())
1590 break;
1592 aReturn.bEnabled = ::comphelper::getBOOL(xCurrentField->getPropertyValue(PROPERTY_ISSEARCHABLE));
1593 const Reference< XRowSet > xRow = getRowSet();
1594 aReturn.bEnabled = aReturn.bEnabled
1595 && xRow.is()
1596 && !xRow->isBeforeFirst()
1597 && !xRow->isAfterLast()
1598 && !xRow->rowDeleted()
1599 && ( ::comphelper::getINT32( xFormSet->getPropertyValue( PROPERTY_ROWCOUNT ) ) != 0 );
1601 break;
1603 case ID_BROWSER_FILTERCRIT:
1604 if ( m_bCannotSelectUnfiltered )
1606 aReturn.bEnabled = sal_True;
1607 break;
1609 // no break
1610 case ID_BROWSER_ORDERCRIT:
1612 const Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
1613 if ( !::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)))
1614 break;
1616 aReturn.bEnabled = getRowSet().is()
1617 && ( ::comphelper::getINT32( xFormSet->getPropertyValue( PROPERTY_ROWCOUNT ) ) != 0 );
1619 break;
1621 case ID_BROWSER_REFRESH:
1622 aReturn.bEnabled = sal_True;
1623 break;
1625 case ID_BROWSER_REDO:
1626 aReturn.bEnabled = sal_False; // simply forget it ;). no redo possible.
1627 break;
1629 case ID_BROWSER_UNDORECORD:
1630 case ID_BROWSER_SAVERECORD:
1632 if (!m_bCurrentlyModified)
1634 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
1635 if (xFormSet.is())
1636 aReturn.bEnabled = ::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ISMODIFIED));
1638 else
1639 aReturn.bEnabled = sal_True;
1641 aReturn.sTitle = (ID_BROWSER_UNDORECORD == nId) ? m_sStateUndoRecord : m_sStateSaveRecord;
1643 break;
1644 case ID_BROWSER_EDITDOC:
1646 // check if it is available
1647 Reference< XPropertySet > xDataSourceSet(getRowSet(), UNO_QUERY);
1648 if (!xDataSourceSet.is())
1649 break; // no datasource -> no edit mode
1651 sal_Int32 nDataSourcePrivileges = ::comphelper::getINT32(xDataSourceSet->getPropertyValue(PROPERTY_PRIVILEGES));
1652 sal_Bool bInsertAllowedAndPossible = ((nDataSourcePrivileges & ::com::sun::star::sdbcx::Privilege::INSERT) != 0) && ::comphelper::getBOOL(xDataSourceSet->getPropertyValue(::rtl::OUString::createFromAscii("AllowInserts")));
1653 sal_Bool bUpdateAllowedAndPossible = ((nDataSourcePrivileges & ::com::sun::star::sdbcx::Privilege::UPDATE) != 0) && ::comphelper::getBOOL(xDataSourceSet->getPropertyValue(::rtl::OUString::createFromAscii("AllowUpdates")));
1654 sal_Bool bDeleteAllowedAndPossible = ((nDataSourcePrivileges & ::com::sun::star::sdbcx::Privilege::DELETE) != 0) && ::comphelper::getBOOL(xDataSourceSet->getPropertyValue(::rtl::OUString::createFromAscii("AllowDeletes")));
1655 if (!bInsertAllowedAndPossible && !bUpdateAllowedAndPossible && !bDeleteAllowedAndPossible)
1656 break; // no insert/update/delete -> no edit mode
1658 if (!isValidCursor() || !isLoaded())
1659 break; // no cursor -> no edit mode
1661 aReturn.bEnabled = sal_True;
1663 sal_Int16 nGridMode = getBrowserView()->getVclControl()->GetOptions();
1664 aReturn.bChecked = nGridMode > DbGridControl::OPT_READONLY;
1666 break;
1667 case ID_BROWSER_FILTERED:
1669 aReturn.bEnabled = sal_False;
1670 Reference< XPropertySet > xActiveSet(getRowSet(), UNO_QUERY);
1671 ::rtl::OUString aFilter = ::comphelper::getString(xActiveSet->getPropertyValue(PROPERTY_FILTER));
1672 ::rtl::OUString aHaving = ::comphelper::getString(xActiveSet->getPropertyValue(PROPERTY_HAVING_CLAUSE));
1673 if ( aFilter.getLength() || aHaving.getLength() )
1675 xActiveSet->getPropertyValue( PROPERTY_APPLYFILTER ) >>= aReturn.bChecked;
1676 aReturn.bEnabled = sal_True;
1678 else
1680 aReturn.bChecked = sal_False;
1681 aReturn.bEnabled = sal_False;
1684 break;
1685 default:
1686 return SbaXDataBrowserController_Base::GetState(nId);
1689 catch(const Exception& )
1691 DBG_UNHANDLED_EXCEPTION();
1694 return aReturn;
1697 //------------------------------------------------------------------------------
1698 void SbaXDataBrowserController::applyParserOrder(const ::rtl::OUString& _rOldOrder)
1700 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::applyParserOrder" );
1701 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
1702 if (!m_xLoadable.is())
1704 OSL_ENSURE(sal_False, "SbaXDataBrowserController::applyParserOrder: invalid row set!");
1705 return;
1708 sal_uInt16 nPos = getCurrentColumnPosition();
1709 sal_Bool bSuccess = sal_False;
1712 xFormSet->setPropertyValue(PROPERTY_ORDER, makeAny(m_xParser->getOrder()));
1713 bSuccess = reloadForm(m_xLoadable);
1715 catch(Exception&)
1719 if (!bSuccess)
1721 xFormSet->setPropertyValue(PROPERTY_ORDER, makeAny(_rOldOrder));
1722 DO_SAFE( m_xParser->setOrder(_rOldOrder), "SbaXDataBrowserController::applyParserOrder: could not restore the old order of my parser !" );
1726 if (loadingCancelled() || !reloadForm(m_xLoadable))
1727 criticalFail();
1729 catch(Exception&)
1731 criticalFail();
1733 InvalidateAll();
1735 InvalidateFeature(ID_BROWSER_REMOVEFILTER);
1737 setCurrentColumnPosition(nPos);
1740 //------------------------------------------------------------------------------
1741 void SbaXDataBrowserController::applyParserFilter(const ::rtl::OUString& _rOldFilter, sal_Bool _bOldFilterApplied,const ::rtl::OUString& _sOldHaving)
1743 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::applyParserFilter" );
1744 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
1745 if (!m_xLoadable.is())
1747 OSL_ENSURE(sal_False, "SbaXDataBrowserController::applyParserFilter: invalid row set!");
1748 return;
1751 sal_uInt16 nPos = getCurrentColumnPosition();
1753 sal_Bool bSuccess = sal_False;
1756 FormErrorHelper aError(this);
1757 xFormSet->setPropertyValue(PROPERTY_FILTER, makeAny(m_xParser->getFilter()));
1758 xFormSet->setPropertyValue(PROPERTY_HAVING_CLAUSE, makeAny(m_xParser->getHavingClause()));
1759 xFormSet->setPropertyValue(PROPERTY_APPLYFILTER, ::comphelper::makeBoolAny(sal_Bool(sal_True)));
1761 bSuccess = reloadForm(m_xLoadable);
1763 catch(Exception&)
1767 if (!bSuccess)
1769 xFormSet->setPropertyValue(PROPERTY_FILTER, makeAny(_rOldFilter));
1770 xFormSet->setPropertyValue(PROPERTY_HAVING_CLAUSE, makeAny(_sOldHaving));
1771 xFormSet->setPropertyValue(PROPERTY_APPLYFILTER, ::comphelper::makeBoolAny(_bOldFilterApplied));
1775 if (loadingCancelled() || !reloadForm(m_xLoadable))
1776 criticalFail();
1778 catch(Exception&)
1780 criticalFail();
1782 InvalidateAll();
1784 InvalidateFeature(ID_BROWSER_REMOVEFILTER);
1786 setCurrentColumnPosition(nPos);
1789 //------------------------------------------------------------------------------
1790 void SbaXDataBrowserController::ExecuteFilterSortCrit(sal_Bool bFilter)
1792 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::ExecuteFilterSortCrit" );
1793 if (!SaveModified())
1794 return;
1796 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
1798 const ::rtl::OUString sOldVal = bFilter ? m_xParser->getFilter() : m_xParser->getOrder();
1799 const ::rtl::OUString sOldHaving = m_xParser->getHavingClause();
1802 Reference< ::com::sun::star::sdbcx::XColumnsSupplier> xSup = getColumnsSupplier();
1803 Reference< XConnection> xCon(xFormSet->getPropertyValue(PROPERTY_ACTIVE_CONNECTION),UNO_QUERY);
1804 if(bFilter)
1806 DlgFilterCrit aDlg( getBrowserView(), getORB(), xCon, m_xParser, xSup->getColumns() );
1807 String aFilter;
1808 if(!aDlg.Execute())
1810 m_xParser->setFilter(sOldVal);
1811 m_xParser->setHavingClause(sOldHaving);
1812 return; // if so we don't need to actualize the grid
1814 aDlg.BuildWherePart();
1816 else
1818 DlgOrderCrit aDlg( getBrowserView(),xCon,m_xParser,xSup->getColumns() );
1819 String aOrder;
1820 if(!aDlg.Execute())
1822 m_xParser->setOrder(sOldVal);
1823 return; // if so we don't need to actualize the grid
1825 aDlg.BuildOrderPart();
1828 catch(const SQLException& )
1830 SQLExceptionInfo aError( ::cppu::getCaughtException() );
1831 showError( aError );
1832 return;
1834 catch(Exception&)
1836 return;
1839 ::rtl::OUString sNewVal = bFilter ? m_xParser->getFilter() : m_xParser->getOrder();
1840 sal_Bool bOldFilterApplied(sal_False);
1841 if (bFilter)
1843 try { bOldFilterApplied = ::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_APPLYFILTER)); } catch(Exception&) { } ;
1846 ::rtl::OUString sNewHaving = m_xParser->getHavingClause();
1847 if ( sOldVal.equals(sNewVal) && (!bFilter || sOldHaving.equals(sNewHaving)) )
1848 // nothing to be done
1849 return;
1851 if (bFilter)
1852 applyParserFilter(sOldVal, bOldFilterApplied,sOldHaving);
1853 else
1854 applyParserOrder(sOldVal);
1858 //------------------------------------------------------------------------------
1859 void SbaXDataBrowserController::ExecuteSearch()
1861 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::ExecuteSearch" );
1862 // calculate the control source of the active field
1863 Reference< ::com::sun::star::form::XGrid > xGrid(getBrowserView()->getGridControl(), UNO_QUERY);
1864 DBG_ASSERT(xGrid.is(), "SbaXDataBrowserController::ExecuteSearch : the control should have an ::com::sun::star::form::XGrid interface !");
1866 Reference< ::com::sun::star::form::XGridPeer > xGridPeer(getBrowserView()->getGridControl()->getPeer(), UNO_QUERY);
1867 Reference< ::com::sun::star::container::XIndexContainer > xColumns = xGridPeer->getColumns();
1868 DBG_ASSERT(xGridPeer.is() && xColumns.is(), "SbaXDataBrowserController::ExecuteSearch : invalid peer !");
1870 sal_Int16 nViewCol = xGrid->getCurrentColumnPosition();
1871 sal_Int16 nModelCol = getBrowserView()->View2ModelPos(nViewCol);
1873 Reference< XPropertySet > xCurrentCol(xColumns->getByIndex(nModelCol),UNO_QUERY);
1874 String sActiveField = ::comphelper::getString(xCurrentCol->getPropertyValue(PROPERTY_CONTROLSOURCE));
1876 // the text within the current cell
1877 String sInitialText;
1878 Reference< ::com::sun::star::container::XIndexAccess > xColControls(xGridPeer, UNO_QUERY);
1879 Reference< XInterface > xCurControl(xColControls->getByIndex(nViewCol),UNO_QUERY);
1880 ::rtl::OUString aInitialText;
1881 if (IsSearchableControl(xCurControl, &aInitialText))
1882 sInitialText = (const sal_Unicode*)aInitialText;
1884 // prohibit the synchronization of the grid's display with the cursor's position
1885 Reference< XPropertySet > xModelSet(getControlModel(), UNO_QUERY);
1886 DBG_ASSERT(xModelSet.is(), "SbaXDataBrowserController::ExecuteSearch : no model set ?!");
1887 xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"), ::comphelper::makeBoolAny(sal_Bool(sal_False)));
1888 xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("AlwaysShowCursor"), ::comphelper::makeBoolAny(sal_Bool(sal_True)));
1889 xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("CursorColor"), makeAny(sal_Int32(COL_LIGHTRED)));
1891 Reference< ::com::sun::star::util::XNumberFormatsSupplier > xNFS(::dbtools::getNumberFormats(::dbtools::getConnection(m_xRowSet), sal_True,getORB()));
1893 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1894 AbstractFmSearchDialog* pDialog = NULL;
1895 if ( pFact )
1897 ::std::vector< String > aContextNames;
1898 aContextNames.push_back( String::CreateFromAscii("Standard") );
1899 pDialog = pFact->CreateFmSearchDialog(getBrowserView(), sInitialText, aContextNames, 0, LINK(this, SbaXDataBrowserController, OnSearchContextRequest));
1901 DBG_ASSERT( pDialog, "SbaXDataBrowserController::ExecuteSearch: could not get the search dialog!" );
1902 if ( pDialog )
1904 pDialog->SetActiveField( sActiveField );
1905 pDialog->SetFoundHandler( LINK( this, SbaXDataBrowserController, OnFoundData ) );
1906 pDialog->SetCanceledNotFoundHdl( LINK( this, SbaXDataBrowserController, OnCanceledNotFound ) );
1907 pDialog->Execute();
1908 delete pDialog;
1911 // restore the grid's normal operating state
1912 xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"), ::comphelper::makeBoolAny(sal_Bool(sal_True)));
1913 xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("AlwaysShowCursor"), ::comphelper::makeBoolAny(sal_Bool(sal_False)));
1914 xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("CursorColor"), Any());
1917 //------------------------------------------------------------------------------
1918 void SbaXDataBrowserController::Execute(sal_uInt16 nId, const Sequence< PropertyValue >& _rArgs)
1920 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::Execute" );
1921 sal_Bool bSortUp = sal_True;
1923 switch (nId)
1925 default:
1926 SbaXDataBrowserController_Base::Execute( nId, _rArgs );
1927 return;
1929 case ID_BROWSER_INSERT_ROW:
1932 if (SaveModified())
1934 getRowSet()->afterLast();
1935 // check if it is available
1936 Reference< XResultSetUpdate > xUpdateCursor(getRowSet(), UNO_QUERY_THROW);
1937 xUpdateCursor->moveToInsertRow();
1940 catch(Exception&)
1942 OSL_ENSURE(0,"Exception caught!");
1944 break;
1945 case SID_FM_DELETEROWS:
1947 if (SaveModified())
1949 SbaGridControl* pVclGrid = getBrowserView()->getVclControl();
1950 if ( pVclGrid )
1952 if( !pVclGrid->GetSelectRowCount() )
1954 pVclGrid->DeactivateCell();
1955 pVclGrid->SelectRow(pVclGrid->GetCurRow());
1957 pVclGrid->DeleteSelectedRows();
1960 break;
1962 case ID_BROWSER_FILTERED:
1963 if (SaveModified())
1965 Reference< XPropertySet > xActiveSet(getRowSet(), UNO_QUERY);
1966 sal_Bool bApplied = ::comphelper::getBOOL(xActiveSet->getPropertyValue(PROPERTY_APPLYFILTER));
1967 xActiveSet->setPropertyValue(PROPERTY_APPLYFILTER, ::comphelper::makeBoolAny(sal_Bool(!bApplied)));
1968 reloadForm(m_xLoadable);
1970 InvalidateFeature(ID_BROWSER_FILTERED);
1971 break;
1972 case ID_BROWSER_EDITDOC:
1974 sal_Int16 nGridMode = getBrowserView()->getVclControl()->GetOptions();
1975 if (nGridMode == DbGridControl::OPT_READONLY)
1976 getBrowserView()->getVclControl()->SetOptions(DbGridControl::OPT_UPDATE | DbGridControl::OPT_INSERT | DbGridControl::OPT_DELETE);
1977 // the options not supported by the data source will be removed automatically
1978 else
1980 if ( !SaveModified( ) )
1981 // give the user a chance to save the current record (if neccessary)
1982 break;
1984 // maybe the user wanted to reject the modified record ?
1985 if (GetState(ID_BROWSER_UNDORECORD).bEnabled)
1986 Execute(ID_BROWSER_UNDORECORD,Sequence<PropertyValue>());
1988 getBrowserView()->getVclControl()->SetOptions(DbGridControl::OPT_READONLY);
1990 InvalidateFeature(ID_BROWSER_EDITDOC);
1992 break;
1994 case ID_BROWSER_SEARCH:
1995 if ( SaveModified( ) )
1996 ExecuteSearch();
1997 break;
1999 case ID_BROWSER_COPY:
2000 if ( getBrowserView()->getVclControl()->GetSelectRowCount() > 0 )
2002 getBrowserView()->getVclControl()->CopySelectedRowsToClipboard();
2003 break;
2005 // run through
2006 case ID_BROWSER_CUT:
2007 case ID_BROWSER_PASTE:
2009 CellControllerRef xCurrentController = getBrowserView()->getVclControl()->Controller();
2010 if (!xCurrentController.Is())
2011 // should be intercepted by GetState. Normally.
2012 // Unfortunately ID_BROWSER_PASTE is a 'fast call' slot, which means it may be executed without checking if it is
2013 // enabled. This would be really deadly herein if the current cell has no controller ...
2014 // (FS - 13.04.99 - #64694#)
2015 return;
2017 Edit& rEdit = (Edit&)xCurrentController->GetWindow();
2018 switch (nId)
2020 case ID_BROWSER_CUT : rEdit.Cut(); break;
2021 case SID_COPY : rEdit.Copy(); break;
2022 case ID_BROWSER_PASTE : rEdit.Paste(); break;
2024 if (ID_BROWSER_CUT == nId || ID_BROWSER_PASTE == nId)
2026 xCurrentController->SetModified();
2027 rEdit.Modify();
2030 break;
2032 case ID_BROWSER_SORTDOWN:
2033 bSortUp = sal_False;
2034 // DON'T break
2035 case ID_BROWSER_SORTUP:
2037 if (!SaveModified())
2038 break;
2040 if (!isValidCursor())
2041 break;
2043 // only one sort order
2044 Reference< XPropertySet > xField(getBoundField(), UNO_QUERY);
2045 if (!xField.is())
2046 break;
2048 const ::rtl::OUString sOldSort = m_xParser->getOrder();
2049 sal_Bool bParserSuccess = sal_False;
2050 HANDLE_SQL_ERRORS(
2051 m_xParser->setOrder(::rtl::OUString()); m_xParser->appendOrderByColumn(xField, bSortUp),
2052 bParserSuccess,
2053 UniString(ModuleRes(SBA_BROWSER_SETTING_ORDER)),
2054 "SbaXDataBrowserController::Execute : caught an exception while composing the new filter !"
2057 if (bParserSuccess)
2058 applyParserOrder(sOldSort);
2060 break;
2062 case ID_BROWSER_AUTOFILTER:
2064 if (!SaveModified())
2065 break;
2067 if (!isValidCursor())
2068 break;
2070 Reference< XPropertySet > xField(getBoundField(), UNO_QUERY);
2071 if (!xField.is())
2072 break;
2074 // check if the column is a aggregate function
2075 sal_Bool bHaving = sal_False;
2076 ::rtl::OUString sName;
2077 xField->getPropertyValue(PROPERTY_NAME) >>= sName;
2078 Reference< XColumnsSupplier > xColumnsSupplier(m_xParser, UNO_QUERY);
2079 Reference< ::com::sun::star::container::XNameAccess > xCols = xColumnsSupplier.is() ? xColumnsSupplier->getColumns() : Reference< ::com::sun::star::container::XNameAccess > ();
2080 if ( xCols.is() && xCols->hasByName(sName) )
2082 Reference<XPropertySet> xProp(xCols->getByName(sName),UNO_QUERY);
2083 static ::rtl::OUString sAgg(RTL_CONSTASCII_USTRINGPARAM("AggregateFunction"));
2084 if ( xProp->getPropertySetInfo()->hasPropertyByName(sAgg) )
2085 xProp->getPropertyValue(sAgg) >>= bHaving;
2088 const ::rtl::OUString sOldFilter = m_xParser->getFilter();
2089 const ::rtl::OUString sOldHaving = m_xParser->getHavingClause();
2091 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
2092 sal_Bool bApplied = ::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_APPLYFILTER));
2093 // do we have a filter but it's not applied ?
2094 // -> completely overwrite it, else append one
2095 if (!bApplied)
2097 DO_SAFE( (bHaving ? m_xParser->setHavingClause(::rtl::OUString()) : m_xParser->setFilter(::rtl::OUString())), "SbaXDataBrowserController::Execute : caught an exception while resetting the new filter !" );
2100 sal_Bool bParserSuccess = sal_False;
2103 if ( bHaving )
2105 HANDLE_SQL_ERRORS(
2106 m_xParser->appendHavingClauseByColumn(xField,sal_True),
2107 bParserSuccess,
2108 UniString(ModuleRes(SBA_BROWSER_SETTING_FILTER)),
2109 "SbaXDataBrowserController::Execute : caught an exception while composing the new filter !"
2112 else
2114 HANDLE_SQL_ERRORS(
2115 m_xParser->appendFilterByColumn(xField,sal_True),
2116 bParserSuccess,
2117 UniString(ModuleRes(SBA_BROWSER_SETTING_FILTER)),
2118 "SbaXDataBrowserController::Execute : caught an exception while composing the new filter !"
2122 if (bParserSuccess)
2123 applyParserFilter(sOldFilter, bApplied,sOldHaving);
2125 InvalidateFeature(ID_BROWSER_REMOVEFILTER);
2126 InvalidateFeature(ID_BROWSER_FILTERED);
2128 break;
2130 case ID_BROWSER_ORDERCRIT:
2131 ExecuteFilterSortCrit(sal_False);
2132 break;
2134 case ID_BROWSER_FILTERCRIT:
2135 ExecuteFilterSortCrit(sal_True);
2136 InvalidateFeature(ID_BROWSER_FILTERED);
2137 break;
2139 case ID_BROWSER_REMOVEFILTER:
2141 if (!SaveModified())
2142 break;
2144 sal_Bool bNeedPostReload = preReloadForm();
2145 // reset the filter and the sort property simutaneously so only _one_ new statement has to be
2146 // sent
2147 Reference< XPropertySet > xSet(getRowSet(), UNO_QUERY);
2148 if ( xSet.is() )
2150 xSet->setPropertyValue(PROPERTY_FILTER,makeAny(::rtl::OUString()));
2151 xSet->setPropertyValue(PROPERTY_HAVING_CLAUSE,makeAny(::rtl::OUString()));
2152 xSet->setPropertyValue(PROPERTY_ORDER,makeAny(::rtl::OUString()));
2156 reloadForm(m_xLoadable);
2157 if ( bNeedPostReload )
2158 postReloadForm();
2160 catch(Exception&)
2163 InvalidateFeature(ID_BROWSER_REMOVEFILTER);
2164 InvalidateFeature(ID_BROWSER_FILTERED);
2166 break;
2168 case ID_BROWSER_REFRESH:
2169 if ( SaveModified( ) )
2171 if (!reloadForm(m_xLoadable))
2172 criticalFail();
2174 break;
2176 case ID_BROWSER_SAVERECORD:
2177 if ( SaveModified( sal_False ) )
2178 setCurrentModified( sal_False );
2179 break;
2181 case ID_BROWSER_UNDORECORD:
2185 // restore the cursor state
2186 Reference< XResultSetUpdate > xCursor(getRowSet(), UNO_QUERY);
2187 Reference< XPropertySet > xSet(xCursor, UNO_QUERY);
2188 Any aVal = xSet->getPropertyValue(PROPERTY_ISNEW);
2189 if (aVal.hasValue() && ::comphelper::getBOOL(aVal))
2191 xCursor->moveToInsertRow();
2192 // no need to reset the grid model after we moved to the insert row, this is done implicitly by the
2193 // form
2194 // (and in some cases it may be deadly to do the reset explicitly after the form did it implicitly,
2195 // cause the form's reset may be async, and this leads to some nice deadlock scenarios ....)
2197 else
2199 xCursor->cancelRowUpdates();
2201 // restore the grids state
2202 Reference< ::com::sun::star::form::XReset > xReset(getControlModel(), UNO_QUERY);
2203 if (xReset.is())
2204 xReset->reset();
2207 catch(SQLException&)
2211 setCurrentModified( sal_False );
2216 //------------------------------------------------------------------------------
2217 sal_Bool SbaXDataBrowserController::SaveModified(sal_Bool bAskFor)
2219 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::SaveModified" );
2220 if ( bAskFor && GetState(ID_BROWSER_SAVERECORD).bEnabled )
2222 getBrowserView()->getVclControl()->GrabFocus();
2224 QueryBox aQry(getBrowserView()->getVclControl(), ModuleRes(QUERY_BRW_SAVEMODIFIED));
2226 switch (aQry.Execute())
2228 case RET_NO:
2229 Execute(ID_BROWSER_UNDORECORD,Sequence<PropertyValue>());
2230 return sal_True;
2231 case RET_CANCEL:
2232 return sal_False;
2236 if ( !CommitCurrent() ) // das aktuelle Control committen lassen
2237 return sal_False;
2239 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
2240 sal_Bool bResult = sal_False;
2243 if (::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ISMODIFIED)))
2245 Reference< XResultSetUpdate > xCursor(getRowSet(), UNO_QUERY);
2246 if (::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ISNEW)))
2247 xCursor->insertRow();
2248 else
2249 xCursor->updateRow();
2251 bResult = sal_True;
2253 catch(SQLException&)
2256 catch(Exception&)
2258 DBG_ERROR("SbaXDataBrowserController::SaveModified : could not save the current record !");
2259 bResult = sal_False;
2262 InvalidateFeature(ID_BROWSER_SAVERECORD);
2263 InvalidateFeature(ID_BROWSER_UNDORECORD);
2264 return bResult;
2267 //------------------------------------------------------------------------------
2268 sal_Bool SbaXDataBrowserController::CommitCurrent()
2270 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::CommitCurrent" );
2271 if (!getBrowserView())
2272 return sal_True;
2274 Reference< ::com::sun::star::awt::XControl > xActiveControl(getBrowserView()->getGridControl());
2275 Reference< ::com::sun::star::form::XBoundControl > xLockingTest(xActiveControl, UNO_QUERY);
2276 sal_Bool bControlIsLocked = xLockingTest.is() && xLockingTest->getLock();
2277 if (xActiveControl.is() && !bControlIsLocked)
2279 // zunaechst das Control fragen ob es das IFace unterstuetzt
2280 Reference< ::com::sun::star::form::XBoundComponent > xBoundControl(xActiveControl, UNO_QUERY);
2281 if (!xBoundControl.is())
2282 xBoundControl = Reference< ::com::sun::star::form::XBoundComponent > (xActiveControl->getModel(), UNO_QUERY);
2283 if (xBoundControl.is() && !xBoundControl->commit())
2284 return sal_False;
2286 return sal_True;
2289 //------------------------------------------------------------------------------
2290 void SbaXDataBrowserController::setCurrentModified( sal_Bool _bSet )
2292 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::setCurrentModified" );
2293 m_bCurrentlyModified = _bSet;
2294 InvalidateFeature( ID_BROWSER_SAVERECORD );
2295 InvalidateFeature( ID_BROWSER_UNDORECORD );
2298 //------------------------------------------------------------------------------
2299 void SbaXDataBrowserController::RowChanged()
2301 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::RowChanged" );
2302 setCurrentModified( sal_False );
2305 //------------------------------------------------------------------------------
2306 void SbaXDataBrowserController::ColumnChanged()
2308 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::ColumnChanged" );
2309 InvalidateFeature(ID_BROWSER_SORTUP);
2310 InvalidateFeature(ID_BROWSER_SORTDOWN);
2311 InvalidateFeature(ID_BROWSER_ORDERCRIT);
2312 InvalidateFeature(ID_BROWSER_FILTERCRIT);
2313 InvalidateFeature(ID_BROWSER_AUTOFILTER);
2314 InvalidateFeature(ID_BROWSER_REMOVEFILTER);
2316 setCurrentModified( sal_False );
2319 //------------------------------------------------------------------------------
2320 void SbaXDataBrowserController::SelectionChanged()
2322 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::SelectionChanged" );
2323 // not interested in
2326 //------------------------------------------------------------------------------
2327 void SbaXDataBrowserController::CellActivated()
2329 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::CellActivated" );
2330 m_aInvalidateClipboard.Start();
2331 OnInvalidateClipboard( NULL );
2334 //------------------------------------------------------------------------------
2335 void SbaXDataBrowserController::CellDeactivated()
2337 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::CellDeactivated" );
2338 m_aInvalidateClipboard.Stop();
2339 OnInvalidateClipboard( NULL );
2342 //------------------------------------------------------------------------------
2343 IMPL_LINK( SbaXDataBrowserController, OnClipboardChanged, void*, EMPTYARG )
2345 ::vos::OGuard aGuard(Application::GetSolarMutex());
2346 return OnInvalidateClipboard( NULL );
2349 //------------------------------------------------------------------------------
2350 IMPL_LINK(SbaXDataBrowserController, OnInvalidateClipboard, AutoTimer*, _pTimer)
2352 InvalidateFeature(ID_BROWSER_CUT);
2353 InvalidateFeature(ID_BROWSER_COPY);
2355 // if the invalidation was triggered by the timer, we do not need to invalidate PASTE.
2356 // The timer is only for checking the CUT/COPY slots regulariry, which depend on the
2357 // selection state of the active cell
2358 // TODO: get a callback at the Edit which allows to be notified when the selection
2359 // changes. This would be much better than this cycle-eating polling mechanism here ....
2360 if ( _pTimer != &m_aInvalidateClipboard )
2361 InvalidateFeature(ID_BROWSER_PASTE);
2363 return 0L;
2366 // -------------------------------------------------------------------------
2367 Reference< XPropertySet > SbaXDataBrowserController::getBoundField(sal_uInt16 nViewPos) const
2369 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::SaveData" );
2370 Reference< XPropertySet > xEmptyReturn;
2372 // get the current column from the grid
2373 if (nViewPos == (sal_uInt16)-1)
2375 Reference< ::com::sun::star::form::XGrid > xGrid(getBrowserView()->getGridControl(), UNO_QUERY);
2376 if (!xGrid.is())
2377 return xEmptyReturn;
2378 nViewPos = xGrid->getCurrentColumnPosition();
2380 sal_uInt16 nCurrentCol = getBrowserView()->View2ModelPos(nViewPos);
2381 if (nCurrentCol == (sal_uInt16)-1)
2382 return xEmptyReturn;
2384 // get the according column from the model
2385 Reference< ::com::sun::star::container::XIndexContainer > xCols(getControlModel(), UNO_QUERY);
2386 Reference< XPropertySet > xCurrentCol(xCols->getByIndex(nCurrentCol),UNO_QUERY);
2387 if (!xCurrentCol.is())
2388 return xEmptyReturn;
2390 xEmptyReturn.set(xCurrentCol->getPropertyValue(PROPERTY_BOUNDFIELD) ,UNO_QUERY);
2391 return xEmptyReturn;
2394 //------------------------------------------------------------------------------
2395 IMPL_LINK(SbaXDataBrowserController, OnSearchContextRequest, FmSearchContext*, pContext)
2397 Reference< ::com::sun::star::container::XIndexAccess > xPeerContainer(getBrowserView()->getGridControl(), UNO_QUERY);
2399 // check all grid columns for their control source
2400 Reference< ::com::sun::star::container::XIndexAccess > xModelColumns(getFormComponent(), UNO_QUERY);
2401 DBG_ASSERT(xModelColumns.is(), "SbaXDataBrowserController::OnSearchContextRequest : there is a grid control without columns !");
2402 // the case 'no columns' should be indicated with an empty container, I think ...
2403 DBG_ASSERT(xModelColumns->getCount() >= xPeerContainer->getCount(), "SbaXDataBrowserController::OnSearchContextRequest : impossible : have more view than model columns !");
2405 String sFieldList;
2406 for (sal_Int32 nViewPos=0; nViewPos<xPeerContainer->getCount(); ++nViewPos)
2408 Reference< XInterface > xCurrentColumn(xPeerContainer->getByIndex(nViewPos),UNO_QUERY);
2409 if (!xCurrentColumn.is())
2410 continue;
2412 // can we use this column control fo searching ?
2413 if (!IsSearchableControl(xCurrentColumn))
2414 continue;
2416 sal_uInt16 nModelPos = getBrowserView()->View2ModelPos((sal_uInt16)nViewPos);
2417 Reference< XPropertySet > xCurrentColModel(xModelColumns->getByIndex(nModelPos),UNO_QUERY);
2418 ::rtl::OUString aName = ::comphelper::getString(xCurrentColModel->getPropertyValue(PROPERTY_CONTROLSOURCE));
2420 sFieldList += (const sal_Unicode*)aName;
2421 sFieldList += ';';
2423 pContext->arrFields.push_back(xCurrentColumn);
2425 sFieldList.EraseTrailingChars(';');
2427 pContext->xCursor.set(getRowSet(),UNO_QUERY);
2428 pContext->strUsedFields = sFieldList;
2430 // if the cursor is in a mode other than STANDARD -> reset
2431 Reference< XPropertySet > xCursorSet(pContext->xCursor, UNO_QUERY);
2432 DBG_ASSERT(xCursorSet.is() && !::comphelper::getBOOL(xCursorSet->getPropertyValue(PROPERTY_ISMODIFIED)),
2433 "SbaXDataBrowserController::OnSearchContextRequest : please do not call for cursors with modified rows !");
2434 if (xCursorSet.is() && ::comphelper::getBOOL(xCursorSet->getPropertyValue(PROPERTY_ISNEW)))
2436 Reference< XResultSetUpdate > xUpdateCursor(pContext->xCursor, UNO_QUERY);
2437 xUpdateCursor->moveToCurrentRow();
2439 return pContext->arrFields.size();
2442 //------------------------------------------------------------------------------
2443 IMPL_LINK(SbaXDataBrowserController, OnFoundData, FmFoundRecordInformation*, pInfo)
2445 Reference< ::com::sun::star::sdbcx::XRowLocate > xCursor(getRowSet(), UNO_QUERY);
2446 DBG_ASSERT(xCursor.is(), "SbaXDataBrowserController::OnFoundData : shit happens. sometimes. but this is simply impossible !");
2448 // move the cursor
2449 xCursor->moveToBookmark(pInfo->aPosition);
2451 // let the grid snyc it's display with the cursor
2452 Reference< XPropertySet > xModelSet(getControlModel(), UNO_QUERY);
2453 DBG_ASSERT(xModelSet.is(), "SbaXDataBrowserController::OnFoundData : no model set ?!");
2454 Any aOld = xModelSet->getPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"));
2455 xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"), ::comphelper::makeBoolAny(sal_Bool(sal_True)));
2456 xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"), aOld);
2458 // and move to the field
2459 Reference< ::com::sun::star::container::XIndexAccess > aColumnControls(getBrowserView()->getGridControl()->getPeer(), UNO_QUERY);
2460 sal_uInt16 nViewPos;
2462 for ( nViewPos = 0; nViewPos < aColumnControls->getCount(); ++nViewPos )
2464 Reference< XInterface > xCurrent(aColumnControls->getByIndex(nViewPos),UNO_QUERY);
2465 if (IsSearchableControl(xCurrent))
2467 if (pInfo->nFieldPos)
2468 --pInfo->nFieldPos;
2469 else
2470 break;
2474 Reference< ::com::sun::star::form::XGrid > xGrid(getBrowserView()->getGridControl(), UNO_QUERY);
2475 xGrid->setCurrentColumnPosition(nViewPos);
2477 return 0;
2480 //------------------------------------------------------------------------------
2481 IMPL_LINK(SbaXDataBrowserController, OnCanceledNotFound, FmFoundRecordInformation*, pInfo)
2483 Reference< ::com::sun::star::sdbcx::XRowLocate > xCursor(getRowSet(), UNO_QUERY);
2487 DBG_ASSERT(xCursor.is(), "SbaXDataBrowserController::OnCanceledNotFound : shit happens. sometimes. but this is simply impossible !");
2488 // move the cursor
2489 xCursor->moveToBookmark(pInfo->aPosition);
2491 catch( const Exception& )
2493 DBG_UNHANDLED_EXCEPTION();
2498 // let the grid snyc it's display with the cursor
2499 Reference< XPropertySet > xModelSet(getControlModel(), UNO_QUERY);
2500 DBG_ASSERT(xModelSet.is(), "SbaXDataBrowserController::OnCanceledNotFound : no model set ?!");
2501 Any aOld = xModelSet->getPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"));
2502 xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"), ::comphelper::makeBoolAny(sal_Bool(sal_True)));
2503 xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"), aOld);
2505 catch( const Exception& )
2507 DBG_UNHANDLED_EXCEPTION();
2510 return 0L;
2513 //------------------------------------------------------------------------------
2514 IMPL_LINK(SbaXDataBrowserController, OnOpenFinishedMainThread, void*, EMPTYARG)
2516 ::vos::OGuard aGuard(Application::GetSolarMutex());
2517 if (!m_nPendingLoadFinished)
2518 // it's possible that the direct call of this link from within suspend caused this method to be executed
2519 // in another thread while we were waiting for the mutex in this thread
2520 return 0;
2521 m_nPendingLoadFinished = 0;
2523 if ( static_cast< LoadFormThread* >( m_pLoadThread )->WasCanceled() )
2524 setLoadingCancelled();
2526 delete m_pLoadThread;
2527 m_pLoadThread = NULL;
2529 LoadFinished(sal_False);
2531 return 0L;
2534 //------------------------------------------------------------------------------
2535 IMPL_LINK(SbaXDataBrowserController, OnOpenFinished, void*, EMPTYARG)
2537 ::osl::MutexGuard aCheckGuard(m_aAsyncLoadSafety);
2539 if (m_bClosingKillOpen)
2541 delete m_pLoadThread;
2542 m_pLoadThread = NULL;
2544 else
2545 // all cleaning has to run in the main thread, not here (this is called synchronously from the LoadThread)
2546 // so we use an user event
2547 m_nPendingLoadFinished = Application::PostUserEvent(LINK(this, SbaXDataBrowserController, OnOpenFinishedMainThread));
2549 return 0L;
2552 //------------------------------------------------------------------------------
2553 IMPL_LINK(SbaXDataBrowserController, OnAsyncGetCellFocus, void*, EMPTYARG)
2555 SbaGridControl* pVclGrid = getBrowserView() ? getBrowserView()->getVclControl() : NULL;
2556 // if we have a controller, but the window for the controller doesn't have the focus, we correct this
2557 if(pVclGrid)
2559 if (!pVclGrid->IsEditing())
2560 return 0L;
2562 if (pVclGrid->HasChildPathFocus())
2563 pVclGrid->Controller()->GetWindow().GrabFocus();
2566 return 0L;
2569 //------------------------------------------------------------------------------
2570 void SbaXDataBrowserController::criticalFail()
2572 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::criticalFail" );
2573 InvalidateAll();
2576 //------------------------------------------------------------------------------
2577 void SbaXDataBrowserController::LoadFinished(sal_Bool /*bWasSynch*/)
2579 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::LoadFinished" );
2580 if (isValid() && !loadingCancelled())
2582 // --------------------------------
2583 // switch the control to alive mode
2584 getBrowserView()->getGridControl()->setDesignMode(sal_False);
2586 // -------------------------------
2587 initializeParser();
2589 // -------------------------------
2590 InvalidateAll();
2592 m_aAsyncGetCellFocus.Call();
2595 // -----------------------------------------------------------------------------
2596 void SbaXDataBrowserController::initializeParser() const
2598 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::initializeParser" );
2599 if ( !m_xParser.is() )
2601 // ----------------------------------------------
2602 // create a parser (needed for filtering/sorting)
2605 const Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
2606 if (::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)))
2607 { // (only if the statement isn't native)
2608 // (it is allowed to use the PROPERTY_ISPASSTHROUGH : _after_ loading a form it is valid)
2609 const Reference<XMultiServiceFactory> xFactory(::dbtools::getConnection(getRowSet()),UNO_QUERY);
2610 if ( xFactory.is() )
2611 m_xParser.set(xFactory->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER),UNO_QUERY);
2614 // initialize the parser with the current sql-statement of the form
2615 if ( m_xParser.is() )
2617 m_xParser->setElementaryQuery(::comphelper::getString(xFormSet->getPropertyValue(PROPERTY_ACTIVECOMMAND)));
2618 m_xParser->setFilter(::comphelper::getString(xFormSet->getPropertyValue(PROPERTY_FILTER)));
2619 m_xParser->setHavingClause(::comphelper::getString(xFormSet->getPropertyValue(PROPERTY_HAVING_CLAUSE)));
2620 m_xParser->setOrder(::comphelper::getString(xFormSet->getPropertyValue(PROPERTY_ORDER)));
2623 catch(Exception&)
2625 DBG_UNHANDLED_EXCEPTION();
2626 m_xParser = NULL;
2627 // no further handling, we ignore the error
2631 //------------------------------------------------------------------------------
2632 void SbaXDataBrowserController::loaded(const EventObject& /*aEvent*/) throw( RuntimeException )
2634 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::loaded" );
2635 // not interested in
2636 // we're loading within an separate thread and have a handling for it's "finished event"
2639 //------------------------------------------------------------------------------
2640 void SbaXDataBrowserController::unloading(const EventObject& /*aEvent*/) throw( RuntimeException )
2642 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::unloading" );
2643 // not interested in
2646 //------------------------------------------------------------------------------
2647 void SbaXDataBrowserController::unloaded(const EventObject& /*aEvent*/) throw( RuntimeException )
2649 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::unloaded" );
2650 InvalidateAll();
2651 // do this asynchron, there are other listeners reacting on this message ...
2652 // (it's a little hack : the grid columns are listening to this event, too, and their bound field may
2653 // change as a reaction on that event. as we have no chance to be notified of this change (which is
2654 // the one we're interested in) we give them time to do what they want to before invalidating our
2655 // bound-field-dependent slots ....
2658 ::comphelper::disposeComponent(m_xParser);
2660 catch(Exception&)
2662 OSL_ENSURE(0,"Exception thrown by dispose");
2666 //------------------------------------------------------------------------------
2667 void SbaXDataBrowserController::reloading(const EventObject& /*aEvent*/) throw( RuntimeException )
2669 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::reloading" );
2670 // not interested in
2673 //------------------------------------------------------------------------------
2674 void SbaXDataBrowserController::reloaded(const EventObject& /*aEvent*/) throw( RuntimeException )
2676 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::reloaded" );
2677 InvalidateAll();
2678 // do this asynchronously, there are other listeners reacting on this message ...
2679 // (it's a little hack : the grid columns are listening to this event, too, and their bound field may
2680 // change as a reaction on that event. as we have no chance to be notified of this change (which is
2681 // the one we're interested in) we give them time to do what they want to before invalidating our
2682 // bound-field-dependent slots ....
2684 //------------------------------------------------------------------------------
2685 void SbaXDataBrowserController::enterFormAction()
2687 if ( !m_nFormActionNestingLevel )
2688 // first action -> reset
2689 m_aCurrentError.clear();
2691 ++m_nFormActionNestingLevel;
2694 //------------------------------------------------------------------------------
2695 void SbaXDataBrowserController::leaveFormAction()
2697 DBG_ASSERT( m_nFormActionNestingLevel > 0, "SbaXDataBrowserController::leaveFormAction : invalid call !" );
2698 if ( --m_nFormActionNestingLevel > 0 )
2699 return;
2701 if ( !m_aCurrentError.isValid() )
2702 return;
2704 m_aAsyncDisplayError.Call();
2707 // -------------------------------------------------------------------------
2708 sal_Bool SbaXDataBrowserController::isLoaded() const
2710 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::isLoaded" );
2711 return m_xLoadable.is() && m_xLoadable->isLoaded();
2714 // -------------------------------------------------------------------------
2715 sal_Bool SbaXDataBrowserController::isValidCursor() const
2717 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::isValidCursor" );
2718 if (!m_xColumnsSupplier.is())
2719 return sal_False;
2720 Reference< ::com::sun::star::container::XNameAccess > xCols = m_xColumnsSupplier->getColumns();
2721 if (!xCols.is() || !xCols->hasElements())
2722 return sal_False;
2724 sal_Bool bIsValid = !(m_xRowSet->isBeforeFirst() || m_xRowSet->isAfterLast());
2725 if ( !bIsValid )
2727 Reference<XPropertySet> xProp(m_xRowSet,UNO_QUERY);
2728 bIsValid = ::cppu::any2bool(xProp->getPropertyValue(PROPERTY_ISNEW));
2729 if ( !bIsValid )
2731 bIsValid = m_xParser.is();
2733 } // if ( !bIsValid )
2734 return bIsValid;
2737 //==================================================================
2738 // LoadFormHelper
2739 //==================================================================
2741 class LoadFormHelper :public ::cppu::WeakImplHelper2< ::com::sun::star::form::XLoadListener,
2742 XRowSetListener>
2744 enum STATE { STARTED, LOADED, POSITIONED, DISPOSED };
2745 STATE m_eState;
2747 Reference< XRowSet > m_xForm;
2749 ::osl::Mutex m_aAccessSafety;
2751 public:
2752 LoadFormHelper(const Reference< XRowSet > & _rxForm);
2754 // ::com::sun::star::form::XLoadListener
2755 virtual void SAL_CALL loaded(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException );
2756 virtual void SAL_CALL unloaded(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException );
2757 virtual void SAL_CALL unloading(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException );
2758 virtual void SAL_CALL reloading(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException );
2759 virtual void SAL_CALL reloaded(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException );
2761 // XRowSetListener
2762 virtual void SAL_CALL cursorMoved(const ::com::sun::star::lang::EventObject& event) throw( RuntimeException );
2763 virtual void SAL_CALL rowChanged(const ::com::sun::star::lang::EventObject& event) throw( RuntimeException );
2764 virtual void SAL_CALL rowSetChanged(const ::com::sun::star::lang::EventObject& event) throw( RuntimeException );
2766 // ::com::sun::star::lang::XEventListener
2767 virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw( RuntimeException );
2770 bool WaitUntilReallyLoaded(bool _bOnlyIfLoaded);
2771 // waits 'til the first positioned event after the loaded event. returns true if successfull,
2772 // false if the form was disposed or unloaded before or while waiting
2773 // if _bOnlyIfLoaded is false and the form isn't loaded already loaded, false will be returned
2774 // (without any wating)
2776 void cancel();
2778 protected:
2779 ~LoadFormHelper();
2781 void implDispose();
2784 DBG_NAME(LoadFormHelper)
2785 //------------------------------------------------------------------------------
2786 LoadFormHelper::LoadFormHelper(const Reference< XRowSet > & _rxForm)
2787 :m_eState(STARTED)
2788 ,m_xForm(_rxForm)
2790 DBG_CTOR(LoadFormHelper,NULL);
2792 Reference< ::com::sun::star::form::XLoadable > (m_xForm, UNO_QUERY)->addLoadListener(this);
2793 m_xForm->addRowSetListener(this);
2796 //------------------------------------------------------------------------------
2797 LoadFormHelper::~LoadFormHelper()
2799 ::osl::MutexGuard aGuard(m_aAccessSafety);
2800 implDispose();
2802 DBG_DTOR(LoadFormHelper,NULL);
2805 //------------------------------------------------------------------------------
2806 void LoadFormHelper::implDispose()
2808 if (DISPOSED != m_eState)
2811 Reference< ::com::sun::star::form::XLoadable > (m_xForm, UNO_QUERY)->removeLoadListener(this);
2812 m_xForm->removeRowSetListener(this);
2813 m_xForm = NULL;
2814 m_eState = DISPOSED;
2818 //------------------------------------------------------------------------------
2819 void SAL_CALL LoadFormHelper::loaded(const ::com::sun::star::lang::EventObject& /*aEvent*/) throw( RuntimeException )
2821 ::osl::MutexGuard aGuard(m_aAccessSafety);
2822 DBG_ASSERT(m_eState == STARTED || m_eState == DISPOSED, "LoadFormHelper::loaded : wrong call !");
2823 if (m_eState == STARTED)
2824 m_eState = LOADED;
2827 //------------------------------------------------------------------------------
2828 void SAL_CALL LoadFormHelper::unloaded(const ::com::sun::star::lang::EventObject& /*aEvent*/) throw( RuntimeException )
2830 ::osl::MutexGuard aGuard(m_aAccessSafety);
2831 DBG_ERROR("LoadFormHelper::unloaded : shouldn't be called !");
2832 implDispose();
2835 //------------------------------------------------------------------------------
2836 void SAL_CALL LoadFormHelper::unloading(const ::com::sun::star::lang::EventObject& /*aEvent*/) throw( RuntimeException )
2840 //------------------------------------------------------------------------------
2841 void SAL_CALL LoadFormHelper::reloading(const ::com::sun::star::lang::EventObject& /*aEvent*/) throw( RuntimeException )
2845 //------------------------------------------------------------------------------
2846 void SAL_CALL LoadFormHelper::reloaded(const ::com::sun::star::lang::EventObject& /*aEvent*/) throw( RuntimeException )
2850 //------------------------------------------------------------------------------
2851 void SAL_CALL LoadFormHelper::cursorMoved(const ::com::sun::star::lang::EventObject& /*event*/) throw( RuntimeException )
2853 ::osl::MutexGuard aGuard(m_aAccessSafety);
2854 if (m_eState == LOADED)
2855 m_eState = POSITIONED;
2858 //------------------------------------------------------------------------------
2859 void SAL_CALL LoadFormHelper::rowChanged(const ::com::sun::star::lang::EventObject& /*event*/) throw( RuntimeException )
2863 //------------------------------------------------------------------------------
2864 void SAL_CALL LoadFormHelper::rowSetChanged(const ::com::sun::star::lang::EventObject& /*event*/) throw( RuntimeException )
2868 //------------------------------------------------------------------------------
2869 void SAL_CALL LoadFormHelper::disposing(const ::com::sun::star::lang::EventObject& /*Source*/) throw( RuntimeException )
2871 ::osl::MutexGuard aGuard(m_aAccessSafety);
2872 implDispose();
2875 //------------------------------------------------------------------------------
2876 void LoadFormHelper::cancel()
2878 implDispose();
2881 //------------------------------------------------------------------------------
2882 bool LoadFormHelper::WaitUntilReallyLoaded(bool _bOnlyIfLoaded)
2884 ::osl::ResettableMutexGuard aGuard( m_aAccessSafety );
2885 if (DISPOSED == m_eState)
2886 return false;
2888 if (_bOnlyIfLoaded && (STARTED == m_eState))
2889 // we did't get a "loaded" event ....
2890 return false;
2892 sal_Bool bDone = (POSITIONED == m_eState);
2893 aGuard.clear();
2895 while (!bDone)
2897 aGuard.reset();
2898 bDone = (POSITIONED == m_eState);
2899 aGuard.clear();
2902 aGuard.reset();
2903 implDispose();
2905 return true;
2908 //==================================================================
2909 // LoadFormThread - a thread for asynchronously loading a form
2910 //==================================================================
2911 //------------------------------------------------------------------------------
2912 void LoadFormThread::run()
2914 // On instantiation of a SfxCancellable the application is notified and 'switches on' the red stop button.
2915 // Unfortunally this is conditioned with the acquirement of the solar mutex, and the application tries
2916 // only once and ignores the notification if it fails.
2917 // To prevent that we get the solar mutex and _block_ 'til we got it.
2918 // As we are in the 'top level execution' of this thread (with a rather small stack and no other mutexes locked)
2919 // we shouldn't experience problems with deadlocks ...
2920 ::vos::OClearableGuard aSolarGuard(Application::GetSolarMutex());
2921 ThreadStopper* pStopper = new ThreadStopper(this, m_sStopperCaption);
2922 aSolarGuard.clear();
2924 // we're not canceled yet
2925 ::osl::ClearableMutexGuard aResetGuard(m_aAccessSafety);
2926 m_bCanceled = sal_False;
2927 aResetGuard.clear();
2929 LoadFormHelper* pHelper = new LoadFormHelper(m_xRowSet);
2930 pHelper->acquire();
2932 // start it
2933 bool bErrorOccured = false;
2934 Reference< XLoadable > xLoadable(m_xRowSet, UNO_QUERY);
2937 Reference< XRowSet > xMove(m_xRowSet, UNO_QUERY);
2938 DBG_ASSERT(xLoadable.is() && xMove.is(), "LoadFormThread::run : invalid cursor !");
2939 xLoadable->load();
2940 // go to the first record if the load was successfull.
2941 Reference< XColumnsSupplier > xColumnsSupplier(m_xRowSet, UNO_QUERY);
2942 Reference< ::com::sun::star::container::XNameAccess > xCols = xColumnsSupplier.is() ? xColumnsSupplier->getColumns() : Reference< ::com::sun::star::container::XNameAccess > ();
2943 if (xCols.is() && xCols->hasElements())
2944 xMove->first();
2945 else
2946 bErrorOccured = true;
2948 catch(Exception&)
2950 bErrorOccured = true;
2953 // check if we were canceled
2954 ::osl::ClearableMutexGuard aTestGuard(m_aAccessSafety);
2955 bool bReallyCanceled = m_bCanceled ? true : false;;
2956 aTestGuard.clear();
2958 bReallyCanceled |= bErrorOccured;
2960 // the load on the form is "slightly asyncronous" (which isn't covered by it's specification, anyway), so wait
2961 // some time ....
2962 // (though me thinks that the load of the new api is synchronous, so we won't need this LoadFormHelper anymore ...)
2963 if (!bReallyCanceled)
2964 pHelper->WaitUntilReallyLoaded(true);
2966 pHelper->cancel();
2967 pHelper->release();
2969 // yes, we were, but eventually the cancel request didn't reach the data source in time
2970 if (bReallyCanceled && xLoadable.is() && xLoadable->isLoaded())
2971 xLoadable->unload();
2973 pStopper->OwnerTerminated();
2974 // this will cause the stopper to delete itself (in the main thread) so we don't have to take care of the
2975 // solar mutex
2978 //------------------------------------------------------------------------------
2979 void LoadFormThread::onTerminated()
2981 ::osl::ClearableMutexGuard aGuard(m_aAccessSafety);
2982 if (m_aTerminationHandler.IsSet())
2984 // within the call of our termination handler we may be deleted, so do anything which is a member
2985 // access before the call ...
2986 // FS - #69801# - 02.12.99
2987 Link aHandler(m_aTerminationHandler);
2988 aGuard.clear();
2989 aHandler.Call(this);
2991 else
2993 // we are fully responsible for the data source and for ourself, so dispose the former ...
2996 ::comphelper::disposeComponent(m_xRowSet);
2998 m_xRowSet = NULL;
3000 catch(Exception&)
3002 OSL_ENSURE(0,"Exception thrown by dispose");
3004 // ... and delete the latter
3005 aGuard.clear(); // like above - releasing the mutex is a member access ...
3006 delete this;
3010 //------------------------------------------------------------------------------
3011 void LoadFormThread::StopIt()
3013 ::osl::ClearableMutexGuard aResetGuard(m_aAccessSafety);
3014 m_bCanceled = sal_True;
3015 aResetGuard.clear();
3017 Reference< XColumnsSupplier > xColumnsSupplier(m_xRowSet, UNO_QUERY);
3018 if (!xColumnsSupplier.is())
3020 DBG_ERROR("LoadFormThread::StopIt : invalid data source !");
3021 return;
3023 Reference< ::com::sun::star::container::XNameAccess > xCols(xColumnsSupplier->getColumns(), UNO_QUERY);
3024 if (!xCols.is() || !xCols->hasElements())
3025 // the cursor isn't alive, don't need to cancel
3026 return;
3028 Reference< ::com::sun::star::util::XCancellable > xCancel(m_xRowSet, UNO_QUERY);
3029 if (xCancel.is())
3031 try { xCancel->cancel(); } catch(SQLException&) {}
3032 // with this the cursor returns from it's load call, this terminates our run, this get's our termination handler to
3033 // be called
3034 // (the try-catch is just in case the cancel wasn't neccessary anymore)
3038 //------------------------------------------------------------------------------
3039 LoadFormThread::ThreadStopper::ThreadStopper(LoadFormThread* pOwner, const String& rTitle)
3040 :SfxCancellable(SFX_APP()->GetCancelManager(), rTitle)
3041 ,m_pOwner(pOwner)
3045 //------------------------------------------------------------------------------
3046 void LoadFormThread::ThreadStopper::Cancel()
3048 if (!m_pOwner)
3049 return;
3051 ::osl::MutexGuard aGuard(m_pOwner->m_aAccessSafety);
3052 if (IsCancelled())
3053 // we already did pass this to our owner
3054 return;
3056 SfxCancellable::Cancel();
3057 m_pOwner->StopIt();
3060 //------------------------------------------------------------------------------
3061 void LoadFormThread::ThreadStopper::OwnerTerminated()
3063 m_pOwner = NULL;
3064 Application::PostUserEvent(LINK(this, LoadFormThread::ThreadStopper, OnDeleteInMainThread), this);
3067 //------------------------------------------------------------------------------
3068 IMPL_LINK(LoadFormThread::ThreadStopper, OnDeleteInMainThread, LoadFormThread::ThreadStopper*, pThis)
3070 delete pThis;
3071 return 0L;
3073 // -----------------------------------------------------------------------------
3074 sal_Int16 SbaXDataBrowserController::getCurrentColumnPosition()
3076 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::getCurrentColumnPosition" );
3077 Reference< ::com::sun::star::form::XGrid > xGrid(getBrowserView()->getGridControl(), UNO_QUERY);
3078 sal_Int16 nViewPos = -1;
3081 if ( xGrid.is() )
3082 nViewPos = xGrid->getCurrentColumnPosition();
3084 catch(Exception&) {}
3085 return nViewPos;
3087 // -----------------------------------------------------------------------------
3088 void SbaXDataBrowserController::setCurrentColumnPosition( sal_Int16 _nPos )
3090 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::setCurrentColumnPosition" );
3091 Reference< ::com::sun::star::form::XGrid > xGrid(getBrowserView()->getGridControl(), UNO_QUERY);
3094 if ( -1 != _nPos )
3095 xGrid->setCurrentColumnPosition(_nPos);
3097 catch(Exception&) {}
3099 // -----------------------------------------------------------------------------
3100 void SbaXDataBrowserController::BeforeDrop()
3102 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::BeforeDrop" );
3103 Reference< ::com::sun::star::sdb::XSQLErrorBroadcaster > xFormError(getRowSet(), UNO_QUERY);
3104 if (xFormError.is())
3105 xFormError->removeSQLErrorListener((::com::sun::star::sdb::XSQLErrorListener*)this);
3107 // -----------------------------------------------------------------------------
3108 void SbaXDataBrowserController::AfterDrop()
3110 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::AfterDrop" );
3111 Reference< ::com::sun::star::sdb::XSQLErrorBroadcaster > xFormError(getRowSet(), UNO_QUERY);
3112 if (xFormError.is())
3113 xFormError->addSQLErrorListener((::com::sun::star::sdb::XSQLErrorListener*)this);
3115 // -----------------------------------------------------------------------------
3116 void SbaXDataBrowserController::addColumnListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel)
3118 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::addColumnListeners" );
3119 // ... all the grid columns
3120 Reference< ::com::sun::star::container::XIndexContainer > xColumns(_xGridControlModel, UNO_QUERY);
3121 if (xColumns.is())
3123 sal_Int32 nCount = xColumns->getCount();
3124 for (sal_uInt16 i=0; i < nCount; ++i)
3126 Reference< XPropertySet > xCol(xColumns->getByIndex(i),UNO_QUERY);
3127 AddColumnListener(xCol);
3131 // -----------------------------------------------------------------------------
3132 sal_Bool SbaXDataBrowserController::InitializeGridModel(const Reference< ::com::sun::star::form::XFormComponent > & /*xGrid*/)
3134 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::InitializeGridModel" );
3135 return sal_True;
3137 //..................................................................
3138 } // namespace dbaui
3139 //..................................................................