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