1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: genericcontroller.cxx,v $
10 * $Revision: 1.94.24.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dbaccess.hxx"
33 #ifndef DBAUI_GENERICCONTROLLER_HXX
34 #include "genericcontroller.hxx"
36 #ifndef _COMPHELPER_UNO3_HXX_
37 #include <comphelper/uno3.hxx>
39 #ifndef _TOOLKIT_AWT_VCLXWINDOW_HXX_
40 #include <toolkit/awt/vclxwindow.hxx>
42 #ifndef DBACCESS_UI_BROWSER_ID_HXX
43 #include "browserids.hxx"
45 #ifndef _SV_SVAPP_HXX //autogen
46 #include <vcl/svapp.hxx>
48 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
49 #include <toolkit/helper/vclunohelper.hxx>
51 #ifndef DBAUI_DATAVIEW_HXX
52 #include "dataview.hxx"
54 #ifndef _TOOLS_DEBUG_HXX
55 #include <tools/debug.hxx>
57 #ifndef TOOLS_DIAGNOSE_EX_H
58 #include <tools/diagnose_ex.h>
60 #ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
61 #include "dbustrings.hrc"
63 #ifndef _VCL_STDTEXT_HXX
64 #include <vcl/stdtext.hxx>
66 #ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
67 #include <cppuhelper/typeprovider.hxx>
69 #include <framework/titlehelper.hxx>
70 #ifndef _COMPHELPER_SEQUENCE_HXX_
71 #include <comphelper/sequence.hxx>
73 #ifndef _COMPHELPER_EXTRACT_HXX_
74 #include <comphelper/extract.hxx>
76 #ifndef _COM_SUN_STAR_SDBC_XDATASOURCE_HPP_
77 #include <com/sun/star/sdbc/XDataSource.hpp>
79 #ifndef _COM_SUN_STAR_SDB_SQLCONTEXT_HPP_
80 #include <com/sun/star/sdb/SQLContext.hpp>
82 #ifndef _COM_SUN_STAR_SDB_XCOMPLETEDCONNECTION_HPP_
83 #include <com/sun/star/sdb/XCompletedConnection.hpp>
85 #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
86 #include <com/sun/star/beans/XPropertySet.hpp>
88 #ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_
89 #include <com/sun/star/task/XInteractionHandler.hpp>
91 #ifndef _COM_SUN_STAR_UTIL_XCLOSEABLE_HPP_
92 #include <com/sun/star/util/XCloseable.hpp>
94 #ifndef DBAUI_TOOLS_HXX
95 #include "UITools.hxx"
97 #ifndef _DBAUI_COMMON_TYPES_HXX_
98 #include "commontypes.hxx"
101 #ifndef _SV_WAITOBJ_HXX
102 #include <vcl/waitobj.hxx>
105 #include <tools/urlobj.hxx>
107 #ifndef SVTOOLS_URIHELPER_HXX
108 #include <svtools/urihelper.hxx>
110 #ifndef _DBAUI_DATASOURCECONNECTOR_HXX_
111 #include "datasourceconnector.hxx"
113 #ifndef INCLUDED_SVTOOLS_MODULEOPTIONS_HXX
114 #include <svtools/moduleoptions.hxx>
116 #ifndef _COM_SUN_STAR_FRAME_FRAMESEARCHFLAG_HPP_
117 #include <com/sun/star/frame/FrameSearchFlag.hpp>
119 #ifndef _COM_SUN_STAR_FRAME_STATUS_VISIBILITY_HPP_
120 #include <com/sun/star/frame/status/Visibility.hpp>
122 #ifndef _COM_SUN_STAR_UTIL_XMODIFIABLE_HPP_
123 #include <com/sun/star/util/XModifiable.hpp>
125 #ifndef _RTL_USTRING_HXX_
126 #include <rtl/ustring.hxx>
128 #ifndef _RTL_LOGFILE_HXX_
129 #include <rtl/logfile.hxx>
133 #include <cppuhelper/implbase1.hxx>
136 using namespace ::com::sun::star
;
137 using namespace ::com::sun::star::uno
;
138 using namespace ::com::sun::star::beans
;
139 using namespace ::com::sun::star::frame
;
140 using namespace ::com::sun::star::frame::status
;
141 using namespace ::com::sun::star::util
;
142 using namespace ::com::sun::star::lang
;
143 using namespace ::com::sun::star::container
;
144 using namespace ::com::sun::star::sdbc
;
145 using namespace ::com::sun::star::sdb
;
146 using namespace ::com::sun::star::task
;
147 using namespace ::com::sun::star::awt
;
148 using namespace ::com::sun::star
;
149 using namespace ::dbtools
;
150 using namespace ::comphelper
;
152 // -------------------------------------------------------------------------
153 #define ALL_FEATURES -1
154 #define FIRST_USER_DEFINED_FEATURE ( ::std::numeric_limits< sal_uInt16 >::max() - 1000 )
155 #define LAST_USER_DEFINED_FEATURE ( ::std::numeric_limits< sal_uInt16 >::max() )
157 // -------------------------------------------------------------------------
158 typedef ::std::hash_map
< sal_Int16
, sal_Int16
> CommandHashMap
;
159 typedef ::std::list
< DispatchInformation
> DispatchInfoList
;
162 // -------------------------------------------------------------------------
163 const ::rtl::OUString
& getConfirmDeletionURL()
165 static const ::rtl::OUString
sConfirmDeletionURL( RTL_CONSTASCII_USTRINGPARAM( ".uno:FormSlots/ConfirmDeletion" ) );
166 return sConfirmDeletionURL
;
172 //==========================================================================
173 //= UserDefinedFeatures
174 //==========================================================================
175 class UserDefinedFeatures
178 UserDefinedFeatures( const Reference
< XController
>& _rxController
);
180 FeatureState
getState( const URL
& _rFeatureURL
);
181 void execute( const URL
& _rFeatureURL
, const Sequence
< PropertyValue
>& _rArgs
);
184 ::com::sun::star::uno::WeakReference
< XController
> m_aController
;
187 //--------------------------------------------------------------------------
188 UserDefinedFeatures::UserDefinedFeatures( const Reference
< XController
>& _rxController
)
189 :m_aController( _rxController
)
193 //--------------------------------------------------------------------------
194 FeatureState
UserDefinedFeatures::getState( const URL
& /*_rFeatureURL*/ )
196 // for now, enable all the time
197 // TODO: we should ask the dispatcher. However, this is laborious, since you cannot ask a dispatcher
198 // directly, but need to add a status listener.
200 aState
.bEnabled
= sal_True
;
204 //--------------------------------------------------------------------------
205 void UserDefinedFeatures::execute( const URL
& _rFeatureURL
, const Sequence
< PropertyValue
>& _rArgs
)
209 Reference
< XController
> xController( (Reference
< XController
>)m_aController
, UNO_SET_THROW
);
210 Reference
< XDispatchProvider
> xDispatchProvider( xController
->getFrame(), UNO_QUERY_THROW
);
211 Reference
< XDispatch
> xDispatch( xDispatchProvider
->queryDispatch(
213 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_self" ) ),
214 FrameSearchFlag::AUTO
217 if ( xDispatch
== xController
)
219 OSL_ENSURE( false, "UserDefinedFeatures::execute: the controller shouldn't be the dispatcher here!" );
223 if ( xDispatch
.is() )
224 xDispatch
->dispatch( _rFeatureURL
, _rArgs
);
226 catch( const Exception
& )
228 DBG_UNHANDLED_EXCEPTION();
232 //==========================================================================
233 //= OGenericUnoController_Data
234 //==========================================================================
235 struct OGenericUnoController_Data
237 ::sfx2::UserInputInterception m_aUserInputInterception
;
238 UserDefinedFeatures m_aUserDefinedFeatures
;
240 OGenericUnoController_Data( OGenericUnoController
& _rController
, ::osl::Mutex
& _rMutex
)
241 :m_aUserInputInterception( _rController
, _rMutex
)
242 ,m_aUserDefinedFeatures( _rController
.getXController() )
247 //==========================================================================
248 //= OGenericUnoController
249 //==========================================================================
250 DBG_NAME(OGenericUnoController
)
251 // -------------------------------------------------------------------------
252 OGenericUnoController::OGenericUnoController(const Reference
< XMultiServiceFactory
>& _rM
)
253 :OGenericUnoController_Base( getMutex() )
255 ,m_bDescribingSupportedFeatures( false )
257 ,m_aAsyncInvalidateAll(LINK(this, OGenericUnoController
, OnAsyncInvalidateAll
))
258 ,m_aAsyncCloseTask(LINK(this, OGenericUnoController
, OnAsyncCloseTask
))
259 ,m_xServiceFactory(_rM
)
260 ,m_aCurrentFrame( *this )
262 ,m_bPreview(sal_False
)
263 ,m_bReadOnly(sal_False
)
264 ,m_bCurrentlyModified(sal_False
)
265 ,m_bExternalTitle(sal_False
)
267 osl_incrementInterlockedCount( &m_refCount
);
269 m_pData
.reset( new OGenericUnoController_Data( *this, getMutex() ) );
271 osl_decrementInterlockedCount( &m_refCount
);
273 DBG_CTOR(OGenericUnoController
,NULL
);
277 m_xUrlTransformer
= Reference
< XURLTransformer
> (_rM
->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer")), UNO_QUERY
);
281 DBG_UNHANDLED_EXCEPTION();
285 // -----------------------------------------------------------------------------
286 OGenericUnoController::OGenericUnoController()
287 :OGenericUnoController_Base( getMutex() )
289 ,m_bDescribingSupportedFeatures( false )
291 ,m_aAsyncInvalidateAll(LINK(this, OGenericUnoController
, OnAsyncInvalidateAll
))
292 ,m_aAsyncCloseTask(LINK(this, OGenericUnoController
, OnAsyncCloseTask
))
293 ,m_aCurrentFrame( *this )
295 ,m_bPreview(sal_False
)
296 ,m_bReadOnly(sal_False
)
297 ,m_bCurrentlyModified(sal_False
)
299 OSL_ENSURE( false, "OGenericUnoController::OGenericUnoController: illegal call!" );
300 // This ctor only exists because the MSVC compiler complained about an unresolved external
301 // symbol. It should not be used at all. Since using it yields strange runtime problems,
302 // we simply abort here.
306 // -----------------------------------------------------------------------------
307 OGenericUnoController::~OGenericUnoController()
310 DBG_DTOR(OGenericUnoController
,NULL
);
313 // -----------------------------------------------------------------------------
314 sal_Bool
OGenericUnoController::Construct(Window
* /*pParent*/)
316 OSL_ENSURE( getView(), "the view is NULL!" );
320 getView()->Construct();
324 m_aSupportedFeatures
.clear();
325 fillSupportedFeatures();
327 // create the database context
328 DBG_ASSERT(getORB().is(), "OGenericUnoController::Construct need a service factory!");
331 m_xDatabaseContext
= Reference
< XNameAccess
>(getORB()->createInstance(SERVICE_SDB_DATABASECONTEXT
), UNO_QUERY
);
335 DBG_ERROR("OGenericUnoController::Construct: could not create (or start listening at) the database context!");
338 if (!m_xDatabaseContext
.is())
339 { // at least notify the user. Though the whole component does not make any sense without the database context ...
340 ShowServiceNotAvailableError(getView(), String(SERVICE_SDB_DATABASECONTEXT
), sal_True
);
344 //------------------------------------------------------------------------------
345 IMPL_LINK(OGenericUnoController
, OnAsyncInvalidateAll
, void*, EMPTYARG
)
347 if ( !OGenericUnoController_Base::rBHelper
.bInDispose
&& !OGenericUnoController_Base::rBHelper
.bDisposed
)
348 InvalidateFeature_Impl();
351 // -----------------------------------------------------------------------------
352 void OGenericUnoController::impl_initialize()
355 // -------------------------------------------------------------------------
356 void SAL_CALL
OGenericUnoController::initialize( const Sequence
< Any
>& aArguments
) throw(Exception
, RuntimeException
)
358 vos::OGuard
aSolarGuard( Application::GetSolarMutex() );
359 ::osl::MutexGuard
aGuard( getMutex() );
361 Reference
< XWindow
> xParent
;
362 Reference
< XFrame
> xFrame
;
364 PropertyValue aValue
;
365 const Any
* pIter
= aArguments
.getConstArray();
366 const Any
* pEnd
= pIter
+ aArguments
.getLength();
368 for ( ; pIter
!= pEnd
; ++pIter
)
370 if ( ( *pIter
>>= aValue
) && ( 0 == aValue
.Name
.compareToAscii( "Frame" ) ) )
372 xFrame
.set(aValue
.Value
,UNO_QUERY_THROW
);
375 else if ( ( *pIter >>= aValue ) && ( 0 == aValue.Name.compareToAscii( "ReadOnly" ) ) )
377 aValue.Value >>= m_bReadOnly;
380 else if ( ( *pIter
>>= aValue
) && ( 0 == aValue
.Name
.compareToAscii( "Preview" ) ) )
382 aValue
.Value
>>= m_bPreview
;
383 m_bReadOnly
= sal_True
;
389 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "need a frame" ) ), *this, 1 );
391 xParent
= xFrame
->getContainerWindow();
392 VCLXWindow
* pParentComponent
= VCLXWindow::GetImplementation(xParent
);
393 Window
* pParentWin
= pParentComponent
? pParentComponent
->GetWindow() : NULL
;
396 throw IllegalArgumentException( ::rtl::OUString::createFromAscii( "Parent window is null" ), *this, 1 );
399 m_aInitParameters
.assign( aArguments
);
400 Construct( pParentWin
);
402 ODataView
* pView
= getView();
404 throw RuntimeException( ::rtl::OUString::createFromAscii( "unable to create a view" ), *this );
406 if ( m_bReadOnly
|| m_bPreview
)
407 pView
->EnableInput( FALSE
);
413 // no one clears my view if I won't
414 ::std::auto_ptr
<Window
> aTemp(m_pView
);
420 //------------------------------------------------------------------------------
421 void SAL_CALL
OGenericUnoController::acquire( ) throw ()
423 OGenericUnoController_Base::acquire();
426 //------------------------------------------------------------------------------
427 void SAL_CALL
OGenericUnoController::release( ) throw ()
429 OGenericUnoController_Base::release();
432 // -------------------------------------------------------------------------
433 void OGenericUnoController::startFrameListening( const Reference
< XFrame
>& _rxFrame
)
436 _rxFrame
->addFrameActionListener( this );
439 // -------------------------------------------------------------------------
440 void OGenericUnoController::stopFrameListening( const Reference
< XFrame
>& _rxFrame
)
443 _rxFrame
->removeFrameActionListener( this );
446 // -------------------------------------------------------------------------
447 void OGenericUnoController::disposing(const EventObject
& Source
) throw( RuntimeException
)
450 if ( Source
.Source
== getFrame() )
451 stopFrameListening( getFrame() );
453 //------------------------------------------------------------------------
454 void OGenericUnoController::modified(const EventObject
& aEvent
) throw( RuntimeException
)
456 ::osl::MutexGuard
aGuard( getMutex() );
457 if ( !isDataSourceReadOnly() )
459 Reference
<XModifiable
> xModi(aEvent
.Source
,UNO_QUERY
);
461 m_bCurrentlyModified
= xModi
->isModified(); // can only be reset by save
463 m_bCurrentlyModified
= sal_True
;
465 InvalidateFeature(ID_BROWSER_SAVEDOC
);
466 InvalidateFeature(ID_BROWSER_UNDO
);
468 // -----------------------------------------------------------------------
469 Reference
< XWindow
> SAL_CALL
OGenericUnoController::getComponentWindow() throw (RuntimeException
)
471 return VCLUnoHelper::GetInterface( getView() );
474 // -----------------------------------------------------------------------
475 ::rtl::OUString SAL_CALL
OGenericUnoController::getViewControllerName() throw (::com::sun::star::uno::RuntimeException
)
477 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Default" ) );
480 // -----------------------------------------------------------------------
481 void OGenericUnoController::attachFrame( const Reference
< XFrame
>& _rxFrame
) throw( RuntimeException
)
483 vos::OGuard
aSolarGuard( Application::GetSolarMutex() );
484 ::osl::MutexGuard
aGuard( getMutex() );
486 stopFrameListening( m_aCurrentFrame
.getFrame() );
487 Reference
< XFrame
> xFrame
= m_aCurrentFrame
.attachFrame( _rxFrame
);
488 startFrameListening( xFrame
);
493 getView()->attachFrame( xFrame
);
496 // -----------------------------------------------------------------------------
497 struct CommandCollector
: public ::std::unary_function
< SupportedFeatures::value_type
, void>
499 sal_uInt16 m_nFeature
;
500 StringBag
& m_rFeatureCommands
;
501 CommandCollector( sal_uInt16 _nFeature
, StringBag
& _rFeatureCommands
)
502 :m_nFeature ( _nFeature
)
503 ,m_rFeatureCommands( _rFeatureCommands
)
507 void operator() ( const SupportedFeatures::value_type
& lhs
)
509 if ( lhs
.second
.nFeatureId
== m_nFeature
)
510 m_rFeatureCommands
.insert( lhs
.first
);
514 // -----------------------------------------------------------------------
517 typedef ::std::vector
< Any
> States
;
519 // ...................................................................
520 void lcl_notifyMultipleStates( XStatusListener
& _rListener
, FeatureStateEvent
& _rEvent
, const States
& _rStates
)
522 for ( States::const_iterator state
= _rStates
.begin();
523 state
!= _rStates
.end();
527 _rEvent
.State
= *state
;
528 _rListener
.statusChanged( _rEvent
);
532 // ...................................................................
533 void lcl_collectStates( const FeatureState
& _rFeatureState
, States
& _out_rStates
)
535 // order matters, due to a bug in framework which resets the check state when any non-boolean event
537 // #i68215# is the bug to (re-)introduce this "ordered" notification here
538 // #i67882# is the bug which was caused by the real fix which we did in framework
539 // #i68216# is the bug which requests to fix the code in Draw which relies on
540 // framework's implementation details
541 // 2006-08-07 / frank.schoenheit@sun.com
542 if ( !!_rFeatureState
.sTitle
)
543 _out_rStates
.push_back( makeAny( *_rFeatureState
.sTitle
) );
544 if ( !!_rFeatureState
.bChecked
)
545 _out_rStates
.push_back( makeAny( (sal_Bool
)*_rFeatureState
.bChecked
) );
546 if ( !!_rFeatureState
.bInvisible
)
547 _out_rStates
.push_back( makeAny( Visibility( !*_rFeatureState
.bInvisible
) ) );
548 if ( _rFeatureState
.aValue
.hasValue() )
549 _out_rStates
.push_back( _rFeatureState
.aValue
);
550 if ( _out_rStates
.empty() )
551 _out_rStates
.push_back( Any() );
555 // -----------------------------------------------------------------------
556 void OGenericUnoController::ImplBroadcastFeatureState(const ::rtl::OUString
& _rFeature
, const Reference
< XStatusListener
> & xListener
, sal_Bool _bIgnoreCache
)
558 sal_uInt16 nFeat
= m_aSupportedFeatures
[ _rFeature
].nFeatureId
;
559 FeatureState
aFeatState( GetState( nFeat
) );
561 FeatureState
& rCachedState
= m_aStateCache
[nFeat
]; // creates if neccessary
562 if ( !_bIgnoreCache
)
564 // check if we really need to notify the listeners : this method may be called much more often than needed, so check
565 // the cached state of the feature
566 sal_Bool bAlreadyCached
= ( m_aStateCache
.find(nFeat
) != m_aStateCache
.end() );
567 if ( bAlreadyCached
)
568 if ( ( rCachedState
.bEnabled
== aFeatState
.bEnabled
)
569 && ( rCachedState
.bChecked
== aFeatState
.bChecked
)
570 && ( rCachedState
.bInvisible
== aFeatState
.bInvisible
)
571 && ( rCachedState
.sTitle
== aFeatState
.sTitle
)
575 rCachedState
= aFeatState
;
577 FeatureStateEvent aEvent
;
578 aEvent
.FeatureURL
.Complete
= _rFeature
;
579 if (m_xUrlTransformer
.is())
580 m_xUrlTransformer
->parseStrict(aEvent
.FeatureURL
);
581 aEvent
.Source
= (XDispatch
*)this;
582 aEvent
.IsEnabled
= aFeatState
.bEnabled
;
584 // collect all states to be notified
586 lcl_collectStates( aFeatState
, aStates
);
588 // a special listener ?
589 if ( xListener
.is() )
590 lcl_notifyMultipleStates( *xListener
.get(), aEvent
, aStates
);
592 { // no -> iterate through all listeners responsible for the URL
593 StringBag aFeatureCommands
;
595 m_aSupportedFeatures
.begin(),
596 m_aSupportedFeatures
.end(),
597 CommandCollector( nFeat
, aFeatureCommands
)
600 // it is possible that listeners are registered or revoked while
601 // we are notifying them, so we must use a copy of m_arrStatusListener, not
602 // m_arrStatusListener itself
603 // #121276# / 2005-05-19 / frank.schoenheit@sun.com
604 Dispatch
aNotifyLoop( m_arrStatusListener
);
605 DispatchIterator iterSearch
= aNotifyLoop
.begin();
606 DispatchIterator iterEnd
= aNotifyLoop
.end();
608 while (iterSearch
!= iterEnd
)
610 DispatchTarget
& rCurrent
= *iterSearch
;
611 if ( aFeatureCommands
.find( rCurrent
.aURL
.Complete
) != aFeatureCommands
.end() )
613 aEvent
.FeatureURL
= rCurrent
.aURL
;
614 lcl_notifyMultipleStates( *rCurrent
.xListener
.get(), aEvent
, aStates
);
622 //------------------------------------------------------------------------------
623 sal_Bool
OGenericUnoController::isFeatureSupported( sal_Int32 _nId
)
625 SupportedFeatures::iterator aFeaturePos
= ::std::find_if(
626 m_aSupportedFeatures
.begin(),
627 m_aSupportedFeatures
.end(),
628 ::std::bind2nd( CompareFeatureById(), _nId
)
631 return ( m_aSupportedFeatures
.end() != aFeaturePos
&& aFeaturePos
->first
.getLength());
634 // -----------------------------------------------------------------------
635 void OGenericUnoController::InvalidateFeature(const ::rtl::OUString
& _rURLPath
, const Reference
< XStatusListener
> & _xListener
, sal_Bool _bForceBroadcast
)
637 ImplInvalidateFeature( m_aSupportedFeatures
[ _rURLPath
].nFeatureId
, _xListener
, _bForceBroadcast
);
640 // -----------------------------------------------------------------------------
641 void OGenericUnoController::InvalidateFeature_Impl()
644 static sal_Int32 s_nRecursions
= 0;
648 sal_Bool bEmpty
= sal_True
;
649 FeatureListener aNextFeature
;
651 ::osl::MutexGuard
aGuard( m_aFeatureMutex
);
652 bEmpty
= m_aFeaturesToInvalidate
.empty();
654 aNextFeature
= m_aFeaturesToInvalidate
.front();
658 if ( ALL_FEATURES
== aNextFeature
.nId
)
660 InvalidateAll_Impl();
665 SupportedFeatures::iterator aFeaturePos
= ::std::find_if(
666 m_aSupportedFeatures
.begin(),
667 m_aSupportedFeatures
.end(),
668 ::std::bind2nd( CompareFeatureById(), aNextFeature
.nId
)
671 #if OSL_DEBUG_LEVEL > 0
672 if ( m_aSupportedFeatures
.end() == aFeaturePos
)
674 ::rtl::OString
sMessage( "OGenericUnoController::InvalidateFeature_Impl: feature id " );
675 sMessage
+= ::rtl::OString::valueOf( aNextFeature
.nId
);
676 sMessage
+= ::rtl::OString( " has been invalidated, but is not supported!" );
677 OSL_ENSURE( false, sMessage
.getStr() );
680 if ( m_aSupportedFeatures
.end() != aFeaturePos
)
681 // we really know this feature
682 ImplBroadcastFeatureState( aFeaturePos
->first
, aNextFeature
.xListener
, aNextFeature
.bForceBroadcast
);
685 ::osl::MutexGuard
aGuard( m_aFeatureMutex
);
686 m_aFeaturesToInvalidate
.pop_front();
687 bEmpty
= m_aFeaturesToInvalidate
.empty();
689 aNextFeature
= m_aFeaturesToInvalidate
.front();
697 // -----------------------------------------------------------------------
698 void OGenericUnoController::ImplInvalidateFeature( sal_Int32 _nId
, const Reference
< XStatusListener
>& _xListener
, sal_Bool _bForceBroadcast
)
700 FeatureListener aListener
;
701 aListener
.nId
= _nId
;
702 aListener
.xListener
= _xListener
;
703 aListener
.bForceBroadcast
= _bForceBroadcast
;
707 ::osl::MutexGuard
aGuard( m_aFeatureMutex
);
708 bWasEmpty
= m_aFeaturesToInvalidate
.empty();
709 m_aFeaturesToInvalidate
.push_back( aListener
);
713 m_aAsyncInvalidateAll
.Call();
716 // -----------------------------------------------------------------------
717 void OGenericUnoController::InvalidateFeature(sal_uInt16 _nId
, const Reference
< XStatusListener
> & _xListener
, sal_Bool _bForceBroadcast
)
719 ImplInvalidateFeature( _nId
, _xListener
, _bForceBroadcast
);
722 // -----------------------------------------------------------------------
723 void OGenericUnoController::InvalidateAll()
725 ImplInvalidateFeature( ALL_FEATURES
, NULL
, sal_True
);
728 // -----------------------------------------------------------------------------
729 void OGenericUnoController::InvalidateAll_Impl()
731 // ---------------------------------
732 // invalidate all aupported features
734 for ( SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.begin();
735 aIter
!= m_aSupportedFeatures
.end();
738 ImplBroadcastFeatureState( aIter
->first
, NULL
, sal_True
);
741 ::osl::MutexGuard
aGuard( m_aFeatureMutex
);
742 DBG_ASSERT(m_aFeaturesToInvalidate
.size(), "OGenericUnoController::InvalidateAll_Impl: to be called from within InvalidateFeature_Impl only!");
743 m_aFeaturesToInvalidate
.pop_front();
744 if(!m_aFeaturesToInvalidate
.empty())
745 m_aAsyncInvalidateAll
.Call();
749 // -----------------------------------------------------------------------
750 Reference
< XDispatch
> OGenericUnoController::queryDispatch(const URL
& aURL
, const ::rtl::OUString
& aTargetFrameName
, sal_Int32 nSearchFlags
) throw( RuntimeException
)
752 Reference
< XDispatch
> xReturn
;
754 OSL_PRECOND( !m_aSupportedFeatures
.empty(), "OGenericUnoController::queryDispatch: shouldn't this be filled at construction time?" );
755 if ( m_aSupportedFeatures
.empty() )
756 fillSupportedFeatures();
758 // URL's we can handle ourself?
759 if ( aURL
.Complete
.equals( getConfirmDeletionURL() )
760 || ( ( m_aSupportedFeatures
.find( aURL
.Complete
) != m_aSupportedFeatures
.end() )
761 && !isUserDefinedFeature( aURL
.Complete
)
767 // no? -> ask the slave dispatcher
768 else if ( m_xSlaveDispatcher
.is() )
770 xReturn
= m_xSlaveDispatcher
->queryDispatch(aURL
, aTargetFrameName
, nSearchFlags
);
777 // -----------------------------------------------------------------------
778 Sequence
< Reference
< XDispatch
> > OGenericUnoController::queryDispatches(const Sequence
< DispatchDescriptor
>& aDescripts
) throw( RuntimeException
)
780 Sequence
< Reference
< XDispatch
> > aReturn
;
781 sal_Int32 nLen
= aDescripts
.getLength();
784 aReturn
.realloc( nLen
);
785 Reference
< XDispatch
>* pReturn
= aReturn
.getArray();
786 const Reference
< XDispatch
>* pReturnEnd
= aReturn
.getArray() + nLen
;
787 const DispatchDescriptor
* pDescripts
= aDescripts
.getConstArray();
789 for ( ; pReturn
!= pReturnEnd
; ++ pReturn
, ++pDescripts
)
791 *pReturn
= queryDispatch( pDescripts
->FeatureURL
, pDescripts
->FrameName
, pDescripts
->SearchFlags
);
798 // -----------------------------------------------------------------------
799 Reference
< XDispatchProvider
> OGenericUnoController::getSlaveDispatchProvider(void) throw( RuntimeException
)
801 return m_xSlaveDispatcher
;
804 // -----------------------------------------------------------------------
805 void OGenericUnoController::setSlaveDispatchProvider(const Reference
< XDispatchProvider
> & _xNewProvider
) throw( RuntimeException
)
807 m_xSlaveDispatcher
= _xNewProvider
;
810 // -----------------------------------------------------------------------
811 Reference
< XDispatchProvider
> OGenericUnoController::getMasterDispatchProvider(void) throw( RuntimeException
)
813 return m_xMasterDispatcher
;
816 // -----------------------------------------------------------------------
817 void OGenericUnoController::setMasterDispatchProvider(const Reference
< XDispatchProvider
> & _xNewProvider
) throw( RuntimeException
)
819 m_xMasterDispatcher
= _xNewProvider
;
822 // -----------------------------------------------------------------------
823 void OGenericUnoController::dispatch(const URL
& _aURL
, const Sequence
< PropertyValue
>& aArgs
) throw(RuntimeException
)
825 ::vos::OGuard
aSolarGuard( Application::GetSolarMutex() );
826 // Since the fix for #123967#, the SolarMutex is not locked anymore when the framework calls into
827 // here. So, lock it ourself. The real solution would be to lock it only in the places
828 // where it's needed, but a) this might turn out difficult, since we then also need to care
829 // for locking in the proper order (SolarMutex and m_aMutex), and b) this would be too many places
830 // for the time frame of the fix.
831 // #i52602# / frank.schoenheit@sun.com / 2005-07-29
834 ::rtl::OString
sLog( "OGenericUnoController::dispatch( '" );
835 sLog
+= ::rtl::OString( _aURL
.Main
.getStr(), _aURL
.Main
.getLength(), osl_getThreadTextEncoding() );
836 sLog
+= ::rtl::OString( "' )" );
837 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "frank.schoenheit@sun.com", sLog
.getStr() );
840 executeChecked(_aURL
,aArgs
);
843 // -----------------------------------------------------------------------
844 void OGenericUnoController::addStatusListener(const Reference
< XStatusListener
> & aListener
, const URL
& _rURL
) throw(RuntimeException
)
846 // parse the ULR now and here, this saves later parsing in each notification round
847 URL
aParsedURL( _rURL
);
848 if ( m_xUrlTransformer
.is() )
849 m_xUrlTransformer
->parseStrict( aParsedURL
);
851 // remeber the listener together with the URL
852 m_arrStatusListener
.insert( m_arrStatusListener
.end(), DispatchTarget( aParsedURL
, aListener
) );
854 // initially broadcast the state
855 ImplBroadcastFeatureState( aParsedURL
.Complete
, aListener
, sal_True
);
856 // force the new state to be broadcasted to the new listener
859 // -----------------------------------------------------------------------
860 void OGenericUnoController::removeStatusListener(const Reference
< XStatusListener
> & aListener
, const URL
& _rURL
) throw(RuntimeException
)
862 DispatchIterator iterSearch
= m_arrStatusListener
.begin();
864 sal_Bool bRemoveForAll
= (_rURL
.Complete
.getLength() == 0);
865 while ( iterSearch
!= m_arrStatusListener
.end() )
867 DispatchTarget
& rCurrent
= *iterSearch
;
868 if ( (rCurrent
.xListener
== aListener
)
870 || (rCurrent
.aURL
.Complete
.equals(_rURL
.Complete
))
874 m_arrStatusListener
.erase( iterSearch
);
876 // remove the listener only for the given URL, so we can exit the loop after deletion
883 OSL_PRECOND( !m_aSupportedFeatures
.empty(), "OGenericUnoController::removeStatusListener: shouldn't this be filled at construction time?" );
884 if ( m_aSupportedFeatures
.empty() )
885 fillSupportedFeatures();
887 SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.find(_rURL
.Complete
);
888 if (aIter
!= m_aSupportedFeatures
.end())
889 { // clear the cache for that feature
890 StateCacheIterator aCachePos
= m_aStateCache
.find( aIter
->second
.nFeatureId
);
891 if ( aCachePos
!= m_aStateCache
.end() )
892 m_aStateCache
.erase( aCachePos
);
895 // now remove the listener from the deque
896 ::osl::MutexGuard
aGuard( m_aFeatureMutex
);
897 m_aFeaturesToInvalidate
.erase(
898 ::std::remove_if( m_aFeaturesToInvalidate
.begin(),
899 m_aFeaturesToInvalidate
.end(),
900 ::std::bind2nd(FindFeatureListener(),aListener
))
901 ,m_aFeaturesToInvalidate
.end());
903 // -----------------------------------------------------------------------------
904 void OGenericUnoController::releaseNumberForComponent()
908 Reference
< XUntitledNumbers
> xUntitledProvider(getPrivateModel(), UNO_QUERY
);
909 if ( xUntitledProvider
.is() )
910 xUntitledProvider
->releaseNumberForComponent(static_cast<XWeak
*>(this));
912 catch( const Exception
& )
917 // -----------------------------------------------------------------------
918 void OGenericUnoController::disposing()
921 EventObject aDisposeEvent
;
922 aDisposeEvent
.Source
= static_cast<XWeak
*>(this);
923 Dispatch aStatusListener
= m_arrStatusListener
;
924 Dispatch::iterator aEnd
= aStatusListener
.end();
925 for (Dispatch::iterator aIter
= aStatusListener
.begin(); aIter
!= aEnd
; ++aIter
)
927 aIter
->xListener
->disposing(aDisposeEvent
);
929 m_arrStatusListener
.clear();
932 m_xDatabaseContext
= NULL
;
934 ::osl::MutexGuard
aGuard( m_aFeatureMutex
);
935 m_aAsyncInvalidateAll
.CancelCall();
936 m_aFeaturesToInvalidate
.clear();
939 releaseNumberForComponent();
941 // check out from all the objects we are listening
943 stopFrameListening( m_aCurrentFrame
.getFrame() );
944 m_aCurrentFrame
.attachFrame( NULL
);
946 m_xMasterDispatcher
= NULL
;
947 m_xSlaveDispatcher
= NULL
;
948 m_xServiceFactory
= NULL
;
951 // -----------------------------------------------------------------------------
952 void SAL_CALL
OGenericUnoController::addEventListener( const Reference
< XEventListener
>& xListener
) throw (RuntimeException
)
955 OGenericUnoController_Base::WeakComponentImplHelperBase::addEventListener( xListener
);
958 // -----------------------------------------------------------------------------
959 void SAL_CALL
OGenericUnoController::removeEventListener( const Reference
< XEventListener
>& xListener
) throw (RuntimeException
)
962 OGenericUnoController_Base::WeakComponentImplHelperBase::removeEventListener( xListener
);
965 //------------------------------------------------------------------------------
966 void OGenericUnoController::frameAction(const FrameActionEvent
& aEvent
) throw( RuntimeException
)
968 ::osl::MutexGuard
aGuard( getMutex() );
969 if ( aEvent
.Frame
== m_aCurrentFrame
.getFrame() )
970 m_aCurrentFrame
.frameAction( aEvent
.Action
);
973 //------------------------------------------------------------------------------
974 void OGenericUnoController::implDescribeSupportedFeature( const sal_Char
* _pAsciiCommandURL
,
975 sal_uInt16 _nFeatureId
, sal_Int16 _nCommandGroup
)
978 DBG_ASSERT( m_bDescribingSupportedFeatures
, "OGenericUnoController::implDescribeSupportedFeature: bad timing for this call!" );
980 OSL_PRECOND( _nFeatureId
< FIRST_USER_DEFINED_FEATURE
, "OGenericUnoController::implDescribeSupportedFeature: invalid feature id!" );
982 ControllerFeature aFeature
;
983 aFeature
.Command
= ::rtl::OUString::createFromAscii( _pAsciiCommandURL
);
984 aFeature
.nFeatureId
= _nFeatureId
;
985 aFeature
.GroupId
= _nCommandGroup
;
987 #if OSL_DEBUG_LEVEL > 0
988 OSL_ENSURE( m_aSupportedFeatures
.find( aFeature
.Command
) == m_aSupportedFeatures
.end(),
989 "OGenericUnoController::implDescribeSupportedFeature: this feature is already there!" );
991 m_aSupportedFeatures
[ aFeature
.Command
] = aFeature
;
994 //------------------------------------------------------------------------------
995 void OGenericUnoController::describeSupportedFeatures()
997 // add all supported features
998 implDescribeSupportedFeature( ".uno:Copy", ID_BROWSER_COPY
, CommandGroup::EDIT
);
999 implDescribeSupportedFeature( ".uno:Cut", ID_BROWSER_CUT
, CommandGroup::EDIT
);
1000 implDescribeSupportedFeature( ".uno:Paste", ID_BROWSER_PASTE
, CommandGroup::EDIT
);
1001 implDescribeSupportedFeature( ".uno:ClipboardFormatItems", ID_BROWSER_CLIPBOARD_FORMAT_ITEMS
);
1002 implDescribeSupportedFeature( ".uno:DSBEditDoc", ID_BROWSER_EDITDOC
, CommandGroup::DOCUMENT
);
1005 //------------------------------------------------------------------------------
1006 FeatureState
OGenericUnoController::GetState( sal_uInt16 _nId
) const
1008 FeatureState aReturn
;
1009 // (disabled automatically)
1013 case ID_BROWSER_UNDO
:
1014 case ID_BROWSER_SAVEDOC
:
1015 aReturn
.bEnabled
= sal_True
;
1018 aReturn
= m_pData
->m_aUserDefinedFeatures
.getState( getURLForId( _nId
) );
1025 //------------------------------------------------------------------------------
1026 void OGenericUnoController::Execute( sal_uInt16 _nId
, const Sequence
< PropertyValue
>& _rArgs
)
1028 OSL_ENSURE( isUserDefinedFeature( _nId
),
1029 "OGenericUnoController::Execute: responsible for user defined features only!" );
1031 // user defined features can be handled by dispatch interceptors resp. protocol handlers only.
1032 // So, we need to do a queryDispatch, and dispatch the URL
1033 m_pData
->m_aUserDefinedFeatures
.execute( getURLForId( _nId
), _rArgs
);
1036 //------------------------------------------------------------------------------
1037 URL
OGenericUnoController::getURLForId(sal_Int32 _nId
) const
1040 if ( m_xUrlTransformer
.is() )
1042 SupportedFeatures::const_iterator aIter
= ::std::find_if(
1043 m_aSupportedFeatures
.begin(),
1044 m_aSupportedFeatures
.end(),
1045 ::std::bind2nd( CompareFeatureById(), _nId
)
1048 if ( m_aSupportedFeatures
.end() != aIter
&& aIter
->first
.getLength() )
1050 aReturn
.Complete
= aIter
->first
;
1051 m_xUrlTransformer
->parseStrict( aReturn
);
1057 //-------------------------------------------------------------------------
1058 bool OGenericUnoController::isUserDefinedFeature( const sal_uInt16 _nFeatureId
) const
1060 return ( _nFeatureId
>= FIRST_USER_DEFINED_FEATURE
) && ( _nFeatureId
< LAST_USER_DEFINED_FEATURE
);
1063 //-------------------------------------------------------------------------
1064 bool OGenericUnoController::isUserDefinedFeature( const ::rtl::OUString
& _rFeatureURL
) const
1066 SupportedFeatures::const_iterator pos
= m_aSupportedFeatures
.find( _rFeatureURL
);
1067 OSL_PRECOND( pos
!= m_aSupportedFeatures
.end(),
1068 "OGenericUnoController::isUserDefinedFeature: this is no supported feature at all!" );
1070 return ( pos
!= m_aSupportedFeatures
.end() ) ? isUserDefinedFeature( pos
->second
.nFeatureId
) : false;
1073 //-------------------------------------------------------------------------
1074 sal_Bool SAL_CALL
OGenericUnoController::supportsService(const ::rtl::OUString
& ServiceName
) throw(RuntimeException
)
1076 Sequence
< ::rtl::OUString
> aSupported(getSupportedServiceNames());
1078 const ::rtl::OUString
* pArray
= aSupported
.getConstArray();
1079 const ::rtl::OUString
* pArrayEnd
= aSupported
.getConstArray() + aSupported
.getLength();
1081 for ( ;( pArray
!= pArrayEnd
) && !pArray
->equals( ServiceName
); ++pArray
)
1083 return pArray
!= pArrayEnd
;
1086 // -----------------------------------------------------------------------------
1087 void OGenericUnoController::startConnectionListening(const Reference
< XConnection
>& _rxConnection
)
1089 // we have to remove ourself before dispoing the connection
1090 Reference
< XComponent
> xComponent(_rxConnection
, UNO_QUERY
);
1091 if (xComponent
.is())
1092 xComponent
->addEventListener(static_cast<XFrameActionListener
*>(this));
1095 // -----------------------------------------------------------------------------
1096 void OGenericUnoController::stopConnectionListening(const Reference
< XConnection
>& _rxConnection
)
1098 // we have to remove ourself before dispoing the connection
1099 Reference
< XComponent
> xComponent(_rxConnection
, UNO_QUERY
);
1100 if (xComponent
.is())
1101 xComponent
->removeEventListener(static_cast<XFrameActionListener
*>(this));
1103 // -----------------------------------------------------------------------------
1104 Reference
< XConnection
> OGenericUnoController::connect( const Reference
< XDataSource
>& _xDataSource
,
1105 ::dbtools::SQLExceptionInfo
* _pErrorInfo
)
1107 WaitObject
aWaitCursor( getView() );
1109 ODatasourceConnector
aConnector( getORB(), getView(), ::rtl::OUString() );
1110 Reference
< XConnection
> xConnection
= aConnector
.connect( _xDataSource
, _pErrorInfo
);
1111 startConnectionListening( xConnection
);
1115 // -----------------------------------------------------------------------------
1116 Reference
< XConnection
> OGenericUnoController::connect( const ::rtl::OUString
& _rDataSourceName
,
1117 const ::rtl::OUString
& _rContextInformation
, ::dbtools::SQLExceptionInfo
* _pErrorInfo
)
1119 WaitObject
aWaitCursor( getView() );
1121 ODatasourceConnector
aConnector( getORB(), getView(), _rContextInformation
);
1122 Reference
<XConnection
> xConnection
= aConnector
.connect( _rDataSourceName
, _pErrorInfo
);
1123 startConnectionListening( xConnection
);
1128 // -----------------------------------------------------------------------------
1129 void OGenericUnoController::showError(const SQLExceptionInfo
& _rInfo
)
1131 ::dbaui::showError(_rInfo
,getView(),getORB());
1133 // -----------------------------------------------------------------------------
1134 Reference
< XLayoutManager
> OGenericUnoController::getLayoutManager(const Reference
< XFrame
>& _xFrame
) const
1136 Reference
< XPropertySet
> xPropSet( _xFrame
, UNO_QUERY
);
1137 Reference
< XLayoutManager
> xLayoutManager
;
1138 if ( xPropSet
.is() )
1142 xLayoutManager
.set(xPropSet
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))),UNO_QUERY
);
1144 catch ( Exception
& )
1148 return xLayoutManager
;
1150 // -----------------------------------------------------------------------------
1151 void OGenericUnoController::loadMenu(const Reference
< XFrame
>& _xFrame
)
1153 Reference
< XLayoutManager
> xLayoutManager
= getLayoutManager(_xFrame
);
1154 if ( xLayoutManager
.is() )
1156 xLayoutManager
->lock();
1157 xLayoutManager
->createElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" )));
1158 xLayoutManager
->createElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/toolbar" )));
1159 xLayoutManager
->unlock();
1160 xLayoutManager
->doLayout();
1163 onLoadedMenu( xLayoutManager
);
1166 // -----------------------------------------------------------------------------
1167 void OGenericUnoController::onLoadedMenu(const Reference
< XLayoutManager
>& /*_xLayoutManager*/)
1169 // not interested in
1172 // -----------------------------------------------------------------------------
1173 void OGenericUnoController::closeTask()
1175 m_aAsyncCloseTask
.Call();
1177 // -----------------------------------------------------------------------------
1178 IMPL_LINK(OGenericUnoController
, OnAsyncCloseTask
, void*, EMPTYARG
)
1180 if ( !OGenericUnoController_Base::rBHelper
.bInDispose
)
1184 Reference
< util::XCloseable
> xCloseable( m_aCurrentFrame
.getFrame(), UNO_QUERY_THROW
);
1185 xCloseable
->close( sal_False
); // false - holds the owner ship for this frame inside this object!
1187 catch( const Exception
& )
1189 DBG_UNHANDLED_EXCEPTION();
1194 // -----------------------------------------------------------------------------
1195 Any SAL_CALL
OGenericUnoController::getViewData(void) throw( RuntimeException
)
1199 // -----------------------------------------------------------------------------
1200 void SAL_CALL
OGenericUnoController::restoreViewData(const Any
& /*Data*/) throw( RuntimeException
)
1204 // -----------------------------------------------------------------------------
1205 Reference
< XModel
> SAL_CALL
OGenericUnoController::getModel(void) throw( RuntimeException
)
1207 return Reference
< XModel
>();
1210 // -----------------------------------------------------------------------------
1211 Reference
< XFrame
> SAL_CALL
OGenericUnoController::getFrame(void) throw( RuntimeException
)
1213 ::osl::MutexGuard
aGuard( getMutex() );
1214 return m_aCurrentFrame
.getFrame();
1217 // -----------------------------------------------------------------------------
1218 sal_Bool SAL_CALL
OGenericUnoController::attachModel(const Reference
< XModel
> & /*xModel*/) throw( RuntimeException
)
1220 OSL_ENSURE( false, "OGenericUnoController::attachModel: not supported!" );
1224 // -----------------------------------------------------------------------------
1225 void OGenericUnoController::executeUnChecked(sal_uInt16 _nCommandId
, const Sequence
< PropertyValue
>& aArgs
)
1227 Execute(_nCommandId
, aArgs
);
1229 // -----------------------------------------------------------------------------
1230 void OGenericUnoController::executeUnChecked(const util::URL
& _rCommand
, const Sequence
< PropertyValue
>& aArgs
)
1232 OSL_PRECOND( !m_aSupportedFeatures
.empty(), "OGenericUnoController::executeUnChecked: shouldn't this be filled at construction time?" );
1233 if ( m_aSupportedFeatures
.empty() )
1234 fillSupportedFeatures();
1236 SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.find( _rCommand
.Complete
);
1237 if (aIter
!= m_aSupportedFeatures
.end())
1238 Execute( aIter
->second
.nFeatureId
, aArgs
);
1240 // -----------------------------------------------------------------------------
1241 void OGenericUnoController::executeChecked(const util::URL
& _rCommand
, const Sequence
< PropertyValue
>& aArgs
)
1243 OSL_PRECOND( !m_aSupportedFeatures
.empty(), "OGenericUnoController::executeChecked: shouldn't this be filled at construction time?" );
1244 if ( m_aSupportedFeatures
.empty() )
1245 fillSupportedFeatures();
1247 SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.find( _rCommand
.Complete
);
1248 if ( aIter
!= m_aSupportedFeatures
.end() )
1250 sal_uInt16 nFeatureId
= aIter
->second
.nFeatureId
;
1251 if ( GetState( nFeatureId
).bEnabled
)
1252 Execute( nFeatureId
, aArgs
);
1255 // -----------------------------------------------------------------------------
1256 //------------------------------------------------------------------------------
1259 ::rtl::OUString
lcl_getModuleHelpModuleName( const Reference
< XFrame
>& _rxFrame
)
1261 const sal_Char
* pReturn
= NULL
;
1265 // get the model of the document in the given frame
1266 Reference
< XController
> xController
;
1267 if ( _rxFrame
.is() )
1268 xController
= _rxFrame
->getController();
1269 Reference
< XModel
> xModel
;
1270 if ( xController
.is() )
1271 xModel
= xController
->getModel();
1272 Reference
< XServiceInfo
> xSI( xModel
, UNO_QUERY
);
1275 { // try to go up the frame hierarchy
1277 Reference
< XFrame
> xParentFrame
;
1278 if ( _rxFrame
.is() )
1279 xParentFrame
= xParentFrame
.query( _rxFrame
->getCreator() );
1280 // did we find a parent frame? Which is no top-level frame?
1281 if ( xParentFrame
.is() && !_rxFrame
->isTop() )
1282 // TODO: to prevent framework assertions, re-insert this "isTop" once 98303 is fixed
1283 return lcl_getModuleHelpModuleName( xParentFrame
);
1287 #if OSL_DEBUG_LEVEL > 0
1288 Sequence
< ::rtl::OUString
> sServiceNames
= xSI
->getSupportedServiceNames();
1289 const ::rtl::OUString
* pLoop
= sServiceNames
.getConstArray();
1290 for ( sal_Int32 i
=0; i
<sServiceNames
.getLength(); ++i
, ++pLoop
)
1292 sal_Int32 nDummy
= 0;
1297 // check which service we know ....
1298 static const sal_Char
* pTransTable
[] = {
1299 "com.sun.star.sdb.OfficeDatabaseDocument","sdatabase",
1300 "com.sun.star.report.ReportDefinition","sdatabase",
1301 "com.sun.star.text.TextDocument", "swriter",
1302 "com.sun.star.sheet.SpreadsheetDocument", "scalc",
1303 "com.sun.star.presentation.PresentationDocument", "simpress",
1304 "com.sun.star.drawing.DrawingDocument", "sdraw",
1305 "com.sun.star.formula.FormularProperties", "smath",
1306 "com.sun.star.chart.ChartDocument", "schart"
1308 OSL_ENSURE( ( sizeof( pTransTable
) / sizeof( pTransTable
[0] ) ) % 2 == 0,
1309 "lcl_getModuleHelpModuleName: odd size of translation table!" );
1311 // loop through the table
1312 sal_Int32 nTableEntries
= ( sizeof( pTransTable
) / sizeof( pTransTable
[0] ) ) / 2;
1313 const sal_Char
** pDocumentService
= pTransTable
;
1314 const sal_Char
** pHelpModuleName
= pTransTable
+ 1;
1315 for ( sal_Int32 j
=0; j
<nTableEntries
; ++j
)
1317 if ( xSI
->supportsService( ::rtl::OUString::createFromAscii( *pDocumentService
) ) )
1318 { // found a table entry which matches the model's services
1319 pReturn
= *pHelpModuleName
;
1323 ++pDocumentService
; ++pDocumentService
;
1324 ++pHelpModuleName
; ++pHelpModuleName
;
1330 // could not determine the document type we're living in
1332 SvtModuleOptions aModOpt
;
1333 if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::E_SWRITER
) )
1334 pReturn
= "swriter";
1335 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::E_SDATABASE
) )
1336 pReturn
= "sdatabase";
1337 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::E_SCALC
) )
1339 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS
) )
1340 pReturn
= "simpress";
1341 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::E_SDRAW
) )
1343 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::E_SMATH
) )
1345 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::E_SCHART
) )
1347 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::E_SBASIC
) )
1351 OSL_ENSURE( sal_False
, "lcl_getModuleHelpModuleName: no installed module found" );
1355 catch( const Exception
& )
1357 DBG_UNHANDLED_EXCEPTION();
1361 pReturn
= "swriter";
1363 return ::rtl::OUString::createFromAscii( pReturn
);
1367 // -----------------------------------------------------------------------------
1369 void OGenericUnoController::openHelpAgent(rtl::OUString
const& _suHelpStringURL
)
1371 rtl::OUString
suURL(_suHelpStringURL
);
1372 rtl::OUString sLanguage
= rtl::OUString::createFromAscii("Language=");
1373 if (suURL
.indexOf(sLanguage
) == -1)
1375 AppendConfigToken(suURL
, sal_False
/* sal_False := add '&' */ );
1378 aURL
.Complete
= suURL
;
1380 openHelpAgent( aURL
);
1383 void OGenericUnoController::openHelpAgent(sal_Int32 _nHelpId
)
1385 openHelpAgent( createHelpAgentURL( lcl_getModuleHelpModuleName( getFrame() ), _nHelpId
) );
1388 void OGenericUnoController::openHelpAgent( const URL
& _rURL
)
1394 if ( m_xUrlTransformer
.is() )
1395 m_xUrlTransformer
->parseStrict(aURL
);
1397 Reference
< XDispatchProvider
> xDispProv( m_aCurrentFrame
.getFrame(), UNO_QUERY
);
1398 Reference
< XDispatch
> xHelpDispatch
;
1399 if ( xDispProv
.is() )
1400 xHelpDispatch
= xDispProv
->queryDispatch(aURL
, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_helpagent")), FrameSearchFlag::PARENT
| FrameSearchFlag::SELF
);
1401 OSL_ENSURE(xHelpDispatch
.is(), "SbaTableQueryBrowser::openHelpAgent: could not get a dispatcher!");
1402 if (xHelpDispatch
.is())
1404 xHelpDispatch
->dispatch(aURL
, Sequence
< PropertyValue
>());
1407 catch( const Exception
& )
1409 DBG_UNHANDLED_EXCEPTION();
1412 // -----------------------------------------------------------------------------
1413 Reference
< awt::XWindow
> OGenericUnoController::getTopMostContainerWindow() const
1415 Reference
< ::com::sun::star::awt::XWindow
> xWindow
;
1417 // get the top most window
1418 Reference
< XFrame
> xFrame( m_aCurrentFrame
.getFrame() );
1421 xWindow
= xFrame
->getContainerWindow();
1423 while ( xFrame
.is() && !xFrame
->isTop() )
1425 xFrame
.set( xFrame
->getCreator(), UNO_QUERY
);
1428 xWindow
= xFrame
->getContainerWindow();
1432 // -----------------------------------------------------------------------------
1433 Reference
< XTitle
> OGenericUnoController::impl_getTitleHelper_throw()
1435 ::vos::OGuard
aSolarGuard( Application::GetSolarMutex() );
1436 ::osl::MutexGuard
aGuard( getMutex() );
1438 if ( ! m_xTitleHelper
.is ())
1440 Reference
< XUntitledNumbers
> xUntitledProvider(getPrivateModel(), UNO_QUERY
);
1441 Reference
< XController
> xThis(static_cast< XController
* >(this), UNO_QUERY_THROW
);
1443 ::framework::TitleHelper
* pHelper
= new ::framework::TitleHelper(m_xServiceFactory
);
1444 m_xTitleHelper
.set( static_cast< ::cppu::OWeakObject
* >(pHelper
), UNO_QUERY_THROW
);
1446 pHelper
->setOwner (xThis
);
1447 pHelper
->connectWithUntitledNumbers (xUntitledProvider
);
1450 return m_xTitleHelper
;
1453 //=============================================================================
1455 ::rtl::OUString SAL_CALL
OGenericUnoController::getTitle()
1456 throw (RuntimeException
)
1458 ::osl::MutexGuard
aGuard( getMutex() );
1459 if ( m_bExternalTitle
)
1460 return impl_getTitleHelper_throw()->getTitle ();
1461 return getPrivateTitle() + impl_getTitleHelper_throw()->getTitle ();
1464 //=============================================================================
1466 void SAL_CALL
OGenericUnoController::setTitle(const ::rtl::OUString
& sTitle
)
1467 throw (RuntimeException
)
1469 vos::OGuard
aSolarGuard( Application::GetSolarMutex() );
1470 ::osl::MutexGuard
aGuard( getMutex() );
1471 m_bExternalTitle
= sal_True
;
1472 impl_getTitleHelper_throw()->setTitle (sTitle
);
1475 //=============================================================================
1476 // XTitleChangeBroadcaster
1477 void SAL_CALL
OGenericUnoController::addTitleChangeListener(const Reference
< XTitleChangeListener
>& xListener
)
1478 throw (RuntimeException
)
1480 Reference
< XTitleChangeBroadcaster
> xBroadcaster(impl_getTitleHelper_throw(), UNO_QUERY
);
1481 if (xBroadcaster
.is ())
1482 xBroadcaster
->addTitleChangeListener (xListener
);
1485 // -----------------------------------------------------------------------------
1486 void SAL_CALL
OGenericUnoController::removeTitleChangeListener(const Reference
< XTitleChangeListener
>& xListener
)
1487 throw (RuntimeException
)
1489 Reference
< XTitleChangeBroadcaster
> xBroadcaster(impl_getTitleHelper_throw(), UNO_QUERY
);
1490 if (xBroadcaster
.is ())
1491 xBroadcaster
->removeTitleChangeListener (xListener
);
1494 // =============================================================================
1495 // XUserInputInterception
1496 // -----------------------------------------------------------------------------
1497 void SAL_CALL
OGenericUnoController::addKeyHandler( const Reference
< XKeyHandler
>& _rxHandler
) throw (RuntimeException
)
1499 if ( _rxHandler
.is() )
1500 m_pData
->m_aUserInputInterception
.addKeyHandler( _rxHandler
);
1503 // -----------------------------------------------------------------------------
1504 void SAL_CALL
OGenericUnoController::removeKeyHandler( const Reference
< XKeyHandler
>& _rxHandler
) throw (RuntimeException
)
1506 m_pData
->m_aUserInputInterception
.removeKeyHandler( _rxHandler
);
1509 // -----------------------------------------------------------------------------
1510 void SAL_CALL
OGenericUnoController::addMouseClickHandler( const Reference
< XMouseClickHandler
>& _rxHandler
) throw (RuntimeException
)
1512 if ( _rxHandler
.is() )
1513 m_pData
->m_aUserInputInterception
.addMouseClickHandler( _rxHandler
);
1516 // -----------------------------------------------------------------------------
1517 void SAL_CALL
OGenericUnoController::removeMouseClickHandler( const Reference
< XMouseClickHandler
>& _rxHandler
) throw (RuntimeException
)
1519 m_pData
->m_aUserInputInterception
.removeMouseClickHandler( _rxHandler
);
1522 // =============================================================================
1523 // -----------------------------------------------------------------------------
1524 void OGenericUnoController::executeChecked(sal_uInt16 _nCommandId
, const Sequence
< PropertyValue
>& aArgs
)
1526 if ( isCommandEnabled(_nCommandId
) )
1527 Execute(_nCommandId
, aArgs
);
1530 // -----------------------------------------------------------------------------
1531 sal_Bool
OGenericUnoController::isCommandEnabled(sal_uInt16 _nCommandId
) const
1533 return GetState( _nCommandId
).bEnabled
;
1536 // -----------------------------------------------------------------------------
1537 sal_uInt16
OGenericUnoController::registerCommandURL( const ::rtl::OUString
& _rCompleteCommandURL
)
1539 if ( !_rCompleteCommandURL
.getLength() )
1542 SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.find( _rCompleteCommandURL
);
1543 if ( aIter
!= m_aSupportedFeatures
.end() )
1544 return aIter
->second
.nFeatureId
;
1546 // this is a previously unkwnon command
1547 sal_uInt16 nFeatureId
= FIRST_USER_DEFINED_FEATURE
;
1548 while ( isFeatureSupported( nFeatureId
) && ( nFeatureId
< LAST_USER_DEFINED_FEATURE
) )
1550 if ( nFeatureId
== LAST_USER_DEFINED_FEATURE
)
1552 OSL_ENSURE( false, "OGenericUnoController::registerCommandURL: no more space for user defined features!" );
1556 ControllerFeature aFeature
;
1557 aFeature
.Command
= _rCompleteCommandURL
;
1558 aFeature
.nFeatureId
= nFeatureId
;
1559 aFeature
.GroupId
= CommandGroup::INTERNAL
;
1560 m_aSupportedFeatures
[ aFeature
.Command
] = aFeature
;
1565 // -----------------------------------------------------------------------------
1566 void OGenericUnoController::notifyHiContrastChanged()
1570 // -----------------------------------------------------------------------------
1571 sal_Bool
OGenericUnoController::isDataSourceReadOnly() const
1576 // -----------------------------------------------------------------------------
1577 Reference
< XController
> OGenericUnoController::getXController() throw( RuntimeException
)
1582 // -----------------------------------------------------------------------------
1583 bool OGenericUnoController::interceptUserInput( const NotifyEvent
& _rEvent
)
1585 return m_pData
->m_aUserInputInterception
.handleNotifyEvent( _rEvent
);
1588 // -----------------------------------------------------------------------------
1589 sal_Bool
OGenericUnoController::isCommandChecked(sal_uInt16 _nCommandId
) const
1591 FeatureState aState
= GetState( _nCommandId
);
1593 return aState
.bChecked
&& (sal_Bool
)*aState
.bChecked
;
1595 // -----------------------------------------------------------------------------
1596 sal_Bool
OGenericUnoController::isCommandEnabled( const ::rtl::OUString
& _rCompleteCommandURL
) const
1598 OSL_ENSURE( _rCompleteCommandURL
.getLength(), "OGenericUnoController::isCommandEnabled: Empty command url!" );
1600 sal_Bool bIsEnabled
= sal_False
;
1601 SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.find( _rCompleteCommandURL
);
1602 if ( aIter
!= m_aSupportedFeatures
.end() )
1603 bIsEnabled
= isCommandEnabled( aIter
->second
.nFeatureId
);
1608 // -----------------------------------------------------------------------------
1609 Sequence
< ::sal_Int16
> SAL_CALL
OGenericUnoController::getSupportedCommandGroups() throw (RuntimeException
)
1611 CommandHashMap aCmdHashMap
;
1612 for ( SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.begin();
1613 aIter
!= m_aSupportedFeatures
.end();
1616 if ( aIter
->second
.GroupId
!= CommandGroup::INTERNAL
)
1617 aCmdHashMap
.insert( CommandHashMap::value_type( aIter
->second
.GroupId
, 0 ));
1619 Sequence
< sal_Int16
> aCommandGroups( aCmdHashMap
.size() );
1620 ::std::transform( aCmdHashMap
.begin(),
1622 aCommandGroups
.getArray(),
1623 ::std::select1st
< CommandHashMap::value_type
>()
1626 return aCommandGroups
;
1629 // -----------------------------------------------------------------------------
1630 Sequence
< DispatchInformation
> SAL_CALL
OGenericUnoController::getConfigurableDispatchInformation( ::sal_Int16 CommandGroup
) throw (RuntimeException
)
1632 DispatchInfoList aInformationList
;
1633 DispatchInformation aDispatchInfo
;
1634 for ( SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.begin();
1635 aIter
!= m_aSupportedFeatures
.end();
1639 if ( sal_Int16( aIter
->second
.GroupId
) == CommandGroup
)
1641 aDispatchInfo
= aIter
->second
;
1642 aInformationList
.push_back( aDispatchInfo
);
1646 Sequence
< DispatchInformation
> aInformation( aInformationList
.size() );
1647 ::std::transform( aInformationList
.begin(),
1648 aInformationList
.end(),
1649 aInformation
.getArray(),
1650 ::std::identity
< DispatchInformation
>()
1653 return aInformation
;
1655 // -----------------------------------------------------------------------------
1656 void OGenericUnoController::fillSupportedFeatures()
1659 m_bDescribingSupportedFeatures
= true;
1661 describeSupportedFeatures();
1662 // -----------------------------------------------------------------------------
1664 m_bDescribingSupportedFeatures
= false;
1669 void SAL_CALL
OGenericUnoController::dispose() throw(::com::sun::star::uno::RuntimeException
)
1671 ::vos::OGuard
aSolarGuard(Application::GetSolarMutex());
1672 OGenericUnoController_Base::dispose();
1674 } // namespace dbaui