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