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