1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_svx.hxx" 26 27 #include "svx/dbtoolsclient.hxx" 28 #include "formcontrolfactory.hxx" 29 #include "fmcontrollayout.hxx" 30 #include "fmprop.hrc" 31 #include "svx/fmresids.hrc" 32 #include "fmservs.hxx" 33 #include "svx/dialmgr.hxx" 34 #include "svx/svdouno.hxx" 35 36 /** === begin UNO includes === **/ 37 #include <com/sun/star/form/XFormComponent.hpp> 38 #include <com/sun/star/form/FormComponentType.hpp> 39 #include <com/sun/star/awt/ScrollBarOrientation.hpp> 40 #include <com/sun/star/awt/MouseWheelBehavior.hpp> 41 #include <com/sun/star/form/XGridColumnFactory.hpp> 42 #include <com/sun/star/style/VerticalAlignment.hpp> 43 #include <com/sun/star/awt/LineEndFormat.hpp> 44 #include <com/sun/star/awt/ImageScaleMode.hpp> 45 #include <com/sun/star/sdbc/DataType.hpp> 46 #include <com/sun/star/util/XNumberFormatTypes.hpp> 47 #include <com/sun/star/sdbc/ColumnValue.hpp> 48 #include <com/sun/star/text/WritingMode2.hpp> 49 #include <com/sun/star/awt/FontDescriptor.hpp> 50 /** === end UNO includes === **/ 51 52 #include <comphelper/componentcontext.hxx> 53 #include <comphelper/numbers.hxx> 54 #include <unotools/syslocale.hxx> 55 #include <tools/gen.hxx> 56 #include <tools/diagnose_ex.h> 57 58 #include <set> 59 60 //........................................................................ 61 namespace svxform 62 { 63 //........................................................................ 64 65 /** === begin UNO using === **/ 66 using ::com::sun::star::uno::Reference; 67 using ::com::sun::star::uno::XInterface; 68 using ::com::sun::star::uno::UNO_QUERY; 69 using ::com::sun::star::uno::UNO_QUERY_THROW; 70 using ::com::sun::star::uno::UNO_SET_THROW; 71 using ::com::sun::star::uno::Exception; 72 using ::com::sun::star::uno::RuntimeException; 73 using ::com::sun::star::uno::Any; 74 using ::com::sun::star::uno::makeAny; 75 using ::com::sun::star::uno::Sequence; 76 using ::com::sun::star::uno::Type; 77 using ::com::sun::star::beans::XPropertySet; 78 using ::com::sun::star::awt::XControlModel; 79 using ::com::sun::star::form::XFormComponent; 80 using ::com::sun::star::container::XIndexAccess; 81 using ::com::sun::star::beans::XPropertySetInfo; 82 using ::com::sun::star::beans::PropertyValue; 83 using ::com::sun::star::container::XChild; 84 using ::com::sun::star::form::XGridColumnFactory; 85 using ::com::sun::star::style::VerticalAlignment_MIDDLE; 86 using ::com::sun::star::beans::Property; 87 using ::com::sun::star::uno::TypeClass_DOUBLE; 88 using ::com::sun::star::uno::TypeClass_LONG; 89 using ::com::sun::star::util::XNumberFormats; 90 using ::com::sun::star::util::XNumberFormatTypes; 91 using ::com::sun::star::awt::FontDescriptor; 92 using ::com::sun::star::lang::Locale; 93 using ::com::sun::star::lang::XServiceInfo; 94 using ::com::sun::star::container::XNameAccess; 95 /** === end UNO using === **/ 96 namespace FormComponentType = ::com::sun::star::form::FormComponentType; 97 namespace ScrollBarOrientation = ::com::sun::star::awt::ScrollBarOrientation; 98 namespace MouseWheelBehavior = ::com::sun::star::awt::MouseWheelBehavior; 99 namespace LineEndFormat = ::com::sun::star::awt::LineEndFormat; 100 namespace ImageScaleMode = ::com::sun::star::awt::ImageScaleMode; 101 namespace DataType = ::com::sun::star::sdbc::DataType; 102 namespace ColumnValue = ::com::sun::star::sdbc::ColumnValue; 103 namespace WritingMode2 = ::com::sun::star::text::WritingMode2; 104 105 //==================================================================== 106 //= FormControlFactory_Data 107 //==================================================================== 108 struct FormControlFactory_Data 109 { 110 ::comphelper::ComponentContext m_aContext; 111 FormControlFactory_Datasvxform::FormControlFactory_Data112 FormControlFactory_Data( const ::comphelper::ComponentContext& _rContext ) 113 :m_aContext( _rContext ) 114 { 115 } 116 }; 117 118 //==================================================================== 119 //= FormControlFactory 120 //==================================================================== 121 //-------------------------------------------------------------------- FormControlFactory(const::comphelper::ComponentContext & _rContext)122 FormControlFactory::FormControlFactory( const ::comphelper::ComponentContext& _rContext ) 123 :m_pData( new FormControlFactory_Data( _rContext ) ) 124 { 125 } 126 127 //-------------------------------------------------------------------- ~FormControlFactory()128 FormControlFactory::~FormControlFactory() 129 { 130 } 131 132 //-------------------------------------------------------------------- initializeControlModel(const DocumentType _eDocType,const SdrUnoObj & _rObject)133 sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const SdrUnoObj& _rObject ) 134 { 135 return initializeControlModel( 136 _eDocType, 137 Reference< XPropertySet >( _rObject.GetUnoControlModel(), UNO_QUERY ), 138 _rObject.GetCurrentBoundRect() 139 ); 140 } 141 142 //-------------------------------------------------------------------- initializeControlModel(const DocumentType _eDocType,const Reference<XPropertySet> & _rxControlModel)143 sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const Reference< XPropertySet >& _rxControlModel ) 144 { 145 return initializeControlModel( 146 _eDocType, _rxControlModel, Rectangle() 147 ); 148 } 149 150 // ----------------------------------------------------------------------------- 151 namespace 152 { 153 //.................................................................... lcl_getUniqueLabel_nothrow(const Reference<XPropertySet> & _rxControlModel,const::rtl::OUString & _rBaseLabel)154 static ::rtl::OUString lcl_getUniqueLabel_nothrow( const Reference< XPropertySet >& _rxControlModel, const ::rtl::OUString& _rBaseLabel ) 155 { 156 ::rtl::OUString sLabel( _rBaseLabel ); 157 try 158 { 159 typedef ::std::set< ::rtl::OUString > StringBag; 160 StringBag aUsedLabels; 161 162 Reference< XFormComponent > xFormComponent( _rxControlModel, UNO_QUERY_THROW ); 163 Reference< XIndexAccess > xContainer( xFormComponent->getParent(), UNO_QUERY_THROW ); 164 // loop through all siblings of the control model, and collect their labels 165 for ( sal_Int32 index=xContainer->getCount(); index>0; ) 166 { 167 Reference< XPropertySet > xElement( xContainer->getByIndex( --index ), UNO_QUERY_THROW ); 168 if ( xElement == _rxControlModel ) 169 continue; 170 171 Reference< XPropertySetInfo > xPSI( xElement->getPropertySetInfo(), UNO_SET_THROW ); 172 if ( !xPSI->hasPropertyByName( FM_PROP_LABEL ) ) 173 continue; 174 175 ::rtl::OUString sElementLabel; 176 OSL_VERIFY( xElement->getPropertyValue( FM_PROP_LABEL ) >>= sElementLabel ); 177 aUsedLabels.insert( sElementLabel ); 178 } 179 180 // now find a free label 181 sal_Int32 i=2; 182 while ( aUsedLabels.find( sLabel ) != aUsedLabels.end() ) 183 { 184 ::rtl::OUStringBuffer aBuffer( _rBaseLabel ); 185 aBuffer.appendAscii( " " ); 186 aBuffer.append( (sal_Int32)i++ ); 187 sLabel = aBuffer.makeStringAndClear(); 188 } 189 } 190 catch( const Exception& ) 191 { 192 DBG_UNHANDLED_EXCEPTION(); 193 } 194 return sLabel; 195 } 196 197 //.................................................................... lcl_getDataSourceIndirectProperties(const Reference<XPropertySet> & _rxControlModel,const::comphelper::ComponentContext & _rContext)198 static Sequence< PropertyValue > lcl_getDataSourceIndirectProperties( const Reference< XPropertySet >& _rxControlModel, 199 const ::comphelper::ComponentContext& _rContext ) 200 { 201 OSL_PRECOND( _rxControlModel.is(), "lcl_getDataSourceIndirectProperties: invalid model!" ); 202 203 Sequence< PropertyValue > aInfo; 204 try 205 { 206 Reference< XChild > xChild( _rxControlModel, UNO_QUERY ); 207 Reference< XPropertySet > xForm; 208 if ( xChild.is() ) 209 xForm = xForm.query( xChild->getParent() ); 210 211 if ( Reference< XGridColumnFactory >( xForm, UNO_QUERY ).is() ) 212 { // hmm. the model is a grid column, in real 213 xChild = xChild.query( xForm ); 214 xForm = xForm.query( xChild->getParent() ); 215 } 216 217 OSL_ENSURE( xForm.is(), "lcl_getDataSourceIndirectProperties: could not determine the form!" ); 218 if ( !xForm.is() ) 219 return aInfo; 220 ::rtl::OUString sDataSourceName; 221 xForm->getPropertyValue( FM_PROP_DATASOURCE ) >>= sDataSourceName; 222 223 Reference< XPropertySet > xDsProperties; 224 if ( sDataSourceName.getLength() ) 225 xDsProperties = xDsProperties.query( OStaticDataAccessTools().getDataSource( sDataSourceName, _rContext.getLegacyServiceFactory() ) ); 226 if ( xDsProperties.is() ) 227 xDsProperties->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Info" ) ) ) >>= aInfo; 228 } 229 catch( const Exception& ) 230 { 231 OSL_ENSURE( sal_False, "lcl_getDataSourceIndirectProperties: caught an exception!" ); 232 } 233 return aInfo; 234 } 235 236 //.................................................................... 237 static const sal_Char* aCharacterAndParagraphProperties[] = 238 { 239 "CharFontName", 240 "CharFontStyleName", 241 "CharFontFamily", 242 "CharFontCharSet", 243 "CharFontPitch", 244 "CharColor", 245 "CharEscapement", 246 "CharHeight", 247 "CharUnderline", 248 "CharWeight", 249 "CharPosture", 250 "CharAutoKerning", 251 "CharBackColor", 252 "CharBackTransparent", 253 "CharCaseMap", 254 "CharCrossedOut", 255 "CharFlash", 256 "CharStrikeout", 257 "CharWordMode", 258 "CharKerning", 259 "CharLocale", 260 "CharKeepTogether", 261 "CharNoLineBreak", 262 "CharShadowed", 263 "CharFontType", 264 "CharStyleName", 265 "CharContoured", 266 "CharCombineIsOn", 267 "CharCombinePrefix", 268 "CharCombineSuffix", 269 "CharEmphasize", 270 "CharRelief", 271 "RubyText", 272 "RubyAdjust", 273 "RubyCharStyleName", 274 "RubyIsAbove", 275 "CharRotation", 276 "CharRotationIsFitToLine", 277 "CharScaleWidth", 278 "HyperLinkURL", 279 "HyperLinkTarget", 280 "HyperLinkName", 281 "VisitedCharStyleName", 282 "UnvisitedCharStyleName", 283 "CharEscapementHeight", 284 "CharNoHyphenation", 285 "CharUnderlineColor", 286 "CharUnderlineHasColor", 287 "CharStyleNames", 288 "CharHeightAsian", 289 "CharWeightAsian", 290 "CharFontNameAsian", 291 "CharFontStyleNameAsian", 292 "CharFontFamilyAsian", 293 "CharFontCharSetAsian", 294 "CharFontPitchAsian", 295 "CharPostureAsian", 296 "CharLocaleAsian", 297 "ParaIsCharacterDistance", 298 "ParaIsForbiddenRules", 299 "ParaIsHangingPunctuation", 300 "CharHeightComplex", 301 "CharWeightComplex", 302 "CharFontNameComplex", 303 "CharFontStyleNameComplex", 304 "CharFontFamilyComplex", 305 "CharFontCharSetComplex", 306 "CharFontPitchComplex", 307 "CharPostureComplex", 308 "CharLocaleComplex", 309 "ParaAdjust", 310 "ParaLineSpacing", 311 "ParaBackColor", 312 "ParaBackTransparent", 313 "ParaBackGraphicURL", 314 "ParaBackGraphicFilter", 315 "ParaBackGraphicLocation", 316 "ParaLastLineAdjust", 317 "ParaExpandSingleWord", 318 "ParaLeftMargin", 319 "ParaRightMargin", 320 "ParaTopMargin", 321 "ParaBottomMargin", 322 "ParaLineNumberCount", 323 "ParaLineNumberStartValue", 324 "PageDescName", 325 "PageNumberOffset", 326 "ParaRegisterModeActive", 327 "ParaTabStops", 328 "ParaStyleName", 329 "DropCapFormat", 330 "DropCapWholeWord", 331 "ParaKeepTogether", 332 "Setting", 333 "ParaSplit", 334 "Setting", 335 "NumberingLevel", 336 "NumberingRules", 337 "NumberingStartValue", 338 "ParaIsNumberingRestart", 339 "NumberingStyleName", 340 "ParaOrphans", 341 "ParaWidows", 342 "ParaShadowFormat", 343 "LeftBorder", 344 "RightBorder", 345 "TopBorder", 346 "BottomBorder", 347 "BorderDistance", 348 "LeftBorderDistance", 349 "RightBorderDistance", 350 "TopBorderDistance", 351 "BottomBorderDistance", 352 "BreakType", 353 "DropCapCharStyleName", 354 "ParaFirstLineIndent", 355 "ParaIsAutoFirstLineIndent", 356 "ParaIsHyphenation", 357 "ParaHyphenationMaxHyphens", 358 "ParaHyphenationMaxLeadingChars", 359 "ParaHyphenationMaxTrailingChars", 360 "ParaVertAlignment", 361 "ParaUserDefinedAttributes", 362 "NumberingIsNumber", 363 "ParaIsConnectBorder", 364 NULL 365 }; 366 367 //.................................................................... lcl_initializeCharacterAttributes(const Reference<XPropertySet> & _rxModel)368 static void lcl_initializeCharacterAttributes( const Reference< XPropertySet >& _rxModel ) 369 { 370 try 371 { 372 Reference< XPropertySet > xStyle( ControlLayouter::getDefaultDocumentTextStyle( _rxModel ), UNO_SET_THROW ); 373 374 // transfer all properties which are described by the style 375 Reference< XPropertySetInfo > xSourcePropInfo( xStyle->getPropertySetInfo(), UNO_SET_THROW ); 376 Reference< XPropertySetInfo > xDestPropInfo( _rxModel->getPropertySetInfo(), UNO_SET_THROW ); 377 378 ::rtl::OUString sPropertyName; 379 const sal_Char** pCharacterProperty = aCharacterAndParagraphProperties; 380 while ( *pCharacterProperty ) 381 { 382 sPropertyName = ::rtl::OUString::createFromAscii( *pCharacterProperty ); 383 384 if ( xSourcePropInfo->hasPropertyByName( sPropertyName ) && xDestPropInfo->hasPropertyByName( sPropertyName ) ) 385 _rxModel->setPropertyValue( sPropertyName, xStyle->getPropertyValue( sPropertyName ) ); 386 387 ++pCharacterProperty; 388 } 389 } 390 catch( const Exception& ) 391 { 392 DBG_UNHANDLED_EXCEPTION(); 393 } 394 } 395 } 396 397 //-------------------------------------------------------------------- initializeControlModel(const DocumentType _eDocType,const Reference<XPropertySet> & _rxControlModel,const Rectangle & _rControlBoundRect)398 sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const Reference< XPropertySet >& _rxControlModel, 399 const Rectangle& _rControlBoundRect ) 400 { 401 sal_Int16 nClassId = FormComponentType::CONTROL; 402 403 OSL_ENSURE( _rxControlModel.is(), "FormControlFactory::initializeControlModel: invalid model!" ); 404 if ( !_rxControlModel.is() ) 405 return nClassId; 406 407 try 408 { 409 ControlLayouter::initializeControlLayout( _rxControlModel, _eDocType ); 410 411 _rxControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId; 412 Reference< XPropertySetInfo > xPSI( _rxControlModel->getPropertySetInfo(), UNO_SET_THROW ); 413 switch ( nClassId ) 414 { 415 case FormComponentType::SCROLLBAR: 416 _rxControlModel->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LiveScroll" ) ), makeAny( (sal_Bool)sal_True ) ); 417 // NO break! 418 case FormComponentType::SPINBUTTON: 419 { 420 sal_Int32 eOrientation = ScrollBarOrientation::HORIZONTAL; 421 if ( !_rControlBoundRect.IsEmpty() && ( _rControlBoundRect.GetWidth() < _rControlBoundRect.GetHeight() ) ) 422 eOrientation = ScrollBarOrientation::VERTICAL; 423 _rxControlModel->setPropertyValue( FM_PROP_ORIENTATION, makeAny( eOrientation ) ); 424 } 425 break; 426 427 case FormComponentType::LISTBOX: 428 case FormComponentType::COMBOBOX: 429 { 430 sal_Bool bDropDown = !_rControlBoundRect.IsEmpty() && ( _rControlBoundRect.GetWidth() >= 3 * _rControlBoundRect.GetHeight() ); 431 if ( xPSI->hasPropertyByName( FM_PROP_DROPDOWN ) ) 432 _rxControlModel->setPropertyValue( FM_PROP_DROPDOWN, makeAny( (sal_Bool)bDropDown ) ); 433 _rxControlModel->setPropertyValue( FM_PROP_LINECOUNT, makeAny( sal_Int16( 20 ) ) ); 434 } 435 break; 436 437 case FormComponentType::TEXTFIELD: 438 { 439 initializeTextFieldLineEnds( _rxControlModel ); 440 lcl_initializeCharacterAttributes( _rxControlModel ); 441 442 if ( !_rControlBoundRect.IsEmpty() 443 && !( _rControlBoundRect.GetWidth() > 4 * _rControlBoundRect.GetHeight() ) 444 ) 445 { 446 if ( xPSI->hasPropertyByName( FM_PROP_MULTILINE ) ) 447 _rxControlModel->setPropertyValue( FM_PROP_MULTILINE, makeAny( (sal_Bool)sal_True ) ); 448 } 449 } 450 break; 451 452 case FormComponentType::RADIOBUTTON: 453 case FormComponentType::CHECKBOX: 454 case FormComponentType::FIXEDTEXT: 455 { 456 ::rtl::OUString sVertAlignPropertyName( RTL_CONSTASCII_USTRINGPARAM( "VerticalAlign" ) ); 457 if ( xPSI->hasPropertyByName( sVertAlignPropertyName ) ) 458 _rxControlModel->setPropertyValue( sVertAlignPropertyName, makeAny( VerticalAlignment_MIDDLE ) ); 459 } 460 break; 461 462 case FormComponentType::IMAGEBUTTON: 463 case FormComponentType::IMAGECONTROL: 464 { 465 const ::rtl::OUString sScaleModeProperty( RTL_CONSTASCII_USTRINGPARAM( "ScaleMode" ) ); 466 if ( xPSI->hasPropertyByName( sScaleModeProperty ) ) 467 _rxControlModel->setPropertyValue( sScaleModeProperty, makeAny( ImageScaleMode::ISOTROPIC ) ); 468 } 469 break; 470 } 471 472 // initial default label for the control 473 if ( xPSI->hasPropertyByName( FM_PROP_LABEL ) ) 474 { 475 ::rtl::OUString sExistingLabel; 476 OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_LABEL ) >>= sExistingLabel ); 477 if ( !sExistingLabel.getLength() ) 478 { 479 ::rtl::OUString sInitialLabel; 480 OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_NAME ) >>= sInitialLabel ); 481 482 sal_uInt16 nTitleResId = 0; 483 switch ( nClassId ) 484 { 485 case FormComponentType::COMMANDBUTTON: nTitleResId = RID_STR_PROPTITLE_PUSHBUTTON; break; 486 case FormComponentType::RADIOBUTTON: nTitleResId = RID_STR_PROPTITLE_RADIOBUTTON; break; 487 case FormComponentType::CHECKBOX: nTitleResId = RID_STR_PROPTITLE_CHECKBOX; break; 488 case FormComponentType::GROUPBOX: nTitleResId = RID_STR_PROPTITLE_GROUPBOX; break; 489 case FormComponentType::FIXEDTEXT: nTitleResId = RID_STR_PROPTITLE_FIXEDTEXT; break; 490 } 491 492 if ( nTitleResId ) 493 sInitialLabel = String( SVX_RES( nTitleResId ) ); 494 495 _rxControlModel->setPropertyValue( 496 FM_PROP_LABEL, 497 makeAny( lcl_getUniqueLabel_nothrow( _rxControlModel, sInitialLabel ) ) 498 ); 499 } 500 } 501 502 // strict format = yes is the default (i93467) 503 if ( xPSI->hasPropertyByName( FM_PROP_STRICTFORMAT ) ) 504 { 505 _rxControlModel->setPropertyValue( FM_PROP_STRICTFORMAT, makeAny( sal_Bool( sal_True ) ) ); 506 } 507 508 // mouse wheel: don't use it for scrolling by default (i110036) 509 if ( xPSI->hasPropertyByName( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) ) 510 { 511 _rxControlModel->setPropertyValue( FM_PROP_MOUSE_WHEEL_BEHAVIOR, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) ); 512 } 513 514 if ( xPSI->hasPropertyByName( FM_PROP_WRITING_MODE ) ) 515 _rxControlModel->setPropertyValue( FM_PROP_WRITING_MODE, makeAny( WritingMode2::CONTEXT ) ); 516 } 517 catch( const Exception& ) 518 { 519 DBG_UNHANDLED_EXCEPTION(); 520 } 521 return nClassId; 522 } 523 524 //------------------------------------------------------------------------------ initializeTextFieldLineEnds(const Reference<XPropertySet> & _rxModel)525 void FormControlFactory::initializeTextFieldLineEnds( const Reference< XPropertySet >& _rxModel ) 526 { 527 OSL_PRECOND( _rxModel.is(), "initializeTextFieldLineEnds: invalid model!" ); 528 if ( !_rxModel.is() ) 529 return; 530 531 try 532 { 533 Reference< XPropertySetInfo > xInfo = _rxModel->getPropertySetInfo(); 534 if ( !xInfo.is() || !xInfo->hasPropertyByName( FM_PROP_LINEENDFORMAT ) ) 535 return; 536 537 // let's see if the data source which the form belongs to (if any) 538 // has a setting for the preferred line end format 539 sal_Bool bDosLineEnds = sal_False; 540 Sequence< PropertyValue > aInfo = lcl_getDataSourceIndirectProperties( _rxModel, m_pData->m_aContext ); 541 const PropertyValue* pInfo = aInfo.getConstArray(); 542 const PropertyValue* pInfoEnd = pInfo + aInfo.getLength(); 543 for ( ; pInfo != pInfoEnd; ++pInfo ) 544 { 545 if ( pInfo->Name.equalsAscii( "PreferDosLikeLineEnds" ) ) 546 { 547 pInfo->Value >>= bDosLineEnds; 548 break; 549 } 550 } 551 552 sal_Int16 nLineEndFormat = bDosLineEnds ? LineEndFormat::CARRIAGE_RETURN_LINE_FEED : LineEndFormat::LINE_FEED; 553 _rxModel->setPropertyValue( FM_PROP_LINEENDFORMAT, makeAny( nLineEndFormat ) ); 554 } 555 catch( const Exception& ) 556 { 557 DBG_UNHANDLED_EXCEPTION(); 558 } 559 } 560 561 //------------------------------------------------------------------------------ initializeFieldDependentProperties(const Reference<XPropertySet> & _rxDatabaseField,const Reference<XPropertySet> & _rxControlModel,const Reference<XNumberFormats> & _rxNumberFormats)562 void FormControlFactory::initializeFieldDependentProperties( const Reference< XPropertySet >& _rxDatabaseField, 563 const Reference< XPropertySet >& _rxControlModel, const Reference< XNumberFormats >& _rxNumberFormats ) 564 { 565 OSL_PRECOND( _rxDatabaseField.is() && _rxControlModel.is(), 566 "FormControlFactory::initializeFieldDependentProperties: illegal params!" ); 567 if ( !_rxDatabaseField.is() || !_rxControlModel.is() ) 568 return; 569 570 try 571 { 572 //////////////////////////////////////////////////////////////////////// 573 // if the field has a numeric format, and the model has a "Scale" property, sync it 574 Reference< XPropertySetInfo > xFieldPSI( _rxDatabaseField->getPropertySetInfo(), UNO_SET_THROW ); 575 Reference< XPropertySetInfo > xModelPSI( _rxControlModel->getPropertySetInfo(), UNO_SET_THROW ); 576 577 if ( xModelPSI->hasPropertyByName( FM_PROP_DECIMAL_ACCURACY ) ) 578 { 579 sal_Int32 nFormatKey = 0; 580 if ( xFieldPSI->hasPropertyByName( FM_PROP_FORMATKEY ) ) 581 { 582 _rxDatabaseField->getPropertyValue( FM_PROP_FORMATKEY ) >>= nFormatKey; 583 } 584 else 585 { 586 nFormatKey = OStaticDataAccessTools().getDefaultNumberFormat( 587 _rxDatabaseField, 588 Reference< XNumberFormatTypes >( _rxNumberFormats, UNO_QUERY ), 589 SvtSysLocale().GetLocaleData().getLocale() 590 ); 591 } 592 593 Any aScaleVal( ::comphelper::getNumberFormatDecimals( _rxNumberFormats, nFormatKey ) ); 594 _rxControlModel->setPropertyValue( FM_PROP_DECIMAL_ACCURACY, aScaleVal ); 595 } 596 597 //////////////////////////////////////////////////////////////////////// 598 // minimum and maximum of the control according to the type of the database field 599 sal_Int32 nDataType = DataType::OTHER; 600 OSL_VERIFY( _rxDatabaseField->getPropertyValue( FM_PROP_FIELDTYPE ) >>= nDataType ); 601 602 if ( xModelPSI->hasPropertyByName( FM_PROP_VALUEMIN ) 603 && xModelPSI->hasPropertyByName( FM_PROP_VALUEMAX ) 604 ) 605 { 606 sal_Int32 nMinValue = -1000000000, nMaxValue = 1000000000; 607 switch ( nDataType ) 608 { 609 case DataType::TINYINT : nMinValue = 0; nMaxValue = 255; break; 610 case DataType::SMALLINT : nMinValue = -32768; nMaxValue = 32767; break; 611 case DataType::INTEGER : nMinValue = 0x80000000; nMaxValue = 0x7FFFFFFF; break; 612 // double and singles are ignored 613 } 614 615 Any aValue; 616 617 // both the minimum and the maximum value properties can be either Long or Double 618 Property aProperty = xModelPSI->getPropertyByName( FM_PROP_VALUEMIN ); 619 if ( aProperty.Type.getTypeClass() == TypeClass_DOUBLE ) 620 aValue <<= (double)nMinValue; 621 else if ( aProperty.Type.getTypeClass() == TypeClass_LONG ) 622 aValue <<= (sal_Int32)nMinValue; 623 else 624 { 625 DBG_ERROR( "FormControlFactory::initializeFieldDependentProperties: unexpected property type (MinValue)!" ); 626 } 627 _rxControlModel->setPropertyValue( FM_PROP_VALUEMIN, aValue ); 628 629 // both the minimum and the maximum value properties can be either Long or Double 630 aProperty = xModelPSI->getPropertyByName( FM_PROP_VALUEMAX ); 631 if ( aProperty.Type.getTypeClass() == TypeClass_DOUBLE ) 632 aValue <<= (double)nMaxValue; 633 else if ( aProperty.Type.getTypeClass() == TypeClass_LONG ) 634 aValue <<= (sal_Int32)nMaxValue; 635 else 636 { 637 DBG_ERROR( "FormControlFactory::initializeFieldDependentProperties: unexpected property type (MaxValue)!" ); 638 } 639 _rxControlModel->setPropertyValue( FM_PROP_VALUEMAX, aValue ); 640 } 641 642 //////////////////////////////////////////////////////////////////////// 643 // a check box can be tristate if and only if the column it is bound to is nullable 644 sal_Int16 nClassId = FormComponentType::CONTROL; 645 OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId ); 646 if ( nClassId == FormComponentType::CHECKBOX ) 647 { 648 sal_Int32 nNullable = ColumnValue::NULLABLE_UNKNOWN; 649 OSL_VERIFY( _rxDatabaseField->getPropertyValue( FM_PROP_ISNULLABLE ) >>= nNullable ); 650 _rxControlModel->setPropertyValue( FM_PROP_TRISTATE, makeAny( sal_Bool( ColumnValue::NO_NULLS != nNullable ) ) ); 651 } 652 } 653 catch( const Exception& ) 654 { 655 DBG_UNHANDLED_EXCEPTION(); 656 } 657 } 658 659 //------------------------------------------------------------------------------ getDefaultName(sal_Int16 _nClassId,const Reference<XServiceInfo> & _rxObject)660 ::rtl::OUString FormControlFactory::getDefaultName( sal_Int16 _nClassId, const Reference< XServiceInfo >& _rxObject ) 661 { 662 sal_uInt16 nResId(0); 663 664 switch ( _nClassId ) 665 { 666 case FormComponentType::COMMANDBUTTON: nResId = RID_STR_PROPTITLE_PUSHBUTTON; break; 667 case FormComponentType::RADIOBUTTON: nResId = RID_STR_PROPTITLE_RADIOBUTTON; break; 668 case FormComponentType::CHECKBOX: nResId = RID_STR_PROPTITLE_CHECKBOX; break; 669 case FormComponentType::LISTBOX: nResId = RID_STR_PROPTITLE_LISTBOX; break; 670 case FormComponentType::COMBOBOX: nResId = RID_STR_PROPTITLE_COMBOBOX; break; 671 case FormComponentType::GROUPBOX: nResId = RID_STR_PROPTITLE_GROUPBOX; break; 672 case FormComponentType::IMAGEBUTTON: nResId = RID_STR_PROPTITLE_IMAGEBUTTON; break; 673 case FormComponentType::FIXEDTEXT: nResId = RID_STR_PROPTITLE_FIXEDTEXT; break; 674 case FormComponentType::GRIDCONTROL: nResId = RID_STR_PROPTITLE_DBGRID; break; 675 case FormComponentType::FILECONTROL: nResId = RID_STR_PROPTITLE_FILECONTROL; break; 676 case FormComponentType::DATEFIELD: nResId = RID_STR_PROPTITLE_DATEFIELD; break; 677 case FormComponentType::TIMEFIELD: nResId = RID_STR_PROPTITLE_TIMEFIELD; break; 678 case FormComponentType::NUMERICFIELD: nResId = RID_STR_PROPTITLE_NUMERICFIELD; break; 679 case FormComponentType::CURRENCYFIELD: nResId = RID_STR_PROPTITLE_CURRENCYFIELD; break; 680 case FormComponentType::PATTERNFIELD: nResId = RID_STR_PROPTITLE_PATTERNFIELD; break; 681 case FormComponentType::IMAGECONTROL: nResId = RID_STR_PROPTITLE_IMAGECONTROL; break; 682 case FormComponentType::HIDDENCONTROL: nResId = RID_STR_PROPTITLE_HIDDEN; break; 683 case FormComponentType::SCROLLBAR: nResId = RID_STR_PROPTITLE_SCROLLBAR; break; 684 case FormComponentType::SPINBUTTON: nResId = RID_STR_PROPTITLE_SPINBUTTON; break; 685 case FormComponentType::NAVIGATIONBAR: nResId = RID_STR_PROPTITLE_NAVBAR; break; 686 687 case FormComponentType::TEXTFIELD: 688 nResId = RID_STR_PROPTITLE_EDIT; 689 if ( _rxObject.is() && _rxObject->supportsService( FM_SUN_COMPONENT_FORMATTEDFIELD ) ) 690 nResId = RID_STR_PROPTITLE_FORMATTED; 691 break; 692 693 default: 694 nResId = RID_STR_CONTROL; break; 695 } 696 697 return String( SVX_RES( nResId ) ); 698 } 699 700 //------------------------------------------------------------------------------ getDefaultUniqueName_ByComponentType(const Reference<XNameAccess> & _rxContainer,const Reference<XPropertySet> & _rxObject)701 ::rtl::OUString FormControlFactory::getDefaultUniqueName_ByComponentType( const Reference< XNameAccess >& _rxContainer, 702 const Reference< XPropertySet >& _rxObject ) 703 { 704 sal_Int16 nClassId = FormComponentType::CONTROL; 705 OSL_VERIFY( _rxObject->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId ); 706 ::rtl::OUString sBaseName = getDefaultName( nClassId, Reference< XServiceInfo >( _rxObject, UNO_QUERY ) ); 707 708 return getUniqueName( _rxContainer, sBaseName ); 709 } 710 711 //------------------------------------------------------------------------------ getUniqueName(const Reference<XNameAccess> & _rxContainer,const::rtl::OUString & _rBaseName)712 ::rtl::OUString FormControlFactory::getUniqueName( const Reference< XNameAccess >& _rxContainer, const ::rtl::OUString& _rBaseName ) 713 { 714 sal_Int32 n = 0; 715 ::rtl::OUString sName; 716 do 717 { 718 ::rtl::OUStringBuffer aBuf( _rBaseName ); 719 aBuf.appendAscii( " " ); 720 aBuf.append( ++n ); 721 sName = aBuf.makeStringAndClear(); 722 } 723 while ( _rxContainer->hasByName( sName ) ); 724 725 return sName; 726 } 727 728 //........................................................................ 729 } // namespace svxform 730 //........................................................................ 731