nss: upgrade to release 3.73
[LibreOffice.git] / dbaccess / source / ui / browser / brwctrlr.cxx
blobc2e175020b4e88ce70878b3ce3f513af7d98e857
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <browserids.hxx>
21 #include <brwctrlr.hxx>
22 #include <brwview.hxx>
23 #include <strings.hrc>
24 #include <strings.hxx>
25 #include <core_resource.hxx>
26 #include <queryfilter.hxx>
27 #include <queryorder.hxx>
28 #include <sqlmessage.hxx>
30 #include <com/sun/star/container/XNameContainer.hpp>
31 #include <com/sun/star/form/XBoundControl.hpp>
32 #include <com/sun/star/form/XDatabaseParameterBroadcaster.hpp>
33 #include <com/sun/star/form/XLoadable.hpp>
34 #include <com/sun/star/form/XReset.hpp>
35 #include <com/sun/star/form/XResetListener.hpp>
36 #include <com/sun/star/form/runtime/XFormController.hpp>
37 #include <com/sun/star/form/runtime/FormOperations.hpp>
38 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
39 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
40 #include <com/sun/star/lang/NoSupportException.hpp>
41 #include <com/sun/star/sdb/CommandType.hpp>
42 #include <com/sun/star/sdb/ErrorCondition.hpp>
43 #include <com/sun/star/sdb/ParametersRequest.hpp>
44 #include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
45 #include <com/sun/star/sdb/XSQLErrorBroadcaster.hpp>
46 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
47 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
48 #include <com/sun/star/sdbc/XConnection.hpp>
49 #include <com/sun/star/sdbc/XResultSetUpdate.hpp>
50 #include <com/sun/star/sdbc/XWarningsSupplier.hpp>
51 #include <com/sun/star/sdbcx/Privilege.hpp>
52 #include <com/sun/star/sdbcx/XRowLocate.hpp>
53 #include <com/sun/star/task/InteractionHandler.hpp>
54 #include <com/sun/star/util/NumberFormatter.hpp>
56 #include <comphelper/enumhelper.hxx>
57 #include <comphelper/extract.hxx>
58 #include <comphelper/interaction.hxx>
59 #include <comphelper/sequence.hxx>
60 #include <comphelper/string.hxx>
61 #include <comphelper/types.hxx>
62 #include <connectivity/dbexception.hxx>
63 #include <connectivity/dbtools.hxx>
64 #include <connectivity/sqlerror.hxx>
65 #include <cppuhelper/exc_hlp.hxx>
66 #include <cppuhelper/implbase2.hxx>
67 #include <osl/mutex.hxx>
68 #include <sal/log.hxx>
69 #include <svx/fmsearch.hxx>
70 #include <svx/svxdlg.hxx>
71 #include <tools/diagnose_ex.h>
72 #include <osl/diagnose.h>
73 #include <vcl/svapp.hxx>
74 #include <vcl/weld.hxx>
76 using namespace ::com::sun::star;
77 using namespace ::com::sun::star::uno;
78 using namespace ::com::sun::star::awt;
79 using namespace ::com::sun::star::sdb;
80 using namespace ::com::sun::star::sdbc;
81 using namespace ::com::sun::star::sdbcx;
82 using namespace ::com::sun::star::task;
83 using namespace ::com::sun::star::beans;
84 using namespace ::com::sun::star::frame;
85 using namespace ::com::sun::star::form::runtime;
86 using namespace ::com::sun::star::form;
87 using namespace ::com::sun::star::util;
88 using namespace ::com::sun::star::lang;
89 using namespace ::com::sun::star::container;
90 using namespace ::dbtools;
91 using namespace ::comphelper;
92 using namespace ::svt;
94 #define HANDLE_SQL_ERRORS( action, successflag, context, message ) \
95 try \
96 { \
97 successflag = false; \
98 action; \
99 successflag = true; \
101 catch(SQLException& e) \
103 SQLException aError = ::dbtools::prependErrorInfo(e, *this, context); \
104 css::sdb::SQLErrorEvent aEvent; \
105 aEvent.Reason <<= aError; \
106 errorOccured(aEvent); \
108 catch(Exception&) \
110 DBG_UNHANDLED_EXCEPTION("dbaccess"); \
113 #define DO_SAFE( action, message ) try { action; } catch(Exception&) { SAL_WARN("dbaccess.ui",message); } ;
115 namespace dbaui
118 namespace {
120 // OParameterContinuation
121 class OParameterContinuation : public OInteraction< XInteractionSupplyParameters >
123 Sequence< PropertyValue > m_aValues;
125 public:
126 OParameterContinuation() { }
128 const Sequence< PropertyValue >& getValues() const { return m_aValues; }
130 // XInteractionSupplyParameters
131 virtual void SAL_CALL setParameters( const Sequence< PropertyValue >& _rValues ) override;
136 void SAL_CALL OParameterContinuation::setParameters( const Sequence< PropertyValue >& _rValues )
138 m_aValues = _rValues;
141 // a helper class implementing a runtime::XFormController, will be aggregated by SbaXDataBrowserController
142 // (we can't derive from XFormController as it's base class is XTabController and the XTabController::getModel collides
143 // with the XController::getModel implemented in our base class SbaXDataBrowserController)
144 class SbaXDataBrowserController::FormControllerImpl
145 : public ::cppu::WeakAggImplHelper2< css::form::runtime::XFormController,
146 css::frame::XFrameActionListener >
148 friend class SbaXDataBrowserController;
149 ::comphelper::OInterfaceContainerHelper2 m_aActivateListeners;
150 SbaXDataBrowserController* m_pOwner;
152 public:
153 explicit FormControllerImpl(SbaXDataBrowserController* pOwner);
155 // XFormController
156 virtual css::uno::Reference< css::form::runtime::XFormOperations > SAL_CALL getFormOperations() override;
157 virtual css::uno::Reference< css::awt::XControl > SAL_CALL getCurrentControl() override;
158 virtual void SAL_CALL addActivateListener(const css::uno::Reference< css::form::XFormControllerListener > & l) override;
159 virtual void SAL_CALL removeActivateListener(const css::uno::Reference< css::form::XFormControllerListener > & l) override;
160 virtual void SAL_CALL addChildController( const css::uno::Reference< css::form::runtime::XFormController >& ChildController ) override;
161 virtual css::uno::Reference< css::form::runtime::XFormControllerContext > SAL_CALL getContext() override;
162 virtual void SAL_CALL setContext( const css::uno::Reference< css::form::runtime::XFormControllerContext >& _context ) override;
163 virtual css::uno::Reference< css::task::XInteractionHandler > SAL_CALL getInteractionHandler() override;
164 virtual void SAL_CALL setInteractionHandler( const css::uno::Reference< css::task::XInteractionHandler >& _interactionHandler ) override;
166 // XChild, base of XFormController
167 virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent( ) override;
168 virtual void SAL_CALL setParent( const css::uno::Reference< css::uno::XInterface >& Parent ) override;
170 // XComponent, base of XFormController
171 virtual void SAL_CALL dispose( ) override;
172 virtual void SAL_CALL addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) override;
173 virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener ) override;
175 // XIndexAccess, base of XFormController
176 virtual ::sal_Int32 SAL_CALL getCount( ) override;
177 virtual css::uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override;
179 // XElementAccess, base of XIndexAccess
180 virtual css::uno::Type SAL_CALL getElementType( ) override;
181 virtual sal_Bool SAL_CALL hasElements( ) override;
183 // XEnumerationAccess, base of XElementAccess
184 virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration( ) override;
186 // XModifyBroadcaster, base of XFormController
187 virtual void SAL_CALL addModifyListener( const css::uno::Reference< css::util::XModifyListener >& aListener ) override;
188 virtual void SAL_CALL removeModifyListener( const css::uno::Reference< css::util::XModifyListener >& aListener ) override;
190 // XConfirmDeleteBroadcaster, base of XFormController
191 virtual void SAL_CALL addConfirmDeleteListener( const css::uno::Reference< css::form::XConfirmDeleteListener >& aListener ) override;
192 virtual void SAL_CALL removeConfirmDeleteListener( const css::uno::Reference< css::form::XConfirmDeleteListener >& aListener ) override;
194 // XSQLErrorBroadcaster, base of XFormController
195 virtual void SAL_CALL addSQLErrorListener( const css::uno::Reference< css::sdb::XSQLErrorListener >& Listener ) override;
196 virtual void SAL_CALL removeSQLErrorListener( const css::uno::Reference< css::sdb::XSQLErrorListener >& Listener ) override;
198 // XRowSetApproveBroadcaster, base of XFormController
199 virtual void SAL_CALL addRowSetApproveListener( const css::uno::Reference< css::sdb::XRowSetApproveListener >& listener ) override;
200 virtual void SAL_CALL removeRowSetApproveListener( const css::uno::Reference< css::sdb::XRowSetApproveListener >& listener ) override;
202 // XDatabaseParameterBroadcaster2, base of XFormController
203 virtual void SAL_CALL addDatabaseParameterListener( const css::uno::Reference< css::form::XDatabaseParameterListener >& aListener ) override;
204 virtual void SAL_CALL removeDatabaseParameterListener( const css::uno::Reference< css::form::XDatabaseParameterListener >& aListener ) override;
206 // XDatabaseParameterBroadcaster, base of XDatabaseParameterBroadcaster2
207 virtual void SAL_CALL addParameterListener( const css::uno::Reference< css::form::XDatabaseParameterListener >& aListener ) override;
208 virtual void SAL_CALL removeParameterListener( const css::uno::Reference< css::form::XDatabaseParameterListener >& aListener ) override;
210 // XModeSelector, base of XFormController
211 virtual void SAL_CALL setMode( const OUString& aMode ) override;
212 virtual OUString SAL_CALL getMode( ) override;
213 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedModes( ) override;
214 virtual sal_Bool SAL_CALL supportsMode( const OUString& aMode ) override;
216 // XTabController, base of XFormController
217 virtual void SAL_CALL setModel(const css::uno::Reference< css::awt::XTabControllerModel > & Model) override;
218 virtual css::uno::Reference< css::awt::XTabControllerModel > SAL_CALL getModel() override;
219 virtual void SAL_CALL setContainer(const css::uno::Reference< css::awt::XControlContainer > & Container) override;
220 virtual css::uno::Reference< css::awt::XControlContainer > SAL_CALL getContainer() override;
221 virtual css::uno::Sequence< css::uno::Reference< css::awt::XControl > > SAL_CALL getControls() override;
222 virtual void SAL_CALL autoTabOrder() override;
223 virtual void SAL_CALL activateTabOrder() override;
224 virtual void SAL_CALL activateFirst() override;
225 virtual void SAL_CALL activateLast() override;
227 // XFrameActionListener
228 virtual void SAL_CALL frameAction(const css::frame::FrameActionEvent& aEvent) override;
230 // XEventListener
231 virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override;
233 protected:
234 virtual ~FormControllerImpl() override;
237 SbaXDataBrowserController::FormControllerImpl::FormControllerImpl(SbaXDataBrowserController* _pOwner)
238 :m_aActivateListeners(_pOwner->getMutex())
239 ,m_pOwner(_pOwner)
242 OSL_ENSURE(m_pOwner, "SbaXDataBrowserController::FormControllerImpl::FormControllerImpl : invalid Owner !");
245 SbaXDataBrowserController::FormControllerImpl::~FormControllerImpl()
250 Reference< runtime::XFormOperations > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getFormOperations()
252 return FormOperations::createWithFormController( m_pOwner->m_xContext, this );
255 Reference< css::awt::XControl > SbaXDataBrowserController::FormControllerImpl::getCurrentControl()
257 return m_pOwner->getBrowserView() ? m_pOwner->getBrowserView()->getGridControl() : Reference< css::awt::XControl > ();
260 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addActivateListener(const Reference< css::form::XFormControllerListener > & l)
262 m_aActivateListeners.addInterface(l);
265 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeActivateListener(const Reference< css::form::XFormControllerListener > & l)
267 m_aActivateListeners.removeInterface(l);
270 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addChildController( const Reference< runtime::XFormController >& )
272 // not supported
273 throw IllegalArgumentException( OUString(), *this, 1 );
276 Reference< runtime::XFormControllerContext > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getContext()
278 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::getContext: no support!!" );
279 return nullptr;
282 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setContext( const Reference< runtime::XFormControllerContext >& /*_context*/ )
284 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::setContext: no support!!" );
287 Reference< XInteractionHandler > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getInteractionHandler()
289 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::getInteractionHandler: no support!!" );
290 return nullptr;
293 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setInteractionHandler( const Reference< XInteractionHandler >& /*_interactionHandler*/ )
295 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::setInteractionHandler: no support!!" );
298 Reference< XInterface > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getParent( )
300 // don't have any parent form controllers
301 return nullptr;
304 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setParent( const Reference< XInterface >& /*Parent*/ )
306 throw NoSupportException( OUString(), *this );
309 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::dispose( )
311 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::dispose: no, you do *not* want to do this!" );
314 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addEventListener( const Reference< XEventListener >& /*xListener*/ )
316 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::addEventListener: no support!!" );
319 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeEventListener( const Reference< XEventListener >& /*aListener*/ )
321 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::removeEventListener: no support!!" );
324 ::sal_Int32 SAL_CALL SbaXDataBrowserController::FormControllerImpl::getCount( )
326 // no sub controllers, never
327 return 0;
330 Any SAL_CALL SbaXDataBrowserController::FormControllerImpl::getByIndex( ::sal_Int32 /*Index*/ )
332 // no sub controllers, never
333 throw IndexOutOfBoundsException( OUString(), *this );
336 Type SAL_CALL SbaXDataBrowserController::FormControllerImpl::getElementType( )
338 return ::cppu::UnoType< runtime::XFormController >::get();
341 sal_Bool SAL_CALL SbaXDataBrowserController::FormControllerImpl::hasElements( )
343 // no sub controllers, never
344 return false;
347 Reference< XEnumeration > SAL_CALL SbaXDataBrowserController::FormControllerImpl::createEnumeration( )
349 return new ::comphelper::OEnumerationByIndex( this );
352 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addModifyListener( const Reference< XModifyListener >& /*_Listener*/ )
354 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::addModifyListener: no support!" );
357 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeModifyListener( const Reference< XModifyListener >& /*_Listener*/ )
359 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::removeModifyListener: no support!" );
362 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addConfirmDeleteListener( const Reference< XConfirmDeleteListener >& /*_Listener*/ )
364 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::addConfirmDeleteListener: no support!" );
367 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeConfirmDeleteListener( const Reference< XConfirmDeleteListener >& /*_Listener*/ )
369 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::removeConfirmDeleteListener: no support!" );
372 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addSQLErrorListener( const Reference< XSQLErrorListener >& /*_Listener*/ )
374 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::addSQLErrorListener: no support!" );
377 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeSQLErrorListener( const Reference< XSQLErrorListener >& /*_Listener*/ )
379 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::removeSQLErrorListener: no support!" );
382 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addRowSetApproveListener( const Reference< XRowSetApproveListener >& /*_Listener*/ )
384 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::addRowSetApproveListener: no support!" );
387 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeRowSetApproveListener( const Reference< XRowSetApproveListener >& /*_Listener*/ )
389 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::removeRowSetApproveListener: no support!" );
392 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addDatabaseParameterListener( const Reference< XDatabaseParameterListener >& /*_Listener*/ )
394 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::addDatabaseParameterListener: no support!" );
397 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeDatabaseParameterListener( const Reference< XDatabaseParameterListener >& /*_Listener*/ )
399 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::removeDatabaseParameterListener: no support!" );
402 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addParameterListener( const Reference< XDatabaseParameterListener >& /*_Listener*/ )
404 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::addParameterListener: no support!" );
407 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeParameterListener( const Reference< XDatabaseParameterListener >& /*_Listener*/ )
409 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::FormControllerImpl::removeParameterListener: no support!" );
412 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setMode( const OUString& _rMode )
414 if ( !supportsMode( _rMode ) )
415 throw NoSupportException();
418 OUString SAL_CALL SbaXDataBrowserController::FormControllerImpl::getMode( )
420 return "DataMode";
423 Sequence< OUString > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getSupportedModes( )
425 Sequence< OUString > aModes { "DataMode" };
426 return aModes;
429 sal_Bool SAL_CALL SbaXDataBrowserController::FormControllerImpl::supportsMode( const OUString& aMode )
431 return aMode == "DataMode";
434 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setModel(const Reference< css::awt::XTabControllerModel > & /*Model*/)
436 SAL_WARN("dbaccess.ui","SbaXDataBrowserController::FormControllerImpl::setModel : invalid call, can't change my model !");
439 Reference< css::awt::XTabControllerModel > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getModel()
441 return Reference< XTabControllerModel >(m_pOwner->getRowSet(), UNO_QUERY);
444 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setContainer(const Reference< css::awt::XControlContainer > &)
446 SAL_WARN("dbaccess.ui","SbaXDataBrowserController::FormControllerImpl::setContainer : invalid call, can't change my container !");
449 Reference< css::awt::XControlContainer > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getContainer()
451 if (m_pOwner->getBrowserView())
452 return m_pOwner->getBrowserView()->getContainer();
453 return Reference< css::awt::XControlContainer > ();
456 Sequence< Reference< css::awt::XControl > > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getControls()
458 if (m_pOwner->getBrowserView())
460 Reference< css::awt::XControl > xGrid = m_pOwner->getBrowserView()->getGridControl();
461 return Sequence< Reference< css::awt::XControl > >(&xGrid, 1);
463 return Sequence< Reference< css::awt::XControl > >();
466 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::autoTabOrder()
468 SAL_WARN("dbaccess.ui","SbaXDataBrowserController::FormControllerImpl::autoTabOrder : nothing to do (always have only one control) !");
471 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::activateTabOrder()
473 SAL_WARN("dbaccess.ui","SbaXDataBrowserController::FormControllerImpl::activateTabOrder : nothing to do (always have only one control) !");
476 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::activateFirst()
478 if (m_pOwner->getBrowserView())
479 m_pOwner->getBrowserView()->getVclControl()->ActivateCell();
482 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::activateLast()
484 if (m_pOwner->getBrowserView())
485 m_pOwner->getBrowserView()->getVclControl()->ActivateCell();
488 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::frameAction(const css::frame::FrameActionEvent& /*aEvent*/)
492 void SAL_CALL SbaXDataBrowserController::FormControllerImpl::disposing(const css::lang::EventObject& /*Source*/)
494 // nothing to do
495 // we don't add ourself as listener to any broadcasters, so we are not responsible for removing us
498 // SbaXDataBrowserController
499 Sequence< Type > SAL_CALL SbaXDataBrowserController::getTypes( )
501 return ::comphelper::concatSequences(
502 SbaXDataBrowserController_Base::getTypes(),
503 m_pFormControllerImpl->getTypes()
507 Sequence< sal_Int8 > SAL_CALL SbaXDataBrowserController::getImplementationId( )
509 return css::uno::Sequence<sal_Int8>();
512 Any SAL_CALL SbaXDataBrowserController::queryInterface(const Type& _rType)
514 // check for our additional interfaces
515 Any aRet = SbaXDataBrowserController_Base::queryInterface(_rType);
517 // check for our aggregate (implementing the XFormController)
518 if (!aRet.hasValue())
519 aRet = m_xFormControllerImpl->queryAggregation(_rType);
521 // no more to offer
522 return aRet;
525 SbaXDataBrowserController::SbaXDataBrowserController(const Reference< css::uno::XComponentContext >& _rM)
526 :SbaXDataBrowserController_Base(_rM)
527 ,m_nRowSetPrivileges(0)
528 ,m_aAsyncGetCellFocus(LINK(this, SbaXDataBrowserController, OnAsyncGetCellFocus))
529 ,m_aAsyncDisplayError( LINK( this, SbaXDataBrowserController, OnAsyncDisplayError ) )
530 ,m_sStateSaveRecord(DBA_RES(RID_STR_SAVE_CURRENT_RECORD))
531 ,m_sStateUndoRecord(DBA_RES(RID_STR_UNDO_MODIFY_RECORD))
532 ,m_sModuleIdentifier( OUString( "com.sun.star.sdb.DataSourceBrowser" ) )
533 ,m_pFormControllerImpl(nullptr)
534 ,m_nFormActionNestingLevel(0)
535 ,m_bLoadCanceled( false )
536 ,m_bCannotSelectUnfiltered( true )
538 // create the form controller aggregate
539 osl_atomic_increment(&m_refCount);
541 m_pFormControllerImpl = new FormControllerImpl(this);
542 m_xFormControllerImpl = m_pFormControllerImpl;
543 m_xFormControllerImpl->setDelegator(*this);
545 osl_atomic_decrement(&m_refCount);
547 m_aInvalidateClipboard.SetDebugName("dbaui::SbaXDataBrowserController m_aInvalidateClipboard");
548 m_aInvalidateClipboard.SetInvokeHandler(LINK(this, SbaXDataBrowserController, OnInvalidateClipboard));
549 m_aInvalidateClipboard.SetTimeout(300);
552 SbaXDataBrowserController::~SbaXDataBrowserController()
554 // deleteView();
555 // release the aggregated form controller
556 if (m_xFormControllerImpl.is())
558 Reference< XInterface > xEmpty;
559 m_xFormControllerImpl->setDelegator(xEmpty);
564 void SbaXDataBrowserController::startFrameListening( const Reference< XFrame >& _rxFrame )
566 SbaXDataBrowserController_Base::startFrameListening( _rxFrame );
568 Reference< XFrameActionListener > xAggListener;
569 if ( m_xFormControllerImpl.is() )
570 m_xFormControllerImpl->queryAggregation( cppu::UnoType<XFrameActionListener>::get() ) >>= xAggListener;
572 if ( _rxFrame.is() && xAggListener.is() )
573 _rxFrame->addFrameActionListener( xAggListener );
576 void SbaXDataBrowserController::stopFrameListening( const Reference< XFrame >& _rxFrame )
578 SbaXDataBrowserController_Base::stopFrameListening( _rxFrame );
580 Reference< XFrameActionListener > xAggListener;
581 if ( m_xFormControllerImpl.is() )
582 m_xFormControllerImpl->queryAggregation( cppu::UnoType<XFrameActionListener>::get() ) >>= xAggListener;
584 if ( _rxFrame.is() && xAggListener.is() )
585 _rxFrame->removeFrameActionListener( xAggListener );
588 void SbaXDataBrowserController::onStartLoading( const Reference< XLoadable >& _rxLoadable )
590 m_bLoadCanceled = false;
591 m_bCannotSelectUnfiltered = false;
593 Reference< XWarningsSupplier > xWarnings( _rxLoadable, UNO_QUERY );
594 if ( xWarnings.is() )
598 xWarnings->clearWarnings();
600 catch(const SQLException& )
602 DBG_UNHANDLED_EXCEPTION("dbaccess");
607 void SbaXDataBrowserController::impl_checkForCannotSelectUnfiltered( const SQLExceptionInfo& _rError )
609 ::connectivity::ErrorCode nErrorCode( connectivity::SQLError::getErrorCode( sdb::ErrorCondition::DATA_CANNOT_SELECT_UNFILTERED ) );
610 if ( static_cast<const SQLException*>(_rError)->ErrorCode == nErrorCode )
612 m_bCannotSelectUnfiltered = true;
613 InvalidateFeature( ID_BROWSER_FILTERCRIT );
617 bool SbaXDataBrowserController::reloadForm( const Reference< XLoadable >& _rxLoadable )
619 weld::WaitObject aWO(getFrameWeld());
621 onStartLoading( _rxLoadable );
623 FormErrorHelper aReportError(this);
624 if (_rxLoadable->isLoaded())
625 _rxLoadable->reload();
626 else
627 _rxLoadable->load();
629 m_xParser.clear();
630 const Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
631 if (::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)))
632 xFormSet->getPropertyValue(PROPERTY_SINGLESELECTQUERYCOMPOSER) >>= m_xParser;
633 #if 0
635 const Reference< XPropertySet > xRowSetProps( getRowSet(), UNO_QUERY );
636 const Reference< XSingleSelectQueryAnalyzer > xAnalyzer( xRowSetProps->getPropertyValue( PROPERTY_SINGLESELECTQUERYCOMPOSER ), UNO_QUERY );
637 if ( xAnalyzer.is() )
639 const Reference< XIndexAccess > xOrderColumns( xAnalyzer->getOrderColumns(), UNO_SET_THROW );
640 const sal_Int32 nOrderColumns( xOrderColumns->getCount() );
641 for ( sal_Int32 c=0; c<nOrderColumns; ++c )
643 const Reference< XPropertySet > xOrderColumn( xOrderColumns->getByIndex(c), UNO_QUERY_THROW );
644 OUString sColumnName;
645 OSL_VERIFY( xOrderColumn->getPropertyValue( PROPERTY_NAME ) >>= sColumnName);
646 OUString sTableName;
647 OSL_VERIFY( xOrderColumn->getPropertyValue( PROPERTY_TABLENAME ) >>= sTableName);
648 (void)sColumnName;
649 (void)sTableName;
653 #endif
655 Reference< XWarningsSupplier > xWarnings( _rxLoadable, UNO_QUERY );
656 if ( xWarnings.is() )
660 SQLExceptionInfo aInfo( xWarnings->getWarnings() );
661 if ( aInfo.isValid() )
663 showError( aInfo );
664 impl_checkForCannotSelectUnfiltered( aInfo );
667 catch(const SQLException& )
669 DBG_UNHANDLED_EXCEPTION("dbaccess");
673 return _rxLoadable->isLoaded();
676 void SbaXDataBrowserController::initFormatter()
678 // create a formatter working with the connections format supplier
679 Reference< css::util::XNumberFormatsSupplier > xSupplier(::dbtools::getNumberFormats(::dbtools::getConnection(m_xRowSet), true, getORB()));
681 if(xSupplier.is())
683 // create a new formatter
684 m_xFormatter.set(util::NumberFormatter::create(getORB()), UNO_QUERY_THROW);
685 m_xFormatter->attachNumberFormatsSupplier(xSupplier);
687 else // clear the formatter
688 m_xFormatter = nullptr;
691 void SbaXDataBrowserController::describeSupportedFeatures()
693 SbaXDataBrowserController_Base::describeSupportedFeatures();
694 implDescribeSupportedFeature( ".uno:FormSlots/undoRecord", ID_BROWSER_UNDORECORD, CommandGroup::CONTROLS );
695 implDescribeSupportedFeature( ".uno:FormController/undoRecord", ID_BROWSER_UNDORECORD, CommandGroup::CONTROLS );
696 implDescribeSupportedFeature( ".uno:RecUndo", ID_BROWSER_UNDORECORD, CommandGroup::CONTROLS );
697 implDescribeSupportedFeature( ".uno:FormSlots/saveRecord", ID_BROWSER_SAVERECORD, CommandGroup::CONTROLS );
698 implDescribeSupportedFeature( ".uno:FormController/saveRecord", ID_BROWSER_SAVERECORD, CommandGroup::CONTROLS );
699 implDescribeSupportedFeature( ".uno:RecSave", ID_BROWSER_SAVERECORD, CommandGroup::CONTROLS );
700 implDescribeSupportedFeature( ".uno:Save", ID_BROWSER_SAVERECORD, CommandGroup::DOCUMENT );
701 implDescribeSupportedFeature( ".uno:RecSearch", SID_FM_SEARCH, CommandGroup::CONTROLS );
702 implDescribeSupportedFeature( ".uno:AutoFilter", SID_FM_AUTOFILTER, CommandGroup::CONTROLS );
703 implDescribeSupportedFeature( ".uno:Refresh", SID_FM_REFRESH, CommandGroup::CONTROLS );
704 implDescribeSupportedFeature( ".uno:OrderCrit", SID_FM_ORDERCRIT, CommandGroup::CONTROLS );
705 implDescribeSupportedFeature( ".uno:RemoveFilterSort", SID_FM_REMOVE_FILTER_SORT,CommandGroup::CONTROLS );
706 implDescribeSupportedFeature( ".uno:FormFiltered", SID_FM_FORM_FILTERED, CommandGroup::CONTROLS );
707 implDescribeSupportedFeature( ".uno:FilterCrit", SID_FM_FILTERCRIT, CommandGroup::CONTROLS );
708 implDescribeSupportedFeature( ".uno:Sortup", ID_BROWSER_SORTUP, CommandGroup::CONTROLS );
709 implDescribeSupportedFeature( ".uno:SortDown", ID_BROWSER_SORTDOWN, CommandGroup::CONTROLS );
710 implDescribeSupportedFeature( ".uno:FormSlots/deleteRecord", SID_FM_DELETEROWS, CommandGroup::EDIT );
711 implDescribeSupportedFeature( ".uno:FormSlots/insertRecord", ID_BROWSER_INSERT_ROW, CommandGroup::INSERT );
714 bool SbaXDataBrowserController::Construct(vcl::Window* pParent)
716 // create/initialize the form and the grid model
717 m_xRowSet = CreateForm();
718 if (!m_xRowSet.is())
719 return false;
721 m_xColumnsSupplier.set(m_xRowSet,UNO_QUERY);
722 m_xLoadable.set(m_xRowSet,UNO_QUERY);
724 Reference< XPropertySet > xFormProperties( m_xRowSet, UNO_QUERY );
725 if ( !InitializeForm( xFormProperties ) )
726 return false;
728 m_xGridModel = CreateGridModel();
729 if (!m_xGridModel.is())
730 return false;
732 // set the formatter if available
733 initFormatter();
735 // we want to have a grid with a "flat" border
736 Reference< XPropertySet > xGridSet(m_xGridModel, UNO_QUERY);
737 if ( xGridSet.is() )
738 xGridSet->setPropertyValue(PROPERTY_BORDER, makeAny(sal_Int16(2)));
741 // marry them
742 Reference< css::container::XNameContainer > xNameCont(m_xRowSet, UNO_QUERY);
744 OUString sText(DBA_RES(STR_DATASOURCE_GRIDCONTROL_NAME));
745 xNameCont->insertByName(sText, makeAny(m_xGridModel));
748 // create the view
749 setView( VclPtr<UnoDataBrowserView>::Create( pParent, *this, getORB() ) );
750 if (!getBrowserView())
751 return false;
753 // late construction
754 bool bSuccess = false;
757 getBrowserView()->Construct(getControlModel());
758 bSuccess = true;
760 catch(SQLException&)
763 catch(Exception&)
765 SAL_WARN("dbaccess.ui","SbaXDataBrowserController::Construct : the construction of UnoDataBrowserView failed !");
768 if (!bSuccess)
770 // deleteView();
771 return false;
774 // now that we have a view we can create the clipboard listener
775 m_aSystemClipboard = TransferableDataHelper::CreateFromSystemClipboard( getView() );
776 m_aSystemClipboard.StartClipboardListening( );
778 m_pClipboardNotifier = new TransferableClipboardListener( LINK( this, SbaXDataBrowserController, OnClipboardChanged ) );
779 m_pClipboardNotifier->AddListener( getView() );
781 // this call create the toolbox
782 SbaXDataBrowserController_Base::Construct(pParent);
784 getBrowserView()->Show();
786 // set the callbacks for the grid control
787 SbaGridControl* pVclGrid = getBrowserView()->getVclControl();
788 OSL_ENSURE(pVclGrid, "SbaXDataBrowserController::Construct : have no VCL control !");
789 pVclGrid->SetMasterListener(this);
791 // add listeners...
793 // ... to the form model
794 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
795 if (xFormSet.is())
797 xFormSet->addPropertyChangeListener(PROPERTY_ISNEW, static_cast<XPropertyChangeListener*>(this));
798 xFormSet->addPropertyChangeListener(PROPERTY_ISMODIFIED, static_cast<XPropertyChangeListener*>(this));
799 xFormSet->addPropertyChangeListener(PROPERTY_ROWCOUNT, static_cast<XPropertyChangeListener*>(this));
800 xFormSet->addPropertyChangeListener(PROPERTY_ACTIVECOMMAND, static_cast<XPropertyChangeListener*>(this));
801 xFormSet->addPropertyChangeListener(PROPERTY_ORDER, static_cast<XPropertyChangeListener*>(this));
802 xFormSet->addPropertyChangeListener(PROPERTY_FILTER, static_cast<XPropertyChangeListener*>(this));
803 xFormSet->addPropertyChangeListener(PROPERTY_HAVING_CLAUSE, static_cast<XPropertyChangeListener*>(this));
804 xFormSet->addPropertyChangeListener(PROPERTY_APPLYFILTER, static_cast<XPropertyChangeListener*>(this));
806 Reference< css::sdb::XSQLErrorBroadcaster > xFormError(getRowSet(), UNO_QUERY);
807 if (xFormError.is())
808 xFormError->addSQLErrorListener(static_cast<css::sdb::XSQLErrorListener*>(this));
810 if (m_xLoadable.is())
811 m_xLoadable->addLoadListener(this);
813 Reference< css::form::XDatabaseParameterBroadcaster > xFormParameter(getRowSet(), UNO_QUERY);
814 if (xFormParameter.is())
815 xFormParameter->addParameterListener(static_cast<css::form::XDatabaseParameterListener*>(this));
817 addModelListeners(getControlModel());
818 addControlListeners(getBrowserView()->getGridControl());
820 // load the form
821 return LoadForm();
824 bool SbaXDataBrowserController::LoadForm()
826 reloadForm( m_xLoadable );
827 return true;
830 void SbaXDataBrowserController::AddColumnListener(const Reference< XPropertySet > & /*xCol*/)
832 // we're not interested in any column properties...
835 void SbaXDataBrowserController::RemoveColumnListener(const Reference< XPropertySet > & /*xCol*/)
839 Reference< XRowSet > SbaXDataBrowserController::CreateForm()
841 return Reference< XRowSet > (
842 getORB()->getServiceManager()->createInstanceWithContext("com.sun.star.form.component.Form", getORB()),
843 UNO_QUERY);
846 Reference< css::form::XFormComponent > SbaXDataBrowserController::CreateGridModel()
848 return Reference< css::form::XFormComponent > (
849 getORB()->getServiceManager()->createInstanceWithContext("com.sun.star.form.component.GridControl", getORB()),
850 UNO_QUERY);
853 void SbaXDataBrowserController::addModelListeners(const Reference< css::awt::XControlModel > & _xGridControlModel)
855 // ... all the grid columns
856 addColumnListeners(_xGridControlModel);
858 // (we are interested in all columns the grid has (and only in these) so we have to listen to the container, too)
859 Reference< css::container::XContainer > xColContainer(_xGridControlModel, UNO_QUERY);
860 if (xColContainer.is())
861 xColContainer->addContainerListener(static_cast<css::container::XContainerListener*>(this));
863 Reference< css::form::XReset > xReset(_xGridControlModel, UNO_QUERY);
864 if (xReset.is())
865 xReset->addResetListener(static_cast<css::form::XResetListener*>(this));
868 void SbaXDataBrowserController::removeModelListeners(const Reference< XControlModel > & _xGridControlModel)
870 // every single column model
871 Reference< XIndexContainer > xColumns(_xGridControlModel, UNO_QUERY);
872 if (xColumns.is())
874 sal_Int32 nCount = xColumns->getCount();
875 for (sal_Int32 i=0; i < nCount; ++i)
877 Reference< XPropertySet > xCol(xColumns->getByIndex(i),UNO_QUERY);
878 RemoveColumnListener(xCol);
882 Reference< XContainer > xColContainer(_xGridControlModel, UNO_QUERY);
883 if (xColContainer.is())
884 xColContainer->removeContainerListener( this );
886 Reference< XReset > xReset(_xGridControlModel, UNO_QUERY);
887 if (xReset.is())
888 xReset->removeResetListener( this );
891 void SbaXDataBrowserController::addControlListeners(const Reference< css::awt::XControl > & _xGridControl)
893 // to ge the 'modified' for the current cell
894 Reference< XModifyBroadcaster > xBroadcaster(getBrowserView()->getGridControl(), UNO_QUERY);
895 if (xBroadcaster.is())
896 xBroadcaster->addModifyListener(static_cast<XModifyListener*>(this));
898 // introduce ourself as dispatch provider for the grid
899 Reference< XDispatchProviderInterception > xInterception(getBrowserView()->getGridControl(), UNO_QUERY);
900 if (xInterception.is())
901 xInterception->registerDispatchProviderInterceptor(static_cast<XDispatchProviderInterceptor*>(this));
903 // add as focus listener to the control (needed for the form controller functionality)
904 Reference< XWindow > xWindow(_xGridControl, UNO_QUERY);
905 if (xWindow.is())
906 xWindow->addFocusListener(this);
909 void SbaXDataBrowserController::removeControlListeners(const Reference< css::awt::XControl > & _xGridControl)
911 Reference< XModifyBroadcaster > xBroadcaster(_xGridControl, UNO_QUERY);
912 if (xBroadcaster.is())
913 xBroadcaster->removeModifyListener(static_cast<XModifyListener*>(this));
915 Reference< XDispatchProviderInterception > xInterception(_xGridControl, UNO_QUERY);
916 if (xInterception.is())
917 xInterception->releaseDispatchProviderInterceptor(static_cast<XDispatchProviderInterceptor*>(this));
919 Reference< XWindow > xWindow(_xGridControl, UNO_QUERY);
920 if (xWindow.is())
921 xWindow->removeFocusListener(this);
924 void SAL_CALL SbaXDataBrowserController::focusGained(const FocusEvent& /*e*/)
926 // notify our activate listeners (registered on the form controller aggregate)
927 EventObject aEvt(*this);
928 ::comphelper::OInterfaceIteratorHelper2 aIter(m_pFormControllerImpl->m_aActivateListeners);
929 while (aIter.hasMoreElements())
930 static_cast<XFormControllerListener*>(aIter.next())->formActivated(aEvt);
933 void SAL_CALL SbaXDataBrowserController::focusLost(const FocusEvent& e)
935 // some general checks
936 if (!getBrowserView() || !getBrowserView()->getGridControl().is())
937 return;
938 Reference< XVclWindowPeer > xMyGridPeer(getBrowserView()->getGridControl()->getPeer(), UNO_QUERY);
939 if (!xMyGridPeer.is())
940 return;
941 Reference< XWindowPeer > xNextControlPeer(e.NextFocus, UNO_QUERY);
942 if (!xNextControlPeer.is())
943 return;
945 // don't do a notification if it remains in the family (i.e. a child of the grid control gets the focus)
946 if (xMyGridPeer->isChild(xNextControlPeer))
947 return;
949 if (xMyGridPeer == xNextControlPeer)
950 return;
952 // notify the listeners that the "form" we represent has been deactivated
953 EventObject aEvt(*this);
954 ::comphelper::OInterfaceIteratorHelper2 aIter(m_pFormControllerImpl->m_aActivateListeners);
955 while (aIter.hasMoreElements())
956 static_cast<XFormControllerListener*>(aIter.next())->formDeactivated(aEvt);
958 // commit the changes of the grid control (as we're deactivated)
959 Reference< XBoundComponent > xCommitable(getBrowserView()->getGridControl(), UNO_QUERY);
960 if (xCommitable.is())
961 xCommitable->commit();
962 else
963 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::focusLost : why is my control not committable?");
966 void SbaXDataBrowserController::disposingFormModel(const css::lang::EventObject& Source)
968 Reference< XPropertySet > xSourceSet(Source.Source, UNO_QUERY);
969 if (xSourceSet.is())
971 xSourceSet->removePropertyChangeListener(PROPERTY_ISNEW, static_cast<XPropertyChangeListener*>(this));
972 xSourceSet->removePropertyChangeListener(PROPERTY_ISMODIFIED, static_cast<XPropertyChangeListener*>(this));
973 xSourceSet->removePropertyChangeListener(PROPERTY_ROWCOUNT, static_cast<XPropertyChangeListener*>(this));
974 xSourceSet->removePropertyChangeListener(PROPERTY_ACTIVECOMMAND, static_cast<XPropertyChangeListener*>(this));
975 xSourceSet->removePropertyChangeListener(PROPERTY_ORDER, static_cast<XPropertyChangeListener*>(this));
976 xSourceSet->removePropertyChangeListener(PROPERTY_FILTER, static_cast<XPropertyChangeListener*>(this));
977 xSourceSet->removePropertyChangeListener(PROPERTY_HAVING_CLAUSE, static_cast<XPropertyChangeListener*>(this));
978 xSourceSet->removePropertyChangeListener(PROPERTY_APPLYFILTER, static_cast<XPropertyChangeListener*>(this));
981 Reference< css::sdb::XSQLErrorBroadcaster > xFormError(Source.Source, UNO_QUERY);
982 if (xFormError.is())
983 xFormError->removeSQLErrorListener(static_cast<css::sdb::XSQLErrorListener*>(this));
985 if (m_xLoadable.is())
986 m_xLoadable->removeLoadListener(this);
988 Reference< css::form::XDatabaseParameterBroadcaster > xFormParameter(Source.Source, UNO_QUERY);
989 if (xFormParameter.is())
990 xFormParameter->removeParameterListener(static_cast<css::form::XDatabaseParameterListener*>(this));
993 void SbaXDataBrowserController::disposingColumnModel(const css::lang::EventObject& Source)
995 RemoveColumnListener(Reference< XPropertySet > (Source.Source, UNO_QUERY));
998 void SbaXDataBrowserController::disposing(const EventObject& Source)
1000 // if it's a component other than our aggregate, forward it to the aggregate
1001 if ( m_xFormControllerImpl != Source.Source )
1003 Reference< XEventListener > xAggListener;
1004 m_xFormControllerImpl->queryAggregation( cppu::UnoType<decltype(xAggListener)>::get() ) >>= xAggListener;
1005 if ( xAggListener.is( ))
1006 xAggListener->disposing( Source );
1009 // is it the grid control ?
1010 if (getBrowserView())
1012 Reference< css::awt::XControl > xSourceControl(Source.Source, UNO_QUERY);
1013 if (xSourceControl == getBrowserView()->getGridControl())
1014 removeControlListeners(getBrowserView()->getGridControl());
1017 // its model (the container of the columns) ?
1018 if (getControlModel() == Source.Source)
1019 removeModelListeners(getControlModel());
1021 // the form's model ?
1022 if (getRowSet() == Source.Source)
1023 disposingFormModel(Source);
1025 // from a single column model ?
1026 Reference< XPropertySet > xSourceSet(Source.Source, UNO_QUERY);
1027 if (xSourceSet.is())
1029 Reference< XPropertySetInfo > xInfo = xSourceSet->getPropertySetInfo();
1030 // we assume that columns have a Width property and all other sets we are listening to don't have
1031 if (xInfo->hasPropertyByName(PROPERTY_WIDTH))
1032 disposingColumnModel(Source);
1034 SbaXDataBrowserController_Base::OGenericUnoController::disposing( Source );
1037 void SAL_CALL SbaXDataBrowserController::setIdentifier( const OUString& Identifier )
1039 ::osl::MutexGuard aGuard( getMutex() );
1040 m_sModuleIdentifier = Identifier;
1043 OUString SAL_CALL SbaXDataBrowserController::getIdentifier( )
1045 ::osl::MutexGuard aGuard( getMutex() );
1046 return m_sModuleIdentifier;
1049 void SbaXDataBrowserController::propertyChange(const PropertyChangeEvent& evt)
1051 Reference< XPropertySet > xSource(evt.Source, UNO_QUERY);
1052 if (!xSource.is())
1053 return;
1055 SolarMutexGuard aGuard;
1056 // the IsModified changed to sal_False ?
1057 if ( evt.PropertyName == PROPERTY_ISMODIFIED
1058 && !::comphelper::getBOOL(evt.NewValue)
1060 { // -> the current field isn't modified anymore, too
1061 setCurrentModified( false );
1064 // switching to a new record ?
1065 if ( evt.PropertyName == PROPERTY_ISNEW
1066 && ::comphelper::getBOOL(evt.NewValue)
1069 if (::comphelper::getINT32(xSource->getPropertyValue(PROPERTY_ROWCOUNT)) == 0)
1070 // if we're switching to a new record and didn't have any records before we need to invalidate
1071 // all slots (as the cursor was invalid before the mode change and so the slots were disabled)
1072 InvalidateAll();
1075 if (evt.PropertyName == PROPERTY_FILTER)
1077 InvalidateFeature(ID_BROWSER_REMOVEFILTER);
1079 else if (evt.PropertyName == PROPERTY_HAVING_CLAUSE)
1081 InvalidateFeature(ID_BROWSER_REMOVEFILTER);
1083 else if (evt.PropertyName == PROPERTY_ORDER)
1085 InvalidateFeature(ID_BROWSER_REMOVEFILTER);
1088 // a new record count ? -> may be our search availability has changed
1089 if (evt.PropertyName == PROPERTY_ROWCOUNT)
1091 sal_Int32 nNewValue = 0, nOldValue = 0;
1092 evt.NewValue >>= nNewValue;
1093 evt.OldValue >>= nOldValue;
1094 if((nOldValue == 0 && nNewValue != 0) || (nOldValue != 0 && nNewValue == 0))
1095 InvalidateAll();
1099 void SbaXDataBrowserController::modified(const css::lang::EventObject& /*aEvent*/)
1101 setCurrentModified( true );
1104 void SbaXDataBrowserController::elementInserted(const css::container::ContainerEvent& evt)
1106 OSL_ENSURE(Reference< XInterface >(evt.Source, UNO_QUERY).get() == Reference< XInterface >(getControlModel(), UNO_QUERY).get(),
1107 "SbaXDataBrowserController::elementInserted: where did this come from (not from the grid model)?!");
1108 Reference< XPropertySet > xNewColumn(evt.Element,UNO_QUERY);
1109 if ( xNewColumn.is() )
1110 AddColumnListener(xNewColumn);
1113 void SbaXDataBrowserController::elementRemoved(const css::container::ContainerEvent& evt)
1115 OSL_ENSURE(Reference< XInterface >(evt.Source, UNO_QUERY).get() == Reference< XInterface >(getControlModel(), UNO_QUERY).get(),
1116 "SbaXDataBrowserController::elementRemoved: where did this come from (not from the grid model)?!");
1117 Reference< XPropertySet > xOldColumn(evt.Element,UNO_QUERY);
1118 if ( xOldColumn.is() )
1119 RemoveColumnListener(xOldColumn);
1122 void SbaXDataBrowserController::elementReplaced(const css::container::ContainerEvent& evt)
1124 OSL_ENSURE(Reference< XInterface >(evt.Source, UNO_QUERY).get() == Reference< XInterface >(getControlModel(), UNO_QUERY).get(),
1125 "SbaXDataBrowserController::elementReplaced: where did this come from (not from the grid model)?!");
1126 Reference< XPropertySet > xOldColumn(evt.ReplacedElement,UNO_QUERY);
1127 if ( xOldColumn.is() )
1128 RemoveColumnListener(xOldColumn);
1130 Reference< XPropertySet > xNewColumn(evt.Element,UNO_QUERY);
1131 if ( xNewColumn.is() )
1132 AddColumnListener(xNewColumn);
1135 sal_Bool SbaXDataBrowserController::suspend(sal_Bool /*bSuspend*/)
1137 m_aAsyncGetCellFocus.CancelCall();
1138 m_aAsyncDisplayError.CancelCall();
1139 m_aAsyncInvalidateAll.CancelCall();
1141 bool bSuccess = SaveModified();
1142 return bSuccess;
1145 void SbaXDataBrowserController::disposing()
1147 // the base class
1148 SbaXDataBrowserController_Base::OGenericUnoController::disposing();
1150 // the data source
1151 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
1152 if (xFormSet.is())
1154 xFormSet->removePropertyChangeListener(PROPERTY_ISNEW, static_cast<XPropertyChangeListener*>(this));
1155 xFormSet->removePropertyChangeListener(PROPERTY_ISMODIFIED, static_cast<XPropertyChangeListener*>(this));
1156 xFormSet->removePropertyChangeListener(PROPERTY_ROWCOUNT, static_cast<XPropertyChangeListener*>(this));
1157 xFormSet->removePropertyChangeListener(PROPERTY_ACTIVECOMMAND, static_cast<XPropertyChangeListener*>(this));
1158 xFormSet->removePropertyChangeListener(PROPERTY_ORDER, static_cast<XPropertyChangeListener*>(this));
1159 xFormSet->removePropertyChangeListener(PROPERTY_FILTER, static_cast<XPropertyChangeListener*>(this));
1160 xFormSet->removePropertyChangeListener(PROPERTY_HAVING_CLAUSE, static_cast<XPropertyChangeListener*>(this));
1161 xFormSet->removePropertyChangeListener(PROPERTY_APPLYFILTER, static_cast<XPropertyChangeListener*>(this));
1164 Reference< css::sdb::XSQLErrorBroadcaster > xFormError(getRowSet(), UNO_QUERY);
1165 if (xFormError.is())
1166 xFormError->removeSQLErrorListener(static_cast<css::sdb::XSQLErrorListener*>(this));
1168 if (m_xLoadable.is())
1169 m_xLoadable->removeLoadListener(this);
1171 Reference< css::form::XDatabaseParameterBroadcaster > xFormParameter(getRowSet(), UNO_QUERY);
1172 if (xFormParameter.is())
1173 xFormParameter->removeParameterListener(static_cast<css::form::XDatabaseParameterListener*>(this));
1175 removeModelListeners(getControlModel());
1177 if ( getView() && m_pClipboardNotifier.is() )
1179 m_pClipboardNotifier->ClearCallbackLink();
1180 m_pClipboardNotifier->RemoveListener( getView() );
1181 m_pClipboardNotifier.clear();
1184 if (getBrowserView())
1186 removeControlListeners(getBrowserView()->getGridControl());
1187 // don't delete explicitly, this is done by the owner (and user) of this controller (me hopes ...)
1188 clearView();
1191 if(m_aInvalidateClipboard.IsActive())
1192 m_aInvalidateClipboard.Stop();
1194 // dispose the row set
1197 ::comphelper::disposeComponent(m_xRowSet);
1199 m_xRowSet = nullptr;
1200 m_xColumnsSupplier = nullptr;
1201 m_xLoadable = nullptr;
1203 catch(Exception&)
1205 DBG_UNHANDLED_EXCEPTION("dbaccess");
1207 m_xParser.clear();
1208 // don't dispose, just reset - it's owned by the RowSet
1211 void SbaXDataBrowserController::frameAction(const css::frame::FrameActionEvent& aEvent)
1213 ::osl::MutexGuard aGuard( getMutex() );
1215 SbaXDataBrowserController_Base::frameAction( aEvent );
1217 if ( aEvent.Source != getFrame() )
1218 return;
1220 switch ( aEvent.Action )
1222 case FrameAction_FRAME_ACTIVATED:
1223 case FrameAction_FRAME_UI_ACTIVATED:
1224 // ensure that the active cell (if any) has the focus
1225 m_aAsyncGetCellFocus.Call();
1226 // start the clipboard timer
1227 if (getBrowserView() && getBrowserView()->getVclControl() && !m_aInvalidateClipboard.IsActive())
1229 m_aInvalidateClipboard.Start();
1230 OnInvalidateClipboard( nullptr );
1232 break;
1233 case FrameAction_FRAME_DEACTIVATING:
1234 case FrameAction_FRAME_UI_DEACTIVATING:
1235 // stop the clipboard invalidator
1236 if (getBrowserView() && getBrowserView()->getVclControl() && m_aInvalidateClipboard.IsActive())
1238 m_aInvalidateClipboard.Stop();
1239 OnInvalidateClipboard( nullptr );
1241 // remove the "get cell focus"-event
1242 m_aAsyncGetCellFocus.CancelCall();
1243 break;
1244 default:
1245 break;
1249 IMPL_LINK_NOARG( SbaXDataBrowserController, OnAsyncDisplayError, void*, void )
1251 if ( m_aCurrentError.isValid() )
1253 OSQLMessageBox aDlg(getFrameWeld(), m_aCurrentError);
1254 aDlg.run();
1258 void SbaXDataBrowserController::errorOccured(const css::sdb::SQLErrorEvent& aEvent)
1260 ::osl::MutexGuard aGuard( getMutex() );
1262 SQLExceptionInfo aInfo( aEvent.Reason );
1263 if ( !aInfo.isValid() )
1264 return;
1266 if ( m_nFormActionNestingLevel )
1268 OSL_ENSURE( !m_aCurrentError.isValid(), "SbaXDataBrowserController::errorOccurred: can handle one error per transaction only!" );
1269 m_aCurrentError = aInfo;
1271 else
1273 m_aCurrentError = aInfo;
1274 m_aAsyncDisplayError.Call();
1278 sal_Bool SbaXDataBrowserController::approveParameter(const css::form::DatabaseParameterEvent& aEvent)
1280 if (aEvent.Source != getRowSet())
1282 // not my data source -> allow anything
1283 SAL_WARN("dbaccess.ui","SbaXDataBrowserController::approveParameter : invalid event source !");
1284 return true;
1287 Reference< css::container::XIndexAccess > xParameters = aEvent.Parameters;
1288 SolarMutexGuard aSolarGuard;
1290 // default handling: instantiate an interaction handler and let it handle the parameter request
1293 // two continuations allowed: OK and Cancel
1294 OParameterContinuation* pParamValues = new OParameterContinuation;
1295 OInteractionAbort* pAbort = new OInteractionAbort;
1296 // the request
1297 ParametersRequest aRequest;
1298 aRequest.Parameters = xParameters;
1299 aRequest.Connection = getConnection(Reference< XRowSet >(aEvent.Source, UNO_QUERY));
1300 OInteractionRequest* pParamRequest = new OInteractionRequest(makeAny(aRequest));
1301 Reference< XInteractionRequest > xParamRequest(pParamRequest);
1302 // some knittings
1303 pParamRequest->addContinuation(pParamValues);
1304 pParamRequest->addContinuation(pAbort);
1306 // create the handler, let it handle the request
1307 Reference< XInteractionHandler2 > xHandler(InteractionHandler::createWithParent(getORB(), getComponentWindow()));
1308 xHandler->handle(xParamRequest);
1310 if (!pParamValues->wasSelected())
1311 { // canceled
1312 setLoadingCancelled();
1313 return false;
1316 // transfer the values into the parameter supplier
1317 Sequence< PropertyValue > aFinalValues = pParamValues->getValues();
1318 if (aFinalValues.getLength() != aRequest.Parameters->getCount())
1320 SAL_WARN("dbaccess.ui","SbaXDataBrowserController::approveParameter: the InteractionHandler returned nonsense!");
1321 setLoadingCancelled();
1322 return false;
1324 const PropertyValue* pFinalValues = aFinalValues.getConstArray();
1325 for (sal_Int32 i=0; i<aFinalValues.getLength(); ++i, ++pFinalValues)
1327 Reference< XPropertySet > xParam(
1328 aRequest.Parameters->getByIndex(i), css::uno::UNO_QUERY);
1329 OSL_ENSURE(xParam.is(), "SbaXDataBrowserController::approveParameter: one of the parameters is no property set!");
1330 if (xParam.is())
1332 #ifdef DBG_UTIL
1333 OUString sName;
1334 xParam->getPropertyValue(PROPERTY_NAME) >>= sName;
1335 OSL_ENSURE(sName == pFinalValues->Name, "SbaXDataBrowserController::approveParameter: suspicious value names!");
1336 #endif
1337 try { xParam->setPropertyValue(PROPERTY_VALUE, pFinalValues->Value); }
1338 catch(Exception&)
1340 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::approveParameter: setting one of the properties failed!");
1345 catch( const Exception& )
1347 DBG_UNHANDLED_EXCEPTION("dbaccess");
1350 return true;
1353 sal_Bool SbaXDataBrowserController::approveReset(const css::lang::EventObject& /*rEvent*/)
1355 return true;
1358 void SbaXDataBrowserController::resetted(const css::lang::EventObject& rEvent)
1360 OSL_ENSURE(rEvent.Source == getControlModel(), "SbaXDataBrowserController::resetted : where did this come from ?");
1361 setCurrentModified( false );
1364 sal_Bool SbaXDataBrowserController::confirmDelete(const css::sdb::RowChangeEvent& /*aEvent*/)
1366 std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog(getFrameWeld(),
1367 VclMessageType::Question, VclButtonsType::YesNo,
1368 DBA_RES(STR_QUERY_BRW_DELETE_ROWS)));
1369 if (xQuery->run() != RET_YES)
1370 return false;
1371 return true;
1374 FeatureState SbaXDataBrowserController::GetState(sal_uInt16 nId) const
1376 FeatureState aReturn;
1377 // (disabled automatically)
1381 // no chance without a view
1382 if (!getBrowserView() || !getBrowserView()->getVclControl())
1383 return aReturn;
1385 switch (nId)
1387 case ID_BROWSER_REMOVEFILTER:
1388 if (!m_xParser.is())
1390 aReturn.bEnabled = false;
1391 return aReturn;
1393 // any filter or sort order set ?
1394 aReturn.bEnabled = m_xParser->getFilter().getLength() || m_xParser->getHavingClause().getLength() || m_xParser->getOrder().getLength();
1395 return aReturn;
1397 // no chance without valid models
1398 if (isValid() && !isValidCursor())
1399 return aReturn;
1401 switch (nId)
1403 case ID_BROWSER_SEARCH:
1405 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
1406 sal_Int32 nCount = ::comphelper::getINT32(xFormSet->getPropertyValue(PROPERTY_ROWCOUNT));
1407 aReturn.bEnabled = nCount != 0;
1409 break;
1410 case ID_BROWSER_INSERT_ROW:
1412 // check if it is available
1413 bool bInsertPrivilege = ( m_nRowSetPrivileges & Privilege::INSERT) != 0;
1414 bool bAllowInsertions = true;
1417 Reference< XPropertySet > xRowSetProps( getRowSet(), UNO_QUERY_THROW );
1418 OSL_VERIFY( xRowSetProps->getPropertyValue("AllowInserts") >>= bAllowInsertions );
1420 catch( const Exception& )
1422 DBG_UNHANDLED_EXCEPTION("dbaccess");
1424 aReturn.bEnabled = bInsertPrivilege && bAllowInsertions;
1426 break;
1427 case SID_FM_DELETEROWS:
1429 // check if it is available
1430 bool bDeletePrivilege = ( m_nRowSetPrivileges & Privilege::INSERT) != 0;
1431 bool bAllowDeletions = true;
1432 sal_Int32 nRowCount = 0;
1433 bool bInsertionRow = false;
1436 Reference< XPropertySet > xRowSetProps( getRowSet(), UNO_QUERY_THROW );
1437 OSL_VERIFY( xRowSetProps->getPropertyValue("AllowDeletes") >>= bAllowDeletions );
1438 OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_ROWCOUNT ) >>= nRowCount );
1439 OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_ISNEW ) >>= bInsertionRow );
1441 catch( const Exception& )
1443 DBG_UNHANDLED_EXCEPTION("dbaccess");
1445 aReturn.bEnabled = bDeletePrivilege && bAllowDeletions && ( nRowCount != 0 ) && !bInsertionRow;
1447 break;
1449 case ID_BROWSER_COPY:
1450 if ( getBrowserView()->getVclControl()->GetSelectRowCount() )
1452 aReturn.bEnabled = m_aCurrentFrame.isActive();
1453 break;
1455 [[fallthrough]];
1456 case ID_BROWSER_PASTE:
1457 case ID_BROWSER_CUT:
1459 CellControllerRef xCurrentController = getBrowserView()->getVclControl()->Controller();
1460 if (const EditCellController* pController = dynamic_cast<const EditCellController*>(xCurrentController.get()))
1462 const IEditImplementation* pEditImplementation = pController->GetEditImplementation();
1463 bool bHasLen = pEditImplementation->GetSelection().Len() != 0;
1464 bool bIsReadOnly = pEditImplementation->IsReadOnly();
1465 switch (nId)
1467 case ID_BROWSER_CUT: aReturn.bEnabled = m_aCurrentFrame.isActive() && bHasLen && !bIsReadOnly; break;
1468 case SID_COPY : aReturn.bEnabled = m_aCurrentFrame.isActive() && bHasLen; break;
1469 case ID_BROWSER_PASTE:
1470 aReturn.bEnabled = m_aCurrentFrame.isActive() && !bIsReadOnly;
1471 if(aReturn.bEnabled)
1473 aReturn.bEnabled = IsFormatSupported( m_aSystemClipboard.GetDataFlavorExVector(), SotClipboardFormatId::STRING );
1475 break;
1479 break;
1481 case ID_BROWSER_SORTUP:
1482 case ID_BROWSER_SORTDOWN:
1483 case ID_BROWSER_AUTOFILTER:
1485 // a native statement can't be filtered or sorted
1486 const Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
1487 if ( !::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)) || !m_xParser.is() )
1488 break;
1490 Reference< XPropertySet > xCurrentField = getBoundField();
1491 if (!xCurrentField.is())
1492 break;
1494 aReturn.bEnabled = ::comphelper::getBOOL(xCurrentField->getPropertyValue(PROPERTY_ISSEARCHABLE));
1495 const Reference< XRowSet > xRow = getRowSet();
1496 aReturn.bEnabled = aReturn.bEnabled
1497 && xRow.is()
1498 && !xRow->isBeforeFirst()
1499 && !xRow->isAfterLast()
1500 && !xRow->rowDeleted()
1501 && ( ::comphelper::getINT32( xFormSet->getPropertyValue( PROPERTY_ROWCOUNT ) ) != 0 );
1503 break;
1505 case ID_BROWSER_FILTERCRIT:
1506 if ( m_bCannotSelectUnfiltered && m_xParser.is() )
1508 aReturn.bEnabled = true;
1509 break;
1511 [[fallthrough]];
1512 case ID_BROWSER_ORDERCRIT:
1514 const Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
1515 if ( !::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)) || !m_xParser.is() )
1516 break;
1518 aReturn.bEnabled = getRowSet().is()
1519 && ( ::comphelper::getINT32( xFormSet->getPropertyValue( PROPERTY_ROWCOUNT ) ) != 0 );
1521 break;
1523 case ID_BROWSER_REFRESH:
1524 aReturn.bEnabled = true;
1525 break;
1527 case ID_BROWSER_REDO:
1528 aReturn.bEnabled = false; // simply forget it ;). no redo possible.
1529 break;
1531 case ID_BROWSER_UNDORECORD:
1532 case ID_BROWSER_SAVERECORD:
1534 if (!m_bCurrentlyModified)
1536 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
1537 if (xFormSet.is())
1538 aReturn.bEnabled = ::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ISMODIFIED));
1540 else
1541 aReturn.bEnabled = true;
1543 aReturn.sTitle = (ID_BROWSER_UNDORECORD == nId) ? m_sStateUndoRecord : m_sStateSaveRecord;
1545 break;
1546 case ID_BROWSER_EDITDOC:
1548 // check if it is available
1549 Reference< XPropertySet > xDataSourceSet(getRowSet(), UNO_QUERY);
1550 if (!xDataSourceSet.is())
1551 break; // no datasource -> no edit mode
1553 sal_Int32 nDataSourcePrivileges = ::comphelper::getINT32(xDataSourceSet->getPropertyValue(PROPERTY_PRIVILEGES));
1554 bool bInsertAllowedAndPossible = ((nDataSourcePrivileges & css::sdbcx::Privilege::INSERT) != 0) && ::comphelper::getBOOL(xDataSourceSet->getPropertyValue("AllowInserts"));
1555 bool bUpdateAllowedAndPossible = ((nDataSourcePrivileges & css::sdbcx::Privilege::UPDATE) != 0) && ::comphelper::getBOOL(xDataSourceSet->getPropertyValue("AllowUpdates"));
1556 bool bDeleteAllowedAndPossible = ((nDataSourcePrivileges & css::sdbcx::Privilege::DELETE) != 0) && ::comphelper::getBOOL(xDataSourceSet->getPropertyValue("AllowDeletes"));
1557 if (!bInsertAllowedAndPossible && !bUpdateAllowedAndPossible && !bDeleteAllowedAndPossible)
1558 break; // no insert/update/delete -> no edit mode
1560 if (!isValidCursor() || !isLoaded())
1561 break; // no cursor -> no edit mode
1563 aReturn.bEnabled = true;
1565 DbGridControlOptions nGridMode = getBrowserView()->getVclControl()->GetOptions();
1566 aReturn.bChecked = nGridMode > DbGridControlOptions::Readonly;
1568 break;
1569 case ID_BROWSER_FILTERED:
1571 aReturn.bEnabled = false;
1572 Reference< XPropertySet > xActiveSet(getRowSet(), UNO_QUERY);
1573 OUString aFilter = ::comphelper::getString(xActiveSet->getPropertyValue(PROPERTY_FILTER));
1574 OUString aHaving = ::comphelper::getString(xActiveSet->getPropertyValue(PROPERTY_HAVING_CLAUSE));
1575 if ( !(aFilter.isEmpty() && aHaving.isEmpty()) )
1577 xActiveSet->getPropertyValue( PROPERTY_APPLYFILTER ) >>= aReturn.bChecked;
1578 aReturn.bEnabled = true;
1580 else
1582 aReturn.bChecked = false;
1583 aReturn.bEnabled = false;
1586 break;
1587 default:
1588 return SbaXDataBrowserController_Base::GetState(nId);
1591 catch(const Exception& )
1593 DBG_UNHANDLED_EXCEPTION("dbaccess");
1596 return aReturn;
1599 void SbaXDataBrowserController::applyParserOrder(const OUString& _rOldOrder,const Reference< XSingleSelectQueryComposer >& _xParser)
1601 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
1602 if (!m_xLoadable.is())
1604 SAL_WARN("dbaccess.ui","SbaXDataBrowserController::applyParserOrder: invalid row set!");
1605 return;
1608 sal_uInt16 nPos = getCurrentColumnPosition();
1609 bool bSuccess = false;
1612 xFormSet->setPropertyValue(PROPERTY_ORDER, makeAny(_xParser->getOrder()));
1613 bSuccess = reloadForm(m_xLoadable);
1615 catch(Exception&)
1619 if (!bSuccess)
1621 xFormSet->setPropertyValue(PROPERTY_ORDER, makeAny(_rOldOrder));
1625 if (loadingCancelled() || !reloadForm(m_xLoadable))
1626 criticalFail();
1628 catch(Exception&)
1630 criticalFail();
1632 InvalidateAll();
1634 InvalidateFeature(ID_BROWSER_REMOVEFILTER);
1636 setCurrentColumnPosition(nPos);
1639 void SbaXDataBrowserController::applyParserFilter(const OUString& _rOldFilter, bool _bOldFilterApplied,const ::OUString& _sOldHaving,const Reference< XSingleSelectQueryComposer >& _xParser)
1641 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
1642 if (!m_xLoadable.is())
1644 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::applyParserFilter: invalid row set!");
1645 return;
1648 sal_uInt16 nPos = getCurrentColumnPosition();
1650 bool bSuccess = false;
1653 FormErrorHelper aError(this);
1654 xFormSet->setPropertyValue(PROPERTY_FILTER, makeAny(_xParser->getFilter()));
1655 xFormSet->setPropertyValue(PROPERTY_HAVING_CLAUSE, makeAny(_xParser->getHavingClause()));
1656 xFormSet->setPropertyValue(PROPERTY_APPLYFILTER, css::uno::Any(true));
1658 bSuccess = reloadForm(m_xLoadable);
1660 catch(Exception&)
1664 if (!bSuccess)
1666 xFormSet->setPropertyValue(PROPERTY_FILTER, makeAny(_rOldFilter));
1667 xFormSet->setPropertyValue(PROPERTY_HAVING_CLAUSE, makeAny(_sOldHaving));
1668 xFormSet->setPropertyValue(PROPERTY_APPLYFILTER, css::uno::Any(_bOldFilterApplied));
1672 if (loadingCancelled() || !reloadForm(m_xLoadable))
1673 criticalFail();
1675 catch(Exception&)
1677 criticalFail();
1679 InvalidateAll();
1681 InvalidateFeature(ID_BROWSER_REMOVEFILTER);
1683 setCurrentColumnPosition(nPos);
1686 Reference< XSingleSelectQueryComposer > SbaXDataBrowserController::createParser_nothrow()
1688 Reference< XSingleSelectQueryComposer > xComposer;
1691 const Reference< XPropertySet > xRowSetProps( getRowSet(), UNO_QUERY_THROW );
1692 const Reference< XMultiServiceFactory > xFactory(
1693 xRowSetProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ), UNO_QUERY_THROW );
1694 xComposer.set( xFactory->createInstance( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER ), UNO_QUERY_THROW );
1696 OUString sActiveCommand;
1697 OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_ACTIVECOMMAND ) >>= sActiveCommand );
1698 if ( !sActiveCommand.isEmpty() )
1700 xComposer->setElementaryQuery( sActiveCommand );
1702 else
1704 OUString sCommand;
1705 OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_COMMAND ) >>= sCommand );
1706 sal_Int32 nCommandType = CommandType::COMMAND;
1707 OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_COMMAND_TYPE ) >>= nCommandType );
1708 xComposer->setCommand( sCommand, nCommandType );
1711 OUString sFilter;
1712 OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_FILTER ) >>= sFilter );
1713 xComposer->setFilter( sFilter );
1715 OUString sHavingClause;
1716 OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_HAVING_CLAUSE ) >>= sHavingClause );
1717 xComposer->setHavingClause( sHavingClause );
1719 OUString sOrder;
1720 OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_ORDER ) >>= sOrder );
1721 xComposer->setOrder( sOrder );
1723 catch ( const Exception& )
1725 DBG_UNHANDLED_EXCEPTION("dbaccess");
1727 return xComposer;
1730 void SbaXDataBrowserController::ExecuteFilterSortCrit(bool bFilter)
1732 if (!SaveModified())
1733 return;
1735 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
1737 const OUString sOldVal = bFilter ? m_xParser->getFilter() : m_xParser->getOrder();
1738 const OUString sOldHaving = m_xParser->getHavingClause();
1739 Reference< XSingleSelectQueryComposer > xParser = createParser_nothrow();
1742 Reference< XConnection> xCon(xFormSet->getPropertyValue(PROPERTY_ACTIVE_CONNECTION),UNO_QUERY);
1743 if(bFilter)
1745 DlgFilterCrit aDlg(getFrameWeld(), getORB(), xCon, xParser, m_xColumnsSupplier->getColumns());
1746 if (!aDlg.run())
1747 return; // if so we don't need to update the grid
1748 aDlg.BuildWherePart();
1750 else
1752 DlgOrderCrit aDlg(getFrameWeld(), xCon, xParser, m_xColumnsSupplier->getColumns());
1753 if (!aDlg.run())
1755 return; // if so we don't need to actualize the grid
1757 aDlg.BuildOrderPart();
1760 catch(const SQLException& )
1762 SQLExceptionInfo aError( ::cppu::getCaughtException() );
1763 showError( aError );
1764 return;
1766 catch(Exception&)
1768 return;
1771 OUString sNewVal = bFilter ? xParser->getFilter() : xParser->getOrder();
1772 bool bOldFilterApplied(false);
1773 if (bFilter)
1775 try { bOldFilterApplied = ::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_APPLYFILTER)); } catch(Exception&) { } ;
1778 OUString sNewHaving = xParser->getHavingClause();
1779 if ( sOldVal == sNewVal && (!bFilter || sOldHaving == sNewHaving) )
1780 // nothing to be done
1781 return;
1783 if (bFilter)
1784 applyParserFilter(sOldVal, bOldFilterApplied,sOldHaving,xParser);
1785 else
1786 applyParserOrder(sOldVal,xParser);
1788 ::comphelper::disposeComponent(xParser);
1791 void SbaXDataBrowserController::ExecuteSearch()
1793 // calculate the control source of the active field
1794 Reference< css::form::XGrid > xGrid(getBrowserView()->getGridControl(), UNO_QUERY);
1795 OSL_ENSURE(xGrid.is(), "SbaXDataBrowserController::ExecuteSearch : the control should have a css::form::XGrid interface !");
1797 Reference< css::form::XGridPeer > xGridPeer(getBrowserView()->getGridControl()->getPeer(), UNO_QUERY);
1798 Reference< css::container::XIndexContainer > xColumns = xGridPeer->getColumns();
1799 OSL_ENSURE(xGridPeer.is() && xColumns.is(), "SbaXDataBrowserController::ExecuteSearch : invalid peer !");
1801 sal_Int16 nViewCol = xGrid->getCurrentColumnPosition();
1802 sal_Int16 nModelCol = getBrowserView()->View2ModelPos(nViewCol);
1804 Reference< XPropertySet > xCurrentCol(xColumns->getByIndex(nModelCol),UNO_QUERY);
1805 OUString sActiveField = ::comphelper::getString(xCurrentCol->getPropertyValue(PROPERTY_CONTROLSOURCE));
1807 // the text within the current cell
1808 OUString sInitialText;
1809 Reference< css::container::XIndexAccess > xColControls(xGridPeer, UNO_QUERY);
1810 Reference< XInterface > xCurControl(xColControls->getByIndex(nViewCol),UNO_QUERY);
1811 OUString aInitialText;
1812 if (IsSearchableControl(xCurControl, &aInitialText))
1813 sInitialText = aInitialText;
1815 // prohibit the synchronization of the grid's display with the cursor's position
1816 Reference< XPropertySet > xModelSet(getControlModel(), UNO_QUERY);
1817 OSL_ENSURE(xModelSet.is(), "SbaXDataBrowserController::ExecuteSearch : no model set ?!");
1818 xModelSet->setPropertyValue("DisplayIsSynchron", css::uno::Any(false));
1819 xModelSet->setPropertyValue("AlwaysShowCursor", css::uno::Any(true));
1820 xModelSet->setPropertyValue("CursorColor", makeAny(COL_LIGHTRED));
1822 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1823 VclPtr<AbstractFmSearchDialog> pDialog;
1824 std::vector< OUString > aContextNames;
1825 aContextNames.emplace_back("Standard" );
1826 pDialog = pFact->CreateFmSearchDialog(getFrameWeld(), sInitialText, aContextNames, 0, LINK(this, SbaXDataBrowserController, OnSearchContextRequest));
1827 pDialog->SetActiveField( sActiveField );
1828 pDialog->SetFoundHandler( LINK( this, SbaXDataBrowserController, OnFoundData ) );
1829 pDialog->SetCanceledNotFoundHdl( LINK( this, SbaXDataBrowserController, OnCanceledNotFound ) );
1830 pDialog->Execute();
1831 pDialog.disposeAndClear();
1833 // restore the grid's normal operating state
1834 xModelSet->setPropertyValue("DisplayIsSynchron", css::uno::Any(true));
1835 xModelSet->setPropertyValue("AlwaysShowCursor", css::uno::Any(false));
1836 xModelSet->setPropertyValue("CursorColor", Any());
1839 void SbaXDataBrowserController::Execute(sal_uInt16 nId, const Sequence< PropertyValue >& _rArgs)
1841 bool bSortUp = true;
1843 switch (nId)
1845 default:
1846 SbaXDataBrowserController_Base::Execute( nId, _rArgs );
1847 return;
1849 case ID_BROWSER_INSERT_ROW:
1852 if (SaveModified())
1854 getRowSet()->afterLast();
1855 // check if it is available
1856 Reference< XResultSetUpdate > xUpdateCursor(getRowSet(), UNO_QUERY_THROW);
1857 xUpdateCursor->moveToInsertRow();
1860 catch(Exception&)
1862 TOOLS_WARN_EXCEPTION("dbaccess.ui", "" );
1864 break;
1865 case SID_FM_DELETEROWS:
1867 if (SaveModified())
1869 SbaGridControl* pVclGrid = getBrowserView()->getVclControl();
1870 if ( pVclGrid )
1872 if( !pVclGrid->GetSelectRowCount() )
1874 pVclGrid->DeactivateCell();
1875 pVclGrid->SelectRow(pVclGrid->GetCurRow());
1877 pVclGrid->DeleteSelectedRows();
1880 break;
1882 case ID_BROWSER_FILTERED:
1883 if (SaveModified())
1885 Reference< XPropertySet > xActiveSet(getRowSet(), UNO_QUERY);
1886 bool bApplied = ::comphelper::getBOOL(xActiveSet->getPropertyValue(PROPERTY_APPLYFILTER));
1887 xActiveSet->setPropertyValue(PROPERTY_APPLYFILTER, css::uno::Any(!bApplied));
1888 reloadForm(m_xLoadable);
1890 InvalidateFeature(ID_BROWSER_FILTERED);
1891 break;
1892 case ID_BROWSER_EDITDOC:
1894 DbGridControlOptions nGridMode = getBrowserView()->getVclControl()->GetOptions();
1895 if (nGridMode == DbGridControlOptions::Readonly)
1896 getBrowserView()->getVclControl()->SetOptions(DbGridControlOptions::Update | DbGridControlOptions::Insert | DbGridControlOptions::Delete);
1897 // the options not supported by the data source will be removed automatically
1898 else
1900 if ( !SaveModified( ) )
1901 // give the user a chance to save the current record (if necessary)
1902 break;
1904 // maybe the user wanted to reject the modified record ?
1905 if (GetState(ID_BROWSER_UNDORECORD).bEnabled)
1906 Execute(ID_BROWSER_UNDORECORD,Sequence<PropertyValue>());
1908 getBrowserView()->getVclControl()->SetOptions(DbGridControlOptions::Readonly);
1910 InvalidateFeature(ID_BROWSER_EDITDOC);
1912 break;
1914 case ID_BROWSER_SEARCH:
1915 if ( SaveModified( ) )
1916 ExecuteSearch();
1917 break;
1919 case ID_BROWSER_COPY:
1920 if ( getBrowserView()->getVclControl()->GetSelectRowCount() > 0 )
1922 getBrowserView()->getVclControl()->CopySelectedRowsToClipboard();
1923 break;
1925 [[fallthrough]];
1926 case ID_BROWSER_CUT:
1927 case ID_BROWSER_PASTE:
1929 CellControllerRef xCurrentController = getBrowserView()->getVclControl()->Controller();
1930 if (EditCellController* pController = dynamic_cast<EditCellController*>(xCurrentController.get()))
1932 IEditImplementation* pEditImplementation = pController->GetEditImplementation();
1933 switch (nId)
1935 case ID_BROWSER_CUT:
1936 pEditImplementation->Cut();
1937 break;
1938 case SID_COPY:
1939 pEditImplementation->Copy();
1940 break;
1941 case ID_BROWSER_PASTE:
1942 pEditImplementation->Paste();
1943 break;
1945 if (ID_BROWSER_CUT == nId || ID_BROWSER_PASTE == nId)
1946 pController->Modify();
1949 break;
1951 case ID_BROWSER_SORTDOWN:
1952 bSortUp = false;
1953 [[fallthrough]];
1954 case ID_BROWSER_SORTUP:
1956 if (!SaveModified())
1957 break;
1959 if (!isValidCursor())
1960 break;
1962 // only one sort order
1963 Reference< XPropertySet > xField = getBoundField();
1964 if (!xField.is())
1965 break;
1967 Reference< XSingleSelectQueryComposer > xParser = createParser_nothrow();
1968 const OUString sOldSort = xParser->getOrder();
1969 bool bParserSuccess = false;
1970 HANDLE_SQL_ERRORS(
1971 xParser->setOrder(OUString()); xParser->appendOrderByColumn(xField, bSortUp),
1972 bParserSuccess,
1973 DBA_RES(SBA_BROWSER_SETTING_ORDER),
1974 "SbaXDataBrowserController::Execute : caught an exception while composing the new filter !"
1977 if (bParserSuccess)
1978 applyParserOrder(sOldSort,xParser);
1980 break;
1982 case ID_BROWSER_AUTOFILTER:
1984 if (!SaveModified())
1985 break;
1987 if (!isValidCursor())
1988 break;
1990 Reference< XPropertySet > xField = getBoundField();
1991 if (!xField.is())
1992 break;
1994 // check if the column is an aggregate function
1995 const bool bHaving(isAggregateColumn(m_xParser, xField));
1997 Reference< XSingleSelectQueryComposer > xParser = createParser_nothrow();
1998 const OUString sOldFilter = xParser->getFilter();
1999 const OUString sOldHaving = xParser->getHavingClause();
2001 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
2002 bool bApplied = ::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_APPLYFILTER));
2003 // do we have a filter but it's not applied ?
2004 // -> completely overwrite it, else append one
2005 if (!bApplied)
2007 DO_SAFE( xParser->setFilter( OUString()), "SbaXDataBrowserController::Execute : caught an exception while resetting unapplied filter !" );
2008 DO_SAFE( xParser->setHavingClause(OUString()), "SbaXDataBrowserController::Execute : caught an exception while resetting unapplied HAVING clause !" );
2011 bool bParserSuccess = false;
2013 const sal_Int32 nOp = SQLFilterOperator::EQUAL;
2015 if ( bHaving )
2017 HANDLE_SQL_ERRORS(
2018 xParser->appendHavingClauseByColumn(xField,true,nOp),
2019 bParserSuccess,
2020 DBA_RES(SBA_BROWSER_SETTING_FILTER),
2021 "SbaXDataBrowserController::Execute : caught an exception while composing the new filter !"
2024 else
2026 HANDLE_SQL_ERRORS(
2027 xParser->appendFilterByColumn(xField,true,nOp),
2028 bParserSuccess,
2029 DBA_RES(SBA_BROWSER_SETTING_FILTER),
2030 "SbaXDataBrowserController::Execute : caught an exception while composing the new filter !"
2034 if (bParserSuccess)
2035 applyParserFilter(sOldFilter, bApplied,sOldHaving,xParser);
2037 InvalidateFeature(ID_BROWSER_REMOVEFILTER);
2038 InvalidateFeature(ID_BROWSER_FILTERED);
2040 break;
2042 case ID_BROWSER_ORDERCRIT:
2043 ExecuteFilterSortCrit(false);
2044 break;
2046 case ID_BROWSER_FILTERCRIT:
2047 ExecuteFilterSortCrit(true);
2048 InvalidateFeature(ID_BROWSER_FILTERED);
2049 break;
2051 case ID_BROWSER_REMOVEFILTER:
2053 if (!SaveModified())
2054 break;
2056 bool bNeedPostReload = preReloadForm();
2057 // reset the filter and the sort property simultaneously so only _one_ new statement has to be
2058 // sent
2059 Reference< XPropertySet > xSet(getRowSet(), UNO_QUERY);
2060 if ( xSet.is() )
2062 xSet->setPropertyValue(PROPERTY_FILTER,makeAny(OUString()));
2063 xSet->setPropertyValue(PROPERTY_HAVING_CLAUSE,makeAny(OUString()));
2064 xSet->setPropertyValue(PROPERTY_ORDER,makeAny(OUString()));
2068 reloadForm(m_xLoadable);
2069 if ( bNeedPostReload )
2070 postReloadForm();
2072 catch(Exception&)
2075 InvalidateFeature(ID_BROWSER_REMOVEFILTER);
2076 InvalidateFeature(ID_BROWSER_FILTERED);
2078 break;
2080 case ID_BROWSER_REFRESH:
2081 if ( SaveModified( ) )
2083 if (!reloadForm(m_xLoadable))
2084 criticalFail();
2086 break;
2088 case ID_BROWSER_SAVERECORD:
2089 if ( SaveModified( false ) )
2090 setCurrentModified( false );
2091 break;
2093 case ID_BROWSER_UNDORECORD:
2097 // restore the cursor state
2098 Reference< XResultSetUpdate > xCursor(getRowSet(), UNO_QUERY);
2099 Reference< XPropertySet > xSet(xCursor, UNO_QUERY);
2100 Any aVal = xSet->getPropertyValue(PROPERTY_ISNEW);
2101 if (aVal.hasValue() && ::comphelper::getBOOL(aVal))
2103 xCursor->moveToInsertRow();
2104 // no need to reset the grid model after we moved to the insert row, this is done implicitly by the
2105 // form
2106 // (and in some cases it may be deadly to do the reset explicitly after the form did it implicitly,
2107 // cause the form's reset may be async, and this leads to some nice deadlock scenarios...)
2109 else
2111 xCursor->cancelRowUpdates();
2113 // restore the grids state
2114 Reference< css::form::XReset > xReset(getControlModel(), UNO_QUERY);
2115 if (xReset.is())
2116 xReset->reset();
2119 catch(SQLException&)
2123 setCurrentModified( false );
2128 bool SbaXDataBrowserController::SaveModified(bool bAskFor)
2130 if ( bAskFor && GetState(ID_BROWSER_SAVERECORD).bEnabled )
2132 getBrowserView()->getVclControl()->GrabFocus();
2134 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(getFrameWeld(), "dbaccess/ui/savemodifieddialog.ui"));
2135 std::unique_ptr<weld::MessageDialog> xQry(xBuilder->weld_message_dialog("SaveModifiedDialog"));
2136 switch (xQry->run())
2138 case RET_NO:
2139 Execute(ID_BROWSER_UNDORECORD,Sequence<PropertyValue>());
2140 return true;
2141 case RET_CANCEL:
2142 return false;
2146 if ( !CommitCurrent() ) // Commit the current control
2147 return false;
2149 Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
2150 bool bResult = false;
2153 if (::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ISMODIFIED)))
2155 Reference< XResultSetUpdate > xCursor(getRowSet(), UNO_QUERY);
2156 if (::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ISNEW)))
2157 xCursor->insertRow();
2158 else
2159 xCursor->updateRow();
2161 bResult = true;
2163 catch(SQLException&)
2166 catch(Exception&)
2168 SAL_WARN("dbaccess.ui", "SbaXDataBrowserController::SaveModified : could not save the current record !");
2169 bResult = false;
2172 InvalidateFeature(ID_BROWSER_SAVERECORD);
2173 InvalidateFeature(ID_BROWSER_UNDORECORD);
2174 return bResult;
2177 bool SbaXDataBrowserController::CommitCurrent()
2179 if (!getBrowserView())
2180 return true;
2182 Reference< css::awt::XControl > xActiveControl(getBrowserView()->getGridControl());
2183 Reference< css::form::XBoundControl > xLockingTest(xActiveControl, UNO_QUERY);
2184 bool bControlIsLocked = xLockingTest.is() && xLockingTest->getLock();
2185 if (xActiveControl.is() && !bControlIsLocked)
2187 // At first check Control if it supports the IFace
2188 Reference< css::form::XBoundComponent > xBoundControl(xActiveControl, UNO_QUERY);
2189 if (!xBoundControl.is())
2190 xBoundControl.set(xActiveControl->getModel(), UNO_QUERY);
2191 if (xBoundControl.is() && !xBoundControl->commit())
2192 return false;
2194 return true;
2197 void SbaXDataBrowserController::setCurrentModified( bool _bSet )
2199 m_bCurrentlyModified = _bSet;
2200 InvalidateFeature( ID_BROWSER_SAVERECORD );
2201 InvalidateFeature( ID_BROWSER_UNDORECORD );
2204 void SbaXDataBrowserController::RowChanged()
2206 setCurrentModified( false );
2209 void SbaXDataBrowserController::ColumnChanged()
2211 InvalidateFeature(ID_BROWSER_SORTUP);
2212 InvalidateFeature(ID_BROWSER_SORTDOWN);
2213 InvalidateFeature(ID_BROWSER_ORDERCRIT);
2214 InvalidateFeature(ID_BROWSER_FILTERCRIT);
2215 InvalidateFeature(ID_BROWSER_AUTOFILTER);
2216 InvalidateFeature(ID_BROWSER_REMOVEFILTER);
2218 setCurrentModified( false );
2221 void SbaXDataBrowserController::SelectionChanged()
2223 // not interested in
2226 void SbaXDataBrowserController::CellActivated()
2228 m_aInvalidateClipboard.Start();
2229 OnInvalidateClipboard( nullptr );
2232 void SbaXDataBrowserController::CellDeactivated()
2234 m_aInvalidateClipboard.Stop();
2235 OnInvalidateClipboard( nullptr );
2238 IMPL_LINK_NOARG(SbaXDataBrowserController, OnClipboardChanged, TransferableDataHelper*, void)
2240 SolarMutexGuard aGuard;
2241 OnInvalidateClipboard( nullptr );
2244 IMPL_LINK(SbaXDataBrowserController, OnInvalidateClipboard, Timer*, _pTimer, void)
2246 InvalidateFeature(ID_BROWSER_CUT);
2247 InvalidateFeature(ID_BROWSER_COPY);
2249 // if the invalidation was triggered by the timer, we do not need to invalidate PASTE.
2250 // The timer is only for checking the CUT/COPY slots regularly, which depend on the
2251 // selection state of the active cell
2252 // TODO: get a callback at the Edit which allows to be notified when the selection
2253 // changes. This would be much better than this cycle-eating polling mechanism here...
2254 if ( _pTimer != &m_aInvalidateClipboard )
2255 InvalidateFeature(ID_BROWSER_PASTE);
2258 Reference< XPropertySet > SbaXDataBrowserController::getBoundField() const
2260 Reference< XPropertySet > xEmptyReturn;
2262 // get the current column from the grid
2263 Reference< css::form::XGrid > xGrid(getBrowserView()->getGridControl(), UNO_QUERY);
2264 if (!xGrid.is())
2265 return xEmptyReturn;
2266 sal_uInt16 nViewPos = xGrid->getCurrentColumnPosition();
2267 sal_uInt16 nCurrentCol = getBrowserView()->View2ModelPos(nViewPos);
2268 if (nCurrentCol == sal_uInt16(-1))
2269 return xEmptyReturn;
2271 // get the according column from the model
2272 Reference< css::container::XIndexContainer > xCols(getControlModel(), UNO_QUERY);
2273 Reference< XPropertySet > xCurrentCol(xCols->getByIndex(nCurrentCol),UNO_QUERY);
2274 if (!xCurrentCol.is())
2275 return xEmptyReturn;
2277 xEmptyReturn.set(xCurrentCol->getPropertyValue(PROPERTY_BOUNDFIELD) ,UNO_QUERY);
2278 return xEmptyReturn;
2281 IMPL_LINK(SbaXDataBrowserController, OnSearchContextRequest, FmSearchContext&, rContext, sal_uInt32)
2283 Reference< css::container::XIndexAccess > xPeerContainer(getBrowserView()->getGridControl(), UNO_QUERY);
2285 // check all grid columns for their control source
2286 Reference< css::container::XIndexAccess > xModelColumns(getFormComponent(), UNO_QUERY);
2287 OSL_ENSURE(xModelColumns.is(), "SbaXDataBrowserController::OnSearchContextRequest : there is a grid control without columns !");
2288 // the case 'no columns' should be indicated with an empty container, I think ...
2289 OSL_ENSURE(xModelColumns->getCount() >= xPeerContainer->getCount(), "SbaXDataBrowserController::OnSearchContextRequest : impossible : have more view than model columns !");
2291 OUString sFieldList;
2292 for (sal_Int32 nViewPos=0; nViewPos<xPeerContainer->getCount(); ++nViewPos)
2294 Reference< XInterface > xCurrentColumn(xPeerContainer->getByIndex(nViewPos),UNO_QUERY);
2295 if (!xCurrentColumn.is())
2296 continue;
2298 // can we use this column control for searching ?
2299 if (!IsSearchableControl(xCurrentColumn))
2300 continue;
2302 sal_uInt16 nModelPos = getBrowserView()->View2ModelPos(static_cast<sal_uInt16>(nViewPos));
2303 Reference< XPropertySet > xCurrentColModel(xModelColumns->getByIndex(nModelPos),UNO_QUERY);
2304 OUString aName = ::comphelper::getString(xCurrentColModel->getPropertyValue(PROPERTY_CONTROLSOURCE));
2306 sFieldList += aName + ";";
2308 rContext.arrFields.push_back(xCurrentColumn);
2310 sFieldList = comphelper::string::stripEnd(sFieldList, ';');
2312 rContext.xCursor = getRowSet();
2313 rContext.strUsedFields = sFieldList;
2315 // if the cursor is in a mode other than STANDARD -> reset
2316 Reference< XPropertySet > xCursorSet(rContext.xCursor, UNO_QUERY);
2317 OSL_ENSURE(xCursorSet.is() && !::comphelper::getBOOL(xCursorSet->getPropertyValue(PROPERTY_ISMODIFIED)),
2318 "SbaXDataBrowserController::OnSearchContextRequest : please do not call for cursors with modified rows !");
2319 if (xCursorSet.is() && ::comphelper::getBOOL(xCursorSet->getPropertyValue(PROPERTY_ISNEW)))
2321 Reference< XResultSetUpdate > xUpdateCursor(rContext.xCursor, UNO_QUERY);
2322 xUpdateCursor->moveToCurrentRow();
2324 return rContext.arrFields.size();
2327 IMPL_LINK(SbaXDataBrowserController, OnFoundData, FmFoundRecordInformation&, rInfo, void)
2329 Reference< css::sdbcx::XRowLocate > xCursor(getRowSet(), UNO_QUERY);
2330 OSL_ENSURE(xCursor.is(), "SbaXDataBrowserController::OnFoundData : xCursor is empty");
2332 // move the cursor
2333 xCursor->moveToBookmark(rInfo.aPosition);
2335 // let the grid sync its display with the cursor
2336 Reference< XPropertySet > xModelSet(getControlModel(), UNO_QUERY);
2337 OSL_ENSURE(xModelSet.is(), "SbaXDataBrowserController::OnFoundData : no model set ?!");
2338 Any aOld = xModelSet->getPropertyValue("DisplayIsSynchron");
2339 xModelSet->setPropertyValue("DisplayIsSynchron", css::uno::Any(true));
2340 xModelSet->setPropertyValue("DisplayIsSynchron", aOld);
2342 // and move to the field
2343 Reference< css::container::XIndexAccess > aColumnControls(getBrowserView()->getGridControl()->getPeer(), UNO_QUERY);
2344 sal_Int32 nViewPos;
2346 for ( nViewPos = 0; nViewPos < aColumnControls->getCount(); ++nViewPos )
2348 Reference< XInterface > xCurrent(aColumnControls->getByIndex(nViewPos),UNO_QUERY);
2349 if (IsSearchableControl(xCurrent))
2351 if (rInfo.nFieldPos)
2352 --rInfo.nFieldPos;
2353 else
2354 break;
2358 Reference< css::form::XGrid > xGrid(getBrowserView()->getGridControl(), UNO_QUERY);
2359 xGrid->setCurrentColumnPosition(nViewPos); //TODO: sal_Int32 -> sal_Int16!
2362 IMPL_LINK(SbaXDataBrowserController, OnCanceledNotFound, FmFoundRecordInformation&, rInfo, void)
2364 Reference< css::sdbcx::XRowLocate > xCursor(getRowSet(), UNO_QUERY);
2368 OSL_ENSURE(xCursor.is(), "SbaXDataBrowserController::OnCanceledNotFound : xCursor is empty");
2369 // move the cursor
2370 xCursor->moveToBookmark(rInfo.aPosition);
2372 catch( const Exception& )
2374 DBG_UNHANDLED_EXCEPTION("dbaccess");
2379 // let the grid sync its display with the cursor
2380 Reference< XPropertySet > xModelSet(getControlModel(), UNO_QUERY);
2381 OSL_ENSURE(xModelSet.is(), "SbaXDataBrowserController::OnCanceledNotFound : no model set ?!");
2382 Any aOld = xModelSet->getPropertyValue("DisplayIsSynchron");
2383 xModelSet->setPropertyValue("DisplayIsSynchron", css::uno::Any(true));
2384 xModelSet->setPropertyValue("DisplayIsSynchron", aOld);
2386 catch( const Exception& )
2388 DBG_UNHANDLED_EXCEPTION("dbaccess");
2392 IMPL_LINK_NOARG(SbaXDataBrowserController, OnAsyncGetCellFocus, void*, void)
2394 SbaGridControl* pVclGrid = getBrowserView() ? getBrowserView()->getVclControl() : nullptr;
2395 // if we have a controller, but the window for the controller doesn't have the focus, we correct this
2396 if (pVclGrid && pVclGrid->IsEditing() && pVclGrid->HasChildPathFocus())
2397 pVclGrid->Controller()->GetWindow().GrabFocus();
2400 void SbaXDataBrowserController::criticalFail()
2402 InvalidateAll();
2403 m_nRowSetPrivileges = 0;
2406 void SbaXDataBrowserController::LoadFinished(bool /*bWasSynch*/)
2408 m_nRowSetPrivileges = 0;
2410 if (!isValid() || loadingCancelled())
2411 return;
2413 // obtain cached values
2416 Reference< XPropertySet > xFormProps( m_xLoadable, UNO_QUERY_THROW );
2417 OSL_VERIFY( xFormProps->getPropertyValue( PROPERTY_PRIVILEGES ) >>= m_nRowSetPrivileges );
2419 catch( const Exception& )
2421 DBG_UNHANDLED_EXCEPTION("dbaccess");
2424 // switch the control to alive mode
2425 getBrowserView()->getGridControl()->setDesignMode(false);
2427 initializeParser();
2429 InvalidateAll();
2431 m_aAsyncGetCellFocus.Call();
2434 void SbaXDataBrowserController::initializeParser() const
2436 if ( m_xParser.is() )
2437 return;
2439 // create a parser (needed for filtering/sorting)
2442 const Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY);
2443 if (::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)))
2444 { // (only if the statement isn't native)
2445 // (it is allowed to use the PROPERTY_ISPASSTHROUGH : _after_ loading a form it is valid)
2446 xFormSet->getPropertyValue(PROPERTY_SINGLESELECTQUERYCOMPOSER) >>= m_xParser;
2449 catch(Exception&)
2451 DBG_UNHANDLED_EXCEPTION("dbaccess");
2452 m_xParser = nullptr;
2453 // no further handling, we ignore the error
2457 void SbaXDataBrowserController::loaded(const EventObject& /*aEvent*/)
2459 // not interested in
2460 // we're loading within a separated thread and have a handling for its "finished event"
2463 void SbaXDataBrowserController::unloading(const EventObject& /*aEvent*/)
2465 // not interested in
2468 void SbaXDataBrowserController::unloaded(const EventObject& /*aEvent*/)
2470 m_xParser.clear();
2471 InvalidateAll();
2472 // do this asynchronously, there are other listeners reacting on this message ...
2473 // (it's a little hack : the grid columns are listening to this event, too, and their bound field may
2474 // change as a reaction on that event. as we have no chance to be notified of this change (which is
2475 // the one we're interested in) we give them time to do what they want to before invalidating our
2476 // bound-field-dependent slots...
2479 void SbaXDataBrowserController::reloading(const EventObject& /*aEvent*/)
2481 // not interested in
2484 void SbaXDataBrowserController::reloaded(const EventObject& /*aEvent*/)
2486 InvalidateAll();
2487 // do this asynchronously, there are other listeners reacting on this message ...
2488 // (it's a little hack : the grid columns are listening to this event, too, and their bound field may
2489 // change as a reaction on that event. as we have no chance to be notified of this change (which is
2490 // the one we're interested in) we give them time to do what they want to before invalidating our
2491 // bound-field-dependent slots...
2494 void SbaXDataBrowserController::enterFormAction()
2496 if ( !m_nFormActionNestingLevel )
2497 // first action -> reset
2498 m_aCurrentError.clear();
2500 ++m_nFormActionNestingLevel;
2503 void SbaXDataBrowserController::leaveFormAction()
2505 OSL_ENSURE( m_nFormActionNestingLevel > 0, "SbaXDataBrowserController::leaveFormAction : invalid call !" );
2506 if ( --m_nFormActionNestingLevel > 0 )
2507 return;
2509 if ( !m_aCurrentError.isValid() )
2510 return;
2512 m_aAsyncDisplayError.Call();
2515 bool SbaXDataBrowserController::isLoaded() const
2517 return m_xLoadable.is() && m_xLoadable->isLoaded();
2520 bool SbaXDataBrowserController::isValidCursor() const
2522 if (!m_xColumnsSupplier.is())
2523 return false;
2524 Reference< css::container::XNameAccess > xCols = m_xColumnsSupplier->getColumns();
2525 if (!xCols.is() || !xCols->hasElements())
2526 return false;
2528 bool bIsValid = !(m_xRowSet->isBeforeFirst() || m_xRowSet->isAfterLast());
2529 if ( !bIsValid )
2531 Reference<XPropertySet> xProp(m_xRowSet,UNO_QUERY);
2532 bIsValid = ::cppu::any2bool(xProp->getPropertyValue(PROPERTY_ISNEW));
2533 if ( !bIsValid )
2535 bIsValid = m_xParser.is();
2538 return bIsValid;
2541 sal_Int16 SbaXDataBrowserController::getCurrentColumnPosition() const
2543 Reference< css::form::XGrid > xGrid(getBrowserView()->getGridControl(), UNO_QUERY);
2544 sal_Int16 nViewPos = -1;
2547 if ( xGrid.is() )
2548 nViewPos = xGrid->getCurrentColumnPosition();
2550 catch(Exception&) {}
2551 return nViewPos;
2554 void SbaXDataBrowserController::setCurrentColumnPosition( sal_Int16 _nPos )
2556 Reference< css::form::XGrid > xGrid(getBrowserView()->getGridControl(), UNO_QUERY);
2559 if ( -1 != _nPos )
2560 xGrid->setCurrentColumnPosition(_nPos);
2562 catch(Exception&) {}
2565 void SbaXDataBrowserController::BeforeDrop()
2567 Reference< css::sdb::XSQLErrorBroadcaster > xFormError(getRowSet(), UNO_QUERY);
2568 if (xFormError.is())
2569 xFormError->removeSQLErrorListener(static_cast<css::sdb::XSQLErrorListener*>(this));
2572 void SbaXDataBrowserController::AfterDrop()
2574 Reference< css::sdb::XSQLErrorBroadcaster > xFormError(getRowSet(), UNO_QUERY);
2575 if (xFormError.is())
2576 xFormError->addSQLErrorListener(static_cast<css::sdb::XSQLErrorListener*>(this));
2579 void SbaXDataBrowserController::addColumnListeners(const Reference< css::awt::XControlModel > & _xGridControlModel)
2581 // ... all the grid columns
2582 Reference< css::container::XIndexContainer > xColumns(_xGridControlModel, UNO_QUERY);
2583 if (xColumns.is())
2585 sal_Int32 nCount = xColumns->getCount();
2586 for (sal_Int32 i=0; i < nCount; ++i)
2588 Reference< XPropertySet > xCol(xColumns->getByIndex(i),UNO_QUERY);
2589 AddColumnListener(xCol);
2594 } // namespace dbaui
2596 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */