1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "formnavigation.hxx"
21 #include "urltransformer.hxx"
22 #include "controlfeatureinterception.hxx"
23 #include "frm_strings.hxx"
25 #include <com/sun/star/form/runtime/FormFeature.hpp>
27 #include <tools/debug.hxx>
28 #include <osl/diagnose.h>
35 using namespace ::com::sun::star::uno
;
36 using namespace ::com::sun::star::beans
;
37 using namespace ::com::sun::star::lang
;
38 using namespace ::com::sun::star::util
;
39 using namespace ::com::sun::star::frame
;
40 namespace FormFeature
= ::com::sun::star::form::runtime::FormFeature
;
42 OFormNavigationHelper::OFormNavigationHelper( const Reference
< XComponentContext
>& _rxORB
)
44 ,m_nConnectedFeatures( 0 )
46 m_pFeatureInterception
.reset( new ControlFeatureInterception( m_xORB
) );
50 OFormNavigationHelper::~OFormNavigationHelper()
55 void SAL_CALL
OFormNavigationHelper::dispose( ) throw( RuntimeException
)
57 m_pFeatureInterception
->dispose();
58 disconnectDispatchers();
62 void OFormNavigationHelper::interceptorsChanged( )
68 void OFormNavigationHelper::featureStateChanged( sal_Int16
/*_nFeatureId*/, bool /*_bEnabled*/ )
74 void OFormNavigationHelper::allFeatureStatesChanged( )
80 void SAL_CALL
OFormNavigationHelper::registerDispatchProviderInterceptor( const Reference
< XDispatchProviderInterceptor
>& _rxInterceptor
) throw (RuntimeException
, std::exception
)
82 m_pFeatureInterception
->registerDispatchProviderInterceptor( _rxInterceptor
);
83 interceptorsChanged();
87 void SAL_CALL
OFormNavigationHelper::releaseDispatchProviderInterceptor( const Reference
< XDispatchProviderInterceptor
>& _rxInterceptor
) throw (RuntimeException
, std::exception
)
89 m_pFeatureInterception
->releaseDispatchProviderInterceptor( _rxInterceptor
);
90 interceptorsChanged();
94 void SAL_CALL
OFormNavigationHelper::statusChanged( const FeatureStateEvent
& _rState
) throw (RuntimeException
, std::exception
)
96 for ( FeatureMap::iterator aFeature
= m_aSupportedFeatures
.begin();
97 aFeature
!= m_aSupportedFeatures
.end();
101 if ( aFeature
->second
.aURL
.Main
== _rState
.FeatureURL
.Main
)
103 if ( ( aFeature
->second
.bCachedState
!= bool(_rState
.IsEnabled
) )
104 || ( aFeature
->second
.aCachedAdditionalState
!= _rState
.State
)
107 // change the cached state
108 aFeature
->second
.bCachedState
= _rState
.IsEnabled
;
109 aFeature
->second
.aCachedAdditionalState
= _rState
.State
;
110 // tell derivees what happened
111 featureStateChanged( aFeature
->first
, _rState
.IsEnabled
);
118 OSL_FAIL( "OFormNavigationHelper::statusChanged: huh? An invalid/unknown URL?" );
122 void SAL_CALL
OFormNavigationHelper::disposing( const EventObject
& _rSource
) throw (RuntimeException
, std::exception
)
124 // was it one of our external dispatchers?
125 if ( m_nConnectedFeatures
)
127 for ( FeatureMap::iterator aFeature
= m_aSupportedFeatures
.begin();
128 aFeature
!= m_aSupportedFeatures
.end();
132 if ( aFeature
->second
.xDispatcher
== _rSource
.Source
)
134 aFeature
->second
.xDispatcher
->removeStatusListener( static_cast< XStatusListener
* >( this ), aFeature
->second
.aURL
);
135 aFeature
->second
.xDispatcher
= NULL
;
136 aFeature
->second
.bCachedState
= false;
137 aFeature
->second
.aCachedAdditionalState
.clear();
138 --m_nConnectedFeatures
;
140 featureStateChanged( aFeature
->first
, false );
148 void OFormNavigationHelper::updateDispatches()
150 if ( !m_nConnectedFeatures
)
151 { // we don't have any dispatchers yet -> do the initial connect
152 connectDispatchers();
156 initializeSupportedFeatures();
158 m_nConnectedFeatures
= 0;
160 Reference
< XDispatch
> xNewDispatcher
;
161 Reference
< XDispatch
> xCurrentDispatcher
;
163 for ( FeatureMap::iterator aFeature
= m_aSupportedFeatures
.begin();
164 aFeature
!= m_aSupportedFeatures
.end();
168 xNewDispatcher
= queryDispatch( aFeature
->second
.aURL
);
169 xCurrentDispatcher
= aFeature
->second
.xDispatcher
;
170 if ( xNewDispatcher
!= xCurrentDispatcher
)
172 // the dispatcher for this particular URL changed
173 if ( xCurrentDispatcher
.is() )
174 xCurrentDispatcher
->removeStatusListener( static_cast< XStatusListener
* >( this ), aFeature
->second
.aURL
);
176 xCurrentDispatcher
= aFeature
->second
.xDispatcher
= xNewDispatcher
;
178 if ( xCurrentDispatcher
.is() )
179 xCurrentDispatcher
->addStatusListener( static_cast< XStatusListener
* >( this ), aFeature
->second
.aURL
);
182 if ( xCurrentDispatcher
.is() )
183 ++m_nConnectedFeatures
;
185 aFeature
->second
.bCachedState
= false;
188 // notify derivee that (potentially) all features changed their state
189 allFeatureStatesChanged( );
193 void OFormNavigationHelper::connectDispatchers()
195 if ( m_nConnectedFeatures
)
196 { // already connected -> just do an update
201 initializeSupportedFeatures();
203 m_nConnectedFeatures
= 0;
205 for ( FeatureMap::iterator aFeature
= m_aSupportedFeatures
.begin();
206 aFeature
!= m_aSupportedFeatures
.end();
210 aFeature
->second
.bCachedState
= false;
211 aFeature
->second
.aCachedAdditionalState
.clear();
212 aFeature
->second
.xDispatcher
= queryDispatch( aFeature
->second
.aURL
);
213 if ( aFeature
->second
.xDispatcher
.is() )
215 ++m_nConnectedFeatures
;
216 aFeature
->second
.xDispatcher
->addStatusListener( static_cast< XStatusListener
* >( this ), aFeature
->second
.aURL
);
220 // notify derivee that (potentially) all features changed their state
221 allFeatureStatesChanged( );
225 void OFormNavigationHelper::disconnectDispatchers()
227 if ( m_nConnectedFeatures
)
229 for ( FeatureMap::iterator aFeature
= m_aSupportedFeatures
.begin();
230 aFeature
!= m_aSupportedFeatures
.end();
234 if ( aFeature
->second
.xDispatcher
.is() )
235 aFeature
->second
.xDispatcher
->removeStatusListener( static_cast< XStatusListener
* >( this ), aFeature
->second
.aURL
);
237 aFeature
->second
.xDispatcher
= NULL
;
238 aFeature
->second
.bCachedState
= false;
239 aFeature
->second
.aCachedAdditionalState
.clear();
242 m_nConnectedFeatures
= 0;
245 // notify derivee that (potentially) all features changed their state
246 allFeatureStatesChanged( );
250 void OFormNavigationHelper::initializeSupportedFeatures( )
252 if ( m_aSupportedFeatures
.empty() )
254 // ask the derivee which feature ids it wants us to support
255 ::std::vector
< sal_Int16
> aFeatureIds
;
256 getSupportedFeatures( aFeatureIds
);
258 OFormNavigationMapper
aUrlMapper( m_xORB
);
260 for ( ::std::vector
< sal_Int16
>::const_iterator aLoop
= aFeatureIds
.begin();
261 aLoop
!= aFeatureIds
.end();
265 FeatureInfo aFeatureInfo
;
268 aUrlMapper
.getFeatureURL( *aLoop
, aFeatureInfo
.aURL
);
269 DBG_ASSERT( bKnownId
, "OFormNavigationHelper::initializeSupportedFeatures: unknown feature id!" );
273 m_aSupportedFeatures
.insert( FeatureMap::value_type( *aLoop
, aFeatureInfo
) );
279 Reference
< XDispatch
> OFormNavigationHelper::queryDispatch( const URL
& _rURL
)
281 return m_pFeatureInterception
->queryDispatch( _rURL
);
285 void OFormNavigationHelper::dispatchWithArgument( sal_Int16 _nFeatureId
, const sal_Char
* _pParamAsciiName
,
286 const Any
& _rParamValue
) const
288 FeatureMap::const_iterator aInfo
= m_aSupportedFeatures
.find( _nFeatureId
);
289 if ( m_aSupportedFeatures
.end() != aInfo
)
291 if ( aInfo
->second
.xDispatcher
.is() )
293 Sequence
< PropertyValue
> aArgs( 1 );
294 aArgs
[0].Name
= OUString::createFromAscii( _pParamAsciiName
);
295 aArgs
[0].Value
= _rParamValue
;
297 aInfo
->second
.xDispatcher
->dispatch( aInfo
->second
.aURL
, aArgs
);
303 void OFormNavigationHelper::dispatch( sal_Int16 _nFeatureId
) const
305 FeatureMap::const_iterator aInfo
= m_aSupportedFeatures
.find( _nFeatureId
);
306 if ( m_aSupportedFeatures
.end() != aInfo
)
308 if ( aInfo
->second
.xDispatcher
.is() )
310 Sequence
< PropertyValue
> aEmptyArgs
;
311 aInfo
->second
.xDispatcher
->dispatch( aInfo
->second
.aURL
, aEmptyArgs
);
317 bool OFormNavigationHelper::isEnabled( sal_Int16 _nFeatureId
) const
319 FeatureMap::const_iterator aInfo
= m_aSupportedFeatures
.find( _nFeatureId
);
320 if ( m_aSupportedFeatures
.end() != aInfo
)
321 return aInfo
->second
.bCachedState
;
327 bool OFormNavigationHelper::getBooleanState( sal_Int16 _nFeatureId
) const
331 FeatureMap::const_iterator aInfo
= m_aSupportedFeatures
.find( _nFeatureId
);
332 if ( m_aSupportedFeatures
.end() != aInfo
)
333 aInfo
->second
.aCachedAdditionalState
>>= bState
;
339 OUString
OFormNavigationHelper::getStringState( sal_Int16 _nFeatureId
) const
343 FeatureMap::const_iterator aInfo
= m_aSupportedFeatures
.find( _nFeatureId
);
344 if ( m_aSupportedFeatures
.end() != aInfo
)
345 aInfo
->second
.aCachedAdditionalState
>>= sState
;
351 sal_Int32
OFormNavigationHelper::getIntegerState( sal_Int16 _nFeatureId
) const
353 sal_Int32 nState
= 0;
355 FeatureMap::const_iterator aInfo
= m_aSupportedFeatures
.find( _nFeatureId
);
356 if ( m_aSupportedFeatures
.end() != aInfo
)
357 aInfo
->second
.aCachedAdditionalState
>>= nState
;
363 void OFormNavigationHelper::invalidateSupportedFeaturesSet()
365 disconnectDispatchers( );
366 // no supported features anymore:
368 m_aSupportedFeatures
.swap( aEmpty
);
371 OFormNavigationMapper::OFormNavigationMapper( const Reference
< XComponentContext
>& _rxORB
)
373 m_pUrlTransformer
.reset( new UrlTransformer( _rxORB
) );
377 OFormNavigationMapper::~OFormNavigationMapper( )
382 bool OFormNavigationMapper::getFeatureURL( sal_Int16 _nFeatureId
, URL
& /* [out] */ _rURL
)
384 // get the ascii version of the URL
385 const char* pAsciiURL
= getFeatureURLAscii( _nFeatureId
);
387 _rURL
= m_pUrlTransformer
->getStrictURLFromAscii( pAsciiURL
);
389 return ( pAsciiURL
!= NULL
);
397 const sal_Int16 nFormFeature
;
398 const sal_Char
* pAsciiURL
;
400 FeatureURL( const sal_Int16 _nFormFeature
, const sal_Char
* _pAsciiURL
)
401 :nFormFeature( _nFormFeature
)
402 ,pAsciiURL( _pAsciiURL
)
406 const FeatureURL
* lcl_getFeatureTable()
408 static const FeatureURL s_aFeatureURLs
[] =
410 FeatureURL( FormFeature::MoveAbsolute
, URL_FORM_POSITION
),
411 FeatureURL( FormFeature::TotalRecords
, URL_FORM_RECORDCOUNT
),
412 FeatureURL( FormFeature::MoveToFirst
, URL_RECORD_FIRST
),
413 FeatureURL( FormFeature::MoveToPrevious
, URL_RECORD_PREV
),
414 FeatureURL( FormFeature::MoveToNext
, URL_RECORD_NEXT
),
415 FeatureURL( FormFeature::MoveToLast
, URL_RECORD_LAST
),
416 FeatureURL( FormFeature::SaveRecordChanges
, URL_RECORD_SAVE
),
417 FeatureURL( FormFeature::UndoRecordChanges
, URL_RECORD_UNDO
),
418 FeatureURL( FormFeature::MoveToInsertRow
, URL_RECORD_NEW
),
419 FeatureURL( FormFeature::DeleteRecord
, URL_RECORD_DELETE
),
420 FeatureURL( FormFeature::ReloadForm
, URL_FORM_REFRESH
),
421 FeatureURL( FormFeature::RefreshCurrentControl
, URL_FORM_REFRESH_CURRENT_CONTROL
),
422 FeatureURL( FormFeature::SortAscending
, URL_FORM_SORT_UP
),
423 FeatureURL( FormFeature::SortDescending
, URL_FORM_SORT_DOWN
),
424 FeatureURL( FormFeature::InteractiveSort
, URL_FORM_SORT
),
425 FeatureURL( FormFeature::AutoFilter
, URL_FORM_AUTO_FILTER
),
426 FeatureURL( FormFeature::InteractiveFilter
, URL_FORM_FILTER
),
427 FeatureURL( FormFeature::ToggleApplyFilter
, URL_FORM_APPLY_FILTER
),
428 FeatureURL( FormFeature::RemoveFilterAndSort
, URL_FORM_REMOVE_FILTER
),
429 FeatureURL( 0, NULL
)
431 return s_aFeatureURLs
;
436 const char* OFormNavigationMapper::getFeatureURLAscii( sal_Int16 _nFeatureId
)
438 const FeatureURL
* pFeatures
= lcl_getFeatureTable();
439 while ( pFeatures
->pAsciiURL
)
441 if ( pFeatures
->nFormFeature
== _nFeatureId
)
442 return pFeatures
->pAsciiURL
;
449 sal_Int16
OFormNavigationMapper::getFeatureId( const OUString
& _rCompleteURL
)
451 const FeatureURL
* pFeatures
= lcl_getFeatureTable();
452 while ( pFeatures
->pAsciiURL
)
454 if ( _rCompleteURL
.equalsAscii( pFeatures
->pAsciiURL
) )
455 return pFeatures
->nFormFeature
;
465 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */