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/numbers.hxx>
45 : #include <comphelper/processfactory.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 : 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;
87 :
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 : Reference<XComponentContext> m_xContext;
103 :
104 0 : FormControlFactory_Data( const Reference<XComponentContext>& _rContext )
105 0 : :m_xContext( _rContext )
106 : {
107 0 : }
108 : };
109 :
110 :
111 : //= FormControlFactory
112 :
113 :
114 0 : FormControlFactory::FormControlFactory( const Reference<XComponentContext>& _rContext )
115 0 : :m_pData( new FormControlFactory_Data( _rContext ) )
116 : {
117 0 : }
118 :
119 0 : FormControlFactory::FormControlFactory( )
120 0 : :m_pData( new FormControlFactory_Data( comphelper::getProcessComponentContext() ) )
121 : {
122 0 : }
123 :
124 :
125 0 : FormControlFactory::~FormControlFactory()
126 : {
127 0 : }
128 :
129 :
130 0 : sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const SdrUnoObj& _rObject )
131 : {
132 : return initializeControlModel(
133 : _eDocType,
134 : Reference< XPropertySet >( _rObject.GetUnoControlModel(), UNO_QUERY ),
135 0 : _rObject.GetCurrentBoundRect()
136 0 : );
137 : }
138 :
139 :
140 0 : sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const Reference< XPropertySet >& _rxControlModel )
141 : {
142 : return initializeControlModel(
143 : _eDocType, _rxControlModel, Rectangle()
144 0 : );
145 : }
146 :
147 :
148 : namespace
149 : {
150 :
151 0 : static OUString lcl_getUniqueLabel_nothrow( const Reference< XPropertySet >& _rxControlModel, const OUString& _rBaseLabel )
152 : {
153 0 : OUString sLabel( _rBaseLabel );
154 : try
155 : {
156 : typedef ::std::set< OUString > StringBag;
157 0 : StringBag aUsedLabels;
158 :
159 0 : Reference< XFormComponent > xFormComponent( _rxControlModel, UNO_QUERY_THROW );
160 0 : Reference< XIndexAccess > xContainer( xFormComponent->getParent(), UNO_QUERY_THROW );
161 : // loop through all siblings of the control model, and collect their labels
162 0 : for ( sal_Int32 index=xContainer->getCount(); index>0; )
163 : {
164 0 : Reference< XPropertySet > xElement( xContainer->getByIndex( --index ), UNO_QUERY_THROW );
165 0 : if ( xElement == _rxControlModel )
166 0 : continue;
167 :
168 0 : Reference< XPropertySetInfo > xPSI( xElement->getPropertySetInfo(), UNO_SET_THROW );
169 0 : if ( !xPSI->hasPropertyByName( FM_PROP_LABEL ) )
170 0 : continue;
171 :
172 0 : OUString sElementLabel;
173 0 : OSL_VERIFY( xElement->getPropertyValue( FM_PROP_LABEL ) >>= sElementLabel );
174 0 : aUsedLabels.insert( sElementLabel );
175 0 : }
176 :
177 : // now find a free label
178 0 : sal_Int32 i=2;
179 0 : while ( aUsedLabels.find( sLabel ) != aUsedLabels.end() )
180 : {
181 0 : OUStringBuffer aBuffer( _rBaseLabel );
182 0 : aBuffer.appendAscii( " " );
183 0 : aBuffer.append( (sal_Int32)i++ );
184 0 : sLabel = aBuffer.makeStringAndClear();
185 0 : }
186 : }
187 0 : catch( const Exception& )
188 : {
189 : DBG_UNHANDLED_EXCEPTION();
190 : }
191 0 : return sLabel;
192 : }
193 :
194 :
195 0 : static Sequence< PropertyValue > lcl_getDataSourceIndirectProperties( const Reference< XPropertySet >& _rxControlModel,
196 : const Reference<XComponentContext>& _rContext )
197 : {
198 : OSL_PRECOND( _rxControlModel.is(), "lcl_getDataSourceIndirectProperties: invalid model!" );
199 :
200 0 : Sequence< PropertyValue > aInfo;
201 : try
202 : {
203 0 : Reference< XChild > xChild( _rxControlModel, UNO_QUERY );
204 0 : Reference< XPropertySet > xForm;
205 0 : if ( xChild.is() )
206 0 : xForm = xForm.query( xChild->getParent() );
207 :
208 0 : if ( Reference< XGridColumnFactory >( xForm, UNO_QUERY ).is() )
209 : { // hmm. the model is a grid column, in real
210 0 : xChild = xChild.query( xForm );
211 0 : xForm = xForm.query( xChild->getParent() );
212 : }
213 :
214 : OSL_ENSURE( xForm.is(), "lcl_getDataSourceIndirectProperties: could not determine the form!" );
215 0 : if ( !xForm.is() )
216 0 : return aInfo;
217 0 : OUString sDataSourceName;
218 0 : xForm->getPropertyValue( FM_PROP_DATASOURCE ) >>= sDataSourceName;
219 :
220 0 : Reference< XPropertySet > xDsProperties;
221 0 : if ( !sDataSourceName.isEmpty() )
222 0 : xDsProperties = xDsProperties.query( OStaticDataAccessTools().getDataSource( sDataSourceName, _rContext ) );
223 0 : if ( xDsProperties.is() )
224 0 : xDsProperties->getPropertyValue("Info") >>= aInfo;
225 : }
226 0 : catch( const Exception& )
227 : {
228 : OSL_FAIL( "lcl_getDataSourceIndirectProperties: caught an exception!" );
229 : }
230 0 : return aInfo;
231 : }
232 :
233 :
234 : static const sal_Char* aCharacterAndParagraphProperties[] =
235 : {
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
362 : };
363 :
364 :
365 0 : static void lcl_initializeCharacterAttributes( const Reference< XPropertySet >& _rxModel )
366 : {
367 : try
368 : {
369 0 : Reference< XPropertySet > xStyle( ControlLayouter::getDefaultDocumentTextStyle( _rxModel ), UNO_SET_THROW );
370 :
371 : // transfer all properties which are described by the style
372 0 : Reference< XPropertySetInfo > xSourcePropInfo( xStyle->getPropertySetInfo(), UNO_SET_THROW );
373 0 : Reference< XPropertySetInfo > xDestPropInfo( _rxModel->getPropertySetInfo(), UNO_SET_THROW );
374 :
375 0 : OUString sPropertyName;
376 0 : const sal_Char** pCharacterProperty = aCharacterAndParagraphProperties;
377 0 : while ( *pCharacterProperty )
378 : {
379 0 : sPropertyName = OUString::createFromAscii( *pCharacterProperty );
380 :
381 0 : if ( xSourcePropInfo->hasPropertyByName( sPropertyName ) && xDestPropInfo->hasPropertyByName( sPropertyName ) )
382 0 : _rxModel->setPropertyValue( sPropertyName, xStyle->getPropertyValue( sPropertyName ) );
383 :
384 0 : ++pCharacterProperty;
385 0 : }
386 : }
387 0 : catch( const Exception& )
388 : {
389 : DBG_UNHANDLED_EXCEPTION();
390 : }
391 0 : }
392 : }
393 :
394 :
395 0 : sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const Reference< XPropertySet >& _rxControlModel,
396 : const Rectangle& _rControlBoundRect )
397 : {
398 0 : sal_Int16 nClassId = FormComponentType::CONTROL;
399 :
400 : OSL_ENSURE( _rxControlModel.is(), "FormControlFactory::initializeControlModel: invalid model!" );
401 0 : if ( !_rxControlModel.is() )
402 0 : return nClassId;
403 :
404 : try
405 : {
406 0 : ControlLayouter::initializeControlLayout( _rxControlModel, _eDocType );
407 :
408 0 : _rxControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId;
409 0 : Reference< XPropertySetInfo > xPSI( _rxControlModel->getPropertySetInfo(), UNO_SET_THROW );
410 0 : switch ( nClassId )
411 : {
412 : case FormComponentType::SCROLLBAR:
413 0 : _rxControlModel->setPropertyValue("LiveScroll", makeAny( (sal_Bool)sal_True ) );
414 : // NO break!
415 : case FormComponentType::SPINBUTTON:
416 : {
417 0 : sal_Int32 eOrientation = ScrollBarOrientation::HORIZONTAL;
418 0 : if ( !_rControlBoundRect.IsEmpty() && ( _rControlBoundRect.GetWidth() < _rControlBoundRect.GetHeight() ) )
419 0 : eOrientation = ScrollBarOrientation::VERTICAL;
420 0 : _rxControlModel->setPropertyValue( FM_PROP_ORIENTATION, makeAny( eOrientation ) );
421 : }
422 0 : break;
423 :
424 : case FormComponentType::LISTBOX:
425 : case FormComponentType::COMBOBOX:
426 : {
427 0 : sal_Bool bDropDown = !_rControlBoundRect.IsEmpty() && ( _rControlBoundRect.GetWidth() >= 3 * _rControlBoundRect.GetHeight() );
428 0 : if ( xPSI->hasPropertyByName( FM_PROP_DROPDOWN ) )
429 0 : _rxControlModel->setPropertyValue( FM_PROP_DROPDOWN, makeAny( (sal_Bool)bDropDown ) );
430 0 : _rxControlModel->setPropertyValue( FM_PROP_LINECOUNT, makeAny( sal_Int16( 20 ) ) );
431 : }
432 0 : break;
433 :
434 : case FormComponentType::TEXTFIELD:
435 : {
436 0 : initializeTextFieldLineEnds( _rxControlModel );
437 0 : lcl_initializeCharacterAttributes( _rxControlModel );
438 :
439 0 : if ( !_rControlBoundRect.IsEmpty()
440 0 : && !( _rControlBoundRect.GetWidth() > 4 * _rControlBoundRect.GetHeight() )
441 : )
442 : {
443 0 : if ( xPSI->hasPropertyByName( FM_PROP_MULTILINE ) )
444 0 : _rxControlModel->setPropertyValue( FM_PROP_MULTILINE, makeAny( (sal_Bool)sal_True ) );
445 : }
446 : }
447 0 : break;
448 :
449 : case FormComponentType::RADIOBUTTON:
450 : case FormComponentType::CHECKBOX:
451 : case FormComponentType::FIXEDTEXT:
452 : {
453 0 : OUString sVertAlignPropertyName( "VerticalAlign" );
454 0 : if ( xPSI->hasPropertyByName( sVertAlignPropertyName ) )
455 0 : _rxControlModel->setPropertyValue( sVertAlignPropertyName, makeAny( VerticalAlignment_MIDDLE ) );
456 : }
457 0 : break;
458 :
459 : case FormComponentType::IMAGEBUTTON:
460 : case FormComponentType::IMAGECONTROL:
461 : {
462 0 : const OUString sScaleModeProperty( "ScaleMode" );
463 0 : if ( xPSI->hasPropertyByName( sScaleModeProperty ) )
464 0 : _rxControlModel->setPropertyValue( sScaleModeProperty, makeAny( ImageScaleMode::ISOTROPIC ) );
465 : }
466 0 : break;
467 : }
468 :
469 : // initial default label for the control
470 0 : if ( xPSI->hasPropertyByName( FM_PROP_LABEL ) )
471 : {
472 0 : OUString sExistingLabel;
473 0 : OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_LABEL ) >>= sExistingLabel );
474 0 : if ( sExistingLabel.isEmpty() )
475 : {
476 0 : OUString sInitialLabel;
477 0 : OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_NAME ) >>= sInitialLabel );
478 :
479 0 : sal_uInt16 nTitleResId = 0;
480 0 : switch ( nClassId )
481 : {
482 0 : case FormComponentType::COMMANDBUTTON: nTitleResId = RID_STR_PROPTITLE_PUSHBUTTON; break;
483 0 : case FormComponentType::RADIOBUTTON: nTitleResId = RID_STR_PROPTITLE_RADIOBUTTON; break;
484 0 : case FormComponentType::CHECKBOX: nTitleResId = RID_STR_PROPTITLE_CHECKBOX; break;
485 0 : case FormComponentType::GROUPBOX: nTitleResId = RID_STR_PROPTITLE_GROUPBOX; break;
486 0 : case FormComponentType::FIXEDTEXT: nTitleResId = RID_STR_PROPTITLE_FIXEDTEXT; break;
487 : }
488 :
489 0 : if ( nTitleResId )
490 0 : sInitialLabel = SVX_RESSTR(nTitleResId);
491 :
492 0 : _rxControlModel->setPropertyValue(
493 : FM_PROP_LABEL,
494 : makeAny( lcl_getUniqueLabel_nothrow( _rxControlModel, sInitialLabel ) )
495 0 : );
496 0 : }
497 : }
498 :
499 : // strict format = yes is the default (i93467)
500 0 : if ( xPSI->hasPropertyByName( FM_PROP_STRICTFORMAT ) )
501 : {
502 0 : _rxControlModel->setPropertyValue( FM_PROP_STRICTFORMAT, makeAny( sal_Bool( sal_True ) ) );
503 : }
504 :
505 : // mouse wheel: don't use it for scrolling by default (i110036)
506 0 : if ( xPSI->hasPropertyByName( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) )
507 : {
508 0 : _rxControlModel->setPropertyValue( FM_PROP_MOUSE_WHEEL_BEHAVIOR, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) );
509 : }
510 :
511 0 : if ( xPSI->hasPropertyByName( FM_PROP_WRITING_MODE ) )
512 0 : _rxControlModel->setPropertyValue( FM_PROP_WRITING_MODE, makeAny( WritingMode2::CONTEXT ) );
513 : }
514 0 : catch( const Exception& )
515 : {
516 : DBG_UNHANDLED_EXCEPTION();
517 : }
518 0 : return nClassId;
519 : }
520 :
521 :
522 0 : void FormControlFactory::initializeTextFieldLineEnds( const Reference< XPropertySet >& _rxModel )
523 : {
524 : OSL_PRECOND( _rxModel.is(), "initializeTextFieldLineEnds: invalid model!" );
525 0 : if ( !_rxModel.is() )
526 0 : return;
527 :
528 : try
529 : {
530 0 : Reference< XPropertySetInfo > xInfo = _rxModel->getPropertySetInfo();
531 0 : if ( !xInfo.is() || !xInfo->hasPropertyByName( FM_PROP_LINEENDFORMAT ) )
532 0 : return;
533 :
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 0 : sal_Bool bDosLineEnds = sal_False;
537 0 : Sequence< PropertyValue > aInfo = lcl_getDataSourceIndirectProperties( _rxModel, m_pData->m_xContext );
538 0 : const PropertyValue* pInfo = aInfo.getConstArray();
539 0 : const PropertyValue* pInfoEnd = pInfo + aInfo.getLength();
540 0 : for ( ; pInfo != pInfoEnd; ++pInfo )
541 : {
542 0 : if ( pInfo->Name == "PreferDosLikeLineEnds" )
543 : {
544 0 : pInfo->Value >>= bDosLineEnds;
545 0 : break;
546 : }
547 : }
548 :
549 0 : sal_Int16 nLineEndFormat = bDosLineEnds ? LineEndFormat::CARRIAGE_RETURN_LINE_FEED : LineEndFormat::LINE_FEED;
550 0 : _rxModel->setPropertyValue( FM_PROP_LINEENDFORMAT, makeAny( nLineEndFormat ) );
551 : }
552 0 : catch( const Exception& )
553 : {
554 : DBG_UNHANDLED_EXCEPTION();
555 : }
556 : }
557 :
558 :
559 0 : void FormControlFactory::initializeFieldDependentProperties( const Reference< XPropertySet >& _rxDatabaseField,
560 : const Reference< XPropertySet >& _rxControlModel, const Reference< XNumberFormats >& _rxNumberFormats )
561 : {
562 : OSL_PRECOND( _rxDatabaseField.is() && _rxControlModel.is(),
563 : "FormControlFactory::initializeFieldDependentProperties: illegal params!" );
564 0 : if ( !_rxDatabaseField.is() || !_rxControlModel.is() )
565 0 : return;
566 :
567 : try
568 : {
569 :
570 : // if the field has a numeric format, and the model has a "Scale" property, sync it
571 0 : Reference< XPropertySetInfo > xFieldPSI( _rxDatabaseField->getPropertySetInfo(), UNO_SET_THROW );
572 0 : Reference< XPropertySetInfo > xModelPSI( _rxControlModel->getPropertySetInfo(), UNO_SET_THROW );
573 :
574 0 : if ( xModelPSI->hasPropertyByName( FM_PROP_DECIMAL_ACCURACY ) )
575 : {
576 0 : sal_Int32 nFormatKey = 0;
577 0 : if ( xFieldPSI->hasPropertyByName( FM_PROP_FORMATKEY ) )
578 : {
579 0 : _rxDatabaseField->getPropertyValue( FM_PROP_FORMATKEY ) >>= nFormatKey;
580 : }
581 : else
582 : {
583 : nFormatKey = OStaticDataAccessTools().getDefaultNumberFormat(
584 : _rxDatabaseField,
585 : Reference< XNumberFormatTypes >( _rxNumberFormats, UNO_QUERY ),
586 0 : SvtSysLocale().GetLanguageTag().getLocale()
587 0 : );
588 : }
589 :
590 0 : Any aScaleVal( ::comphelper::getNumberFormatDecimals( _rxNumberFormats, nFormatKey ) );
591 0 : _rxControlModel->setPropertyValue( FM_PROP_DECIMAL_ACCURACY, aScaleVal );
592 : }
593 :
594 :
595 : // minimum and maximum of the control according to the type of the database field
596 0 : sal_Int32 nDataType = DataType::OTHER;
597 0 : OSL_VERIFY( _rxDatabaseField->getPropertyValue( FM_PROP_FIELDTYPE ) >>= nDataType );
598 :
599 0 : if ( xModelPSI->hasPropertyByName( FM_PROP_VALUEMIN )
600 0 : && xModelPSI->hasPropertyByName( FM_PROP_VALUEMAX )
601 : )
602 : {
603 0 : sal_Int32 nMinValue = -1000000000, nMaxValue = 1000000000;
604 0 : switch ( nDataType )
605 : {
606 0 : case DataType::TINYINT : nMinValue = 0; nMaxValue = 255; break;
607 0 : case DataType::SMALLINT : nMinValue = -32768; nMaxValue = 32767; break;
608 0 : case DataType::INTEGER : nMinValue = 0x80000000; nMaxValue = 0x7FFFFFFF; break;
609 : // double and singles are ignored
610 : }
611 :
612 0 : Any aValue;
613 :
614 : // both the minimum and the maximum value properties can be either Long or Double
615 0 : Property aProperty = xModelPSI->getPropertyByName( FM_PROP_VALUEMIN );
616 0 : if ( aProperty.Type.getTypeClass() == TypeClass_DOUBLE )
617 0 : aValue <<= (double)nMinValue;
618 0 : else if ( aProperty.Type.getTypeClass() == TypeClass_LONG )
619 0 : aValue <<= (sal_Int32)nMinValue;
620 : else
621 : {
622 : OSL_FAIL( "FormControlFactory::initializeFieldDependentProperties: unexpected property type (MinValue)!" );
623 : }
624 0 : _rxControlModel->setPropertyValue( FM_PROP_VALUEMIN, aValue );
625 :
626 : // both the minimum and the maximum value properties can be either Long or Double
627 0 : aProperty = xModelPSI->getPropertyByName( FM_PROP_VALUEMAX );
628 0 : if ( aProperty.Type.getTypeClass() == TypeClass_DOUBLE )
629 0 : aValue <<= (double)nMaxValue;
630 0 : else if ( aProperty.Type.getTypeClass() == TypeClass_LONG )
631 0 : aValue <<= (sal_Int32)nMaxValue;
632 : else
633 : {
634 : OSL_FAIL( "FormControlFactory::initializeFieldDependentProperties: unexpected property type (MaxValue)!" );
635 : }
636 0 : _rxControlModel->setPropertyValue( FM_PROP_VALUEMAX, aValue );
637 : }
638 :
639 :
640 : // a check box can be tristate if and only if the column it is bound to is nullable
641 0 : sal_Int16 nClassId = FormComponentType::CONTROL;
642 0 : OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
643 0 : if ( nClassId == FormComponentType::CHECKBOX )
644 : {
645 0 : sal_Int32 nNullable = ColumnValue::NULLABLE_UNKNOWN;
646 0 : OSL_VERIFY( _rxDatabaseField->getPropertyValue( FM_PROP_ISNULLABLE ) >>= nNullable );
647 0 : _rxControlModel->setPropertyValue( FM_PROP_TRISTATE, makeAny( sal_Bool( ColumnValue::NO_NULLS != nNullable ) ) );
648 0 : }
649 : }
650 0 : catch( const Exception& )
651 : {
652 : DBG_UNHANDLED_EXCEPTION();
653 : }
654 : }
655 :
656 :
657 0 : OUString FormControlFactory::getDefaultName( sal_Int16 _nClassId, const Reference< XServiceInfo >& _rxObject )
658 : {
659 0 : sal_uInt16 nResId(0);
660 :
661 0 : switch ( _nClassId )
662 : {
663 0 : case FormComponentType::COMMANDBUTTON: nResId = RID_STR_PROPTITLE_PUSHBUTTON; break;
664 0 : case FormComponentType::RADIOBUTTON: nResId = RID_STR_PROPTITLE_RADIOBUTTON; break;
665 0 : case FormComponentType::CHECKBOX: nResId = RID_STR_PROPTITLE_CHECKBOX; break;
666 0 : case FormComponentType::LISTBOX: nResId = RID_STR_PROPTITLE_LISTBOX; break;
667 0 : case FormComponentType::COMBOBOX: nResId = RID_STR_PROPTITLE_COMBOBOX; break;
668 0 : case FormComponentType::GROUPBOX: nResId = RID_STR_PROPTITLE_GROUPBOX; break;
669 0 : case FormComponentType::IMAGEBUTTON: nResId = RID_STR_PROPTITLE_IMAGEBUTTON; break;
670 0 : case FormComponentType::FIXEDTEXT: nResId = RID_STR_PROPTITLE_FIXEDTEXT; break;
671 0 : case FormComponentType::GRIDCONTROL: nResId = RID_STR_PROPTITLE_DBGRID; break;
672 0 : case FormComponentType::FILECONTROL: nResId = RID_STR_PROPTITLE_FILECONTROL; break;
673 0 : case FormComponentType::DATEFIELD: nResId = RID_STR_PROPTITLE_DATEFIELD; break;
674 0 : case FormComponentType::TIMEFIELD: nResId = RID_STR_PROPTITLE_TIMEFIELD; break;
675 0 : case FormComponentType::NUMERICFIELD: nResId = RID_STR_PROPTITLE_NUMERICFIELD; break;
676 0 : case FormComponentType::CURRENCYFIELD: nResId = RID_STR_PROPTITLE_CURRENCYFIELD; break;
677 0 : case FormComponentType::PATTERNFIELD: nResId = RID_STR_PROPTITLE_PATTERNFIELD; break;
678 0 : case FormComponentType::IMAGECONTROL: nResId = RID_STR_PROPTITLE_IMAGECONTROL; break;
679 0 : case FormComponentType::HIDDENCONTROL: nResId = RID_STR_PROPTITLE_HIDDEN; break;
680 0 : case FormComponentType::SCROLLBAR: nResId = RID_STR_PROPTITLE_SCROLLBAR; break;
681 0 : case FormComponentType::SPINBUTTON: nResId = RID_STR_PROPTITLE_SPINBUTTON; break;
682 0 : case FormComponentType::NAVIGATIONBAR: nResId = RID_STR_PROPTITLE_NAVBAR; break;
683 :
684 : case FormComponentType::TEXTFIELD:
685 0 : nResId = RID_STR_PROPTITLE_EDIT;
686 0 : if ( _rxObject.is() && _rxObject->supportsService( FM_SUN_COMPONENT_FORMATTEDFIELD ) )
687 0 : nResId = RID_STR_PROPTITLE_FORMATTED;
688 0 : break;
689 :
690 : default:
691 0 : nResId = RID_STR_CONTROL; break;
692 : }
693 :
694 0 : return SVX_RESSTR(nResId);
695 : }
696 :
697 :
698 0 : OUString FormControlFactory::getDefaultUniqueName_ByComponentType( const Reference< XNameAccess >& _rxContainer,
699 : const Reference< XPropertySet >& _rxObject )
700 : {
701 0 : sal_Int16 nClassId = FormComponentType::CONTROL;
702 0 : OSL_VERIFY( _rxObject->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
703 0 : OUString sBaseName = getDefaultName( nClassId, Reference< XServiceInfo >( _rxObject, UNO_QUERY ) );
704 :
705 0 : return getUniqueName( _rxContainer, sBaseName );
706 : }
707 :
708 :
709 0 : OUString FormControlFactory::getUniqueName( const Reference< XNameAccess >& _rxContainer, const OUString& _rBaseName )
710 : {
711 0 : sal_Int32 n = 0;
712 0 : OUString sName;
713 0 : do
714 : {
715 0 : OUStringBuffer aBuf( _rBaseName );
716 0 : aBuf.appendAscii( " " );
717 0 : aBuf.append( ++n );
718 0 : sName = aBuf.makeStringAndClear();
719 : }
720 0 : while ( _rxContainer->hasByName( sName ) );
721 :
722 0 : return sName;
723 : }
724 :
725 :
726 : } // namespace svxform
727 :
728 :
729 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|