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