1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "genericcontroller.hxx"
30 #include <comphelper/uno3.hxx>
31 #include <toolkit/awt/vclxwindow.hxx>
32 #include "browserids.hxx"
33 #include <vcl/svapp.hxx>
34 #include <toolkit/helper/vclunohelper.hxx>
35 #include "dataview.hxx"
36 #include <tools/diagnose_ex.h>
37 #include <osl/diagnose.h>
38 #include "dbustrings.hrc"
39 #include <vcl/stdtext.hxx>
40 #include <cppuhelper/typeprovider.hxx>
41 #include <framework/titlehelper.hxx>
42 #include <comphelper/sequence.hxx>
43 #include <comphelper/extract.hxx>
44 #include <com/sun/star/sdbc/XDataSource.hpp>
45 #include <com/sun/star/sdb/SQLContext.hpp>
46 #include <com/sun/star/sdb/XCompletedConnection.hpp>
47 #include <com/sun/star/beans/XPropertySet.hpp>
48 #include <com/sun/star/task/XInteractionHandler.hpp>
49 #include <com/sun/star/util/XCloseable.hpp>
50 #include "UITools.hxx"
51 #include "commontypes.hxx"
53 #include <vcl/waitobj.hxx>
54 #include <svl/urihelper.hxx>
55 #include "datasourceconnector.hxx"
56 #include <unotools/moduleoptions.hxx>
57 #include <com/sun/star/frame/FrameSearchFlag.hpp>
58 #include <com/sun/star/frame/status/Visibility.hpp>
59 #include <com/sun/star/util/XModifiable.hpp>
60 #include <rtl/ustring.hxx>
61 #include <rtl/logfile.hxx>
63 #include <o3tl/compat_functional.hxx>
64 #include <boost/unordered_map.hpp>
65 #include <cppuhelper/implbase1.hxx>
68 using namespace ::com::sun::star
;
69 using namespace ::com::sun::star::uno
;
70 using namespace ::com::sun::star::beans
;
71 using namespace ::com::sun::star::frame
;
72 using namespace ::com::sun::star::frame::status
;
73 using namespace ::com::sun::star::util
;
74 using namespace ::com::sun::star::lang
;
75 using namespace ::com::sun::star::container
;
76 using namespace ::com::sun::star::sdbc
;
77 using namespace ::com::sun::star::sdb
;
78 using namespace ::com::sun::star::task
;
79 using namespace ::com::sun::star::awt
;
80 using namespace ::com::sun::star
;
81 using namespace ::dbtools
;
82 using namespace ::comphelper
;
84 // -------------------------------------------------------------------------
85 #define ALL_FEATURES -1
86 #define FIRST_USER_DEFINED_FEATURE ( ::std::numeric_limits< sal_uInt16 >::max() - 1000 )
87 #define LAST_USER_DEFINED_FEATURE ( ::std::numeric_limits< sal_uInt16 >::max() )
89 // -------------------------------------------------------------------------
90 typedef ::boost::unordered_map
< sal_Int16
, sal_Int16
> CommandHashMap
;
91 typedef ::std::list
< DispatchInformation
> DispatchInfoList
;
94 // -------------------------------------------------------------------------
95 const ::rtl::OUString
& getConfirmDeletionURL()
97 static const ::rtl::OUString
sConfirmDeletionURL( RTL_CONSTASCII_USTRINGPARAM( ".uno:FormSlots/ConfirmDeletion" ) );
98 return sConfirmDeletionURL
;
104 //==========================================================================
105 //= UserDefinedFeatures
106 //==========================================================================
107 class UserDefinedFeatures
110 UserDefinedFeatures( const Reference
< XController
>& _rxController
);
112 FeatureState
getState( const URL
& _rFeatureURL
);
113 void execute( const URL
& _rFeatureURL
, const Sequence
< PropertyValue
>& _rArgs
);
116 ::com::sun::star::uno::WeakReference
< XController
> m_aController
;
119 //--------------------------------------------------------------------------
120 UserDefinedFeatures::UserDefinedFeatures( const Reference
< XController
>& _rxController
)
121 :m_aController( _rxController
)
125 //--------------------------------------------------------------------------
126 FeatureState
UserDefinedFeatures::getState( const URL
& /*_rFeatureURL*/ )
128 // for now, enable all the time
129 // TODO: we should ask the dispatcher. However, this is laborious, since you cannot ask a dispatcher
130 // directly, but need to add a status listener.
132 aState
.bEnabled
= sal_True
;
136 //--------------------------------------------------------------------------
137 void UserDefinedFeatures::execute( const URL
& _rFeatureURL
, const Sequence
< PropertyValue
>& _rArgs
)
141 Reference
< XController
> xController( (Reference
< XController
>)m_aController
, UNO_SET_THROW
);
142 Reference
< XDispatchProvider
> xDispatchProvider( xController
->getFrame(), UNO_QUERY_THROW
);
143 Reference
< XDispatch
> xDispatch( xDispatchProvider
->queryDispatch(
145 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_self" ) ),
146 FrameSearchFlag::AUTO
149 if ( xDispatch
== xController
)
151 OSL_FAIL( "UserDefinedFeatures::execute: the controller shouldn't be the dispatcher here!" );
155 if ( xDispatch
.is() )
156 xDispatch
->dispatch( _rFeatureURL
, _rArgs
);
158 catch( const Exception
& )
160 DBG_UNHANDLED_EXCEPTION();
164 //==========================================================================
165 //= OGenericUnoController_Data
166 //==========================================================================
167 struct OGenericUnoController_Data
169 ::sfx2::UserInputInterception m_aUserInputInterception
;
170 UserDefinedFeatures m_aUserDefinedFeatures
;
172 OGenericUnoController_Data( OGenericUnoController
& _rController
, ::osl::Mutex
& _rMutex
)
173 :m_aUserInputInterception( _rController
, _rMutex
)
174 ,m_aUserDefinedFeatures( _rController
.getXController() )
179 //==========================================================================
180 //= OGenericUnoController
181 //==========================================================================
182 DBG_NAME(OGenericUnoController
)
183 // -------------------------------------------------------------------------
184 OGenericUnoController::OGenericUnoController(const Reference
< XMultiServiceFactory
>& _rM
)
185 :OGenericUnoController_Base( getMutex() )
188 ,m_bDescribingSupportedFeatures( false )
190 ,m_aAsyncInvalidateAll(LINK(this, OGenericUnoController
, OnAsyncInvalidateAll
))
191 ,m_aAsyncCloseTask(LINK(this, OGenericUnoController
, OnAsyncCloseTask
))
192 ,m_xServiceFactory(_rM
)
193 ,m_aCurrentFrame( *this )
194 ,m_bPreview(sal_False
)
195 ,m_bReadOnly(sal_False
)
196 ,m_bCurrentlyModified(sal_False
)
197 ,m_bExternalTitle(sal_False
)
199 osl_incrementInterlockedCount( &m_refCount
);
201 m_pData
.reset( new OGenericUnoController_Data( *this, getMutex() ) );
203 osl_decrementInterlockedCount( &m_refCount
);
205 DBG_CTOR(OGenericUnoController
,NULL
);
209 m_xUrlTransformer
= Reference
< XURLTransformer
> (_rM
->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))), UNO_QUERY
);
213 DBG_UNHANDLED_EXCEPTION();
218 // -----------------------------------------------------------------------------
219 OGenericUnoController::OGenericUnoController()
220 :OGenericUnoController_Base( getMutex() )
223 ,m_bDescribingSupportedFeatures( false )
225 ,m_aAsyncInvalidateAll(LINK(this, OGenericUnoController
, OnAsyncInvalidateAll
))
226 ,m_aAsyncCloseTask(LINK(this, OGenericUnoController
, OnAsyncCloseTask
))
227 ,m_aCurrentFrame( *this )
228 ,m_bPreview(sal_False
)
229 ,m_bReadOnly(sal_False
)
230 ,m_bCurrentlyModified(sal_False
)
232 OSL_FAIL( "OGenericUnoController::OGenericUnoController: illegal call!" );
233 // This ctor only exists because the MSVC compiler complained about an unresolved external
234 // symbol. It should not be used at all. Since using it yields strange runtime problems,
235 // we simply abort here.
240 // -----------------------------------------------------------------------------
241 OGenericUnoController::~OGenericUnoController()
244 DBG_DTOR(OGenericUnoController
,NULL
);
247 // -----------------------------------------------------------------------------
248 sal_Bool
OGenericUnoController::Construct(Window
* /*pParent*/)
250 OSL_ENSURE( getView(), "the view is NULL!" );
254 getView()->Construct();
258 m_aSupportedFeatures
.clear();
259 fillSupportedFeatures();
261 // create the database context
262 OSL_ENSURE(getORB().is(), "OGenericUnoController::Construct need a service factory!");
265 m_xDatabaseContext
= Reference
< XNameAccess
>(getORB()->createInstance(SERVICE_SDB_DATABASECONTEXT
), UNO_QUERY
);
269 OSL_FAIL("OGenericUnoController::Construct: could not create (or start listening at) the database context!");
272 if (!m_xDatabaseContext
.is())
273 { // at least notify the user. Though the whole component does not make any sense without the database context ...
274 ShowServiceNotAvailableError(getView(), String(SERVICE_SDB_DATABASECONTEXT
), sal_True
);
278 //------------------------------------------------------------------------------
279 IMPL_LINK_NOARG(OGenericUnoController
, OnAsyncInvalidateAll
)
281 if ( !OGenericUnoController_Base::rBHelper
.bInDispose
&& !OGenericUnoController_Base::rBHelper
.bDisposed
)
282 InvalidateFeature_Impl();
285 // -----------------------------------------------------------------------------
286 void OGenericUnoController::impl_initialize()
289 // -------------------------------------------------------------------------
290 void SAL_CALL
OGenericUnoController::initialize( const Sequence
< Any
>& aArguments
) throw(Exception
, RuntimeException
)
292 SolarMutexGuard aSolarGuard
;
293 ::osl::MutexGuard
aGuard( getMutex() );
295 Reference
< XWindow
> xParent
;
296 Reference
< XFrame
> xFrame
;
298 PropertyValue aValue
;
299 const Any
* pIter
= aArguments
.getConstArray();
300 const Any
* pEnd
= pIter
+ aArguments
.getLength();
302 for ( ; pIter
!= pEnd
; ++pIter
)
304 if ( ( *pIter
>>= aValue
) && ( 0 == aValue
.Name
.compareToAscii( "Frame" ) ) )
306 xFrame
.set(aValue
.Value
,UNO_QUERY_THROW
);
308 else if ( ( *pIter
>>= aValue
) && ( 0 == aValue
.Name
.compareToAscii( "Preview" ) ) )
310 aValue
.Value
>>= m_bPreview
;
311 m_bReadOnly
= sal_True
;
317 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "need a frame" ) ), *this, 1 );
319 xParent
= xFrame
->getContainerWindow();
320 VCLXWindow
* pParentComponent
= VCLXWindow::GetImplementation(xParent
);
321 Window
* pParentWin
= pParentComponent
? pParentComponent
->GetWindow() : NULL
;
324 throw IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Parent window is null")), *this, 1 );
327 m_aInitParameters
.assign( aArguments
);
328 Construct( pParentWin
);
330 ODataView
* pView
= getView();
332 throw RuntimeException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unable to create a view")), *this );
334 if ( m_bReadOnly
|| m_bPreview
)
335 pView
->EnableInput( sal_False
);
341 // no one clears my view if I won't
342 ::std::auto_ptr
<Window
> aTemp(m_pView
);
348 //------------------------------------------------------------------------------
349 void SAL_CALL
OGenericUnoController::acquire( ) throw ()
351 OGenericUnoController_Base::acquire();
354 //------------------------------------------------------------------------------
355 void SAL_CALL
OGenericUnoController::release( ) throw ()
357 OGenericUnoController_Base::release();
360 // -------------------------------------------------------------------------
361 void OGenericUnoController::startFrameListening( const Reference
< XFrame
>& _rxFrame
)
364 _rxFrame
->addFrameActionListener( this );
367 // -------------------------------------------------------------------------
368 void OGenericUnoController::stopFrameListening( const Reference
< XFrame
>& _rxFrame
)
371 _rxFrame
->removeFrameActionListener( this );
374 // -------------------------------------------------------------------------
375 void OGenericUnoController::disposing(const EventObject
& Source
) throw( RuntimeException
)
378 if ( Source
.Source
== getFrame() )
379 stopFrameListening( getFrame() );
381 //------------------------------------------------------------------------
382 void OGenericUnoController::modified(const EventObject
& aEvent
) throw( RuntimeException
)
384 ::osl::MutexGuard
aGuard( getMutex() );
385 if ( !isDataSourceReadOnly() )
387 Reference
<XModifiable
> xModi(aEvent
.Source
,UNO_QUERY
);
389 m_bCurrentlyModified
= xModi
->isModified(); // can only be reset by save
391 m_bCurrentlyModified
= sal_True
;
393 InvalidateFeature(ID_BROWSER_SAVEDOC
);
394 InvalidateFeature(ID_BROWSER_UNDO
);
396 // -----------------------------------------------------------------------
397 Reference
< XWindow
> SAL_CALL
OGenericUnoController::getComponentWindow() throw (RuntimeException
)
399 return VCLUnoHelper::GetInterface( getView() );
402 // -----------------------------------------------------------------------
403 ::rtl::OUString SAL_CALL
OGenericUnoController::getViewControllerName() throw (::com::sun::star::uno::RuntimeException
)
405 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Default" ) );
408 // -----------------------------------------------------------------------
409 Sequence
< PropertyValue
> SAL_CALL
OGenericUnoController::getCreationArguments() throw (RuntimeException
)
411 // currently we do not support any creation args, so anything passed to XModel2::createViewController would be
412 // lost, so we can equally return an empty sequence here
413 return Sequence
< PropertyValue
>();
416 // -----------------------------------------------------------------------
417 void OGenericUnoController::attachFrame( const Reference
< XFrame
>& _rxFrame
) throw( RuntimeException
)
419 SolarMutexGuard aSolarGuard
;
420 ::osl::MutexGuard
aGuard( getMutex() );
422 stopFrameListening( m_aCurrentFrame
.getFrame() );
423 Reference
< XFrame
> xFrame
= m_aCurrentFrame
.attachFrame( _rxFrame
);
424 startFrameListening( xFrame
);
429 getView()->attachFrame( xFrame
);
432 // -----------------------------------------------------------------------------
433 struct CommandCollector
: public ::std::unary_function
< SupportedFeatures::value_type
, void>
435 sal_uInt16 m_nFeature
;
436 StringBag
& m_rFeatureCommands
;
437 CommandCollector( sal_uInt16 _nFeature
, StringBag
& _rFeatureCommands
)
438 :m_nFeature ( _nFeature
)
439 ,m_rFeatureCommands( _rFeatureCommands
)
443 void operator() ( const SupportedFeatures::value_type
& lhs
)
445 if ( lhs
.second
.nFeatureId
== m_nFeature
)
446 m_rFeatureCommands
.insert( lhs
.first
);
450 // -----------------------------------------------------------------------
453 typedef ::std::vector
< Any
> States
;
455 // ...................................................................
456 void lcl_notifyMultipleStates( XStatusListener
& _rListener
, FeatureStateEvent
& _rEvent
, const States
& _rStates
)
458 for ( States::const_iterator state
= _rStates
.begin();
459 state
!= _rStates
.end();
463 _rEvent
.State
= *state
;
464 _rListener
.statusChanged( _rEvent
);
468 // ...................................................................
469 void lcl_collectStates( const FeatureState
& _rFeatureState
, States
& _out_rStates
)
471 // order matters, due to a bug in framework which resets the check state when any non-boolean event
473 // #i68215# is the bug to (re-)introduce this "ordered" notification here
474 // #i67882# is the bug which was caused by the real fix which we did in framework
475 // #i68216# is the bug which requests to fix the code in Draw which relies on
476 // framework's implementation details
477 if ( !!_rFeatureState
.sTitle
)
478 _out_rStates
.push_back( makeAny( *_rFeatureState
.sTitle
) );
479 if ( !!_rFeatureState
.bChecked
)
480 _out_rStates
.push_back( makeAny( (sal_Bool
)*_rFeatureState
.bChecked
) );
481 if ( !!_rFeatureState
.bInvisible
)
482 _out_rStates
.push_back( makeAny( Visibility( !*_rFeatureState
.bInvisible
) ) );
483 if ( _rFeatureState
.aValue
.hasValue() )
484 _out_rStates
.push_back( _rFeatureState
.aValue
);
485 if ( _out_rStates
.empty() )
486 _out_rStates
.push_back( Any() );
490 // -----------------------------------------------------------------------
491 void OGenericUnoController::ImplBroadcastFeatureState(const ::rtl::OUString
& _rFeature
, const Reference
< XStatusListener
> & xListener
, sal_Bool _bIgnoreCache
)
493 sal_uInt16 nFeat
= m_aSupportedFeatures
[ _rFeature
].nFeatureId
;
494 FeatureState
aFeatState( GetState( nFeat
) );
496 FeatureState
& rCachedState
= m_aStateCache
[nFeat
]; // creates if neccessary
497 if ( !_bIgnoreCache
)
499 // check if we really need to notify the listeners : this method may be called much more often than needed, so check
500 // the cached state of the feature
501 sal_Bool bAlreadyCached
= ( m_aStateCache
.find(nFeat
) != m_aStateCache
.end() );
502 if ( bAlreadyCached
)
503 if ( ( rCachedState
.bEnabled
== aFeatState
.bEnabled
)
504 && ( rCachedState
.bChecked
== aFeatState
.bChecked
)
505 && ( rCachedState
.bInvisible
== aFeatState
.bInvisible
)
506 && ( rCachedState
.sTitle
== aFeatState
.sTitle
)
510 rCachedState
= aFeatState
;
512 FeatureStateEvent aEvent
;
513 aEvent
.FeatureURL
.Complete
= _rFeature
;
514 if (m_xUrlTransformer
.is())
515 m_xUrlTransformer
->parseStrict(aEvent
.FeatureURL
);
516 aEvent
.Source
= (XDispatch
*)this;
517 aEvent
.IsEnabled
= aFeatState
.bEnabled
;
519 // collect all states to be notified
521 lcl_collectStates( aFeatState
, aStates
);
523 // a special listener ?
524 if ( xListener
.is() )
525 lcl_notifyMultipleStates( *xListener
.get(), aEvent
, aStates
);
527 { // no -> iterate through all listeners responsible for the URL
528 StringBag aFeatureCommands
;
530 m_aSupportedFeatures
.begin(),
531 m_aSupportedFeatures
.end(),
532 CommandCollector( nFeat
, aFeatureCommands
)
535 // it is possible that listeners are registered or revoked while
536 // we are notifying them, so we must use a copy of m_arrStatusListener, not
537 // m_arrStatusListener itself
538 Dispatch
aNotifyLoop( m_arrStatusListener
);
539 DispatchIterator iterSearch
= aNotifyLoop
.begin();
540 DispatchIterator iterEnd
= aNotifyLoop
.end();
542 while (iterSearch
!= iterEnd
)
544 DispatchTarget
& rCurrent
= *iterSearch
;
545 if ( aFeatureCommands
.find( rCurrent
.aURL
.Complete
) != aFeatureCommands
.end() )
547 aEvent
.FeatureURL
= rCurrent
.aURL
;
548 lcl_notifyMultipleStates( *rCurrent
.xListener
.get(), aEvent
, aStates
);
556 //------------------------------------------------------------------------------
557 sal_Bool
OGenericUnoController::isFeatureSupported( sal_Int32 _nId
)
559 SupportedFeatures::iterator aFeaturePos
= ::std::find_if(
560 m_aSupportedFeatures
.begin(),
561 m_aSupportedFeatures
.end(),
562 ::std::bind2nd( CompareFeatureById(), _nId
)
565 return ( m_aSupportedFeatures
.end() != aFeaturePos
&& !aFeaturePos
->first
.isEmpty());
568 // -----------------------------------------------------------------------
569 void OGenericUnoController::InvalidateFeature(const ::rtl::OUString
& _rURLPath
, const Reference
< XStatusListener
> & _xListener
, sal_Bool _bForceBroadcast
)
571 ImplInvalidateFeature( m_aSupportedFeatures
[ _rURLPath
].nFeatureId
, _xListener
, _bForceBroadcast
);
574 // -----------------------------------------------------------------------------
575 void OGenericUnoController::InvalidateFeature_Impl()
578 static sal_Int32 s_nRecursions
= 0;
582 sal_Bool bEmpty
= sal_True
;
583 FeatureListener aNextFeature
;
585 ::osl::MutexGuard
aGuard( m_aFeatureMutex
);
586 bEmpty
= m_aFeaturesToInvalidate
.empty();
588 aNextFeature
= m_aFeaturesToInvalidate
.front();
592 if ( ALL_FEATURES
== aNextFeature
.nId
)
594 InvalidateAll_Impl();
599 SupportedFeatures::iterator aFeaturePos
= ::std::find_if(
600 m_aSupportedFeatures
.begin(),
601 m_aSupportedFeatures
.end(),
602 ::std::bind2nd( CompareFeatureById(), aNextFeature
.nId
)
605 #if OSL_DEBUG_LEVEL > 0
606 if ( m_aSupportedFeatures
.end() == aFeaturePos
)
608 ::rtl::OString
sMessage( "OGenericUnoController::InvalidateFeature_Impl: feature id " );
609 sMessage
+= ::rtl::OString::valueOf( aNextFeature
.nId
);
610 sMessage
+= ::rtl::OString( " has been invalidated, but is not supported!" );
611 OSL_FAIL( sMessage
.getStr() );
614 if ( m_aSupportedFeatures
.end() != aFeaturePos
)
615 // we really know this feature
616 ImplBroadcastFeatureState( aFeaturePos
->first
, aNextFeature
.xListener
, aNextFeature
.bForceBroadcast
);
619 ::osl::MutexGuard
aGuard( m_aFeatureMutex
);
620 m_aFeaturesToInvalidate
.pop_front();
621 bEmpty
= m_aFeaturesToInvalidate
.empty();
623 aNextFeature
= m_aFeaturesToInvalidate
.front();
631 // -----------------------------------------------------------------------
632 void OGenericUnoController::ImplInvalidateFeature( sal_Int32 _nId
, const Reference
< XStatusListener
>& _xListener
, sal_Bool _bForceBroadcast
)
634 #if OSL_DEBUG_LEVEL > 0
637 SupportedFeatures::iterator aFeaturePos
= ::std::find_if(
638 m_aSupportedFeatures
.begin(),
639 m_aSupportedFeatures
.end(),
640 ::std::bind2nd( CompareFeatureById(), _nId
)
642 OSL_ENSURE( aFeaturePos
!= m_aSupportedFeatures
.end(), "OGenericUnoController::ImplInvalidateFeature: invalidating an unsupported feature is suspicious, at least!" );
646 FeatureListener aListener
;
647 aListener
.nId
= _nId
;
648 aListener
.xListener
= _xListener
;
649 aListener
.bForceBroadcast
= _bForceBroadcast
;
653 ::osl::MutexGuard
aGuard( m_aFeatureMutex
);
654 bWasEmpty
= m_aFeaturesToInvalidate
.empty();
655 m_aFeaturesToInvalidate
.push_back( aListener
);
659 m_aAsyncInvalidateAll
.Call();
662 // -----------------------------------------------------------------------
663 void OGenericUnoController::InvalidateFeature(sal_uInt16 _nId
, const Reference
< XStatusListener
> & _xListener
, sal_Bool _bForceBroadcast
)
665 ImplInvalidateFeature( _nId
, _xListener
, _bForceBroadcast
);
668 // -----------------------------------------------------------------------
669 void OGenericUnoController::InvalidateAll()
671 ImplInvalidateFeature( ALL_FEATURES
, NULL
, sal_True
);
674 // -----------------------------------------------------------------------------
675 void OGenericUnoController::InvalidateAll_Impl()
677 // ---------------------------------
678 // invalidate all supported features
680 for ( SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.begin();
681 aIter
!= m_aSupportedFeatures
.end();
684 ImplBroadcastFeatureState( aIter
->first
, NULL
, sal_True
);
687 ::osl::MutexGuard
aGuard( m_aFeatureMutex
);
688 OSL_ENSURE(m_aFeaturesToInvalidate
.size(), "OGenericUnoController::InvalidateAll_Impl: to be called from within InvalidateFeature_Impl only!");
689 m_aFeaturesToInvalidate
.pop_front();
690 if(!m_aFeaturesToInvalidate
.empty())
691 m_aAsyncInvalidateAll
.Call();
695 // -----------------------------------------------------------------------
696 Reference
< XDispatch
> OGenericUnoController::queryDispatch(const URL
& aURL
, const ::rtl::OUString
& aTargetFrameName
, sal_Int32 nSearchFlags
) throw( RuntimeException
)
698 Reference
< XDispatch
> xReturn
;
700 OSL_PRECOND( !m_aSupportedFeatures
.empty(), "OGenericUnoController::queryDispatch: shouldn't this be filled at construction time?" );
701 if ( m_aSupportedFeatures
.empty() )
702 fillSupportedFeatures();
704 // URL's we can handle ourself?
705 if ( aURL
.Complete
.equals( getConfirmDeletionURL() )
706 || ( ( m_aSupportedFeatures
.find( aURL
.Complete
) != m_aSupportedFeatures
.end() )
707 && !isUserDefinedFeature( aURL
.Complete
)
713 // no? -> ask the slave dispatcher
714 else if ( m_xSlaveDispatcher
.is() )
716 xReturn
= m_xSlaveDispatcher
->queryDispatch(aURL
, aTargetFrameName
, nSearchFlags
);
723 // -----------------------------------------------------------------------
724 Sequence
< Reference
< XDispatch
> > OGenericUnoController::queryDispatches(const Sequence
< DispatchDescriptor
>& aDescripts
) throw( RuntimeException
)
726 Sequence
< Reference
< XDispatch
> > aReturn
;
727 sal_Int32 nLen
= aDescripts
.getLength();
730 aReturn
.realloc( nLen
);
731 Reference
< XDispatch
>* pReturn
= aReturn
.getArray();
732 const Reference
< XDispatch
>* pReturnEnd
= aReturn
.getArray() + nLen
;
733 const DispatchDescriptor
* pDescripts
= aDescripts
.getConstArray();
735 for ( ; pReturn
!= pReturnEnd
; ++ pReturn
, ++pDescripts
)
737 *pReturn
= queryDispatch( pDescripts
->FeatureURL
, pDescripts
->FrameName
, pDescripts
->SearchFlags
);
744 // -----------------------------------------------------------------------
745 Reference
< XDispatchProvider
> OGenericUnoController::getSlaveDispatchProvider(void) throw( RuntimeException
)
747 return m_xSlaveDispatcher
;
750 // -----------------------------------------------------------------------
751 void OGenericUnoController::setSlaveDispatchProvider(const Reference
< XDispatchProvider
> & _xNewProvider
) throw( RuntimeException
)
753 m_xSlaveDispatcher
= _xNewProvider
;
756 // -----------------------------------------------------------------------
757 Reference
< XDispatchProvider
> OGenericUnoController::getMasterDispatchProvider(void) throw( RuntimeException
)
759 return m_xMasterDispatcher
;
762 // -----------------------------------------------------------------------
763 void OGenericUnoController::setMasterDispatchProvider(const Reference
< XDispatchProvider
> & _xNewProvider
) throw( RuntimeException
)
765 m_xMasterDispatcher
= _xNewProvider
;
768 // -----------------------------------------------------------------------
769 void OGenericUnoController::dispatch(const URL
& _aURL
, const Sequence
< PropertyValue
>& aArgs
) throw(RuntimeException
)
771 SolarMutexGuard aSolarGuard
;
772 // The SolarMutex is not locked anymore when the framework calls into
773 // here. So, lock it ourself. The real solution would be to lock it only in the places
774 // where it's needed, but a) this might turn out difficult, since we then also need to care
775 // for locking in the proper order (SolarMutex and m_aMutex), and b) this would be too many places
776 // for the time frame of the fix.
780 ::rtl::OString
sLog( "OGenericUnoController::dispatch( '" );
781 sLog
+= ::rtl::OString( _aURL
.Main
.getStr(), _aURL
.Main
.getLength(), osl_getThreadTextEncoding() );
782 sLog
+= ::rtl::OString( "' )" );
783 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "dbaccess", "frank.schoenheit@sun.com", sLog
.getStr() );
786 executeChecked(_aURL
,aArgs
);
789 // -----------------------------------------------------------------------
790 void OGenericUnoController::addStatusListener(const Reference
< XStatusListener
> & aListener
, const URL
& _rURL
) throw(RuntimeException
)
792 // parse the ULR now and here, this saves later parsing in each notification round
793 URL
aParsedURL( _rURL
);
794 if ( m_xUrlTransformer
.is() )
795 m_xUrlTransformer
->parseStrict( aParsedURL
);
797 // remember the listener together with the URL
798 m_arrStatusListener
.insert( m_arrStatusListener
.end(), DispatchTarget( aParsedURL
, aListener
) );
800 // initially broadcast the state
801 ImplBroadcastFeatureState( aParsedURL
.Complete
, aListener
, sal_True
);
802 // force the new state to be broadcast to the new listener
805 // -----------------------------------------------------------------------
806 void OGenericUnoController::removeStatusListener(const Reference
< XStatusListener
> & aListener
, const URL
& _rURL
) throw(RuntimeException
)
808 DispatchIterator iterSearch
= m_arrStatusListener
.begin();
810 sal_Bool bRemoveForAll
= _rURL
.Complete
.isEmpty();
811 while ( iterSearch
!= m_arrStatusListener
.end() )
813 DispatchTarget
& rCurrent
= *iterSearch
;
814 if ( (rCurrent
.xListener
== aListener
)
816 || (rCurrent
.aURL
.Complete
.equals(_rURL
.Complete
))
820 m_arrStatusListener
.erase( iterSearch
);
822 // remove the listener only for the given URL, so we can exit the loop after deletion
829 OSL_PRECOND( !m_aSupportedFeatures
.empty(), "OGenericUnoController::removeStatusListener: shouldn't this be filled at construction time?" );
830 if ( m_aSupportedFeatures
.empty() )
831 fillSupportedFeatures();
833 SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.find(_rURL
.Complete
);
834 if (aIter
!= m_aSupportedFeatures
.end())
835 { // clear the cache for that feature
836 StateCacheIterator aCachePos
= m_aStateCache
.find( aIter
->second
.nFeatureId
);
837 if ( aCachePos
!= m_aStateCache
.end() )
838 m_aStateCache
.erase( aCachePos
);
841 // now remove the listener from the deque
842 ::osl::MutexGuard
aGuard( m_aFeatureMutex
);
843 m_aFeaturesToInvalidate
.erase(
844 ::std::remove_if( m_aFeaturesToInvalidate
.begin(),
845 m_aFeaturesToInvalidate
.end(),
846 ::std::bind2nd(FindFeatureListener(),aListener
))
847 ,m_aFeaturesToInvalidate
.end());
849 // -----------------------------------------------------------------------------
850 void OGenericUnoController::releaseNumberForComponent()
854 Reference
< XUntitledNumbers
> xUntitledProvider(getPrivateModel(), UNO_QUERY
);
855 if ( xUntitledProvider
.is() )
856 xUntitledProvider
->releaseNumberForComponent(static_cast<XWeak
*>(this));
858 catch( const Exception
& )
863 // -----------------------------------------------------------------------
864 void OGenericUnoController::disposing()
867 EventObject aDisposeEvent
;
868 aDisposeEvent
.Source
= static_cast<XWeak
*>(this);
869 Dispatch aStatusListener
= m_arrStatusListener
;
870 Dispatch::iterator aEnd
= aStatusListener
.end();
871 for (Dispatch::iterator aIter
= aStatusListener
.begin(); aIter
!= aEnd
; ++aIter
)
873 aIter
->xListener
->disposing(aDisposeEvent
);
875 m_arrStatusListener
.clear();
878 m_xDatabaseContext
= NULL
;
880 ::osl::MutexGuard
aGuard( m_aFeatureMutex
);
881 m_aAsyncInvalidateAll
.CancelCall();
882 m_aFeaturesToInvalidate
.clear();
885 releaseNumberForComponent();
887 // check out from all the objects we are listening
889 stopFrameListening( m_aCurrentFrame
.getFrame() );
890 m_aCurrentFrame
.attachFrame( NULL
);
892 m_xMasterDispatcher
= NULL
;
893 m_xSlaveDispatcher
= NULL
;
894 m_xServiceFactory
= NULL
;
895 m_xTitleHelper
.clear();
896 m_xUrlTransformer
.clear();
897 m_aInitParameters
.clear();
900 // -----------------------------------------------------------------------------
901 void SAL_CALL
OGenericUnoController::addEventListener( const Reference
< XEventListener
>& xListener
) throw (RuntimeException
)
904 OGenericUnoController_Base::WeakComponentImplHelperBase::addEventListener( xListener
);
907 // -----------------------------------------------------------------------------
908 void SAL_CALL
OGenericUnoController::removeEventListener( const Reference
< XEventListener
>& xListener
) throw (RuntimeException
)
911 OGenericUnoController_Base::WeakComponentImplHelperBase::removeEventListener( xListener
);
914 //------------------------------------------------------------------------------
915 void OGenericUnoController::frameAction(const FrameActionEvent
& aEvent
) throw( RuntimeException
)
917 ::osl::MutexGuard
aGuard( getMutex() );
918 if ( aEvent
.Frame
== m_aCurrentFrame
.getFrame() )
919 m_aCurrentFrame
.frameAction( aEvent
.Action
);
922 //------------------------------------------------------------------------------
923 void OGenericUnoController::implDescribeSupportedFeature( const sal_Char
* _pAsciiCommandURL
,
924 sal_uInt16 _nFeatureId
, sal_Int16 _nCommandGroup
)
927 OSL_ENSURE( m_bDescribingSupportedFeatures
, "OGenericUnoController::implDescribeSupportedFeature: bad timing for this call!" );
929 OSL_PRECOND( _nFeatureId
< FIRST_USER_DEFINED_FEATURE
, "OGenericUnoController::implDescribeSupportedFeature: invalid feature id!" );
931 ControllerFeature aFeature
;
932 aFeature
.Command
= ::rtl::OUString::createFromAscii( _pAsciiCommandURL
);
933 aFeature
.nFeatureId
= _nFeatureId
;
934 aFeature
.GroupId
= _nCommandGroup
;
936 #if OSL_DEBUG_LEVEL > 0
937 OSL_ENSURE( m_aSupportedFeatures
.find( aFeature
.Command
) == m_aSupportedFeatures
.end(),
938 "OGenericUnoController::implDescribeSupportedFeature: this feature is already there!" );
940 m_aSupportedFeatures
[ aFeature
.Command
] = aFeature
;
943 //------------------------------------------------------------------------------
944 void OGenericUnoController::describeSupportedFeatures()
946 // add all supported features
947 implDescribeSupportedFeature( ".uno:Copy", ID_BROWSER_COPY
, CommandGroup::EDIT
);
948 implDescribeSupportedFeature( ".uno:Cut", ID_BROWSER_CUT
, CommandGroup::EDIT
);
949 implDescribeSupportedFeature( ".uno:Paste", ID_BROWSER_PASTE
, CommandGroup::EDIT
);
950 implDescribeSupportedFeature( ".uno:ClipboardFormatItems", ID_BROWSER_CLIPBOARD_FORMAT_ITEMS
);
951 implDescribeSupportedFeature( ".uno:DSBEditDoc", ID_BROWSER_EDITDOC
, CommandGroup::DOCUMENT
);
954 //------------------------------------------------------------------------------
955 FeatureState
OGenericUnoController::GetState( sal_uInt16 _nId
) const
957 FeatureState aReturn
;
958 // (disabled automatically)
962 case ID_BROWSER_UNDO
:
963 case ID_BROWSER_SAVEDOC
:
964 aReturn
.bEnabled
= sal_True
;
967 aReturn
= m_pData
->m_aUserDefinedFeatures
.getState( getURLForId( _nId
) );
974 //------------------------------------------------------------------------------
975 void OGenericUnoController::Execute( sal_uInt16 _nId
, const Sequence
< PropertyValue
>& _rArgs
)
977 OSL_ENSURE( isUserDefinedFeature( _nId
),
978 "OGenericUnoController::Execute: responsible for user defined features only!" );
980 // user defined features can be handled by dispatch interceptors resp. protocol handlers only.
981 // So, we need to do a queryDispatch, and dispatch the URL
982 m_pData
->m_aUserDefinedFeatures
.execute( getURLForId( _nId
), _rArgs
);
985 //------------------------------------------------------------------------------
986 URL
OGenericUnoController::getURLForId(sal_Int32 _nId
) const
989 if ( m_xUrlTransformer
.is() )
991 SupportedFeatures::const_iterator aIter
= ::std::find_if(
992 m_aSupportedFeatures
.begin(),
993 m_aSupportedFeatures
.end(),
994 ::std::bind2nd( CompareFeatureById(), _nId
)
997 if ( m_aSupportedFeatures
.end() != aIter
&& !aIter
->first
.isEmpty() )
999 aReturn
.Complete
= aIter
->first
;
1000 m_xUrlTransformer
->parseStrict( aReturn
);
1006 //-------------------------------------------------------------------------
1007 bool OGenericUnoController::isUserDefinedFeature( const sal_uInt16 _nFeatureId
) const
1009 return ( _nFeatureId
>= FIRST_USER_DEFINED_FEATURE
) && ( _nFeatureId
< LAST_USER_DEFINED_FEATURE
);
1012 //-------------------------------------------------------------------------
1013 bool OGenericUnoController::isUserDefinedFeature( const ::rtl::OUString
& _rFeatureURL
) const
1015 SupportedFeatures::const_iterator pos
= m_aSupportedFeatures
.find( _rFeatureURL
);
1016 OSL_PRECOND( pos
!= m_aSupportedFeatures
.end(),
1017 "OGenericUnoController::isUserDefinedFeature: this is no supported feature at all!" );
1019 return ( pos
!= m_aSupportedFeatures
.end() ) ? isUserDefinedFeature( pos
->second
.nFeatureId
) : false;
1022 //-------------------------------------------------------------------------
1023 sal_Bool SAL_CALL
OGenericUnoController::supportsService(const ::rtl::OUString
& ServiceName
) throw(RuntimeException
)
1025 Sequence
< ::rtl::OUString
> aSupported(getSupportedServiceNames());
1027 const ::rtl::OUString
* pArray
= aSupported
.getConstArray();
1028 const ::rtl::OUString
* pArrayEnd
= aSupported
.getConstArray() + aSupported
.getLength();
1030 for ( ;( pArray
!= pArrayEnd
) && !pArray
->equals( ServiceName
); ++pArray
)
1032 return pArray
!= pArrayEnd
;
1035 // -----------------------------------------------------------------------------
1036 void OGenericUnoController::startConnectionListening(const Reference
< XConnection
>& _rxConnection
)
1038 // we have to remove ourself before dispoing the connection
1039 Reference
< XComponent
> xComponent(_rxConnection
, UNO_QUERY
);
1040 if (xComponent
.is())
1041 xComponent
->addEventListener(static_cast<XFrameActionListener
*>(this));
1044 // -----------------------------------------------------------------------------
1045 void OGenericUnoController::stopConnectionListening(const Reference
< XConnection
>& _rxConnection
)
1047 // we have to remove ourself before dispoing the connection
1048 Reference
< XComponent
> xComponent(_rxConnection
, UNO_QUERY
);
1049 if (xComponent
.is())
1050 xComponent
->removeEventListener(static_cast<XFrameActionListener
*>(this));
1052 // -----------------------------------------------------------------------------
1053 Reference
< XConnection
> OGenericUnoController::connect( const Reference
< XDataSource
>& _xDataSource
,
1054 ::dbtools::SQLExceptionInfo
* _pErrorInfo
)
1056 WaitObject
aWaitCursor( getView() );
1058 ODatasourceConnector
aConnector( getORB(), getView(), ::rtl::OUString() );
1059 Reference
< XConnection
> xConnection
= aConnector
.connect( _xDataSource
, _pErrorInfo
);
1060 startConnectionListening( xConnection
);
1064 // -----------------------------------------------------------------------------
1065 Reference
< XConnection
> OGenericUnoController::connect( const ::rtl::OUString
& _rDataSourceName
,
1066 const ::rtl::OUString
& _rContextInformation
, ::dbtools::SQLExceptionInfo
* _pErrorInfo
)
1068 WaitObject
aWaitCursor( getView() );
1070 ODatasourceConnector
aConnector( getORB(), getView(), _rContextInformation
);
1071 Reference
<XConnection
> xConnection
= aConnector
.connect( _rDataSourceName
, _pErrorInfo
);
1072 startConnectionListening( xConnection
);
1077 // -----------------------------------------------------------------------------
1078 void OGenericUnoController::showError(const SQLExceptionInfo
& _rInfo
)
1080 ::dbaui::showError(_rInfo
,getView(),getORB());
1082 // -----------------------------------------------------------------------------
1083 Reference
< XLayoutManager
> OGenericUnoController::getLayoutManager(const Reference
< XFrame
>& _xFrame
) const
1085 Reference
< XPropertySet
> xPropSet( _xFrame
, UNO_QUERY
);
1086 Reference
< XLayoutManager
> xLayoutManager
;
1087 if ( xPropSet
.is() )
1091 xLayoutManager
.set(xPropSet
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))),UNO_QUERY
);
1093 catch ( Exception
& )
1097 return xLayoutManager
;
1099 // -----------------------------------------------------------------------------
1100 void OGenericUnoController::loadMenu(const Reference
< XFrame
>& _xFrame
)
1102 Reference
< XLayoutManager
> xLayoutManager
= getLayoutManager(_xFrame
);
1103 if ( xLayoutManager
.is() )
1105 xLayoutManager
->lock();
1106 xLayoutManager
->createElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" )));
1107 xLayoutManager
->createElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/toolbar" )));
1108 xLayoutManager
->unlock();
1109 xLayoutManager
->doLayout();
1112 onLoadedMenu( xLayoutManager
);
1115 // -----------------------------------------------------------------------------
1116 void OGenericUnoController::onLoadedMenu(const Reference
< XLayoutManager
>& /*_xLayoutManager*/)
1118 // not interested in
1121 // -----------------------------------------------------------------------------
1122 void OGenericUnoController::closeTask()
1124 m_aAsyncCloseTask
.Call();
1126 // -----------------------------------------------------------------------------
1127 IMPL_LINK_NOARG(OGenericUnoController
, OnAsyncCloseTask
)
1129 if ( !OGenericUnoController_Base::rBHelper
.bInDispose
)
1133 Reference
< util::XCloseable
> xCloseable( m_aCurrentFrame
.getFrame(), UNO_QUERY_THROW
);
1134 xCloseable
->close( sal_False
); // false - holds the owner ship for this frame inside this object!
1136 catch( const Exception
& )
1138 DBG_UNHANDLED_EXCEPTION();
1143 // -----------------------------------------------------------------------------
1144 Any SAL_CALL
OGenericUnoController::getViewData(void) throw( RuntimeException
)
1148 // -----------------------------------------------------------------------------
1149 void SAL_CALL
OGenericUnoController::restoreViewData(const Any
& /*Data*/) throw( RuntimeException
)
1153 // -----------------------------------------------------------------------------
1154 Reference
< XModel
> SAL_CALL
OGenericUnoController::getModel(void) throw( RuntimeException
)
1156 return Reference
< XModel
>();
1159 // -----------------------------------------------------------------------------
1160 Reference
< XFrame
> SAL_CALL
OGenericUnoController::getFrame(void) throw( RuntimeException
)
1162 ::osl::MutexGuard
aGuard( getMutex() );
1163 return m_aCurrentFrame
.getFrame();
1166 // -----------------------------------------------------------------------------
1167 sal_Bool SAL_CALL
OGenericUnoController::attachModel(const Reference
< XModel
> & /*xModel*/) throw( RuntimeException
)
1169 OSL_FAIL( "OGenericUnoController::attachModel: not supported!" );
1173 // -----------------------------------------------------------------------------
1174 void OGenericUnoController::executeUnChecked(sal_uInt16 _nCommandId
, const Sequence
< PropertyValue
>& aArgs
)
1176 Execute(_nCommandId
, aArgs
);
1178 // -----------------------------------------------------------------------------
1179 void OGenericUnoController::executeUnChecked(const util::URL
& _rCommand
, const Sequence
< PropertyValue
>& aArgs
)
1181 OSL_PRECOND( !m_aSupportedFeatures
.empty(), "OGenericUnoController::executeUnChecked: shouldn't this be filled at construction time?" );
1182 if ( m_aSupportedFeatures
.empty() )
1183 fillSupportedFeatures();
1185 SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.find( _rCommand
.Complete
);
1186 if (aIter
!= m_aSupportedFeatures
.end())
1187 Execute( aIter
->second
.nFeatureId
, aArgs
);
1189 // -----------------------------------------------------------------------------
1190 void OGenericUnoController::executeChecked(const util::URL
& _rCommand
, const Sequence
< PropertyValue
>& aArgs
)
1192 OSL_PRECOND( !m_aSupportedFeatures
.empty(), "OGenericUnoController::executeChecked: shouldn't this be filled at construction time?" );
1193 if ( m_aSupportedFeatures
.empty() )
1194 fillSupportedFeatures();
1196 SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.find( _rCommand
.Complete
);
1197 if ( aIter
!= m_aSupportedFeatures
.end() )
1199 sal_uInt16 nFeatureId
= aIter
->second
.nFeatureId
;
1200 if ( GetState( nFeatureId
).bEnabled
)
1201 Execute( nFeatureId
, aArgs
);
1204 // -----------------------------------------------------------------------------
1205 //------------------------------------------------------------------------------
1208 ::rtl::OUString
lcl_getModuleHelpModuleName( const Reference
< XFrame
>& _rxFrame
)
1210 const sal_Char
* pReturn
= NULL
;
1214 // get the model of the document in the given frame
1215 Reference
< XController
> xController
;
1216 if ( _rxFrame
.is() )
1217 xController
= _rxFrame
->getController();
1218 Reference
< XModel
> xModel
;
1219 if ( xController
.is() )
1220 xModel
= xController
->getModel();
1221 Reference
< XServiceInfo
> xSI( xModel
, UNO_QUERY
);
1224 { // try to go up the frame hierarchy
1226 Reference
< XFrame
> xParentFrame
;
1227 if ( _rxFrame
.is() )
1228 xParentFrame
= xParentFrame
.query( _rxFrame
->getCreator() );
1229 // did we find a parent frame? Which is no top-level frame?
1230 if ( xParentFrame
.is() && !_rxFrame
->isTop() )
1231 // TODO: to prevent framework assertions, re-insert this "isTop" once 98303 is fixed
1232 return lcl_getModuleHelpModuleName( xParentFrame
);
1236 #if OSL_DEBUG_LEVEL > 0
1237 Sequence
< ::rtl::OUString
> sServiceNames
= xSI
->getSupportedServiceNames();
1238 const ::rtl::OUString
* pLoop
= sServiceNames
.getConstArray();
1239 for ( sal_Int32 i
=0; i
<sServiceNames
.getLength(); ++i
, ++pLoop
)
1241 sal_Int32 nDummy
= 0;
1246 // check which service we know ....
1247 static const sal_Char
* pTransTable
[] = {
1248 "com.sun.star.sdb.OfficeDatabaseDocument","sdatabase",
1249 "com.sun.star.report.ReportDefinition","sdatabase",
1250 "com.sun.star.text.TextDocument", "swriter",
1251 "com.sun.star.sheet.SpreadsheetDocument", "scalc",
1252 "com.sun.star.presentation.PresentationDocument", "simpress",
1253 "com.sun.star.drawing.DrawingDocument", "sdraw",
1254 "com.sun.star.formula.FormularProperties", "smath",
1255 "com.sun.star.chart.ChartDocument", "schart"
1257 OSL_ENSURE( ( sizeof( pTransTable
) / sizeof( pTransTable
[0] ) ) % 2 == 0,
1258 "lcl_getModuleHelpModuleName: odd size of translation table!" );
1260 // loop through the table
1261 sal_Int32 nTableEntries
= ( sizeof( pTransTable
) / sizeof( pTransTable
[0] ) ) / 2;
1262 const sal_Char
** pDocumentService
= pTransTable
;
1263 const sal_Char
** pHelpModuleName
= pTransTable
+ 1;
1264 for ( sal_Int32 j
=0; j
<nTableEntries
; ++j
)
1266 if ( xSI
->supportsService( ::rtl::OUString::createFromAscii( *pDocumentService
) ) )
1267 { // found a table entry which matches the model's services
1268 pReturn
= *pHelpModuleName
;
1272 ++pDocumentService
; ++pDocumentService
;
1273 ++pHelpModuleName
; ++pHelpModuleName
;
1279 // could not determine the document type we're living in
1281 SvtModuleOptions aModOpt
;
1282 if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::E_SWRITER
) )
1283 pReturn
= "swriter";
1284 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::E_SDATABASE
) )
1285 pReturn
= "sdatabase";
1286 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::E_SCALC
) )
1288 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS
) )
1289 pReturn
= "simpress";
1290 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::E_SDRAW
) )
1292 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::E_SMATH
) )
1294 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::E_SCHART
) )
1296 else if ( aModOpt
.IsModuleInstalled( SvtModuleOptions::E_SBASIC
) )
1300 OSL_FAIL( "lcl_getModuleHelpModuleName: no installed module found" );
1304 catch( const Exception
& )
1306 DBG_UNHANDLED_EXCEPTION();
1310 pReturn
= "swriter";
1312 return ::rtl::OUString::createFromAscii( pReturn
);
1316 // -----------------------------------------------------------------------------
1318 void OGenericUnoController::openHelpAgent(rtl::OUString
const& _suHelpStringURL
)
1320 rtl::OUString
suURL(_suHelpStringURL
);
1321 rtl::OUString
sLanguage(RTL_CONSTASCII_USTRINGPARAM("Language="));
1322 if (suURL
.indexOf(sLanguage
) == -1)
1324 AppendConfigToken(suURL
, sal_False
/* sal_False := add '&' */ );
1327 aURL
.Complete
= suURL
;
1329 openHelpAgent( aURL
);
1332 void OGenericUnoController::openHelpAgent(const rtl::OString
& _sHelpId
)
1334 openHelpAgent( createHelpAgentURL( lcl_getModuleHelpModuleName( getFrame() ), _sHelpId
) );
1337 void OGenericUnoController::openHelpAgent( const URL
& _rURL
)
1343 if ( m_xUrlTransformer
.is() )
1344 m_xUrlTransformer
->parseStrict(aURL
);
1346 Reference
< XDispatchProvider
> xDispProv( m_aCurrentFrame
.getFrame(), UNO_QUERY
);
1347 Reference
< XDispatch
> xHelpDispatch
;
1348 if ( xDispProv
.is() )
1349 xHelpDispatch
= xDispProv
->queryDispatch(aURL
, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_helpagent")), FrameSearchFlag::PARENT
| FrameSearchFlag::SELF
);
1350 OSL_ENSURE(xHelpDispatch
.is(), "SbaTableQueryBrowser::openHelpAgent: could not get a dispatcher!");
1351 if (xHelpDispatch
.is())
1353 xHelpDispatch
->dispatch(aURL
, Sequence
< PropertyValue
>());
1356 catch( const Exception
& )
1358 DBG_UNHANDLED_EXCEPTION();
1361 // -----------------------------------------------------------------------------
1362 Reference
< awt::XWindow
> OGenericUnoController::getTopMostContainerWindow() const
1364 Reference
< ::com::sun::star::awt::XWindow
> xWindow
;
1366 // get the top most window
1367 Reference
< XFrame
> xFrame( m_aCurrentFrame
.getFrame() );
1370 xWindow
= xFrame
->getContainerWindow();
1372 while ( xFrame
.is() && !xFrame
->isTop() )
1374 xFrame
.set( xFrame
->getCreator(), UNO_QUERY
);
1377 xWindow
= xFrame
->getContainerWindow();
1381 // -----------------------------------------------------------------------------
1382 Reference
< XTitle
> OGenericUnoController::impl_getTitleHelper_throw()
1384 SolarMutexGuard aSolarGuard
;
1385 ::osl::MutexGuard
aGuard( getMutex() );
1387 if ( ! m_xTitleHelper
.is ())
1389 Reference
< XUntitledNumbers
> xUntitledProvider(getPrivateModel(), UNO_QUERY
);
1390 Reference
< XController
> xThis(static_cast< XController
* >(this), UNO_QUERY_THROW
);
1392 ::framework::TitleHelper
* pHelper
= new ::framework::TitleHelper(m_xServiceFactory
);
1393 m_xTitleHelper
.set( static_cast< ::cppu::OWeakObject
* >(pHelper
), UNO_QUERY_THROW
);
1395 pHelper
->setOwner (xThis
);
1396 pHelper
->connectWithUntitledNumbers (xUntitledProvider
);
1399 return m_xTitleHelper
;
1402 //=============================================================================
1404 ::rtl::OUString SAL_CALL
OGenericUnoController::getTitle()
1405 throw (RuntimeException
)
1407 ::osl::MutexGuard
aGuard( getMutex() );
1408 if ( m_bExternalTitle
)
1409 return impl_getTitleHelper_throw()->getTitle ();
1410 return getPrivateTitle() + impl_getTitleHelper_throw()->getTitle ();
1413 //=============================================================================
1415 void SAL_CALL
OGenericUnoController::setTitle(const ::rtl::OUString
& sTitle
)
1416 throw (RuntimeException
)
1418 SolarMutexGuard aSolarGuard
;
1419 ::osl::MutexGuard
aGuard( getMutex() );
1420 m_bExternalTitle
= sal_True
;
1421 impl_getTitleHelper_throw()->setTitle (sTitle
);
1424 //=============================================================================
1425 // XTitleChangeBroadcaster
1426 void SAL_CALL
OGenericUnoController::addTitleChangeListener(const Reference
< XTitleChangeListener
>& xListener
)
1427 throw (RuntimeException
)
1429 Reference
< XTitleChangeBroadcaster
> xBroadcaster(impl_getTitleHelper_throw(), UNO_QUERY
);
1430 if (xBroadcaster
.is ())
1431 xBroadcaster
->addTitleChangeListener (xListener
);
1434 // -----------------------------------------------------------------------------
1435 void SAL_CALL
OGenericUnoController::removeTitleChangeListener(const Reference
< XTitleChangeListener
>& xListener
)
1436 throw (RuntimeException
)
1438 Reference
< XTitleChangeBroadcaster
> xBroadcaster(impl_getTitleHelper_throw(), UNO_QUERY
);
1439 if (xBroadcaster
.is ())
1440 xBroadcaster
->removeTitleChangeListener (xListener
);
1443 // =============================================================================
1444 // XUserInputInterception
1445 // -----------------------------------------------------------------------------
1446 void SAL_CALL
OGenericUnoController::addKeyHandler( const Reference
< XKeyHandler
>& _rxHandler
) throw (RuntimeException
)
1448 if ( _rxHandler
.is() )
1449 m_pData
->m_aUserInputInterception
.addKeyHandler( _rxHandler
);
1452 // -----------------------------------------------------------------------------
1453 void SAL_CALL
OGenericUnoController::removeKeyHandler( const Reference
< XKeyHandler
>& _rxHandler
) throw (RuntimeException
)
1455 m_pData
->m_aUserInputInterception
.removeKeyHandler( _rxHandler
);
1458 // -----------------------------------------------------------------------------
1459 void SAL_CALL
OGenericUnoController::addMouseClickHandler( const Reference
< XMouseClickHandler
>& _rxHandler
) throw (RuntimeException
)
1461 if ( _rxHandler
.is() )
1462 m_pData
->m_aUserInputInterception
.addMouseClickHandler( _rxHandler
);
1465 // -----------------------------------------------------------------------------
1466 void SAL_CALL
OGenericUnoController::removeMouseClickHandler( const Reference
< XMouseClickHandler
>& _rxHandler
) throw (RuntimeException
)
1468 m_pData
->m_aUserInputInterception
.removeMouseClickHandler( _rxHandler
);
1471 // =============================================================================
1472 // -----------------------------------------------------------------------------
1473 void OGenericUnoController::executeChecked(sal_uInt16 _nCommandId
, const Sequence
< PropertyValue
>& aArgs
)
1475 if ( isCommandEnabled(_nCommandId
) )
1476 Execute(_nCommandId
, aArgs
);
1479 // -----------------------------------------------------------------------------
1480 sal_Bool
OGenericUnoController::isCommandEnabled(sal_uInt16 _nCommandId
) const
1482 return GetState( _nCommandId
).bEnabled
;
1485 // -----------------------------------------------------------------------------
1486 sal_uInt16
OGenericUnoController::registerCommandURL( const ::rtl::OUString
& _rCompleteCommandURL
)
1488 if ( _rCompleteCommandURL
.isEmpty() )
1491 SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.find( _rCompleteCommandURL
);
1492 if ( aIter
!= m_aSupportedFeatures
.end() )
1493 return aIter
->second
.nFeatureId
;
1495 // this is a previously unkwnon command
1496 sal_uInt16 nFeatureId
= FIRST_USER_DEFINED_FEATURE
;
1497 while ( isFeatureSupported( nFeatureId
) && ( nFeatureId
< LAST_USER_DEFINED_FEATURE
) )
1499 if ( nFeatureId
== LAST_USER_DEFINED_FEATURE
)
1501 OSL_FAIL( "OGenericUnoController::registerCommandURL: no more space for user defined features!" );
1505 ControllerFeature aFeature
;
1506 aFeature
.Command
= _rCompleteCommandURL
;
1507 aFeature
.nFeatureId
= nFeatureId
;
1508 aFeature
.GroupId
= CommandGroup::INTERNAL
;
1509 m_aSupportedFeatures
[ aFeature
.Command
] = aFeature
;
1514 // -----------------------------------------------------------------------------
1515 void OGenericUnoController::notifyHiContrastChanged()
1519 // -----------------------------------------------------------------------------
1520 sal_Bool
OGenericUnoController::isDataSourceReadOnly() const
1525 // -----------------------------------------------------------------------------
1526 Reference
< XController
> OGenericUnoController::getXController() throw( RuntimeException
)
1531 // -----------------------------------------------------------------------------
1532 bool OGenericUnoController::interceptUserInput( const NotifyEvent
& _rEvent
)
1534 return m_pData
->m_aUserInputInterception
.handleNotifyEvent( _rEvent
);
1537 // -----------------------------------------------------------------------------
1538 sal_Bool
OGenericUnoController::isCommandChecked(sal_uInt16 _nCommandId
) const
1540 FeatureState aState
= GetState( _nCommandId
);
1542 return aState
.bChecked
&& (sal_Bool
)*aState
.bChecked
;
1544 // -----------------------------------------------------------------------------
1545 sal_Bool
OGenericUnoController::isCommandEnabled( const ::rtl::OUString
& _rCompleteCommandURL
) const
1547 OSL_ENSURE( !_rCompleteCommandURL
.isEmpty(), "OGenericUnoController::isCommandEnabled: Empty command url!" );
1549 sal_Bool bIsEnabled
= sal_False
;
1550 SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.find( _rCompleteCommandURL
);
1551 if ( aIter
!= m_aSupportedFeatures
.end() )
1552 bIsEnabled
= isCommandEnabled( aIter
->second
.nFeatureId
);
1557 // -----------------------------------------------------------------------------
1558 Sequence
< ::sal_Int16
> SAL_CALL
OGenericUnoController::getSupportedCommandGroups() throw (RuntimeException
)
1560 CommandHashMap aCmdHashMap
;
1561 for ( SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.begin();
1562 aIter
!= m_aSupportedFeatures
.end();
1565 if ( aIter
->second
.GroupId
!= CommandGroup::INTERNAL
)
1566 aCmdHashMap
.insert( CommandHashMap::value_type( aIter
->second
.GroupId
, 0 ));
1568 Sequence
< sal_Int16
> aCommandGroups( aCmdHashMap
.size() );
1569 ::std::transform( aCmdHashMap
.begin(),
1571 aCommandGroups
.getArray(),
1572 ::o3tl::select1st
< CommandHashMap::value_type
>()
1575 return aCommandGroups
;
1580 //Current c++0x draft (apparently) has std::identity, but not operator()
1581 template<typename T
> struct SGI_identity
: public std::unary_function
<T
,T
>
1583 T
& operator()(T
& x
) const { return x
; }
1584 const T
& operator()(const T
& x
) const { return x
; }
1588 // -----------------------------------------------------------------------------
1589 Sequence
< DispatchInformation
> SAL_CALL
OGenericUnoController::getConfigurableDispatchInformation( ::sal_Int16 CommandGroup
) throw (RuntimeException
)
1591 DispatchInfoList aInformationList
;
1592 DispatchInformation aDispatchInfo
;
1593 for ( SupportedFeatures::const_iterator aIter
= m_aSupportedFeatures
.begin();
1594 aIter
!= m_aSupportedFeatures
.end();
1598 if ( sal_Int16( aIter
->second
.GroupId
) == CommandGroup
)
1600 aDispatchInfo
= aIter
->second
;
1601 aInformationList
.push_back( aDispatchInfo
);
1605 Sequence
< DispatchInformation
> aInformation( aInformationList
.size() );
1606 ::std::transform( aInformationList
.begin(),
1607 aInformationList
.end(),
1608 aInformation
.getArray(),
1609 SGI_identity
< DispatchInformation
>()
1612 return aInformation
;
1614 // -----------------------------------------------------------------------------
1615 void OGenericUnoController::fillSupportedFeatures()
1618 m_bDescribingSupportedFeatures
= true;
1620 describeSupportedFeatures();
1621 // -----------------------------------------------------------------------------
1623 m_bDescribingSupportedFeatures
= false;
1628 void SAL_CALL
OGenericUnoController::dispose() throw(::com::sun::star::uno::RuntimeException
)
1630 SolarMutexGuard aSolarGuard
;
1631 OGenericUnoController_Base::dispose();
1633 } // namespace dbaui
1635 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */