Bump version to 6.4-15
[LibreOffice.git] / svx / source / form / formcontrolfactory.cxx
blob5f7cbedef8f40ac9794fcd5d5604c5ce4e7861cb
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 .
21 #include <formcontrolfactory.hxx>
22 #include <fmcontrollayout.hxx>
23 #include <fmprop.hxx>
24 #include <svx/strings.hrc>
25 #include <fmservs.hxx>
26 #include <svx/dialmgr.hxx>
27 #include <svx/svdouno.hxx>
29 #include <com/sun/star/form/XFormComponent.hpp>
30 #include <com/sun/star/form/FormComponentType.hpp>
31 #include <com/sun/star/awt/ScrollBarOrientation.hpp>
32 #include <com/sun/star/awt/MouseWheelBehavior.hpp>
33 #include <com/sun/star/form/XGridColumnFactory.hpp>
34 #include <com/sun/star/style/VerticalAlignment.hpp>
35 #include <com/sun/star/awt/LineEndFormat.hpp>
36 #include <com/sun/star/awt/ImageScaleMode.hpp>
37 #include <com/sun/star/sdbc/DataType.hpp>
38 #include <com/sun/star/util/XNumberFormatTypes.hpp>
39 #include <com/sun/star/sdbc/ColumnValue.hpp>
40 #include <com/sun/star/text/WritingMode2.hpp>
42 #include <comphelper/numbers.hxx>
43 #include <comphelper/processfactory.hxx>
44 #include <unotools/syslocale.hxx>
45 #include <tools/gen.hxx>
46 #include <tools/diagnose_ex.h>
47 #include <connectivity/dbtools.hxx>
48 #include <i18nlangtag/languagetag.hxx>
50 #include <set>
52 using namespace ::dbtools;
54 namespace svxform
58 using ::com::sun::star::uno::Reference;
59 using ::com::sun::star::uno::UNO_QUERY;
60 using ::com::sun::star::uno::UNO_QUERY_THROW;
61 using ::com::sun::star::uno::UNO_SET_THROW;
62 using ::com::sun::star::uno::Exception;
63 using ::com::sun::star::uno::Any;
64 using ::com::sun::star::uno::makeAny;
65 using ::com::sun::star::uno::Sequence;
66 using ::com::sun::star::uno::Type;
67 using ::com::sun::star::uno::XComponentContext;
68 using ::com::sun::star::beans::XPropertySet;
69 using ::com::sun::star::form::XFormComponent;
70 using ::com::sun::star::container::XIndexAccess;
71 using ::com::sun::star::beans::XPropertySetInfo;
72 using ::com::sun::star::beans::PropertyValue;
73 using ::com::sun::star::container::XChild;
74 using ::com::sun::star::form::XGridColumnFactory;
75 using ::com::sun::star::style::VerticalAlignment_MIDDLE;
76 using ::com::sun::star::beans::Property;
77 using ::com::sun::star::uno::TypeClass_DOUBLE;
78 using ::com::sun::star::uno::TypeClass_LONG;
79 using ::com::sun::star::util::XNumberFormats;
80 using ::com::sun::star::util::XNumberFormatTypes;
81 using ::com::sun::star::lang::XServiceInfo;
82 using ::com::sun::star::container::XNameAccess;
84 namespace FormComponentType = ::com::sun::star::form::FormComponentType;
85 namespace ScrollBarOrientation = ::com::sun::star::awt::ScrollBarOrientation;
86 namespace MouseWheelBehavior = ::com::sun::star::awt::MouseWheelBehavior;
87 namespace LineEndFormat = ::com::sun::star::awt::LineEndFormat;
88 namespace ImageScaleMode = ::com::sun::star::awt::ImageScaleMode;
89 namespace DataType = ::com::sun::star::sdbc::DataType;
90 namespace ColumnValue = ::com::sun::star::sdbc::ColumnValue;
91 namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
93 struct FormControlFactory_Data
95 Reference<XComponentContext> m_xContext;
97 explicit FormControlFactory_Data( const Reference<XComponentContext>& _rContext )
98 :m_xContext( _rContext )
103 FormControlFactory::FormControlFactory( const Reference<XComponentContext>& _rContext )
104 :m_pData( new FormControlFactory_Data( _rContext ) )
108 FormControlFactory::FormControlFactory( )
109 :m_pData( new FormControlFactory_Data( comphelper::getProcessComponentContext() ) )
114 FormControlFactory::~FormControlFactory()
119 sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const SdrUnoObj& _rObject )
121 return initializeControlModel(
122 _eDocType,
123 Reference< XPropertySet >( _rObject.GetUnoControlModel(), UNO_QUERY ),
124 _rObject.GetCurrentBoundRect()
129 void FormControlFactory::initializeControlModel( const DocumentType _eDocType, const Reference< XPropertySet >& _rxControlModel )
131 initializeControlModel(
132 _eDocType, _rxControlModel, tools::Rectangle()
137 namespace
140 OUString lcl_getUniqueLabel_nothrow( const Reference< XPropertySet >& _rxControlModel, const OUString& _rBaseLabel )
142 OUString sLabel( _rBaseLabel );
145 typedef ::std::set< OUString > StringBag;
146 StringBag aUsedLabels;
148 Reference< XFormComponent > xFormComponent( _rxControlModel, UNO_QUERY_THROW );
149 Reference< XIndexAccess > xContainer( xFormComponent->getParent(), UNO_QUERY_THROW );
150 // loop through all siblings of the control model, and collect their labels
151 for ( sal_Int32 index=xContainer->getCount(); index>0; )
153 Reference< XPropertySet > xElement( xContainer->getByIndex( --index ), UNO_QUERY_THROW );
154 if ( xElement == _rxControlModel )
155 continue;
157 Reference< XPropertySetInfo > xPSI( xElement->getPropertySetInfo(), UNO_SET_THROW );
158 if ( !xPSI->hasPropertyByName( FM_PROP_LABEL ) )
159 continue;
161 OUString sElementLabel;
162 OSL_VERIFY( xElement->getPropertyValue( FM_PROP_LABEL ) >>= sElementLabel );
163 aUsedLabels.insert( sElementLabel );
166 // now find a free label
167 sal_Int32 i=2;
168 while ( aUsedLabels.find( sLabel ) != aUsedLabels.end() )
170 OUStringBuffer aBuffer( _rBaseLabel );
171 aBuffer.append( " " );
172 aBuffer.append( i++ );
173 sLabel = aBuffer.makeStringAndClear();
176 catch( const Exception& )
178 DBG_UNHANDLED_EXCEPTION("svx");
180 return sLabel;
184 Sequence< PropertyValue > lcl_getDataSourceIndirectProperties( const Reference< XPropertySet >& _rxControlModel,
185 const Reference<XComponentContext>& _rContext )
187 OSL_PRECOND( _rxControlModel.is(), "lcl_getDataSourceIndirectProperties: invalid model!" );
189 Sequence< PropertyValue > aInfo;
192 Reference< XChild > xChild( _rxControlModel, UNO_QUERY );
193 Reference< XPropertySet > xForm;
194 if ( xChild.is() )
195 xForm.set(xChild->getParent(), css::uno::UNO_QUERY);
197 if ( Reference< XGridColumnFactory >( xForm, UNO_QUERY ).is() )
198 { // hmm. the model is a grid column, in real
199 xChild.set(xForm, css::uno::UNO_QUERY);
200 xForm.set(xChild->getParent(), css::uno::UNO_QUERY);
203 OSL_ENSURE( xForm.is(), "lcl_getDataSourceIndirectProperties: could not determine the form!" );
204 if ( !xForm.is() )
205 return aInfo;
206 OUString sDataSourceName;
207 xForm->getPropertyValue( FM_PROP_DATASOURCE ) >>= sDataSourceName;
209 Reference< XPropertySet > xDsProperties;
210 if ( !sDataSourceName.isEmpty() )
211 xDsProperties.set(getDataSource( sDataSourceName, _rContext ), css::uno::UNO_QUERY);
212 if ( xDsProperties.is() )
213 xDsProperties->getPropertyValue("Info") >>= aInfo;
215 catch( const Exception& )
217 OSL_FAIL( "lcl_getDataSourceIndirectProperties: caught an exception!" );
219 return aInfo;
223 static const sal_Char* aCharacterAndParagraphProperties[] =
225 "CharFontName",
226 "CharFontStyleName",
227 "CharFontFamily",
228 "CharFontCharSet",
229 "CharFontPitch",
230 "CharColor",
231 "CharEscapement",
232 "CharHeight",
233 "CharUnderline",
234 "CharWeight",
235 "CharPosture",
236 "CharAutoKerning",
237 "CharBackColor",
238 "CharBackTransparent",
239 "CharCaseMap",
240 "CharCrossedOut",
241 "CharFlash",
242 "CharStrikeout",
243 "CharWordMode",
244 "CharKerning",
245 "CharLocale",
246 "CharKeepTogether",
247 "CharNoLineBreak",
248 "CharShadowed",
249 "CharFontType",
250 "CharStyleName",
251 "CharContoured",
252 "CharCombineIsOn",
253 "CharCombinePrefix",
254 "CharCombineSuffix",
255 "CharEmphasize",
256 "CharRelief",
257 "RubyText",
258 "RubyAdjust",
259 "RubyCharStyleName",
260 "RubyIsAbove",
261 "CharRotation",
262 "CharRotationIsFitToLine",
263 "CharScaleWidth",
264 "HyperLinkURL",
265 "HyperLinkTarget",
266 "HyperLinkName",
267 "VisitedCharStyleName",
268 "UnvisitedCharStyleName",
269 "CharEscapementHeight",
270 "CharNoHyphenation",
271 "CharUnderlineColor",
272 "CharUnderlineHasColor",
273 "CharStyleNames",
274 "CharHeightAsian",
275 "CharWeightAsian",
276 "CharFontNameAsian",
277 "CharFontStyleNameAsian",
278 "CharFontFamilyAsian",
279 "CharFontCharSetAsian",
280 "CharFontPitchAsian",
281 "CharPostureAsian",
282 "CharLocaleAsian",
283 "ParaIsCharacterDistance",
284 "ParaIsForbiddenRules",
285 "ParaIsHangingPunctuation",
286 "CharHeightComplex",
287 "CharWeightComplex",
288 "CharFontNameComplex",
289 "CharFontStyleNameComplex",
290 "CharFontFamilyComplex",
291 "CharFontCharSetComplex",
292 "CharFontPitchComplex",
293 "CharPostureComplex",
294 "CharLocaleComplex",
295 "ParaAdjust",
296 "ParaLineSpacing",
297 "ParaBackColor",
298 "ParaBackTransparent",
299 "ParaBackGraphic",
300 "ParaBackGraphicURL",
301 "ParaBackGraphicFilter",
302 "ParaBackGraphicLocation",
303 "ParaLastLineAdjust",
304 "ParaExpandSingleWord",
305 "ParaLeftMargin",
306 "ParaRightMargin",
307 "ParaTopMargin",
308 "ParaBottomMargin",
309 "ParaLineNumberCount",
310 "ParaLineNumberStartValue",
311 "PageDescName",
312 "PageNumberOffset",
313 "ParaRegisterModeActive",
314 "ParaTabStops",
315 "ParaStyleName",
316 "DropCapFormat",
317 "DropCapWholeWord",
318 "ParaKeepTogether",
319 "Setting",
320 "ParaSplit",
321 "Setting",
322 "NumberingLevel",
323 "NumberingRules",
324 "NumberingStartValue",
325 "ParaIsNumberingRestart",
326 "NumberingStyleName",
327 "ParaOrphans",
328 "ParaWidows",
329 "ParaShadowFormat",
330 "LeftBorder",
331 "RightBorder",
332 "TopBorder",
333 "BottomBorder",
334 "BorderDistance",
335 "LeftBorderDistance",
336 "RightBorderDistance",
337 "TopBorderDistance",
338 "BottomBorderDistance",
339 "BreakType",
340 "DropCapCharStyleName",
341 "ParaFirstLineIndent",
342 "ParaIsAutoFirstLineIndent",
343 "ParaIsHyphenation",
344 "ParaHyphenationMaxHyphens",
345 "ParaHyphenationMaxLeadingChars",
346 "ParaHyphenationMaxTrailingChars",
347 "ParaVertAlignment",
348 "ParaUserDefinedAttributes",
349 "NumberingIsNumber",
350 "ParaIsConnectBorder",
351 nullptr
355 void lcl_initializeCharacterAttributes( const Reference< XPropertySet >& _rxModel )
359 Reference< XPropertySet > xStyle( ControlLayouter::getDefaultDocumentTextStyle( _rxModel ), UNO_SET_THROW );
361 // transfer all properties which are described by the style
362 Reference< XPropertySetInfo > xSourcePropInfo( xStyle->getPropertySetInfo(), UNO_SET_THROW );
363 Reference< XPropertySetInfo > xDestPropInfo( _rxModel->getPropertySetInfo(), UNO_SET_THROW );
365 OUString sPropertyName;
366 const sal_Char** pCharacterProperty = aCharacterAndParagraphProperties;
367 while ( *pCharacterProperty )
369 sPropertyName = OUString::createFromAscii( *pCharacterProperty );
371 if ( xSourcePropInfo->hasPropertyByName( sPropertyName ) && xDestPropInfo->hasPropertyByName( sPropertyName ) )
372 _rxModel->setPropertyValue( sPropertyName, xStyle->getPropertyValue( sPropertyName ) );
374 ++pCharacterProperty;
377 catch( const Exception& )
379 DBG_UNHANDLED_EXCEPTION("svx");
385 sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const Reference< XPropertySet >& _rxControlModel,
386 const tools::Rectangle& _rControlBoundRect )
388 sal_Int16 nClassId = FormComponentType::CONTROL;
390 OSL_ENSURE( _rxControlModel.is(), "FormControlFactory::initializeControlModel: invalid model!" );
391 if ( !_rxControlModel.is() )
392 return nClassId;
396 ControlLayouter::initializeControlLayout( _rxControlModel, _eDocType );
398 _rxControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId;
399 Reference< XPropertySetInfo > xPSI( _rxControlModel->getPropertySetInfo(), UNO_SET_THROW );
400 switch ( nClassId )
402 case FormComponentType::SCROLLBAR:
403 _rxControlModel->setPropertyValue("LiveScroll", makeAny( true ) );
404 [[fallthrough]];
405 case FormComponentType::SPINBUTTON:
407 sal_Int32 eOrientation = ScrollBarOrientation::HORIZONTAL;
408 if ( !_rControlBoundRect.IsEmpty() && ( _rControlBoundRect.GetWidth() < _rControlBoundRect.GetHeight() ) )
409 eOrientation = ScrollBarOrientation::VERTICAL;
410 _rxControlModel->setPropertyValue( FM_PROP_ORIENTATION, makeAny( eOrientation ) );
412 break;
414 case FormComponentType::LISTBOX:
415 case FormComponentType::COMBOBOX:
417 bool bDropDown = !_rControlBoundRect.IsEmpty() && ( _rControlBoundRect.GetWidth() >= 3 * _rControlBoundRect.GetHeight() );
418 if ( xPSI->hasPropertyByName( FM_PROP_DROPDOWN ) )
419 _rxControlModel->setPropertyValue( FM_PROP_DROPDOWN, makeAny( bDropDown ) );
420 _rxControlModel->setPropertyValue( FM_PROP_LINECOUNT, makeAny( sal_Int16( 20 ) ) );
422 break;
424 case FormComponentType::TEXTFIELD:
426 initializeTextFieldLineEnds( _rxControlModel );
427 lcl_initializeCharacterAttributes( _rxControlModel );
429 if ( !_rControlBoundRect.IsEmpty()
430 && ( _rControlBoundRect.GetWidth() <= 4 * _rControlBoundRect.GetHeight() )
433 if ( xPSI->hasPropertyByName( FM_PROP_MULTILINE ) )
434 _rxControlModel->setPropertyValue( FM_PROP_MULTILINE, makeAny( true ) );
437 break;
439 case FormComponentType::RADIOBUTTON:
440 case FormComponentType::CHECKBOX:
441 case FormComponentType::FIXEDTEXT:
443 OUString sVertAlignPropertyName( "VerticalAlign" );
444 if ( xPSI->hasPropertyByName( sVertAlignPropertyName ) )
445 _rxControlModel->setPropertyValue( sVertAlignPropertyName, makeAny( VerticalAlignment_MIDDLE ) );
447 break;
449 case FormComponentType::IMAGEBUTTON:
450 case FormComponentType::IMAGECONTROL:
452 const OUString sScaleModeProperty( "ScaleMode" );
453 if ( xPSI->hasPropertyByName( sScaleModeProperty ) )
454 _rxControlModel->setPropertyValue( sScaleModeProperty, makeAny( ImageScaleMode::ISOTROPIC ) );
456 break;
459 // initial default label for the control
460 if ( xPSI->hasPropertyByName( FM_PROP_LABEL ) )
462 OUString sExistingLabel;
463 OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_LABEL ) >>= sExistingLabel );
464 if ( sExistingLabel.isEmpty() )
466 OUString sInitialLabel;
467 OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_NAME ) >>= sInitialLabel );
469 const char* pTitleResId = nullptr;
470 switch ( nClassId )
472 case FormComponentType::COMMANDBUTTON: pTitleResId = RID_STR_PROPTITLE_PUSHBUTTON; break;
473 case FormComponentType::RADIOBUTTON: pTitleResId = RID_STR_PROPTITLE_RADIOBUTTON; break;
474 case FormComponentType::CHECKBOX: pTitleResId = RID_STR_PROPTITLE_CHECKBOX; break;
475 case FormComponentType::GROUPBOX: pTitleResId = RID_STR_PROPTITLE_GROUPBOX; break;
476 case FormComponentType::FIXEDTEXT: pTitleResId = RID_STR_PROPTITLE_FIXEDTEXT; break;
479 if (pTitleResId)
480 sInitialLabel = SvxResId(pTitleResId);
482 _rxControlModel->setPropertyValue(
483 FM_PROP_LABEL,
484 makeAny( lcl_getUniqueLabel_nothrow( _rxControlModel, sInitialLabel ) )
489 // strict format = yes is the default (i93467)
490 if ( xPSI->hasPropertyByName( FM_PROP_STRICTFORMAT ) )
492 _rxControlModel->setPropertyValue( FM_PROP_STRICTFORMAT, makeAny( true ) );
495 // mouse wheel: don't use it for scrolling by default (i110036)
496 if ( xPSI->hasPropertyByName( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) )
498 _rxControlModel->setPropertyValue( FM_PROP_MOUSE_WHEEL_BEHAVIOR, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) );
501 if ( xPSI->hasPropertyByName( FM_PROP_WRITING_MODE ) )
502 _rxControlModel->setPropertyValue( FM_PROP_WRITING_MODE, makeAny( WritingMode2::CONTEXT ) );
504 catch( const Exception& )
506 DBG_UNHANDLED_EXCEPTION("svx");
508 return nClassId;
512 void FormControlFactory::initializeTextFieldLineEnds( const Reference< XPropertySet >& _rxModel )
514 OSL_PRECOND( _rxModel.is(), "initializeTextFieldLineEnds: invalid model!" );
515 if ( !_rxModel.is() )
516 return;
520 Reference< XPropertySetInfo > xInfo = _rxModel->getPropertySetInfo();
521 if ( !xInfo.is() || !xInfo->hasPropertyByName( FM_PROP_LINEENDFORMAT ) )
522 return;
524 // let's see if the data source which the form belongs to (if any)
525 // has a setting for the preferred line end format
526 bool bDosLineEnds = false;
527 Sequence< PropertyValue > aInfo = lcl_getDataSourceIndirectProperties( _rxModel, m_pData->m_xContext );
528 const PropertyValue* pInfo = std::find_if(aInfo.begin(), aInfo.end(),
529 [](const PropertyValue& rInfo) { return rInfo.Name == "PreferDosLikeLineEnds"; });
530 if (pInfo != aInfo.end())
531 pInfo->Value >>= bDosLineEnds;
533 sal_Int16 nLineEndFormat = bDosLineEnds ? LineEndFormat::CARRIAGE_RETURN_LINE_FEED : LineEndFormat::LINE_FEED;
534 _rxModel->setPropertyValue( FM_PROP_LINEENDFORMAT, makeAny( nLineEndFormat ) );
536 catch( const Exception& )
538 DBG_UNHANDLED_EXCEPTION("svx");
543 void FormControlFactory::initializeFieldDependentProperties( const Reference< XPropertySet >& _rxDatabaseField,
544 const Reference< XPropertySet >& _rxControlModel, const Reference< XNumberFormats >& _rxNumberFormats )
546 OSL_PRECOND( _rxDatabaseField.is() && _rxControlModel.is(),
547 "FormControlFactory::initializeFieldDependentProperties: illegal params!" );
548 if ( !_rxDatabaseField.is() || !_rxControlModel.is() )
549 return;
554 // if the field has a numeric format, and the model has a "Scale" property, sync it
555 Reference< XPropertySetInfo > xFieldPSI( _rxDatabaseField->getPropertySetInfo(), UNO_SET_THROW );
556 Reference< XPropertySetInfo > xModelPSI( _rxControlModel->getPropertySetInfo(), UNO_SET_THROW );
558 if ( xModelPSI->hasPropertyByName( FM_PROP_DECIMAL_ACCURACY ) )
560 sal_Int32 nFormatKey = 0;
561 if ( xFieldPSI->hasPropertyByName( FM_PROP_FORMATKEY ) )
563 _rxDatabaseField->getPropertyValue( FM_PROP_FORMATKEY ) >>= nFormatKey;
565 else
567 nFormatKey = getDefaultNumberFormat(
568 _rxDatabaseField,
569 Reference< XNumberFormatTypes >( _rxNumberFormats, UNO_QUERY ),
570 SvtSysLocale().GetLanguageTag().getLocale()
574 Any aScaleVal( ::comphelper::getNumberFormatDecimals( _rxNumberFormats, nFormatKey ) );
575 _rxControlModel->setPropertyValue( FM_PROP_DECIMAL_ACCURACY, aScaleVal );
579 // minimum and maximum of the control according to the type of the database field
580 sal_Int32 nDataType = DataType::OTHER;
581 OSL_VERIFY( _rxDatabaseField->getPropertyValue( FM_PROP_FIELDTYPE ) >>= nDataType );
583 if ( xModelPSI->hasPropertyByName( FM_PROP_VALUEMIN )
584 && xModelPSI->hasPropertyByName( FM_PROP_VALUEMAX )
587 sal_Int32 nMinValue = -1000000000, nMaxValue = 1000000000;
588 switch ( nDataType )
590 case DataType::TINYINT : nMinValue = 0; nMaxValue = 255; break;
591 case DataType::SMALLINT : nMinValue = -32768; nMaxValue = 32767; break;
592 case DataType::INTEGER : nMinValue = 0x80000000; nMaxValue = 0x7FFFFFFF; break;
593 // double and singles are ignored
596 Any aValue;
598 // both the minimum and the maximum value properties can be either Long or Double
599 Property aProperty = xModelPSI->getPropertyByName( FM_PROP_VALUEMIN );
600 if ( aProperty.Type.getTypeClass() == TypeClass_DOUBLE )
601 aValue <<= static_cast<double>(nMinValue);
602 else if ( aProperty.Type.getTypeClass() == TypeClass_LONG )
603 aValue <<= nMinValue;
604 else
606 OSL_FAIL( "FormControlFactory::initializeFieldDependentProperties: unexpected property type (MinValue)!" );
608 _rxControlModel->setPropertyValue( FM_PROP_VALUEMIN, aValue );
610 // both the minimum and the maximum value properties can be either Long or Double
611 aProperty = xModelPSI->getPropertyByName( FM_PROP_VALUEMAX );
612 if ( aProperty.Type.getTypeClass() == TypeClass_DOUBLE )
613 aValue <<= static_cast<double>(nMaxValue);
614 else if ( aProperty.Type.getTypeClass() == TypeClass_LONG )
615 aValue <<= nMaxValue;
616 else
618 OSL_FAIL( "FormControlFactory::initializeFieldDependentProperties: unexpected property type (MaxValue)!" );
620 _rxControlModel->setPropertyValue( FM_PROP_VALUEMAX, aValue );
624 // a check box can be tristate if and only if the column it is bound to is nullable
625 sal_Int16 nClassId = FormComponentType::CONTROL;
626 OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
627 if ( nClassId == FormComponentType::CHECKBOX )
629 sal_Int32 nNullable = ColumnValue::NULLABLE_UNKNOWN;
630 OSL_VERIFY( _rxDatabaseField->getPropertyValue( FM_PROP_ISNULLABLE ) >>= nNullable );
631 _rxControlModel->setPropertyValue( FM_PROP_TRISTATE, makeAny( ColumnValue::NO_NULLS != nNullable ) );
634 catch( const Exception& )
636 DBG_UNHANDLED_EXCEPTION("svx");
641 OUString FormControlFactory::getDefaultName( sal_Int16 _nClassId, const Reference< XServiceInfo >& _rxObject )
643 const char* pResId(nullptr);
645 switch ( _nClassId )
647 case FormComponentType::COMMANDBUTTON: pResId = RID_STR_PROPTITLE_PUSHBUTTON; break;
648 case FormComponentType::RADIOBUTTON: pResId = RID_STR_PROPTITLE_RADIOBUTTON; break;
649 case FormComponentType::CHECKBOX: pResId = RID_STR_PROPTITLE_CHECKBOX; break;
650 case FormComponentType::LISTBOX: pResId = RID_STR_PROPTITLE_LISTBOX; break;
651 case FormComponentType::COMBOBOX: pResId = RID_STR_PROPTITLE_COMBOBOX; break;
652 case FormComponentType::GROUPBOX: pResId = RID_STR_PROPTITLE_GROUPBOX; break;
653 case FormComponentType::IMAGEBUTTON: pResId = RID_STR_PROPTITLE_IMAGEBUTTON; break;
654 case FormComponentType::FIXEDTEXT: pResId = RID_STR_PROPTITLE_FIXEDTEXT; break;
655 case FormComponentType::GRIDCONTROL: pResId = RID_STR_PROPTITLE_DBGRID; break;
656 case FormComponentType::FILECONTROL: pResId = RID_STR_PROPTITLE_FILECONTROL; break;
657 case FormComponentType::DATEFIELD: pResId = RID_STR_PROPTITLE_DATEFIELD; break;
658 case FormComponentType::TIMEFIELD: pResId = RID_STR_PROPTITLE_TIMEFIELD; break;
659 case FormComponentType::NUMERICFIELD: pResId = RID_STR_PROPTITLE_NUMERICFIELD; break;
660 case FormComponentType::CURRENCYFIELD: pResId = RID_STR_PROPTITLE_CURRENCYFIELD; break;
661 case FormComponentType::PATTERNFIELD: pResId = RID_STR_PROPTITLE_PATTERNFIELD; break;
662 case FormComponentType::IMAGECONTROL: pResId = RID_STR_PROPTITLE_IMAGECONTROL; break;
663 case FormComponentType::HIDDENCONTROL: pResId = RID_STR_PROPTITLE_HIDDEN; break;
664 case FormComponentType::SCROLLBAR: pResId = RID_STR_PROPTITLE_SCROLLBAR; break;
665 case FormComponentType::SPINBUTTON: pResId = RID_STR_PROPTITLE_SPINBUTTON; break;
666 case FormComponentType::NAVIGATIONBAR: pResId = RID_STR_PROPTITLE_NAVBAR; break;
668 case FormComponentType::TEXTFIELD:
669 pResId = RID_STR_PROPTITLE_EDIT;
670 if ( _rxObject.is() && _rxObject->supportsService( FM_SUN_COMPONENT_FORMATTEDFIELD ) )
671 pResId = RID_STR_PROPTITLE_FORMATTED;
672 break;
674 default:
675 pResId = RID_STR_CONTROL; break;
678 return SvxResId(pResId);
682 OUString FormControlFactory::getDefaultUniqueName_ByComponentType( const Reference< XNameAccess >& _rxContainer,
683 const Reference< XPropertySet >& _rxObject )
685 sal_Int16 nClassId = FormComponentType::CONTROL;
686 OSL_VERIFY( _rxObject->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
687 OUString sBaseName = getDefaultName( nClassId, Reference< XServiceInfo >( _rxObject, UNO_QUERY ) );
689 return getUniqueName( _rxContainer, sBaseName );
693 OUString FormControlFactory::getUniqueName( const Reference< XNameAccess >& _rxContainer, const OUString& _rBaseName )
695 sal_Int32 n = 0;
696 OUString sName;
699 OUStringBuffer aBuf( _rBaseName );
700 aBuf.append( " " );
701 aBuf.append( ++n );
702 sName = aBuf.makeStringAndClear();
704 while ( _rxContainer->hasByName( sName ) );
706 return sName;
713 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */