fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / dbaccess / source / ui / browser / genericcontroller.cxx
blob4d2bf1503f70677b5f44f1d13a3fb792f2fbb685
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 <dbaccess/genericcontroller.hxx>
21 #include <comphelper/uno3.hxx>
22 #include <toolkit/awt/vclxwindow.hxx>
23 #include "browserids.hxx"
24 #include <vcl/svapp.hxx>
25 #include <toolkit/helper/vclunohelper.hxx>
26 #include <dbaccess/dataview.hxx>
27 #include <tools/diagnose_ex.h>
28 #include <osl/diagnose.h>
29 #include "dbustrings.hrc"
30 #include <vcl/stdtext.hxx>
31 #include <comphelper/processfactory.hxx>
32 #include <cppuhelper/typeprovider.hxx>
33 #include <framework/titlehelper.hxx>
34 #include <comphelper/sequence.hxx>
35 #include <comphelper/extract.hxx>
36 #include <cppuhelper/supportsservice.hxx>
37 #include <com/sun/star/sdbc/XDataSource.hpp>
38 #include <com/sun/star/sdb/DatabaseContext.hpp>
39 #include <com/sun/star/sdb/SQLContext.hpp>
40 #include <com/sun/star/sdb/XCompletedConnection.hpp>
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <com/sun/star/task/XInteractionHandler.hpp>
43 #include <com/sun/star/util/URLTransformer.hpp>
44 #include <com/sun/star/util/XCloseable.hpp>
45 #include "UITools.hxx"
46 #include "commontypes.hxx"
48 #include <vcl/waitobj.hxx>
49 #include <svl/urihelper.hxx>
50 #include "datasourceconnector.hxx"
51 #include <unotools/moduleoptions.hxx>
52 #include <com/sun/star/frame/FrameSearchFlag.hpp>
53 #include <com/sun/star/frame/status/Visibility.hpp>
54 #include <com/sun/star/util/XModifiable.hpp>
55 #include <rtl/ustring.hxx>
56 #include <algorithm>
57 #include <o3tl/compat_functional.hxx>
58 #include <boost/scoped_ptr.hpp>
59 #include <cppuhelper/implbase1.hxx>
60 #include <limits>
61 #include <unordered_map>
63 using namespace ::com::sun::star;
64 using namespace ::com::sun::star::uno;
65 using namespace ::com::sun::star::beans;
66 using namespace ::com::sun::star::frame;
67 using namespace ::com::sun::star::frame::status;
68 using namespace ::com::sun::star::util;
69 using namespace ::com::sun::star::lang;
70 using namespace ::com::sun::star::container;
71 using namespace ::com::sun::star::sdbc;
72 using namespace ::com::sun::star::sdb;
73 using namespace ::com::sun::star::task;
74 using namespace ::com::sun::star::awt;
75 using namespace ::dbtools;
76 using namespace ::comphelper;
78 #define ALL_FEATURES -1
79 #define FIRST_USER_DEFINED_FEATURE ( ::std::numeric_limits< sal_uInt16 >::max() - 1000 )
80 #define LAST_USER_DEFINED_FEATURE ( ::std::numeric_limits< sal_uInt16 >::max() )
82 typedef std::unordered_map< sal_Int16, sal_Int16 > CommandHashMap;
83 typedef ::std::list< DispatchInformation > DispatchInfoList;
85 namespace dbaui
88 // UserDefinedFeatures
89 class UserDefinedFeatures
91 public:
92 UserDefinedFeatures( const Reference< XController >& _rxController );
94 static FeatureState getState( const URL& _rFeatureURL );
95 void execute( const URL& _rFeatureURL, const Sequence< PropertyValue>& _rArgs );
97 private:
98 ::com::sun::star::uno::WeakReference< XController > m_aController;
101 UserDefinedFeatures::UserDefinedFeatures( const Reference< XController >& _rxController )
102 :m_aController( _rxController )
106 FeatureState UserDefinedFeatures::getState( const URL& /*_rFeatureURL*/ )
108 // for now, enable all the time
109 // TODO: we should ask the dispatcher. However, this is laborious, since you cannot ask a dispatcher
110 // directly, but need to add a status listener.
111 FeatureState aState;
112 aState.bEnabled = true;
113 return aState;
116 void UserDefinedFeatures::execute( const URL& _rFeatureURL, const Sequence< PropertyValue>& _rArgs )
120 Reference< XController > xController( Reference< XController >(m_aController), UNO_SET_THROW );
121 Reference< XDispatchProvider > xDispatchProvider( xController->getFrame(), UNO_QUERY_THROW );
122 Reference< XDispatch > xDispatch( xDispatchProvider->queryDispatch(
123 _rFeatureURL,
124 OUString( "_self" ),
125 FrameSearchFlag::AUTO
126 ) );
128 if ( xDispatch == xController )
130 SAL_WARN("dbaccess.ui", "UserDefinedFeatures::execute: the controller shouldn't be the dispatcher here!" );
131 xDispatch.clear();
134 if ( xDispatch.is() )
135 xDispatch->dispatch( _rFeatureURL, _rArgs );
137 catch( const Exception& )
139 DBG_UNHANDLED_EXCEPTION();
143 // OGenericUnoController_Data
144 struct OGenericUnoController_Data
146 ::sfx2::UserInputInterception m_aUserInputInterception;
147 UserDefinedFeatures m_aUserDefinedFeatures;
149 OGenericUnoController_Data( OGenericUnoController& _rController, ::osl::Mutex& _rMutex )
150 :m_aUserInputInterception( _rController, _rMutex )
151 ,m_aUserDefinedFeatures( _rController.getXController() )
156 // OGenericUnoController
157 OGenericUnoController::OGenericUnoController(const Reference< XComponentContext >& _rM)
158 :OGenericUnoController_Base( getMutex() )
159 ,m_pView(NULL)
160 #ifdef DBG_UTIL
161 ,m_bDescribingSupportedFeatures( false )
162 #endif
163 ,m_aAsyncInvalidateAll(LINK(this, OGenericUnoController, OnAsyncInvalidateAll))
164 ,m_aAsyncCloseTask(LINK(this, OGenericUnoController, OnAsyncCloseTask))
165 ,m_xContext(_rM)
166 ,m_aCurrentFrame( *this )
167 ,m_bPreview(false)
168 ,m_bReadOnly(false)
169 ,m_bCurrentlyModified(false)
170 ,m_bExternalTitle(false)
172 osl_atomic_increment( &m_refCount );
174 m_pData.reset( new OGenericUnoController_Data( *this, getMutex() ) );
176 osl_atomic_decrement( &m_refCount );
181 m_xUrlTransformer = URLTransformer::create(_rM);
183 catch(Exception&)
185 DBG_UNHANDLED_EXCEPTION();
189 #ifdef _MSC_VER
191 #pragma warning(push)
192 #pragma warning(disable:4702)
194 OGenericUnoController::OGenericUnoController()
195 :OGenericUnoController_Base( getMutex() )
196 ,m_pView(NULL)
197 #ifdef DBG_UTIL
198 ,m_bDescribingSupportedFeatures( false )
199 #endif
200 ,m_aAsyncInvalidateAll(LINK(this, OGenericUnoController, OnAsyncInvalidateAll))
201 ,m_aAsyncCloseTask(LINK(this, OGenericUnoController, OnAsyncCloseTask))
202 ,m_aCurrentFrame( *this )
203 ,m_bPreview(sal_False)
204 ,m_bReadOnly(sal_False)
205 ,m_bCurrentlyModified(sal_False)
207 SAL_WARN("dbaccess.ui", "OGenericUnoController::OGenericUnoController: illegal call!" );
208 // This ctor only exists because the MSVC compiler complained about an unresolved external
209 // symbol. It should not be used at all. Since using it yields strange runtime problems,
210 // we simply abort here.
211 abort();
214 #pragma warning(pop)
216 #endif
218 OGenericUnoController::~OGenericUnoController()
223 bool OGenericUnoController::Construct(vcl::Window* /*pParent*/)
225 OSL_ENSURE( getView(), "the view is NULL!" );
227 if ( getView() )
229 getView()->Construct();
230 getView()->Show();
233 m_aSupportedFeatures.clear();
234 fillSupportedFeatures();
236 // create the database context
237 OSL_ENSURE(getORB().is(), "OGenericUnoController::Construct need a service factory!");
240 m_xDatabaseContext = DatabaseContext::create(getORB());
242 catch(const Exception&)
244 SAL_WARN("dbaccess.ui","OGenericUnoController::Construct: could not create (or start listening at) the database context!");
245 // at least notify the user. Though the whole component does not make any sense without the database context ...
246 ShowServiceNotAvailableError(getView(), OUString("com.sun.star.sdb.DatabaseContext"), true);
249 return true;
252 IMPL_LINK_NOARG(OGenericUnoController, OnAsyncInvalidateAll)
254 if ( !OGenericUnoController_Base::rBHelper.bInDispose && !OGenericUnoController_Base::rBHelper.bDisposed )
255 InvalidateFeature_Impl();
256 return 0L;
259 void OGenericUnoController::impl_initialize()
263 void SAL_CALL OGenericUnoController::initialize( const Sequence< Any >& aArguments ) throw(Exception, RuntimeException, std::exception)
265 SolarMutexGuard aSolarGuard;
266 ::osl::MutexGuard aGuard( getMutex() );
268 Reference< XWindow > xParent;
269 Reference< XFrame > xFrame;
271 PropertyValue aValue;
272 const Any* pIter = aArguments.getConstArray();
273 const Any* pEnd = pIter + aArguments.getLength();
275 for ( ; pIter != pEnd; ++pIter )
277 if ( ( *pIter >>= aValue ) && aValue.Name == "Frame" )
279 xFrame.set(aValue.Value,UNO_QUERY_THROW);
281 else if ( ( *pIter >>= aValue ) && aValue.Name == "Preview" )
283 aValue.Value >>= m_bPreview;
284 m_bReadOnly = true;
289 if ( !xFrame.is() )
290 throw IllegalArgumentException("need a frame", *this, 1 );
292 xParent = xFrame->getContainerWindow();
293 VCLXWindow* pParentComponent = VCLXWindow::GetImplementation(xParent);
294 VclPtr< vcl::Window > pParentWin = pParentComponent ? pParentComponent->GetWindow() : VclPtr< vcl::Window >();
295 if (!pParentWin)
297 throw IllegalArgumentException("Parent window is null", *this, 1 );
300 m_aInitParameters.assign( aArguments );
301 Construct( pParentWin );
303 ODataView* pView = getView();
304 if ( !pView )
305 throw RuntimeException("unable to create a view", *this );
307 if ( m_bReadOnly || m_bPreview )
308 pView->EnableInput( false );
310 impl_initialize();
312 catch(Exception&)
314 // no one clears my view if I won't
315 m_pView = NULL;
316 throw;
320 void SAL_CALL OGenericUnoController::acquire( ) throw ()
322 OGenericUnoController_Base::acquire();
325 void SAL_CALL OGenericUnoController::release( ) throw ()
327 OGenericUnoController_Base::release();
330 void OGenericUnoController::startFrameListening( const Reference< XFrame >& _rxFrame )
332 if ( _rxFrame.is() )
333 _rxFrame->addFrameActionListener( this );
336 void OGenericUnoController::stopFrameListening( const Reference< XFrame >& _rxFrame )
338 if ( _rxFrame.is() )
339 _rxFrame->removeFrameActionListener( this );
342 void OGenericUnoController::disposing(const EventObject& Source) throw( RuntimeException, std::exception )
344 // our frame ?
345 if ( Source.Source == getFrame() )
346 stopFrameListening( getFrame() );
349 void OGenericUnoController::modified(const EventObject& aEvent) throw( RuntimeException, std::exception )
351 ::osl::MutexGuard aGuard( getMutex() );
352 if ( !isDataSourceReadOnly() )
354 Reference<XModifiable> xModi(aEvent.Source,UNO_QUERY);
355 if ( xModi.is() )
356 m_bCurrentlyModified = xModi->isModified(); // can only be reset by save
357 else
358 m_bCurrentlyModified = true;
360 InvalidateFeature(ID_BROWSER_SAVEDOC);
361 InvalidateFeature(ID_BROWSER_UNDO);
364 Reference< XWindow > SAL_CALL OGenericUnoController::getComponentWindow() throw (RuntimeException, std::exception)
366 SolarMutexGuard g;
367 return VCLUnoHelper::GetInterface( getView() );
370 OUString SAL_CALL OGenericUnoController::getViewControllerName() throw (::com::sun::star::uno::RuntimeException, std::exception)
372 return OUString( "Default" );
375 Sequence< PropertyValue > SAL_CALL OGenericUnoController::getCreationArguments() throw (RuntimeException, std::exception)
377 // currently we do not support any creation args, so anything passed to XModel2::createViewController would be
378 // lost, so we can equally return an empty sequence here
379 return Sequence< PropertyValue >();
382 void OGenericUnoController::attachFrame( const Reference< XFrame >& _rxFrame ) throw( RuntimeException, std::exception )
384 SolarMutexGuard aSolarGuard;
385 ::osl::MutexGuard aGuard( getMutex() );
387 stopFrameListening( m_aCurrentFrame.getFrame() );
388 Reference< XFrame > xFrame = m_aCurrentFrame.attachFrame( _rxFrame );
389 startFrameListening( xFrame );
391 loadMenu( xFrame );
393 if ( getView() )
394 getView()->attachFrame( xFrame );
397 struct CommandCollector : public ::std::unary_function< SupportedFeatures::value_type, void>
399 sal_uInt16 m_nFeature;
400 StringBag& m_rFeatureCommands;
401 CommandCollector( sal_uInt16 _nFeature, StringBag& _rFeatureCommands )
402 :m_nFeature ( _nFeature )
403 ,m_rFeatureCommands( _rFeatureCommands )
407 void operator() ( const SupportedFeatures::value_type& lhs )
409 if ( lhs.second.nFeatureId == m_nFeature )
410 m_rFeatureCommands.insert( lhs.first );
414 namespace
416 typedef ::std::vector< Any > States;
418 void lcl_notifyMultipleStates( XStatusListener& _rListener, FeatureStateEvent& _rEvent, const States& _rStates )
420 for ( States::const_iterator state = _rStates.begin();
421 state != _rStates.end();
422 ++state
425 _rEvent.State = *state;
426 _rListener.statusChanged( _rEvent );
430 void lcl_collectStates( const FeatureState& _rFeatureState, States& _out_rStates )
432 // order matters, due to a bug in framework which resets the check state when any non-boolean event
433 // arrives
434 // #i68215# is the bug to (re-)introduce this "ordered" notification here
435 // #i67882# is the bug which was caused by the real fix which we did in framework
436 // #i68216# is the bug which requests to fix the code in Draw which relies on
437 // framework's implementation details
438 if ( !!_rFeatureState.sTitle )
439 _out_rStates.push_back( makeAny( *_rFeatureState.sTitle ) );
440 if ( !!_rFeatureState.bChecked )
441 _out_rStates.push_back( makeAny( *_rFeatureState.bChecked ) );
442 if ( !!_rFeatureState.bInvisible )
443 _out_rStates.push_back( makeAny( Visibility( !*_rFeatureState.bInvisible ) ) );
444 if ( _rFeatureState.aValue.hasValue() )
445 _out_rStates.push_back( _rFeatureState.aValue );
446 if ( _out_rStates.empty() )
447 _out_rStates.push_back( Any() );
451 void OGenericUnoController::ImplBroadcastFeatureState(const OUString& _rFeature, const Reference< XStatusListener > & xListener, bool _bIgnoreCache)
453 sal_uInt16 nFeat = m_aSupportedFeatures[ _rFeature ].nFeatureId;
454 FeatureState aFeatState( GetState( nFeat ) );
456 FeatureState& rCachedState = m_aStateCache[nFeat]; // creates if necessary
457 if ( !_bIgnoreCache )
459 // check if we really need to notify the listeners : this method may be called much more often than needed, so check
460 // the cached state of the feature
461 bool bAlreadyCached = ( m_aStateCache.find(nFeat) != m_aStateCache.end() );
462 if ( bAlreadyCached )
463 if ( ( rCachedState.bEnabled == aFeatState.bEnabled )
464 && ( rCachedState.bChecked == aFeatState.bChecked )
465 && ( rCachedState.bInvisible == aFeatState.bInvisible )
466 && ( rCachedState.sTitle == aFeatState.sTitle )
468 return;
470 rCachedState = aFeatState;
472 FeatureStateEvent aEvent;
473 aEvent.FeatureURL.Complete = _rFeature;
474 if (m_xUrlTransformer.is())
475 m_xUrlTransformer->parseStrict(aEvent.FeatureURL);
476 aEvent.Source = (XDispatch*)this;
477 aEvent.IsEnabled = aFeatState.bEnabled;
479 // collect all states to be notified
480 States aStates;
481 lcl_collectStates( aFeatState, aStates );
483 // a special listener ?
484 if ( xListener.is() )
485 lcl_notifyMultipleStates( *xListener.get(), aEvent, aStates );
486 else
487 { // no -> iterate through all listeners responsible for the URL
488 StringBag aFeatureCommands;
489 ::std::for_each(
490 m_aSupportedFeatures.begin(),
491 m_aSupportedFeatures.end(),
492 CommandCollector( nFeat, aFeatureCommands )
495 // it is possible that listeners are registered or revoked while
496 // we are notifying them, so we must use a copy of m_arrStatusListener, not
497 // m_arrStatusListener itself
498 Dispatch aNotifyLoop( m_arrStatusListener );
499 Dispatch::iterator iterSearch = aNotifyLoop.begin();
500 Dispatch::iterator iterEnd = aNotifyLoop.end();
502 while (iterSearch != iterEnd)
504 DispatchTarget& rCurrent = *iterSearch;
505 if ( aFeatureCommands.find( rCurrent.aURL.Complete ) != aFeatureCommands.end() )
507 aEvent.FeatureURL = rCurrent.aURL;
508 lcl_notifyMultipleStates( *rCurrent.xListener.get(), aEvent, aStates );
510 ++iterSearch;
516 bool OGenericUnoController::isFeatureSupported( sal_Int32 _nId )
518 SupportedFeatures::iterator aFeaturePos = ::std::find_if(
519 m_aSupportedFeatures.begin(),
520 m_aSupportedFeatures.end(),
521 ::std::bind2nd( CompareFeatureById(), _nId )
524 return ( m_aSupportedFeatures.end() != aFeaturePos && !aFeaturePos->first.isEmpty());
527 void OGenericUnoController::InvalidateFeature_Impl()
529 #ifdef DBG_UTIL
530 static sal_Int32 s_nRecursions = 0;
531 ++s_nRecursions;
532 #endif
534 bool bEmpty = true;
535 FeatureListener aNextFeature;
537 ::osl::MutexGuard aGuard( m_aFeatureMutex);
538 bEmpty = m_aFeaturesToInvalidate.empty();
539 if (!bEmpty)
540 aNextFeature = m_aFeaturesToInvalidate.front();
542 while(!bEmpty)
544 if ( ALL_FEATURES == aNextFeature.nId )
546 InvalidateAll_Impl();
547 break;
549 else
551 SupportedFeatures::iterator aFeaturePos = ::std::find_if(
552 m_aSupportedFeatures.begin(),
553 m_aSupportedFeatures.end(),
554 ::std::bind2nd( CompareFeatureById(), aNextFeature.nId )
557 #if OSL_DEBUG_LEVEL > 0
558 if ( m_aSupportedFeatures.end() == aFeaturePos )
560 OString sMessage( "OGenericUnoController::InvalidateFeature_Impl: feature id " );
561 sMessage += OString::number( aNextFeature.nId );
562 sMessage += OString( " has been invalidated, but is not supported!" );
563 SAL_WARN("dbaccess.ui", sMessage.getStr() );
565 #endif
566 if ( m_aSupportedFeatures.end() != aFeaturePos )
567 // we really know this feature
568 ImplBroadcastFeatureState( aFeaturePos->first, aNextFeature.xListener, aNextFeature.bForceBroadcast );
571 ::osl::MutexGuard aGuard( m_aFeatureMutex);
572 m_aFeaturesToInvalidate.pop_front();
573 bEmpty = m_aFeaturesToInvalidate.empty();
574 if (!bEmpty)
575 aNextFeature = m_aFeaturesToInvalidate.front();
578 #ifdef DBG_UTIL
579 --s_nRecursions;
580 #endif
583 void OGenericUnoController::ImplInvalidateFeature( sal_Int32 _nId, const Reference< XStatusListener >& _xListener, bool _bForceBroadcast )
585 #if OSL_DEBUG_LEVEL > 0
586 if ( _nId != -1 )
588 SupportedFeatures::iterator aFeaturePos = ::std::find_if(
589 m_aSupportedFeatures.begin(),
590 m_aSupportedFeatures.end(),
591 ::std::bind2nd( CompareFeatureById(), _nId )
593 OSL_ENSURE( aFeaturePos != m_aSupportedFeatures.end(), "OGenericUnoController::ImplInvalidateFeature: invalidating an unsupported feature is suspicious, at least!" );
595 #endif
597 FeatureListener aListener;
598 aListener.nId = _nId;
599 aListener.xListener = _xListener;
600 aListener.bForceBroadcast = _bForceBroadcast;
602 bool bWasEmpty;
604 ::osl::MutexGuard aGuard( m_aFeatureMutex );
605 bWasEmpty = m_aFeaturesToInvalidate.empty();
606 m_aFeaturesToInvalidate.push_back( aListener );
609 if ( bWasEmpty )
610 m_aAsyncInvalidateAll.Call();
613 void OGenericUnoController::InvalidateFeature(sal_uInt16 _nId, const Reference< XStatusListener > & _xListener, bool _bForceBroadcast)
615 ImplInvalidateFeature( _nId, _xListener, _bForceBroadcast );
618 void OGenericUnoController::InvalidateAll()
620 ImplInvalidateFeature( ALL_FEATURES, NULL, true );
623 void OGenericUnoController::InvalidateAll_Impl()
625 // invalidate all supported features
627 for ( SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.begin();
628 aIter != m_aSupportedFeatures.end();
629 ++aIter
631 ImplBroadcastFeatureState( aIter->first, NULL, true );
634 ::osl::MutexGuard aGuard( m_aFeatureMutex);
635 OSL_ENSURE(m_aFeaturesToInvalidate.size(), "OGenericUnoController::InvalidateAll_Impl: to be called from within InvalidateFeature_Impl only!");
636 m_aFeaturesToInvalidate.pop_front();
637 if(!m_aFeaturesToInvalidate.empty())
638 m_aAsyncInvalidateAll.Call();
642 Reference< XDispatch > OGenericUnoController::queryDispatch(const URL& aURL, const OUString& aTargetFrameName, sal_Int32 nSearchFlags) throw( RuntimeException, std::exception )
644 Reference< XDispatch > xReturn;
646 OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::queryDispatch: shouldn't this be filled at construction time?" );
647 if ( m_aSupportedFeatures.empty() )
648 fillSupportedFeatures();
650 // URL's we can handle ourself?
651 if ( aURL.Complete == ".uno:FormSlots/ConfirmDeletion"
652 || ( ( m_aSupportedFeatures.find( aURL.Complete ) != m_aSupportedFeatures.end() )
653 && !isUserDefinedFeature( aURL.Complete )
657 xReturn = this;
659 // no? -> ask the slave dispatcher
660 else if ( m_xSlaveDispatcher.is() )
662 xReturn = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags);
665 // outta here
666 return xReturn;
669 Sequence< Reference< XDispatch > > OGenericUnoController::queryDispatches(const Sequence< DispatchDescriptor >& aDescripts) throw( RuntimeException, std::exception )
671 Sequence< Reference< XDispatch > > aReturn;
672 sal_Int32 nLen = aDescripts.getLength();
673 if ( nLen )
675 aReturn.realloc( nLen );
676 Reference< XDispatch >* pReturn = aReturn.getArray();
677 const Reference< XDispatch >* pReturnEnd = aReturn.getArray() + nLen;
678 const DispatchDescriptor* pDescripts = aDescripts.getConstArray();
680 for ( ; pReturn != pReturnEnd; ++ pReturn, ++pDescripts )
682 *pReturn = queryDispatch( pDescripts->FeatureURL, pDescripts->FrameName, pDescripts->SearchFlags );
686 return aReturn;
689 Reference< XDispatchProvider > OGenericUnoController::getSlaveDispatchProvider() throw( RuntimeException, std::exception )
691 return m_xSlaveDispatcher;
694 void OGenericUnoController::setSlaveDispatchProvider(const Reference< XDispatchProvider > & _xNewProvider) throw( RuntimeException, std::exception )
696 m_xSlaveDispatcher = _xNewProvider;
699 Reference< XDispatchProvider > OGenericUnoController::getMasterDispatchProvider() throw( RuntimeException, std::exception )
701 return m_xMasterDispatcher;
704 void OGenericUnoController::setMasterDispatchProvider(const Reference< XDispatchProvider > & _xNewProvider) throw( RuntimeException, std::exception )
706 m_xMasterDispatcher = _xNewProvider;
709 void OGenericUnoController::dispatch(const URL& _aURL, const Sequence< PropertyValue >& aArgs) throw(RuntimeException, std::exception)
711 SolarMutexGuard aSolarGuard;
712 // The SolarMutex is not locked anymore when the framework calls into
713 // here. So, lock it ourself. The real solution would be to lock it only in the places
714 // where it's needed, but a) this might turn out difficult, since we then also need to care
715 // for locking in the proper order (SolarMutex and m_aMutex), and b) this would be too many places
716 // for the time frame of the fix.
717 // #i52602#
718 executeChecked(_aURL,aArgs);
721 void OGenericUnoController::addStatusListener(const Reference< XStatusListener > & aListener, const URL& _rURL) throw(RuntimeException, std::exception)
723 // parse the URL now and here, this saves later parsing in each notification round
724 URL aParsedURL( _rURL );
725 if ( m_xUrlTransformer.is() )
726 m_xUrlTransformer->parseStrict( aParsedURL );
728 // remember the listener together with the URL
729 m_arrStatusListener.insert( m_arrStatusListener.end(), DispatchTarget( aParsedURL, aListener ) );
731 // initially broadcast the state
732 ImplBroadcastFeatureState( aParsedURL.Complete, aListener, true );
733 // force the new state to be broadcast to the new listener
736 void OGenericUnoController::removeStatusListener(const Reference< XStatusListener > & aListener, const URL& _rURL) throw(RuntimeException, std::exception)
738 Dispatch::iterator iterSearch = m_arrStatusListener.begin();
740 bool bRemoveForAll = _rURL.Complete.isEmpty();
741 while ( iterSearch != m_arrStatusListener.end() )
743 DispatchTarget& rCurrent = *iterSearch;
744 if ( (rCurrent.xListener == aListener)
745 && ( bRemoveForAll
746 || (rCurrent.aURL.Complete.equals(_rURL.Complete))
750 m_arrStatusListener.erase( iterSearch++ );
751 if (!bRemoveForAll)
752 // remove the listener only for the given URL, so we can exit the loop after deletion
753 break;
755 else
756 ++iterSearch;
759 OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::removeStatusListener: shouldn't this be filled at construction time?" );
760 if ( m_aSupportedFeatures.empty() )
761 fillSupportedFeatures();
763 SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find(_rURL.Complete);
764 if (aIter != m_aSupportedFeatures.end())
765 { // clear the cache for that feature
766 StateCache::iterator aCachePos = m_aStateCache.find( aIter->second.nFeatureId );
767 if ( aCachePos != m_aStateCache.end() )
768 m_aStateCache.erase( aCachePos );
771 // now remove the listener from the deque
772 ::osl::MutexGuard aGuard( m_aFeatureMutex );
773 m_aFeaturesToInvalidate.erase(
774 ::std::remove_if( m_aFeaturesToInvalidate.begin(),
775 m_aFeaturesToInvalidate.end(),
776 ::std::bind2nd(FindFeatureListener(),aListener))
777 ,m_aFeaturesToInvalidate.end());
780 void OGenericUnoController::releaseNumberForComponent()
784 Reference< XUntitledNumbers > xUntitledProvider(getPrivateModel(), UNO_QUERY );
785 if ( xUntitledProvider.is() )
786 xUntitledProvider->releaseNumberForComponent(static_cast<XWeak*>(this));
788 catch( const Exception& )
790 // NII
794 void OGenericUnoController::disposing()
797 EventObject aDisposeEvent;
798 aDisposeEvent.Source = static_cast<XWeak*>(this);
799 Dispatch aStatusListener = m_arrStatusListener;
800 Dispatch::iterator aEnd = aStatusListener.end();
801 for (Dispatch::iterator aIter = aStatusListener.begin(); aIter != aEnd; ++aIter)
803 aIter->xListener->disposing(aDisposeEvent);
805 m_arrStatusListener.clear();
808 m_xDatabaseContext = NULL;
810 ::osl::MutexGuard aGuard( m_aFeatureMutex);
811 m_aAsyncInvalidateAll.CancelCall();
812 m_aFeaturesToInvalidate.clear();
815 releaseNumberForComponent();
817 // check out from all the objects we are listening
818 // the frame
819 stopFrameListening( m_aCurrentFrame.getFrame() );
820 m_aCurrentFrame.attachFrame( NULL );
822 m_xMasterDispatcher = NULL;
823 m_xSlaveDispatcher = NULL;
824 m_xTitleHelper.clear();
825 m_xUrlTransformer.clear();
826 m_aInitParameters.clear();
829 void SAL_CALL OGenericUnoController::addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException, std::exception)
831 // disambiguate
832 OGenericUnoController_Base::WeakComponentImplHelperBase::addEventListener( xListener );
835 void SAL_CALL OGenericUnoController::removeEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException, std::exception)
837 // disambiguate
838 OGenericUnoController_Base::WeakComponentImplHelperBase::removeEventListener( xListener );
841 void OGenericUnoController::frameAction(const FrameActionEvent& aEvent) throw( RuntimeException, std::exception )
843 ::osl::MutexGuard aGuard( getMutex() );
844 if ( aEvent.Frame == m_aCurrentFrame.getFrame() )
845 m_aCurrentFrame.frameAction( aEvent.Action );
848 void OGenericUnoController::implDescribeSupportedFeature( const sal_Char* _pAsciiCommandURL,
849 sal_uInt16 _nFeatureId, sal_Int16 _nCommandGroup )
851 #ifdef DBG_UTIL
852 OSL_ENSURE( m_bDescribingSupportedFeatures, "OGenericUnoController::implDescribeSupportedFeature: bad timing for this call!" );
853 #endif
854 OSL_PRECOND( _nFeatureId < FIRST_USER_DEFINED_FEATURE, "OGenericUnoController::implDescribeSupportedFeature: invalid feature id!" );
856 ControllerFeature aFeature;
857 aFeature.Command = OUString::createFromAscii( _pAsciiCommandURL );
858 aFeature.nFeatureId = _nFeatureId;
859 aFeature.GroupId = _nCommandGroup;
861 #if OSL_DEBUG_LEVEL > 0
862 OSL_ENSURE( m_aSupportedFeatures.find( aFeature.Command ) == m_aSupportedFeatures.end(),
863 "OGenericUnoController::implDescribeSupportedFeature: this feature is already there!" );
864 #endif
865 m_aSupportedFeatures[ aFeature.Command ] = aFeature;
868 void OGenericUnoController::describeSupportedFeatures()
870 // add all supported features
871 implDescribeSupportedFeature( ".uno:Copy", ID_BROWSER_COPY, CommandGroup::EDIT );
872 implDescribeSupportedFeature( ".uno:Cut", ID_BROWSER_CUT, CommandGroup::EDIT );
873 implDescribeSupportedFeature( ".uno:Paste", ID_BROWSER_PASTE, CommandGroup::EDIT );
874 implDescribeSupportedFeature( ".uno:ClipboardFormatItems", ID_BROWSER_CLIPBOARD_FORMAT_ITEMS );
875 implDescribeSupportedFeature( ".uno:DSBEditDoc", ID_BROWSER_EDITDOC, CommandGroup::DOCUMENT );
878 FeatureState OGenericUnoController::GetState( sal_uInt16 _nId ) const
880 FeatureState aReturn;
881 // (disabled automatically)
883 switch ( _nId )
885 case ID_BROWSER_UNDO:
886 case ID_BROWSER_SAVEDOC:
887 aReturn.bEnabled = true;
888 break;
889 default:
890 aReturn = UserDefinedFeatures::getState( getURLForId( _nId ) );
891 break;
894 return aReturn;
897 void OGenericUnoController::Execute( sal_uInt16 _nId, const Sequence< PropertyValue>& _rArgs )
899 OSL_ENSURE( isUserDefinedFeature( _nId ),
900 "OGenericUnoController::Execute: responsible for user defined features only!" );
902 // user defined features can be handled by dispatch interceptors resp. protocol handlers only.
903 // So, we need to do a queryDispatch, and dispatch the URL
904 m_pData->m_aUserDefinedFeatures.execute( getURLForId( _nId ), _rArgs );
907 URL OGenericUnoController::getURLForId(sal_Int32 _nId) const
909 URL aReturn;
910 if ( m_xUrlTransformer.is() )
912 SupportedFeatures::const_iterator aIter = ::std::find_if(
913 m_aSupportedFeatures.begin(),
914 m_aSupportedFeatures.end(),
915 ::std::bind2nd( CompareFeatureById(), _nId )
918 if ( m_aSupportedFeatures.end() != aIter && !aIter->first.isEmpty() )
920 aReturn.Complete = aIter->first;
921 m_xUrlTransformer->parseStrict( aReturn );
924 return aReturn;
927 bool OGenericUnoController::isUserDefinedFeature( const sal_uInt16 _nFeatureId )
929 return ( _nFeatureId >= FIRST_USER_DEFINED_FEATURE ) && ( _nFeatureId < LAST_USER_DEFINED_FEATURE );
932 bool OGenericUnoController::isUserDefinedFeature( const OUString& _rFeatureURL ) const
934 SupportedFeatures::const_iterator pos = m_aSupportedFeatures.find( _rFeatureURL );
935 OSL_PRECOND( pos != m_aSupportedFeatures.end(),
936 "OGenericUnoController::isUserDefinedFeature: this is no supported feature at all!" );
938 return ( pos != m_aSupportedFeatures.end() ) && isUserDefinedFeature( pos->second.nFeatureId );
941 sal_Bool SAL_CALL OGenericUnoController::supportsService(const OUString& ServiceName) throw(RuntimeException, std::exception)
943 return cppu::supportsService(this, ServiceName);
946 void OGenericUnoController::startConnectionListening(const Reference< XConnection >& _rxConnection)
948 // we have to remove ourself before dispoing the connection
949 Reference< XComponent > xComponent(_rxConnection, UNO_QUERY);
950 if (xComponent.is())
951 xComponent->addEventListener(static_cast<XFrameActionListener*>(this));
954 void OGenericUnoController::stopConnectionListening(const Reference< XConnection >& _rxConnection)
956 // we have to remove ourself before dispoing the connection
957 Reference< XComponent > xComponent(_rxConnection, UNO_QUERY);
958 if (xComponent.is())
959 xComponent->removeEventListener(static_cast<XFrameActionListener*>(this));
962 Reference< XConnection > OGenericUnoController::connect( const Reference< XDataSource>& _xDataSource,
963 ::dbtools::SQLExceptionInfo* _pErrorInfo )
965 WaitObject aWaitCursor( getView() );
967 ODatasourceConnector aConnector( getORB(), getView(), OUString() );
968 Reference< XConnection > xConnection = aConnector.connect( _xDataSource, _pErrorInfo );
969 startConnectionListening( xConnection );
971 return xConnection;
974 Reference< XConnection > OGenericUnoController::connect( const OUString& _rDataSourceName,
975 const OUString& _rContextInformation, ::dbtools::SQLExceptionInfo* _pErrorInfo )
977 WaitObject aWaitCursor( getView() );
979 ODatasourceConnector aConnector( getORB(), getView(), _rContextInformation );
980 Reference<XConnection> xConnection = aConnector.connect( _rDataSourceName, _pErrorInfo );
981 startConnectionListening( xConnection );
983 return xConnection;
986 void OGenericUnoController::setView( const VclPtr<ODataView> &i_rView )
988 m_pView = i_rView;
991 void OGenericUnoController::clearView()
993 m_pView = NULL;
996 void OGenericUnoController::showError(const SQLExceptionInfo& _rInfo)
998 ::dbaui::showError(_rInfo,getView(),getORB());
1001 Reference< XLayoutManager > OGenericUnoController::getLayoutManager(const Reference< XFrame >& _xFrame)
1003 Reference< XPropertySet > xPropSet( _xFrame, UNO_QUERY );
1004 Reference< XLayoutManager > xLayoutManager;
1005 if ( xPropSet.is() )
1009 xLayoutManager.set(xPropSet->getPropertyValue("LayoutManager"),UNO_QUERY);
1011 catch ( Exception& )
1015 return xLayoutManager;
1018 void OGenericUnoController::loadMenu(const Reference< XFrame >& _xFrame)
1020 Reference< XLayoutManager > xLayoutManager = getLayoutManager(_xFrame);
1021 if ( xLayoutManager.is() )
1023 xLayoutManager->lock();
1024 xLayoutManager->createElement( OUString( "private:resource/menubar/menubar" ));
1025 xLayoutManager->createElement( OUString( "private:resource/toolbar/toolbar" ));
1026 xLayoutManager->unlock();
1027 xLayoutManager->doLayout();
1030 onLoadedMenu( xLayoutManager );
1033 void OGenericUnoController::onLoadedMenu(const Reference< XLayoutManager >& /*_xLayoutManager*/)
1035 // not interested in
1038 void OGenericUnoController::closeTask()
1040 m_aAsyncCloseTask.Call();
1043 IMPL_LINK_NOARG(OGenericUnoController, OnAsyncCloseTask)
1045 if ( !OGenericUnoController_Base::rBHelper.bInDispose )
1049 Reference< util::XCloseable > xCloseable( m_aCurrentFrame.getFrame(), UNO_QUERY_THROW );
1050 xCloseable->close( sal_False ); // false - holds the owner ship for this frame inside this object!
1052 catch( const Exception& )
1054 DBG_UNHANDLED_EXCEPTION();
1057 return 0L;
1060 Any SAL_CALL OGenericUnoController::getViewData() throw( RuntimeException, std::exception )
1062 return Any();
1065 void SAL_CALL OGenericUnoController::restoreViewData(const Any& /*Data*/) throw( RuntimeException, std::exception )
1069 Reference< XModel > SAL_CALL OGenericUnoController::getModel() throw( RuntimeException, std::exception )
1071 return Reference< XModel >();
1074 Reference< XFrame > SAL_CALL OGenericUnoController::getFrame() throw( RuntimeException, std::exception )
1076 ::osl::MutexGuard aGuard( getMutex() );
1077 return m_aCurrentFrame.getFrame();
1080 sal_Bool SAL_CALL OGenericUnoController::attachModel(const Reference< XModel > & /*xModel*/) throw( RuntimeException, std::exception )
1082 SAL_WARN("dbaccess.ui", "OGenericUnoController::attachModel: not supported!" );
1083 return sal_False;
1086 void OGenericUnoController::executeUnChecked(sal_uInt16 _nCommandId, const Sequence< PropertyValue >& aArgs)
1088 Execute(_nCommandId, aArgs);
1091 void OGenericUnoController::executeUnChecked(const util::URL& _rCommand, const Sequence< PropertyValue >& aArgs)
1093 OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::executeUnChecked: shouldn't this be filled at construction time?" );
1094 if ( m_aSupportedFeatures.empty() )
1095 fillSupportedFeatures();
1097 SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCommand.Complete );
1098 if (aIter != m_aSupportedFeatures.end())
1099 Execute( aIter->second.nFeatureId, aArgs );
1102 void OGenericUnoController::executeChecked(const util::URL& _rCommand, const Sequence< PropertyValue >& aArgs)
1104 OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::executeChecked: shouldn't this be filled at construction time?" );
1105 if ( m_aSupportedFeatures.empty() )
1106 fillSupportedFeatures();
1108 SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCommand.Complete );
1109 if ( aIter != m_aSupportedFeatures.end() )
1111 sal_uInt16 nFeatureId = aIter->second.nFeatureId;
1112 if ( GetState( nFeatureId ).bEnabled )
1113 Execute( nFeatureId, aArgs );
1117 namespace
1119 OUString lcl_getModuleHelpModuleName( const Reference< XFrame >& _rxFrame )
1121 const sal_Char* pReturn = NULL;
1125 // get the model of the document in the given frame
1126 Reference< XController > xController;
1127 if ( _rxFrame.is() )
1128 xController = _rxFrame->getController();
1129 Reference< XModel > xModel;
1130 if ( xController.is() )
1131 xModel = xController->getModel();
1132 Reference< XServiceInfo > xSI( xModel, UNO_QUERY );
1134 if ( !xSI.is() )
1135 { // try to go up the frame hierarchy
1137 Reference< XFrame > xParentFrame;
1138 if ( _rxFrame.is() )
1139 xParentFrame.set(_rxFrame->getCreator(), css::uno::UNO_QUERY);
1140 // did we find a parent frame? Which is no top-level frame?
1141 if ( xParentFrame.is() && !_rxFrame->isTop() )
1142 // TODO: to prevent framework assertions, re-insert this "isTop" once 98303 is fixed
1143 return lcl_getModuleHelpModuleName( xParentFrame );
1145 else
1147 #if OSL_DEBUG_LEVEL > 0
1148 Sequence< OUString > sServiceNames = xSI->getSupportedServiceNames();
1149 const OUString* pLoop = sServiceNames.getConstArray();
1150 for ( sal_Int32 i=0; i<sServiceNames.getLength(); ++i, ++pLoop )
1152 sal_Int32 nDummy = 0;
1153 (void)nDummy;
1155 #endif
1157 // check which service we know ....
1158 static const sal_Char* pTransTable[] = {
1159 "com.sun.star.sdb.OfficeDatabaseDocument","sdatabase",
1160 "com.sun.star.report.ReportDefinition","sdatabase",
1161 "com.sun.star.text.TextDocument", "swriter",
1162 "com.sun.star.sheet.SpreadsheetDocument", "scalc",
1163 "com.sun.star.presentation.PresentationDocument", "simpress",
1164 "com.sun.star.drawing.DrawingDocument", "sdraw",
1165 "com.sun.star.formula.FormularProperties", "smath",
1166 "com.sun.star.chart.ChartDocument", "schart"
1168 OSL_ENSURE( ( sizeof( pTransTable ) / sizeof( pTransTable[0] ) ) % 2 == 0,
1169 "lcl_getModuleHelpModuleName: odd size of translation table!" );
1171 // loop through the table
1172 sal_Int32 nTableEntries = ( sizeof( pTransTable ) / sizeof( pTransTable[0] ) ) / 2;
1173 const sal_Char** pDocumentService = pTransTable;
1174 const sal_Char** pHelpModuleName = pTransTable + 1;
1175 for ( sal_Int32 j=0; j<nTableEntries; ++j )
1177 if ( xSI->supportsService( OUString::createFromAscii( *pDocumentService ) ) )
1178 { // found a table entry which matches the model's services
1179 pReturn = *pHelpModuleName;
1180 break;
1183 ++pDocumentService; ++pDocumentService;
1184 ++pHelpModuleName; ++pHelpModuleName;
1188 if ( !pReturn )
1190 // could not determine the document type we're living in
1191 // ->fallback
1192 SvtModuleOptions aModOpt;
1193 if ( aModOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
1194 pReturn = "swriter";
1195 else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::EModule::DATABASE ) )
1196 pReturn = "sdatabase";
1197 else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
1198 pReturn = "scalc";
1199 else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
1200 pReturn = "simpress";
1201 else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
1202 pReturn = "sdraw";
1203 else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::EModule::MATH ) )
1204 pReturn = "smath";
1205 else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::EModule::CHART ) )
1206 pReturn = "schart";
1207 else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::EModule::BASIC ) )
1208 pReturn = "sbasic";
1209 else
1211 SAL_WARN("dbaccess.ui", "lcl_getModuleHelpModuleName: no installed module found" );
1215 catch( const Exception& )
1217 DBG_UNHANDLED_EXCEPTION();
1220 if ( !pReturn )
1221 pReturn = "swriter";
1223 return OUString::createFromAscii( pReturn );
1227 void OGenericUnoController::openHelpAgent(OUString const& _suHelpStringURL )
1229 OUString suURL(_suHelpStringURL);
1230 OUString sLanguage( "Language=" );
1231 if (suURL.indexOf(sLanguage) == -1)
1233 AppendConfigToken(suURL, false /* sal_False := add '&' */ );
1235 URL aURL;
1236 aURL.Complete = suURL;
1238 openHelpAgent( aURL );
1241 void OGenericUnoController::openHelpAgent(const OString& _sHelpId)
1243 openHelpAgent( createHelpAgentURL( lcl_getModuleHelpModuleName( getFrame() ), _sHelpId ) );
1246 void OGenericUnoController::openHelpAgent( const URL& _rURL )
1250 URL aURL( _rURL );
1252 if ( m_xUrlTransformer.is() )
1253 m_xUrlTransformer->parseStrict(aURL);
1255 Reference< XDispatchProvider > xDispProv( m_aCurrentFrame.getFrame(), UNO_QUERY );
1256 Reference< XDispatch > xHelpDispatch;
1257 if ( xDispProv.is() )
1258 xHelpDispatch = xDispProv->queryDispatch(aURL, OUString( "_helpagent" ), FrameSearchFlag::PARENT | FrameSearchFlag::SELF);
1259 OSL_ENSURE(xHelpDispatch.is(), "SbaTableQueryBrowser::openHelpAgent: could not get a dispatcher!");
1260 if (xHelpDispatch.is())
1262 xHelpDispatch->dispatch(aURL, Sequence< PropertyValue >());
1265 catch( const Exception& )
1267 DBG_UNHANDLED_EXCEPTION();
1271 Reference< awt::XWindow> OGenericUnoController::getTopMostContainerWindow() const
1273 Reference< ::com::sun::star::awt::XWindow> xWindow;
1275 // get the top most window
1276 Reference< XFrame > xFrame( m_aCurrentFrame.getFrame() );
1277 if ( xFrame.is() )
1279 xWindow = xFrame->getContainerWindow();
1281 while ( xFrame.is() && !xFrame->isTop() )
1283 xFrame.set( xFrame->getCreator(), UNO_QUERY );
1285 if ( xFrame.is() )
1286 xWindow = xFrame->getContainerWindow();
1288 return xWindow;
1291 Reference< XTitle > OGenericUnoController::impl_getTitleHelper_throw()
1293 SolarMutexGuard aSolarGuard;
1294 ::osl::MutexGuard aGuard( getMutex() );
1296 if ( ! m_xTitleHelper.is ())
1298 Reference< XUntitledNumbers > xUntitledProvider(getPrivateModel(), UNO_QUERY );
1299 Reference< XController > xThis(static_cast< XController* >(this), UNO_QUERY_THROW);
1301 ::framework::TitleHelper* pHelper = new ::framework::TitleHelper( m_xContext );
1302 m_xTitleHelper.set( static_cast< ::cppu::OWeakObject* >(pHelper), UNO_QUERY_THROW);
1304 pHelper->setOwner (xThis );
1305 pHelper->connectWithUntitledNumbers (xUntitledProvider);
1308 return m_xTitleHelper;
1311 // XTitle
1312 OUString SAL_CALL OGenericUnoController::getTitle()
1313 throw (RuntimeException, std::exception)
1315 ::osl::MutexGuard aGuard( getMutex() );
1316 if ( m_bExternalTitle )
1317 return impl_getTitleHelper_throw()->getTitle ();
1318 return getPrivateTitle() + impl_getTitleHelper_throw()->getTitle ();
1321 // XTitle
1322 void SAL_CALL OGenericUnoController::setTitle(const OUString& sTitle)
1323 throw (RuntimeException, std::exception)
1325 SolarMutexGuard aSolarGuard;
1326 ::osl::MutexGuard aGuard( getMutex() );
1327 m_bExternalTitle = true;
1328 impl_getTitleHelper_throw()->setTitle (sTitle);
1331 // XTitleChangeBroadcaster
1332 void SAL_CALL OGenericUnoController::addTitleChangeListener(const Reference< XTitleChangeListener >& xListener)
1333 throw (RuntimeException, std::exception)
1335 Reference< XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper_throw(), UNO_QUERY);
1336 if (xBroadcaster.is ())
1337 xBroadcaster->addTitleChangeListener (xListener);
1340 void SAL_CALL OGenericUnoController::removeTitleChangeListener(const Reference< XTitleChangeListener >& xListener)
1341 throw (RuntimeException, std::exception)
1343 Reference< XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper_throw(), UNO_QUERY);
1344 if (xBroadcaster.is ())
1345 xBroadcaster->removeTitleChangeListener (xListener);
1348 // XUserInputInterception
1349 void SAL_CALL OGenericUnoController::addKeyHandler( const Reference< XKeyHandler >& _rxHandler ) throw (RuntimeException, std::exception)
1351 if ( _rxHandler.is() )
1352 m_pData->m_aUserInputInterception.addKeyHandler( _rxHandler );
1355 void SAL_CALL OGenericUnoController::removeKeyHandler( const Reference< XKeyHandler >& _rxHandler ) throw (RuntimeException, std::exception)
1357 m_pData->m_aUserInputInterception.removeKeyHandler( _rxHandler );
1360 void SAL_CALL OGenericUnoController::addMouseClickHandler( const Reference< XMouseClickHandler >& _rxHandler ) throw (RuntimeException, std::exception)
1362 if ( _rxHandler.is() )
1363 m_pData->m_aUserInputInterception.addMouseClickHandler( _rxHandler );
1366 void SAL_CALL OGenericUnoController::removeMouseClickHandler( const Reference< XMouseClickHandler >& _rxHandler ) throw (RuntimeException, std::exception)
1368 m_pData->m_aUserInputInterception.removeMouseClickHandler( _rxHandler );
1371 void OGenericUnoController::executeChecked(sal_uInt16 _nCommandId, const Sequence< PropertyValue >& aArgs)
1373 if ( isCommandEnabled(_nCommandId) )
1374 Execute(_nCommandId, aArgs);
1377 bool OGenericUnoController::isCommandEnabled(sal_uInt16 _nCommandId) const
1379 return GetState( _nCommandId ).bEnabled;
1382 sal_uInt16 OGenericUnoController::registerCommandURL( const OUString& _rCompleteCommandURL )
1384 if ( _rCompleteCommandURL.isEmpty() )
1385 return 0;
1387 SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCompleteCommandURL );
1388 if ( aIter != m_aSupportedFeatures.end() )
1389 return aIter->second.nFeatureId;
1391 // this is a previously unkwnon command
1392 sal_uInt16 nFeatureId = FIRST_USER_DEFINED_FEATURE;
1393 while ( isFeatureSupported( nFeatureId ) && ( nFeatureId < LAST_USER_DEFINED_FEATURE ) )
1394 ++nFeatureId;
1395 if ( nFeatureId == LAST_USER_DEFINED_FEATURE )
1397 SAL_WARN("dbaccess.ui", "OGenericUnoController::registerCommandURL: no more space for user defined features!" );
1398 return 0L;
1401 ControllerFeature aFeature;
1402 aFeature.Command = _rCompleteCommandURL;
1403 aFeature.nFeatureId = nFeatureId;
1404 aFeature.GroupId = CommandGroup::INTERNAL;
1405 m_aSupportedFeatures[ aFeature.Command ] = aFeature;
1407 return nFeatureId;
1410 void OGenericUnoController::notifyHiContrastChanged()
1414 bool OGenericUnoController::isDataSourceReadOnly() const
1416 return false;
1419 Reference< XController > OGenericUnoController::getXController() throw( RuntimeException )
1421 return this;
1424 bool OGenericUnoController::interceptUserInput( const NotifyEvent& _rEvent )
1426 return m_pData->m_aUserInputInterception.handleNotifyEvent( _rEvent );
1429 bool OGenericUnoController::isCommandChecked(sal_uInt16 _nCommandId) const
1431 FeatureState aState = GetState( _nCommandId );
1433 return aState.bChecked && *aState.bChecked;
1436 bool OGenericUnoController::isCommandEnabled( const OUString& _rCompleteCommandURL ) const
1438 OSL_ENSURE( !_rCompleteCommandURL.isEmpty(), "OGenericUnoController::isCommandEnabled: Empty command url!" );
1440 bool bIsEnabled = false;
1441 SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCompleteCommandURL );
1442 if ( aIter != m_aSupportedFeatures.end() )
1443 bIsEnabled = isCommandEnabled( aIter->second.nFeatureId );
1445 return bIsEnabled;
1448 Sequence< ::sal_Int16 > SAL_CALL OGenericUnoController::getSupportedCommandGroups() throw (RuntimeException, std::exception)
1450 CommandHashMap aCmdHashMap;
1451 for ( SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.begin();
1452 aIter != m_aSupportedFeatures.end();
1453 ++aIter
1455 if ( aIter->second.GroupId != CommandGroup::INTERNAL )
1456 aCmdHashMap.insert( CommandHashMap::value_type( aIter->second.GroupId, 0 ));
1458 Sequence< sal_Int16 > aCommandGroups( aCmdHashMap.size() );
1459 ::std::transform( aCmdHashMap.begin(),
1460 aCmdHashMap.end(),
1461 aCommandGroups.getArray(),
1462 ::o3tl::select1st< CommandHashMap::value_type >()
1465 return aCommandGroups;
1468 namespace
1470 //Current c++0x draft (apparently) has std::identity, but not operator()
1471 template<typename T> struct SGI_identity : public std::unary_function<T,T>
1473 T& operator()(T& x) const { return x; }
1474 const T& operator()(const T& x) const { return x; }
1478 Sequence< DispatchInformation > SAL_CALL OGenericUnoController::getConfigurableDispatchInformation( ::sal_Int16 CommandGroup ) throw (RuntimeException, std::exception)
1480 DispatchInfoList aInformationList;
1481 DispatchInformation aDispatchInfo;
1482 for ( SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.begin();
1483 aIter != m_aSupportedFeatures.end();
1484 ++aIter
1487 if ( sal_Int16( aIter->second.GroupId ) == CommandGroup )
1489 aDispatchInfo = aIter->second;
1490 aInformationList.push_back( aDispatchInfo );
1494 Sequence< DispatchInformation > aInformation( aInformationList.size() );
1495 ::std::transform( aInformationList.begin(),
1496 aInformationList.end(),
1497 aInformation.getArray(),
1498 SGI_identity< DispatchInformation >()
1501 return aInformation;
1504 void OGenericUnoController::fillSupportedFeatures()
1506 #ifdef DBG_UTIL
1507 m_bDescribingSupportedFeatures = true;
1508 #endif
1509 describeSupportedFeatures();
1510 #ifdef DBG_UTIL
1511 m_bDescribingSupportedFeatures = false;
1512 #endif
1515 void SAL_CALL OGenericUnoController::dispose() throw(::com::sun::star::uno::RuntimeException, std::exception)
1517 SolarMutexGuard aSolarGuard;
1518 OGenericUnoController_Base::dispose();
1521 } // namespace dbaui
1523 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */