Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / svx / source / form / formcontrolfactory.cxx
blobc4fb5435a210ac6001ddd94fddf90384d919fe5e
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 "svx/dbtoolsclient.hxx"
22 #include "formcontrolfactory.hxx"
23 #include "fmcontrollayout.hxx"
24 #include "fmprop.hrc"
25 #include "svx/fmresids.hrc"
26 #include "fmservs.hxx"
27 #include "svx/dialmgr.hxx"
28 #include "svx/svdouno.hxx"
30 #include <com/sun/star/form/XFormComponent.hpp>
31 #include <com/sun/star/form/FormComponentType.hpp>
32 #include <com/sun/star/awt/ScrollBarOrientation.hpp>
33 #include <com/sun/star/awt/MouseWheelBehavior.hpp>
34 #include <com/sun/star/form/XGridColumnFactory.hpp>
35 #include <com/sun/star/style/VerticalAlignment.hpp>
36 #include <com/sun/star/awt/LineEndFormat.hpp>
37 #include <com/sun/star/awt/ImageScaleMode.hpp>
38 #include <com/sun/star/sdbc/DataType.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>
42 #include <com/sun/star/awt/FontDescriptor.hpp>
44 #include <comphelper/numbers.hxx>
45 #include <comphelper/processfactory.hxx>
46 #include <unotools/syslocale.hxx>
47 #include <tools/gen.hxx>
48 #include <tools/diagnose_ex.h>
50 #include <set>
53 namespace svxform
57 using ::com::sun::star::uno::Reference;
58 using ::com::sun::star::uno::XInterface;
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::RuntimeException;
64 using ::com::sun::star::uno::Any;
65 using ::com::sun::star::uno::makeAny;
66 using ::com::sun::star::uno::Sequence;
67 using ::com::sun::star::uno::Type;
68 using ::com::sun::star::uno::XComponentContext;
69 using ::com::sun::star::beans::XPropertySet;
70 using ::com::sun::star::awt::XControlModel;
71 using ::com::sun::star::form::XFormComponent;
72 using ::com::sun::star::container::XIndexAccess;
73 using ::com::sun::star::beans::XPropertySetInfo;
74 using ::com::sun::star::beans::PropertyValue;
75 using ::com::sun::star::container::XChild;
76 using ::com::sun::star::form::XGridColumnFactory;
77 using ::com::sun::star::style::VerticalAlignment_MIDDLE;
78 using ::com::sun::star::beans::Property;
79 using ::com::sun::star::uno::TypeClass_DOUBLE;
80 using ::com::sun::star::uno::TypeClass_LONG;
81 using ::com::sun::star::util::XNumberFormats;
82 using ::com::sun::star::util::XNumberFormatTypes;
83 using ::com::sun::star::awt::FontDescriptor;
84 using ::com::sun::star::lang::Locale;
85 using ::com::sun::star::lang::XServiceInfo;
86 using ::com::sun::star::container::XNameAccess;
88 namespace FormComponentType = ::com::sun::star::form::FormComponentType;
89 namespace ScrollBarOrientation = ::com::sun::star::awt::ScrollBarOrientation;
90 namespace MouseWheelBehavior = ::com::sun::star::awt::MouseWheelBehavior;
91 namespace LineEndFormat = ::com::sun::star::awt::LineEndFormat;
92 namespace ImageScaleMode = ::com::sun::star::awt::ImageScaleMode;
93 namespace DataType = ::com::sun::star::sdbc::DataType;
94 namespace ColumnValue = ::com::sun::star::sdbc::ColumnValue;
95 namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
98 //= FormControlFactory_Data
100 struct FormControlFactory_Data
102 Reference<XComponentContext> m_xContext;
104 FormControlFactory_Data( const Reference<XComponentContext>& _rContext )
105 :m_xContext( _rContext )
111 //= FormControlFactory
114 FormControlFactory::FormControlFactory( const Reference<XComponentContext>& _rContext )
115 :m_pData( new FormControlFactory_Data( _rContext ) )
119 FormControlFactory::FormControlFactory( )
120 :m_pData( new FormControlFactory_Data( comphelper::getProcessComponentContext() ) )
125 FormControlFactory::~FormControlFactory()
130 sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const SdrUnoObj& _rObject )
132 return initializeControlModel(
133 _eDocType,
134 Reference< XPropertySet >( _rObject.GetUnoControlModel(), UNO_QUERY ),
135 _rObject.GetCurrentBoundRect()
140 sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const Reference< XPropertySet >& _rxControlModel )
142 return initializeControlModel(
143 _eDocType, _rxControlModel, Rectangle()
148 namespace
151 static OUString lcl_getUniqueLabel_nothrow( const Reference< XPropertySet >& _rxControlModel, const OUString& _rBaseLabel )
153 OUString sLabel( _rBaseLabel );
156 typedef ::std::set< OUString > StringBag;
157 StringBag aUsedLabels;
159 Reference< XFormComponent > xFormComponent( _rxControlModel, UNO_QUERY_THROW );
160 Reference< XIndexAccess > xContainer( xFormComponent->getParent(), UNO_QUERY_THROW );
161 // loop through all siblings of the control model, and collect their labels
162 for ( sal_Int32 index=xContainer->getCount(); index>0; )
164 Reference< XPropertySet > xElement( xContainer->getByIndex( --index ), UNO_QUERY_THROW );
165 if ( xElement == _rxControlModel )
166 continue;
168 Reference< XPropertySetInfo > xPSI( xElement->getPropertySetInfo(), UNO_SET_THROW );
169 if ( !xPSI->hasPropertyByName( FM_PROP_LABEL ) )
170 continue;
172 OUString sElementLabel;
173 OSL_VERIFY( xElement->getPropertyValue( FM_PROP_LABEL ) >>= sElementLabel );
174 aUsedLabels.insert( sElementLabel );
177 // now find a free label
178 sal_Int32 i=2;
179 while ( aUsedLabels.find( sLabel ) != aUsedLabels.end() )
181 OUStringBuffer aBuffer( _rBaseLabel );
182 aBuffer.appendAscii( " " );
183 aBuffer.append( (sal_Int32)i++ );
184 sLabel = aBuffer.makeStringAndClear();
187 catch( const Exception& )
189 DBG_UNHANDLED_EXCEPTION();
191 return sLabel;
195 static Sequence< PropertyValue > lcl_getDataSourceIndirectProperties( const Reference< XPropertySet >& _rxControlModel,
196 const Reference<XComponentContext>& _rContext )
198 OSL_PRECOND( _rxControlModel.is(), "lcl_getDataSourceIndirectProperties: invalid model!" );
200 Sequence< PropertyValue > aInfo;
203 Reference< XChild > xChild( _rxControlModel, UNO_QUERY );
204 Reference< XPropertySet > xForm;
205 if ( xChild.is() )
206 xForm = xForm.query( xChild->getParent() );
208 if ( Reference< XGridColumnFactory >( xForm, UNO_QUERY ).is() )
209 { // hmm. the model is a grid column, in real
210 xChild = xChild.query( xForm );
211 xForm = xForm.query( xChild->getParent() );
214 OSL_ENSURE( xForm.is(), "lcl_getDataSourceIndirectProperties: could not determine the form!" );
215 if ( !xForm.is() )
216 return aInfo;
217 OUString sDataSourceName;
218 xForm->getPropertyValue( FM_PROP_DATASOURCE ) >>= sDataSourceName;
220 Reference< XPropertySet > xDsProperties;
221 if ( !sDataSourceName.isEmpty() )
222 xDsProperties = xDsProperties.query( OStaticDataAccessTools().getDataSource( sDataSourceName, _rContext ) );
223 if ( xDsProperties.is() )
224 xDsProperties->getPropertyValue("Info") >>= aInfo;
226 catch( const Exception& )
228 OSL_FAIL( "lcl_getDataSourceIndirectProperties: caught an exception!" );
230 return aInfo;
234 static const sal_Char* aCharacterAndParagraphProperties[] =
236 "CharFontName",
237 "CharFontStyleName",
238 "CharFontFamily",
239 "CharFontCharSet",
240 "CharFontPitch",
241 "CharColor",
242 "CharEscapement",
243 "CharHeight",
244 "CharUnderline",
245 "CharWeight",
246 "CharPosture",
247 "CharAutoKerning",
248 "CharBackColor",
249 "CharBackTransparent",
250 "CharCaseMap",
251 "CharCrossedOut",
252 "CharFlash",
253 "CharStrikeout",
254 "CharWordMode",
255 "CharKerning",
256 "CharLocale",
257 "CharKeepTogether",
258 "CharNoLineBreak",
259 "CharShadowed",
260 "CharFontType",
261 "CharStyleName",
262 "CharContoured",
263 "CharCombineIsOn",
264 "CharCombinePrefix",
265 "CharCombineSuffix",
266 "CharEmphasize",
267 "CharRelief",
268 "RubyText",
269 "RubyAdjust",
270 "RubyCharStyleName",
271 "RubyIsAbove",
272 "CharRotation",
273 "CharRotationIsFitToLine",
274 "CharScaleWidth",
275 "HyperLinkURL",
276 "HyperLinkTarget",
277 "HyperLinkName",
278 "VisitedCharStyleName",
279 "UnvisitedCharStyleName",
280 "CharEscapementHeight",
281 "CharNoHyphenation",
282 "CharUnderlineColor",
283 "CharUnderlineHasColor",
284 "CharStyleNames",
285 "CharHeightAsian",
286 "CharWeightAsian",
287 "CharFontNameAsian",
288 "CharFontStyleNameAsian",
289 "CharFontFamilyAsian",
290 "CharFontCharSetAsian",
291 "CharFontPitchAsian",
292 "CharPostureAsian",
293 "CharLocaleAsian",
294 "ParaIsCharacterDistance",
295 "ParaIsForbiddenRules",
296 "ParaIsHangingPunctuation",
297 "CharHeightComplex",
298 "CharWeightComplex",
299 "CharFontNameComplex",
300 "CharFontStyleNameComplex",
301 "CharFontFamilyComplex",
302 "CharFontCharSetComplex",
303 "CharFontPitchComplex",
304 "CharPostureComplex",
305 "CharLocaleComplex",
306 "ParaAdjust",
307 "ParaLineSpacing",
308 "ParaBackColor",
309 "ParaBackTransparent",
310 "ParaBackGraphicURL",
311 "ParaBackGraphicFilter",
312 "ParaBackGraphicLocation",
313 "ParaLastLineAdjust",
314 "ParaExpandSingleWord",
315 "ParaLeftMargin",
316 "ParaRightMargin",
317 "ParaTopMargin",
318 "ParaBottomMargin",
319 "ParaLineNumberCount",
320 "ParaLineNumberStartValue",
321 "PageDescName",
322 "PageNumberOffset",
323 "ParaRegisterModeActive",
324 "ParaTabStops",
325 "ParaStyleName",
326 "DropCapFormat",
327 "DropCapWholeWord",
328 "ParaKeepTogether",
329 "Setting",
330 "ParaSplit",
331 "Setting",
332 "NumberingLevel",
333 "NumberingRules",
334 "NumberingStartValue",
335 "ParaIsNumberingRestart",
336 "NumberingStyleName",
337 "ParaOrphans",
338 "ParaWidows",
339 "ParaShadowFormat",
340 "LeftBorder",
341 "RightBorder",
342 "TopBorder",
343 "BottomBorder",
344 "BorderDistance",
345 "LeftBorderDistance",
346 "RightBorderDistance",
347 "TopBorderDistance",
348 "BottomBorderDistance",
349 "BreakType",
350 "DropCapCharStyleName",
351 "ParaFirstLineIndent",
352 "ParaIsAutoFirstLineIndent",
353 "ParaIsHyphenation",
354 "ParaHyphenationMaxHyphens",
355 "ParaHyphenationMaxLeadingChars",
356 "ParaHyphenationMaxTrailingChars",
357 "ParaVertAlignment",
358 "ParaUserDefinedAttributes",
359 "NumberingIsNumber",
360 "ParaIsConnectBorder",
361 NULL
365 static void lcl_initializeCharacterAttributes( const Reference< XPropertySet >& _rxModel )
369 Reference< XPropertySet > xStyle( ControlLayouter::getDefaultDocumentTextStyle( _rxModel ), UNO_SET_THROW );
371 // transfer all properties which are described by the style
372 Reference< XPropertySetInfo > xSourcePropInfo( xStyle->getPropertySetInfo(), UNO_SET_THROW );
373 Reference< XPropertySetInfo > xDestPropInfo( _rxModel->getPropertySetInfo(), UNO_SET_THROW );
375 OUString sPropertyName;
376 const sal_Char** pCharacterProperty = aCharacterAndParagraphProperties;
377 while ( *pCharacterProperty )
379 sPropertyName = OUString::createFromAscii( *pCharacterProperty );
381 if ( xSourcePropInfo->hasPropertyByName( sPropertyName ) && xDestPropInfo->hasPropertyByName( sPropertyName ) )
382 _rxModel->setPropertyValue( sPropertyName, xStyle->getPropertyValue( sPropertyName ) );
384 ++pCharacterProperty;
387 catch( const Exception& )
389 DBG_UNHANDLED_EXCEPTION();
395 sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const Reference< XPropertySet >& _rxControlModel,
396 const Rectangle& _rControlBoundRect )
398 sal_Int16 nClassId = FormComponentType::CONTROL;
400 OSL_ENSURE( _rxControlModel.is(), "FormControlFactory::initializeControlModel: invalid model!" );
401 if ( !_rxControlModel.is() )
402 return nClassId;
406 ControlLayouter::initializeControlLayout( _rxControlModel, _eDocType );
408 _rxControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId;
409 Reference< XPropertySetInfo > xPSI( _rxControlModel->getPropertySetInfo(), UNO_SET_THROW );
410 switch ( nClassId )
412 case FormComponentType::SCROLLBAR:
413 _rxControlModel->setPropertyValue("LiveScroll", makeAny( true ) );
414 // NO break!
415 case FormComponentType::SPINBUTTON:
417 sal_Int32 eOrientation = ScrollBarOrientation::HORIZONTAL;
418 if ( !_rControlBoundRect.IsEmpty() && ( _rControlBoundRect.GetWidth() < _rControlBoundRect.GetHeight() ) )
419 eOrientation = ScrollBarOrientation::VERTICAL;
420 _rxControlModel->setPropertyValue( FM_PROP_ORIENTATION, makeAny( eOrientation ) );
422 break;
424 case FormComponentType::LISTBOX:
425 case FormComponentType::COMBOBOX:
427 bool bDropDown = !_rControlBoundRect.IsEmpty() && ( _rControlBoundRect.GetWidth() >= 3 * _rControlBoundRect.GetHeight() );
428 if ( xPSI->hasPropertyByName( FM_PROP_DROPDOWN ) )
429 _rxControlModel->setPropertyValue( FM_PROP_DROPDOWN, makeAny( bDropDown ) );
430 _rxControlModel->setPropertyValue( FM_PROP_LINECOUNT, makeAny( sal_Int16( 20 ) ) );
432 break;
434 case FormComponentType::TEXTFIELD:
436 initializeTextFieldLineEnds( _rxControlModel );
437 lcl_initializeCharacterAttributes( _rxControlModel );
439 if ( !_rControlBoundRect.IsEmpty()
440 && !( _rControlBoundRect.GetWidth() > 4 * _rControlBoundRect.GetHeight() )
443 if ( xPSI->hasPropertyByName( FM_PROP_MULTILINE ) )
444 _rxControlModel->setPropertyValue( FM_PROP_MULTILINE, makeAny( true ) );
447 break;
449 case FormComponentType::RADIOBUTTON:
450 case FormComponentType::CHECKBOX:
451 case FormComponentType::FIXEDTEXT:
453 OUString sVertAlignPropertyName( "VerticalAlign" );
454 if ( xPSI->hasPropertyByName( sVertAlignPropertyName ) )
455 _rxControlModel->setPropertyValue( sVertAlignPropertyName, makeAny( VerticalAlignment_MIDDLE ) );
457 break;
459 case FormComponentType::IMAGEBUTTON:
460 case FormComponentType::IMAGECONTROL:
462 const OUString sScaleModeProperty( "ScaleMode" );
463 if ( xPSI->hasPropertyByName( sScaleModeProperty ) )
464 _rxControlModel->setPropertyValue( sScaleModeProperty, makeAny( ImageScaleMode::ISOTROPIC ) );
466 break;
469 // initial default label for the control
470 if ( xPSI->hasPropertyByName( FM_PROP_LABEL ) )
472 OUString sExistingLabel;
473 OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_LABEL ) >>= sExistingLabel );
474 if ( sExistingLabel.isEmpty() )
476 OUString sInitialLabel;
477 OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_NAME ) >>= sInitialLabel );
479 sal_uInt16 nTitleResId = 0;
480 switch ( nClassId )
482 case FormComponentType::COMMANDBUTTON: nTitleResId = RID_STR_PROPTITLE_PUSHBUTTON; break;
483 case FormComponentType::RADIOBUTTON: nTitleResId = RID_STR_PROPTITLE_RADIOBUTTON; break;
484 case FormComponentType::CHECKBOX: nTitleResId = RID_STR_PROPTITLE_CHECKBOX; break;
485 case FormComponentType::GROUPBOX: nTitleResId = RID_STR_PROPTITLE_GROUPBOX; break;
486 case FormComponentType::FIXEDTEXT: nTitleResId = RID_STR_PROPTITLE_FIXEDTEXT; break;
489 if ( nTitleResId )
490 sInitialLabel = SVX_RESSTR(nTitleResId);
492 _rxControlModel->setPropertyValue(
493 FM_PROP_LABEL,
494 makeAny( lcl_getUniqueLabel_nothrow( _rxControlModel, sInitialLabel ) )
499 // strict format = yes is the default (i93467)
500 if ( xPSI->hasPropertyByName( FM_PROP_STRICTFORMAT ) )
502 _rxControlModel->setPropertyValue( FM_PROP_STRICTFORMAT, makeAny( true ) );
505 // mouse wheel: don't use it for scrolling by default (i110036)
506 if ( xPSI->hasPropertyByName( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) )
508 _rxControlModel->setPropertyValue( FM_PROP_MOUSE_WHEEL_BEHAVIOR, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) );
511 if ( xPSI->hasPropertyByName( FM_PROP_WRITING_MODE ) )
512 _rxControlModel->setPropertyValue( FM_PROP_WRITING_MODE, makeAny( WritingMode2::CONTEXT ) );
514 catch( const Exception& )
516 DBG_UNHANDLED_EXCEPTION();
518 return nClassId;
522 void FormControlFactory::initializeTextFieldLineEnds( const Reference< XPropertySet >& _rxModel )
524 OSL_PRECOND( _rxModel.is(), "initializeTextFieldLineEnds: invalid model!" );
525 if ( !_rxModel.is() )
526 return;
530 Reference< XPropertySetInfo > xInfo = _rxModel->getPropertySetInfo();
531 if ( !xInfo.is() || !xInfo->hasPropertyByName( FM_PROP_LINEENDFORMAT ) )
532 return;
534 // let's see if the data source which the form belongs to (if any)
535 // has a setting for the preferred line end format
536 bool bDosLineEnds = false;
537 Sequence< PropertyValue > aInfo = lcl_getDataSourceIndirectProperties( _rxModel, m_pData->m_xContext );
538 const PropertyValue* pInfo = aInfo.getConstArray();
539 const PropertyValue* pInfoEnd = pInfo + aInfo.getLength();
540 for ( ; pInfo != pInfoEnd; ++pInfo )
542 if ( pInfo->Name == "PreferDosLikeLineEnds" )
544 pInfo->Value >>= bDosLineEnds;
545 break;
549 sal_Int16 nLineEndFormat = bDosLineEnds ? LineEndFormat::CARRIAGE_RETURN_LINE_FEED : LineEndFormat::LINE_FEED;
550 _rxModel->setPropertyValue( FM_PROP_LINEENDFORMAT, makeAny( nLineEndFormat ) );
552 catch( const Exception& )
554 DBG_UNHANDLED_EXCEPTION();
559 void FormControlFactory::initializeFieldDependentProperties( const Reference< XPropertySet >& _rxDatabaseField,
560 const Reference< XPropertySet >& _rxControlModel, const Reference< XNumberFormats >& _rxNumberFormats )
562 OSL_PRECOND( _rxDatabaseField.is() && _rxControlModel.is(),
563 "FormControlFactory::initializeFieldDependentProperties: illegal params!" );
564 if ( !_rxDatabaseField.is() || !_rxControlModel.is() )
565 return;
570 // if the field has a numeric format, and the model has a "Scale" property, sync it
571 Reference< XPropertySetInfo > xFieldPSI( _rxDatabaseField->getPropertySetInfo(), UNO_SET_THROW );
572 Reference< XPropertySetInfo > xModelPSI( _rxControlModel->getPropertySetInfo(), UNO_SET_THROW );
574 if ( xModelPSI->hasPropertyByName( FM_PROP_DECIMAL_ACCURACY ) )
576 sal_Int32 nFormatKey = 0;
577 if ( xFieldPSI->hasPropertyByName( FM_PROP_FORMATKEY ) )
579 _rxDatabaseField->getPropertyValue( FM_PROP_FORMATKEY ) >>= nFormatKey;
581 else
583 nFormatKey = OStaticDataAccessTools().getDefaultNumberFormat(
584 _rxDatabaseField,
585 Reference< XNumberFormatTypes >( _rxNumberFormats, UNO_QUERY ),
586 SvtSysLocale().GetLanguageTag().getLocale()
590 Any aScaleVal( ::comphelper::getNumberFormatDecimals( _rxNumberFormats, nFormatKey ) );
591 _rxControlModel->setPropertyValue( FM_PROP_DECIMAL_ACCURACY, aScaleVal );
595 // minimum and maximum of the control according to the type of the database field
596 sal_Int32 nDataType = DataType::OTHER;
597 OSL_VERIFY( _rxDatabaseField->getPropertyValue( FM_PROP_FIELDTYPE ) >>= nDataType );
599 if ( xModelPSI->hasPropertyByName( FM_PROP_VALUEMIN )
600 && xModelPSI->hasPropertyByName( FM_PROP_VALUEMAX )
603 sal_Int32 nMinValue = -1000000000, nMaxValue = 1000000000;
604 switch ( nDataType )
606 case DataType::TINYINT : nMinValue = 0; nMaxValue = 255; break;
607 case DataType::SMALLINT : nMinValue = -32768; nMaxValue = 32767; break;
608 case DataType::INTEGER : nMinValue = 0x80000000; nMaxValue = 0x7FFFFFFF; break;
609 // double and singles are ignored
612 Any aValue;
614 // both the minimum and the maximum value properties can be either Long or Double
615 Property aProperty = xModelPSI->getPropertyByName( FM_PROP_VALUEMIN );
616 if ( aProperty.Type.getTypeClass() == TypeClass_DOUBLE )
617 aValue <<= (double)nMinValue;
618 else if ( aProperty.Type.getTypeClass() == TypeClass_LONG )
619 aValue <<= (sal_Int32)nMinValue;
620 else
622 OSL_FAIL( "FormControlFactory::initializeFieldDependentProperties: unexpected property type (MinValue)!" );
624 _rxControlModel->setPropertyValue( FM_PROP_VALUEMIN, aValue );
626 // both the minimum and the maximum value properties can be either Long or Double
627 aProperty = xModelPSI->getPropertyByName( FM_PROP_VALUEMAX );
628 if ( aProperty.Type.getTypeClass() == TypeClass_DOUBLE )
629 aValue <<= (double)nMaxValue;
630 else if ( aProperty.Type.getTypeClass() == TypeClass_LONG )
631 aValue <<= (sal_Int32)nMaxValue;
632 else
634 OSL_FAIL( "FormControlFactory::initializeFieldDependentProperties: unexpected property type (MaxValue)!" );
636 _rxControlModel->setPropertyValue( FM_PROP_VALUEMAX, aValue );
640 // a check box can be tristate if and only if the column it is bound to is nullable
641 sal_Int16 nClassId = FormComponentType::CONTROL;
642 OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
643 if ( nClassId == FormComponentType::CHECKBOX )
645 sal_Int32 nNullable = ColumnValue::NULLABLE_UNKNOWN;
646 OSL_VERIFY( _rxDatabaseField->getPropertyValue( FM_PROP_ISNULLABLE ) >>= nNullable );
647 _rxControlModel->setPropertyValue( FM_PROP_TRISTATE, makeAny( ColumnValue::NO_NULLS != nNullable ) );
650 catch( const Exception& )
652 DBG_UNHANDLED_EXCEPTION();
657 OUString FormControlFactory::getDefaultName( sal_Int16 _nClassId, const Reference< XServiceInfo >& _rxObject )
659 sal_uInt16 nResId(0);
661 switch ( _nClassId )
663 case FormComponentType::COMMANDBUTTON: nResId = RID_STR_PROPTITLE_PUSHBUTTON; break;
664 case FormComponentType::RADIOBUTTON: nResId = RID_STR_PROPTITLE_RADIOBUTTON; break;
665 case FormComponentType::CHECKBOX: nResId = RID_STR_PROPTITLE_CHECKBOX; break;
666 case FormComponentType::LISTBOX: nResId = RID_STR_PROPTITLE_LISTBOX; break;
667 case FormComponentType::COMBOBOX: nResId = RID_STR_PROPTITLE_COMBOBOX; break;
668 case FormComponentType::GROUPBOX: nResId = RID_STR_PROPTITLE_GROUPBOX; break;
669 case FormComponentType::IMAGEBUTTON: nResId = RID_STR_PROPTITLE_IMAGEBUTTON; break;
670 case FormComponentType::FIXEDTEXT: nResId = RID_STR_PROPTITLE_FIXEDTEXT; break;
671 case FormComponentType::GRIDCONTROL: nResId = RID_STR_PROPTITLE_DBGRID; break;
672 case FormComponentType::FILECONTROL: nResId = RID_STR_PROPTITLE_FILECONTROL; break;
673 case FormComponentType::DATEFIELD: nResId = RID_STR_PROPTITLE_DATEFIELD; break;
674 case FormComponentType::TIMEFIELD: nResId = RID_STR_PROPTITLE_TIMEFIELD; break;
675 case FormComponentType::NUMERICFIELD: nResId = RID_STR_PROPTITLE_NUMERICFIELD; break;
676 case FormComponentType::CURRENCYFIELD: nResId = RID_STR_PROPTITLE_CURRENCYFIELD; break;
677 case FormComponentType::PATTERNFIELD: nResId = RID_STR_PROPTITLE_PATTERNFIELD; break;
678 case FormComponentType::IMAGECONTROL: nResId = RID_STR_PROPTITLE_IMAGECONTROL; break;
679 case FormComponentType::HIDDENCONTROL: nResId = RID_STR_PROPTITLE_HIDDEN; break;
680 case FormComponentType::SCROLLBAR: nResId = RID_STR_PROPTITLE_SCROLLBAR; break;
681 case FormComponentType::SPINBUTTON: nResId = RID_STR_PROPTITLE_SPINBUTTON; break;
682 case FormComponentType::NAVIGATIONBAR: nResId = RID_STR_PROPTITLE_NAVBAR; break;
684 case FormComponentType::TEXTFIELD:
685 nResId = RID_STR_PROPTITLE_EDIT;
686 if ( _rxObject.is() && _rxObject->supportsService( FM_SUN_COMPONENT_FORMATTEDFIELD ) )
687 nResId = RID_STR_PROPTITLE_FORMATTED;
688 break;
690 default:
691 nResId = RID_STR_CONTROL; break;
694 return SVX_RESSTR(nResId);
698 OUString FormControlFactory::getDefaultUniqueName_ByComponentType( const Reference< XNameAccess >& _rxContainer,
699 const Reference< XPropertySet >& _rxObject )
701 sal_Int16 nClassId = FormComponentType::CONTROL;
702 OSL_VERIFY( _rxObject->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
703 OUString sBaseName = getDefaultName( nClassId, Reference< XServiceInfo >( _rxObject, UNO_QUERY ) );
705 return getUniqueName( _rxContainer, sBaseName );
709 OUString FormControlFactory::getUniqueName( const Reference< XNameAccess >& _rxContainer, const OUString& _rBaseName )
711 sal_Int32 n = 0;
712 OUString sName;
715 OUStringBuffer aBuf( _rBaseName );
716 aBuf.appendAscii( " " );
717 aBuf.append( ++n );
718 sName = aBuf.makeStringAndClear();
720 while ( _rxContainer->hasByName( sName ) );
722 return sName;
726 } // namespace svxform
729 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */