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_extensions.hxx"
26 #include "submissionhandler.hxx"
27 #include "formmetadata.hxx"
28 #include "formstrings.hxx"
29 #include "handlerhelper.hxx"
30
31 /** === begin UNO includes === **/
32 #include <com/sun/star/form/FormButtonType.hpp>
33 #include <com/sun/star/container/XNamed.hpp>
34 #include <com/sun/star/container/XIndexAccess.hpp>
35 #include <com/sun/star/form/submission/XSubmissionSupplier.hpp>
36 #include <com/sun/star/inspection/XObjectInspectorUI.hpp>
37 /** === end UNO includes === **/
38 #include <tools/debug.hxx>
39 #include <rtl/ustrbuf.hxx>
40
41 //------------------------------------------------------------------------
createRegistryInfo_SubmissionPropertyHandler()42 extern "C" void SAL_CALL createRegistryInfo_SubmissionPropertyHandler()
43 {
44 ::pcr::SubmissionPropertyHandler::registerImplementation();
45 }
46
47 //........................................................................
48 namespace pcr
49 {
50 //........................................................................
51
52 using namespace ::comphelper;
53 using namespace ::com::sun::star;
54 using namespace ::com::sun::star::uno;
55 using namespace ::com::sun::star::lang;
56 using namespace ::com::sun::star::beans;
57 using namespace ::com::sun::star::script;
58 using namespace ::com::sun::star::form;
59 using namespace ::com::sun::star::xforms;
60 using namespace ::com::sun::star::container;
61 using namespace ::com::sun::star::inspection;
62
63 //====================================================================
64 //= SubmissionHelper
65 //====================================================================
66 //--------------------------------------------------------------------
SubmissionHelper(::osl::Mutex & _rMutex,const Reference<XPropertySet> & _rxIntrospectee,const Reference<frame::XModel> & _rxContextDocument)67 SubmissionHelper::SubmissionHelper( ::osl::Mutex& _rMutex, const Reference< XPropertySet >& _rxIntrospectee, const Reference< frame::XModel >& _rxContextDocument )
68 :EFormsHelper( _rMutex, _rxIntrospectee, _rxContextDocument )
69 {
70 OSL_ENSURE( canTriggerSubmissions( _rxIntrospectee, _rxContextDocument ),
71 "SubmissionHelper::SubmissionHelper: you should not have instantiated me!" );
72 }
73
74 //--------------------------------------------------------------------
canTriggerSubmissions(const Reference<XPropertySet> & _rxControlModel,const Reference<frame::XModel> & _rxContextDocument)75 bool SubmissionHelper::canTriggerSubmissions( const Reference< XPropertySet >& _rxControlModel,
76 const Reference< frame::XModel >& _rxContextDocument ) SAL_THROW(())
77 {
78 if ( !EFormsHelper::isEForm( _rxContextDocument ) )
79 return false;
80
81 try
82 {
83 Reference< submission::XSubmissionSupplier > xSubmissionSupp( _rxControlModel, UNO_QUERY );
84 if ( xSubmissionSupp.is() )
85 return true;
86 }
87 catch( const Exception& )
88 {
89 OSL_ENSURE( sal_False, "SubmissionHelper::canTriggerSubmissions: caught an exception!" );
90 }
91 return false;
92 }
93
94 //====================================================================
95 //= SubmissionPropertyHandler
96 //====================================================================
DBG_NAME(SubmissionPropertyHandler)97 DBG_NAME( SubmissionPropertyHandler )
98 //--------------------------------------------------------------------
99 SubmissionPropertyHandler::SubmissionPropertyHandler( const Reference< XComponentContext >& _rxContext )
100 :EditPropertyHandler_Base( _rxContext )
101 ,OPropertyChangeListener( m_aMutex )
102 ,m_pPropChangeMultiplexer( NULL )
103 {
104 DBG_CTOR( SubmissionPropertyHandler, NULL );
105 }
106
107 //--------------------------------------------------------------------
~SubmissionPropertyHandler()108 SubmissionPropertyHandler::~SubmissionPropertyHandler( )
109 {
110 disposeAdapter();
111 DBG_DTOR( SubmissionPropertyHandler, NULL );
112 }
113
114 //--------------------------------------------------------------------
getImplementationName_static()115 ::rtl::OUString SAL_CALL SubmissionPropertyHandler::getImplementationName_static( ) throw (RuntimeException)
116 {
117 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.SubmissionPropertyHandler" ) );
118 }
119
120 //--------------------------------------------------------------------
getSupportedServiceNames_static()121 Sequence< ::rtl::OUString > SAL_CALL SubmissionPropertyHandler::getSupportedServiceNames_static( ) throw (RuntimeException)
122 {
123 Sequence< ::rtl::OUString > aSupported( 1 );
124 aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.inspection.SubmissionPropertyHandler" ) );
125 return aSupported;
126 }
127
128 //--------------------------------------------------------------------
getPropertyValue(const::rtl::OUString & _rPropertyName)129 Any SAL_CALL SubmissionPropertyHandler::getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
130 {
131 ::osl::MutexGuard aGuard( m_aMutex );
132 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
133
134 OSL_ENSURE( m_pHelper.get(), "SubmissionPropertyHandler::getPropertyValue: inconsistency!" );
135 // if we survived impl_getPropertyId_throw, we should have a helper, since no helper implies no properties
136
137 Any aReturn;
138 try
139 {
140 switch ( nPropId )
141 {
142 case PROPERTY_ID_SUBMISSION_ID:
143 {
144 Reference< submission::XSubmissionSupplier > xSubmissionSupp( m_xComponent, UNO_QUERY );
145 OSL_ENSURE( xSubmissionSupp.is(), "SubmissionPropertyHandler::getPropertyValue: this should never happen ..." );
146 // this handler is not intended for components which are no XSubmissionSupplier
147 Reference< submission::XSubmission > xSubmission;
148 if ( xSubmissionSupp.is() )
149 xSubmission = xSubmissionSupp->getSubmission( );
150 aReturn <<= xSubmission;
151 }
152 break;
153
154 case PROPERTY_ID_XFORMS_BUTTONTYPE:
155 {
156 FormButtonType eType = FormButtonType_PUSH;
157 OSL_VERIFY( m_xComponent->getPropertyValue( PROPERTY_BUTTONTYPE ) >>= eType );
158 if ( ( eType != FormButtonType_PUSH ) && ( eType != FormButtonType_SUBMIT ) )
159 eType = FormButtonType_PUSH;
160 aReturn <<= eType;
161 }
162 break;
163
164 default:
165 DBG_ERROR( "SubmissionPropertyHandler::getPropertyValue: cannot handle this property!" );
166 break;
167 }
168 }
169 catch( const Exception& )
170 {
171 OSL_ENSURE( sal_False, "SubmissionPropertyHandler::getPropertyValue: caught an exception!" );
172 }
173
174 return aReturn;
175 }
176
177 //--------------------------------------------------------------------
setPropertyValue(const::rtl::OUString & _rPropertyName,const Any & _rValue)178 void SAL_CALL SubmissionPropertyHandler::setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw (UnknownPropertyException, RuntimeException)
179 {
180 ::osl::MutexGuard aGuard( m_aMutex );
181 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
182
183 OSL_ENSURE( m_pHelper.get(), "SubmissionPropertyHandler::setPropertyValue: inconsistency!" );
184 // if we survived impl_getPropertyId_throw, we should have a helper, since no helper implies no properties
185
186 try
187 {
188 switch ( nPropId )
189 {
190 case PROPERTY_ID_SUBMISSION_ID:
191 {
192 Reference< submission::XSubmission > xSubmission;
193 OSL_VERIFY( _rValue >>= xSubmission );
194
195 Reference< submission::XSubmissionSupplier > xSubmissionSupp( m_xComponent, UNO_QUERY );
196 OSL_ENSURE( xSubmissionSupp.is(), "SubmissionPropertyHandler::setPropertyValue: this should never happen ..." );
197 // this handler is not intended for components which are no XSubmissionSupplier
198 if ( xSubmissionSupp.is() )
199 {
200 xSubmissionSupp->setSubmission( xSubmission );
201 impl_setContextDocumentModified_nothrow();
202 }
203 }
204 break;
205
206 case PROPERTY_ID_XFORMS_BUTTONTYPE:
207 m_xComponent->setPropertyValue( PROPERTY_BUTTONTYPE, _rValue );
208 break;
209
210 default:
211 OSL_ENSURE( sal_False, "SubmissionPropertyHandler::setPropertyValue: cannot handle this id!" );
212 }
213 }
214 catch( const Exception& )
215 {
216 OSL_ENSURE( sal_False, "SubmissionPropertyHandler::setPropertyValue: caught an exception!" );
217 }
218 }
219
220 //--------------------------------------------------------------------
getActuatingProperties()221 Sequence< ::rtl::OUString > SAL_CALL SubmissionPropertyHandler::getActuatingProperties( ) throw (RuntimeException)
222 {
223 ::osl::MutexGuard aGuard( m_aMutex );
224 if ( !m_pHelper.get() )
225 return Sequence< ::rtl::OUString >();
226
227 Sequence< ::rtl::OUString > aReturn( 1 );
228 aReturn[ 0 ] = PROPERTY_XFORMS_BUTTONTYPE;
229 return aReturn;
230 }
231
232 //--------------------------------------------------------------------
getSupersededProperties()233 Sequence< ::rtl::OUString > SAL_CALL SubmissionPropertyHandler::getSupersededProperties( ) throw (RuntimeException)
234 {
235 ::osl::MutexGuard aGuard( m_aMutex );
236 if ( !m_pHelper.get() )
237 return Sequence< ::rtl::OUString >();
238
239 Sequence< ::rtl::OUString > aReturn( 3 );
240 aReturn[ 0 ] = PROPERTY_TARGET_URL;
241 aReturn[ 1 ] = PROPERTY_TARGET_FRAME;
242 aReturn[ 2 ] = PROPERTY_BUTTONTYPE;
243 return aReturn;
244 }
245
246 //--------------------------------------------------------------------
onNewComponent()247 void SubmissionPropertyHandler::onNewComponent()
248 {
249 if ( m_pPropChangeMultiplexer )
250 {
251 m_pPropChangeMultiplexer->dispose();
252 m_pPropChangeMultiplexer->release();
253 m_pPropChangeMultiplexer = NULL;
254 }
255
256 EditPropertyHandler_Base::onNewComponent();
257
258 Reference< frame::XModel > xDocument( impl_getContextDocument_nothrow() );
259 DBG_ASSERT( xDocument.is(), "SubmissionPropertyHandler::onNewComponent: no document!" );
260
261 m_pHelper.reset();
262
263 if ( SubmissionHelper::canTriggerSubmissions( m_xComponent, xDocument ) )
264 {
265 m_pHelper.reset( new SubmissionHelper( m_aMutex, m_xComponent, xDocument ) );
266
267 m_pPropChangeMultiplexer = new OPropertyChangeMultiplexer( this, m_xComponent );
268 m_pPropChangeMultiplexer->acquire();
269 m_pPropChangeMultiplexer->addProperty( PROPERTY_BUTTONTYPE );
270 }
271 }
272
273 //--------------------------------------------------------------------
doDescribeSupportedProperties() const274 Sequence< Property > SAL_CALL SubmissionPropertyHandler::doDescribeSupportedProperties() const
275 {
276 ::std::vector< Property > aProperties;
277 if ( m_pHelper.get() )
278 {
279 implAddPropertyDescription( aProperties, PROPERTY_SUBMISSION_ID, ::getCppuType( static_cast< Reference< submission::XSubmission > * >( NULL ) ) );
280 implAddPropertyDescription( aProperties, PROPERTY_XFORMS_BUTTONTYPE, ::getCppuType( static_cast< FormButtonType* >( NULL ) ) );
281 }
282 if ( aProperties.empty() )
283 return Sequence< Property >();
284 return Sequence< Property >( &(*aProperties.begin()), aProperties.size() );
285 }
286
287 //--------------------------------------------------------------------
describePropertyLine(const::rtl::OUString & _rPropertyName,const Reference<XPropertyControlFactory> & _rxControlFactory)288 LineDescriptor SAL_CALL SubmissionPropertyHandler::describePropertyLine( const ::rtl::OUString& _rPropertyName,
289 const Reference< XPropertyControlFactory >& _rxControlFactory )
290 throw (UnknownPropertyException, NullPointerException, RuntimeException)
291 {
292 ::osl::MutexGuard aGuard( m_aMutex );
293 if ( !_rxControlFactory.is() )
294 throw NullPointerException();
295 if ( !m_pHelper.get() )
296 RuntimeException();
297
298 ::std::vector< ::rtl::OUString > aListEntries;
299 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
300 switch ( nPropId )
301 {
302 case PROPERTY_ID_SUBMISSION_ID:
303 const_cast< SubmissionHelper* >( m_pHelper.get() )->getAllElementUINames( EFormsHelper::Submission, aListEntries, false );
304 break;
305
306 case PROPERTY_ID_XFORMS_BUTTONTYPE:
307 {
308 // available options are nearly the same as for the "normal" button type, but only the
309 // first two options
310 aListEntries = m_pInfoService->getPropertyEnumRepresentations( PROPERTY_ID_BUTTONTYPE );
311 aListEntries.resize( 2 );
312 }
313 break;
314
315 default:
316 OSL_ENSURE( sal_False, "SubmissionPropertyHandler::describePropertyLine: cannot handle this id!" );
317 return LineDescriptor();
318 }
319
320 LineDescriptor aDescriptor;
321 aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory, aListEntries, sal_False, sal_True );
322 aDescriptor.DisplayName = m_pInfoService->getPropertyTranslation( nPropId );
323 aDescriptor.Category = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "General" ) );
324 aDescriptor.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( nPropId ) );
325 return aDescriptor;
326 }
327
328 //--------------------------------------------------------------------
actuatingPropertyChanged(const::rtl::OUString & _rActuatingPropertyName,const Any & _rNewValue,const Any &,const Reference<XObjectInspectorUI> & _rxInspectorUI,sal_Bool)329 void SAL_CALL SubmissionPropertyHandler::actuatingPropertyChanged( const ::rtl::OUString& _rActuatingPropertyName, const Any& _rNewValue, const Any& /*_rOldValue*/, const Reference< XObjectInspectorUI >& _rxInspectorUI, sal_Bool ) throw (NullPointerException, RuntimeException)
330 {
331 if ( !_rxInspectorUI.is() )
332 throw NullPointerException();
333
334 ::osl::MutexGuard aGuard( m_aMutex );
335 PropertyId nActuatingPropId( impl_getPropertyId_throw( _rActuatingPropertyName ) );
336 OSL_PRECOND( m_pHelper.get(), "SubmissionPropertyHandler::actuatingPropertyChanged: inconsistentcy!" );
337 // if we survived impl_getPropertyId_throw, we should have a helper, since no helper implies no properties
338
339 switch ( nActuatingPropId )
340 {
341 case PROPERTY_ID_XFORMS_BUTTONTYPE:
342 {
343 FormButtonType eType = FormButtonType_PUSH;
344 OSL_VERIFY( _rNewValue >>= eType );
345 _rxInspectorUI->enablePropertyUI( PROPERTY_SUBMISSION_ID, eType == FormButtonType_SUBMIT );
346 }
347 break;
348
349 default:
350 OSL_ENSURE( sal_False, "SubmissionPropertyHandler::actuatingPropertyChanged: cannot handle this id!" );
351 }
352 }
353
354 //--------------------------------------------------------------------
convertToPropertyValue(const::rtl::OUString & _rPropertyName,const Any & _rControlValue)355 Any SAL_CALL SubmissionPropertyHandler::convertToPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rControlValue ) throw (UnknownPropertyException, RuntimeException)
356 {
357 ::osl::MutexGuard aGuard( m_aMutex );
358 Any aPropertyValue;
359
360 OSL_ENSURE( m_pHelper.get(), "SubmissionPropertyHandler::convertToPropertyValue: we have no SupportedProperties!" );
361 if ( !m_pHelper.get() )
362 return aPropertyValue;
363
364 ::rtl::OUString sControlValue;
365 OSL_VERIFY( _rControlValue >>= sControlValue );
366
367 PropertyId nPropId( m_pInfoService->getPropertyId( _rPropertyName ) );
368 switch ( nPropId )
369 {
370 case PROPERTY_ID_SUBMISSION_ID:
371 {
372 Reference< XSubmission > xSubmission( m_pHelper->getModelElementFromUIName( EFormsHelper::Submission, sControlValue ), UNO_QUERY );
373 aPropertyValue <<= xSubmission;
374 }
375 break;
376
377 case PROPERTY_ID_XFORMS_BUTTONTYPE:
378 {
379 ::rtl::Reference< IPropertyEnumRepresentation > aEnumConversion(
380 new DefaultEnumRepresentation( *m_pInfoService, ::getCppuType( static_cast< FormButtonType* >( NULL ) ), PROPERTY_ID_BUTTONTYPE ) );
381 // TODO/UNOize: make aEnumConversion a member?
382 aEnumConversion->getValueFromDescription( sControlValue, aPropertyValue );
383 }
384 break;
385
386 default:
387 OSL_ENSURE( sal_False, "SubmissionPropertyHandler::convertToPropertyValue: cannot handle this id!" );
388 }
389
390 return aPropertyValue;
391 }
392
393 //--------------------------------------------------------------------
convertToControlValue(const::rtl::OUString & _rPropertyName,const Any & _rPropertyValue,const Type & _rControlValueType)394 Any SAL_CALL SubmissionPropertyHandler::convertToControlValue( const ::rtl::OUString& _rPropertyName, const Any& _rPropertyValue, const Type& _rControlValueType ) throw (UnknownPropertyException, RuntimeException)
395 {
396 ::osl::MutexGuard aGuard( m_aMutex );
397 Any aControlValue;
398
399 OSL_ENSURE( m_pHelper.get(), "SubmissionPropertyHandler::convertToControlValue: we have no SupportedProperties!" );
400 if ( !m_pHelper.get() )
401 return aControlValue;
402
403 OSL_ENSURE( _rControlValueType.getTypeClass() == TypeClass_STRING,
404 "SubmissionPropertyHandler::convertToControlValue: all our controls should use strings for value exchange!" );
405 (void)_rControlValueType;
406
407 PropertyId nPropId( m_pInfoService->getPropertyId( _rPropertyName ) );
408 switch ( nPropId )
409 {
410 case PROPERTY_ID_SUBMISSION_ID:
411 {
412 Reference< XPropertySet > xSubmission( _rPropertyValue, UNO_QUERY );
413 if ( xSubmission.is() )
414 aControlValue <<= m_pHelper->getModelElementUIName( EFormsHelper::Submission, xSubmission );
415 }
416 break;
417
418 case PROPERTY_ID_XFORMS_BUTTONTYPE:
419 {
420 ::rtl::Reference< IPropertyEnumRepresentation > aEnumConversion(
421 new DefaultEnumRepresentation( *m_pInfoService, _rPropertyValue.getValueType(), PROPERTY_ID_BUTTONTYPE ) );
422 // TODO/UNOize: make aEnumConversion a member?
423 aControlValue <<= aEnumConversion->getDescriptionForValue( _rPropertyValue );
424 }
425 break;
426
427 default:
428 OSL_ENSURE( sal_False, "SubmissionPropertyHandler::convertToControlValue: cannot handle this id!" );
429 }
430
431 return aControlValue;
432 }
433
434 //--------------------------------------------------------------------
_propertyChanged(const PropertyChangeEvent & _rEvent)435 void SubmissionPropertyHandler::_propertyChanged( const PropertyChangeEvent& _rEvent ) throw(RuntimeException)
436 {
437 if ( _rEvent.PropertyName == PROPERTY_BUTTONTYPE )
438 firePropertyChange( PROPERTY_XFORMS_BUTTONTYPE, PROPERTY_ID_XFORMS_BUTTONTYPE, _rEvent.OldValue, _rEvent.NewValue );
439 }
440
441 //........................................................................
442 } // namespace pcr
443 //........................................................................
444
445