use insert function instead of for loop
[LibreOffice.git] / extensions / source / propctrlr / xsdvalidationhelper.cxx
blob5580a8ec3a4f1c453f5f8b020d370629cfdeedb5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "xsdvalidationhelper.hxx"
21 #include "xsddatatypes.hxx"
22 #include "formstrings.hxx"
24 #include <com/sun/star/lang/XServiceInfo.hpp>
25 #include <com/sun/star/xsd/DataTypeClass.hpp>
26 #include <com/sun/star/util/NumberFormat.hpp>
27 #include <com/sun/star/util/XNumberFormatTypes.hpp>
28 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
29 #include <com/sun/star/xforms/XDataTypeRepository.hpp>
30 #include <unotools/syslocale.hxx>
31 #include <i18nlangtag/languagetag.hxx>
32 #include <comphelper/diagnose_ex.hxx>
35 namespace pcr
39 using namespace ::com::sun::star;
40 using namespace ::com::sun::star::uno;
41 using namespace ::com::sun::star::beans;
42 using namespace ::com::sun::star::xsd;
43 using namespace ::com::sun::star::util;
44 using namespace ::com::sun::star::lang;
45 using namespace ::com::sun::star::xforms;
47 namespace NumberFormat = ::com::sun::star::util::NumberFormat;
50 //= XSDValidationHelper
53 XSDValidationHelper::XSDValidationHelper( ::osl::Mutex& _rMutex, const Reference< XPropertySet >& _rxIntrospectee, const Reference< frame::XModel >& _rxContextDocument )
54 :EFormsHelper( _rMutex, _rxIntrospectee, _rxContextDocument )
55 ,m_bInspectingFormattedField( false )
57 try
59 Reference< XPropertySetInfo > xPSI;
60 Reference< XServiceInfo > xSI( _rxIntrospectee, UNO_QUERY );
61 if ( m_xControlModel.is() )
62 xPSI = m_xControlModel->getPropertySetInfo();
63 if ( xPSI.is()
64 && xPSI->hasPropertyByName( PROPERTY_FORMATKEY )
65 && xPSI->hasPropertyByName( PROPERTY_FORMATSSUPPLIER )
66 && xSI.is()
67 && xSI->supportsService( SERVICE_COMPONENT_FORMATTEDFIELD )
69 m_bInspectingFormattedField = true;
71 catch( const Exception& )
73 TOOLS_WARN_EXCEPTION("extensions.propctrlr",
74 "caught an exception while examining the introspectee!");
79 void XSDValidationHelper::getAvailableDataTypeNames( std::vector< OUString >& /* [out] */ _rNames ) const
81 _rNames.resize( 0 );
83 try
85 Reference< XDataTypeRepository > xRepository = getDataTypeRepository();
86 if ( xRepository.is() )
88 const Sequence<OUString> aElements = xRepository->getElementNames();
90 _rNames.resize( aElements.getLength() );
91 std::copy( aElements.begin(), aElements.end(), _rNames.begin() );
94 catch( const Exception& )
96 TOOLS_WARN_EXCEPTION( "extensions.propctrlr", "XSDValidationHelper::getAvailableDataTypeNames" );
101 Reference< XDataTypeRepository > XSDValidationHelper::getDataTypeRepository() const
103 Reference< XDataTypeRepository > xRepository;
105 Reference< xforms::XModel > xModel( getCurrentFormModel( ) );
106 if ( xModel.is() )
107 xRepository = xModel->getDataTypeRepository();
109 return xRepository;
113 Reference< XDataTypeRepository > XSDValidationHelper::getDataTypeRepository( const OUString& _rModelName ) const
115 Reference< XDataTypeRepository > xRepository;
117 Reference< xforms::XModel > xModel( getFormModelByName( _rModelName ) );
118 if ( xModel.is() )
119 xRepository = xModel->getDataTypeRepository();
121 return xRepository;
125 Reference< XDataType > XSDValidationHelper::getDataType( const OUString& _rName ) const
127 Reference< XDataType > xDataType;
129 if ( !_rName.isEmpty() )
131 Reference< XDataTypeRepository > xRepository = getDataTypeRepository();
132 if ( xRepository.is() )
133 xDataType = xRepository->getDataType( _rName );
135 return xDataType;
139 OUString XSDValidationHelper::getValidatingDataTypeName( ) const
141 OUString sDataTypeName;
144 Reference< XPropertySet > xBinding( getCurrentBinding() );
145 // it's allowed here to not (yet) have a binding
146 if ( xBinding.is() )
148 OSL_VERIFY( xBinding->getPropertyValue( PROPERTY_XSD_DATA_TYPE ) >>= sDataTypeName );
151 catch( const Exception& )
153 TOOLS_WARN_EXCEPTION( "extensions.propctrlr", "XSDValidationHelper::getValidatingDataTypeName" );
155 return sDataTypeName;
159 ::rtl::Reference< XSDDataType > XSDValidationHelper::getDataTypeByName( const OUString& _rName ) const
161 ::rtl::Reference< XSDDataType > pReturn;
165 Reference< XDataType > xValidatedAgainst;
167 if ( !_rName.isEmpty() )
168 xValidatedAgainst = getDataType( _rName );
170 if ( xValidatedAgainst.is() )
171 pReturn = new XSDDataType( xValidatedAgainst );
173 catch( const Exception& )
175 TOOLS_WARN_EXCEPTION( "extensions.propctrlr", "XSDValidationHelper::getDataTypeByName" );
178 return pReturn;
182 ::rtl::Reference< XSDDataType > XSDValidationHelper::getValidatingDataType( ) const
184 return getDataTypeByName( getValidatingDataTypeName() );
188 bool XSDValidationHelper::cloneDataType( const ::rtl::Reference< XSDDataType >& _pDataType, const OUString& _rNewName ) const
190 OSL_ENSURE( _pDataType.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type!" );
191 if ( !_pDataType.is() )
192 return false;
196 Reference< XDataTypeRepository > xRepository( getDataTypeRepository() );
197 OSL_ENSURE( xRepository.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type repository!" );
198 if ( !xRepository.is() )
199 return false;
201 Reference< XDataType > xDataType( _pDataType->getUnoDataType() );
202 OSL_ENSURE( xDataType.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type (II)!" );
203 if ( !xDataType.is() )
204 return false;
206 xRepository->cloneDataType( xDataType->getName(), _rNewName );
208 catch( const Exception& )
210 TOOLS_WARN_EXCEPTION( "extensions.propctrlr", "XSDValidationHelper::cloneDataType" );
212 return true;
216 bool XSDValidationHelper::removeDataTypeFromRepository( const OUString& _rName ) const
220 Reference< XDataTypeRepository > xRepository( getDataTypeRepository() );
221 OSL_ENSURE( xRepository.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type repository!" );
222 if ( !xRepository.is() )
223 return false;
225 if ( !xRepository->hasByName( _rName ) )
227 OSL_FAIL( "XSDValidationHelper::removeDataTypeFromRepository: invalid repository and/or data type!" );
228 return false;
231 xRepository->revokeDataType( _rName );
233 catch( const Exception& )
235 TOOLS_WARN_EXCEPTION( "extensions.propctrlr", "XSDValidationHelper::removeDataTypeFromRepository" );
236 return false;
238 return true;
242 void XSDValidationHelper::setValidatingDataTypeByName( const OUString& _rName ) const
246 Reference< XPropertySet > xBinding( getCurrentBinding() );
247 OSL_ENSURE( xBinding.is(), "XSDValidationHelper::setValidatingDataTypeByName: no active binding - how this?" );
249 if ( xBinding.is() )
251 // get the old data type - this is necessary for notifying property changes
252 OUString sOldDataTypeName;
253 OSL_VERIFY( xBinding->getPropertyValue( PROPERTY_XSD_DATA_TYPE ) >>= sOldDataTypeName );
254 Reference< XPropertySet > xOldType;
255 try {
256 xOldType = getDataType( sOldDataTypeName );
257 } catch( const Exception& ) { }
259 // set the new data type name
260 xBinding->setPropertyValue( PROPERTY_XSD_DATA_TYPE, Any( _rName ) );
262 // retrieve the new data type object
263 Reference< XPropertySet > xNewType = getDataType( _rName );
265 // fire any changes in the properties which result from this new type
266 std::set< OUString > aFilter; aFilter.insert( PROPERTY_NAME );
267 firePropertyChanges( xOldType, xNewType, aFilter );
269 // fire the change in the Data Type property
270 OUString sNewDataTypeName;
271 OSL_VERIFY( xBinding->getPropertyValue( PROPERTY_XSD_DATA_TYPE ) >>= sNewDataTypeName );
272 firePropertyChange( PROPERTY_XSD_DATA_TYPE, Any( sOldDataTypeName ), Any( sNewDataTypeName ) );
275 catch( const Exception& )
277 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
282 void XSDValidationHelper::copyDataType( const OUString& _rFromModel, const OUString& _rToModel,
283 const OUString& _rDataTypeName ) const
285 if ( _rFromModel == _rToModel )
286 // nothing to do (me thinks)
287 return;
291 Reference< XDataTypeRepository > xFromRepository, xToRepository;
292 if ( !_rFromModel.isEmpty() )
293 xFromRepository = getDataTypeRepository( _rFromModel );
294 if ( !_rToModel.isEmpty() )
295 xToRepository = getDataTypeRepository( _rToModel );
297 if ( !xFromRepository.is() || !xToRepository.is() )
298 return;
300 if ( !xFromRepository->hasByName( _rDataTypeName ) || xToRepository->hasByName( _rDataTypeName ) )
301 // not existent in the source, or already existent (by name) in the destination
302 return;
304 // determine the built-in type belonging to the source type
305 ::rtl::Reference< XSDDataType > pSourceType = new XSDDataType( xFromRepository->getDataType( _rDataTypeName ) );
306 OUString sTargetBaseType = getBasicTypeNameForClass( pSourceType->classify(), xToRepository );
308 // create the target type
309 Reference< XDataType > xTargetType = xToRepository->cloneDataType( sTargetBaseType, _rDataTypeName );
310 ::rtl::Reference< XSDDataType > pTargetType = new XSDDataType( xTargetType );
312 // copy the facets
313 pTargetType->copyFacetsFrom( pSourceType );
315 catch( const Exception& )
317 TOOLS_WARN_EXCEPTION( "extensions.propctrlr", "XSDValidationHelper::copyDataType" );
322 void XSDValidationHelper::findDefaultFormatForIntrospectee()
326 ::rtl::Reference< XSDDataType > xDataType = getValidatingDataType();
327 if ( xDataType.is() )
329 // find a NumberFormat type corresponding to the DataTypeClass
330 sal_Int16 nNumberFormatType = NumberFormat::NUMBER;
331 switch ( xDataType->classify() )
333 case DataTypeClass::DATETIME:
334 nNumberFormatType = NumberFormat::DATETIME;
335 break;
336 case DataTypeClass::DATE:
337 nNumberFormatType = NumberFormat::DATE;
338 break;
339 case DataTypeClass::TIME:
340 nNumberFormatType = NumberFormat::TIME;
341 break;
342 case DataTypeClass::STRING:
343 case DataTypeClass::anyURI:
344 case DataTypeClass::QName:
345 case DataTypeClass::NOTATION:
346 nNumberFormatType = NumberFormat::TEXT;
347 break;
350 // get the number formatter from the introspectee
351 Reference< XNumberFormatsSupplier > xSupplier;
352 Reference< XNumberFormatTypes > xFormatTypes;
353 OSL_VERIFY( m_xControlModel->getPropertyValue( PROPERTY_FORMATSSUPPLIER ) >>= xSupplier );
354 if ( xSupplier.is() )
355 xFormatTypes.set(xSupplier->getNumberFormats(), css::uno::UNO_QUERY);
356 OSL_ENSURE( xFormatTypes.is(), "XSDValidationHelper::findDefaultFormatForIntrospectee: no number formats for the introspectee!" );
357 if ( !xFormatTypes.is() )
358 return;
360 // and the standard format for the given NumberFormat type
361 sal_Int32 nDesiredFormat = xFormatTypes->getStandardFormat( nNumberFormatType, SvtSysLocale().GetLanguageTag().getLocale() );
363 // set this at the introspectee
364 m_xControlModel->setPropertyValue( PROPERTY_FORMATKEY, Any( nDesiredFormat ) );
367 catch( const Exception& )
369 TOOLS_WARN_EXCEPTION( "extensions.propctrlr", "XSDValidationHelper::findDefaultFormatForIntrospectee" );
374 OUString XSDValidationHelper::getBasicTypeNameForClass( sal_Int16 _nClass ) const
376 return getBasicTypeNameForClass( _nClass, getDataTypeRepository() );
380 OUString XSDValidationHelper::getBasicTypeNameForClass( sal_Int16 _nClass, const Reference< XDataTypeRepository >& _rxRepository )
382 OUString sReturn;
383 OSL_ENSURE( _rxRepository.is(), "XSDValidationHelper::getBasicTypeNameForClass: invalid repository!" );
384 if ( !_rxRepository.is() )
385 return sReturn;
389 Reference< XDataType > xDataType = _rxRepository->getBasicDataType( _nClass );
390 OSL_ENSURE( xDataType.is(), "XSDValidationHelper::getBasicTypeNameForClass: invalid data type returned!" );
391 if ( xDataType.is() )
392 sReturn = xDataType->getName();
394 catch( const Exception& )
396 TOOLS_WARN_EXCEPTION( "extensions.propctrlr", "XSDValidationHelper::getBasicTypeNameForClass" );
399 return sReturn;
403 } // namespace pcr
406 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */