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