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