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