summaryrefslogtreecommitdiff
path: root/extensions/source/propctrlr/xsdvalidationpropertyhandler.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/source/propctrlr/xsdvalidationpropertyhandler.cxx')
-rw-r--r--extensions/source/propctrlr/xsdvalidationpropertyhandler.cxx695
1 files changed, 695 insertions, 0 deletions
diff --git a/extensions/source/propctrlr/xsdvalidationpropertyhandler.cxx b/extensions/source/propctrlr/xsdvalidationpropertyhandler.cxx
new file mode 100644
index 000000000000..ac69955ac444
--- /dev/null
+++ b/extensions/source/propctrlr/xsdvalidationpropertyhandler.cxx
@@ -0,0 +1,695 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+#include "xsdvalidationpropertyhandler.hxx"
+#include "formstrings.hxx"
+#include "formmetadata.hxx"
+#include "xsddatatypes.hxx"
+#include "modulepcr.hxx"
+#include "formresid.hrc"
+#include "formlocalid.hrc"
+#include "propctrlr.hrc"
+#include "newdatatype.hxx"
+#include "xsdvalidationhelper.hxx"
+#include "pcrcommon.hxx"
+#include "handlerhelper.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/xsd/WhiteSpaceTreatment.hpp>
+#include <com/sun/star/xsd/DataTypeClass.hpp>
+#include <com/sun/star/inspection/PropertyControlType.hpp>
+#include <com/sun/star/beans/Optional.hpp>
+#include <com/sun/star/inspection/XObjectInspectorUI.hpp>
+#include <com/sun/star/inspection/PropertyLineElement.hpp>
+/** === end UNO includes === **/
+#include <vcl/msgbox.hxx>
+#include <tools/debug.hxx>
+#include <svtools/localresaccess.hxx>
+#include <sal/macros.h>
+
+#include <algorithm>
+#include <functional>
+#include <limits>
+
+//------------------------------------------------------------------------
+extern "C" void SAL_CALL createRegistryInfo_XSDValidationPropertyHandler()
+{
+ ::pcr::XSDValidationPropertyHandler::registerImplementation();
+}
+
+//........................................................................
+namespace pcr
+{
+//........................................................................
+
+ using namespace ::com::sun::star;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::xforms;
+ using namespace ::com::sun::star::xsd;
+ using namespace ::com::sun::star::script;
+ using namespace ::com::sun::star::inspection;
+
+ using ::com::sun::star::beans::PropertyAttribute::MAYBEVOID;
+
+ //====================================================================
+ //= XSDValidationPropertyHandler
+ //====================================================================
+ DBG_NAME( XSDValidationPropertyHandler )
+ //--------------------------------------------------------------------
+ XSDValidationPropertyHandler::XSDValidationPropertyHandler( const Reference< XComponentContext >& _rxContext )
+ :XSDValidationPropertyHandler_Base( _rxContext )
+ {
+ DBG_CTOR( XSDValidationPropertyHandler, NULL );
+ }
+
+ //--------------------------------------------------------------------
+ XSDValidationPropertyHandler::~XSDValidationPropertyHandler()
+ {
+ DBG_DTOR( XSDValidationPropertyHandler, NULL );
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL XSDValidationPropertyHandler::getImplementationName_static( ) throw (RuntimeException)
+ {
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.XSDValidationPropertyHandler" ) );
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL XSDValidationPropertyHandler::getSupportedServiceNames_static( ) throw (RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aSupported( 1 );
+ aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.inspection.XSDValidationPropertyHandler" ) );
+ return aSupported;
+ }
+
+ //--------------------------------------------------------------------
+ Any SAL_CALL XSDValidationPropertyHandler::getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
+
+ OSL_ENSURE( m_pHelper.get(), "XSDValidationPropertyHandler::getPropertyValue: inconsistency!" );
+ // if we survived impl_getPropertyId_throw, we should have a helper, since no helper implies no properties
+
+ Any aReturn;
+ ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
+ switch ( nPropId )
+ {
+ // common facets
+ case PROPERTY_ID_XSD_DATA_TYPE: aReturn = pType.is() ? pType->getFacet( PROPERTY_NAME ) : makeAny( ::rtl::OUString() ); break;
+ case PROPERTY_ID_XSD_WHITESPACES:aReturn = pType.is() ? pType->getFacet( PROPERTY_XSD_WHITESPACES ) : makeAny( WhiteSpaceTreatment::Preserve ); break;
+ case PROPERTY_ID_XSD_PATTERN: aReturn = pType.is() ? pType->getFacet( PROPERTY_XSD_PATTERN ) : makeAny( ::rtl::OUString() ); break;
+
+ // all other properties are simply forwarded, if they exist at the given type
+ default:
+ {
+ if ( pType.is() && pType->hasFacet( _rPropertyName ) )
+ aReturn = pType->getFacet( _rPropertyName );
+ }
+ break;
+ }
+
+ return aReturn;
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL XSDValidationPropertyHandler::setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw (UnknownPropertyException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
+
+ OSL_ENSURE( m_pHelper.get(), "XSDValidationPropertyHandler::getPropertyValue: inconsistency!" );
+ // if we survived impl_getPropertyId_throw, we should have a helper, since no helper implies no properties
+
+ if ( PROPERTY_ID_XSD_DATA_TYPE == nPropId )
+ {
+ ::rtl::OUString sTypeName;
+ OSL_VERIFY( _rValue >>= sTypeName );
+ m_pHelper->setValidatingDataTypeByName( sTypeName );
+ impl_setContextDocumentModified_nothrow();
+ return;
+ }
+
+ ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
+ if ( !pType.is() )
+ {
+ OSL_FAIL( "XSDValidationPropertyHandler::setPropertyValue: you're trying to set a type facet, without a current type!" );
+ return;
+ }
+
+ pType->setFacet( _rPropertyName, _rValue );
+ impl_setContextDocumentModified_nothrow();
+ }
+
+ //--------------------------------------------------------------------
+ void XSDValidationPropertyHandler::onNewComponent()
+ {
+ XSDValidationPropertyHandler_Base::onNewComponent();
+
+ Reference< frame::XModel > xDocument( impl_getContextDocument_nothrow() );
+ DBG_ASSERT( xDocument.is(), "XSDValidationPropertyHandler::onNewComponent: no document!" );
+ if ( EFormsHelper::isEForm( xDocument ) )
+ m_pHelper.reset( new XSDValidationHelper( m_aMutex, m_xComponent, xDocument ) );
+ else
+ m_pHelper.reset( NULL );
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< Property > XSDValidationPropertyHandler::doDescribeSupportedProperties() const
+ {
+ ::std::vector< Property > aProperties;
+
+ if ( m_pHelper.get() )
+ {
+ bool bAllowBinding = m_pHelper->canBindToAnyDataType();
+
+ if ( bAllowBinding )
+ {
+ aProperties.reserve( 12 );
+
+ addStringPropertyDescription( aProperties, PROPERTY_XSD_DATA_TYPE );
+ addInt16PropertyDescription ( aProperties, PROPERTY_XSD_WHITESPACES );
+ addStringPropertyDescription( aProperties, PROPERTY_XSD_PATTERN );
+
+ // string facets
+ addInt32PropertyDescription( aProperties, PROPERTY_XSD_LENGTH, MAYBEVOID );
+ addInt32PropertyDescription( aProperties, PROPERTY_XSD_MIN_LENGTH, MAYBEVOID );
+ addInt32PropertyDescription( aProperties, PROPERTY_XSD_MAX_LENGTH, MAYBEVOID );
+
+ // decimal facets
+ addInt32PropertyDescription( aProperties, PROPERTY_XSD_TOTAL_DIGITS, MAYBEVOID );
+ addInt32PropertyDescription( aProperties, PROPERTY_XSD_FRACTION_DIGITS, MAYBEVOID );
+
+ // facets for different types
+ addInt16PropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_INT, MAYBEVOID );
+ addInt16PropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_INT, MAYBEVOID );
+ addInt16PropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_INT, MAYBEVOID );
+ addInt16PropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_INT, MAYBEVOID );
+ addDoublePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_DOUBLE, MAYBEVOID );
+ addDoublePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_DOUBLE, MAYBEVOID );
+ addDoublePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_DOUBLE, MAYBEVOID );
+ addDoublePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_DOUBLE, MAYBEVOID );
+ addDatePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_DATE, MAYBEVOID );
+ addDatePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_DATE, MAYBEVOID );
+ addDatePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_DATE, MAYBEVOID );
+ addDatePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_DATE, MAYBEVOID );
+ addTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_TIME, MAYBEVOID );
+ addTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_TIME, MAYBEVOID );
+ addTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_TIME, MAYBEVOID );
+ addTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_TIME, MAYBEVOID );
+ addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_INCLUSIVE_DATE_TIME, MAYBEVOID );
+ addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MAX_EXCLUSIVE_DATE_TIME, MAYBEVOID );
+ addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_INCLUSIVE_DATE_TIME, MAYBEVOID );
+ addDateTimePropertyDescription( aProperties, PROPERTY_XSD_MIN_EXCLUSIVE_DATE_TIME, MAYBEVOID );
+ }
+ }
+
+ if ( aProperties.empty() )
+ return Sequence< Property >();
+ return Sequence< Property >( &(*aProperties.begin()), aProperties.size() );
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL XSDValidationPropertyHandler::getSupersededProperties( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ ::std::vector< ::rtl::OUString > aSuperfluous;
+ if ( m_pHelper.get() )
+ {
+ aSuperfluous.push_back( PROPERTY_CONTROLSOURCE );
+ aSuperfluous.push_back( PROPERTY_EMPTY_IS_NULL );
+ aSuperfluous.push_back( PROPERTY_FILTERPROPOSAL );
+ aSuperfluous.push_back( PROPERTY_LISTSOURCETYPE );
+ aSuperfluous.push_back( PROPERTY_LISTSOURCE );
+ aSuperfluous.push_back( PROPERTY_BOUNDCOLUMN );
+
+ bool bAllowBinding = m_pHelper->canBindToAnyDataType();
+
+ if ( bAllowBinding )
+ {
+ aSuperfluous.push_back( PROPERTY_MAXTEXTLEN );
+ aSuperfluous.push_back( PROPERTY_VALUEMIN );
+ aSuperfluous.push_back( PROPERTY_VALUEMAX );
+ aSuperfluous.push_back( PROPERTY_DECIMAL_ACCURACY );
+ aSuperfluous.push_back( PROPERTY_TIMEMIN );
+ aSuperfluous.push_back( PROPERTY_TIMEMAX );
+ aSuperfluous.push_back( PROPERTY_DATEMIN );
+ aSuperfluous.push_back( PROPERTY_DATEMAX );
+ aSuperfluous.push_back( PROPERTY_EFFECTIVE_MIN );
+ aSuperfluous.push_back( PROPERTY_EFFECTIVE_MAX );
+ }
+ }
+
+ if ( aSuperfluous.empty() )
+ return Sequence< ::rtl::OUString >();
+ return Sequence< ::rtl::OUString >( &(*aSuperfluous.begin()), aSuperfluous.size() );
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL XSDValidationPropertyHandler::getActuatingProperties( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ ::std::vector< ::rtl::OUString > aInterestedInActuations( 2 );
+ if ( m_pHelper.get() )
+ {
+ aInterestedInActuations.push_back( PROPERTY_XSD_DATA_TYPE );
+ aInterestedInActuations.push_back( PROPERTY_XML_DATA_MODEL );
+ }
+ if ( aInterestedInActuations.empty() )
+ return Sequence< ::rtl::OUString >();
+ return Sequence< ::rtl::OUString >( &(*aInterestedInActuations.begin()), aInterestedInActuations.size() );
+ }
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ void showPropertyUI( const Reference< XObjectInspectorUI >& _rxInspectorUI, const ::rtl::OUString& _rPropertyName, bool _bShow )
+ {
+ if ( _bShow )
+ _rxInspectorUI->showPropertyUI( _rPropertyName );
+ else
+ _rxInspectorUI->hidePropertyUI( _rPropertyName );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ LineDescriptor SAL_CALL XSDValidationPropertyHandler::describePropertyLine( const ::rtl::OUString& _rPropertyName,
+ const Reference< XPropertyControlFactory >& _rxControlFactory )
+ throw (UnknownPropertyException, NullPointerException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !_rxControlFactory.is() )
+ throw NullPointerException();
+ if ( !m_pHelper.get() )
+ throw RuntimeException();
+
+ PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
+
+ LineDescriptor aDescriptor;
+ if ( nPropId != PROPERTY_ID_XSD_DATA_TYPE )
+ aDescriptor.IndentLevel = 1;
+
+ // collect some information about the to-be-created control
+ sal_Int16 nControlType = PropertyControlType::TextField;
+ ::std::vector< ::rtl::OUString > aListEntries;
+ Optional< double > aMinValue( sal_False, 0 );
+ Optional< double > aMaxValue( sal_False, 0 );
+
+ switch ( nPropId )
+ {
+ case PROPERTY_ID_XSD_DATA_TYPE:
+ nControlType = PropertyControlType::ListBox;
+
+ implGetAvailableDataTypeNames( aListEntries );
+
+ aDescriptor.PrimaryButtonId = UID_PROP_ADD_DATA_TYPE;
+ aDescriptor.SecondaryButtonId = UID_PROP_REMOVE_DATA_TYPE;
+ aDescriptor.HasPrimaryButton = aDescriptor.HasSecondaryButton = sal_True;
+ aDescriptor.PrimaryButtonImageURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:graphicrepository/extensions/res/buttonplus.png" ) );
+ aDescriptor.SecondaryButtonImageURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:graphicrepository/extensions/res/buttonminus.png" ) );
+ break;
+
+ case PROPERTY_ID_XSD_WHITESPACES:
+ {
+ nControlType = PropertyControlType::ListBox;
+ aListEntries = m_pInfoService->getPropertyEnumRepresentations( PROPERTY_ID_XSD_WHITESPACES );
+ }
+ break;
+
+ case PROPERTY_ID_XSD_PATTERN:
+ nControlType = PropertyControlType::TextField;
+ break;
+
+ case PROPERTY_ID_XSD_LENGTH:
+ case PROPERTY_ID_XSD_MIN_LENGTH:
+ case PROPERTY_ID_XSD_MAX_LENGTH:
+ nControlType = PropertyControlType::NumericField;
+ break;
+
+ case PROPERTY_ID_XSD_TOTAL_DIGITS:
+ case PROPERTY_ID_XSD_FRACTION_DIGITS:
+ nControlType = PropertyControlType::NumericField;
+ break;
+
+ case PROPERTY_ID_XSD_MAX_INCLUSIVE_INT:
+ case PROPERTY_ID_XSD_MAX_EXCLUSIVE_INT:
+ case PROPERTY_ID_XSD_MIN_INCLUSIVE_INT:
+ case PROPERTY_ID_XSD_MIN_EXCLUSIVE_INT:
+ {
+ nControlType = PropertyControlType::NumericField;
+
+ // handle limits for various 'INT' types according to
+ // their actual semantics (year, month, day)
+
+ ::rtl::Reference< XSDDataType > xDataType( m_pHelper->getValidatingDataType() );
+ sal_Int16 nTypeClass = xDataType.is() ? xDataType->classify() : DataTypeClass::STRING;
+
+ aMinValue.IsPresent = aMaxValue.IsPresent = sal_True;
+ aMinValue.Value = DataTypeClass::gYear == nTypeClass ? 0 : 1;
+ aMaxValue.Value = ::std::numeric_limits< sal_Int32 >::max();
+ if ( DataTypeClass::gMonth == nTypeClass )
+ aMaxValue.Value = 12;
+ else if ( DataTypeClass::gDay == nTypeClass )
+ aMaxValue.Value = 31;
+ }
+ break;
+
+ case PROPERTY_ID_XSD_MAX_INCLUSIVE_DOUBLE:
+ case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DOUBLE:
+ case PROPERTY_ID_XSD_MIN_INCLUSIVE_DOUBLE:
+ case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DOUBLE:
+ nControlType = PropertyControlType::NumericField;
+ // TODO/eForms: do we have "auto-digits"?
+ break;
+
+ case PROPERTY_ID_XSD_MAX_INCLUSIVE_DATE:
+ case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DATE:
+ case PROPERTY_ID_XSD_MIN_INCLUSIVE_DATE:
+ case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DATE:
+ nControlType = PropertyControlType::DateField;
+ break;
+
+ case PROPERTY_ID_XSD_MAX_INCLUSIVE_TIME:
+ case PROPERTY_ID_XSD_MAX_EXCLUSIVE_TIME:
+ case PROPERTY_ID_XSD_MIN_INCLUSIVE_TIME:
+ case PROPERTY_ID_XSD_MIN_EXCLUSIVE_TIME:
+ nControlType = PropertyControlType::TimeField;
+ break;
+
+ case PROPERTY_ID_XSD_MAX_INCLUSIVE_DATE_TIME:
+ case PROPERTY_ID_XSD_MAX_EXCLUSIVE_DATE_TIME:
+ case PROPERTY_ID_XSD_MIN_INCLUSIVE_DATE_TIME:
+ case PROPERTY_ID_XSD_MIN_EXCLUSIVE_DATE_TIME:
+ nControlType = PropertyControlType::DateTimeField;
+ break;
+
+ default:
+ OSL_FAIL( "XSDValidationPropertyHandler::describePropertyLine: cannot handle this property!" );
+ break;
+ }
+
+ switch ( nControlType )
+ {
+ case PropertyControlType::ListBox:
+ aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
+ break;
+ case PropertyControlType::NumericField:
+ aDescriptor.Control = PropertyHandlerHelper::createNumericControl( _rxControlFactory, 0, aMinValue, aMaxValue, sal_False );
+ break;
+ default:
+ aDescriptor.Control = _rxControlFactory->createPropertyControl( nControlType, sal_False );
+ break;
+ }
+
+ aDescriptor.Category = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Data" ) );
+ aDescriptor.DisplayName = m_pInfoService->getPropertyTranslation( nPropId );
+ aDescriptor.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( nPropId ) );
+
+ return aDescriptor;
+ }
+
+ //--------------------------------------------------------------------
+ InteractiveSelectionResult SAL_CALL XSDValidationPropertyHandler::onInteractivePropertySelection( const ::rtl::OUString& _rPropertyName, sal_Bool _bPrimary, Any& /*_rData*/, const Reference< XObjectInspectorUI >& _rxInspectorUI ) throw (UnknownPropertyException, NullPointerException, RuntimeException)
+ {
+ if ( !_rxInspectorUI.is() )
+ throw NullPointerException();
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ OSL_ENSURE( m_pHelper.get(), "XSDValidationPropertyHandler::onInteractivePropertySelection: we don't have any SupportedProperties!" );
+ if ( !m_pHelper.get() )
+ return InteractiveSelectionResult_Cancelled;
+
+ PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
+
+ switch ( nPropId )
+ {
+ case PROPERTY_ID_XSD_DATA_TYPE:
+ {
+ if ( _bPrimary )
+ {
+ ::rtl::OUString sNewDataTypeName;
+ if ( implPrepareCloneDataCurrentType( sNewDataTypeName ) )
+ {
+ implDoCloneCurrentDataType( sNewDataTypeName );
+ return InteractiveSelectionResult_Success;
+ }
+ }
+ else
+ return implPrepareRemoveCurrentDataType() && implDoRemoveCurrentDataType() ? InteractiveSelectionResult_Success : InteractiveSelectionResult_Cancelled;
+ }
+ break;
+
+ default:
+ OSL_FAIL( "XSDValidationPropertyHandler::onInteractivePropertySelection: unexpected property to build a dedicated UI!" );
+ break;
+ }
+ return InteractiveSelectionResult_Cancelled;
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL XSDValidationPropertyHandler::addPropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ XSDValidationPropertyHandler_Base::addPropertyChangeListener( _rxListener );
+ if ( m_pHelper.get() )
+ m_pHelper->registerBindingListener( _rxListener );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL XSDValidationPropertyHandler::removePropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( m_pHelper.get() )
+ m_pHelper->revokeBindingListener( _rxListener );
+ XSDValidationPropertyHandler_Base::removePropertyChangeListener( _rxListener );
+ }
+
+ //--------------------------------------------------------------------
+ bool XSDValidationPropertyHandler::implPrepareCloneDataCurrentType( ::rtl::OUString& _rNewName ) SAL_THROW(())
+ {
+ OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implPrepareCloneDataCurrentType: this will crash!" );
+
+ ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
+ if ( !pType.is() )
+ {
+ OSL_FAIL( "XSDValidationPropertyHandler::implPrepareCloneDataCurrentType: invalid current data type!" );
+ return false;
+ }
+
+ ::std::vector< ::rtl::OUString > aExistentNames;
+ m_pHelper->getAvailableDataTypeNames( aExistentNames );
+
+ NewDataTypeDialog aDialog( NULL, pType->getName(), aExistentNames ); // TODO/eForms: proper parent
+ if ( aDialog.Execute() != RET_OK )
+ return false;
+
+ _rNewName = aDialog.GetName();
+ return true;
+ }
+
+ //--------------------------------------------------------------------
+ bool XSDValidationPropertyHandler::implDoCloneCurrentDataType( const ::rtl::OUString& _rNewName ) SAL_THROW(())
+ {
+ OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implDoCloneCurrentDataType: this will crash!" );
+
+ ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
+ if ( !pType.is() )
+ return false;
+
+ if ( !m_pHelper->cloneDataType( pType, _rNewName ) )
+ return false;
+
+ m_pHelper->setValidatingDataTypeByName( _rNewName );
+ return true;
+ }
+
+ //--------------------------------------------------------------------
+ bool XSDValidationPropertyHandler::implPrepareRemoveCurrentDataType() SAL_THROW(())
+ {
+ OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implPrepareRemoveCurrentDataType: this will crash!" );
+
+ ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
+ if ( !pType.is() )
+ {
+ OSL_FAIL( "XSDValidationPropertyHandler::implPrepareRemoveCurrentDataType: invalid current data type!" );
+ return false;
+ }
+
+ // confirmation message
+ String sConfirmation( PcrRes( RID_STR_CONFIRM_DELETE_DATA_TYPE ) );
+ sConfirmation.SearchAndReplaceAscii( "#type#", pType->getName() );
+ QueryBox aQuery( NULL, WB_YES_NO, sConfirmation ); // TODO/eForms: proper parent
+ if ( aQuery.Execute() != RET_YES )
+ return false;
+
+ return true;
+ }
+
+ //--------------------------------------------------------------------
+ bool XSDValidationPropertyHandler::implDoRemoveCurrentDataType() SAL_THROW(())
+ {
+ OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implDoRemoveCurrentDataType: this will crash!" );
+
+ ::rtl::Reference< XSDDataType > pType = m_pHelper->getValidatingDataType();
+ if ( !pType.is() )
+ return false;
+
+ // set a new data type at the binding, which is the "basic" type for the one
+ // we are going to delete
+ // (do this before the actual deletion, so the old type is still valid for property change
+ // notifications)
+ m_pHelper->setValidatingDataTypeByName( m_pHelper->getBasicTypeNameForClass( pType->classify() ) );
+ // now remove the type
+ m_pHelper->removeDataTypeFromRepository( pType->getName() );
+
+ return true;
+ }
+
+ //--------------------------------------------------------------------
+ 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)
+ {
+ if ( !_rxInspectorUI.is() )
+ throw NullPointerException();
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ PropertyId nActuatingPropId( impl_getPropertyId_throw( _rActuatingPropertyName ) );
+ if ( !m_pHelper.get() )
+ throw RuntimeException();
+ // if we survived impl_getPropertyId_throw, we should have a helper, since no helper implies no properties
+
+ switch ( nActuatingPropId )
+ {
+ case PROPERTY_ID_XSD_DATA_TYPE:
+ {
+ ::rtl::Reference< XSDDataType > xDataType( m_pHelper->getValidatingDataType() );
+
+ // is removal of this type possible?
+ sal_Bool bIsBasicType = xDataType.is() && xDataType->isBasicType();
+ _rxInspectorUI->enablePropertyUIElements( PROPERTY_XSD_DATA_TYPE, PropertyLineElement::PrimaryButton, xDataType.is() );
+ _rxInspectorUI->enablePropertyUIElements( PROPERTY_XSD_DATA_TYPE, PropertyLineElement::SecondaryButton, xDataType.is() && !bIsBasicType );
+
+ //------------------------------------------------------------
+ // show the facets which are available at the data type
+ ::rtl::OUString aFacets[] = {
+ PROPERTY_XSD_WHITESPACES, PROPERTY_XSD_PATTERN,
+ PROPERTY_XSD_LENGTH, PROPERTY_XSD_MIN_LENGTH, PROPERTY_XSD_MAX_LENGTH, PROPERTY_XSD_TOTAL_DIGITS,
+ PROPERTY_XSD_FRACTION_DIGITS,
+ PROPERTY_XSD_MAX_INCLUSIVE_INT,
+ PROPERTY_XSD_MAX_EXCLUSIVE_INT,
+ PROPERTY_XSD_MIN_INCLUSIVE_INT,
+ PROPERTY_XSD_MIN_EXCLUSIVE_INT,
+ PROPERTY_XSD_MAX_INCLUSIVE_DOUBLE,
+ PROPERTY_XSD_MAX_EXCLUSIVE_DOUBLE,
+ PROPERTY_XSD_MIN_INCLUSIVE_DOUBLE,
+ PROPERTY_XSD_MIN_EXCLUSIVE_DOUBLE,
+ PROPERTY_XSD_MAX_INCLUSIVE_DATE,
+ PROPERTY_XSD_MAX_EXCLUSIVE_DATE,
+ PROPERTY_XSD_MIN_INCLUSIVE_DATE,
+ PROPERTY_XSD_MIN_EXCLUSIVE_DATE,
+ PROPERTY_XSD_MAX_INCLUSIVE_TIME,
+ PROPERTY_XSD_MAX_EXCLUSIVE_TIME,
+ PROPERTY_XSD_MIN_INCLUSIVE_TIME,
+ PROPERTY_XSD_MIN_EXCLUSIVE_TIME,
+ PROPERTY_XSD_MAX_INCLUSIVE_DATE_TIME,
+ PROPERTY_XSD_MAX_EXCLUSIVE_DATE_TIME,
+ PROPERTY_XSD_MIN_INCLUSIVE_DATE_TIME,
+ PROPERTY_XSD_MIN_EXCLUSIVE_DATE_TIME
+ };
+
+ size_t i=0;
+ const ::rtl::OUString* pLoop = NULL;
+ for ( i = 0, pLoop = aFacets;
+ i < SAL_N_ELEMENTS( aFacets );
+ ++i, ++pLoop
+ )
+ {
+ showPropertyUI( _rxInspectorUI, *pLoop, xDataType.is() && xDataType->hasFacet( *pLoop ) );
+ _rxInspectorUI->enablePropertyUI( *pLoop, !bIsBasicType );
+ }
+ }
+ break;
+
+ case PROPERTY_ID_XML_DATA_MODEL:
+ {
+ // The data type which the current binding works with may not be present in the
+ // new model. Thus, transfer it.
+ ::rtl::OUString sOldModelName; _rOldValue >>= sOldModelName;
+ ::rtl::OUString sNewModelName; _rNewValue >>= sNewModelName;
+ ::rtl::OUString sDataType = m_pHelper->getValidatingDataTypeName();
+ m_pHelper->copyDataType( sOldModelName, sNewModelName, sDataType );
+
+ // the list of available data types depends on the chosen model, so update this
+ if ( !_bFirstTimeInit )
+ _rxInspectorUI->rebuildPropertyUI( PROPERTY_XSD_DATA_TYPE );
+ }
+ break;
+
+ default:
+ OSL_FAIL( "XSDValidationPropertyHandler::actuatingPropertyChanged: cannot handle this property!" );
+ return;
+ }
+
+ // in both cases, we need to care for the current value of the XSD_DATA_TYPE property,
+ // and update the FormatKey of the formatted field we're inspecting (if any)
+ if ( !_bFirstTimeInit && m_pHelper->isInspectingFormattedField() )
+ m_pHelper->findDefaultFormatForIntrospectee();
+ }
+
+ //--------------------------------------------------------------------
+ void XSDValidationPropertyHandler::implGetAvailableDataTypeNames( ::std::vector< ::rtl::OUString >& /* [out] */ _rNames ) const SAL_THROW(())
+ {
+ OSL_PRECOND( m_pHelper.get(), "XSDValidationPropertyHandler::implGetAvailableDataTypeNames: this will crash!" );
+ // start with *all* types which are available at the model
+ ::std::vector< ::rtl::OUString > aAllTypes;
+ m_pHelper->getAvailableDataTypeNames( aAllTypes );
+ _rNames.clear();
+ _rNames.reserve( aAllTypes.size() );
+
+ // then allow only those which are "compatible" with our control
+ for ( ::std::vector< ::rtl::OUString >::const_iterator dataType = aAllTypes.begin();
+ dataType != aAllTypes.end();
+ ++dataType
+ )
+ {
+ ::rtl::Reference< XSDDataType > pType = m_pHelper->getDataTypeByName( *dataType );
+ if ( pType.is() && m_pHelper->canBindToDataType( pType->classify() ) )
+ _rNames.push_back( *dataType );
+ }
+ }
+
+//........................................................................
+} // namespace pcr
+//........................................................................
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */