1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_dbaccess.hxx"
26 #ifndef DBAUI_GENERICCONTROLLER_HXX
27 #include "genericcontroller.hxx"
28 #endif
29 #ifndef _COMPHELPER_UNO3_HXX_
30 #include <comphelper/uno3.hxx>
31 #endif
32 #ifndef _TOOLKIT_AWT_VCLXWINDOW_HXX_
33 #include <toolkit/awt/vclxwindow.hxx>
34 #endif
35 #ifndef DBACCESS_UI_BROWSER_ID_HXX
36 #include "browserids.hxx"
37 #endif
38 #ifndef _SV_SVAPP_HXX //autogen
39 #include <vcl/svapp.hxx>
40 #endif
41 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
42 #include <toolkit/helper/vclunohelper.hxx>
43 #endif
44 #ifndef DBAUI_DATAVIEW_HXX
45 #include "dataview.hxx"
46 #endif
47 #ifndef _TOOLS_DEBUG_HXX
48 #include <tools/debug.hxx>
49 #endif
50 #ifndef TOOLS_DIAGNOSE_EX_H
51 #include <tools/diagnose_ex.h>
52 #endif
53 #ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
54 #include "dbustrings.hrc"
55 #endif
56 #ifndef _VCL_STDTEXT_HXX
57 #include <vcl/stdtext.hxx>
58 #endif
59 #ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
60 #include <cppuhelper/typeprovider.hxx>
61 #endif
62 #include <framework/titlehelper.hxx>
63 #ifndef _COMPHELPER_SEQUENCE_HXX_
64 #include <comphelper/sequence.hxx>
65 #endif
66 #ifndef _COMPHELPER_EXTRACT_HXX_
67 #include <comphelper/extract.hxx>
68 #endif
69 #ifndef _COM_SUN_STAR_SDBC_XDATASOURCE_HPP_
70 #include <com/sun/star/sdbc/XDataSource.hpp>
71 #endif
72 #ifndef _COM_SUN_STAR_SDB_SQLCONTEXT_HPP_
73 #include <com/sun/star/sdb/SQLContext.hpp>
74 #endif
75 #ifndef _COM_SUN_STAR_SDB_XCOMPLETEDCONNECTION_HPP_
76 #include <com/sun/star/sdb/XCompletedConnection.hpp>
77 #endif
78 #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
79 #include <com/sun/star/beans/XPropertySet.hpp>
80 #endif
81 #ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_
82 #include <com/sun/star/task/XInteractionHandler.hpp>
83 #endif
84 #ifndef _COM_SUN_STAR_UTIL_XCLOSEABLE_HPP_
85 #include <com/sun/star/util/XCloseable.hpp>
86 #endif
87 #ifndef DBAUI_TOOLS_HXX
88 #include "UITools.hxx"
89 #endif
90 #ifndef _DBAUI_COMMON_TYPES_HXX_
91 #include "commontypes.hxx"
92 #endif
93 
94 #ifndef _SV_WAITOBJ_HXX
95 #include <vcl/waitobj.hxx>
96 #endif
97 #ifndef _URLOBJ_HXX
98 #include <tools/urlobj.hxx>
99 #endif
100 #ifndef SVTOOLS_URIHELPER_HXX
101 #include <svl/urihelper.hxx>
102 #endif
103 #ifndef _DBAUI_DATASOURCECONNECTOR_HXX_
104 #include "datasourceconnector.hxx"
105 #endif
106 #ifndef INCLUDED_SVTOOLS_MODULEOPTIONS_HXX
107 #include <unotools/moduleoptions.hxx>
108 #endif
109 #ifndef _COM_SUN_STAR_FRAME_FRAMESEARCHFLAG_HPP_
110 #include <com/sun/star/frame/FrameSearchFlag.hpp>
111 #endif
112 #ifndef _COM_SUN_STAR_FRAME_STATUS_VISIBILITY_HPP_
113 #include <com/sun/star/frame/status/Visibility.hpp>
114 #endif
115 #ifndef _COM_SUN_STAR_UTIL_XMODIFIABLE_HPP_
116 #include <com/sun/star/util/XModifiable.hpp>
117 #endif
118 #ifndef _RTL_USTRING_HXX_
119 #include <rtl/ustring.hxx>
120 #endif
121 #ifndef _RTL_LOGFILE_HXX_
122 #include <rtl/logfile.hxx>
123 #endif
124 #include <algorithm>
125 #include <hash_map>
126 #include <cppuhelper/implbase1.hxx>
127 #include <limits>
128 
129 using namespace ::com::sun::star;
130 using namespace ::com::sun::star::uno;
131 using namespace ::com::sun::star::beans;
132 using namespace ::com::sun::star::frame;
133 using namespace ::com::sun::star::frame::status;
134 using namespace ::com::sun::star::util;
135 using namespace ::com::sun::star::lang;
136 using namespace ::com::sun::star::container;
137 using namespace ::com::sun::star::sdbc;
138 using namespace ::com::sun::star::sdb;
139 using namespace ::com::sun::star::task;
140 using namespace ::com::sun::star::awt;
141 using namespace ::com::sun::star;
142 using namespace ::dbtools;
143 using namespace ::comphelper;
144 
145 // -------------------------------------------------------------------------
146 #define ALL_FEATURES	            -1
147 #define FIRST_USER_DEFINED_FEATURE  ( ::std::numeric_limits< sal_uInt16 >::max() - 1000 )
148 #define LAST_USER_DEFINED_FEATURE   ( ::std::numeric_limits< sal_uInt16 >::max()        )
149 
150 // -------------------------------------------------------------------------
151 typedef ::std::hash_map< sal_Int16, sal_Int16 > CommandHashMap;
152 typedef ::std::list< DispatchInformation > DispatchInfoList;
153 
154 
155 // -------------------------------------------------------------------------
getConfirmDeletionURL()156 const ::rtl::OUString& getConfirmDeletionURL()
157 {
158 	static const ::rtl::OUString sConfirmDeletionURL( RTL_CONSTASCII_USTRINGPARAM( ".uno:FormSlots/ConfirmDeletion" ) );
159 	return sConfirmDeletionURL;
160 }
161 
162 namespace dbaui
163 {
164 
165 //==========================================================================
166 //= UserDefinedFeatures
167 //==========================================================================
168 class UserDefinedFeatures
169 {
170 public:
171     UserDefinedFeatures( const Reference< XController >& _rxController );
172 
173     FeatureState    getState( const URL& _rFeatureURL );
174     void            execute( const URL& _rFeatureURL, const Sequence< PropertyValue>& _rArgs );
175 
176 private:
177     ::com::sun::star::uno::WeakReference< XController > m_aController;
178 };
179 
180 //--------------------------------------------------------------------------
UserDefinedFeatures(const Reference<XController> & _rxController)181 UserDefinedFeatures::UserDefinedFeatures( const Reference< XController >& _rxController )
182     :m_aController( _rxController )
183 {
184 }
185 
186 //--------------------------------------------------------------------------
getState(const URL &)187 FeatureState UserDefinedFeatures::getState( const URL& /*_rFeatureURL*/ )
188 {
189     // for now, enable all the time
190     // TODO: we should ask the dispatcher. However, this is laborious, since you cannot ask a dispatcher
191     // directly, but need to add a status listener.
192     FeatureState aState;
193     aState.bEnabled = sal_True;
194     return aState;
195 }
196 
197 //--------------------------------------------------------------------------
execute(const URL & _rFeatureURL,const Sequence<PropertyValue> & _rArgs)198 void UserDefinedFeatures::execute( const URL& _rFeatureURL, const Sequence< PropertyValue>& _rArgs )
199 {
200     try
201     {
202         Reference< XController > xController( (Reference< XController >)m_aController, UNO_SET_THROW );
203         Reference< XDispatchProvider > xDispatchProvider( xController->getFrame(), UNO_QUERY_THROW );
204         Reference< XDispatch > xDispatch( xDispatchProvider->queryDispatch(
205             _rFeatureURL,
206             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_self" ) ),
207             FrameSearchFlag::AUTO
208         ) );
209 
210         if ( xDispatch == xController )
211         {
212             OSL_ENSURE( false, "UserDefinedFeatures::execute: the controller shouldn't be the dispatcher here!" );
213             xDispatch.clear();
214         }
215 
216         if ( xDispatch.is() )
217             xDispatch->dispatch( _rFeatureURL, _rArgs );
218     }
219     catch( const Exception& )
220     {
221     	DBG_UNHANDLED_EXCEPTION();
222     }
223 }
224 
225 //==========================================================================
226 //= OGenericUnoController_Data
227 //==========================================================================
228 struct OGenericUnoController_Data
229 {
230     ::sfx2::UserInputInterception   m_aUserInputInterception;
231     UserDefinedFeatures             m_aUserDefinedFeatures;
232 
OGenericUnoController_Datadbaui::OGenericUnoController_Data233     OGenericUnoController_Data( OGenericUnoController& _rController, ::osl::Mutex& _rMutex )
234         :m_aUserInputInterception( _rController, _rMutex )
235         ,m_aUserDefinedFeatures( _rController.getXController() )
236     {
237     }
238 };
239 
240 //==========================================================================
241 //= OGenericUnoController
242 //==========================================================================
DBG_NAME(OGenericUnoController)243 DBG_NAME(OGenericUnoController)
244 // -------------------------------------------------------------------------
245 OGenericUnoController::OGenericUnoController(const Reference< XMultiServiceFactory >& _rM)
246 	:OGenericUnoController_Base( getMutex() )
247 	,m_pView(NULL)
248 #ifdef DBG_UTIL
249     ,m_bDescribingSupportedFeatures( false )
250 #endif
251 	,m_aAsyncInvalidateAll(LINK(this, OGenericUnoController, OnAsyncInvalidateAll))
252 	,m_aAsyncCloseTask(LINK(this, OGenericUnoController, OnAsyncCloseTask))
253 	,m_xServiceFactory(_rM)
254     ,m_aCurrentFrame( *this )
255 	,m_bPreview(sal_False)
256 	,m_bReadOnly(sal_False)
257 	,m_bCurrentlyModified(sal_False)
258     ,m_bExternalTitle(sal_False)
259 {
260     osl_incrementInterlockedCount( &m_refCount );
261     {
262         m_pData.reset( new OGenericUnoController_Data( *this, getMutex() ) );
263     }
264     osl_decrementInterlockedCount( &m_refCount );
265 
266     DBG_CTOR(OGenericUnoController,NULL);
267 
268 	try
269 	{
270 		m_xUrlTransformer = Reference< XURLTransformer > (_rM->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer")), UNO_QUERY);
271 	}
272 	catch(Exception&)
273 	{
274         DBG_UNHANDLED_EXCEPTION();
275 	}
276 }
277 
278 #ifdef WNT
279 // -----------------------------------------------------------------------------
OGenericUnoController()280 OGenericUnoController::OGenericUnoController()
281 	:OGenericUnoController_Base( getMutex() )
282 	,m_pView(NULL)
283 #ifdef DBG_UTIL
284     ,m_bDescribingSupportedFeatures( false )
285 #endif
286 	,m_aAsyncInvalidateAll(LINK(this, OGenericUnoController, OnAsyncInvalidateAll))
287 	,m_aAsyncCloseTask(LINK(this, OGenericUnoController, OnAsyncCloseTask))
288     ,m_aCurrentFrame( *this )
289 	,m_bPreview(sal_False)
290 	,m_bReadOnly(sal_False)
291 	,m_bCurrentlyModified(sal_False)
292 {
293     OSL_ENSURE( false, "OGenericUnoController::OGenericUnoController: illegal call!" );
294     // This ctor only exists because the MSVC compiler complained about an unresolved external
295     // symbol. It should not be used at all. Since using it yields strange runtime problems,
296     // we simply abort here.
297     abort();
298 }
299 #endif
300 
301 // -----------------------------------------------------------------------------
~OGenericUnoController()302 OGenericUnoController::~OGenericUnoController()
303 {
304 
305     DBG_DTOR(OGenericUnoController,NULL);
306 }
307 
308 // -----------------------------------------------------------------------------
Construct(Window *)309 sal_Bool OGenericUnoController::Construct(Window* /*pParent*/)
310 {
311 	OSL_ENSURE( getView(), "the view is NULL!" );
312 
313 	if ( getView() )
314 	{
315 		getView()->Construct();
316 		getView()->Show();
317 	}
318 
319     m_aSupportedFeatures.clear();
320 	fillSupportedFeatures();
321 
322 	// create the database context
323 	DBG_ASSERT(getORB().is(), "OGenericUnoController::Construct need a service factory!");
324 	try
325 	{
326 		m_xDatabaseContext = Reference< XNameAccess >(getORB()->createInstance(SERVICE_SDB_DATABASECONTEXT), UNO_QUERY);
327 	}
328 	catch(Exception&)
329 	{
330 		DBG_ERROR("OGenericUnoController::Construct: could not create (or start listening at) the database context!");
331 	}
332 
333 	if (!m_xDatabaseContext.is())
334 	{		// at least notify the user. Though the whole component does not make any sense without the database context ...
335 		ShowServiceNotAvailableError(getView(), String(SERVICE_SDB_DATABASECONTEXT), sal_True);
336 	}
337 	return sal_True;
338 }
339 //------------------------------------------------------------------------------
IMPL_LINK(OGenericUnoController,OnAsyncInvalidateAll,void *,EMPTYARG)340 IMPL_LINK(OGenericUnoController, OnAsyncInvalidateAll, void*, EMPTYARG)
341 {
342 	if ( !OGenericUnoController_Base::rBHelper.bInDispose && !OGenericUnoController_Base::rBHelper.bDisposed )
343 		InvalidateFeature_Impl();
344 	return 0L;
345 }
346 // -----------------------------------------------------------------------------
impl_initialize()347 void OGenericUnoController::impl_initialize()
348 {
349 }
350 // -------------------------------------------------------------------------
initialize(const Sequence<Any> & aArguments)351 void SAL_CALL OGenericUnoController::initialize( const Sequence< Any >& aArguments ) throw(Exception, RuntimeException)
352 {
353 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
354 	::osl::MutexGuard aGuard( getMutex() );
355 
356 	Reference< XWindow >		xParent;
357 	Reference< XFrame > xFrame;
358 
359 	PropertyValue aValue;
360 	const Any* pIter	= aArguments.getConstArray();
361 	const Any* pEnd 	= pIter + aArguments.getLength();
362 
363 	for ( ; pIter != pEnd; ++pIter )
364 	{
365 		if ( ( *pIter >>= aValue ) && ( 0 == aValue.Name.compareToAscii( "Frame" ) ) )
366 		{
367             xFrame.set(aValue.Value,UNO_QUERY_THROW);
368 		}
369         /* #i42316#
370 		else if ( ( *pIter >>= aValue ) && ( 0 == aValue.Name.compareToAscii( "ReadOnly" ) ) )
371 		{
372 			aValue.Value >>= m_bReadOnly;
373 		}
374         */
375 		else if ( ( *pIter >>= aValue ) && ( 0 == aValue.Name.compareToAscii( "Preview" ) ) )
376 		{
377 			aValue.Value >>= m_bPreview;
378             m_bReadOnly = sal_True;
379 		}
380 	}
381 	try
382 	{
383 		if ( !xFrame.is() )
384             throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "need a frame" ) ), *this, 1 );
385 
386         xParent = xFrame->getContainerWindow();
387 		VCLXWindow* pParentComponent = VCLXWindow::GetImplementation(xParent);
388 		Window* pParentWin = pParentComponent ? pParentComponent->GetWindow() : NULL;
389 		if (!pParentWin)
390 		{
391 			throw IllegalArgumentException( ::rtl::OUString::createFromAscii( "Parent window is null" ), *this, 1 );
392 		}
393 
394         m_aInitParameters.assign( aArguments );
395 		Construct( pParentWin );
396 
397         ODataView* pView = getView();
398         if ( !pView )
399             throw RuntimeException( ::rtl::OUString::createFromAscii( "unable to create a view" ), *this );
400 
401 		if ( m_bReadOnly || m_bPreview )
402 			pView->EnableInput( sal_False );
403 
404         impl_initialize();
405 	}
406 	catch(Exception& e)
407 	{
408 		// no one clears my view if I won't
409 		::std::auto_ptr<Window> aTemp(m_pView);
410 		m_pView = NULL;
411 		throw;
412 	}
413 }
414 
415 //------------------------------------------------------------------------------
acquire()416 void SAL_CALL OGenericUnoController::acquire(  ) throw ()
417 {
418 	OGenericUnoController_Base::acquire();
419 }
420 
421 //------------------------------------------------------------------------------
release()422 void SAL_CALL OGenericUnoController::release(  ) throw ()
423 {
424 	OGenericUnoController_Base::release();
425 }
426 
427 // -------------------------------------------------------------------------
startFrameListening(const Reference<XFrame> & _rxFrame)428 void OGenericUnoController::startFrameListening( const Reference< XFrame >& _rxFrame )
429 {
430     if ( _rxFrame.is() )
431 	    _rxFrame->addFrameActionListener( this );
432 }
433 
434 // -------------------------------------------------------------------------
stopFrameListening(const Reference<XFrame> & _rxFrame)435 void OGenericUnoController::stopFrameListening( const Reference< XFrame >& _rxFrame )
436 {
437 	if ( _rxFrame.is() )
438 		_rxFrame->removeFrameActionListener( this );
439 }
440 
441 // -------------------------------------------------------------------------
disposing(const EventObject & Source)442 void OGenericUnoController::disposing(const EventObject& Source) throw( RuntimeException )
443 {
444 	// our frame ?
445 	if ( Source.Source == getFrame() )
446 		stopFrameListening( getFrame() );
447 }
448 //------------------------------------------------------------------------
modified(const EventObject & aEvent)449 void OGenericUnoController::modified(const EventObject& aEvent) throw( RuntimeException )
450 {
451 	::osl::MutexGuard aGuard( getMutex() );
452 	if ( !isDataSourceReadOnly() )
453 	{
454 		Reference<XModifiable> xModi(aEvent.Source,UNO_QUERY);
455 		if ( xModi.is() )
456 			m_bCurrentlyModified = xModi->isModified(); // can only be reset by save
457 		else
458 			m_bCurrentlyModified = sal_True;
459 	}
460 	InvalidateFeature(ID_BROWSER_SAVEDOC);
461 	InvalidateFeature(ID_BROWSER_UNDO);
462 }
463 // -----------------------------------------------------------------------
getComponentWindow()464 Reference< XWindow > SAL_CALL OGenericUnoController::getComponentWindow() throw (RuntimeException)
465 {
466 	return VCLUnoHelper::GetInterface( getView() );
467 }
468 
469 // -----------------------------------------------------------------------
getViewControllerName()470 ::rtl::OUString SAL_CALL OGenericUnoController::getViewControllerName() throw (::com::sun::star::uno::RuntimeException)
471 {
472     return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Default" ) );
473 }
474 
475 // -----------------------------------------------------------------------
getCreationArguments()476 Sequence< PropertyValue > SAL_CALL OGenericUnoController::getCreationArguments() throw (RuntimeException)
477 {
478     // currently we do not support any creation args, so anything passed to XModel2::createViewController would be
479     // lost, so we can equally return an empty sequence here
480     return Sequence< PropertyValue >();
481 }
482 
483 // -----------------------------------------------------------------------
attachFrame(const Reference<XFrame> & _rxFrame)484 void OGenericUnoController::attachFrame( const Reference< XFrame >& _rxFrame ) throw( RuntimeException )
485 {
486     vos::OGuard aSolarGuard( Application::GetSolarMutex() );
487 	::osl::MutexGuard aGuard( getMutex() );
488 
489     stopFrameListening( m_aCurrentFrame.getFrame() );
490 	Reference< XFrame > xFrame = m_aCurrentFrame.attachFrame( _rxFrame );
491 	startFrameListening( xFrame );
492 
493 	loadMenu( xFrame );
494 
495 	if ( getView() )
496 		getView()->attachFrame( xFrame );
497 }
498 
499 // -----------------------------------------------------------------------------
500 struct CommandCollector : public ::std::unary_function< SupportedFeatures::value_type, void>
501 {
502 	sal_uInt16  m_nFeature;
503 	StringBag&  m_rFeatureCommands;
CommandCollectordbaui::CommandCollector504 	CommandCollector( sal_uInt16 _nFeature, StringBag& _rFeatureCommands )
505         :m_nFeature        ( _nFeature         )
506         ,m_rFeatureCommands( _rFeatureCommands )
507     {
508     }
509 
operator ()dbaui::CommandCollector510 	void operator() ( const SupportedFeatures::value_type& lhs )
511 	{
512 		if ( lhs.second.nFeatureId == m_nFeature )
513 			m_rFeatureCommands.insert( lhs.first );
514 	}
515 };
516 
517 // -----------------------------------------------------------------------
518 namespace
519 {
520     typedef ::std::vector< Any >    States;
521 
522     // ...................................................................
lcl_notifyMultipleStates(XStatusListener & _rListener,FeatureStateEvent & _rEvent,const States & _rStates)523     void    lcl_notifyMultipleStates( XStatusListener& _rListener, FeatureStateEvent& _rEvent, const States& _rStates )
524     {
525         for (   States::const_iterator state = _rStates.begin();
526                 state != _rStates.end();
527                 ++state
528             )
529         {
530             _rEvent.State = *state;
531             _rListener.statusChanged( _rEvent );
532         }
533     }
534 
535     // ...................................................................
lcl_collectStates(const FeatureState & _rFeatureState,States & _out_rStates)536     void    lcl_collectStates( const FeatureState& _rFeatureState, States& _out_rStates )
537     {
538         // order matters, due to a bug in framework which resets the check state when any non-boolean event
539         // arrives
540         // #i68215# is the bug to (re-)introduce this "ordered" notification here
541         // #i67882# is the bug which was caused by the real fix which we did in framework
542         // #i68216# is the bug which requests to fix the code in Draw which relies on
543         //          framework's implementation details
544         // 2006-08-07 / frank.schoenheit@sun.com
545         if ( !!_rFeatureState.sTitle )
546             _out_rStates.push_back( makeAny( *_rFeatureState.sTitle ) );
547         if ( !!_rFeatureState.bChecked )
548             _out_rStates.push_back( makeAny( (sal_Bool)*_rFeatureState.bChecked ) );
549         if ( !!_rFeatureState.bInvisible )
550             _out_rStates.push_back( makeAny( Visibility( !*_rFeatureState.bInvisible ) ) );
551         if ( _rFeatureState.aValue.hasValue() )
552             _out_rStates.push_back( _rFeatureState.aValue );
553         if ( _out_rStates.empty() )
554             _out_rStates.push_back( Any() );
555     }
556 }
557 
558 // -----------------------------------------------------------------------
ImplBroadcastFeatureState(const::rtl::OUString & _rFeature,const Reference<XStatusListener> & xListener,sal_Bool _bIgnoreCache)559 void OGenericUnoController::ImplBroadcastFeatureState(const ::rtl::OUString& _rFeature, const Reference< XStatusListener > & xListener, sal_Bool _bIgnoreCache)
560 {
561 	sal_uInt16 nFeat = m_aSupportedFeatures[ _rFeature ].nFeatureId;
562 	FeatureState aFeatState( GetState( nFeat ) );
563 
564 	FeatureState& rCachedState = m_aStateCache[nFeat];	// creates if neccessary
565 	if ( !_bIgnoreCache )
566 	{
567 		// check if we really need to notify the listeners : this method may be called much more often than needed, so check
568 		// the cached state of the feature
569 		sal_Bool bAlreadyCached = ( m_aStateCache.find(nFeat) != m_aStateCache.end() );
570 		if ( bAlreadyCached )
571             if  (   ( rCachedState.bEnabled == aFeatState.bEnabled )
572                 &&  ( rCachedState.bChecked == aFeatState.bChecked )
573                 &&  ( rCachedState.bInvisible == aFeatState.bInvisible )
574                 &&  ( rCachedState.sTitle == aFeatState.sTitle )
575                 )
576             return;
577 	}
578 	rCachedState = aFeatState;
579 
580 	FeatureStateEvent aEvent;
581 	aEvent.FeatureURL.Complete = _rFeature;
582 	if (m_xUrlTransformer.is())
583 		m_xUrlTransformer->parseStrict(aEvent.FeatureURL);
584 	aEvent.Source		= (XDispatch*)this;
585 	aEvent.IsEnabled	= aFeatState.bEnabled;
586 
587     // collect all states to be notified
588     States aStates;
589     lcl_collectStates( aFeatState, aStates );
590 
591 	// a special listener ?
592 	if ( xListener.is() )
593         lcl_notifyMultipleStates( *xListener.get(), aEvent, aStates );
594 	else
595 	{	// no -> iterate through all listeners responsible for the URL
596         StringBag aFeatureCommands;
597 		::std::for_each(
598             m_aSupportedFeatures.begin(),
599             m_aSupportedFeatures.end(),
600             CommandCollector( nFeat, aFeatureCommands )
601         );
602 
603 		// it is possible that listeners are registered or revoked while
604 		// we are notifying them, so we must use a copy of m_arrStatusListener, not
605 		// m_arrStatusListener itself
606 		// #121276# / 2005-05-19 / frank.schoenheit@sun.com
607 		Dispatch aNotifyLoop( m_arrStatusListener );
608 		DispatchIterator iterSearch = aNotifyLoop.begin();
609 		DispatchIterator iterEnd = aNotifyLoop.end();
610 
611 		while (iterSearch != iterEnd)
612 		{
613 			DispatchTarget& rCurrent = *iterSearch;
614 			if ( aFeatureCommands.find( rCurrent.aURL.Complete ) != aFeatureCommands.end() )
615 			{
616 				aEvent.FeatureURL = rCurrent.aURL;
617                 lcl_notifyMultipleStates( *rCurrent.xListener.get(), aEvent, aStates );
618 			}
619 			++iterSearch;
620 		}
621 	}
622 
623 }
624 
625 //------------------------------------------------------------------------------
isFeatureSupported(sal_Int32 _nId)626 sal_Bool OGenericUnoController::isFeatureSupported( sal_Int32 _nId )
627 {
628 	SupportedFeatures::iterator aFeaturePos = ::std::find_if(
629 		m_aSupportedFeatures.begin(),
630 		m_aSupportedFeatures.end(),
631 		::std::bind2nd( CompareFeatureById(), _nId )
632 	);
633 
634     return ( m_aSupportedFeatures.end() != aFeaturePos && aFeaturePos->first.getLength());
635 }
636 
637 // -----------------------------------------------------------------------
InvalidateFeature(const::rtl::OUString & _rURLPath,const Reference<XStatusListener> & _xListener,sal_Bool _bForceBroadcast)638 void OGenericUnoController::InvalidateFeature(const ::rtl::OUString& _rURLPath, const Reference< XStatusListener > & _xListener, sal_Bool _bForceBroadcast)
639 {
640 	ImplInvalidateFeature( m_aSupportedFeatures[ _rURLPath ].nFeatureId, _xListener, _bForceBroadcast );
641 }
642 
643 // -----------------------------------------------------------------------------
InvalidateFeature_Impl()644 void OGenericUnoController::InvalidateFeature_Impl()
645 {
646 #ifdef DBG_UTIL
647 	static sal_Int32 s_nRecursions = 0;
648 	++s_nRecursions;
649 #endif
650 
651 	sal_Bool bEmpty = sal_True;
652 	FeatureListener aNextFeature;
653 	{
654 		::osl::MutexGuard aGuard( m_aFeatureMutex);
655 		bEmpty = m_aFeaturesToInvalidate.empty();
656 		if (!bEmpty)
657 			aNextFeature = m_aFeaturesToInvalidate.front();
658 	}
659 	while(!bEmpty)
660 	{
661 		if ( ALL_FEATURES == aNextFeature.nId )
662 		{
663 			InvalidateAll_Impl();
664 			break;
665 		}
666 		else
667 		{
668 			SupportedFeatures::iterator aFeaturePos = ::std::find_if(
669 				m_aSupportedFeatures.begin(),
670 				m_aSupportedFeatures.end(),
671 				::std::bind2nd( CompareFeatureById(), aNextFeature.nId )
672 			);
673 
674 #if OSL_DEBUG_LEVEL > 0
675             if ( m_aSupportedFeatures.end() == aFeaturePos )
676             {
677                 ::rtl::OString sMessage( "OGenericUnoController::InvalidateFeature_Impl: feature id " );
678                 sMessage += ::rtl::OString::valueOf( aNextFeature.nId );
679                 sMessage += ::rtl::OString( " has been invalidated, but is not supported!" );
680                 OSL_ENSURE( false, sMessage.getStr() );
681             }
682 #endif
683 			if ( m_aSupportedFeatures.end() != aFeaturePos )
684 				// we really know this feature
685 				ImplBroadcastFeatureState( aFeaturePos->first, aNextFeature.xListener, aNextFeature.bForceBroadcast );
686 		}
687 
688 		::osl::MutexGuard aGuard( m_aFeatureMutex);
689 		m_aFeaturesToInvalidate.pop_front();
690 		bEmpty = m_aFeaturesToInvalidate.empty();
691 		if (!bEmpty)
692 			aNextFeature = m_aFeaturesToInvalidate.front();
693 	}
694 
695 #ifdef DBG_UTIL
696 	--s_nRecursions;
697 #endif
698 }
699 
700 // -----------------------------------------------------------------------
ImplInvalidateFeature(sal_Int32 _nId,const Reference<XStatusListener> & _xListener,sal_Bool _bForceBroadcast)701 void OGenericUnoController::ImplInvalidateFeature( sal_Int32 _nId, const Reference< XStatusListener >& _xListener, sal_Bool _bForceBroadcast )
702 {
703 #if OSL_DEBUG_LEVEL > 0
704     if ( _nId != -1 )
705     {
706 	    SupportedFeatures::iterator aFeaturePos = ::std::find_if(
707 		    m_aSupportedFeatures.begin(),
708 		    m_aSupportedFeatures.end(),
709 		    ::std::bind2nd( CompareFeatureById(), _nId )
710 	    );
711         OSL_ENSURE( aFeaturePos != m_aSupportedFeatures.end(), "OGenericUnoController::ImplInvalidateFeature: invalidating an unsupported feature is suspicious, at least!" );
712     }
713 #endif
714 
715 	FeatureListener aListener;
716 	aListener.nId               = _nId;
717 	aListener.xListener         = _xListener;
718 	aListener.bForceBroadcast   = _bForceBroadcast;
719 
720 	sal_Bool bWasEmpty;
721 	{
722 		::osl::MutexGuard aGuard( m_aFeatureMutex );
723 		bWasEmpty = m_aFeaturesToInvalidate.empty();
724 		m_aFeaturesToInvalidate.push_back( aListener );
725 	}
726 
727 	if ( bWasEmpty )
728 		m_aAsyncInvalidateAll.Call();
729 }
730 
731 // -----------------------------------------------------------------------
InvalidateFeature(sal_uInt16 _nId,const Reference<XStatusListener> & _xListener,sal_Bool _bForceBroadcast)732 void OGenericUnoController::InvalidateFeature(sal_uInt16 _nId, const Reference< XStatusListener > & _xListener, sal_Bool _bForceBroadcast)
733 {
734 	ImplInvalidateFeature( _nId, _xListener, _bForceBroadcast );
735 }
736 
737 // -----------------------------------------------------------------------
InvalidateAll()738 void OGenericUnoController::InvalidateAll()
739 {
740 	ImplInvalidateFeature( ALL_FEATURES, NULL, sal_True );
741 }
742 
743 // -----------------------------------------------------------------------------
InvalidateAll_Impl()744 void OGenericUnoController::InvalidateAll_Impl()
745 {
746 	// ---------------------------------
747 	// invalidate all aupported features
748 
749 	for (   SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.begin();
750             aIter != m_aSupportedFeatures.end();
751             ++aIter
752         )
753 		ImplBroadcastFeatureState( aIter->first, NULL, sal_True );
754 
755 	{
756 		::osl::MutexGuard aGuard( m_aFeatureMutex);
757 		DBG_ASSERT(m_aFeaturesToInvalidate.size(), "OGenericUnoController::InvalidateAll_Impl: to be called from within InvalidateFeature_Impl only!");
758 		m_aFeaturesToInvalidate.pop_front();
759 		if(!m_aFeaturesToInvalidate.empty())
760 			m_aAsyncInvalidateAll.Call();
761 	}
762 }
763 
764 // -----------------------------------------------------------------------
queryDispatch(const URL & aURL,const::rtl::OUString & aTargetFrameName,sal_Int32 nSearchFlags)765 Reference< XDispatch >	OGenericUnoController::queryDispatch(const URL& aURL, const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags) throw( RuntimeException )
766 {
767 	Reference< XDispatch > xReturn;
768 
769     OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::queryDispatch: shouldn't this be filled at construction time?" );
770     if ( m_aSupportedFeatures.empty() )
771         fillSupportedFeatures();
772 
773 	// URL's we can handle ourself?
774 	if  (   aURL.Complete.equals( getConfirmDeletionURL() )
775         ||  (   ( m_aSupportedFeatures.find( aURL.Complete ) != m_aSupportedFeatures.end() )
776             &&  !isUserDefinedFeature( aURL.Complete )
777             )
778         )
779 	{
780 		xReturn = this;
781 	}
782 	// no? -> ask the slave dispatcher
783 	else if ( m_xSlaveDispatcher.is() )
784 	{
785 		xReturn = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags);
786 	}
787 
788 	// outta here
789 	return xReturn;
790 }
791 
792 // -----------------------------------------------------------------------
queryDispatches(const Sequence<DispatchDescriptor> & aDescripts)793 Sequence< Reference< XDispatch > > OGenericUnoController::queryDispatches(const Sequence< DispatchDescriptor >& aDescripts) throw( RuntimeException )
794 {
795 	Sequence< Reference< XDispatch > > aReturn;
796 	sal_Int32 nLen = aDescripts.getLength();
797 	if ( nLen )
798 	{
799 		aReturn.realloc( nLen );
800 				Reference< XDispatch >* pReturn 	= aReturn.getArray();
801 		const	Reference< XDispatch >* pReturnEnd	= aReturn.getArray() + nLen;
802 		const	DispatchDescriptor* 	pDescripts	= aDescripts.getConstArray();
803 
804 		for ( ; pReturn != pReturnEnd; ++ pReturn, ++pDescripts )
805 		{
806 			*pReturn = queryDispatch( pDescripts->FeatureURL, pDescripts->FrameName, pDescripts->SearchFlags );
807 		}
808 	}
809 
810 	return aReturn;
811 }
812 
813 // -----------------------------------------------------------------------
getSlaveDispatchProvider(void)814 Reference< XDispatchProvider >	OGenericUnoController::getSlaveDispatchProvider(void) throw( RuntimeException )
815 {
816 	return m_xSlaveDispatcher;
817 }
818 
819 // -----------------------------------------------------------------------
setSlaveDispatchProvider(const Reference<XDispatchProvider> & _xNewProvider)820 void OGenericUnoController::setSlaveDispatchProvider(const Reference< XDispatchProvider > & _xNewProvider) throw( RuntimeException )
821 {
822 	m_xSlaveDispatcher = _xNewProvider;
823 }
824 
825 // -----------------------------------------------------------------------
getMasterDispatchProvider(void)826 Reference< XDispatchProvider >	OGenericUnoController::getMasterDispatchProvider(void) throw( RuntimeException )
827 {
828 	return m_xMasterDispatcher;
829 }
830 
831 // -----------------------------------------------------------------------
setMasterDispatchProvider(const Reference<XDispatchProvider> & _xNewProvider)832 void OGenericUnoController::setMasterDispatchProvider(const Reference< XDispatchProvider > & _xNewProvider) throw( RuntimeException )
833 {
834 	m_xMasterDispatcher = _xNewProvider;
835 }
836 
837 // -----------------------------------------------------------------------
dispatch(const URL & _aURL,const Sequence<PropertyValue> & aArgs)838 void OGenericUnoController::dispatch(const URL& _aURL, const Sequence< PropertyValue >& aArgs) throw(RuntimeException)
839 {
840     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
841     // Since the fix for #123967#, the SolarMutex is not locked anymore when the framework calls into
842     // here. So, lock it ourself. The real solution would be to lock it only in the places
843     // where it's needed, but a) this might turn out difficult, since we then also need to care
844     // for locking in the proper order (SolarMutex and m_aMutex), and b) this would be too many places
845     // for the time frame of the fix.
846     // #i52602# / frank.schoenheit@sun.com / 2005-07-29
847 
848 #ifdef TIMELOG
849     ::rtl::OString sLog( "OGenericUnoController::dispatch( '" );
850     sLog += ::rtl::OString( _aURL.Main.getStr(), _aURL.Main.getLength(), osl_getThreadTextEncoding() );
851     sLog += ::rtl::OString( "' )" );
852     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "frank.schoenheit@sun.com", sLog.getStr() );
853 #endif
854 
855     executeChecked(_aURL,aArgs);
856 }
857 
858 // -----------------------------------------------------------------------
addStatusListener(const Reference<XStatusListener> & aListener,const URL & _rURL)859 void OGenericUnoController::addStatusListener(const Reference< XStatusListener > & aListener, const URL& _rURL) throw(RuntimeException)
860 {
861     // parse the ULR now and here, this saves later parsing in each notification round
862     URL aParsedURL( _rURL );
863 	if ( m_xUrlTransformer.is() )
864 		m_xUrlTransformer->parseStrict( aParsedURL );
865 
866     // remeber the listener together with the URL
867 	m_arrStatusListener.insert( m_arrStatusListener.end(), DispatchTarget( aParsedURL, aListener ) );
868 
869     // initially broadcast the state
870 	ImplBroadcastFeatureState( aParsedURL.Complete, aListener, sal_True );
871 		// force the new state to be broadcasted to the new listener
872 }
873 
874 // -----------------------------------------------------------------------
removeStatusListener(const Reference<XStatusListener> & aListener,const URL & _rURL)875 void OGenericUnoController::removeStatusListener(const Reference< XStatusListener > & aListener, const URL& _rURL) throw(RuntimeException)
876 {
877 	DispatchIterator iterSearch = m_arrStatusListener.begin();
878 
879 	sal_Bool bRemoveForAll = (_rURL.Complete.getLength() == 0);
880 	while ( iterSearch != m_arrStatusListener.end() )
881 	{
882 		DispatchTarget& rCurrent = *iterSearch;
883 		if	(	(rCurrent.xListener == aListener)
884 			&&	(	bRemoveForAll
885 				||	(rCurrent.aURL.Complete.equals(_rURL.Complete))
886 				)
887 			)
888 		{
889 			m_arrStatusListener.erase( iterSearch );
890 			if (!bRemoveForAll)
891 				// remove the listener only for the given URL, so we can exit the loop after deletion
892 				break;
893 		}
894 		else
895 			++iterSearch;
896 	}
897 
898     OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::removeStatusListener: shouldn't this be filled at construction time?" );
899     if ( m_aSupportedFeatures.empty() )
900         fillSupportedFeatures();
901 
902 	SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find(_rURL.Complete);
903 	if (aIter != m_aSupportedFeatures.end())
904 	{	// clear the cache for that feature
905 		StateCacheIterator aCachePos = m_aStateCache.find( aIter->second.nFeatureId );
906 		if ( aCachePos != m_aStateCache.end() )
907 			m_aStateCache.erase( aCachePos );
908 	}
909 
910 	// now remove the listener from the deque
911 	::osl::MutexGuard aGuard( m_aFeatureMutex );
912 	m_aFeaturesToInvalidate.erase(
913 		::std::remove_if(	m_aFeaturesToInvalidate.begin(),
914 							m_aFeaturesToInvalidate.end(),
915 							::std::bind2nd(FindFeatureListener(),aListener))
916 		,m_aFeaturesToInvalidate.end());
917 }
918 // -----------------------------------------------------------------------------
releaseNumberForComponent()919 void OGenericUnoController::releaseNumberForComponent()
920 {
921     try
922     {
923         Reference< XUntitledNumbers > xUntitledProvider(getPrivateModel(), UNO_QUERY      );
924         if ( xUntitledProvider.is() )
925             xUntitledProvider->releaseNumberForComponent(static_cast<XWeak*>(this));
926     }
927     catch( const Exception& )
928 	{
929         // NII
930 	}
931 }
932 // -----------------------------------------------------------------------
disposing()933 void OGenericUnoController::disposing()
934 {
935 	{
936 		EventObject aDisposeEvent;
937 		aDisposeEvent.Source = static_cast<XWeak*>(this);
938 		Dispatch aStatusListener = m_arrStatusListener;
939 		Dispatch::iterator aEnd = aStatusListener.end();
940 		for (Dispatch::iterator aIter = aStatusListener.begin(); aIter != aEnd; ++aIter)
941 		{
942 			aIter->xListener->disposing(aDisposeEvent);
943 		}
944 		m_arrStatusListener.clear();
945 	}
946 
947 	m_xDatabaseContext = NULL;
948 	{
949 		::osl::MutexGuard aGuard( m_aFeatureMutex);
950 		m_aAsyncInvalidateAll.CancelCall();
951 		m_aFeaturesToInvalidate.clear();
952 	}
953 
954     releaseNumberForComponent();
955 
956 	// check out from all the objects we are listening
957 	// the frame
958 	stopFrameListening( m_aCurrentFrame.getFrame() );
959     m_aCurrentFrame.attachFrame( NULL );
960 
961     m_xMasterDispatcher = NULL;
962     m_xSlaveDispatcher = NULL;
963     m_xServiceFactory = NULL;
964 	m_xTitleHelper.clear();
965     m_xUrlTransformer.clear();
966     m_aInitParameters.clear();
967 }
968 
969 // -----------------------------------------------------------------------------
addEventListener(const Reference<XEventListener> & xListener)970 void SAL_CALL OGenericUnoController::addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException)
971 {
972     // disambiguate
973     OGenericUnoController_Base::WeakComponentImplHelperBase::addEventListener( xListener );
974 }
975 
976 // -----------------------------------------------------------------------------
removeEventListener(const Reference<XEventListener> & xListener)977 void SAL_CALL OGenericUnoController::removeEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException)
978 {
979     // disambiguate
980     OGenericUnoController_Base::WeakComponentImplHelperBase::removeEventListener( xListener );
981 }
982 
983 //------------------------------------------------------------------------------
frameAction(const FrameActionEvent & aEvent)984 void OGenericUnoController::frameAction(const FrameActionEvent& aEvent) throw( RuntimeException )
985 {
986     ::osl::MutexGuard aGuard( getMutex() );
987     if ( aEvent.Frame == m_aCurrentFrame.getFrame() )
988         m_aCurrentFrame.frameAction( aEvent.Action );
989 }
990 
991 //------------------------------------------------------------------------------
implDescribeSupportedFeature(const sal_Char * _pAsciiCommandURL,sal_uInt16 _nFeatureId,sal_Int16 _nCommandGroup)992 void OGenericUnoController::implDescribeSupportedFeature( const sal_Char* _pAsciiCommandURL,
993         sal_uInt16 _nFeatureId, sal_Int16 _nCommandGroup )
994 {
995 #ifdef DBG_UTIL
996     DBG_ASSERT( m_bDescribingSupportedFeatures, "OGenericUnoController::implDescribeSupportedFeature: bad timing for this call!" );
997 #endif
998     OSL_PRECOND( _nFeatureId < FIRST_USER_DEFINED_FEATURE, "OGenericUnoController::implDescribeSupportedFeature: invalid feature id!" );
999 
1000     ControllerFeature aFeature;
1001     aFeature.Command = ::rtl::OUString::createFromAscii( _pAsciiCommandURL );
1002     aFeature.nFeatureId = _nFeatureId;
1003     aFeature.GroupId = _nCommandGroup;
1004 
1005 #if OSL_DEBUG_LEVEL > 0
1006     OSL_ENSURE( m_aSupportedFeatures.find( aFeature.Command ) == m_aSupportedFeatures.end(),
1007         "OGenericUnoController::implDescribeSupportedFeature: this feature is already there!" );
1008 #endif
1009     m_aSupportedFeatures[ aFeature.Command ] = aFeature;
1010 }
1011 
1012 //------------------------------------------------------------------------------
describeSupportedFeatures()1013 void OGenericUnoController::describeSupportedFeatures()
1014 {
1015     // add all supported features
1016     implDescribeSupportedFeature( ".uno:Copy", ID_BROWSER_COPY, CommandGroup::EDIT );
1017 	implDescribeSupportedFeature( ".uno:Cut", ID_BROWSER_CUT, CommandGroup::EDIT );
1018 	implDescribeSupportedFeature( ".uno:Paste", ID_BROWSER_PASTE, CommandGroup::EDIT );
1019 	implDescribeSupportedFeature( ".uno:ClipboardFormatItems", ID_BROWSER_CLIPBOARD_FORMAT_ITEMS );
1020 	implDescribeSupportedFeature( ".uno:DSBEditDoc", ID_BROWSER_EDITDOC, CommandGroup::DOCUMENT );
1021 }
1022 
1023 //------------------------------------------------------------------------------
GetState(sal_uInt16 _nId) const1024 FeatureState OGenericUnoController::GetState( sal_uInt16 _nId ) const
1025 {
1026 	FeatureState aReturn;
1027 		// (disabled automatically)
1028 
1029 	switch ( _nId )
1030 	{
1031 		case ID_BROWSER_UNDO:
1032 		case ID_BROWSER_SAVEDOC:
1033 			aReturn.bEnabled = sal_True;
1034 			break;
1035         default:
1036             aReturn = m_pData->m_aUserDefinedFeatures.getState( getURLForId( _nId ) );
1037             break;
1038 	}
1039 
1040 	return aReturn;
1041 }
1042 
1043 //------------------------------------------------------------------------------
Execute(sal_uInt16 _nId,const Sequence<PropertyValue> & _rArgs)1044 void OGenericUnoController::Execute( sal_uInt16 _nId, const Sequence< PropertyValue>& _rArgs )
1045 {
1046     OSL_ENSURE( isUserDefinedFeature( _nId ),
1047         "OGenericUnoController::Execute: responsible for user defined features only!" );
1048 
1049     // user defined features can be handled by dispatch interceptors resp. protocol handlers only.
1050     // So, we need to do a queryDispatch, and dispatch the URL
1051     m_pData->m_aUserDefinedFeatures.execute( getURLForId( _nId ), _rArgs );
1052 }
1053 
1054 //------------------------------------------------------------------------------
getURLForId(sal_Int32 _nId) const1055 URL OGenericUnoController::getURLForId(sal_Int32 _nId) const
1056 {
1057 	URL aReturn;
1058 	if ( m_xUrlTransformer.is() )
1059 	{
1060 		SupportedFeatures::const_iterator aIter = ::std::find_if(
1061 			m_aSupportedFeatures.begin(),
1062 			m_aSupportedFeatures.end(),
1063 			::std::bind2nd( CompareFeatureById(), _nId )
1064 		);
1065 
1066 		if ( m_aSupportedFeatures.end() != aIter && aIter->first.getLength() )
1067 		{
1068 			aReturn.Complete = aIter->first;
1069 			m_xUrlTransformer->parseStrict( aReturn );
1070 		}
1071 	}
1072 	return aReturn;
1073 }
1074 
1075 //-------------------------------------------------------------------------
isUserDefinedFeature(const sal_uInt16 _nFeatureId) const1076 bool OGenericUnoController::isUserDefinedFeature( const sal_uInt16 _nFeatureId ) const
1077 {
1078     return ( _nFeatureId >= FIRST_USER_DEFINED_FEATURE ) && ( _nFeatureId < LAST_USER_DEFINED_FEATURE );
1079 }
1080 
1081 //-------------------------------------------------------------------------
isUserDefinedFeature(const::rtl::OUString & _rFeatureURL) const1082 bool OGenericUnoController::isUserDefinedFeature( const ::rtl::OUString& _rFeatureURL ) const
1083 {
1084     SupportedFeatures::const_iterator pos = m_aSupportedFeatures.find( _rFeatureURL );
1085     OSL_PRECOND( pos != m_aSupportedFeatures.end(),
1086         "OGenericUnoController::isUserDefinedFeature: this is no supported feature at all!" );
1087 
1088     return ( pos != m_aSupportedFeatures.end() ) ? isUserDefinedFeature( pos->second.nFeatureId ) : false;
1089 }
1090 
1091 //-------------------------------------------------------------------------
supportsService(const::rtl::OUString & ServiceName)1092 sal_Bool SAL_CALL OGenericUnoController::supportsService(const ::rtl::OUString& ServiceName) throw(RuntimeException)
1093 {
1094 	Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
1095 
1096 	const ::rtl::OUString* pArray = aSupported.getConstArray();
1097 	const ::rtl::OUString* pArrayEnd = aSupported.getConstArray() + aSupported.getLength();
1098 
1099 	for ( ;( pArray != pArrayEnd ) && !pArray->equals( ServiceName ); ++pArray )
1100 		;
1101 	return pArray != pArrayEnd;
1102 }
1103 
1104 // -----------------------------------------------------------------------------
startConnectionListening(const Reference<XConnection> & _rxConnection)1105 void OGenericUnoController::startConnectionListening(const Reference< XConnection >& _rxConnection)
1106 {
1107 	// we have to remove ourself before dispoing the connection
1108 	Reference< XComponent >  xComponent(_rxConnection, UNO_QUERY);
1109 	if (xComponent.is())
1110 		xComponent->addEventListener(static_cast<XFrameActionListener*>(this));
1111 }
1112 
1113 // -----------------------------------------------------------------------------
stopConnectionListening(const Reference<XConnection> & _rxConnection)1114 void OGenericUnoController::stopConnectionListening(const Reference< XConnection >& _rxConnection)
1115 {
1116 	// we have to remove ourself before dispoing the connection
1117 	Reference< XComponent >  xComponent(_rxConnection, UNO_QUERY);
1118 	if (xComponent.is())
1119 		xComponent->removeEventListener(static_cast<XFrameActionListener*>(this));
1120 }
1121 // -----------------------------------------------------------------------------
connect(const Reference<XDataSource> & _xDataSource,::dbtools::SQLExceptionInfo * _pErrorInfo)1122 Reference< XConnection > OGenericUnoController::connect( const Reference< XDataSource>& _xDataSource,
1123     ::dbtools::SQLExceptionInfo* _pErrorInfo )
1124 {
1125 	WaitObject aWaitCursor( getView() );
1126 
1127 	ODatasourceConnector aConnector( getORB(), getView(), ::rtl::OUString() );
1128 	Reference< XConnection > xConnection = aConnector.connect( _xDataSource, _pErrorInfo );
1129 	startConnectionListening( xConnection );
1130 
1131 	return xConnection;
1132 }
1133 // -----------------------------------------------------------------------------
connect(const::rtl::OUString & _rDataSourceName,const::rtl::OUString & _rContextInformation,::dbtools::SQLExceptionInfo * _pErrorInfo)1134 Reference< XConnection > OGenericUnoController::connect( const ::rtl::OUString& _rDataSourceName,
1135     const ::rtl::OUString& _rContextInformation, ::dbtools::SQLExceptionInfo* _pErrorInfo )
1136 {
1137 	WaitObject aWaitCursor( getView() );
1138 
1139 	ODatasourceConnector aConnector( getORB(), getView(), _rContextInformation );
1140 	Reference<XConnection> xConnection = aConnector.connect( _rDataSourceName, _pErrorInfo );
1141 	startConnectionListening( xConnection );
1142 
1143 	return xConnection;
1144 }
1145 
1146 // -----------------------------------------------------------------------------
showError(const SQLExceptionInfo & _rInfo)1147 void OGenericUnoController::showError(const SQLExceptionInfo& _rInfo)
1148 {
1149 	::dbaui::showError(_rInfo,getView(),getORB());
1150 }
1151 // -----------------------------------------------------------------------------
getLayoutManager(const Reference<XFrame> & _xFrame) const1152 Reference< XLayoutManager > OGenericUnoController::getLayoutManager(const Reference< XFrame >& _xFrame) const
1153 {
1154 	Reference< XPropertySet > xPropSet( _xFrame, UNO_QUERY );
1155     Reference< XLayoutManager > xLayoutManager;
1156 	if ( xPropSet.is() )
1157     {
1158         try
1159         {
1160 			xLayoutManager.set(xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))),UNO_QUERY);
1161         }
1162         catch ( Exception& )
1163         {
1164         }
1165     }
1166 	return xLayoutManager;
1167 }
1168 // -----------------------------------------------------------------------------
loadMenu(const Reference<XFrame> & _xFrame)1169 void OGenericUnoController::loadMenu(const Reference< XFrame >& _xFrame)
1170 {
1171     Reference< XLayoutManager > xLayoutManager = getLayoutManager(_xFrame);
1172     if ( xLayoutManager.is() )
1173 	{
1174 		xLayoutManager->lock();
1175         xLayoutManager->createElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" )));
1176 		xLayoutManager->createElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/toolbar" )));
1177 		xLayoutManager->unlock();
1178 		xLayoutManager->doLayout();
1179 	}
1180 
1181     onLoadedMenu( xLayoutManager );
1182 }
1183 
1184 // -----------------------------------------------------------------------------
onLoadedMenu(const Reference<XLayoutManager> &)1185 void OGenericUnoController::onLoadedMenu(const Reference< XLayoutManager >& /*_xLayoutManager*/)
1186 {
1187     // not interested in
1188 }
1189 
1190 // -----------------------------------------------------------------------------
closeTask()1191 void OGenericUnoController::closeTask()
1192 {
1193 	m_aAsyncCloseTask.Call();
1194 }
1195 // -----------------------------------------------------------------------------
IMPL_LINK(OGenericUnoController,OnAsyncCloseTask,void *,EMPTYARG)1196 IMPL_LINK(OGenericUnoController, OnAsyncCloseTask, void*, EMPTYARG)
1197 {
1198 	if ( !OGenericUnoController_Base::rBHelper.bInDispose )
1199 	{
1200         try
1201         {
1202             Reference< util::XCloseable > xCloseable( m_aCurrentFrame.getFrame(), UNO_QUERY_THROW );
1203             xCloseable->close( sal_False ); // false - holds the owner ship for this frame inside this object!
1204         }
1205         catch( const Exception& )
1206         {
1207             DBG_UNHANDLED_EXCEPTION();
1208         }
1209 	}
1210 	return 0L;
1211 }
1212 // -----------------------------------------------------------------------------
getViewData(void)1213 Any SAL_CALL OGenericUnoController::getViewData(void) throw( RuntimeException )
1214 {
1215 	return Any();
1216 }
1217 // -----------------------------------------------------------------------------
restoreViewData(const Any &)1218 void SAL_CALL OGenericUnoController::restoreViewData(const Any& /*Data*/) throw( RuntimeException )
1219 {
1220 }
1221 
1222 // -----------------------------------------------------------------------------
getModel(void)1223 Reference< XModel > SAL_CALL OGenericUnoController::getModel(void) throw( RuntimeException )
1224 {
1225     return Reference< XModel >();
1226 }
1227 
1228 // -----------------------------------------------------------------------------
getFrame(void)1229 Reference< XFrame > SAL_CALL OGenericUnoController::getFrame(void) throw( RuntimeException )
1230 {
1231     ::osl::MutexGuard aGuard( getMutex() );
1232     return m_aCurrentFrame.getFrame();
1233 }
1234 
1235 // -----------------------------------------------------------------------------
attachModel(const Reference<XModel> &)1236 sal_Bool SAL_CALL OGenericUnoController::attachModel(const Reference< XModel > & /*xModel*/) throw( RuntimeException )
1237 {
1238     OSL_ENSURE( false, "OGenericUnoController::attachModel: not supported!" );
1239     return sal_False;
1240 }
1241 
1242 // -----------------------------------------------------------------------------
executeUnChecked(sal_uInt16 _nCommandId,const Sequence<PropertyValue> & aArgs)1243 void OGenericUnoController::executeUnChecked(sal_uInt16 _nCommandId, const Sequence< PropertyValue >& aArgs)
1244 {
1245 	Execute(_nCommandId, aArgs);
1246 }
1247 // -----------------------------------------------------------------------------
executeUnChecked(const util::URL & _rCommand,const Sequence<PropertyValue> & aArgs)1248 void OGenericUnoController::executeUnChecked(const util::URL& _rCommand, const Sequence< PropertyValue >& aArgs)
1249 {
1250     OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::executeUnChecked: shouldn't this be filled at construction time?" );
1251     if ( m_aSupportedFeatures.empty() )
1252         fillSupportedFeatures();
1253 
1254     SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCommand.Complete );
1255 	if (aIter != m_aSupportedFeatures.end())
1256 		Execute( aIter->second.nFeatureId, aArgs );
1257 }
1258 // -----------------------------------------------------------------------------
executeChecked(const util::URL & _rCommand,const Sequence<PropertyValue> & aArgs)1259 void OGenericUnoController::executeChecked(const util::URL& _rCommand, const Sequence< PropertyValue >& aArgs)
1260 {
1261     OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::executeChecked: shouldn't this be filled at construction time?" );
1262     if ( m_aSupportedFeatures.empty() )
1263         fillSupportedFeatures();
1264 
1265     SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCommand.Complete );
1266 	if ( aIter != m_aSupportedFeatures.end() )
1267 	{
1268 		sal_uInt16 nFeatureId = aIter->second.nFeatureId;
1269 		if ( GetState( nFeatureId ).bEnabled )
1270 			Execute( nFeatureId, aArgs );
1271 	}
1272 }
1273 // -----------------------------------------------------------------------------
1274 //------------------------------------------------------------------------------
1275 namespace
1276 {
lcl_getModuleHelpModuleName(const Reference<XFrame> & _rxFrame)1277 	::rtl::OUString lcl_getModuleHelpModuleName( const Reference< XFrame >& _rxFrame )
1278 	{
1279 		const sal_Char* pReturn = NULL;
1280 
1281 		try
1282 		{
1283 			// get the model of the document in the given frame
1284 			Reference< XController > xController;
1285 			if ( _rxFrame.is() )
1286 				xController = _rxFrame->getController();
1287 			Reference< XModel > xModel;
1288 			if ( xController.is() )
1289 				xModel = xController->getModel();
1290 			Reference< XServiceInfo > xSI( xModel, UNO_QUERY );
1291 
1292 			if ( !xSI.is() )
1293 			{	// try to go up the frame hierarchy
1294 
1295 				Reference< XFrame > xParentFrame;
1296 				if ( _rxFrame.is() )
1297 					xParentFrame = xParentFrame.query( _rxFrame->getCreator() );
1298 				// did we find a parent frame? Which is no top-level frame?
1299 				if ( xParentFrame.is() && !_rxFrame->isTop() )
1300 					// TODO: to prevent framework assertions, re-insert this "isTop" once 98303 is fixed
1301 					return lcl_getModuleHelpModuleName( xParentFrame );
1302 			}
1303 			else
1304 			{
1305 #if OSL_DEBUG_LEVEL > 0
1306 				Sequence< ::rtl::OUString > sServiceNames = xSI->getSupportedServiceNames();
1307 				const ::rtl::OUString* pLoop = sServiceNames.getConstArray();
1308 				for ( sal_Int32 i=0; i<sServiceNames.getLength(); ++i, ++pLoop )
1309 				{
1310 					sal_Int32 nDummy = 0;
1311                     (void)nDummy;
1312 				}
1313 #endif
1314 
1315 				// check which service we know ....
1316 				static const sal_Char* pTransTable[] = {
1317 					"com.sun.star.sdb.OfficeDatabaseDocument","sdatabase",
1318                     "com.sun.star.report.ReportDefinition","sdatabase",
1319 					"com.sun.star.text.TextDocument",	"swriter",
1320 					"com.sun.star.sheet.SpreadsheetDocument", "scalc",
1321 					"com.sun.star.presentation.PresentationDocument", "simpress",
1322 					"com.sun.star.drawing.DrawingDocument", "sdraw",
1323 					"com.sun.star.formula.FormularProperties", "smath",
1324 					"com.sun.star.chart.ChartDocument", "schart"
1325 				};
1326 				OSL_ENSURE( ( sizeof( pTransTable ) / sizeof( pTransTable[0] ) ) % 2 == 0,
1327 					"lcl_getModuleHelpModuleName: odd size of translation table!" );
1328 
1329 				// loop through the table
1330 				sal_Int32 nTableEntries = ( sizeof( pTransTable ) / sizeof( pTransTable[0] ) ) / 2;
1331 				const sal_Char** pDocumentService = pTransTable;
1332 				const sal_Char** pHelpModuleName = pTransTable + 1;
1333 				for ( sal_Int32 j=0; j<nTableEntries; ++j )
1334 				{
1335 					if ( xSI->supportsService( ::rtl::OUString::createFromAscii( *pDocumentService ) ) )
1336 					{	// found a table entry which matches the model's services
1337 						pReturn = *pHelpModuleName;
1338 						break;
1339 					}
1340 
1341 					++pDocumentService; ++pDocumentService;
1342 					++pHelpModuleName; ++pHelpModuleName;
1343 				}
1344 			}
1345 
1346 			if ( !pReturn )
1347 			{
1348 				// could not determine the document type we're living in
1349 				// ->fallback
1350 				SvtModuleOptions aModOpt;
1351 				if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
1352 					pReturn = "swriter";
1353 				else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
1354 					pReturn = "sdatabase";
1355 				else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
1356 					pReturn = "scalc";
1357 				else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
1358 					pReturn = "simpress";
1359 				else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
1360 					pReturn = "sdraw";
1361 				else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SMATH ) )
1362 					pReturn = "smath";
1363 				else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SCHART ) )
1364 					pReturn = "schart";
1365 				else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SBASIC ) )
1366 					pReturn = "sbasic";
1367 				else
1368 				{
1369 					OSL_ENSURE( sal_False, "lcl_getModuleHelpModuleName: no installed module found" );
1370 				}
1371 			}
1372 		}
1373         catch( const Exception& )
1374         {
1375             DBG_UNHANDLED_EXCEPTION();
1376         }
1377 
1378 		if ( !pReturn )
1379 			pReturn = "swriter";
1380 
1381 		return ::rtl::OUString::createFromAscii( pReturn );
1382 	}
1383 }
1384 
1385 // -----------------------------------------------------------------------------
1386 
openHelpAgent(rtl::OUString const & _suHelpStringURL)1387 void OGenericUnoController::openHelpAgent(rtl::OUString const& _suHelpStringURL )
1388 {
1389     rtl::OUString suURL(_suHelpStringURL);
1390     rtl::OUString sLanguage = rtl::OUString::createFromAscii("Language=");
1391     if (suURL.indexOf(sLanguage) == -1)
1392     {
1393         AppendConfigToken(suURL, sal_False /* sal_False := add '&' */ );
1394     }
1395     URL aURL;
1396     aURL.Complete = suURL;
1397 
1398     openHelpAgent( aURL );
1399 }
1400 
openHelpAgent(const rtl::OString & _sHelpId)1401 void OGenericUnoController::openHelpAgent(const rtl::OString& _sHelpId)
1402 {
1403 	openHelpAgent( createHelpAgentURL( lcl_getModuleHelpModuleName( getFrame() ), _sHelpId ) );
1404 }
1405 
openHelpAgent(const URL & _rURL)1406 void OGenericUnoController::openHelpAgent( const URL& _rURL )
1407 {
1408 	try
1409 	{
1410         URL aURL( _rURL );
1411 
1412         if ( m_xUrlTransformer.is() )
1413             m_xUrlTransformer->parseStrict(aURL);
1414 
1415 		Reference< XDispatchProvider > xDispProv( m_aCurrentFrame.getFrame(), UNO_QUERY );
1416 		Reference< XDispatch > xHelpDispatch;
1417 		if ( xDispProv.is() )
1418 			xHelpDispatch = xDispProv->queryDispatch(aURL, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_helpagent")), FrameSearchFlag::PARENT | FrameSearchFlag::SELF);
1419 		OSL_ENSURE(xHelpDispatch.is(), "SbaTableQueryBrowser::openHelpAgent: could not get a dispatcher!");
1420 		if (xHelpDispatch.is())
1421 		{
1422 			xHelpDispatch->dispatch(aURL, Sequence< PropertyValue >());
1423 		}
1424 	}
1425     catch( const Exception& )
1426     {
1427         DBG_UNHANDLED_EXCEPTION();
1428     }
1429 }
1430 // -----------------------------------------------------------------------------
getTopMostContainerWindow() const1431 Reference< awt::XWindow> OGenericUnoController::getTopMostContainerWindow() const
1432 {
1433 	Reference< ::com::sun::star::awt::XWindow> xWindow;
1434 
1435     // get the top most window
1436     Reference< XFrame > xFrame( m_aCurrentFrame.getFrame() );
1437 	if ( xFrame.is() )
1438 	{
1439 		xWindow = xFrame->getContainerWindow();
1440 
1441         while ( xFrame.is() && !xFrame->isTop() )
1442 		{
1443 			xFrame.set( xFrame->getCreator(), UNO_QUERY );
1444 		}
1445 		if ( xFrame.is() )
1446 			xWindow = xFrame->getContainerWindow();
1447 	}
1448 	return xWindow;
1449 }
1450 // -----------------------------------------------------------------------------
impl_getTitleHelper_throw()1451 Reference< XTitle > OGenericUnoController::impl_getTitleHelper_throw()
1452 {
1453     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1454     ::osl::MutexGuard aGuard( getMutex() );
1455 
1456     if ( ! m_xTitleHelper.is ())
1457     {
1458         Reference< XUntitledNumbers > xUntitledProvider(getPrivateModel(), UNO_QUERY      );
1459         Reference< XController >      xThis(static_cast< XController* >(this), UNO_QUERY_THROW);
1460 
1461         ::framework::TitleHelper* pHelper = new ::framework::TitleHelper(m_xServiceFactory);
1462         m_xTitleHelper.set( static_cast< ::cppu::OWeakObject* >(pHelper), UNO_QUERY_THROW);
1463 
1464         pHelper->setOwner                   (xThis            );
1465         pHelper->connectWithUntitledNumbers (xUntitledProvider);
1466     }
1467 
1468     return m_xTitleHelper;
1469 }
1470 
1471 //=============================================================================
1472 // XTitle
getTitle()1473 ::rtl::OUString SAL_CALL OGenericUnoController::getTitle()
1474     throw (RuntimeException)
1475 {
1476     ::osl::MutexGuard aGuard( getMutex() );
1477     if ( m_bExternalTitle )
1478         return impl_getTitleHelper_throw()->getTitle ();
1479     return getPrivateTitle() + impl_getTitleHelper_throw()->getTitle ();
1480 }
1481 
1482 //=============================================================================
1483 // XTitle
setTitle(const::rtl::OUString & sTitle)1484 void SAL_CALL OGenericUnoController::setTitle(const ::rtl::OUString& sTitle)
1485     throw (RuntimeException)
1486 {
1487     vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1488 	::osl::MutexGuard aGuard( getMutex() );
1489     m_bExternalTitle = sal_True;
1490     impl_getTitleHelper_throw()->setTitle (sTitle);
1491 }
1492 
1493 //=============================================================================
1494 // XTitleChangeBroadcaster
addTitleChangeListener(const Reference<XTitleChangeListener> & xListener)1495 void SAL_CALL OGenericUnoController::addTitleChangeListener(const Reference< XTitleChangeListener >& xListener)
1496     throw (RuntimeException)
1497 {
1498     Reference< XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper_throw(), UNO_QUERY);
1499     if (xBroadcaster.is ())
1500         xBroadcaster->addTitleChangeListener (xListener);
1501 }
1502 
1503 // -----------------------------------------------------------------------------
removeTitleChangeListener(const Reference<XTitleChangeListener> & xListener)1504 void SAL_CALL OGenericUnoController::removeTitleChangeListener(const Reference< XTitleChangeListener >& xListener)
1505     throw (RuntimeException)
1506 {
1507     Reference< XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper_throw(), UNO_QUERY);
1508     if (xBroadcaster.is ())
1509         xBroadcaster->removeTitleChangeListener (xListener);
1510 }
1511 
1512 // =============================================================================
1513 // XUserInputInterception
1514 // -----------------------------------------------------------------------------
addKeyHandler(const Reference<XKeyHandler> & _rxHandler)1515 void SAL_CALL OGenericUnoController::addKeyHandler( const Reference< XKeyHandler >& _rxHandler ) throw (RuntimeException)
1516 {
1517     if ( _rxHandler.is() )
1518         m_pData->m_aUserInputInterception.addKeyHandler( _rxHandler );
1519 }
1520 
1521 // -----------------------------------------------------------------------------
removeKeyHandler(const Reference<XKeyHandler> & _rxHandler)1522 void SAL_CALL OGenericUnoController::removeKeyHandler( const Reference< XKeyHandler >& _rxHandler ) throw (RuntimeException)
1523 {
1524     m_pData->m_aUserInputInterception.removeKeyHandler( _rxHandler );
1525 }
1526 
1527 // -----------------------------------------------------------------------------
addMouseClickHandler(const Reference<XMouseClickHandler> & _rxHandler)1528 void SAL_CALL OGenericUnoController::addMouseClickHandler( const Reference< XMouseClickHandler >& _rxHandler ) throw (RuntimeException)
1529 {
1530     if ( _rxHandler.is() )
1531         m_pData->m_aUserInputInterception.addMouseClickHandler( _rxHandler );
1532 }
1533 
1534 // -----------------------------------------------------------------------------
removeMouseClickHandler(const Reference<XMouseClickHandler> & _rxHandler)1535 void SAL_CALL OGenericUnoController::removeMouseClickHandler( const Reference< XMouseClickHandler >& _rxHandler ) throw (RuntimeException)
1536 {
1537     m_pData->m_aUserInputInterception.removeMouseClickHandler( _rxHandler );
1538 }
1539 
1540 // =============================================================================
1541 // -----------------------------------------------------------------------------
executeChecked(sal_uInt16 _nCommandId,const Sequence<PropertyValue> & aArgs)1542 void OGenericUnoController::executeChecked(sal_uInt16 _nCommandId, const Sequence< PropertyValue >& aArgs)
1543 {
1544 	if ( isCommandEnabled(_nCommandId) )
1545 		Execute(_nCommandId, aArgs);
1546 }
1547 
1548 // -----------------------------------------------------------------------------
isCommandEnabled(sal_uInt16 _nCommandId) const1549 sal_Bool OGenericUnoController::isCommandEnabled(sal_uInt16 _nCommandId) const
1550 {
1551 	return GetState( _nCommandId ).bEnabled;
1552 }
1553 
1554 // -----------------------------------------------------------------------------
registerCommandURL(const::rtl::OUString & _rCompleteCommandURL)1555 sal_uInt16 OGenericUnoController::registerCommandURL( const ::rtl::OUString& _rCompleteCommandURL )
1556 {
1557     if ( !_rCompleteCommandURL.getLength() )
1558         return 0;
1559 
1560     SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCompleteCommandURL );
1561 	if ( aIter != m_aSupportedFeatures.end() )
1562 		return aIter->second.nFeatureId;
1563 
1564     // this is a previously unkwnon command
1565     sal_uInt16 nFeatureId = FIRST_USER_DEFINED_FEATURE;
1566     while ( isFeatureSupported( nFeatureId ) && ( nFeatureId < LAST_USER_DEFINED_FEATURE ) )
1567         ++nFeatureId;
1568     if ( nFeatureId == LAST_USER_DEFINED_FEATURE )
1569     {
1570         OSL_ENSURE( false, "OGenericUnoController::registerCommandURL: no more space for user defined features!" );
1571         return 0L;
1572     }
1573 
1574     ControllerFeature aFeature;
1575     aFeature.Command = _rCompleteCommandURL;
1576     aFeature.nFeatureId = nFeatureId;
1577     aFeature.GroupId = CommandGroup::INTERNAL;
1578     m_aSupportedFeatures[ aFeature.Command ] = aFeature;
1579 
1580     return nFeatureId;
1581 }
1582 
1583 // -----------------------------------------------------------------------------
notifyHiContrastChanged()1584 void OGenericUnoController::notifyHiContrastChanged()
1585 {
1586 }
1587 
1588 // -----------------------------------------------------------------------------
isDataSourceReadOnly() const1589 sal_Bool OGenericUnoController::isDataSourceReadOnly() const
1590 {
1591     return sal_False;
1592 }
1593 
1594 // -----------------------------------------------------------------------------
getXController()1595 Reference< XController > OGenericUnoController::getXController() throw( RuntimeException )
1596 {
1597     return this;
1598 }
1599 
1600 // -----------------------------------------------------------------------------
interceptUserInput(const NotifyEvent & _rEvent)1601 bool OGenericUnoController::interceptUserInput( const NotifyEvent& _rEvent )
1602 {
1603     return m_pData->m_aUserInputInterception.handleNotifyEvent( _rEvent );
1604 }
1605 
1606 // -----------------------------------------------------------------------------
isCommandChecked(sal_uInt16 _nCommandId) const1607 sal_Bool OGenericUnoController::isCommandChecked(sal_uInt16 _nCommandId) const
1608 {
1609     FeatureState aState = GetState( _nCommandId );
1610 
1611 	return aState.bChecked && (sal_Bool)*aState.bChecked;
1612 }
1613 // -----------------------------------------------------------------------------
isCommandEnabled(const::rtl::OUString & _rCompleteCommandURL) const1614 sal_Bool OGenericUnoController::isCommandEnabled( const ::rtl::OUString& _rCompleteCommandURL ) const
1615 {
1616     OSL_ENSURE( _rCompleteCommandURL.getLength(), "OGenericUnoController::isCommandEnabled: Empty command url!" );
1617 
1618 	sal_Bool bIsEnabled = sal_False;
1619     SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCompleteCommandURL );
1620 	if ( aIter != m_aSupportedFeatures.end() )
1621 		bIsEnabled = isCommandEnabled( aIter->second.nFeatureId );
1622 
1623 	return bIsEnabled;
1624 }
1625 
1626 // -----------------------------------------------------------------------------
getSupportedCommandGroups()1627 Sequence< ::sal_Int16 > SAL_CALL OGenericUnoController::getSupportedCommandGroups() throw (RuntimeException)
1628 {
1629     CommandHashMap aCmdHashMap;
1630 	for (   SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.begin();
1631             aIter != m_aSupportedFeatures.end();
1632             ++aIter
1633         )
1634         if ( aIter->second.GroupId != CommandGroup::INTERNAL )
1635             aCmdHashMap.insert( CommandHashMap::value_type( aIter->second.GroupId, 0 ));
1636 
1637     Sequence< sal_Int16 > aCommandGroups( aCmdHashMap.size() );
1638     ::std::transform( aCmdHashMap.begin(),
1639         aCmdHashMap.end(),
1640         aCommandGroups.getArray(),
1641         ::std::select1st< CommandHashMap::value_type >()
1642     );
1643 
1644     return aCommandGroups;
1645 }
1646 
1647 // -----------------------------------------------------------------------------
getConfigurableDispatchInformation(::sal_Int16 CommandGroup)1648 Sequence< DispatchInformation > SAL_CALL OGenericUnoController::getConfigurableDispatchInformation( ::sal_Int16 CommandGroup ) throw (RuntimeException)
1649 {
1650     DispatchInfoList    aInformationList;
1651     DispatchInformation aDispatchInfo;
1652     for (   SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.begin();
1653             aIter != m_aSupportedFeatures.end();
1654             ++aIter
1655         )
1656     {
1657         if ( sal_Int16( aIter->second.GroupId ) == CommandGroup )
1658         {
1659             aDispatchInfo = aIter->second;
1660             aInformationList.push_back( aDispatchInfo );
1661         }
1662     }
1663 
1664     Sequence< DispatchInformation > aInformation( aInformationList.size() );
1665     ::std::transform( aInformationList.begin(),
1666         aInformationList.end(),
1667         aInformation.getArray(),
1668         ::std::identity< DispatchInformation >()
1669     );
1670 
1671     return aInformation;
1672 }
1673 // -----------------------------------------------------------------------------
fillSupportedFeatures()1674 void OGenericUnoController::fillSupportedFeatures()
1675 {
1676 #ifdef DBG_UTIL
1677     m_bDescribingSupportedFeatures = true;
1678 #endif
1679 	describeSupportedFeatures();
1680 // -----------------------------------------------------------------------------
1681 #ifdef DBG_UTIL
1682     m_bDescribingSupportedFeatures = false;
1683 #endif
1684 }
1685 
1686 
dispose()1687 void SAL_CALL OGenericUnoController::dispose() throw(::com::sun::star::uno::RuntimeException)
1688 {
1689 	::vos::OGuard aSolarGuard(Application::GetSolarMutex());
1690 	OGenericUnoController_Base::dispose();
1691 }
1692 }   // namespace dbaui
1693 
1694