Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "xsdvalidationpropertyhandler.hxx"
21 : #include "formstrings.hxx"
22 : #include "formmetadata.hxx"
23 : #include "xsddatatypes.hxx"
24 : #include "modulepcr.hxx"
25 : #include "formresid.hrc"
26 : #include "formlocalid.hrc"
27 : #include "propctrlr.hrc"
28 : #include "newdatatype.hxx"
29 : #include "xsdvalidationhelper.hxx"
30 : #include "pcrcommon.hxx"
31 : #include "handlerhelper.hxx"
32 :
33 : #include <com/sun/star/beans/PropertyAttribute.hpp>
34 : #include <com/sun/star/xsd/WhiteSpaceTreatment.hpp>
35 : #include <com/sun/star/xsd/DataTypeClass.hpp>
36 : #include <com/sun/star/inspection/PropertyControlType.hpp>
37 : #include <com/sun/star/beans/Optional.hpp>
38 : #include <com/sun/star/inspection/XObjectInspectorUI.hpp>
39 : #include <com/sun/star/inspection/PropertyLineElement.hpp>
40 : #include <vcl/msgbox.hxx>
41 : #include <tools/debug.hxx>
42 : #include <svtools/localresaccess.hxx>
43 : #include <sal/macros.h>
44 :
45 : #include <algorithm>
46 : #include <functional>
47 : #include <limits>
48 :
49 : //------------------------------------------------------------------------
50 0 : extern "C" void SAL_CALL createRegistryInfo_XSDValidationPropertyHandler()
51 : {
52 0 : ::pcr::XSDValidationPropertyHandler::registerImplementation();
53 0 : }
54 :
55 : //........................................................................
56 : namespace pcr
57 : {
58 : //........................................................................
59 :
60 : using namespace ::com::sun::star;
61 : using namespace ::com::sun::star::uno;
62 : using namespace ::com::sun::star::lang;
63 : using namespace ::com::sun::star::beans;
64 : using namespace ::com::sun::star::xforms;
65 : using namespace ::com::sun::star::xsd;
66 : using namespace ::com::sun::star::script;
67 : using namespace ::com::sun::star::inspection;
68 :
69 : using ::com::sun::star::beans::PropertyAttribute::MAYBEVOID;
70 :
71 : //====================================================================
72 : //= XSDValidationPropertyHandler
73 : //====================================================================
74 : DBG_NAME( XSDValidationPropertyHandler )
75 : //--------------------------------------------------------------------
76 0 : XSDValidationPropertyHandler::XSDValidationPropertyHandler( const Reference< XComponentContext >& _rxContext )
77 0 : :XSDValidationPropertyHandler_Base( _rxContext )
78 : {
79 : DBG_CTOR( XSDValidationPropertyHandler, NULL );
80 0 : }
81 :
82 : //--------------------------------------------------------------------
83 0 : XSDValidationPropertyHandler::~XSDValidationPropertyHandler()
84 : {
85 : DBG_DTOR( XSDValidationPropertyHandler, NULL );
86 0 : }
87 :
88 : //--------------------------------------------------------------------
89 0 : ::rtl::OUString SAL_CALL XSDValidationPropertyHandler::getImplementationName_static( ) throw (RuntimeException)
90 : {
91 0 : return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.XSDValidationPropertyHandler" ) );
92 : }
93 :
94 : //--------------------------------------------------------------------
95 0 : Sequence< ::rtl::OUString > SAL_CALL XSDValidationPropertyHandler::getSupportedServiceNames_static( ) throw (RuntimeException)
96 : {
97 0 : Sequence< ::rtl::OUString > aSupported( 1 );
98 0 : aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.inspection.XSDValidationPropertyHandler" ) );
99 0 : return aSupported;
100 : }
101 :
102 : //--------------------------------------------------------------------
103 0 : Any SAL_CALL XSDValidationPropertyHandler::getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
104 : {
105 0 : ::osl::MutexGuard aGuard( m_aMutex );
106 0 : PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
107 :
108 : OSL_ENSURE( m_pHelper.get(), "XSDValidationPropertyHandler::getPropertyValue: inconsistency!" );
109 : // if we survived impl_getPropertyId_throw, we should have a helper, since no helper implies no properties
110 :
111 0 : Any aReturn;
112 0 : ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
113 0 : switch ( nPropId )
114 : {
115 : // common facets
116 0 : case PROPERTY_ID_XSD_DATA_TYPE: aReturn = pType.is() ? pType->getFacet( PROPERTY_NAME ) : makeAny( ::rtl::OUString() ); break;
117 0 : case PROPERTY_ID_XSD_WHITESPACES:aReturn = pType.is() ? pType->getFacet( PROPERTY_XSD_WHITESPACES ) : makeAny( WhiteSpaceTreatment::Preserve ); break;
118 0 : case PROPERTY_ID_XSD_PATTERN: aReturn = pType.is() ? pType->getFacet( PROPERTY_XSD_PATTERN ) : makeAny( ::rtl::OUString() ); break;
119 :
120 : // all other properties are simply forwarded, if they exist at the given type
121 : default:
122 : {
123 0 : if ( pType.is() && pType->hasFacet( _rPropertyName ) )
124 0 : aReturn = pType->getFacet( _rPropertyName );
125 : }
126 0 : break;
127 : }
128 :
129 0 : return aReturn;
130 : }
131 :
132 : //--------------------------------------------------------------------
133 0 : void SAL_CALL XSDValidationPropertyHandler::setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw (UnknownPropertyException, RuntimeException)
134 : {
135 0 : ::osl::MutexGuard aGuard( m_aMutex );
136 0 : PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
137 :
138 : OSL_ENSURE( m_pHelper.get(), "XSDValidationPropertyHandler::getPropertyValue: inconsistency!" );
139 : // if we survived impl_getPropertyId_throw, we should have a helper, since no helper implies no properties
140 :
141 0 : if ( PROPERTY_ID_XSD_DATA_TYPE == nPropId )
142 : {
143 0 : ::rtl::OUString sTypeName;
144 0 : OSL_VERIFY( _rValue >>= sTypeName );
145 0 : m_pHelper->setValidatingDataTypeByName( sTypeName );
146 0 : impl_setContextDocumentModified_nothrow();
147 0 : return;
148 : }
149 :
150 0 : ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
151 0 : if ( !pType.is() )
152 : {
153 : OSL_FAIL( "XSDValidationPropertyHandler::setPropertyValue: you're trying to set a type facet, without a current type!" );
154 : return;
155 : }
156 :
157 0 : pType->setFacet( _rPropertyName, _rValue );
158 0 : impl_setContextDocumentModified_nothrow();
159 : }
160 :
161 : //--------------------------------------------------------------------
162 0 : void XSDValidationPropertyHandler::onNewComponent()
163 : {
164 0 : XSDValidationPropertyHandler_Base::onNewComponent();
165 :
166 0 : Reference< frame::XModel > xDocument( impl_getContextDocument_nothrow() );
167 : DBG_ASSERT( xDocument.is(), "XSDValidationPropertyHandler::onNewComponent: no document!" );
168 0 : if ( EFormsHelper::isEForm( xDocument ) )
169 0 : m_pHelper.reset( new XSDValidationHelper( m_aMutex, m_xComponent, xDocument ) );
170 : else
171 0 : m_pHelper.reset( NULL );
172 0 : }
173 :
174 : //--------------------------------------------------------------------
175 0 : Sequence< Property > XSDValidationPropertyHandler::doDescribeSupportedProperties() const
176 : {
177 0 : ::std::vector< Property > aProperties;
178 :
179 0 : if ( m_pHelper.get() )
180 : {
181 0 : bool bAllowBinding = m_pHelper->canBindToAnyDataType();
182 :
183 0 : if ( bAllowBinding )
184 : {
185 0 : aProperties.reserve( 12 );
186 :
187 0 : addStringPropertyDescription( aProperties, PROPERTY_XSD_DATA_TYPE );
188 0 : addInt16PropertyDescription ( aProperties, PROPERTY_XSD_WHITESPACES );
189 0 : addStringPropertyDescription( aProperties, PROPERTY_XSD_PATTERN );
190 :
191 : // string facets
192 0 : addInt32PropertyDescription( aProperties, PROPERTY_XSD_LENGTH, MAYBEVOID );
193 0 : addInt32PropertyDescription( aProperties, PROPERTY_XSD_MIN_LENGTH, MAYBEVOID );
194 0 : addInt32PropertyDescription( aProperties, PROPERTY_XSD_MAX_LENGTH, MAYBEVOID );
195 :
196 : // decimal facets
197 0 : addInt32PropertyDescription( aProperties, PROPERTY_XSD_TOTAL_DIGITS, MAYBEVOID );
198 0 : addInt32PropertyDescription( aProperties, PROPERTY_XSD_FRACTION_DIGITS, MAYBEVOID );
199 :
200 : // facets for different types
201 0 : addInt16PropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_INT, MAYBEVOID );
202 0 : addInt16PropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_INT, MAYBEVOID );
203 0 : addInt16PropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_INT, MAYBEVOID );
204 0 : addInt16PropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_INT, MAYBEVOID );
205 0 : addDoublePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_DOUBLE, MAYBEVOID );
206 0 : addDoublePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_DOUBLE, MAYBEVOID );
207 0 : addDoublePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_DOUBLE, MAYBEVOID );
208 0 : addDoublePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_DOUBLE, MAYBEVOID );
209 0 : addDatePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_DATE, MAYBEVOID );
210 0 : addDatePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_DATE, MAYBEVOID );
211 0 : addDatePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_DATE, MAYBEVOID );
212 0 : addDatePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_DATE, MAYBEVOID );
213 0 : addTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_TIME, MAYBEVOID );
214 0 : addTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_TIME, MAYBEVOID );
215 0 : addTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_TIME, MAYBEVOID );
216 0 : addTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_TIME, MAYBEVOID );
217 0 : addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_DATE_TIME, MAYBEVOID );
218 0 : addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_DATE_TIME, MAYBEVOID );
219 0 : addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_DATE_TIME, MAYBEVOID );
220 0 : addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_DATE_TIME, MAYBEVOID );
221 : }
222 : }
223 :
224 0 : if ( aProperties.empty() )
225 0 : return Sequence< Property >();
226 0 : return Sequence< Property >( &(*aProperties.begin()), aProperties.size() );
227 : }
228 :
229 : //--------------------------------------------------------------------
230 0 : Sequence< ::rtl::OUString > SAL_CALL XSDValidationPropertyHandler::getSupersededProperties( ) throw (RuntimeException)
231 : {
232 0 : ::osl::MutexGuard aGuard( m_aMutex );
233 :
234 0 : ::std::vector< ::rtl::OUString > aSuperfluous;
235 0 : if ( m_pHelper.get() )
236 : {
237 0 : aSuperfluous.push_back( static_cast<const rtl::OUString&>(PROPERTY_CONTROLSOURCE) );
238 0 : aSuperfluous.push_back( static_cast<const rtl::OUString&>(PROPERTY_EMPTY_IS_NULL) );
239 0 : aSuperfluous.push_back( static_cast<const rtl::OUString&>(PROPERTY_FILTERPROPOSAL) );
240 0 : aSuperfluous.push_back( static_cast<const rtl::OUString&>(PROPERTY_LISTSOURCETYPE) );
241 0 : aSuperfluous.push_back( static_cast<const rtl::OUString&>(PROPERTY_LISTSOURCE) );
242 0 : aSuperfluous.push_back( static_cast<const rtl::OUString&>(PROPERTY_BOUNDCOLUMN) );
243 :
244 0 : bool bAllowBinding = m_pHelper->canBindToAnyDataType();
245 :
246 0 : if ( bAllowBinding )
247 : {
248 0 : aSuperfluous.push_back( static_cast<const rtl::OUString&>(PROPERTY_MAXTEXTLEN) );
249 0 : aSuperfluous.push_back( static_cast<const rtl::OUString&>(PROPERTY_VALUEMIN) );
250 0 : aSuperfluous.push_back( static_cast<const rtl::OUString&>(PROPERTY_VALUEMAX) );
251 0 : aSuperfluous.push_back( static_cast<const rtl::OUString&>(PROPERTY_DECIMAL_ACCURACY) );
252 0 : aSuperfluous.push_back( static_cast<const rtl::OUString&>(PROPERTY_TIMEMIN) );
253 0 : aSuperfluous.push_back( static_cast<const rtl::OUString&>(PROPERTY_TIMEMAX) );
254 0 : aSuperfluous.push_back( static_cast<const rtl::OUString&>(PROPERTY_DATEMIN) );
255 0 : aSuperfluous.push_back( static_cast<const rtl::OUString&>(PROPERTY_DATEMAX) );
256 0 : aSuperfluous.push_back( static_cast<const rtl::OUString&>(PROPERTY_EFFECTIVE_MIN) );
257 0 : aSuperfluous.push_back( static_cast<const rtl::OUString&>(PROPERTY_EFFECTIVE_MAX) );
258 : }
259 : }
260 :
261 0 : if ( aSuperfluous.empty() )
262 0 : return Sequence< ::rtl::OUString >();
263 0 : return Sequence< ::rtl::OUString >( &(*aSuperfluous.begin()), aSuperfluous.size() );
264 : }
265 :
266 : //--------------------------------------------------------------------
267 0 : Sequence< ::rtl::OUString > SAL_CALL XSDValidationPropertyHandler::getActuatingProperties( ) throw (RuntimeException)
268 : {
269 0 : ::osl::MutexGuard aGuard( m_aMutex );
270 0 : ::std::vector< ::rtl::OUString > aInterestedInActuations( 2 );
271 0 : if ( m_pHelper.get() )
272 : {
273 0 : aInterestedInActuations.push_back( static_cast<const rtl::OUString&>(PROPERTY_XSD_DATA_TYPE) );
274 0 : aInterestedInActuations.push_back( static_cast<const rtl::OUString&>(PROPERTY_XML_DATA_MODEL) );
275 : }
276 0 : if ( aInterestedInActuations.empty() )
277 0 : return Sequence< ::rtl::OUString >();
278 0 : return Sequence< ::rtl::OUString >( &(*aInterestedInActuations.begin()), aInterestedInActuations.size() );
279 : }
280 :
281 : //--------------------------------------------------------------------
282 : namespace
283 : {
284 0 : void showPropertyUI( const Reference< XObjectInspectorUI >& _rxInspectorUI, const ::rtl::OUString& _rPropertyName, bool _bShow )
285 : {
286 0 : if ( _bShow )
287 0 : _rxInspectorUI->showPropertyUI( _rPropertyName );
288 : else
289 0 : _rxInspectorUI->hidePropertyUI( _rPropertyName );
290 0 : }
291 : }
292 :
293 : //--------------------------------------------------------------------
294 0 : LineDescriptor SAL_CALL XSDValidationPropertyHandler::describePropertyLine( const ::rtl::OUString& _rPropertyName,
295 : const Reference< XPropertyControlFactory >& _rxControlFactory )
296 : throw (UnknownPropertyException, NullPointerException, RuntimeException)
297 : {
298 0 : ::osl::MutexGuard aGuard( m_aMutex );
299 0 : if ( !_rxControlFactory.is() )
300 0 : throw NullPointerException();
301 0 : if ( !m_pHelper.get() )
302 0 : throw RuntimeException();
303 :
304 0 : PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
305 :
306 0 : LineDescriptor aDescriptor;
307 0 : if ( nPropId != PROPERTY_ID_XSD_DATA_TYPE )
308 0 : aDescriptor.IndentLevel = 1;
309 :
310 : // collect some information about the to-be-created control
311 0 : sal_Int16 nControlType = PropertyControlType::TextField;
312 0 : ::std::vector< ::rtl::OUString > aListEntries;
313 0 : Optional< double > aMinValue( sal_False, 0 );
314 0 : Optional< double > aMaxValue( sal_False, 0 );
315 :
316 0 : switch ( nPropId )
317 : {
318 : case PROPERTY_ID_XSD_DATA_TYPE:
319 0 : nControlType = PropertyControlType::ListBox;
320 :
321 0 : implGetAvailableDataTypeNames( aListEntries );
322 :
323 0 : aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_ADD_DATA_TYPE);
324 0 : aDescriptor.SecondaryButtonId = rtl::OUString::createFromAscii(UID_PROP_REMOVE_DATA_TYPE);;
325 0 : aDescriptor.HasPrimaryButton = aDescriptor.HasSecondaryButton = sal_True;
326 0 : aDescriptor.PrimaryButtonImageURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:graphicrepository/extensions/res/buttonplus.png" ) );
327 0 : aDescriptor.SecondaryButtonImageURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:graphicrepository/extensions/res/buttonminus.png" ) );
328 0 : break;
329 :
330 : case PROPERTY_ID_XSD_WHITESPACES:
331 : {
332 0 : nControlType = PropertyControlType::ListBox;
333 0 : aListEntries = m_pInfoService->getPropertyEnumRepresentations( PROPERTY_ID_XSD_WHITESPACES );
334 : }
335 0 : break;
336 :
337 : case PROPERTY_ID_XSD_PATTERN:
338 0 : nControlType = PropertyControlType::TextField;
339 0 : break;
340 :
341 : case PROPERTY_ID_XSD_LENGTH:
342 : case PROPERTY_ID_XSD_MIN_LENGTH:
343 : case PROPERTY_ID_XSD_MAX_LENGTH:
344 0 : nControlType = PropertyControlType::NumericField;
345 0 : break;
346 :
347 : case PROPERTY_ID_XSD_TOTAL_DIGITS:
348 : case PROPERTY_ID_XSD_FRACTION_DIGITS:
349 0 : nControlType = PropertyControlType::NumericField;
350 0 : break;
351 :
352 : case PROPERTY_ID_XSD_MAX_INCLUSIVE_INT:
353 : case PROPERTY_ID_XSD_MAX_EXCLUSIVE_INT:
354 : case PROPERTY_ID_XSD_MIN_INCLUSIVE_INT:
355 : case PROPERTY_ID_XSD_MIN_EXCLUSIVE_INT:
356 : {
357 0 : nControlType = PropertyControlType::NumericField;
358 :
359 : // handle limits for various 'INT' types according to
360 : // their actual semantics (year, month, day)
361 :
362 0 : ::rtl::Reference< XSDDataType > xDataType( m_pHelper->getValidatingDataType() );
363 0 : sal_Int16 nTypeClass = xDataType.is() ? xDataType->classify() : DataTypeClass::STRING;
364 :
365 0 : aMinValue.IsPresent = aMaxValue.IsPresent = sal_True;
366 0 : aMinValue.Value = DataTypeClass::gYear == nTypeClass ? 0 : 1;
367 0 : aMaxValue.Value = ::std::numeric_limits< sal_Int32 >::max();
368 0 : if ( DataTypeClass::gMonth == nTypeClass )
369 0 : aMaxValue.Value = 12;
370 0 : else if ( DataTypeClass::gDay == nTypeClass )
371 0 : aMaxValue.Value = 31;
372 : }
373 0 : break;
374 :
375 : case PROPERTY_ID_XSD_MAX_INCLUSIVE_DOUBLE:
376 : case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DOUBLE:
377 : case PROPERTY_ID_XSD_MIN_INCLUSIVE_DOUBLE:
378 : case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DOUBLE:
379 0 : nControlType = PropertyControlType::NumericField;
380 : // TODO/eForms: do we have "auto-digits"?
381 0 : break;
382 :
383 : case PROPERTY_ID_XSD_MAX_INCLUSIVE_DATE:
384 : case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DATE:
385 : case PROPERTY_ID_XSD_MIN_INCLUSIVE_DATE:
386 : case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DATE:
387 0 : nControlType = PropertyControlType::DateField;
388 0 : break;
389 :
390 : case PROPERTY_ID_XSD_MAX_INCLUSIVE_TIME:
391 : case PROPERTY_ID_XSD_MAX_EXCLUSIVE_TIME:
392 : case PROPERTY_ID_XSD_MIN_INCLUSIVE_TIME:
393 : case PROPERTY_ID_XSD_MIN_EXCLUSIVE_TIME:
394 0 : nControlType = PropertyControlType::TimeField;
395 0 : break;
396 :
397 : case PROPERTY_ID_XSD_MAX_INCLUSIVE_DATE_TIME:
398 : case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DATE_TIME:
399 : case PROPERTY_ID_XSD_MIN_INCLUSIVE_DATE_TIME:
400 : case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DATE_TIME:
401 0 : nControlType = PropertyControlType::DateTimeField;
402 0 : break;
403 :
404 : default:
405 : OSL_FAIL( "XSDValidationPropertyHandler::describePropertyLine: cannot handle this property!" );
406 0 : break;
407 : }
408 :
409 0 : switch ( nControlType )
410 : {
411 : case PropertyControlType::ListBox:
412 0 : aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
413 0 : break;
414 : case PropertyControlType::NumericField:
415 0 : aDescriptor.Control = PropertyHandlerHelper::createNumericControl( _rxControlFactory, 0, aMinValue, aMaxValue, sal_False );
416 0 : break;
417 : default:
418 0 : aDescriptor.Control = _rxControlFactory->createPropertyControl( nControlType, sal_False );
419 0 : break;
420 : }
421 :
422 0 : aDescriptor.Category = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Data" ) );
423 0 : aDescriptor.DisplayName = m_pInfoService->getPropertyTranslation( nPropId );
424 0 : aDescriptor.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( nPropId ) );
425 :
426 0 : return aDescriptor;
427 : }
428 :
429 : //--------------------------------------------------------------------
430 0 : InteractiveSelectionResult SAL_CALL XSDValidationPropertyHandler::onInteractivePropertySelection( const ::rtl::OUString& _rPropertyName, sal_Bool _bPrimary, Any& /*_rData*/, const Reference< XObjectInspectorUI >& _rxInspectorUI ) throw (UnknownPropertyException, NullPointerException, RuntimeException)
431 : {
432 0 : if ( !_rxInspectorUI.is() )
433 0 : throw NullPointerException();
434 :
435 0 : ::osl::MutexGuard aGuard( m_aMutex );
436 : OSL_ENSURE( m_pHelper.get(), "XSDValidationPropertyHandler::onInteractivePropertySelection: we don't have any SupportedProperties!" );
437 0 : if ( !m_pHelper.get() )
438 0 : return InteractiveSelectionResult_Cancelled;
439 :
440 0 : PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
441 :
442 0 : switch ( nPropId )
443 : {
444 : case PROPERTY_ID_XSD_DATA_TYPE:
445 : {
446 0 : if ( _bPrimary )
447 : {
448 0 : ::rtl::OUString sNewDataTypeName;
449 0 : if ( implPrepareCloneDataCurrentType( sNewDataTypeName ) )
450 : {
451 0 : implDoCloneCurrentDataType( sNewDataTypeName );
452 0 : return InteractiveSelectionResult_Success;
453 0 : }
454 : }
455 : else
456 0 : return implPrepareRemoveCurrentDataType() && implDoRemoveCurrentDataType() ? InteractiveSelectionResult_Success : InteractiveSelectionResult_Cancelled;
457 : }
458 0 : break;
459 :
460 : default:
461 : OSL_FAIL( "XSDValidationPropertyHandler::onInteractivePropertySelection: unexpected property to build a dedicated UI!" );
462 0 : break;
463 : }
464 0 : return InteractiveSelectionResult_Cancelled;
465 : }
466 :
467 : //--------------------------------------------------------------------
468 0 : void SAL_CALL XSDValidationPropertyHandler::addPropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
469 : {
470 0 : ::osl::MutexGuard aGuard( m_aMutex );
471 0 : XSDValidationPropertyHandler_Base::addPropertyChangeListener( _rxListener );
472 0 : if ( m_pHelper.get() )
473 0 : m_pHelper->registerBindingListener( _rxListener );
474 0 : }
475 :
476 : //--------------------------------------------------------------------
477 0 : void SAL_CALL XSDValidationPropertyHandler::removePropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
478 : {
479 0 : ::osl::MutexGuard aGuard( m_aMutex );
480 0 : if ( m_pHelper.get() )
481 0 : m_pHelper->revokeBindingListener( _rxListener );
482 0 : XSDValidationPropertyHandler_Base::removePropertyChangeListener( _rxListener );
483 0 : }
484 :
485 : //--------------------------------------------------------------------
486 0 : bool XSDValidationPropertyHandler::implPrepareCloneDataCurrentType( ::rtl::OUString& _rNewName ) SAL_THROW(())
487 : {
488 : OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implPrepareCloneDataCurrentType: this will crash!" );
489 :
490 0 : ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
491 0 : if ( !pType.is() )
492 : {
493 : OSL_FAIL( "XSDValidationPropertyHandler::implPrepareCloneDataCurrentType: invalid current data type!" );
494 0 : return false;
495 : }
496 :
497 0 : ::std::vector< ::rtl::OUString > aExistentNames;
498 0 : m_pHelper->getAvailableDataTypeNames( aExistentNames );
499 :
500 0 : NewDataTypeDialog aDialog( NULL, pType->getName(), aExistentNames ); // TODO/eForms: proper parent
501 0 : if ( aDialog.Execute() != RET_OK )
502 0 : return false;
503 :
504 0 : _rNewName = aDialog.GetName();
505 0 : return true;
506 : }
507 :
508 : //--------------------------------------------------------------------
509 0 : bool XSDValidationPropertyHandler::implDoCloneCurrentDataType( const ::rtl::OUString& _rNewName ) SAL_THROW(())
510 : {
511 : OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implDoCloneCurrentDataType: this will crash!" );
512 :
513 0 : ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
514 0 : if ( !pType.is() )
515 0 : return false;
516 :
517 0 : if ( !m_pHelper->cloneDataType( pType, _rNewName ) )
518 0 : return false;
519 :
520 0 : m_pHelper->setValidatingDataTypeByName( _rNewName );
521 0 : return true;
522 : }
523 :
524 : //--------------------------------------------------------------------
525 0 : bool XSDValidationPropertyHandler::implPrepareRemoveCurrentDataType() SAL_THROW(())
526 : {
527 : OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implPrepareRemoveCurrentDataType: this will crash!" );
528 :
529 0 : ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
530 0 : if ( !pType.is() )
531 : {
532 : OSL_FAIL( "XSDValidationPropertyHandler::implPrepareRemoveCurrentDataType: invalid current data type!" );
533 0 : return false;
534 : }
535 :
536 : // confirmation message
537 0 : String sConfirmation( PcrRes( RID_STR_CONFIRM_DELETE_DATA_TYPE ) );
538 0 : sConfirmation.SearchAndReplaceAscii( "#type#", pType->getName() );
539 0 : QueryBox aQuery( NULL, WB_YES_NO, sConfirmation ); // TODO/eForms: proper parent
540 0 : if ( aQuery.Execute() != RET_YES )
541 0 : return false;
542 :
543 0 : return true;
544 : }
545 :
546 : //--------------------------------------------------------------------
547 0 : bool XSDValidationPropertyHandler::implDoRemoveCurrentDataType() SAL_THROW(())
548 : {
549 : OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implDoRemoveCurrentDataType: this will crash!" );
550 :
551 0 : ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
552 0 : if ( !pType.is() )
553 0 : return false;
554 :
555 : // set a new data type at the binding, which is the "basic" type for the one
556 : // we are going to delete
557 : // (do this before the actual deletion, so the old type is still valid for property change
558 : // notifications)
559 0 : m_pHelper->setValidatingDataTypeByName( m_pHelper->getBasicTypeNameForClass( pType->classify() ) );
560 : // now remove the type
561 0 : m_pHelper->removeDataTypeFromRepository( pType->getName() );
562 :
563 0 : return true;
564 : }
565 :
566 : //--------------------------------------------------------------------
567 0 : void SAL_CALL XSDValidationPropertyHandler::actuatingPropertyChanged( const ::rtl::OUString& _rActuatingPropertyName, const Any& _rNewValue, const Any& _rOldValue, const Reference< XObjectInspectorUI >& _rxInspectorUI, sal_Bool _bFirstTimeInit ) throw (NullPointerException, RuntimeException)
568 : {
569 0 : if ( !_rxInspectorUI.is() )
570 0 : throw NullPointerException();
571 :
572 0 : ::osl::MutexGuard aGuard( m_aMutex );
573 0 : PropertyId nActuatingPropId( impl_getPropertyId_throw( _rActuatingPropertyName ) );
574 0 : if ( !m_pHelper.get() )
575 0 : throw RuntimeException();
576 : // if we survived impl_getPropertyId_throw, we should have a helper, since no helper implies no properties
577 :
578 0 : switch ( nActuatingPropId )
579 : {
580 : case PROPERTY_ID_XSD_DATA_TYPE:
581 : {
582 0 : ::rtl::Reference< XSDDataType > xDataType( m_pHelper->getValidatingDataType() );
583 :
584 : // is removal of this type possible?
585 0 : sal_Bool bIsBasicType = xDataType.is() && xDataType->isBasicType();
586 0 : _rxInspectorUI->enablePropertyUIElements( PROPERTY_XSD_DATA_TYPE, PropertyLineElement::PrimaryButton, xDataType.is() );
587 0 : _rxInspectorUI->enablePropertyUIElements( PROPERTY_XSD_DATA_TYPE, PropertyLineElement::SecondaryButton, xDataType.is() && !bIsBasicType );
588 :
589 : //------------------------------------------------------------
590 : // show the facets which are available at the data type
591 : ::rtl::OUString aFacets[] = {
592 : PROPERTY_XSD_WHITESPACES, PROPERTY_XSD_PATTERN,
593 : PROPERTY_XSD_LENGTH, PROPERTY_XSD_MIN_LENGTH, PROPERTY_XSD_MAX_LENGTH, PROPERTY_XSD_TOTAL_DIGITS,
594 : PROPERTY_XSD_FRACTION_DIGITS,
595 : PROPERTY_XSD_MAX_INCLUSIVE_INT,
596 : PROPERTY_XSD_MAX_EXCLUSIVE_INT,
597 : PROPERTY_XSD_MIN_INCLUSIVE_INT,
598 : PROPERTY_XSD_MIN_EXCLUSIVE_INT,
599 : PROPERTY_XSD_MAX_INCLUSIVE_DOUBLE,
600 : PROPERTY_XSD_MAX_EXCLUSIVE_DOUBLE,
601 : PROPERTY_XSD_MIN_INCLUSIVE_DOUBLE,
602 : PROPERTY_XSD_MIN_EXCLUSIVE_DOUBLE,
603 : PROPERTY_XSD_MAX_INCLUSIVE_DATE,
604 : PROPERTY_XSD_MAX_EXCLUSIVE_DATE,
605 : PROPERTY_XSD_MIN_INCLUSIVE_DATE,
606 : PROPERTY_XSD_MIN_EXCLUSIVE_DATE,
607 : PROPERTY_XSD_MAX_INCLUSIVE_TIME,
608 : PROPERTY_XSD_MAX_EXCLUSIVE_TIME,
609 : PROPERTY_XSD_MIN_INCLUSIVE_TIME,
610 : PROPERTY_XSD_MIN_EXCLUSIVE_TIME,
611 : PROPERTY_XSD_MAX_INCLUSIVE_DATE_TIME,
612 : PROPERTY_XSD_MAX_EXCLUSIVE_DATE_TIME,
613 : PROPERTY_XSD_MIN_INCLUSIVE_DATE_TIME,
614 : PROPERTY_XSD_MIN_EXCLUSIVE_DATE_TIME
615 0 : };
616 :
617 0 : size_t i=0;
618 0 : const ::rtl::OUString* pLoop = NULL;
619 0 : for ( i = 0, pLoop = aFacets;
620 : i < SAL_N_ELEMENTS( aFacets );
621 : ++i, ++pLoop
622 : )
623 : {
624 0 : showPropertyUI( _rxInspectorUI, *pLoop, xDataType.is() && xDataType->hasFacet( *pLoop ) );
625 0 : _rxInspectorUI->enablePropertyUI( *pLoop, !bIsBasicType );
626 0 : }
627 : }
628 0 : break;
629 :
630 : case PROPERTY_ID_XML_DATA_MODEL:
631 : {
632 : // The data type which the current binding works with may not be present in the
633 : // new model. Thus, transfer it.
634 0 : ::rtl::OUString sOldModelName; _rOldValue >>= sOldModelName;
635 0 : ::rtl::OUString sNewModelName; _rNewValue >>= sNewModelName;
636 0 : ::rtl::OUString sDataType = m_pHelper->getValidatingDataTypeName();
637 0 : m_pHelper->copyDataType( sOldModelName, sNewModelName, sDataType );
638 :
639 : // the list of available data types depends on the chosen model, so update this
640 0 : if ( !_bFirstTimeInit )
641 0 : _rxInspectorUI->rebuildPropertyUI( PROPERTY_XSD_DATA_TYPE );
642 : }
643 0 : break;
644 :
645 : default:
646 : OSL_FAIL( "XSDValidationPropertyHandler::actuatingPropertyChanged: cannot handle this property!" );
647 0 : return;
648 : }
649 :
650 : // in both cases, we need to care for the current value of the XSD_DATA_TYPE property,
651 : // and update the FormatKey of the formatted field we're inspecting (if any)
652 0 : if ( !_bFirstTimeInit && m_pHelper->isInspectingFormattedField() )
653 0 : m_pHelper->findDefaultFormatForIntrospectee();
654 : }
655 :
656 : //--------------------------------------------------------------------
657 0 : void XSDValidationPropertyHandler::implGetAvailableDataTypeNames( ::std::vector< ::rtl::OUString >& /* [out] */ _rNames ) const SAL_THROW(())
658 : {
659 : OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implGetAvailableDataTypeNames: this will crash!" );
660 : // start with *all* types which are available at the model
661 0 : ::std::vector< ::rtl::OUString > aAllTypes;
662 0 : m_pHelper->getAvailableDataTypeNames( aAllTypes );
663 0 : _rNames.clear();
664 0 : _rNames.reserve( aAllTypes.size() );
665 :
666 : // then allow only those which are "compatible" with our control
667 0 : for ( ::std::vector< ::rtl::OUString >::const_iterator dataType = aAllTypes.begin();
668 0 : dataType != aAllTypes.end();
669 : ++dataType
670 : )
671 : {
672 0 : ::rtl::Reference< XSDDataType > pType = m_pHelper->getDataTypeByName( *dataType );
673 0 : if ( pType.is() && m_pHelper->canBindToDataType( pType->classify() ) )
674 0 : _rNames.push_back( *dataType );
675 0 : }
676 0 : }
677 :
678 : //........................................................................
679 : } // namespace pcr
680 : //........................................................................
681 :
682 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|