| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_svx.hxx" |
| |
| #include "svx/dbtoolsclient.hxx" |
| #include "formcontrolfactory.hxx" |
| #include "fmcontrollayout.hxx" |
| #include "fmprop.hrc" |
| #include "svx/fmresids.hrc" |
| #include "fmservs.hxx" |
| #include "svx/dialmgr.hxx" |
| #include "svx/svdouno.hxx" |
| |
| /** === begin UNO includes === **/ |
| #include <com/sun/star/form/XFormComponent.hpp> |
| #include <com/sun/star/form/FormComponentType.hpp> |
| #include <com/sun/star/awt/ScrollBarOrientation.hpp> |
| #include <com/sun/star/awt/MouseWheelBehavior.hpp> |
| #include <com/sun/star/form/XGridColumnFactory.hpp> |
| #include <com/sun/star/style/VerticalAlignment.hpp> |
| #include <com/sun/star/awt/LineEndFormat.hpp> |
| #include <com/sun/star/awt/ImageScaleMode.hpp> |
| #include <com/sun/star/sdbc/DataType.hpp> |
| #include <com/sun/star/util/XNumberFormatTypes.hpp> |
| #include <com/sun/star/sdbc/ColumnValue.hpp> |
| #include <com/sun/star/text/WritingMode2.hpp> |
| #include <com/sun/star/awt/FontDescriptor.hpp> |
| /** === end UNO includes === **/ |
| |
| #include <comphelper/componentcontext.hxx> |
| #include <comphelper/numbers.hxx> |
| #include <unotools/syslocale.hxx> |
| #include <tools/gen.hxx> |
| #include <tools/diagnose_ex.h> |
| |
| #include <set> |
| |
| //........................................................................ |
| namespace svxform |
| { |
| //........................................................................ |
| |
| /** === begin UNO using === **/ |
| using ::com::sun::star::uno::Reference; |
| using ::com::sun::star::uno::XInterface; |
| using ::com::sun::star::uno::UNO_QUERY; |
| using ::com::sun::star::uno::UNO_QUERY_THROW; |
| using ::com::sun::star::uno::UNO_SET_THROW; |
| using ::com::sun::star::uno::Exception; |
| using ::com::sun::star::uno::RuntimeException; |
| using ::com::sun::star::uno::Any; |
| using ::com::sun::star::uno::makeAny; |
| using ::com::sun::star::uno::Sequence; |
| using ::com::sun::star::uno::Type; |
| using ::com::sun::star::beans::XPropertySet; |
| using ::com::sun::star::awt::XControlModel; |
| using ::com::sun::star::form::XFormComponent; |
| using ::com::sun::star::container::XIndexAccess; |
| using ::com::sun::star::beans::XPropertySetInfo; |
| using ::com::sun::star::beans::PropertyValue; |
| using ::com::sun::star::container::XChild; |
| using ::com::sun::star::form::XGridColumnFactory; |
| using ::com::sun::star::style::VerticalAlignment_MIDDLE; |
| using ::com::sun::star::beans::Property; |
| using ::com::sun::star::uno::TypeClass_DOUBLE; |
| using ::com::sun::star::uno::TypeClass_LONG; |
| using ::com::sun::star::util::XNumberFormats; |
| using ::com::sun::star::util::XNumberFormatTypes; |
| using ::com::sun::star::awt::FontDescriptor; |
| using ::com::sun::star::lang::Locale; |
| using ::com::sun::star::lang::XServiceInfo; |
| using ::com::sun::star::container::XNameAccess; |
| /** === end UNO using === **/ |
| namespace FormComponentType = ::com::sun::star::form::FormComponentType; |
| namespace ScrollBarOrientation = ::com::sun::star::awt::ScrollBarOrientation; |
| namespace MouseWheelBehavior = ::com::sun::star::awt::MouseWheelBehavior; |
| namespace LineEndFormat = ::com::sun::star::awt::LineEndFormat; |
| namespace ImageScaleMode = ::com::sun::star::awt::ImageScaleMode; |
| namespace DataType = ::com::sun::star::sdbc::DataType; |
| namespace ColumnValue = ::com::sun::star::sdbc::ColumnValue; |
| namespace WritingMode2 = ::com::sun::star::text::WritingMode2; |
| |
| //==================================================================== |
| //= FormControlFactory_Data |
| //==================================================================== |
| struct FormControlFactory_Data |
| { |
| ::comphelper::ComponentContext m_aContext; |
| |
| FormControlFactory_Data( const ::comphelper::ComponentContext& _rContext ) |
| :m_aContext( _rContext ) |
| { |
| } |
| }; |
| |
| //==================================================================== |
| //= FormControlFactory |
| //==================================================================== |
| //-------------------------------------------------------------------- |
| FormControlFactory::FormControlFactory( const ::comphelper::ComponentContext& _rContext ) |
| :m_pData( new FormControlFactory_Data( _rContext ) ) |
| { |
| } |
| |
| //-------------------------------------------------------------------- |
| FormControlFactory::~FormControlFactory() |
| { |
| } |
| |
| //-------------------------------------------------------------------- |
| sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const SdrUnoObj& _rObject ) |
| { |
| return initializeControlModel( |
| _eDocType, |
| Reference< XPropertySet >( _rObject.GetUnoControlModel(), UNO_QUERY ), |
| _rObject.GetCurrentBoundRect() |
| ); |
| } |
| |
| //-------------------------------------------------------------------- |
| sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const Reference< XPropertySet >& _rxControlModel ) |
| { |
| return initializeControlModel( |
| _eDocType, _rxControlModel, Rectangle() |
| ); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| namespace |
| { |
| //.................................................................... |
| static ::rtl::OUString lcl_getUniqueLabel_nothrow( const Reference< XPropertySet >& _rxControlModel, const ::rtl::OUString& _rBaseLabel ) |
| { |
| ::rtl::OUString sLabel( _rBaseLabel ); |
| try |
| { |
| typedef ::std::set< ::rtl::OUString > StringBag; |
| StringBag aUsedLabels; |
| |
| Reference< XFormComponent > xFormComponent( _rxControlModel, UNO_QUERY_THROW ); |
| Reference< XIndexAccess > xContainer( xFormComponent->getParent(), UNO_QUERY_THROW ); |
| // loop through all siblings of the control model, and collect their labels |
| for ( sal_Int32 index=xContainer->getCount(); index>0; ) |
| { |
| Reference< XPropertySet > xElement( xContainer->getByIndex( --index ), UNO_QUERY_THROW ); |
| if ( xElement == _rxControlModel ) |
| continue; |
| |
| Reference< XPropertySetInfo > xPSI( xElement->getPropertySetInfo(), UNO_SET_THROW ); |
| if ( !xPSI->hasPropertyByName( FM_PROP_LABEL ) ) |
| continue; |
| |
| ::rtl::OUString sElementLabel; |
| OSL_VERIFY( xElement->getPropertyValue( FM_PROP_LABEL ) >>= sElementLabel ); |
| aUsedLabels.insert( sElementLabel ); |
| } |
| |
| // now find a free label |
| sal_Int32 i=2; |
| while ( aUsedLabels.find( sLabel ) != aUsedLabels.end() ) |
| { |
| ::rtl::OUStringBuffer aBuffer( _rBaseLabel ); |
| aBuffer.appendAscii( " " ); |
| aBuffer.append( (sal_Int32)i++ ); |
| sLabel = aBuffer.makeStringAndClear(); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| return sLabel; |
| } |
| |
| //.................................................................... |
| static Sequence< PropertyValue > lcl_getDataSourceIndirectProperties( const Reference< XPropertySet >& _rxControlModel, |
| const ::comphelper::ComponentContext& _rContext ) |
| { |
| OSL_PRECOND( _rxControlModel.is(), "lcl_getDataSourceIndirectProperties: invalid model!" ); |
| |
| Sequence< PropertyValue > aInfo; |
| try |
| { |
| Reference< XChild > xChild( _rxControlModel, UNO_QUERY ); |
| Reference< XPropertySet > xForm; |
| if ( xChild.is() ) |
| xForm = xForm.query( xChild->getParent() ); |
| |
| if ( Reference< XGridColumnFactory >( xForm, UNO_QUERY ).is() ) |
| { // hmm. the model is a grid column, in real |
| xChild = xChild.query( xForm ); |
| xForm = xForm.query( xChild->getParent() ); |
| } |
| |
| OSL_ENSURE( xForm.is(), "lcl_getDataSourceIndirectProperties: could not determine the form!" ); |
| if ( !xForm.is() ) |
| return aInfo; |
| ::rtl::OUString sDataSourceName; |
| xForm->getPropertyValue( FM_PROP_DATASOURCE ) >>= sDataSourceName; |
| |
| Reference< XPropertySet > xDsProperties; |
| if ( sDataSourceName.getLength() ) |
| xDsProperties = xDsProperties.query( OStaticDataAccessTools().getDataSource( sDataSourceName, _rContext.getLegacyServiceFactory() ) ); |
| if ( xDsProperties.is() ) |
| xDsProperties->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Info" ) ) ) >>= aInfo; |
| } |
| catch( const Exception& ) |
| { |
| OSL_ENSURE( sal_False, "lcl_getDataSourceIndirectProperties: caught an exception!" ); |
| } |
| return aInfo; |
| } |
| |
| //.................................................................... |
| static const sal_Char* aCharacterAndParagraphProperties[] = |
| { |
| "CharFontName", |
| "CharFontStyleName", |
| "CharFontFamily", |
| "CharFontCharSet", |
| "CharFontPitch", |
| "CharColor", |
| "CharEscapement", |
| "CharHeight", |
| "CharUnderline", |
| "CharWeight", |
| "CharPosture", |
| "CharAutoKerning", |
| "CharBackColor", |
| "CharBackTransparent", |
| "CharCaseMap", |
| "CharCrossedOut", |
| "CharFlash", |
| "CharStrikeout", |
| "CharWordMode", |
| "CharKerning", |
| "CharLocale", |
| "CharKeepTogether", |
| "CharNoLineBreak", |
| "CharShadowed", |
| "CharFontType", |
| "CharStyleName", |
| "CharContoured", |
| "CharCombineIsOn", |
| "CharCombinePrefix", |
| "CharCombineSuffix", |
| "CharEmphasize", |
| "CharRelief", |
| "RubyText", |
| "RubyAdjust", |
| "RubyCharStyleName", |
| "RubyIsAbove", |
| "CharRotation", |
| "CharRotationIsFitToLine", |
| "CharScaleWidth", |
| "HyperLinkURL", |
| "HyperLinkTarget", |
| "HyperLinkName", |
| "VisitedCharStyleName", |
| "UnvisitedCharStyleName", |
| "CharEscapementHeight", |
| "CharNoHyphenation", |
| "CharUnderlineColor", |
| "CharUnderlineHasColor", |
| "CharStyleNames", |
| "CharHeightAsian", |
| "CharWeightAsian", |
| "CharFontNameAsian", |
| "CharFontStyleNameAsian", |
| "CharFontFamilyAsian", |
| "CharFontCharSetAsian", |
| "CharFontPitchAsian", |
| "CharPostureAsian", |
| "CharLocaleAsian", |
| "ParaIsCharacterDistance", |
| "ParaIsForbiddenRules", |
| "ParaIsHangingPunctuation", |
| "CharHeightComplex", |
| "CharWeightComplex", |
| "CharFontNameComplex", |
| "CharFontStyleNameComplex", |
| "CharFontFamilyComplex", |
| "CharFontCharSetComplex", |
| "CharFontPitchComplex", |
| "CharPostureComplex", |
| "CharLocaleComplex", |
| "ParaAdjust", |
| "ParaLineSpacing", |
| "ParaBackColor", |
| "ParaBackTransparent", |
| "ParaBackGraphicURL", |
| "ParaBackGraphicFilter", |
| "ParaBackGraphicLocation", |
| "ParaLastLineAdjust", |
| "ParaExpandSingleWord", |
| "ParaLeftMargin", |
| "ParaRightMargin", |
| "ParaTopMargin", |
| "ParaBottomMargin", |
| "ParaLineNumberCount", |
| "ParaLineNumberStartValue", |
| "PageDescName", |
| "PageNumberOffset", |
| "ParaRegisterModeActive", |
| "ParaTabStops", |
| "ParaStyleName", |
| "DropCapFormat", |
| "DropCapWholeWord", |
| "ParaKeepTogether", |
| "Setting", |
| "ParaSplit", |
| "Setting", |
| "NumberingLevel", |
| "NumberingRules", |
| "NumberingStartValue", |
| "ParaIsNumberingRestart", |
| "NumberingStyleName", |
| "ParaOrphans", |
| "ParaWidows", |
| "ParaShadowFormat", |
| "LeftBorder", |
| "RightBorder", |
| "TopBorder", |
| "BottomBorder", |
| "BorderDistance", |
| "LeftBorderDistance", |
| "RightBorderDistance", |
| "TopBorderDistance", |
| "BottomBorderDistance", |
| "BreakType", |
| "DropCapCharStyleName", |
| "ParaFirstLineIndent", |
| "ParaIsAutoFirstLineIndent", |
| "ParaIsHyphenation", |
| "ParaHyphenationMaxHyphens", |
| "ParaHyphenationMaxLeadingChars", |
| "ParaHyphenationMaxTrailingChars", |
| "ParaVertAlignment", |
| "ParaUserDefinedAttributes", |
| "NumberingIsNumber", |
| "ParaIsConnectBorder", |
| NULL |
| }; |
| |
| //.................................................................... |
| static void lcl_initializeCharacterAttributes( const Reference< XPropertySet >& _rxModel ) |
| { |
| try |
| { |
| Reference< XPropertySet > xStyle( ControlLayouter::getDefaultDocumentTextStyle( _rxModel ), UNO_SET_THROW ); |
| |
| // transfer all properties which are described by the style |
| Reference< XPropertySetInfo > xSourcePropInfo( xStyle->getPropertySetInfo(), UNO_SET_THROW ); |
| Reference< XPropertySetInfo > xDestPropInfo( _rxModel->getPropertySetInfo(), UNO_SET_THROW ); |
| |
| ::rtl::OUString sPropertyName; |
| const sal_Char** pCharacterProperty = aCharacterAndParagraphProperties; |
| while ( *pCharacterProperty ) |
| { |
| sPropertyName = ::rtl::OUString::createFromAscii( *pCharacterProperty ); |
| |
| if ( xSourcePropInfo->hasPropertyByName( sPropertyName ) && xDestPropInfo->hasPropertyByName( sPropertyName ) ) |
| _rxModel->setPropertyValue( sPropertyName, xStyle->getPropertyValue( sPropertyName ) ); |
| |
| ++pCharacterProperty; |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| } |
| |
| //-------------------------------------------------------------------- |
| sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const Reference< XPropertySet >& _rxControlModel, |
| const Rectangle& _rControlBoundRect ) |
| { |
| sal_Int16 nClassId = FormComponentType::CONTROL; |
| |
| OSL_ENSURE( _rxControlModel.is(), "FormControlFactory::initializeControlModel: invalid model!" ); |
| if ( !_rxControlModel.is() ) |
| return nClassId; |
| |
| try |
| { |
| ControlLayouter::initializeControlLayout( _rxControlModel, _eDocType ); |
| |
| _rxControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId; |
| Reference< XPropertySetInfo > xPSI( _rxControlModel->getPropertySetInfo(), UNO_SET_THROW ); |
| switch ( nClassId ) |
| { |
| case FormComponentType::SCROLLBAR: |
| _rxControlModel->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LiveScroll" ) ), makeAny( (sal_Bool)sal_True ) ); |
| // NO break! |
| case FormComponentType::SPINBUTTON: |
| { |
| sal_Int32 eOrientation = ScrollBarOrientation::HORIZONTAL; |
| if ( !_rControlBoundRect.IsEmpty() && ( _rControlBoundRect.GetWidth() < _rControlBoundRect.GetHeight() ) ) |
| eOrientation = ScrollBarOrientation::VERTICAL; |
| _rxControlModel->setPropertyValue( FM_PROP_ORIENTATION, makeAny( eOrientation ) ); |
| } |
| break; |
| |
| case FormComponentType::LISTBOX: |
| case FormComponentType::COMBOBOX: |
| { |
| sal_Bool bDropDown = !_rControlBoundRect.IsEmpty() && ( _rControlBoundRect.GetWidth() >= 3 * _rControlBoundRect.GetHeight() ); |
| if ( xPSI->hasPropertyByName( FM_PROP_DROPDOWN ) ) |
| _rxControlModel->setPropertyValue( FM_PROP_DROPDOWN, makeAny( (sal_Bool)bDropDown ) ); |
| _rxControlModel->setPropertyValue( FM_PROP_LINECOUNT, makeAny( sal_Int16( 20 ) ) ); |
| } |
| break; |
| |
| case FormComponentType::TEXTFIELD: |
| { |
| initializeTextFieldLineEnds( _rxControlModel ); |
| lcl_initializeCharacterAttributes( _rxControlModel ); |
| |
| if ( !_rControlBoundRect.IsEmpty() |
| && !( _rControlBoundRect.GetWidth() > 4 * _rControlBoundRect.GetHeight() ) |
| ) |
| { |
| if ( xPSI->hasPropertyByName( FM_PROP_MULTILINE ) ) |
| _rxControlModel->setPropertyValue( FM_PROP_MULTILINE, makeAny( (sal_Bool)sal_True ) ); |
| } |
| } |
| break; |
| |
| case FormComponentType::RADIOBUTTON: |
| case FormComponentType::CHECKBOX: |
| case FormComponentType::FIXEDTEXT: |
| { |
| ::rtl::OUString sVertAlignPropertyName( RTL_CONSTASCII_USTRINGPARAM( "VerticalAlign" ) ); |
| if ( xPSI->hasPropertyByName( sVertAlignPropertyName ) ) |
| _rxControlModel->setPropertyValue( sVertAlignPropertyName, makeAny( VerticalAlignment_MIDDLE ) ); |
| } |
| break; |
| |
| case FormComponentType::IMAGEBUTTON: |
| case FormComponentType::IMAGECONTROL: |
| { |
| const ::rtl::OUString sScaleModeProperty( RTL_CONSTASCII_USTRINGPARAM( "ScaleMode" ) ); |
| if ( xPSI->hasPropertyByName( sScaleModeProperty ) ) |
| _rxControlModel->setPropertyValue( sScaleModeProperty, makeAny( ImageScaleMode::ISOTROPIC ) ); |
| } |
| break; |
| } |
| |
| // initial default label for the control |
| if ( xPSI->hasPropertyByName( FM_PROP_LABEL ) ) |
| { |
| ::rtl::OUString sExistingLabel; |
| OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_LABEL ) >>= sExistingLabel ); |
| if ( !sExistingLabel.getLength() ) |
| { |
| ::rtl::OUString sInitialLabel; |
| OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_NAME ) >>= sInitialLabel ); |
| |
| sal_uInt16 nTitleResId = 0; |
| switch ( nClassId ) |
| { |
| case FormComponentType::COMMANDBUTTON: nTitleResId = RID_STR_PROPTITLE_PUSHBUTTON; break; |
| case FormComponentType::RADIOBUTTON: nTitleResId = RID_STR_PROPTITLE_RADIOBUTTON; break; |
| case FormComponentType::CHECKBOX: nTitleResId = RID_STR_PROPTITLE_CHECKBOX; break; |
| case FormComponentType::GROUPBOX: nTitleResId = RID_STR_PROPTITLE_GROUPBOX; break; |
| case FormComponentType::FIXEDTEXT: nTitleResId = RID_STR_PROPTITLE_FIXEDTEXT; break; |
| } |
| |
| if ( nTitleResId ) |
| sInitialLabel = String( SVX_RES( nTitleResId ) ); |
| |
| _rxControlModel->setPropertyValue( |
| FM_PROP_LABEL, |
| makeAny( lcl_getUniqueLabel_nothrow( _rxControlModel, sInitialLabel ) ) |
| ); |
| } |
| } |
| |
| // strict format = yes is the default (i93467) |
| if ( xPSI->hasPropertyByName( FM_PROP_STRICTFORMAT ) ) |
| { |
| _rxControlModel->setPropertyValue( FM_PROP_STRICTFORMAT, makeAny( sal_Bool( sal_True ) ) ); |
| } |
| |
| // mouse wheel: don't use it for scrolling by default (i110036) |
| if ( xPSI->hasPropertyByName( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) ) |
| { |
| _rxControlModel->setPropertyValue( FM_PROP_MOUSE_WHEEL_BEHAVIOR, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) ); |
| } |
| |
| if ( xPSI->hasPropertyByName( FM_PROP_WRITING_MODE ) ) |
| _rxControlModel->setPropertyValue( FM_PROP_WRITING_MODE, makeAny( WritingMode2::CONTEXT ) ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| return nClassId; |
| } |
| |
| //------------------------------------------------------------------------------ |
| void FormControlFactory::initializeTextFieldLineEnds( const Reference< XPropertySet >& _rxModel ) |
| { |
| OSL_PRECOND( _rxModel.is(), "initializeTextFieldLineEnds: invalid model!" ); |
| if ( !_rxModel.is() ) |
| return; |
| |
| try |
| { |
| Reference< XPropertySetInfo > xInfo = _rxModel->getPropertySetInfo(); |
| if ( !xInfo.is() || !xInfo->hasPropertyByName( FM_PROP_LINEENDFORMAT ) ) |
| return; |
| |
| // let's see if the data source which the form belongs to (if any) |
| // has a setting for the preferred line end format |
| sal_Bool bDosLineEnds = sal_False; |
| Sequence< PropertyValue > aInfo = lcl_getDataSourceIndirectProperties( _rxModel, m_pData->m_aContext ); |
| const PropertyValue* pInfo = aInfo.getConstArray(); |
| const PropertyValue* pInfoEnd = pInfo + aInfo.getLength(); |
| for ( ; pInfo != pInfoEnd; ++pInfo ) |
| { |
| if ( pInfo->Name.equalsAscii( "PreferDosLikeLineEnds" ) ) |
| { |
| pInfo->Value >>= bDosLineEnds; |
| break; |
| } |
| } |
| |
| sal_Int16 nLineEndFormat = bDosLineEnds ? LineEndFormat::CARRIAGE_RETURN_LINE_FEED : LineEndFormat::LINE_FEED; |
| _rxModel->setPropertyValue( FM_PROP_LINEENDFORMAT, makeAny( nLineEndFormat ) ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| //------------------------------------------------------------------------------ |
| void FormControlFactory::initializeFieldDependentProperties( const Reference< XPropertySet >& _rxDatabaseField, |
| const Reference< XPropertySet >& _rxControlModel, const Reference< XNumberFormats >& _rxNumberFormats ) |
| { |
| OSL_PRECOND( _rxDatabaseField.is() && _rxControlModel.is(), |
| "FormControlFactory::initializeFieldDependentProperties: illegal params!" ); |
| if ( !_rxDatabaseField.is() || !_rxControlModel.is() ) |
| return; |
| |
| try |
| { |
| //////////////////////////////////////////////////////////////////////// |
| // if the field has a numeric format, and the model has a "Scale" property, sync it |
| Reference< XPropertySetInfo > xFieldPSI( _rxDatabaseField->getPropertySetInfo(), UNO_SET_THROW ); |
| Reference< XPropertySetInfo > xModelPSI( _rxControlModel->getPropertySetInfo(), UNO_SET_THROW ); |
| |
| if ( xModelPSI->hasPropertyByName( FM_PROP_DECIMAL_ACCURACY ) ) |
| { |
| sal_Int32 nFormatKey = 0; |
| if ( xFieldPSI->hasPropertyByName( FM_PROP_FORMATKEY ) ) |
| { |
| _rxDatabaseField->getPropertyValue( FM_PROP_FORMATKEY ) >>= nFormatKey; |
| } |
| else |
| { |
| nFormatKey = OStaticDataAccessTools().getDefaultNumberFormat( |
| _rxDatabaseField, |
| Reference< XNumberFormatTypes >( _rxNumberFormats, UNO_QUERY ), |
| SvtSysLocale().GetLocaleData().getLocale() |
| ); |
| } |
| |
| Any aScaleVal( ::comphelper::getNumberFormatDecimals( _rxNumberFormats, nFormatKey ) ); |
| _rxControlModel->setPropertyValue( FM_PROP_DECIMAL_ACCURACY, aScaleVal ); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // minimum and maximum of the control according to the type of the database field |
| sal_Int32 nDataType = DataType::OTHER; |
| OSL_VERIFY( _rxDatabaseField->getPropertyValue( FM_PROP_FIELDTYPE ) >>= nDataType ); |
| |
| if ( xModelPSI->hasPropertyByName( FM_PROP_VALUEMIN ) |
| && xModelPSI->hasPropertyByName( FM_PROP_VALUEMAX ) |
| ) |
| { |
| sal_Int32 nMinValue = -1000000000, nMaxValue = 1000000000; |
| switch ( nDataType ) |
| { |
| case DataType::TINYINT : nMinValue = 0; nMaxValue = 255; break; |
| case DataType::SMALLINT : nMinValue = -32768; nMaxValue = 32767; break; |
| case DataType::INTEGER : nMinValue = 0x80000000; nMaxValue = 0x7FFFFFFF; break; |
| // double and singles are ignored |
| } |
| |
| Any aValue; |
| |
| // both the minimum and the maximum value properties can be either Long or Double |
| Property aProperty = xModelPSI->getPropertyByName( FM_PROP_VALUEMIN ); |
| if ( aProperty.Type.getTypeClass() == TypeClass_DOUBLE ) |
| aValue <<= (double)nMinValue; |
| else if ( aProperty.Type.getTypeClass() == TypeClass_LONG ) |
| aValue <<= (sal_Int32)nMinValue; |
| else |
| { |
| DBG_ERROR( "FormControlFactory::initializeFieldDependentProperties: unexpected property type (MinValue)!" ); |
| } |
| _rxControlModel->setPropertyValue( FM_PROP_VALUEMIN, aValue ); |
| |
| // both the minimum and the maximum value properties can be either Long or Double |
| aProperty = xModelPSI->getPropertyByName( FM_PROP_VALUEMAX ); |
| if ( aProperty.Type.getTypeClass() == TypeClass_DOUBLE ) |
| aValue <<= (double)nMaxValue; |
| else if ( aProperty.Type.getTypeClass() == TypeClass_LONG ) |
| aValue <<= (sal_Int32)nMaxValue; |
| else |
| { |
| DBG_ERROR( "FormControlFactory::initializeFieldDependentProperties: unexpected property type (MaxValue)!" ); |
| } |
| _rxControlModel->setPropertyValue( FM_PROP_VALUEMAX, aValue ); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| // a check box can be tristate if and only if the column it is bound to is nullable |
| sal_Int16 nClassId = FormComponentType::CONTROL; |
| OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId ); |
| if ( nClassId == FormComponentType::CHECKBOX ) |
| { |
| sal_Int32 nNullable = ColumnValue::NULLABLE_UNKNOWN; |
| OSL_VERIFY( _rxDatabaseField->getPropertyValue( FM_PROP_ISNULLABLE ) >>= nNullable ); |
| _rxControlModel->setPropertyValue( FM_PROP_TRISTATE, makeAny( sal_Bool( ColumnValue::NO_NULLS != nNullable ) ) ); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| //------------------------------------------------------------------------------ |
| ::rtl::OUString FormControlFactory::getDefaultName( sal_Int16 _nClassId, const Reference< XServiceInfo >& _rxObject ) |
| { |
| sal_uInt16 nResId(0); |
| |
| switch ( _nClassId ) |
| { |
| case FormComponentType::COMMANDBUTTON: nResId = RID_STR_PROPTITLE_PUSHBUTTON; break; |
| case FormComponentType::RADIOBUTTON: nResId = RID_STR_PROPTITLE_RADIOBUTTON; break; |
| case FormComponentType::CHECKBOX: nResId = RID_STR_PROPTITLE_CHECKBOX; break; |
| case FormComponentType::LISTBOX: nResId = RID_STR_PROPTITLE_LISTBOX; break; |
| case FormComponentType::COMBOBOX: nResId = RID_STR_PROPTITLE_COMBOBOX; break; |
| case FormComponentType::GROUPBOX: nResId = RID_STR_PROPTITLE_GROUPBOX; break; |
| case FormComponentType::IMAGEBUTTON: nResId = RID_STR_PROPTITLE_IMAGEBUTTON; break; |
| case FormComponentType::FIXEDTEXT: nResId = RID_STR_PROPTITLE_FIXEDTEXT; break; |
| case FormComponentType::GRIDCONTROL: nResId = RID_STR_PROPTITLE_DBGRID; break; |
| case FormComponentType::FILECONTROL: nResId = RID_STR_PROPTITLE_FILECONTROL; break; |
| case FormComponentType::DATEFIELD: nResId = RID_STR_PROPTITLE_DATEFIELD; break; |
| case FormComponentType::TIMEFIELD: nResId = RID_STR_PROPTITLE_TIMEFIELD; break; |
| case FormComponentType::NUMERICFIELD: nResId = RID_STR_PROPTITLE_NUMERICFIELD; break; |
| case FormComponentType::CURRENCYFIELD: nResId = RID_STR_PROPTITLE_CURRENCYFIELD; break; |
| case FormComponentType::PATTERNFIELD: nResId = RID_STR_PROPTITLE_PATTERNFIELD; break; |
| case FormComponentType::IMAGECONTROL: nResId = RID_STR_PROPTITLE_IMAGECONTROL; break; |
| case FormComponentType::HIDDENCONTROL: nResId = RID_STR_PROPTITLE_HIDDEN; break; |
| case FormComponentType::SCROLLBAR: nResId = RID_STR_PROPTITLE_SCROLLBAR; break; |
| case FormComponentType::SPINBUTTON: nResId = RID_STR_PROPTITLE_SPINBUTTON; break; |
| case FormComponentType::NAVIGATIONBAR: nResId = RID_STR_PROPTITLE_NAVBAR; break; |
| |
| case FormComponentType::TEXTFIELD: |
| nResId = RID_STR_PROPTITLE_EDIT; |
| if ( _rxObject.is() && _rxObject->supportsService( FM_SUN_COMPONENT_FORMATTEDFIELD ) ) |
| nResId = RID_STR_PROPTITLE_FORMATTED; |
| break; |
| |
| default: |
| nResId = RID_STR_CONTROL; break; |
| } |
| |
| return String( SVX_RES( nResId ) ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| ::rtl::OUString FormControlFactory::getDefaultUniqueName_ByComponentType( const Reference< XNameAccess >& _rxContainer, |
| const Reference< XPropertySet >& _rxObject ) |
| { |
| sal_Int16 nClassId = FormComponentType::CONTROL; |
| OSL_VERIFY( _rxObject->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId ); |
| ::rtl::OUString sBaseName = getDefaultName( nClassId, Reference< XServiceInfo >( _rxObject, UNO_QUERY ) ); |
| |
| return getUniqueName( _rxContainer, sBaseName ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| ::rtl::OUString FormControlFactory::getUniqueName( const Reference< XNameAccess >& _rxContainer, const ::rtl::OUString& _rBaseName ) |
| { |
| sal_Int32 n = 0; |
| ::rtl::OUString sName; |
| do |
| { |
| ::rtl::OUStringBuffer aBuf( _rBaseName ); |
| aBuf.appendAscii( " " ); |
| aBuf.append( ++n ); |
| sName = aBuf.makeStringAndClear(); |
| } |
| while ( _rxContainer->hasByName( sName ) ); |
| |
| return sName; |
| } |
| |
| //........................................................................ |
| } // namespace svxform |
| //........................................................................ |