Simplify a bit
[LibreOffice.git] / svx / source / form / formcontrolfactory.cxx
blob1b32f7e8f3960ddec5055c8bd1fee5c24e20e827
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/sdbc/XDataSource.hpp>
39 #include <com/sun/star/util/XNumberFormatTypes.hpp>
40 #include <com/sun/star/sdbc/ColumnValue.hpp>
41 #include <com/sun/star/text/WritingMode2.hpp>
43 #include <comphelper/numbers.hxx>
44 #include <comphelper/processfactory.hxx>
45 #include <unotools/syslocale.hxx>
46 #include <tools/gen.hxx>
47 #include <comphelper/diagnose_ex.hxx>
48 #include <connectivity/dbtools.hxx>
49 #include <i18nlangtag/languagetag.hxx>
51 #include <set>
53 using namespace ::dbtools;
55 namespace svxform
59 using ::com::sun::star::uno::Reference;
60 using ::com::sun::star::uno::UNO_QUERY;
61 using ::com::sun::star::uno::UNO_QUERY_THROW;
62 using ::com::sun::star::uno::UNO_SET_THROW;
63 using ::com::sun::star::uno::Exception;
64 using ::com::sun::star::uno::Any;
65 using ::com::sun::star::uno::Sequence;
66 using ::com::sun::star::uno::XComponentContext;
67 using ::com::sun::star::beans::XPropertySet;
68 using ::com::sun::star::form::XFormComponent;
69 using ::com::sun::star::container::XIndexAccess;
70 using ::com::sun::star::beans::XPropertySetInfo;
71 using ::com::sun::star::beans::PropertyValue;
72 using ::com::sun::star::container::XChild;
73 using ::com::sun::star::form::XGridColumnFactory;
74 using ::com::sun::star::style::VerticalAlignment_MIDDLE;
75 using ::com::sun::star::beans::Property;
76 using ::com::sun::star::uno::TypeClass_DOUBLE;
77 using ::com::sun::star::uno::TypeClass_LONG;
78 using ::com::sun::star::util::XNumberFormats;
79 using ::com::sun::star::util::XNumberFormatTypes;
80 using ::com::sun::star::lang::XServiceInfo;
81 using ::com::sun::star::container::XNameAccess;
83 namespace FormComponentType = ::com::sun::star::form::FormComponentType;
84 namespace ScrollBarOrientation = ::com::sun::star::awt::ScrollBarOrientation;
85 namespace MouseWheelBehavior = ::com::sun::star::awt::MouseWheelBehavior;
86 namespace LineEndFormat = ::com::sun::star::awt::LineEndFormat;
87 namespace ImageScaleMode = ::com::sun::star::awt::ImageScaleMode;
88 namespace DataType = ::com::sun::star::sdbc::DataType;
89 namespace ColumnValue = ::com::sun::star::sdbc::ColumnValue;
90 namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
92 FormControlFactory::FormControlFactory( const Reference<XComponentContext>& _rContext )
93 :m_xContext( _rContext )
97 FormControlFactory::FormControlFactory( )
98 :m_xContext( comphelper::getProcessComponentContext() )
103 FormControlFactory::~FormControlFactory()
108 sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const SdrUnoObj& _rObject )
110 return initializeControlModel(
111 _eDocType,
112 Reference< XPropertySet >( _rObject.GetUnoControlModel(), UNO_QUERY ),
113 _rObject.GetCurrentBoundRect()
118 void FormControlFactory::initializeControlModel( const DocumentType _eDocType, const Reference< XPropertySet >& _rxControlModel )
120 initializeControlModel(
121 _eDocType, _rxControlModel, tools::Rectangle()
126 namespace
129 OUString lcl_getUniqueLabel_nothrow( const Reference< XPropertySet >& _rxControlModel, const OUString& _rBaseLabel )
131 OUString sLabel( _rBaseLabel );
134 typedef ::std::set< OUString > StringBag;
135 StringBag aUsedLabels;
137 Reference< XFormComponent > xFormComponent( _rxControlModel, UNO_QUERY_THROW );
138 Reference< XIndexAccess > xContainer( xFormComponent->getParent(), UNO_QUERY_THROW );
139 // loop through all siblings of the control model, and collect their labels
140 for ( sal_Int32 index=xContainer->getCount(); index>0; )
142 Reference< XPropertySet > xElement( xContainer->getByIndex( --index ), UNO_QUERY_THROW );
143 if ( xElement == _rxControlModel )
144 continue;
146 Reference< XPropertySetInfo > xPSI( xElement->getPropertySetInfo(), UNO_SET_THROW );
147 if ( !xPSI->hasPropertyByName( FM_PROP_LABEL ) )
148 continue;
150 OUString sElementLabel;
151 OSL_VERIFY( xElement->getPropertyValue( FM_PROP_LABEL ) >>= sElementLabel );
152 aUsedLabels.insert( sElementLabel );
155 // now find a free label
156 sal_Int32 i=2;
157 while ( aUsedLabels.find( sLabel ) != aUsedLabels.end() )
158 sLabel = _rBaseLabel + " " + OUString::number( i++ );
160 catch( const Exception& )
162 DBG_UNHANDLED_EXCEPTION("svx");
164 return sLabel;
168 Sequence< PropertyValue > lcl_getDataSourceIndirectProperties( const Reference< XPropertySet >& _rxControlModel,
169 const Reference<XComponentContext>& _rContext )
171 OSL_PRECOND( _rxControlModel.is(), "lcl_getDataSourceIndirectProperties: invalid model!" );
173 Sequence< PropertyValue > aInfo;
176 Reference< XChild > xChild( _rxControlModel, UNO_QUERY );
177 Reference< XPropertySet > xForm;
178 if ( xChild.is() )
179 xForm.set(xChild->getParent(), css::uno::UNO_QUERY);
181 if ( Reference< XGridColumnFactory >( xForm, UNO_QUERY ).is() )
182 { // hmm. the model is a grid column, in real
183 xChild.set(xForm, css::uno::UNO_QUERY);
184 xForm.set(xChild->getParent(), css::uno::UNO_QUERY);
187 OSL_ENSURE( xForm.is(), "lcl_getDataSourceIndirectProperties: could not determine the form!" );
188 if ( !xForm.is() )
189 return aInfo;
190 OUString sDataSourceName;
191 xForm->getPropertyValue( FM_PROP_DATASOURCE ) >>= sDataSourceName;
193 Reference< XPropertySet > xDsProperties;
194 if ( !sDataSourceName.isEmpty() )
195 xDsProperties.set(getDataSource( sDataSourceName, _rContext ), css::uno::UNO_QUERY);
196 if ( xDsProperties.is() )
197 xDsProperties->getPropertyValue(u"Info"_ustr) >>= aInfo;
199 catch( const Exception& )
201 TOOLS_WARN_EXCEPTION( "svx", "lcl_getDataSourceIndirectProperties" );
203 return aInfo;
207 constexpr OUString aCharacterAndParagraphProperties[]
209 u"CharFontName"_ustr,
210 u"CharFontStyleName"_ustr,
211 u"CharFontFamily"_ustr,
212 u"CharFontCharSet"_ustr,
213 u"CharFontPitch"_ustr,
214 u"CharColor"_ustr,
215 u"CharEscapement"_ustr,
216 u"CharHeight"_ustr,
217 u"CharUnderline"_ustr,
218 u"CharWeight"_ustr,
219 u"CharPosture"_ustr,
220 u"CharAutoKerning"_ustr,
221 u"CharBackColor"_ustr,
222 u"CharBackTransparent"_ustr,
223 u"CharCaseMap"_ustr,
224 u"CharCrossedOut"_ustr,
225 u"CharFlash"_ustr,
226 u"CharStrikeout"_ustr,
227 u"CharWordMode"_ustr,
228 u"CharKerning"_ustr,
229 u"CharLocale"_ustr,
230 u"CharKeepTogether"_ustr,
231 u"CharNoLineBreak"_ustr,
232 u"CharShadowed"_ustr,
233 u"CharFontType"_ustr,
234 u"CharStyleName"_ustr,
235 u"CharContoured"_ustr,
236 u"CharCombineIsOn"_ustr,
237 u"CharCombinePrefix"_ustr,
238 u"CharCombineSuffix"_ustr,
239 u"CharEmphasize"_ustr,
240 u"CharRelief"_ustr,
241 u"RubyText"_ustr,
242 u"RubyAdjust"_ustr,
243 u"RubyCharStyleName"_ustr,
244 u"RubyIsAbove"_ustr,
245 u"CharRotation"_ustr,
246 u"CharRotationIsFitToLine"_ustr,
247 u"CharScaleWidth"_ustr,
248 u"HyperLinkURL"_ustr,
249 u"HyperLinkTarget"_ustr,
250 u"HyperLinkName"_ustr,
251 u"VisitedCharStyleName"_ustr,
252 u"UnvisitedCharStyleName"_ustr,
253 u"CharEscapementHeight"_ustr,
254 u"CharNoHyphenation"_ustr,
255 u"CharUnderlineColor"_ustr,
256 u"CharUnderlineHasColor"_ustr,
257 u"CharStyleNames"_ustr,
258 u"CharHeightAsian"_ustr,
259 u"CharWeightAsian"_ustr,
260 u"CharFontNameAsian"_ustr,
261 u"CharFontStyleNameAsian"_ustr,
262 u"CharFontFamilyAsian"_ustr,
263 u"CharFontCharSetAsian"_ustr,
264 u"CharFontPitchAsian"_ustr,
265 u"CharPostureAsian"_ustr,
266 u"CharLocaleAsian"_ustr,
267 u"ParaIsCharacterDistance"_ustr,
268 u"ParaIsForbiddenRules"_ustr,
269 u"ParaIsHangingPunctuation"_ustr,
270 u"CharHeightComplex"_ustr,
271 u"CharWeightComplex"_ustr,
272 u"CharFontNameComplex"_ustr,
273 u"CharFontStyleNameComplex"_ustr,
274 u"CharFontFamilyComplex"_ustr,
275 u"CharFontCharSetComplex"_ustr,
276 u"CharFontPitchComplex"_ustr,
277 u"CharPostureComplex"_ustr,
278 u"CharLocaleComplex"_ustr,
279 u"ParaAdjust"_ustr,
280 u"ParaLineSpacing"_ustr,
281 u"ParaBackColor"_ustr,
282 u"ParaBackTransparent"_ustr,
283 u"ParaBackGraphic"_ustr,
284 u"ParaBackGraphicURL"_ustr,
285 u"ParaBackGraphicFilter"_ustr,
286 u"ParaBackGraphicLocation"_ustr,
287 u"ParaLastLineAdjust"_ustr,
288 u"ParaExpandSingleWord"_ustr,
289 u"ParaLeftMargin"_ustr,
290 u"ParaRightMargin"_ustr,
291 u"ParaTopMargin"_ustr,
292 u"ParaBottomMargin"_ustr,
293 u"ParaLineNumberCount"_ustr,
294 u"ParaLineNumberStartValue"_ustr,
295 u"PageDescName"_ustr,
296 u"PageNumberOffset"_ustr,
297 u"ParaRegisterModeActive"_ustr,
298 u"ParaTabStops"_ustr,
299 u"ParaStyleName"_ustr,
300 u"DropCapFormat"_ustr,
301 u"DropCapWholeWord"_ustr,
302 u"ParaKeepTogether"_ustr,
303 u"Setting"_ustr,
304 u"ParaSplit"_ustr,
305 u"Setting"_ustr,
306 u"NumberingLevel"_ustr,
307 u"NumberingRules"_ustr,
308 u"NumberingStartValue"_ustr,
309 u"ParaIsNumberingRestart"_ustr,
310 u"NumberingStyleName"_ustr,
311 u"ParaOrphans"_ustr,
312 u"ParaWidows"_ustr,
313 u"ParaShadowFormat"_ustr,
314 u"LeftBorder"_ustr,
315 u"RightBorder"_ustr,
316 u"TopBorder"_ustr,
317 u"BottomBorder"_ustr,
318 u"BorderDistance"_ustr,
319 u"LeftBorderDistance"_ustr,
320 u"RightBorderDistance"_ustr,
321 u"TopBorderDistance"_ustr,
322 u"BottomBorderDistance"_ustr,
323 u"BreakType"_ustr,
324 u"DropCapCharStyleName"_ustr,
325 u"ParaFirstLineIndent"_ustr,
326 u"ParaIsAutoFirstLineIndent"_ustr,
327 u"ParaIsHyphenation"_ustr,
328 u"ParaHyphenationMaxHyphens"_ustr,
329 u"ParaHyphenationMaxLeadingChars"_ustr,
330 u"ParaHyphenationMaxTrailingChars"_ustr,
331 u"ParaVertAlignment"_ustr,
332 u"ParaUserDefinedAttributes"_ustr,
333 u"NumberingIsNumber"_ustr,
334 u"ParaIsConnectBorder"_ustr
338 void lcl_initializeCharacterAttributes( const Reference< XPropertySet >& _rxModel )
342 Reference< XPropertySet > xStyle( ControlLayouter::getDefaultDocumentTextStyle( _rxModel ), UNO_SET_THROW );
344 // transfer all properties which are described by the style
345 Reference< XPropertySetInfo > xSourcePropInfo( xStyle->getPropertySetInfo(), UNO_SET_THROW );
346 Reference< XPropertySetInfo > xDestPropInfo( _rxModel->getPropertySetInfo(), UNO_SET_THROW );
348 for (const OUString & sPropertyName : aCharacterAndParagraphProperties)
350 if ( xSourcePropInfo->hasPropertyByName( sPropertyName ) && xDestPropInfo->hasPropertyByName( sPropertyName ) )
351 _rxModel->setPropertyValue( sPropertyName, xStyle->getPropertyValue( sPropertyName ) );
354 catch( const Exception& )
356 DBG_UNHANDLED_EXCEPTION("svx");
362 sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const Reference< XPropertySet >& _rxControlModel,
363 const tools::Rectangle& _rControlBoundRect )
365 sal_Int16 nClassId = FormComponentType::CONTROL;
367 OSL_ENSURE( _rxControlModel.is(), "FormControlFactory::initializeControlModel: invalid model!" );
368 if ( !_rxControlModel.is() )
369 return nClassId;
373 ControlLayouter::initializeControlLayout( _rxControlModel, _eDocType );
375 _rxControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId;
376 Reference< XPropertySetInfo > xPSI( _rxControlModel->getPropertySetInfo(), UNO_SET_THROW );
377 switch ( nClassId )
379 case FormComponentType::SCROLLBAR:
380 _rxControlModel->setPropertyValue(u"LiveScroll"_ustr, Any( true ) );
381 [[fallthrough]];
382 case FormComponentType::SPINBUTTON:
384 sal_Int32 eOrientation = ScrollBarOrientation::HORIZONTAL;
385 if ( !_rControlBoundRect.IsEmpty() && ( _rControlBoundRect.GetWidth() < _rControlBoundRect.GetHeight() ) )
386 eOrientation = ScrollBarOrientation::VERTICAL;
387 _rxControlModel->setPropertyValue( FM_PROP_ORIENTATION, Any( eOrientation ) );
389 break;
391 case FormComponentType::LISTBOX:
392 case FormComponentType::COMBOBOX:
394 bool bDropDown = !_rControlBoundRect.IsEmpty() && ( _rControlBoundRect.GetWidth() >= 3 * _rControlBoundRect.GetHeight() );
395 if ( xPSI->hasPropertyByName( FM_PROP_DROPDOWN ) )
396 _rxControlModel->setPropertyValue( FM_PROP_DROPDOWN, Any( bDropDown ) );
397 _rxControlModel->setPropertyValue( FM_PROP_LINECOUNT, Any( sal_Int16( 20 ) ) );
399 break;
401 case FormComponentType::TEXTFIELD:
403 initializeTextFieldLineEnds( _rxControlModel );
404 lcl_initializeCharacterAttributes( _rxControlModel );
406 if ( !_rControlBoundRect.IsEmpty()
407 && ( _rControlBoundRect.GetWidth() <= 4 * _rControlBoundRect.GetHeight() )
410 if ( xPSI->hasPropertyByName( FM_PROP_MULTILINE ) )
411 _rxControlModel->setPropertyValue( FM_PROP_MULTILINE, Any( true ) );
414 break;
416 case FormComponentType::RADIOBUTTON:
417 case FormComponentType::CHECKBOX:
418 case FormComponentType::FIXEDTEXT:
420 OUString sVertAlignPropertyName( u"VerticalAlign"_ustr );
421 if ( xPSI->hasPropertyByName( sVertAlignPropertyName ) )
422 _rxControlModel->setPropertyValue( sVertAlignPropertyName, Any( VerticalAlignment_MIDDLE ) );
424 break;
426 case FormComponentType::IMAGEBUTTON:
427 case FormComponentType::IMAGECONTROL:
429 static constexpr OUString sScaleModeProperty( u"ScaleMode"_ustr );
430 if ( xPSI->hasPropertyByName( sScaleModeProperty ) )
431 _rxControlModel->setPropertyValue( sScaleModeProperty, Any( ImageScaleMode::ISOTROPIC ) );
433 break;
436 // initial default label for the control
437 if ( xPSI->hasPropertyByName( FM_PROP_LABEL ) )
439 OUString sExistingLabel;
440 OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_LABEL ) >>= sExistingLabel );
441 if ( sExistingLabel.isEmpty() )
443 OUString sInitialLabel;
444 OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_NAME ) >>= sInitialLabel );
446 TranslateId pTitleResId;
447 switch ( nClassId )
449 case FormComponentType::COMMANDBUTTON: pTitleResId = RID_STR_PROPTITLE_PUSHBUTTON; break;
450 case FormComponentType::RADIOBUTTON: pTitleResId = RID_STR_PROPTITLE_RADIOBUTTON; break;
451 case FormComponentType::CHECKBOX: pTitleResId = RID_STR_PROPTITLE_CHECKBOX; break;
452 case FormComponentType::GROUPBOX: pTitleResId = RID_STR_PROPTITLE_GROUPBOX; break;
453 case FormComponentType::FIXEDTEXT: pTitleResId = RID_STR_PROPTITLE_FIXEDTEXT; break;
456 if (pTitleResId)
457 sInitialLabel = SvxResId(pTitleResId);
459 _rxControlModel->setPropertyValue(
460 FM_PROP_LABEL,
461 Any( lcl_getUniqueLabel_nothrow( _rxControlModel, sInitialLabel ) )
466 // strict format = yes is the default (i93467)
467 if ( xPSI->hasPropertyByName( FM_PROP_STRICTFORMAT ) )
469 _rxControlModel->setPropertyValue( FM_PROP_STRICTFORMAT, Any( true ) );
472 // mouse wheel: don't use it for scrolling by default (i110036)
473 if ( xPSI->hasPropertyByName( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) )
475 _rxControlModel->setPropertyValue( FM_PROP_MOUSE_WHEEL_BEHAVIOR, Any( MouseWheelBehavior::SCROLL_DISABLED ) );
478 if ( xPSI->hasPropertyByName( FM_PROP_WRITING_MODE ) )
479 _rxControlModel->setPropertyValue( FM_PROP_WRITING_MODE, Any( WritingMode2::CONTEXT ) );
481 catch( const Exception& )
483 DBG_UNHANDLED_EXCEPTION("svx");
485 return nClassId;
489 void FormControlFactory::initializeTextFieldLineEnds( const Reference< XPropertySet >& _rxModel )
491 OSL_PRECOND( _rxModel.is(), "initializeTextFieldLineEnds: invalid model!" );
492 if ( !_rxModel.is() )
493 return;
497 Reference< XPropertySetInfo > xInfo = _rxModel->getPropertySetInfo();
498 if ( !xInfo.is() || !xInfo->hasPropertyByName( FM_PROP_LINEENDFORMAT ) )
499 return;
501 // let's see if the data source which the form belongs to (if any)
502 // has a setting for the preferred line end format
503 bool bDosLineEnds = false;
504 const Sequence< PropertyValue > aInfo = lcl_getDataSourceIndirectProperties( _rxModel, m_xContext );
505 const PropertyValue* pInfo = std::find_if(aInfo.begin(), aInfo.end(),
506 [](const PropertyValue& rInfo) { return rInfo.Name == "PreferDosLikeLineEnds"; });
507 if (pInfo != aInfo.end())
508 pInfo->Value >>= bDosLineEnds;
510 sal_Int16 nLineEndFormat = bDosLineEnds ? LineEndFormat::CARRIAGE_RETURN_LINE_FEED : LineEndFormat::LINE_FEED;
511 _rxModel->setPropertyValue( FM_PROP_LINEENDFORMAT, Any( nLineEndFormat ) );
513 catch( const Exception& )
515 DBG_UNHANDLED_EXCEPTION("svx");
520 void FormControlFactory::initializeFieldDependentProperties( const Reference< XPropertySet >& _rxDatabaseField,
521 const Reference< XPropertySet >& _rxControlModel, const Reference< XNumberFormats >& _rxNumberFormats )
523 OSL_PRECOND( _rxDatabaseField.is() && _rxControlModel.is(),
524 "FormControlFactory::initializeFieldDependentProperties: illegal params!" );
525 if ( !_rxDatabaseField.is() || !_rxControlModel.is() )
526 return;
531 // if the field has a numeric format, and the model has a "Scale" property, sync it
532 Reference< XPropertySetInfo > xFieldPSI( _rxDatabaseField->getPropertySetInfo(), UNO_SET_THROW );
533 Reference< XPropertySetInfo > xModelPSI( _rxControlModel->getPropertySetInfo(), UNO_SET_THROW );
535 if ( xModelPSI->hasPropertyByName( FM_PROP_DECIMAL_ACCURACY ) )
537 sal_Int32 nFormatKey = 0;
538 if ( xFieldPSI->hasPropertyByName( FM_PROP_FORMATKEY ) )
540 _rxDatabaseField->getPropertyValue( FM_PROP_FORMATKEY ) >>= nFormatKey;
542 else
544 nFormatKey = getDefaultNumberFormat(
545 _rxDatabaseField,
546 Reference< XNumberFormatTypes >( _rxNumberFormats, UNO_QUERY ),
547 SvtSysLocale().GetLanguageTag().getLocale()
551 Any aScaleVal( ::comphelper::getNumberFormatDecimals( _rxNumberFormats, nFormatKey ) );
552 _rxControlModel->setPropertyValue( FM_PROP_DECIMAL_ACCURACY, aScaleVal );
556 // minimum and maximum of the control according to the type of the database field
557 sal_Int32 nDataType = DataType::OTHER;
558 OSL_VERIFY( _rxDatabaseField->getPropertyValue( FM_PROP_FIELDTYPE ) >>= nDataType );
560 if ( xModelPSI->hasPropertyByName( FM_PROP_VALUEMIN )
561 && xModelPSI->hasPropertyByName( FM_PROP_VALUEMAX )
564 sal_Int32 nMinValue = -1000000000, nMaxValue = 1000000000;
565 switch ( nDataType )
567 case DataType::TINYINT : nMinValue = 0; nMaxValue = 255; break;
568 case DataType::SMALLINT : nMinValue = -32768; nMaxValue = 32767; break;
569 case DataType::INTEGER : nMinValue = 0x80000000; nMaxValue = 0x7FFFFFFF; break;
570 // double and singles are ignored
573 Any aValue;
575 // both the minimum and the maximum value properties can be either Long or Double
576 Property aProperty = xModelPSI->getPropertyByName( FM_PROP_VALUEMIN );
577 if ( aProperty.Type.getTypeClass() == TypeClass_DOUBLE )
578 aValue <<= static_cast<double>(nMinValue);
579 else if ( aProperty.Type.getTypeClass() == TypeClass_LONG )
580 aValue <<= nMinValue;
581 else
583 OSL_FAIL( "FormControlFactory::initializeFieldDependentProperties: unexpected property type (MinValue)!" );
585 _rxControlModel->setPropertyValue( FM_PROP_VALUEMIN, aValue );
587 // both the minimum and the maximum value properties can be either Long or Double
588 aProperty = xModelPSI->getPropertyByName( FM_PROP_VALUEMAX );
589 if ( aProperty.Type.getTypeClass() == TypeClass_DOUBLE )
590 aValue <<= static_cast<double>(nMaxValue);
591 else if ( aProperty.Type.getTypeClass() == TypeClass_LONG )
592 aValue <<= nMaxValue;
593 else
595 OSL_FAIL( "FormControlFactory::initializeFieldDependentProperties: unexpected property type (MaxValue)!" );
597 _rxControlModel->setPropertyValue( FM_PROP_VALUEMAX, aValue );
601 // a check box can be tristate if and only if the column it is bound to is nullable
602 sal_Int16 nClassId = FormComponentType::CONTROL;
603 OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
604 if ( nClassId == FormComponentType::CHECKBOX )
606 sal_Int32 nNullable = ColumnValue::NULLABLE_UNKNOWN;
607 OSL_VERIFY( _rxDatabaseField->getPropertyValue( FM_PROP_ISNULLABLE ) >>= nNullable );
608 _rxControlModel->setPropertyValue( FM_PROP_TRISTATE, Any( ColumnValue::NO_NULLS != nNullable ) );
611 catch( const Exception& )
613 DBG_UNHANDLED_EXCEPTION("svx");
618 OUString FormControlFactory::getDefaultName( sal_Int16 _nClassId, const Reference< XServiceInfo >& _rxObject )
620 TranslateId pResId;
622 switch ( _nClassId )
624 case FormComponentType::COMMANDBUTTON: pResId = RID_STR_PROPTITLE_PUSHBUTTON; break;
625 case FormComponentType::RADIOBUTTON: pResId = RID_STR_PROPTITLE_RADIOBUTTON; break;
626 case FormComponentType::CHECKBOX: pResId = RID_STR_PROPTITLE_CHECKBOX; break;
627 case FormComponentType::LISTBOX: pResId = RID_STR_PROPTITLE_LISTBOX; break;
628 case FormComponentType::COMBOBOX: pResId = RID_STR_PROPTITLE_COMBOBOX; break;
629 case FormComponentType::GROUPBOX: pResId = RID_STR_PROPTITLE_GROUPBOX; break;
630 case FormComponentType::IMAGEBUTTON: pResId = RID_STR_PROPTITLE_IMAGEBUTTON; break;
631 case FormComponentType::FIXEDTEXT: pResId = RID_STR_PROPTITLE_FIXEDTEXT; break;
632 case FormComponentType::GRIDCONTROL: pResId = RID_STR_PROPTITLE_DBGRID; break;
633 case FormComponentType::FILECONTROL: pResId = RID_STR_PROPTITLE_FILECONTROL; break;
634 case FormComponentType::DATEFIELD: pResId = RID_STR_PROPTITLE_DATEFIELD; break;
635 case FormComponentType::TIMEFIELD: pResId = RID_STR_PROPTITLE_TIMEFIELD; break;
636 case FormComponentType::NUMERICFIELD: pResId = RID_STR_PROPTITLE_NUMERICFIELD; break;
637 case FormComponentType::CURRENCYFIELD: pResId = RID_STR_PROPTITLE_CURRENCYFIELD; break;
638 case FormComponentType::PATTERNFIELD: pResId = RID_STR_PROPTITLE_PATTERNFIELD; break;
639 case FormComponentType::IMAGECONTROL: pResId = RID_STR_PROPTITLE_IMAGECONTROL; break;
640 case FormComponentType::HIDDENCONTROL: pResId = RID_STR_PROPTITLE_HIDDEN; break;
641 case FormComponentType::SCROLLBAR: pResId = RID_STR_PROPTITLE_SCROLLBAR; break;
642 case FormComponentType::SPINBUTTON: pResId = RID_STR_PROPTITLE_SPINBUTTON; break;
643 case FormComponentType::NAVIGATIONBAR: pResId = RID_STR_PROPTITLE_NAVBAR; break;
645 case FormComponentType::TEXTFIELD:
646 pResId = RID_STR_PROPTITLE_EDIT;
647 if ( _rxObject.is() && _rxObject->supportsService( FM_SUN_COMPONENT_FORMATTEDFIELD ) )
648 pResId = RID_STR_PROPTITLE_FORMATTED;
649 break;
651 default:
652 pResId = RID_STR_CONTROL; break;
655 return SvxResId(pResId);
659 OUString FormControlFactory::getDefaultUniqueName_ByComponentType( const Reference< XNameAccess >& _rxContainer,
660 const Reference< XPropertySet >& _rxObject )
662 sal_Int16 nClassId = FormComponentType::CONTROL;
663 OSL_VERIFY( _rxObject->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
664 OUString sBaseName = getDefaultName( nClassId, Reference< XServiceInfo >( _rxObject, UNO_QUERY ) );
666 return getUniqueName( _rxContainer, sBaseName );
670 OUString FormControlFactory::getUniqueName( const Reference< XNameAccess >& _rxContainer, std::u16string_view _rBaseName )
672 sal_Int32 n = 0;
673 OUString sName;
676 sName = OUString::Concat(_rBaseName) + " " + OUString::number( ++n );
678 while ( _rxContainer->hasByName( sName ) );
680 return sName;
687 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */