LibreOffice Module svx (master)  1
formcontrolfactory.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 
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>
28 
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>
42 
43 #include <comphelper/numbers.hxx>
45 #include <unotools/syslocale.hxx>
46 #include <tools/gen.hxx>
47 #include <tools/diagnose_ex.h>
48 #include <connectivity/dbtools.hxx>
50 
51 #include <set>
52 
53 using namespace ::dbtools;
54 
55 namespace svxform
56 {
57 
58 
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::makeAny;
66  using ::com::sun::star::uno::Sequence;
67  using ::com::sun::star::uno::XComponentContext;
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;
83 
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;
92 
94  :m_xContext( _rContext )
95  {
96  }
97 
98  FormControlFactory::FormControlFactory( )
100  {
101  }
102 
103 
105  {
106  }
107 
108 
109  sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const SdrUnoObj& _rObject )
110  {
111  return initializeControlModel(
112  _eDocType,
113  Reference< XPropertySet >( _rObject.GetUnoControlModel(), UNO_QUERY ),
114  _rObject.GetCurrentBoundRect()
115  );
116  }
117 
118 
119  void FormControlFactory::initializeControlModel( const DocumentType _eDocType, const Reference< XPropertySet >& _rxControlModel )
120  {
122  _eDocType, _rxControlModel, tools::Rectangle()
123  );
124  }
125 
126 
127  namespace
128  {
129 
130  OUString lcl_getUniqueLabel_nothrow( const Reference< XPropertySet >& _rxControlModel, const OUString& _rBaseLabel )
131  {
132  OUString sLabel( _rBaseLabel );
133  try
134  {
135  typedef ::std::set< OUString > StringBag;
136  StringBag aUsedLabels;
137 
138  Reference< XFormComponent > xFormComponent( _rxControlModel, UNO_QUERY_THROW );
139  Reference< XIndexAccess > xContainer( xFormComponent->getParent(), UNO_QUERY_THROW );
140  // loop through all siblings of the control model, and collect their labels
141  for ( sal_Int32 index=xContainer->getCount(); index>0; )
142  {
143  Reference< XPropertySet > xElement( xContainer->getByIndex( --index ), UNO_QUERY_THROW );
144  if ( xElement == _rxControlModel )
145  continue;
146 
147  Reference< XPropertySetInfo > xPSI( xElement->getPropertySetInfo(), UNO_SET_THROW );
148  if ( !xPSI->hasPropertyByName( FM_PROP_LABEL ) )
149  continue;
150 
151  OUString sElementLabel;
152  OSL_VERIFY( xElement->getPropertyValue( FM_PROP_LABEL ) >>= sElementLabel );
153  aUsedLabels.insert( sElementLabel );
154  }
155 
156  // now find a free label
157  sal_Int32 i=2;
158  while ( aUsedLabels.find( sLabel ) != aUsedLabels.end() )
159  {
160  OUStringBuffer aBuffer( _rBaseLabel );
161  aBuffer.append( " " );
162  aBuffer.append( i++ );
163  sLabel = aBuffer.makeStringAndClear();
164  }
165  }
166  catch( const Exception& )
167  {
169  }
170  return sLabel;
171  }
172 
173 
174  Sequence< PropertyValue > lcl_getDataSourceIndirectProperties( const Reference< XPropertySet >& _rxControlModel,
175  const Reference<XComponentContext>& _rContext )
176  {
177  OSL_PRECOND( _rxControlModel.is(), "lcl_getDataSourceIndirectProperties: invalid model!" );
178 
179  Sequence< PropertyValue > aInfo;
180  try
181  {
182  Reference< XChild > xChild( _rxControlModel, UNO_QUERY );
184  if ( xChild.is() )
185  xForm.set(xChild->getParent(), css::uno::UNO_QUERY);
186 
187  if ( Reference< XGridColumnFactory >( xForm, UNO_QUERY ).is() )
188  { // hmm. the model is a grid column, in real
189  xChild.set(xForm, css::uno::UNO_QUERY);
190  xForm.set(xChild->getParent(), css::uno::UNO_QUERY);
191  }
192 
193  OSL_ENSURE( xForm.is(), "lcl_getDataSourceIndirectProperties: could not determine the form!" );
194  if ( !xForm.is() )
195  return aInfo;
196  OUString sDataSourceName;
197  xForm->getPropertyValue( FM_PROP_DATASOURCE ) >>= sDataSourceName;
198 
199  Reference< XPropertySet > xDsProperties;
200  if ( !sDataSourceName.isEmpty() )
201  xDsProperties.set(getDataSource( sDataSourceName, _rContext ), css::uno::UNO_QUERY);
202  if ( xDsProperties.is() )
203  xDsProperties->getPropertyValue("Info") >>= aInfo;
204  }
205  catch( const Exception& )
206  {
207  TOOLS_WARN_EXCEPTION( "svx", "lcl_getDataSourceIndirectProperties" );
208  }
209  return aInfo;
210  }
211 
212 
213  const char* aCharacterAndParagraphProperties[] =
214  {
215  "CharFontName",
216  "CharFontStyleName",
217  "CharFontFamily",
218  "CharFontCharSet",
219  "CharFontPitch",
220  "CharColor",
221  "CharEscapement",
222  "CharHeight",
223  "CharUnderline",
224  "CharWeight",
225  "CharPosture",
226  "CharAutoKerning",
227  "CharBackColor",
228  "CharBackTransparent",
229  "CharCaseMap",
230  "CharCrossedOut",
231  "CharFlash",
232  "CharStrikeout",
233  "CharWordMode",
234  "CharKerning",
235  "CharLocale",
236  "CharKeepTogether",
237  "CharNoLineBreak",
238  "CharShadowed",
239  "CharFontType",
240  "CharStyleName",
241  "CharContoured",
242  "CharCombineIsOn",
243  "CharCombinePrefix",
244  "CharCombineSuffix",
245  "CharEmphasize",
246  "CharRelief",
247  "RubyText",
248  "RubyAdjust",
249  "RubyCharStyleName",
250  "RubyIsAbove",
251  "CharRotation",
252  "CharRotationIsFitToLine",
253  "CharScaleWidth",
254  "HyperLinkURL",
255  "HyperLinkTarget",
256  "HyperLinkName",
257  "VisitedCharStyleName",
258  "UnvisitedCharStyleName",
259  "CharEscapementHeight",
260  "CharNoHyphenation",
261  "CharUnderlineColor",
262  "CharUnderlineHasColor",
263  "CharStyleNames",
264  "CharHeightAsian",
265  "CharWeightAsian",
266  "CharFontNameAsian",
267  "CharFontStyleNameAsian",
268  "CharFontFamilyAsian",
269  "CharFontCharSetAsian",
270  "CharFontPitchAsian",
271  "CharPostureAsian",
272  "CharLocaleAsian",
273  "ParaIsCharacterDistance",
274  "ParaIsForbiddenRules",
275  "ParaIsHangingPunctuation",
276  "CharHeightComplex",
277  "CharWeightComplex",
278  "CharFontNameComplex",
279  "CharFontStyleNameComplex",
280  "CharFontFamilyComplex",
281  "CharFontCharSetComplex",
282  "CharFontPitchComplex",
283  "CharPostureComplex",
284  "CharLocaleComplex",
285  "ParaAdjust",
286  "ParaLineSpacing",
287  "ParaBackColor",
288  "ParaBackTransparent",
289  "ParaBackGraphic",
290  "ParaBackGraphicURL",
291  "ParaBackGraphicFilter",
292  "ParaBackGraphicLocation",
293  "ParaLastLineAdjust",
294  "ParaExpandSingleWord",
295  "ParaLeftMargin",
296  "ParaRightMargin",
297  "ParaTopMargin",
298  "ParaBottomMargin",
299  "ParaLineNumberCount",
300  "ParaLineNumberStartValue",
301  "PageDescName",
302  "PageNumberOffset",
303  "ParaRegisterModeActive",
304  "ParaTabStops",
305  "ParaStyleName",
306  "DropCapFormat",
307  "DropCapWholeWord",
308  "ParaKeepTogether",
309  "Setting",
310  "ParaSplit",
311  "Setting",
312  "NumberingLevel",
313  "NumberingRules",
314  "NumberingStartValue",
315  "ParaIsNumberingRestart",
316  "NumberingStyleName",
317  "ParaOrphans",
318  "ParaWidows",
319  "ParaShadowFormat",
320  "LeftBorder",
321  "RightBorder",
322  "TopBorder",
323  "BottomBorder",
324  "BorderDistance",
325  "LeftBorderDistance",
326  "RightBorderDistance",
327  "TopBorderDistance",
328  "BottomBorderDistance",
329  "BreakType",
330  "DropCapCharStyleName",
331  "ParaFirstLineIndent",
332  "ParaIsAutoFirstLineIndent",
333  "ParaIsHyphenation",
334  "ParaHyphenationMaxHyphens",
335  "ParaHyphenationMaxLeadingChars",
336  "ParaHyphenationMaxTrailingChars",
337  "ParaVertAlignment",
338  "ParaUserDefinedAttributes",
339  "NumberingIsNumber",
340  "ParaIsConnectBorder",
341  nullptr
342  };
343 
344 
345  void lcl_initializeCharacterAttributes( const Reference< XPropertySet >& _rxModel )
346  {
347  try
348  {
349  Reference< XPropertySet > xStyle( ControlLayouter::getDefaultDocumentTextStyle( _rxModel ), UNO_SET_THROW );
350 
351  // transfer all properties which are described by the style
352  Reference< XPropertySetInfo > xSourcePropInfo( xStyle->getPropertySetInfo(), UNO_SET_THROW );
353  Reference< XPropertySetInfo > xDestPropInfo( _rxModel->getPropertySetInfo(), UNO_SET_THROW );
354 
355  OUString sPropertyName;
356  const char** pCharacterProperty = aCharacterAndParagraphProperties;
357  while ( *pCharacterProperty )
358  {
359  sPropertyName = OUString::createFromAscii( *pCharacterProperty );
360 
361  if ( xSourcePropInfo->hasPropertyByName( sPropertyName ) && xDestPropInfo->hasPropertyByName( sPropertyName ) )
362  _rxModel->setPropertyValue( sPropertyName, xStyle->getPropertyValue( sPropertyName ) );
363 
364  ++pCharacterProperty;
365  }
366  }
367  catch( const Exception& )
368  {
370  }
371  }
372  }
373 
374 
375  sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const Reference< XPropertySet >& _rxControlModel,
376  const tools::Rectangle& _rControlBoundRect )
377  {
378  sal_Int16 nClassId = FormComponentType::CONTROL;
379 
380  OSL_ENSURE( _rxControlModel.is(), "FormControlFactory::initializeControlModel: invalid model!" );
381  if ( !_rxControlModel.is() )
382  return nClassId;
383 
384  try
385  {
386  ControlLayouter::initializeControlLayout( _rxControlModel, _eDocType );
387 
388  _rxControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId;
389  Reference< XPropertySetInfo > xPSI( _rxControlModel->getPropertySetInfo(), UNO_SET_THROW );
390  switch ( nClassId )
391  {
392  case FormComponentType::SCROLLBAR:
393  _rxControlModel->setPropertyValue("LiveScroll", makeAny( true ) );
394  [[fallthrough]];
395  case FormComponentType::SPINBUTTON:
396  {
397  sal_Int32 eOrientation = ScrollBarOrientation::HORIZONTAL;
398  if ( !_rControlBoundRect.IsEmpty() && ( _rControlBoundRect.GetWidth() < _rControlBoundRect.GetHeight() ) )
399  eOrientation = ScrollBarOrientation::VERTICAL;
400  _rxControlModel->setPropertyValue( FM_PROP_ORIENTATION, makeAny( eOrientation ) );
401  }
402  break;
403 
404  case FormComponentType::LISTBOX:
405  case FormComponentType::COMBOBOX:
406  {
407  bool bDropDown = !_rControlBoundRect.IsEmpty() && ( _rControlBoundRect.GetWidth() >= 3 * _rControlBoundRect.GetHeight() );
408  if ( xPSI->hasPropertyByName( FM_PROP_DROPDOWN ) )
409  _rxControlModel->setPropertyValue( FM_PROP_DROPDOWN, makeAny( bDropDown ) );
410  _rxControlModel->setPropertyValue( FM_PROP_LINECOUNT, makeAny( sal_Int16( 20 ) ) );
411  }
412  break;
413 
414  case FormComponentType::TEXTFIELD:
415  {
416  initializeTextFieldLineEnds( _rxControlModel );
417  lcl_initializeCharacterAttributes( _rxControlModel );
418 
419  if ( !_rControlBoundRect.IsEmpty()
420  && ( _rControlBoundRect.GetWidth() <= 4 * _rControlBoundRect.GetHeight() )
421  )
422  {
423  if ( xPSI->hasPropertyByName( FM_PROP_MULTILINE ) )
424  _rxControlModel->setPropertyValue( FM_PROP_MULTILINE, makeAny( true ) );
425  }
426  }
427  break;
428 
429  case FormComponentType::RADIOBUTTON:
430  case FormComponentType::CHECKBOX:
431  case FormComponentType::FIXEDTEXT:
432  {
433  OUString sVertAlignPropertyName( "VerticalAlign" );
434  if ( xPSI->hasPropertyByName( sVertAlignPropertyName ) )
435  _rxControlModel->setPropertyValue( sVertAlignPropertyName, makeAny( VerticalAlignment_MIDDLE ) );
436  }
437  break;
438 
439  case FormComponentType::IMAGEBUTTON:
440  case FormComponentType::IMAGECONTROL:
441  {
442  static const OUStringLiteral sScaleModeProperty( u"ScaleMode" );
443  if ( xPSI->hasPropertyByName( sScaleModeProperty ) )
444  _rxControlModel->setPropertyValue( sScaleModeProperty, makeAny( ImageScaleMode::ISOTROPIC ) );
445  }
446  break;
447  }
448 
449  // initial default label for the control
450  if ( xPSI->hasPropertyByName( FM_PROP_LABEL ) )
451  {
452  OUString sExistingLabel;
453  OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_LABEL ) >>= sExistingLabel );
454  if ( sExistingLabel.isEmpty() )
455  {
456  OUString sInitialLabel;
457  OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_NAME ) >>= sInitialLabel );
458 
459  TranslateId pTitleResId;
460  switch ( nClassId )
461  {
462  case FormComponentType::COMMANDBUTTON: pTitleResId = RID_STR_PROPTITLE_PUSHBUTTON; break;
463  case FormComponentType::RADIOBUTTON: pTitleResId = RID_STR_PROPTITLE_RADIOBUTTON; break;
464  case FormComponentType::CHECKBOX: pTitleResId = RID_STR_PROPTITLE_CHECKBOX; break;
465  case FormComponentType::GROUPBOX: pTitleResId = RID_STR_PROPTITLE_GROUPBOX; break;
466  case FormComponentType::FIXEDTEXT: pTitleResId = RID_STR_PROPTITLE_FIXEDTEXT; break;
467  }
468 
469  if (pTitleResId)
470  sInitialLabel = SvxResId(pTitleResId);
471 
472  _rxControlModel->setPropertyValue(
473  FM_PROP_LABEL,
474  makeAny( lcl_getUniqueLabel_nothrow( _rxControlModel, sInitialLabel ) )
475  );
476  }
477  }
478 
479  // strict format = yes is the default (i93467)
480  if ( xPSI->hasPropertyByName( FM_PROP_STRICTFORMAT ) )
481  {
482  _rxControlModel->setPropertyValue( FM_PROP_STRICTFORMAT, makeAny( true ) );
483  }
484 
485  // mouse wheel: don't use it for scrolling by default (i110036)
486  if ( xPSI->hasPropertyByName( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) )
487  {
488  _rxControlModel->setPropertyValue( FM_PROP_MOUSE_WHEEL_BEHAVIOR, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) );
489  }
490 
491  if ( xPSI->hasPropertyByName( FM_PROP_WRITING_MODE ) )
492  _rxControlModel->setPropertyValue( FM_PROP_WRITING_MODE, makeAny( WritingMode2::CONTEXT ) );
493  }
494  catch( const Exception& )
495  {
497  }
498  return nClassId;
499  }
500 
501 
503  {
504  OSL_PRECOND( _rxModel.is(), "initializeTextFieldLineEnds: invalid model!" );
505  if ( !_rxModel.is() )
506  return;
507 
508  try
509  {
510  Reference< XPropertySetInfo > xInfo = _rxModel->getPropertySetInfo();
511  if ( !xInfo.is() || !xInfo->hasPropertyByName( FM_PROP_LINEENDFORMAT ) )
512  return;
513 
514  // let's see if the data source which the form belongs to (if any)
515  // has a setting for the preferred line end format
516  bool bDosLineEnds = false;
517  Sequence< PropertyValue > aInfo = lcl_getDataSourceIndirectProperties( _rxModel, m_xContext );
518  const PropertyValue* pInfo = std::find_if(aInfo.begin(), aInfo.end(),
519  [](const PropertyValue& rInfo) { return rInfo.Name == "PreferDosLikeLineEnds"; });
520  if (pInfo != aInfo.end())
521  pInfo->Value >>= bDosLineEnds;
522 
523  sal_Int16 nLineEndFormat = bDosLineEnds ? LineEndFormat::CARRIAGE_RETURN_LINE_FEED : LineEndFormat::LINE_FEED;
524  _rxModel->setPropertyValue( FM_PROP_LINEENDFORMAT, makeAny( nLineEndFormat ) );
525  }
526  catch( const Exception& )
527  {
529  }
530  }
531 
532 
534  const Reference< XPropertySet >& _rxControlModel, const Reference< XNumberFormats >& _rxNumberFormats )
535  {
536  OSL_PRECOND( _rxDatabaseField.is() && _rxControlModel.is(),
537  "FormControlFactory::initializeFieldDependentProperties: illegal params!" );
538  if ( !_rxDatabaseField.is() || !_rxControlModel.is() )
539  return;
540 
541  try
542  {
543 
544  // if the field has a numeric format, and the model has a "Scale" property, sync it
545  Reference< XPropertySetInfo > xFieldPSI( _rxDatabaseField->getPropertySetInfo(), UNO_SET_THROW );
546  Reference< XPropertySetInfo > xModelPSI( _rxControlModel->getPropertySetInfo(), UNO_SET_THROW );
547 
548  if ( xModelPSI->hasPropertyByName( FM_PROP_DECIMAL_ACCURACY ) )
549  {
550  sal_Int32 nFormatKey = 0;
551  if ( xFieldPSI->hasPropertyByName( FM_PROP_FORMATKEY ) )
552  {
553  _rxDatabaseField->getPropertyValue( FM_PROP_FORMATKEY ) >>= nFormatKey;
554  }
555  else
556  {
557  nFormatKey = getDefaultNumberFormat(
558  _rxDatabaseField,
559  Reference< XNumberFormatTypes >( _rxNumberFormats, UNO_QUERY ),
560  SvtSysLocale().GetLanguageTag().getLocale()
561  );
562  }
563 
564  Any aScaleVal( ::comphelper::getNumberFormatDecimals( _rxNumberFormats, nFormatKey ) );
565  _rxControlModel->setPropertyValue( FM_PROP_DECIMAL_ACCURACY, aScaleVal );
566  }
567 
568 
569  // minimum and maximum of the control according to the type of the database field
570  sal_Int32 nDataType = DataType::OTHER;
571  OSL_VERIFY( _rxDatabaseField->getPropertyValue( FM_PROP_FIELDTYPE ) >>= nDataType );
572 
573  if ( xModelPSI->hasPropertyByName( FM_PROP_VALUEMIN )
574  && xModelPSI->hasPropertyByName( FM_PROP_VALUEMAX )
575  )
576  {
577  sal_Int32 nMinValue = -1000000000, nMaxValue = 1000000000;
578  switch ( nDataType )
579  {
580  case DataType::TINYINT : nMinValue = 0; nMaxValue = 255; break;
581  case DataType::SMALLINT : nMinValue = -32768; nMaxValue = 32767; break;
582  case DataType::INTEGER : nMinValue = 0x80000000; nMaxValue = 0x7FFFFFFF; break;
583  // double and singles are ignored
584  }
585 
586  Any aValue;
587 
588  // both the minimum and the maximum value properties can be either Long or Double
589  Property aProperty = xModelPSI->getPropertyByName( FM_PROP_VALUEMIN );
590  if ( aProperty.Type.getTypeClass() == TypeClass_DOUBLE )
591  aValue <<= static_cast<double>(nMinValue);
592  else if ( aProperty.Type.getTypeClass() == TypeClass_LONG )
593  aValue <<= nMinValue;
594  else
595  {
596  OSL_FAIL( "FormControlFactory::initializeFieldDependentProperties: unexpected property type (MinValue)!" );
597  }
598  _rxControlModel->setPropertyValue( FM_PROP_VALUEMIN, aValue );
599 
600  // both the minimum and the maximum value properties can be either Long or Double
601  aProperty = xModelPSI->getPropertyByName( FM_PROP_VALUEMAX );
602  if ( aProperty.Type.getTypeClass() == TypeClass_DOUBLE )
603  aValue <<= static_cast<double>(nMaxValue);
604  else if ( aProperty.Type.getTypeClass() == TypeClass_LONG )
605  aValue <<= nMaxValue;
606  else
607  {
608  OSL_FAIL( "FormControlFactory::initializeFieldDependentProperties: unexpected property type (MaxValue)!" );
609  }
610  _rxControlModel->setPropertyValue( FM_PROP_VALUEMAX, aValue );
611  }
612 
613 
614  // a check box can be tristate if and only if the column it is bound to is nullable
615  sal_Int16 nClassId = FormComponentType::CONTROL;
616  OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
617  if ( nClassId == FormComponentType::CHECKBOX )
618  {
619  sal_Int32 nNullable = ColumnValue::NULLABLE_UNKNOWN;
620  OSL_VERIFY( _rxDatabaseField->getPropertyValue( FM_PROP_ISNULLABLE ) >>= nNullable );
621  _rxControlModel->setPropertyValue( FM_PROP_TRISTATE, makeAny( ColumnValue::NO_NULLS != nNullable ) );
622  }
623  }
624  catch( const Exception& )
625  {
627  }
628  }
629 
630 
631  OUString FormControlFactory::getDefaultName( sal_Int16 _nClassId, const Reference< XServiceInfo >& _rxObject )
632  {
633  TranslateId pResId;
634 
635  switch ( _nClassId )
636  {
637  case FormComponentType::COMMANDBUTTON: pResId = RID_STR_PROPTITLE_PUSHBUTTON; break;
638  case FormComponentType::RADIOBUTTON: pResId = RID_STR_PROPTITLE_RADIOBUTTON; break;
639  case FormComponentType::CHECKBOX: pResId = RID_STR_PROPTITLE_CHECKBOX; break;
640  case FormComponentType::LISTBOX: pResId = RID_STR_PROPTITLE_LISTBOX; break;
641  case FormComponentType::COMBOBOX: pResId = RID_STR_PROPTITLE_COMBOBOX; break;
642  case FormComponentType::GROUPBOX: pResId = RID_STR_PROPTITLE_GROUPBOX; break;
643  case FormComponentType::IMAGEBUTTON: pResId = RID_STR_PROPTITLE_IMAGEBUTTON; break;
644  case FormComponentType::FIXEDTEXT: pResId = RID_STR_PROPTITLE_FIXEDTEXT; break;
645  case FormComponentType::GRIDCONTROL: pResId = RID_STR_PROPTITLE_DBGRID; break;
646  case FormComponentType::FILECONTROL: pResId = RID_STR_PROPTITLE_FILECONTROL; break;
647  case FormComponentType::DATEFIELD: pResId = RID_STR_PROPTITLE_DATEFIELD; break;
648  case FormComponentType::TIMEFIELD: pResId = RID_STR_PROPTITLE_TIMEFIELD; break;
649  case FormComponentType::NUMERICFIELD: pResId = RID_STR_PROPTITLE_NUMERICFIELD; break;
650  case FormComponentType::CURRENCYFIELD: pResId = RID_STR_PROPTITLE_CURRENCYFIELD; break;
651  case FormComponentType::PATTERNFIELD: pResId = RID_STR_PROPTITLE_PATTERNFIELD; break;
652  case FormComponentType::IMAGECONTROL: pResId = RID_STR_PROPTITLE_IMAGECONTROL; break;
653  case FormComponentType::HIDDENCONTROL: pResId = RID_STR_PROPTITLE_HIDDEN; break;
654  case FormComponentType::SCROLLBAR: pResId = RID_STR_PROPTITLE_SCROLLBAR; break;
655  case FormComponentType::SPINBUTTON: pResId = RID_STR_PROPTITLE_SPINBUTTON; break;
656  case FormComponentType::NAVIGATIONBAR: pResId = RID_STR_PROPTITLE_NAVBAR; break;
657 
658  case FormComponentType::TEXTFIELD:
659  pResId = RID_STR_PROPTITLE_EDIT;
660  if ( _rxObject.is() && _rxObject->supportsService( FM_SUN_COMPONENT_FORMATTEDFIELD ) )
661  pResId = RID_STR_PROPTITLE_FORMATTED;
662  break;
663 
664  default:
665  pResId = RID_STR_CONTROL; break;
666  }
667 
668  return SvxResId(pResId);
669  }
670 
671 
673  const Reference< XPropertySet >& _rxObject )
674  {
675  sal_Int16 nClassId = FormComponentType::CONTROL;
676  OSL_VERIFY( _rxObject->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
677  OUString sBaseName = getDefaultName( nClassId, Reference< XServiceInfo >( _rxObject, UNO_QUERY ) );
678 
679  return getUniqueName( _rxContainer, sBaseName );
680  }
681 
682 
683  OUString FormControlFactory::getUniqueName( const Reference< XNameAccess >& _rxContainer, const OUString& _rBaseName )
684  {
685  sal_Int32 n = 0;
686  OUString sName;
687  do
688  {
689  OUStringBuffer aBuf( _rBaseName );
690  aBuf.append( " " );
691  aBuf.append( ++n );
692  sName = aBuf.makeStringAndClear();
693  }
694  while ( _rxContainer->hasByName( sName ) );
695 
696  return sName;
697  }
698 
699 
700 }
701 
702 
703 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XInterface > getDataSource(const Reference< XInterface > &_rxDependentObject)
sal_Int32 nNullable
#define FM_PROP_DECIMAL_ACCURACY
Definition: fmprop.hxx:72
virtual const tools::Rectangle & GetCurrentBoundRect() const
Definition: svdobj.cxx:957
std::set< OUString > StringBag
#define FM_PROP_FIELDTYPE
Definition: fmprop.hxx:75
#define FM_PROP_VALUEMAX
Definition: fmprop.hxx:37
void initializeControlLayout(const css::uno::Reference< css::beans::XPropertySet > &_rxControlModel, DocumentType _eDocType)
initializes the layout of a newly created form control (model)
sal_Int64 n
#define FM_PROP_MULTILINE
Definition: fmprop.hxx:51
aBuf
#define FM_PROP_DATASOURCE
Definition: fmprop.hxx:78
static OUString getDefaultName(const sal_Int16 nClassId, const css::uno::Reference< css::lang::XServiceInfo > &_rxObject)
#define FM_PROP_NAME
Definition: fmprop.hxx:29
#define FM_PROP_TRISTATE
Definition: fmprop.hxx:58
DataType
static OUString getDefaultUniqueName_ByComponentType(const css::uno::Reference< css::container::XNameAccess > &_rxContainer, const css::uno::Reference< css::beans::XPropertySet > &_rxObject)
OUString SvxResId(TranslateId aId)
Definition: dialmgr.cxx:24
#define FM_PROP_CLASSID
Definition: fmprop.hxx:30
constexpr tools::Long GetWidth() const
constexpr bool IsEmpty() const
DocumentType
#define DBG_UNHANDLED_EXCEPTION(...)
#define TOOLS_WARN_EXCEPTION(area, stream)
int i
class SAL_NO_VTABLE XPropertySet
Definition: xmlexchg.hxx:28
OUString sName
css::uno::Reference< css::beans::XPropertySet > getDefaultDocumentTextStyle(const css::uno::Reference< css::beans::XPropertySet > &_rxModel)
gets the "default" style in a document which can be used if some default text format is needed ...
#define FM_PROP_ISNULLABLE
Definition: fmprop.hxx:124
#define FM_PROP_FORMATKEY
Definition: fmprop.hxx:65
#define FM_PROP_ORIENTATION
Definition: fmprop.hxx:134
tuple index
css::uno::Reference< css::uno::XComponentContext > m_xContext
#define FM_SUN_COMPONENT_FORMATTEDFIELD
Definition: fmservs.hxx:73
const LanguageTag & getLocale()
sal_Int32 getDefaultNumberFormat(const Reference< XPropertySet > &_xColumn, const Reference< XNumberFormatTypes > &_xTypes, const Locale &_rLocale)
#define FM_PROP_WRITING_MODE
Definition: fmprop.hxx:145
#define FM_PROP_LINEENDFORMAT
Definition: fmprop.hxx:135
std::unique_ptr< char[]> aBuffer
static void initializeFieldDependentProperties(const css::uno::Reference< css::beans::XPropertySet > &_rxDatabaseField, const css::uno::Reference< css::beans::XPropertySet > &_rxControlModel, const css::uno::Reference< css::util::XNumberFormats > &_rxNumberFormats)
sal_Int16 initializeControlModel(const DocumentType _eDocType, const css::uno::Reference< css::beans::XPropertySet > &_rxControlModel, const tools::Rectangle &_rControlBoundRect)
initializes the given control model which is to be newly inserted into a document ...
sal_Int32 nDataType
#define FM_PROP_STRICTFORMAT
Definition: fmprop.hxx:77
Reference< XComponentContext > getProcessComponentContext()
#define FM_PROP_MOUSE_WHEEL_BEHAVIOR
Definition: fmprop.hxx:146
css::uno::Any getNumberFormatDecimals(const css::uno::Reference< css::util::XNumberFormats > &xFormats, sal_Int32 nKey)
const css::uno::Reference< css::awt::XControlModel > & GetUnoControlModel() const
Definition: svdouno.hxx:91
class FmSearchEngine - Impl class for FmSearchDialog
#define FM_PROP_DROPDOWN
Definition: fmprop.hxx:96
Reference< XComponentContext > m_xContext
#define FM_PROP_VALUEMIN
Definition: fmprop.hxx:36
#define FM_PROP_LINECOUNT
Definition: fmprop.hxx:89
void initializeTextFieldLineEnds(const css::uno::Reference< css::beans::XPropertySet > &_rxModel)
static OUString getUniqueName(const css::uno::Reference< css::container::XNameAccess > &_rxContainer, const OUString &_rBaseName)
constexpr tools::Long GetHeight() const
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)