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/util/XNumberFormatTypes.hpp>
39 #include <com/sun/star/sdbc/ColumnValue.hpp>
40 #include <com/sun/star/text/WritingMode2.hpp>
41 
42 #include <comphelper/numbers.hxx>
44 #include <unotools/syslocale.hxx>
45 #include <tools/gen.hxx>
46 #include <tools/diagnose_ex.h>
47 #include <connectivity/dbtools.hxx>
49 
50 #include <set>
51 
52 using namespace ::dbtools;
53 
54 namespace svxform
55 {
56 
57 
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;
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  {
96 
98  :m_xContext( _rContext )
99  {
100  }
101  };
102 
104  :m_pData( new FormControlFactory_Data( _rContext ) )
105  {
106  }
107 
110  {
111  }
112 
113 
115  {
116  }
117 
118 
119  sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const SdrUnoObj& _rObject )
120  {
121  return initializeControlModel(
122  _eDocType,
123  Reference< XPropertySet >( _rObject.GetUnoControlModel(), UNO_QUERY ),
124  _rObject.GetCurrentBoundRect()
125  );
126  }
127 
128 
129  void FormControlFactory::initializeControlModel( const DocumentType _eDocType, const Reference< XPropertySet >& _rxControlModel )
130  {
132  _eDocType, _rxControlModel, tools::Rectangle()
133  );
134  }
135 
136 
137  namespace
138  {
139 
140  OUString lcl_getUniqueLabel_nothrow( const Reference< XPropertySet >& _rxControlModel, const OUString& _rBaseLabel )
141  {
142  OUString sLabel( _rBaseLabel );
143  try
144  {
145  typedef ::std::set< OUString > StringBag;
146  StringBag aUsedLabels;
147 
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; )
152  {
153  Reference< XPropertySet > xElement( xContainer->getByIndex( --index ), UNO_QUERY_THROW );
154  if ( xElement == _rxControlModel )
155  continue;
156 
157  Reference< XPropertySetInfo > xPSI( xElement->getPropertySetInfo(), UNO_SET_THROW );
158  if ( !xPSI->hasPropertyByName( FM_PROP_LABEL ) )
159  continue;
160 
161  OUString sElementLabel;
162  OSL_VERIFY( xElement->getPropertyValue( FM_PROP_LABEL ) >>= sElementLabel );
163  aUsedLabels.insert( sElementLabel );
164  }
165 
166  // now find a free label
167  sal_Int32 i=2;
168  while ( aUsedLabels.find( sLabel ) != aUsedLabels.end() )
169  {
170  OUStringBuffer aBuffer( _rBaseLabel );
171  aBuffer.append( " " );
172  aBuffer.append( i++ );
173  sLabel = aBuffer.makeStringAndClear();
174  }
175  }
176  catch( const Exception& )
177  {
179  }
180  return sLabel;
181  }
182 
183 
184  Sequence< PropertyValue > lcl_getDataSourceIndirectProperties( const Reference< XPropertySet >& _rxControlModel,
185  const Reference<XComponentContext>& _rContext )
186  {
187  OSL_PRECOND( _rxControlModel.is(), "lcl_getDataSourceIndirectProperties: invalid model!" );
188 
189  Sequence< PropertyValue > aInfo;
190  try
191  {
192  Reference< XChild > xChild( _rxControlModel, UNO_QUERY );
193  Reference< XPropertySet > xForm;
194  if ( xChild.is() )
195  xForm.set(xChild->getParent(), css::uno::UNO_QUERY);
196 
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);
201  }
202 
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;
208 
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;
214  }
215  catch( const Exception& )
216  {
217  OSL_FAIL( "lcl_getDataSourceIndirectProperties: caught an exception!" );
218  }
219  return aInfo;
220  }
221 
222 
223  static const sal_Char* aCharacterAndParagraphProperties[] =
224  {
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
352  };
353 
354 
355  void lcl_initializeCharacterAttributes( const Reference< XPropertySet >& _rxModel )
356  {
357  try
358  {
359  Reference< XPropertySet > xStyle( ControlLayouter::getDefaultDocumentTextStyle( _rxModel ), UNO_SET_THROW );
360 
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 );
364 
365  OUString sPropertyName;
366  const sal_Char** pCharacterProperty = aCharacterAndParagraphProperties;
367  while ( *pCharacterProperty )
368  {
369  sPropertyName = OUString::createFromAscii( *pCharacterProperty );
370 
371  if ( xSourcePropInfo->hasPropertyByName( sPropertyName ) && xDestPropInfo->hasPropertyByName( sPropertyName ) )
372  _rxModel->setPropertyValue( sPropertyName, xStyle->getPropertyValue( sPropertyName ) );
373 
374  ++pCharacterProperty;
375  }
376  }
377  catch( const Exception& )
378  {
380  }
381  }
382  }
383 
384 
385  sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const Reference< XPropertySet >& _rxControlModel,
386  const tools::Rectangle& _rControlBoundRect )
387  {
388  sal_Int16 nClassId = FormComponentType::CONTROL;
389 
390  OSL_ENSURE( _rxControlModel.is(), "FormControlFactory::initializeControlModel: invalid model!" );
391  if ( !_rxControlModel.is() )
392  return nClassId;
393 
394  try
395  {
396  ControlLayouter::initializeControlLayout( _rxControlModel, _eDocType );
397 
398  _rxControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId;
399  Reference< XPropertySetInfo > xPSI( _rxControlModel->getPropertySetInfo(), UNO_SET_THROW );
400  switch ( nClassId )
401  {
402  case FormComponentType::SCROLLBAR:
403  _rxControlModel->setPropertyValue("LiveScroll", makeAny( true ) );
404  [[fallthrough]];
405  case FormComponentType::SPINBUTTON:
406  {
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 ) );
411  }
412  break;
413 
414  case FormComponentType::LISTBOX:
415  case FormComponentType::COMBOBOX:
416  {
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 ) ) );
421  }
422  break;
423 
424  case FormComponentType::TEXTFIELD:
425  {
426  initializeTextFieldLineEnds( _rxControlModel );
427  lcl_initializeCharacterAttributes( _rxControlModel );
428 
429  if ( !_rControlBoundRect.IsEmpty()
430  && ( _rControlBoundRect.GetWidth() <= 4 * _rControlBoundRect.GetHeight() )
431  )
432  {
433  if ( xPSI->hasPropertyByName( FM_PROP_MULTILINE ) )
434  _rxControlModel->setPropertyValue( FM_PROP_MULTILINE, makeAny( true ) );
435  }
436  }
437  break;
438 
439  case FormComponentType::RADIOBUTTON:
440  case FormComponentType::CHECKBOX:
441  case FormComponentType::FIXEDTEXT:
442  {
443  OUString sVertAlignPropertyName( "VerticalAlign" );
444  if ( xPSI->hasPropertyByName( sVertAlignPropertyName ) )
445  _rxControlModel->setPropertyValue( sVertAlignPropertyName, makeAny( VerticalAlignment_MIDDLE ) );
446  }
447  break;
448 
449  case FormComponentType::IMAGEBUTTON:
450  case FormComponentType::IMAGECONTROL:
451  {
452  const OUString sScaleModeProperty( "ScaleMode" );
453  if ( xPSI->hasPropertyByName( sScaleModeProperty ) )
454  _rxControlModel->setPropertyValue( sScaleModeProperty, makeAny( ImageScaleMode::ISOTROPIC ) );
455  }
456  break;
457  }
458 
459  // initial default label for the control
460  if ( xPSI->hasPropertyByName( FM_PROP_LABEL ) )
461  {
462  OUString sExistingLabel;
463  OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_LABEL ) >>= sExistingLabel );
464  if ( sExistingLabel.isEmpty() )
465  {
466  OUString sInitialLabel;
467  OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_NAME ) >>= sInitialLabel );
468 
469  const char* pTitleResId = nullptr;
470  switch ( nClassId )
471  {
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;
477  }
478 
479  if (pTitleResId)
480  sInitialLabel = SvxResId(pTitleResId);
481 
482  _rxControlModel->setPropertyValue(
483  FM_PROP_LABEL,
484  makeAny( lcl_getUniqueLabel_nothrow( _rxControlModel, sInitialLabel ) )
485  );
486  }
487  }
488 
489  // strict format = yes is the default (i93467)
490  if ( xPSI->hasPropertyByName( FM_PROP_STRICTFORMAT ) )
491  {
492  _rxControlModel->setPropertyValue( FM_PROP_STRICTFORMAT, makeAny( true ) );
493  }
494 
495  // mouse wheel: don't use it for scrolling by default (i110036)
496  if ( xPSI->hasPropertyByName( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) )
497  {
498  _rxControlModel->setPropertyValue( FM_PROP_MOUSE_WHEEL_BEHAVIOR, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) );
499  }
500 
501  if ( xPSI->hasPropertyByName( FM_PROP_WRITING_MODE ) )
502  _rxControlModel->setPropertyValue( FM_PROP_WRITING_MODE, makeAny( WritingMode2::CONTEXT ) );
503  }
504  catch( const Exception& )
505  {
507  }
508  return nClassId;
509  }
510 
511 
512  void FormControlFactory::initializeTextFieldLineEnds( const Reference< XPropertySet >& _rxModel )
513  {
514  OSL_PRECOND( _rxModel.is(), "initializeTextFieldLineEnds: invalid model!" );
515  if ( !_rxModel.is() )
516  return;
517 
518  try
519  {
520  Reference< XPropertySetInfo > xInfo = _rxModel->getPropertySetInfo();
521  if ( !xInfo.is() || !xInfo->hasPropertyByName( FM_PROP_LINEENDFORMAT ) )
522  return;
523 
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;
532 
533  sal_Int16 nLineEndFormat = bDosLineEnds ? LineEndFormat::CARRIAGE_RETURN_LINE_FEED : LineEndFormat::LINE_FEED;
534  _rxModel->setPropertyValue( FM_PROP_LINEENDFORMAT, makeAny( nLineEndFormat ) );
535  }
536  catch( const Exception& )
537  {
539  }
540  }
541 
542 
543  void FormControlFactory::initializeFieldDependentProperties( const Reference< XPropertySet >& _rxDatabaseField,
544  const Reference< XPropertySet >& _rxControlModel, const Reference< XNumberFormats >& _rxNumberFormats )
545  {
546  OSL_PRECOND( _rxDatabaseField.is() && _rxControlModel.is(),
547  "FormControlFactory::initializeFieldDependentProperties: illegal params!" );
548  if ( !_rxDatabaseField.is() || !_rxControlModel.is() )
549  return;
550 
551  try
552  {
553 
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 );
557 
558  if ( xModelPSI->hasPropertyByName( FM_PROP_DECIMAL_ACCURACY ) )
559  {
560  sal_Int32 nFormatKey = 0;
561  if ( xFieldPSI->hasPropertyByName( FM_PROP_FORMATKEY ) )
562  {
563  _rxDatabaseField->getPropertyValue( FM_PROP_FORMATKEY ) >>= nFormatKey;
564  }
565  else
566  {
567  nFormatKey = getDefaultNumberFormat(
568  _rxDatabaseField,
569  Reference< XNumberFormatTypes >( _rxNumberFormats, UNO_QUERY ),
570  SvtSysLocale().GetLanguageTag().getLocale()
571  );
572  }
573 
574  Any aScaleVal( ::comphelper::getNumberFormatDecimals( _rxNumberFormats, nFormatKey ) );
575  _rxControlModel->setPropertyValue( FM_PROP_DECIMAL_ACCURACY, aScaleVal );
576  }
577 
578 
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 );
582 
583  if ( xModelPSI->hasPropertyByName( FM_PROP_VALUEMIN )
584  && xModelPSI->hasPropertyByName( FM_PROP_VALUEMAX )
585  )
586  {
587  sal_Int32 nMinValue = -1000000000, nMaxValue = 1000000000;
588  switch ( nDataType )
589  {
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
594  }
595 
596  Any aValue;
597 
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
605  {
606  OSL_FAIL( "FormControlFactory::initializeFieldDependentProperties: unexpected property type (MinValue)!" );
607  }
608  _rxControlModel->setPropertyValue( FM_PROP_VALUEMIN, aValue );
609 
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
617  {
618  OSL_FAIL( "FormControlFactory::initializeFieldDependentProperties: unexpected property type (MaxValue)!" );
619  }
620  _rxControlModel->setPropertyValue( FM_PROP_VALUEMAX, aValue );
621  }
622 
623 
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 )
628  {
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 ) );
632  }
633  }
634  catch( const Exception& )
635  {
637  }
638  }
639 
640 
641  OUString FormControlFactory::getDefaultName( sal_Int16 _nClassId, const Reference< XServiceInfo >& _rxObject )
642  {
643  const char* pResId(nullptr);
644 
645  switch ( _nClassId )
646  {
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;
667 
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;
673 
674  default:
675  pResId = RID_STR_CONTROL; break;
676  }
677 
678  return SvxResId(pResId);
679  }
680 
681 
682  OUString FormControlFactory::getDefaultUniqueName_ByComponentType( const Reference< XNameAccess >& _rxContainer,
683  const Reference< XPropertySet >& _rxObject )
684  {
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 ) );
688 
689  return getUniqueName( _rxContainer, sBaseName );
690  }
691 
692 
693  OUString FormControlFactory::getUniqueName( const Reference< XNameAccess >& _rxContainer, const OUString& _rBaseName )
694  {
695  sal_Int32 n = 0;
696  OUString sName;
697  do
698  {
699  OUStringBuffer aBuf( _rBaseName );
700  aBuf.append( " " );
701  aBuf.append( ++n );
702  sName = aBuf.makeStringAndClear();
703  }
704  while ( _rxContainer->hasByName( sName ) );
705 
706  return sName;
707  }
708 
709 
710 }
711 
712 
713 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XInterface > getDataSource(const Reference< XInterface > &_rxDependentObject)
long GetWidth() const
sal_Int32 nNullable
#define FM_PROP_DECIMAL_ACCURACY
Definition: fmprop.hxx:72
long GetHeight() const
virtual const tools::Rectangle & GetCurrentBoundRect() const
Definition: svdobj.cxx:881
::std::unique_ptr< FormControlFactory_Data > m_pData
#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
FormControlFactory_Data(const Reference< XComponentContext > &_rContext)
static OUString getDefaultName(const sal_Int16 nClassId, const css::uno::Reference< css::lang::XServiceInfo > &_rxObject)
std::set< OUString > StringBag
bool IsEmpty() const
#define FM_PROP_TRISTATE
Definition: fmprop.hxx:58
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:28
DataType
static OUString getDefaultUniqueName_ByComponentType(const css::uno::Reference< css::container::XNameAccess > &_rxContainer, const css::uno::Reference< css::beans::XPropertySet > &_rxObject)
char sal_Char
#define FM_PROP_CLASSID
Definition: fmprop.hxx:30
DocumentType
#define DBG_UNHANDLED_EXCEPTION(...)
class SAL_NO_VTABLE XPropertySet
Definition: xmlexchg.hxx:31
OUString sName
int i
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
FmFilterData *const m_pData
Definition: filtnav.cxx:184
#define FM_SUN_COMPONENT_FORMATTEDFIELD
Definition: fmservs.hxx:75
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
#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)
Reference< XComponentContext > m_xContext
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)