merged tag LIBREOFFICE_3_2_99_3
[LibreOffice.git] / extensions / source / propctrlr / xsdvalidationhelper.cxx
blob7e6440ae5a8c2f08a1b0ce83d6a27befa280967f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
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.
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).
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.
27 ************************************************************************/
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_extensions.hxx"
31 #include "xsdvalidationhelper.hxx"
32 #include "xsddatatypes.hxx"
33 #include "formstrings.hxx"
35 /** === begin UNO includes === **/
36 #include <com/sun/star/lang/XServiceInfo.hpp>
37 #include <com/sun/star/xsd/DataTypeClass.hpp>
38 #include <com/sun/star/util/NumberFormat.hpp>
39 #include <com/sun/star/util/XNumberFormatTypes.hpp>
40 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
41 #include <com/sun/star/xforms/XDataTypeRepository.hpp>
42 /** === end UNO includes === **/
43 #include <unotools/syslocale.hxx>
44 #include <tools/diagnose_ex.h>
46 //........................................................................
47 namespace pcr
49 //........................................................................
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::beans;
54 using namespace ::com::sun::star::xsd;
55 using namespace ::com::sun::star::util;
56 using namespace ::com::sun::star::lang;
57 using namespace ::com::sun::star::xforms;
59 namespace NumberFormat = ::com::sun::star::util::NumberFormat;
61 //====================================================================
62 //= XSDValidationHelper
63 //====================================================================
64 //--------------------------------------------------------------------
65 XSDValidationHelper::XSDValidationHelper( ::osl::Mutex& _rMutex, const Reference< XPropertySet >& _rxIntrospectee, const Reference< frame::XModel >& _rxContextDocument )
66 :EFormsHelper( _rMutex, _rxIntrospectee, _rxContextDocument )
67 ,m_bInspectingFormattedField( false )
69 try
71 Reference< XPropertySetInfo > xPSI;
72 Reference< XServiceInfo > xSI( _rxIntrospectee, UNO_QUERY );
73 if ( m_xControlModel.is() )
74 xPSI = m_xControlModel->getPropertySetInfo();
75 if ( xPSI.is()
76 && xPSI->hasPropertyByName( PROPERTY_FORMATKEY )
77 && xPSI->hasPropertyByName( PROPERTY_FORMATSSUPPLIER )
78 && xSI.is()
79 && xSI->supportsService( SERVICE_COMPONENT_FORMATTEDFIELD )
81 m_bInspectingFormattedField = true;
83 catch( const Exception& )
85 OSL_ENSURE( sal_False, "XSDValidationHelper::XSDValidationHelper: caught an exception while examining the introspectee!" );
89 //--------------------------------------------------------------------
90 void XSDValidationHelper::getAvailableDataTypeNames( ::std::vector< ::rtl::OUString >& /* [out] */ _rNames ) const SAL_THROW(())
92 _rNames.resize( 0 );
94 try
96 Reference< XDataTypeRepository > xRepository = getDataTypeRepository();
97 Sequence< ::rtl::OUString > aElements;
98 if ( xRepository.is() )
99 aElements = xRepository->getElementNames();
101 _rNames.resize( aElements.getLength() );
102 ::std::copy( aElements.getConstArray(), aElements.getConstArray() + aElements.getLength(), _rNames.begin() );
104 catch( const Exception& )
106 OSL_ENSURE( sal_False, "XSDValidationHelper::getAvailableDataTypeNames: caught an exception!" );
110 //--------------------------------------------------------------------
111 Reference< XDataTypeRepository > XSDValidationHelper::getDataTypeRepository() const SAL_THROW((Exception))
113 Reference< XDataTypeRepository > xRepository;
115 Reference< xforms::XModel > xModel( getCurrentFormModel( ) );
116 if ( xModel.is() )
117 xRepository = xModel->getDataTypeRepository();
119 return xRepository;
122 //--------------------------------------------------------------------
123 Reference< XDataTypeRepository > XSDValidationHelper::getDataTypeRepository( const ::rtl::OUString& _rModelName ) const SAL_THROW((Exception))
125 Reference< XDataTypeRepository > xRepository;
127 Reference< xforms::XModel > xModel( getFormModelByName( _rModelName ) );
128 if ( xModel.is() )
129 xRepository = xModel->getDataTypeRepository();
131 return xRepository;
134 //--------------------------------------------------------------------
135 Reference< XDataType > XSDValidationHelper::getDataType( const ::rtl::OUString& _rName ) const SAL_THROW((Exception))
137 Reference< XDataType > xDataType;
139 if ( _rName.getLength() )
141 Reference< XDataTypeRepository > xRepository = getDataTypeRepository();
142 if ( xRepository.is() )
143 xDataType = xRepository->getDataType( _rName );
145 return xDataType;
148 //--------------------------------------------------------------------
149 ::rtl::OUString XSDValidationHelper::getValidatingDataTypeName( ) const SAL_THROW(())
151 ::rtl::OUString sDataTypeName;
154 Reference< XPropertySet > xBinding( getCurrentBinding() );
155 // it's allowed here to not (yet) have a binding
156 if ( xBinding.is() )
158 OSL_VERIFY( xBinding->getPropertyValue( PROPERTY_XSD_DATA_TYPE ) >>= sDataTypeName );
161 catch( const Exception& )
163 OSL_ENSURE( sal_False, "XSDValidationHelper::getValidatingDataTypeName: caught an exception!" );
165 return sDataTypeName;
168 //--------------------------------------------------------------------
169 ::rtl::Reference< XSDDataType > XSDValidationHelper::getDataTypeByName( const ::rtl::OUString& _rName ) const SAL_THROW(())
171 ::rtl::Reference< XSDDataType > pReturn;
175 Reference< XDataType > xValidatedAgainst;
177 if ( _rName.getLength() )
178 xValidatedAgainst = getDataType( _rName );
180 if ( xValidatedAgainst.is() )
181 pReturn = new XSDDataType( xValidatedAgainst );
183 catch( const Exception& )
185 OSL_ENSURE( sal_False, "XSDValidationHelper::getDataTypeByName: caught an exception!" );
188 return pReturn;
191 //--------------------------------------------------------------------
192 ::rtl::Reference< XSDDataType > XSDValidationHelper::getValidatingDataType( ) const SAL_THROW(())
194 return getDataTypeByName( getValidatingDataTypeName() );
197 //--------------------------------------------------------------------
198 bool XSDValidationHelper::cloneDataType( const ::rtl::Reference< XSDDataType >& _pDataType, const ::rtl::OUString& _rNewName ) const SAL_THROW(())
200 OSL_ENSURE( _pDataType.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type!" );
201 if ( !_pDataType.is() )
202 return false;
206 Reference< XDataTypeRepository > xRepository( getDataTypeRepository() );
207 OSL_ENSURE( xRepository.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type repository!" );
208 if ( !xRepository.is() )
209 return false;
211 Reference< XDataType > xDataType( _pDataType->getUnoDataType() );
212 OSL_ENSURE( xDataType.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type (II)!" );
213 if ( !xDataType.is() )
214 return false;
216 xRepository->cloneDataType( xDataType->getName(), _rNewName );
218 catch( const Exception& )
220 OSL_ENSURE( sal_False, "XSDValidationHelper::cloneDataType: caught an exception!" );
222 return true;
225 //--------------------------------------------------------------------
226 bool XSDValidationHelper::removeDataTypeFromRepository( const ::rtl::OUString& _rName ) const SAL_THROW(())
230 Reference< XDataTypeRepository > xRepository( getDataTypeRepository() );
231 OSL_ENSURE( xRepository.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type repository!" );
232 if ( !xRepository.is() )
233 return false;
235 if ( !xRepository->hasByName( _rName ) )
237 OSL_ENSURE( sal_False, "XSDValidationHelper::removeDataTypeFromRepository: invalid repository and/or data type!" );
238 return false;
241 xRepository->revokeDataType( _rName );
243 catch( const Exception& )
245 OSL_ENSURE( sal_False, "XSDValidationHelper::removeDataTypeFromRepository: caught an exception!" );
246 return false;
248 return true;
251 //--------------------------------------------------------------------
252 void XSDValidationHelper::setValidatingDataTypeByName( const ::rtl::OUString& _rName ) const SAL_THROW(())
256 Reference< XPropertySet > xBinding( getCurrentBinding() );
257 OSL_ENSURE( xBinding.is(), "XSDValidationHelper::setValidatingDataTypeByName: no active binding - how this?" );
259 if ( xBinding.is() )
261 // get the old data type - this is necessary for notifying property changes
262 ::rtl::OUString sOldDataTypeName;
263 OSL_VERIFY( xBinding->getPropertyValue( PROPERTY_XSD_DATA_TYPE ) >>= sOldDataTypeName );
264 Reference< XPropertySet > xOldType;
265 try { xOldType = xOldType.query( getDataType( sOldDataTypeName ) ); } catch( const Exception& ) { }
267 // set the new data type name
268 xBinding->setPropertyValue( PROPERTY_XSD_DATA_TYPE, makeAny( _rName ) );
270 // retrieve the new data type object
271 Reference< XPropertySet > xNewType( getDataType( _rName ), UNO_QUERY );
273 // fire any changes in the properties which result from this new type
274 std::set< ::rtl::OUString > aFilter; aFilter.insert( PROPERTY_NAME );
275 firePropertyChanges( xOldType, xNewType, aFilter );
277 // fire the change in the Data Type property
278 ::rtl::OUString sNewDataTypeName;
279 OSL_VERIFY( xBinding->getPropertyValue( PROPERTY_XSD_DATA_TYPE ) >>= sNewDataTypeName );
280 firePropertyChange( PROPERTY_XSD_DATA_TYPE, makeAny( sOldDataTypeName ), makeAny( sNewDataTypeName ) );
283 catch( const Exception& )
285 DBG_UNHANDLED_EXCEPTION();
289 //--------------------------------------------------------------------
290 void XSDValidationHelper::copyDataType( const ::rtl::OUString& _rFromModel, const ::rtl::OUString& _rToModel,
291 const ::rtl::OUString& _rDataTypeName ) const SAL_THROW(())
293 if ( _rFromModel == _rToModel )
294 // nothing to do (me thinks)
295 return;
299 Reference< XDataTypeRepository > xFromRepository, xToRepository;
300 if ( _rFromModel.getLength() )
301 xFromRepository = getDataTypeRepository( _rFromModel );
302 if ( _rToModel.getLength() )
303 xToRepository = getDataTypeRepository( _rToModel );
305 if ( !xFromRepository.is() || !xToRepository.is() )
306 return;
308 if ( !xFromRepository->hasByName( _rDataTypeName ) || xToRepository->hasByName( _rDataTypeName ) )
309 // not existent in the source, or already existent (by name) in the destination
310 return;
312 // determine the built-in type belonging to the source type
313 ::rtl::Reference< XSDDataType > pSourceType = new XSDDataType( xFromRepository->getDataType( _rDataTypeName ) );
314 ::rtl::OUString sTargetBaseType = getBasicTypeNameForClass( pSourceType->classify(), xToRepository );
316 // create the target type
317 Reference< XDataType > xTargetType = xToRepository->cloneDataType( sTargetBaseType, _rDataTypeName );
318 ::rtl::Reference< XSDDataType > pTargetType = new XSDDataType( xTargetType );
320 // copy the facets
321 pTargetType->copyFacetsFrom( pSourceType );
323 catch( const Exception& )
325 OSL_ENSURE( sal_False, "XSDValidationHelper::copyDataType: caught an exception!" );
329 //--------------------------------------------------------------------
330 void XSDValidationHelper::findDefaultFormatForIntrospectee() SAL_THROW(())
334 ::rtl::Reference< XSDDataType > xDataType = getValidatingDataType();
335 if ( xDataType.is() )
337 // find a NumberFormat type corresponding to the DataTypeClass
338 sal_Int16 nNumberFormatType = NumberFormat::NUMBER;
339 switch ( xDataType->classify() )
341 case DataTypeClass::DATETIME:
342 nNumberFormatType = NumberFormat::DATETIME;
343 break;
344 case DataTypeClass::DATE:
345 nNumberFormatType = NumberFormat::DATE;
346 break;
347 case DataTypeClass::TIME:
348 nNumberFormatType = NumberFormat::TIME;
349 break;
350 case DataTypeClass::STRING:
351 case DataTypeClass::anyURI:
352 case DataTypeClass::QName:
353 case DataTypeClass::NOTATION:
354 nNumberFormatType = NumberFormat::TEXT;
355 break;
358 // get the number formatter from the introspectee
359 Reference< XNumberFormatsSupplier > xSupplier;
360 Reference< XNumberFormatTypes > xFormatTypes;
361 OSL_VERIFY( m_xControlModel->getPropertyValue( PROPERTY_FORMATSSUPPLIER ) >>= xSupplier );
362 if ( xSupplier.is() )
363 xFormatTypes = xFormatTypes.query( xSupplier->getNumberFormats() );
364 OSL_ENSURE( xFormatTypes.is(), "XSDValidationHelper::findDefaultFormatForIntrospectee: no number formats for the introspectee!" );
365 if ( !xFormatTypes.is() )
366 return;
368 // and the standard format for the given NumberFormat type
369 sal_Int32 nDesiredFormat = xFormatTypes->getStandardFormat( nNumberFormatType, SvtSysLocale().GetLocaleData().getLocale() );
371 // set this at the introspectee
372 m_xControlModel->setPropertyValue( PROPERTY_FORMATKEY, makeAny( nDesiredFormat ) );
375 catch( const Exception& )
377 OSL_ENSURE( sal_False, "XSDValidationHelper::findDefaultFormatForIntrospectee: caught an exception!" );
381 //--------------------------------------------------------------------
382 ::rtl::OUString XSDValidationHelper::getBasicTypeNameForClass( sal_Int16 _nClass ) const SAL_THROW(())
384 return getBasicTypeNameForClass( _nClass, getDataTypeRepository() );
387 //--------------------------------------------------------------------
388 ::rtl::OUString XSDValidationHelper::getBasicTypeNameForClass( sal_Int16 _nClass, Reference< XDataTypeRepository > _rxRepository ) const SAL_THROW(())
390 ::rtl::OUString sReturn;
391 OSL_ENSURE( _rxRepository.is(), "XSDValidationHelper::getBasicTypeNameForClass: invalid repository!" );
392 if ( !_rxRepository.is() )
393 return sReturn;
397 Reference< XDataType > xDataType = _rxRepository->getBasicDataType( _nClass );
398 OSL_ENSURE( xDataType.is(), "XSDValidationHelper::getBasicTypeNameForClass: invalid data type returned!" );
399 if ( xDataType.is() )
400 sReturn = xDataType->getName();
402 catch( const Exception& )
404 OSL_ENSURE( sal_False, "XSDValidationHelper::getBasicTypeNameForClass: caught an exception!" );
407 return sReturn;
410 //........................................................................
411 } // namespace pcr
412 //........................................................................
414 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */