xref: /AOO41X/main/dbaccess/source/ui/browser/genericcontroller.cxx (revision 96de54900b79e13b861fbc62cbf36018b54e21b7) !
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