1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: formnavigation.cxx,v $
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_forms.hxx"
33 #include "formnavigation.hxx"
34 #include "urltransformer.hxx"
35 #include "controlfeatureinterception.hxx"
36 #include <tools/debug.hxx>
37 #ifndef _SVX_SVXIDS_HRC
38 #include <svx/svxids.hrc>
40 #include "frm_strings.hxx"
42 //.........................................................................
45 //.........................................................................
47 using namespace ::com::sun::star::uno
;
48 using namespace ::com::sun::star::beans
;
49 using namespace ::com::sun::star::lang
;
50 using namespace ::com::sun::star::util
;
51 using namespace ::com::sun::star::frame
;
53 //==================================================================
54 //= OFormNavigationHelper
55 //==================================================================
56 DBG_NAME( OFormNavigationHelper
)
57 //------------------------------------------------------------------
58 OFormNavigationHelper::OFormNavigationHelper( const Reference
< XMultiServiceFactory
>& _rxORB
)
60 ,m_nConnectedFeatures( 0 )
62 DBG_CTOR( OFormNavigationHelper
, NULL
);
63 m_pFeatureInterception
.reset( new ControlFeatureInterception( m_xORB
) );
66 //------------------------------------------------------------------
67 OFormNavigationHelper::~OFormNavigationHelper()
69 DBG_DTOR( OFormNavigationHelper
, NULL
);
72 //------------------------------------------------------------------
73 void SAL_CALL
OFormNavigationHelper::dispose( ) throw( RuntimeException
)
75 m_pFeatureInterception
->dispose();
76 disconnectDispatchers();
79 //------------------------------------------------------------------
80 void OFormNavigationHelper::interceptorsChanged( )
85 //------------------------------------------------------------------
86 void OFormNavigationHelper::featureStateChanged( sal_Int32
/*_nFeatureId*/, sal_Bool
/*_bEnabled*/ )
91 //------------------------------------------------------------------
92 void OFormNavigationHelper::allFeatureStatesChanged( )
97 //------------------------------------------------------------------
98 void SAL_CALL
OFormNavigationHelper::registerDispatchProviderInterceptor( const Reference
< XDispatchProviderInterceptor
>& _rxInterceptor
) throw (RuntimeException
)
100 m_pFeatureInterception
->registerDispatchProviderInterceptor( _rxInterceptor
);
101 interceptorsChanged();
104 //------------------------------------------------------------------
105 void SAL_CALL
OFormNavigationHelper::releaseDispatchProviderInterceptor( const Reference
< XDispatchProviderInterceptor
>& _rxInterceptor
) throw (RuntimeException
)
107 m_pFeatureInterception
->releaseDispatchProviderInterceptor( _rxInterceptor
);
108 interceptorsChanged();
111 //------------------------------------------------------------------
112 void SAL_CALL
OFormNavigationHelper::statusChanged( const FeatureStateEvent
& _rState
) throw (RuntimeException
)
114 for ( FeatureMap::iterator aFeature
= m_aSupportedFeatures
.begin();
115 aFeature
!= m_aSupportedFeatures
.end();
119 if ( aFeature
->second
.aURL
.Main
== _rState
.FeatureURL
.Main
)
121 if ( ( aFeature
->second
.bCachedState
!= _rState
.IsEnabled
)
122 || ( aFeature
->second
.aCachedAdditionalState
!= _rState
.State
)
125 // change the cached state
126 aFeature
->second
.bCachedState
= _rState
.IsEnabled
;
127 aFeature
->second
.aCachedAdditionalState
= _rState
.State
;
128 // tell derivees what happened
129 featureStateChanged( aFeature
->first
, _rState
.IsEnabled
);
136 DBG_ERROR( "OFormNavigationHelper::statusChanged: huh? An invalid/unknown URL?" );
139 //------------------------------------------------------------------
140 void SAL_CALL
OFormNavigationHelper::disposing( const EventObject
& _rSource
) throw (RuntimeException
)
142 // was it one of our external dispatchers?
143 if ( m_nConnectedFeatures
)
145 for ( FeatureMap::iterator aFeature
= m_aSupportedFeatures
.begin();
146 aFeature
!= m_aSupportedFeatures
.end();
150 if ( aFeature
->second
.xDispatcher
== _rSource
.Source
)
152 aFeature
->second
.xDispatcher
->removeStatusListener( static_cast< XStatusListener
* >( this ), aFeature
->second
.aURL
);
153 aFeature
->second
.xDispatcher
= NULL
;
154 aFeature
->second
.bCachedState
= sal_False
;
155 aFeature
->second
.aCachedAdditionalState
.clear();
156 --m_nConnectedFeatures
;
158 featureStateChanged( aFeature
->first
, sal_False
);
165 //------------------------------------------------------------------
166 void OFormNavigationHelper::updateDispatches()
168 if ( !m_nConnectedFeatures
)
169 { // we don't have any dispatchers yet -> do the initial connect
170 connectDispatchers();
174 initializeSupportedFeatures();
176 m_nConnectedFeatures
= 0;
178 Reference
< XDispatch
> xNewDispatcher
;
179 Reference
< XDispatch
> xCurrentDispatcher
;
181 for ( FeatureMap::iterator aFeature
= m_aSupportedFeatures
.begin();
182 aFeature
!= m_aSupportedFeatures
.end();
186 xNewDispatcher
= queryDispatch( aFeature
->second
.aURL
);
187 xCurrentDispatcher
= aFeature
->second
.xDispatcher
;
188 if ( xNewDispatcher
!= xCurrentDispatcher
)
190 // the dispatcher for this particular URL changed
191 if ( xCurrentDispatcher
.is() )
192 xCurrentDispatcher
->removeStatusListener( static_cast< XStatusListener
* >( this ), aFeature
->second
.aURL
);
194 xCurrentDispatcher
= aFeature
->second
.xDispatcher
= xNewDispatcher
;
196 if ( xCurrentDispatcher
.is() )
197 xCurrentDispatcher
->addStatusListener( static_cast< XStatusListener
* >( this ), aFeature
->second
.aURL
);
200 if ( xCurrentDispatcher
.is() )
201 ++m_nConnectedFeatures
;
203 aFeature
->second
.bCachedState
= sal_False
;
206 // notify derivee that (potentially) all features changed their state
207 allFeatureStatesChanged( );
210 //------------------------------------------------------------------
211 void OFormNavigationHelper::connectDispatchers()
213 if ( m_nConnectedFeatures
)
214 { // already connected -> just do an update
219 initializeSupportedFeatures();
221 m_nConnectedFeatures
= 0;
223 for ( FeatureMap::iterator aFeature
= m_aSupportedFeatures
.begin();
224 aFeature
!= m_aSupportedFeatures
.end();
228 aFeature
->second
.bCachedState
= sal_False
;
229 aFeature
->second
.aCachedAdditionalState
.clear();
230 aFeature
->second
.xDispatcher
= queryDispatch( aFeature
->second
.aURL
);
231 if ( aFeature
->second
.xDispatcher
.is() )
233 ++m_nConnectedFeatures
;
234 aFeature
->second
.xDispatcher
->addStatusListener( static_cast< XStatusListener
* >( this ), aFeature
->second
.aURL
);
238 // notify derivee that (potentially) all features changed their state
239 allFeatureStatesChanged( );
242 //------------------------------------------------------------------
243 void OFormNavigationHelper::disconnectDispatchers()
245 if ( m_nConnectedFeatures
)
247 for ( FeatureMap::iterator aFeature
= m_aSupportedFeatures
.begin();
248 aFeature
!= m_aSupportedFeatures
.end();
252 if ( aFeature
->second
.xDispatcher
.is() )
253 aFeature
->second
.xDispatcher
->removeStatusListener( static_cast< XStatusListener
* >( this ), aFeature
->second
.aURL
);
255 aFeature
->second
.xDispatcher
= NULL
;
256 aFeature
->second
.bCachedState
= sal_False
;
257 aFeature
->second
.aCachedAdditionalState
.clear();
260 m_nConnectedFeatures
= 0;
263 // notify derivee that (potentially) all features changed their state
264 allFeatureStatesChanged( );
267 //------------------------------------------------------------------
268 void OFormNavigationHelper::initializeSupportedFeatures( )
270 if ( m_aSupportedFeatures
.empty() )
272 // ask the derivee which feature ids it wants us to support
273 ::std::vector
< sal_Int32
> aFeatureIds
;
274 getSupportedFeatures( aFeatureIds
);
276 OFormNavigationMapper
aUrlMapper( m_xORB
);
278 for ( ::std::vector
< sal_Int32
>::const_iterator aLoop
= aFeatureIds
.begin();
279 aLoop
!= aFeatureIds
.end();
283 FeatureInfo aFeatureInfo
;
286 aUrlMapper
.getFeatureURL( *aLoop
, aFeatureInfo
.aURL
);
287 DBG_ASSERT( bKnownId
, "OFormNavigationHelper::initializeSupportedFeatures: unknown feature id!" );
291 m_aSupportedFeatures
.insert( FeatureMap::value_type( *aLoop
, aFeatureInfo
) );
296 //------------------------------------------------------------------
297 Reference
< XDispatch
> OFormNavigationHelper::queryDispatch( const URL
& _rURL
)
299 return m_pFeatureInterception
->queryDispatch( _rURL
);
302 //------------------------------------------------------------------
303 void OFormNavigationHelper::dispatchWithArgument( sal_Int32 _nFeatureId
, const sal_Char
* _pParamAsciiName
,
304 const Any
& _rParamValue
) const
306 FeatureMap::const_iterator aInfo
= m_aSupportedFeatures
.find( _nFeatureId
);
307 if ( m_aSupportedFeatures
.end() != aInfo
)
309 if ( aInfo
->second
.xDispatcher
.is() )
311 Sequence
< PropertyValue
> aArgs( 1 );
312 aArgs
[0].Name
= ::rtl::OUString::createFromAscii( _pParamAsciiName
);
313 aArgs
[0].Value
= _rParamValue
;
315 aInfo
->second
.xDispatcher
->dispatch( aInfo
->second
.aURL
, aArgs
);
320 //------------------------------------------------------------------
321 void OFormNavigationHelper::dispatch( sal_Int32 _nFeatureId
) const
323 FeatureMap::const_iterator aInfo
= m_aSupportedFeatures
.find( _nFeatureId
);
324 if ( m_aSupportedFeatures
.end() != aInfo
)
326 if ( aInfo
->second
.xDispatcher
.is() )
328 Sequence
< PropertyValue
> aEmptyArgs
;
329 aInfo
->second
.xDispatcher
->dispatch( aInfo
->second
.aURL
, aEmptyArgs
);
334 //------------------------------------------------------------------
335 bool OFormNavigationHelper::isEnabled( sal_Int32 _nFeatureId
) const
337 FeatureMap::const_iterator aInfo
= m_aSupportedFeatures
.find( _nFeatureId
);
338 if ( m_aSupportedFeatures
.end() != aInfo
)
339 return aInfo
->second
.bCachedState
;
344 //------------------------------------------------------------------
345 bool OFormNavigationHelper::getBooleanState( sal_Int32 _nFeatureId
) const
347 sal_Bool bState
= sal_False
;
349 FeatureMap::const_iterator aInfo
= m_aSupportedFeatures
.find( _nFeatureId
);
350 if ( m_aSupportedFeatures
.end() != aInfo
)
351 aInfo
->second
.aCachedAdditionalState
>>= bState
;
356 //------------------------------------------------------------------
357 ::rtl::OUString
OFormNavigationHelper::getStringState( sal_Int32 _nFeatureId
) const
359 ::rtl::OUString sState
;
361 FeatureMap::const_iterator aInfo
= m_aSupportedFeatures
.find( _nFeatureId
);
362 if ( m_aSupportedFeatures
.end() != aInfo
)
363 aInfo
->second
.aCachedAdditionalState
>>= sState
;
368 //------------------------------------------------------------------
369 sal_Int32
OFormNavigationHelper::getIntegerState( sal_Int32 _nFeatureId
) const
371 sal_Int32 nState
= 0;
373 FeatureMap::const_iterator aInfo
= m_aSupportedFeatures
.find( _nFeatureId
);
374 if ( m_aSupportedFeatures
.end() != aInfo
)
375 aInfo
->second
.aCachedAdditionalState
>>= nState
;
380 //------------------------------------------------------------------
381 void OFormNavigationHelper::invalidateSupportedFeaturesSet()
383 disconnectDispatchers( );
384 // no supported features anymore:
386 m_aSupportedFeatures
.swap( aEmpty
);
389 //==================================================================
390 //= OFormNavigationMapper
391 //==================================================================
392 //------------------------------------------------------------------
393 OFormNavigationMapper::OFormNavigationMapper( const Reference
< XMultiServiceFactory
>& _rxORB
)
395 m_pUrlTransformer
.reset( new UrlTransformer( _rxORB
) );
398 //------------------------------------------------------------------
399 OFormNavigationMapper::~OFormNavigationMapper( )
403 //------------------------------------------------------------------
404 bool OFormNavigationMapper::getFeatureURL( sal_Int32 _nFeatureId
, URL
& /* [out] */ _rURL
)
406 // get the ascii version of the URL
407 const char* pAsciiURL
= getFeatureURLAscii( _nFeatureId
);
409 _rURL
= m_pUrlTransformer
->getStrictURLFromAscii( pAsciiURL
);
411 return ( pAsciiURL
!= NULL
);
414 //------------------------------------------------------------------
415 const char* OFormNavigationMapper::getFeatureURLAscii( sal_Int32 _nFeatureId
)
417 const char* pAsciiURL
= NULL
;
419 switch ( _nFeatureId
)
421 case SID_FM_RECORD_ABSOLUTE
: pAsciiURL
= URL_FORM_POSITION
; break;
422 case SID_FM_RECORD_TOTAL
: pAsciiURL
= URL_FORM_RECORDCOUNT
; break;
423 case SID_FM_RECORD_FIRST
: pAsciiURL
= URL_RECORD_FIRST
; break;
424 case SID_FM_RECORD_PREV
: pAsciiURL
= URL_RECORD_PREV
; break;
425 case SID_FM_RECORD_NEXT
: pAsciiURL
= URL_RECORD_NEXT
; break;
426 case SID_FM_RECORD_LAST
: pAsciiURL
= URL_RECORD_LAST
; break;
427 case SID_FM_RECORD_SAVE
: pAsciiURL
= URL_RECORD_SAVE
; break;
428 case SID_FM_RECORD_UNDO
: pAsciiURL
= URL_RECORD_UNDO
; break;
429 case SID_FM_RECORD_NEW
: pAsciiURL
= URL_RECORD_NEW
; break;
430 case SID_FM_RECORD_DELETE
: pAsciiURL
= URL_RECORD_DELETE
; break;
431 case SID_FM_REFRESH
: pAsciiURL
= URL_FORM_REFRESH
; break;
432 case SID_FM_REFRESH_FORM_CONTROL
: pAsciiURL
= URL_FORM_REFRESH_CURRENT_CONTROL
; break;
434 case SID_FM_SORTUP
: pAsciiURL
= URL_FORM_SORT_UP
; break;
435 case SID_FM_SORTDOWN
: pAsciiURL
= URL_FORM_SORT_DOWN
; break;
436 case SID_FM_ORDERCRIT
: pAsciiURL
= URL_FORM_SORT
; break;
437 case SID_FM_AUTOFILTER
: pAsciiURL
= URL_FORM_AUTO_FILTER
; break;
438 case SID_FM_FILTERCRIT
: pAsciiURL
= URL_FORM_FILTER
; break;
439 case SID_FM_FORM_FILTERED
: pAsciiURL
= URL_FORM_APPLY_FILTER
; break;
440 case SID_FM_REMOVE_FILTER_SORT
: pAsciiURL
= URL_FORM_REMOVE_FILTER
; break;
445 //------------------------------------------------------------------
446 sal_Int32
OFormNavigationMapper::getFeatureId( const ::rtl::OUString
& _rCompleteURL
)
448 sal_Int32 nFeatureId
= -1;
450 if ( _rCompleteURL
== URL_FORM_POSITION
)
451 nFeatureId
= SID_FM_RECORD_ABSOLUTE
;
452 else if ( _rCompleteURL
== URL_FORM_RECORDCOUNT
)
453 nFeatureId
= SID_FM_RECORD_TOTAL
;
454 else if ( _rCompleteURL
== URL_RECORD_FIRST
)
455 nFeatureId
= SID_FM_RECORD_FIRST
;
456 else if ( _rCompleteURL
== URL_RECORD_PREV
)
457 nFeatureId
= SID_FM_RECORD_PREV
;
458 else if ( _rCompleteURL
== URL_RECORD_NEXT
)
459 nFeatureId
= SID_FM_RECORD_NEXT
;
460 else if ( _rCompleteURL
== URL_RECORD_LAST
)
461 nFeatureId
= SID_FM_RECORD_LAST
;
462 else if ( _rCompleteURL
== URL_RECORD_SAVE
)
463 nFeatureId
= SID_FM_RECORD_SAVE
;
464 else if ( _rCompleteURL
== URL_RECORD_UNDO
)
465 nFeatureId
= SID_FM_RECORD_UNDO
;
466 else if ( _rCompleteURL
== URL_RECORD_NEW
)
467 nFeatureId
= SID_FM_RECORD_NEW
;
468 else if ( _rCompleteURL
== URL_RECORD_DELETE
)
469 nFeatureId
= SID_FM_RECORD_DELETE
;
470 else if ( _rCompleteURL
== URL_FORM_REFRESH
)
471 nFeatureId
= SID_FM_REFRESH
;
472 else if ( _rCompleteURL
== URL_FORM_REFRESH_CURRENT_CONTROL
)
473 nFeatureId
= SID_FM_REFRESH_FORM_CONTROL
;
474 else if ( _rCompleteURL
== URL_FORM_SORT_UP
)
475 nFeatureId
= SID_FM_SORTUP
;
476 else if ( _rCompleteURL
== URL_FORM_SORT_DOWN
)
477 nFeatureId
= SID_FM_SORTDOWN
;
478 else if ( _rCompleteURL
== URL_FORM_SORT
)
479 nFeatureId
= SID_FM_ORDERCRIT
;
480 else if ( _rCompleteURL
== URL_FORM_AUTO_FILTER
)
481 nFeatureId
= SID_FM_AUTOFILTER
;
482 else if ( _rCompleteURL
== URL_FORM_FILTER
)
483 nFeatureId
= SID_FM_FILTERCRIT
;
484 else if ( _rCompleteURL
== URL_FORM_APPLY_FILTER
)
485 nFeatureId
= SID_FM_FORM_FILTERED
;
486 else if ( _rCompleteURL
== URL_FORM_REMOVE_FILTER
)
487 nFeatureId
= SID_FM_REMOVE_FILTER_SORT
;
489 DBG_ASSERT( ( -1 == nFeatureId
) || _rCompleteURL
.equalsAscii( getFeatureURLAscii( nFeatureId
) ),
490 "OFormNavigationMapper::getFeatureId: inconsistent maps!" );
495 //.........................................................................
497 //.........................................................................