1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
57 #include <o3tl/compat_functional.hxx>
58 #include <boost/scoped_ptr.hpp>
59 #include <cppuhelper/implbase1.hxx>
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
;
88 // UserDefinedFeatures
89 class UserDefinedFeatures
92 UserDefinedFeatures( const Reference
< XController
>& _rxController
);
94 static FeatureState
getState( const URL
& _rFeatureURL
);
95 void execute( const URL
& _rFeatureURL
, const Sequence
< PropertyValue
>& _rArgs
);
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.
112 aState
.bEnabled
= true;
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(
125 FrameSearchFlag::AUTO
128 if ( xDispatch
== xController
)
130 SAL_WARN("dbaccess.ui", "UserDefinedFeatures::execute: the controller shouldn't be the dispatcher here!" );
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() )
161 ,m_bDescribingSupportedFeatures( false )
163 ,m_aAsyncInvalidateAll(LINK(this, OGenericUnoController
, OnAsyncInvalidateAll
))
164 ,m_aAsyncCloseTask(LINK(this, OGenericUnoController
, OnAsyncCloseTask
))
166 ,m_aCurrentFrame( *this )
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
);
185 DBG_UNHANDLED_EXCEPTION();
191 #pragma warning(push)
192 #pragma warning(disable:4702)
194 OGenericUnoController::OGenericUnoController()
195 :OGenericUnoController_Base( getMutex() )
198 ,m_bDescribingSupportedFeatures( false )
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.
218 OGenericUnoController::~OGenericUnoController()
223 bool OGenericUnoController::Construct(vcl::Window
* /*pParent*/)
225 OSL_ENSURE( getView(), "the view is NULL!" );
229 getView()->Construct();
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);
252 IMPL_LINK_NOARG(OGenericUnoController
, OnAsyncInvalidateAll
)
254 if ( !OGenericUnoController_Base::rBHelper
.bInDispose
&& !OGenericUnoController_Base::rBHelper
.bDisposed
)
255 InvalidateFeature_Impl();
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
;
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
>();
297 throw IllegalArgumentException("Parent window is null", *this, 1 );
300 m_aInitParameters
.assign( aArguments
);
301 Construct( pParentWin
);
303 ODataView
* pView
= getView();
305 throw RuntimeException("unable to create a view", *this );
307 if ( m_bReadOnly
|| m_bPreview
)
308 pView
->EnableInput( false );
314 // no one clears my view if I won't
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
)
333 _rxFrame
->addFrameActionListener( this );
336 void OGenericUnoController::stopFrameListening( const Reference
< XFrame
>& _rxFrame
)
339 _rxFrame
->removeFrameActionListener( this );
342 void OGenericUnoController::disposing(const EventObject
& Source
) throw( RuntimeException
, std::exception
)
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
);
356 m_bCurrentlyModified
= xModi
->isModified(); // can only be reset by save
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
)
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
);
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
);
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();
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
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
)
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
481 lcl_collectStates( aFeatState
, aStates
);
483 // a special listener ?
484 if ( xListener
.is() )
485 lcl_notifyMultipleStates( *xListener
.get(), aEvent
, aStates
);
487 { // no -> iterate through all listeners responsible for the URL
488 StringBag aFeatureCommands
;
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
);
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()
530 static sal_Int32 s_nRecursions
= 0;
535 FeatureListener aNextFeature
;
537 ::osl::MutexGuard
aGuard( m_aFeatureMutex
);
538 bEmpty
= m_aFeaturesToInvalidate
.empty();
540 aNextFeature
= m_aFeaturesToInvalidate
.front();
544 if ( ALL_FEATURES
== aNextFeature
.nId
)
546 InvalidateAll_Impl();
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() );
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();
575 aNextFeature
= m_aFeaturesToInvalidate
.front();
583 void OGenericUnoController::ImplInvalidateFeature( sal_Int32 _nId
, const Reference
< XStatusListener
>& _xListener
, bool _bForceBroadcast
)
585 #if OSL_DEBUG_LEVEL > 0
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!" );
597 FeatureListener aListener
;
598 aListener
.nId
= _nId
;
599 aListener
.xListener
= _xListener
;
600 aListener
.bForceBroadcast
= _bForceBroadcast
;
604 ::osl::MutexGuard
aGuard( m_aFeatureMutex
);
605 bWasEmpty
= m_aFeaturesToInvalidate
.empty();
606 m_aFeaturesToInvalidate
.push_back( aListener
);
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();
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
)
659 // no? -> ask the slave dispatcher
660 else if ( m_xSlaveDispatcher
.is() )
662 xReturn
= m_xSlaveDispatcher
->queryDispatch(aURL
, aTargetFrameName
, nSearchFlags
);
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();
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
);
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.
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
)
746 || (rCurrent
.aURL
.Complete
.equals(_rURL
.Complete
))
750 m_arrStatusListener
.erase( iterSearch
++ );
752 // remove the listener only for the given URL, so we can exit the loop after deletion
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
& )
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
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
)
832 OGenericUnoController_Base::WeakComponentImplHelperBase::addEventListener( xListener
);
835 void SAL_CALL
OGenericUnoController::removeEventListener( const Reference
< XEventListener
>& xListener
) throw (RuntimeException
, std::exception
)
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
)
852 OSL_ENSURE( m_bDescribingSupportedFeatures
, "OGenericUnoController::implDescribeSupportedFeature: bad timing for this call!" );
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!" );
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)
885 case ID_BROWSER_UNDO
:
886 case ID_BROWSER_SAVEDOC
:
887 aReturn
.bEnabled
= true;
890 aReturn
= UserDefinedFeatures::getState( getURLForId( _nId
) );
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
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
);
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
);
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
);
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
);
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
);
986 void OGenericUnoController::setView( const VclPtr
<ODataView
> &i_rView
)
991 void OGenericUnoController::clearView()
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();
1060 Any SAL_CALL
OGenericUnoController::getViewData() throw( RuntimeException
, std::exception
)
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!" );
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
);
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
);
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
);
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;
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
;
1183 ++pDocumentService
; ++pDocumentService
;
1184 ++pHelpModuleName
; ++pHelpModuleName
;
1190 // could not determine the document type we're living in
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
) )
1199 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS
) )
1200 pReturn
= "simpress";
1201 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::EModule::DRAW
) )
1203 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::EModule::MATH
) )
1205 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::EModule::CHART
) )
1207 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::EModule::BASIC
) )
1211 SAL_WARN("dbaccess.ui", "lcl_getModuleHelpModuleName: no installed module found" );
1215 catch( const Exception
& )
1217 DBG_UNHANDLED_EXCEPTION();
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 '&' */ );
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
)
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() );
1279 xWindow
= xFrame
->getContainerWindow();
1281 while ( xFrame
.is() && !xFrame
->isTop() )
1283 xFrame
.set( xFrame
->getCreator(), UNO_QUERY
);
1286 xWindow
= xFrame
->getContainerWindow();
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
;
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 ();
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() )
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
) )
1395 if ( nFeatureId
== LAST_USER_DEFINED_FEATURE
)
1397 SAL_WARN("dbaccess.ui", "OGenericUnoController::registerCommandURL: no more space for user defined features!" );
1401 ControllerFeature aFeature
;
1402 aFeature
.Command
= _rCompleteCommandURL
;
1403 aFeature
.nFeatureId
= nFeatureId
;
1404 aFeature
.GroupId
= CommandGroup::INTERNAL
;
1405 m_aSupportedFeatures
[ aFeature
.Command
] = aFeature
;
1410 void OGenericUnoController::notifyHiContrastChanged()
1414 bool OGenericUnoController::isDataSourceReadOnly() const
1419 Reference
< XController
> OGenericUnoController::getXController() throw( RuntimeException
)
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
);
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();
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(),
1461 aCommandGroups
.getArray(),
1462 ::o3tl::select1st
< CommandHashMap::value_type
>()
1465 return aCommandGroups
;
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();
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()
1507 m_bDescribingSupportedFeatures
= true;
1509 describeSupportedFeatures();
1511 m_bDescribingSupportedFeatures
= false;
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: */