bump product version to 4.1.6.2
[LibreOffice.git] / extensions / source / propctrlr / formcomponenthandler.cxx
blobd0bf73ecdadceb382a532c17720e948ab7448940
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "controltype.hxx"
22 #include "propctrlr.hrc"
23 #include "extensio.hrc"
24 #include "fontdialog.hxx"
25 #include "formcomponenthandler.hxx"
26 #include "formlinkdialog.hxx"
27 #include "formmetadata.hxx"
28 #include "formresid.hrc"
29 #include "formstrings.hxx"
30 #include "handlerhelper.hxx"
31 #include "listselectiondlg.hxx"
32 #include "pcrcommon.hxx"
33 #include "selectlabeldialog.hxx"
34 #include "taborder.hxx"
35 #include "usercontrol.hxx"
37 #include <com/sun/star/lang/NullPointerException.hpp>
38 #include <com/sun/star/awt/XControlModel.hpp>
39 #include <com/sun/star/lang/XServiceInfo.hpp>
40 #include <com/sun/star/form/FormComponentType.hpp>
41 #include <com/sun/star/beans/PropertyAttribute.hpp>
42 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
43 #include <com/sun/star/container/XNameAccess.hpp>
44 #include <com/sun/star/form/XForm.hpp>
45 #include <com/sun/star/container/XChild.hpp>
46 #include <com/sun/star/sdb/OrderDialog.hpp>
47 #include <com/sun/star/sdb/FilterDialog.hpp>
48 #include <com/sun/star/sdbc/XConnection.hpp>
49 #include <com/sun/star/sdb/CommandType.hpp>
50 #include <com/sun/star/sdb/DatabaseContext.hpp>
51 #include <com/sun/star/form/XGridColumnFactory.hpp>
52 #include <com/sun/star/sdb/SQLContext.hpp>
53 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
54 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
55 #include <com/sun/star/form/ListSourceType.hpp>
56 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
57 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
58 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
59 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
60 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
61 #include <com/sun/star/awt/XTabControllerModel.hpp>
62 #include <com/sun/star/form/FormSubmitEncoding.hpp>
63 #include <com/sun/star/awt/VisualEffect.hpp>
64 #include <com/sun/star/form/FormButtonType.hpp>
65 #include <com/sun/star/inspection/PropertyControlType.hpp>
66 #include <com/sun/star/util/MeasureUnit.hpp>
67 #include <com/sun/star/inspection/XObjectInspectorUI.hpp>
68 #include <com/sun/star/inspection/PropertyLineElement.hpp>
69 #include <com/sun/star/resource/XStringResourceManager.hpp>
70 #include <com/sun/star/resource/MissingResourceException.hpp>
71 #include <com/sun/star/graphic/GraphicObject.hpp>
72 #include <com/sun/star/text/WritingMode2.hpp>
74 #include <comphelper/extract.hxx>
75 #include <connectivity/dbconversion.hxx>
76 #include <connectivity/dbexception.hxx>
77 #include <cppuhelper/exc_hlp.hxx>
78 #include <sfx2/app.hxx>
79 #include <sfx2/basedlgs.hxx>
80 #include <sfx2/docfilt.hxx>
81 #include <sfx2/filedlghelper.hxx>
82 #include <svl/ctloptions.hxx>
83 #include <svtools/colrdlg.hxx>
84 #include <svl/filenotation.hxx>
85 #include <svl/intitem.hxx>
86 #include <svl/itemset.hxx>
87 #include <unotools/moduleoptions.hxx>
88 #include <svl/numuno.hxx>
89 #include <svl/urihelper.hxx>
90 #include <svx/dialogs.hrc>
91 #include <svx/numinf.hxx>
92 #include <svx/svxdlg.hxx>
93 #include <svx/svxids.hrc>
94 #include <toolkit/helper/vclunohelper.hxx>
95 #include <tools/diagnose_ex.h>
96 #include <vcl/msgbox.hxx>
97 #include <vcl/stdtext.hxx>
98 #include <vcl/wrkwin.hxx>
99 #include <tools/StringListResource.hxx>
100 #include <sal/macros.h>
102 #include <limits>
104 #define GRAPHOBJ_URLPREFIX "vnd.sun.star.GraphicObject:"
105 //------------------------------------------------------------------------
106 extern "C" void SAL_CALL createRegistryInfo_FormComponentPropertyHandler()
108 ::pcr::FormComponentPropertyHandler::registerImplementation();
111 //........................................................................
112 namespace pcr
114 //........................................................................
116 using namespace ::com::sun::star;
117 using namespace uno;
118 using namespace lang;
119 using namespace beans;
120 using namespace frame;
121 using namespace script;
122 using namespace form;
123 using namespace util;
124 using namespace awt;
125 using namespace sdb;
126 using namespace sdbc;
127 using namespace sdbcx;
128 using namespace container;
129 using namespace ui::dialogs;
130 using namespace inspection;
131 using namespace ::dbtools;
133 namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
135 //====================================================================
136 //= FormComponentPropertyHandler
137 //====================================================================
138 DBG_NAME( FormComponentPropertyHandler )
139 #define PROPERTY_ID_ROWSET 1
140 //--------------------------------------------------------------------
141 FormComponentPropertyHandler::FormComponentPropertyHandler( const Reference< XComponentContext >& _rxContext )
142 :FormComponentPropertyHandler_Base( _rxContext )
143 ,::comphelper::OPropertyContainer(FormComponentPropertyHandler_Base::rBHelper)
144 ,m_sDefaultValueString( String( PcrRes( RID_STR_STANDARD ) ) )
145 ,m_eComponentClass( eUnknown )
146 ,m_bComponentIsSubForm( false )
147 ,m_bHaveListSource( false )
148 ,m_bHaveCommand( false )
149 ,m_nClassId( 0 )
151 DBG_CTOR( FormComponentPropertyHandler, NULL );
152 registerProperty(PROPERTY_ROWSET,PROPERTY_ID_ROWSET,0,&m_xRowSet,::getCppuType(&m_xRowSet));
155 //--------------------------------------------------------------------
156 FormComponentPropertyHandler::~FormComponentPropertyHandler()
158 DBG_DTOR( FormComponentPropertyHandler, NULL );
160 //--------------------------------------------------------------------
161 IMPLEMENT_FORWARD_XINTERFACE2(FormComponentPropertyHandler,FormComponentPropertyHandler_Base,::comphelper::OPropertyContainer)
162 //--------------------------------------------------------------------
163 OUString SAL_CALL FormComponentPropertyHandler::getImplementationName_static( ) throw (RuntimeException)
165 return OUString( "com.sun.star.comp.extensions.FormComponentPropertyHandler" );
168 //--------------------------------------------------------------------
169 Sequence< OUString > SAL_CALL FormComponentPropertyHandler::getSupportedServiceNames_static( ) throw (RuntimeException)
171 Sequence< OUString > aSupported( 1 );
172 aSupported[0] = OUString( "com.sun.star.form.inspection.FormComponentPropertyHandler" );
173 return aSupported;
176 //============================================
177 // TODO: -> export from toolkit
178 struct LanguageDependentProp
180 const char* pPropName;
181 sal_Int32 nPropNameLength;
184 static LanguageDependentProp aLanguageDependentProp[] =
186 { "Text", 4 },
187 { "Label", 5 },
188 { "Title", 5 },
189 { "HelpText", 8 },
190 { "CurrencySymbol", 14 },
191 { "StringItemList", 14 },
192 { 0, 0 }
195 namespace
197 bool lcl_isLanguageDependentProperty( OUString aName )
199 bool bRet = false;
201 LanguageDependentProp* pLangDepProp = aLanguageDependentProp;
202 while( pLangDepProp->pPropName != 0 )
204 if( aName.equalsAsciiL( pLangDepProp->pPropName, pLangDepProp->nPropNameLength ))
206 bRet = true;
207 break;
209 pLangDepProp++;
211 return bRet;
214 Reference< resource::XStringResourceResolver > lcl_getStringResourceResolverForProperty
215 ( Reference< XPropertySet > _xComponent, const OUString& _rPropertyName,
216 const Any& _rPropertyValue )
218 Reference< resource::XStringResourceResolver > xRet;
219 const TypeClass eType = _rPropertyValue.getValueType().getTypeClass();
220 if ( (eType == TypeClass_STRING || eType == TypeClass_SEQUENCE) &&
221 lcl_isLanguageDependentProperty( _rPropertyName ) )
223 static const OUString s_sResourceResolverPropName("ResourceResolver");
225 Reference< resource::XStringResourceResolver > xStringResourceResolver;
228 xStringResourceResolver.set( _xComponent->getPropertyValue( s_sResourceResolverPropName ),UNO_QUERY);
229 if( xStringResourceResolver.is() &&
230 xStringResourceResolver->getLocales().getLength() > 0 )
232 xRet = xStringResourceResolver;
235 catch(const UnknownPropertyException&)
237 // nii
241 return xRet;
245 //--------------------------------------------------------------------
246 Any FormComponentPropertyHandler::impl_getPropertyValue_throw( const OUString& _rPropertyName ) const
248 const PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
250 Any aPropertyValue( m_xComponent->getPropertyValue( _rPropertyName ) );
252 Reference< resource::XStringResourceResolver > xStringResourceResolver
253 = lcl_getStringResourceResolverForProperty( m_xComponent, _rPropertyName, aPropertyValue );
254 if( xStringResourceResolver.is() )
256 TypeClass eType = aPropertyValue.getValueType().getTypeClass();
257 if( eType == TypeClass_STRING )
259 OUString aPropStr;
260 aPropertyValue >>= aPropStr;
261 if( aPropStr.getLength() > 1 )
263 OUString aPureIdStr = aPropStr.copy( 1 );
264 if( xStringResourceResolver->hasEntryForId( aPureIdStr ) )
266 OUString aResourceStr = xStringResourceResolver->resolveString( aPureIdStr );
267 aPropertyValue <<= aResourceStr;
271 // StringItemList?
272 else if( eType == TypeClass_SEQUENCE )
274 Sequence< OUString > aStrings;
275 aPropertyValue >>= aStrings;
277 const OUString* pStrings = aStrings.getConstArray();
278 sal_Int32 nCount = aStrings.getLength();
280 Sequence< OUString > aResolvedStrings;
281 aResolvedStrings.realloc( nCount );
282 OUString* pResolvedStrings = aResolvedStrings.getArray();
285 for ( sal_Int32 i = 0; i < nCount; ++i )
287 OUString aIdStr = pStrings[i];
288 OUString aPureIdStr = aIdStr.copy( 1 );
289 if( xStringResourceResolver->hasEntryForId( aPureIdStr ) )
290 pResolvedStrings[i] = xStringResourceResolver->resolveString( aPureIdStr );
291 else
292 pResolvedStrings[i] = aIdStr;
295 catch( const resource::MissingResourceException & )
297 aPropertyValue <<= aResolvedStrings;
300 else
301 impl_normalizePropertyValue_nothrow( aPropertyValue, nPropId );
303 return aPropertyValue;
306 //--------------------------------------------------------------------
307 Any SAL_CALL FormComponentPropertyHandler::getPropertyValue( const OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
309 if( _rPropertyName == PROPERTY_ROWSET )
310 return ::comphelper::OPropertyContainer::getPropertyValue( _rPropertyName );
312 ::osl::MutexGuard aGuard( m_aMutex );
313 return impl_getPropertyValue_throw( _rPropertyName );
316 //--------------------------------------------------------------------
317 void SAL_CALL FormComponentPropertyHandler::setPropertyValue( const OUString& _rPropertyName, const Any& _rValue ) throw (UnknownPropertyException, RuntimeException)
319 if( _rPropertyName == PROPERTY_ROWSET )
321 ::comphelper::OPropertyContainer::setPropertyValue( _rPropertyName, _rValue );
322 return;
325 ::osl::MutexGuard aGuard( m_aMutex );
326 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) ); // check if property is known by the handler
328 Reference< graphic::XGraphicObject > xGrfObj;
329 if ( PROPERTY_ID_IMAGE_URL == nPropId && ( _rValue >>= xGrfObj ) )
331 DBG_ASSERT( xGrfObj.is(), "FormComponentPropertyHandler::setPropertyValue() xGrfObj is invalid");
332 OUString sObjectID( GRAPHOBJ_URLPREFIX );
333 sObjectID = sObjectID + xGrfObj->getUniqueID();
334 m_xComponent->setPropertyValue( _rPropertyName, uno::makeAny( sObjectID ) );
336 else if ( PROPERTY_ID_FONT == nPropId )
338 // special handling, the value is a faked value we generated ourself in impl_executeFontDialog_nothrow
339 Sequence< NamedValue > aFontPropertyValues;
340 OSL_VERIFY( _rValue >>= aFontPropertyValues );
341 const NamedValue* fontPropertyValue = aFontPropertyValues.getConstArray();
342 const NamedValue* fontPropertyValueEnd = fontPropertyValue + aFontPropertyValues.getLength();
343 for ( ; fontPropertyValue != fontPropertyValueEnd; ++fontPropertyValue )
344 m_xComponent->setPropertyValue( fontPropertyValue->Name, fontPropertyValue->Value );
346 else
348 Any aValue = _rValue;
350 Reference< resource::XStringResourceResolver > xStringResourceResolver
351 = lcl_getStringResourceResolverForProperty( m_xComponent, _rPropertyName, _rValue );
352 if( xStringResourceResolver.is() )
354 Reference< resource::XStringResourceManager >
355 xStringResourceManager( xStringResourceResolver, UNO_QUERY );
356 if( xStringResourceManager.is() )
358 Any aPropertyValue( m_xComponent->getPropertyValue( _rPropertyName ) );
359 TypeClass eType = aPropertyValue.getValueType().getTypeClass();
360 if( eType == TypeClass_STRING )
362 OUString aPropStr;
363 aPropertyValue >>= aPropStr;
364 if( aPropStr.getLength() > 1 )
366 OUString aPureIdStr = aPropStr.copy( 1 );
367 OUString aValueStr;
368 _rValue >>= aValueStr;
369 xStringResourceManager->setString( aPureIdStr, aValueStr );
370 aValue = aPropertyValue; // set value to force modified
373 // StringItemList?
374 else if( eType == TypeClass_SEQUENCE )
376 static OUString aDot(".");
377 static OUString aEsc("&");
379 // Put strings into resource using new ids
380 Sequence< OUString > aNewStrings;
381 _rValue >>= aNewStrings;
383 const OUString* pNewStrings = aNewStrings.getConstArray();
384 sal_Int32 nNewCount = aNewStrings.getLength();
386 // Create new Ids
387 OUString* pNewPureIds = new OUString[nNewCount];
388 OUString aIdStrBase = aDot;
389 Any aNameAny = m_xComponent->getPropertyValue(PROPERTY_NAME);
390 OUString sControlName;
391 aNameAny >>= sControlName;
392 aIdStrBase += sControlName;
393 aIdStrBase += aDot;
394 aIdStrBase += _rPropertyName;
395 sal_Int32 i;
396 OUString aDummyStr;
397 for ( i = 0; i < nNewCount; ++i )
399 sal_Int32 nUniqueId = xStringResourceManager->getUniqueNumericId();
400 OUString aPureIdStr = OUString::valueOf( nUniqueId );
401 aPureIdStr += aIdStrBase;
402 pNewPureIds[i] = aPureIdStr;
403 // Force usage of next Unique Id
404 xStringResourceManager->setString( aPureIdStr, aDummyStr );
407 // Move strings to new Ids for all locales
408 Sequence< Locale > aLocaleSeq = xStringResourceManager->getLocales();
409 const Locale* pLocale = aLocaleSeq.getConstArray();
410 sal_Int32 nLocaleCount = aLocaleSeq.getLength();
411 Sequence< OUString > aOldIdStrings;
412 aPropertyValue >>= aOldIdStrings;
415 const OUString* pOldIdStrings = aOldIdStrings.getConstArray();
416 sal_Int32 nOldIdCount = aOldIdStrings.getLength();
417 for ( i = 0; i < nNewCount; ++i )
419 OUString aOldIdStr;
420 OUString aOldPureIdStr;
421 if( i < nOldIdCount )
423 aOldIdStr = pOldIdStrings[i];
424 aOldPureIdStr = aOldIdStr.copy( 1 );
426 OUString aNewPureIdStr = pNewPureIds[i];
428 for ( sal_Int32 iLocale = 0; iLocale < nLocaleCount; ++iLocale )
430 Locale aLocale = pLocale[iLocale];
432 OUString aResourceStr;
433 if( !aOldPureIdStr.isEmpty() )
435 if( xStringResourceManager->hasEntryForIdAndLocale( aOldPureIdStr, aLocale ) )
437 aResourceStr = xStringResourceManager->
438 resolveStringForLocale( aOldPureIdStr, aLocale );
441 xStringResourceManager->setStringForLocale( aNewPureIdStr, aResourceStr, aLocale );
445 catch( const resource::MissingResourceException & )
449 // Set new strings for current locale and create
450 // new Id sequence as new property value
451 Sequence< OUString > aNewIdStrings;
452 aNewIdStrings.realloc( nNewCount );
453 OUString* pNewIdStrings = aNewIdStrings.getArray();
454 for ( i = 0; i < nNewCount; ++i )
456 OUString aPureIdStr = pNewPureIds[i];
457 OUString aStr = pNewStrings[i];
458 xStringResourceManager->setString( aPureIdStr, aStr );
460 OUString aIdStr = aEsc;
461 aIdStr += aPureIdStr;
462 pNewIdStrings[i] = aIdStr;
464 aValue <<= aNewIdStrings;
466 // Remove old ids from resource for all locales
467 const OUString* pOldIdStrings = aOldIdStrings.getConstArray();
468 sal_Int32 nOldIdCount = aOldIdStrings.getLength();
469 for( i = 0 ; i < nOldIdCount ; ++i )
471 OUString aIdStr = pOldIdStrings[i];
472 OUString aPureIdStr = aIdStr.copy( 1 );
473 for ( sal_Int32 iLocale = 0; iLocale < nLocaleCount; ++iLocale )
475 Locale aLocale = pLocale[iLocale];
478 xStringResourceManager->removeIdForLocale( aPureIdStr, aLocale );
480 catch( const resource::MissingResourceException & )
484 delete[] pNewPureIds;
489 m_xComponent->setPropertyValue( _rPropertyName, aValue );
493 //--------------------------------------------------------------------
494 Any SAL_CALL FormComponentPropertyHandler::convertToPropertyValue( const OUString& _rPropertyName, const Any& _rControlValue ) throw (UnknownPropertyException, RuntimeException)
496 ::osl::MutexGuard aGuard( m_aMutex );
497 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
498 Property aProperty( impl_getPropertyFromId_throw( nPropId ) );
500 Any aPropertyValue( _rControlValue );
501 if ( !aPropertyValue.hasValue() )
503 if ( ( aProperty.Attributes & PropertyAttribute::MAYBEVOID ) == 0 )
504 // default construct an instance of the proper type
505 aPropertyValue = Any( NULL, aProperty.Type );
506 // nothing to do
507 return aPropertyValue;
510 /// care for the special "default" string, translate it to VOID
511 if ( m_aPropertiesWithDefListEntry.find( _rPropertyName ) != m_aPropertiesWithDefListEntry.end() )
513 // it's a control with a string list
514 OUString sStringValue;
515 if ( _rControlValue >>= sStringValue )
516 { // note that ColorListBoxes might transfer values either as string or as css.util.Color,
517 // so this check here is important
518 if ( sStringValue == m_sDefaultValueString )
519 return Any();
523 switch ( nPropId )
525 case PROPERTY_ID_DATASOURCE:
527 OUString sControlValue;
528 OSL_VERIFY( _rControlValue >>= sControlValue );
530 if ( !sControlValue.isEmpty() )
532 Reference< XDatabaseContext > xDatabaseContext = sdb::DatabaseContext::create( m_aContext.getUNOContext() );
533 if ( !xDatabaseContext->hasByName( sControlValue ) )
535 ::svt::OFileNotation aTransformer(sControlValue);
536 aPropertyValue <<= OUString( aTransformer.get( ::svt::OFileNotation::N_URL ) );
540 break; // case PROPERTY_ID_DATASOURCE
542 case PROPERTY_ID_SHOW_POSITION:
543 case PROPERTY_ID_SHOW_NAVIGATION:
544 case PROPERTY_ID_SHOW_RECORDACTIONS:
545 case PROPERTY_ID_SHOW_FILTERSORT:
547 OUString sControlValue;
548 OSL_VERIFY( _rControlValue >>= sControlValue );
550 ::std::vector< OUString > aListEntries;
551 tools::StringListResource aRes( PcrRes( RID_RSC_ENUM_SHOWHIDE ), aListEntries );
552 OSL_ENSURE( aListEntries.size() == 2, "FormComponentPropertyHandler::convertToPropertyValue: broken resource for Show/Hide!" );
553 sal_Bool bShow = ( aListEntries.size() < 2 ) || ( sControlValue == aListEntries[1] );
555 aPropertyValue <<= bShow;
557 break;
559 case PROPERTY_ID_TARGET_URL:
560 case PROPERTY_ID_IMAGE_URL:
562 OUString sControlValue;
563 OSL_VERIFY( _rControlValue >>= sControlValue );
564 // Don't convert a placeholder
565 if ( nPropId == PROPERTY_ID_IMAGE_URL && sControlValue.equals( String( PcrRes( RID_EMBED_IMAGE_PLACEHOLDER ) ) ) )
566 aPropertyValue <<= sControlValue;
567 else
569 INetURLObject aDocURL( impl_getDocumentURL_nothrow() );
570 aPropertyValue <<= (OUString)URIHelper::SmartRel2Abs( aDocURL, sControlValue, Link(), false, true, INetURLObject::WAS_ENCODED, INetURLObject::DECODE_TO_IURI );
573 break;
575 case PROPERTY_ID_DATEMIN:
576 case PROPERTY_ID_DATEMAX:
577 case PROPERTY_ID_DEFAULT_DATE:
578 case PROPERTY_ID_DATE:
580 util::Date aDate;
581 OSL_VERIFY( _rControlValue >>= aDate );
582 aPropertyValue <<= aDate;
584 break;
586 case PROPERTY_ID_TIMEMIN:
587 case PROPERTY_ID_TIMEMAX:
588 case PROPERTY_ID_DEFAULT_TIME:
589 case PROPERTY_ID_TIME:
591 util::Time aTime;
592 OSL_VERIFY( _rControlValue >>= aTime );
593 aPropertyValue <<= aTime;
595 break;
597 case PROPERTY_ID_WRITING_MODE:
599 aPropertyValue = FormComponentPropertyHandler_Base::convertToPropertyValue( _rPropertyName, _rControlValue );
601 sal_Int16 nNormalizedValue( 2 );
602 OSL_VERIFY( aPropertyValue >>= nNormalizedValue );
603 sal_Int16 nWritingMode = WritingMode2::CONTEXT;
604 switch ( nNormalizedValue )
606 case 0: nWritingMode = WritingMode2::LR_TB; break;
607 case 1: nWritingMode = WritingMode2::RL_TB; break;
608 case 2: nWritingMode = WritingMode2::CONTEXT; break;
609 default:
610 OSL_FAIL( "FormComponentPropertyHandler::convertToPropertyValue: unexpected 'normalized value' for WritingMode!" );
611 nWritingMode = WritingMode2::CONTEXT;
612 break;
615 aPropertyValue <<= nWritingMode;
617 break;
619 default:
620 aPropertyValue = FormComponentPropertyHandler_Base::convertToPropertyValue( _rPropertyName, _rControlValue );
621 break; // default
623 } // switch ( nPropId )
625 return aPropertyValue;
628 //--------------------------------------------------------------------
629 Any SAL_CALL FormComponentPropertyHandler::convertToControlValue( const OUString& _rPropertyName, const Any& _rPropertyValue, const Type& _rControlValueType ) throw (UnknownPropertyException, RuntimeException)
631 ::osl::MutexGuard aGuard( m_aMutex );
632 sal_Int32 nPropId = m_pInfoService->getPropertyId( _rPropertyName );
633 DBG_ASSERT( nPropId != -1, "FormComponentPropertyHandler::convertToPropertyValue: not one of my properties!!" );
635 Property aProperty( impl_getPropertyFromId_throw( nPropId ) );
637 Any aControlValue( _rPropertyValue );
638 if ( !aControlValue.hasValue() )
640 // if the property is represented with a list box or color list box, we need to
641 // translate this into the string "Default"
642 if ( m_aPropertiesWithDefListEntry.find( _rPropertyName ) != m_aPropertiesWithDefListEntry.end() )
643 aControlValue <<= m_sDefaultValueString;
645 return aControlValue;
648 switch ( nPropId )
650 //////////////////////////////////////////////////////////////
651 case PROPERTY_ID_SHOW_POSITION:
652 case PROPERTY_ID_SHOW_NAVIGATION:
653 case PROPERTY_ID_SHOW_RECORDACTIONS:
654 case PROPERTY_ID_SHOW_FILTERSORT:
656 ::std::vector< OUString > aListEntries;
657 tools::StringListResource aRes( PcrRes( RID_RSC_ENUM_SHOWHIDE ), aListEntries );
658 OSL_ENSURE( aListEntries.size() == 2, "FormComponentPropertyHandler::convertToControlValue: broken resource for Show/Hide!" );
660 if ( aListEntries.size() == 2 )
662 OUString sControlValue = ::comphelper::getBOOL( _rPropertyValue )
663 ? aListEntries[1]
664 : aListEntries[0];
665 aControlValue <<= sControlValue;
668 break;
670 //////////////////////////////////////////////////////////////
671 case PROPERTY_ID_DATASOURCE:
673 OSL_ENSURE( _rControlValueType.getTypeClass() == TypeClass_STRING,
674 "FormComponentPropertyHandler::convertToControlValue: wrong ControlValueType!" );
676 OUString sDataSource;
677 _rPropertyValue >>= sDataSource;
678 if ( !sDataSource.isEmpty() )
680 ::svt::OFileNotation aTransformer( sDataSource );
681 sDataSource = aTransformer.get( ::svt::OFileNotation::N_SYSTEM );
683 aControlValue <<= sDataSource;
685 break;
687 //////////////////////////////////////////////////////////////
688 case PROPERTY_ID_CONTROLLABEL:
690 OUString sControlValue;
692 Reference< XPropertySet > xSet;
693 _rPropertyValue >>= xSet;
694 Reference< XPropertySetInfo > xPSI;
695 if ( xSet.is() )
696 xPSI = xSet->getPropertySetInfo();
697 if ( xPSI.is() && xPSI->hasPropertyByName( PROPERTY_LABEL ) )
699 OUStringBuffer aValue;
700 aValue.append( (sal_Unicode)'<' );
701 OUString sLabel;
702 OSL_VERIFY( xSet->getPropertyValue( PROPERTY_LABEL ) >>= sLabel );
703 aValue.append( sLabel );
704 aValue.append( (sal_Unicode)'>' );
705 sControlValue = aValue.makeStringAndClear();
708 aControlValue <<= sControlValue;
710 break;
712 //////////////////////////////////////////////////////////////
713 case PROPERTY_ID_DATEMIN:
714 case PROPERTY_ID_DATEMAX:
715 case PROPERTY_ID_DEFAULT_DATE:
716 case PROPERTY_ID_DATE:
718 sal_Int32 nDate = 0;
719 OSL_VERIFY( _rPropertyValue >>= nDate );
720 aControlValue <<= DBTypeConversion::toDate( nDate );
722 break;
724 case PROPERTY_ID_TIMEMIN:
725 case PROPERTY_ID_TIMEMAX:
726 case PROPERTY_ID_DEFAULT_TIME:
727 case PROPERTY_ID_TIME:
729 sal_Int64 nTime = 0;
730 OSL_VERIFY( _rPropertyValue >>= nTime );
731 aControlValue <<= DBTypeConversion::toTime( nTime );
733 break;
735 case PROPERTY_ID_WRITING_MODE:
737 sal_Int16 nWritingMode( WritingMode2::CONTEXT );
738 OSL_VERIFY( _rPropertyValue >>= nWritingMode );
739 sal_Int16 nNormalized = 2;
740 switch ( nWritingMode )
742 case WritingMode2::LR_TB: nNormalized = 0; break;
743 case WritingMode2::RL_TB: nNormalized = 1; break;
744 case WritingMode2::CONTEXT: nNormalized = 2; break;
745 default:
746 OSL_FAIL( "FormComponentPropertyHandler::convertToControlValue: unsupported API value for WritingMode!" );
747 nNormalized = 2;
748 break;
751 aControlValue = FormComponentPropertyHandler_Base::convertToControlValue( _rPropertyName, makeAny( nNormalized ), _rControlValueType );
753 break;
755 case PROPERTY_ID_FONT:
757 FontDescriptor aFont;
758 OSL_VERIFY( _rPropertyValue >>= aFont );
760 OUStringBuffer displayName;
761 if ( aFont.Name.isEmpty() )
763 displayName.append( String( PcrRes( RID_STR_FONT_DEFAULT ) ) );
765 else
767 // font name
768 displayName.append( aFont.Name );
769 displayName.appendAscii( ", " );
771 // font style
772 ::FontWeight eWeight = VCLUnoHelper::ConvertFontWeight( aFont.Weight );
773 sal_uInt16 nStyleResID = RID_STR_FONTSTYLE_REGULAR;
774 if ( aFont.Slant == FontSlant_ITALIC )
776 if ( eWeight > WEIGHT_NORMAL )
777 nStyleResID = RID_STR_FONTSTYLE_BOLD_ITALIC;
778 else
779 nStyleResID = RID_STR_FONTSTYLE_ITALIC;
781 else
783 if ( eWeight > WEIGHT_NORMAL )
784 nStyleResID = RID_STR_FONTSTYLE_BOLD;
786 displayName.append( String( PcrRes( nStyleResID ) ) );
788 // font size
789 if ( aFont.Height )
791 displayName.appendAscii( ", " );
792 displayName.append( sal_Int32( aFont.Height ) );
796 aControlValue <<= displayName.makeStringAndClear();
798 break;
800 default:
801 aControlValue = FormComponentPropertyHandler_Base::convertToControlValue( _rPropertyName, _rPropertyValue, _rControlValueType );
802 break;
804 } // switch ( nPropId )
806 return aControlValue;
809 //--------------------------------------------------------------------
810 PropertyState SAL_CALL FormComponentPropertyHandler::getPropertyState( const OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
812 ::osl::MutexGuard aGuard( m_aMutex );
813 if ( m_xPropertyState.is() )
814 return m_xPropertyState->getPropertyState( _rPropertyName );
815 return PropertyState_DIRECT_VALUE;
818 //--------------------------------------------------------------------
819 void SAL_CALL FormComponentPropertyHandler::addPropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
821 ::osl::MutexGuard aGuard( m_aMutex );
822 FormComponentPropertyHandler_Base::addPropertyChangeListener( _rxListener );
823 if ( m_xComponent.is() )
824 m_xComponent->addPropertyChangeListener( OUString(), _rxListener );
827 //--------------------------------------------------------------------
828 void SAL_CALL FormComponentPropertyHandler::removePropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
830 ::osl::MutexGuard aGuard( m_aMutex );
831 if ( m_xComponent.is() )
832 m_xComponent->removePropertyChangeListener( OUString(), _rxListener );
833 FormComponentPropertyHandler_Base::removePropertyChangeListener( _rxListener );
836 //--------------------------------------------------------------------
837 void FormComponentPropertyHandler::onNewComponent()
839 FormComponentPropertyHandler_Base::onNewComponent();
840 if ( !m_xComponentPropertyInfo.is() && m_xComponent.is() )
841 throw NullPointerException();
843 m_xPropertyState.set( m_xComponent, UNO_QUERY );
844 m_eComponentClass = eUnknown;
845 m_bComponentIsSubForm = m_bHaveListSource = m_bHaveCommand = false;
846 m_nClassId = 0;
848 impl_initComponentMetaData_throw();
851 //--------------------------------------------------------------------
852 Sequence< Property > SAL_CALL FormComponentPropertyHandler::doDescribeSupportedProperties() const
854 if ( !m_xComponentPropertyInfo.is() )
855 return Sequence< Property >();
857 ::std::vector< Property > aProperties;
859 Sequence< Property > aAllProperties( m_xComponentPropertyInfo->getProperties() );
860 aProperties.reserve( aAllProperties.getLength() );
862 // filter the properties
863 PropertyId nPropId( 0 );
864 OUString sDisplayName;
866 Property* pProperty = aAllProperties.getArray();
867 Property* pPropertiesEnd = pProperty + aAllProperties.getLength();
868 for ( ; pProperty != pPropertiesEnd; ++pProperty )
870 nPropId = m_pInfoService->getPropertyId( pProperty->Name );
871 if ( nPropId == -1 )
872 continue;
873 pProperty->Handle = nPropId;
875 sDisplayName = m_pInfoService->getPropertyTranslation( nPropId );
876 if ( sDisplayName.isEmpty() )
877 continue;
879 sal_uInt32 nPropertyUIFlags = m_pInfoService->getPropertyUIFlags( nPropId );
880 bool bIsVisibleForForms = ( nPropertyUIFlags & PROP_FLAG_FORM_VISIBLE ) != 0;
881 bool bIsVisibleForDialogs = ( nPropertyUIFlags & PROP_FLAG_DIALOG_VISIBLE ) != 0;
883 // depending on whether we're working for a form or a UNO dialog, some
884 // properties are not displayed
885 if ( ( m_eComponentClass == eFormControl && !bIsVisibleForForms )
886 || ( m_eComponentClass == eDialogControl && !bIsVisibleForDialogs )
888 continue;
890 // some generic sanity checks
891 if ( impl_shouldExcludeProperty_nothrow( *pProperty ) )
892 continue;
894 switch ( nPropId )
896 case PROPERTY_ID_BORDER:
897 case PROPERTY_ID_TABSTOP:
898 // BORDER and TABSTOP are normalized (see impl_normalizePropertyValue_nothrow)
899 // to not allow VOID values
900 pProperty->Attributes &= ~( PropertyAttribute::MAYBEVOID );
901 break;
903 case PROPERTY_ID_LISTSOURCE:
904 // no cursor source if no Base is installed. #124939#
905 // This fix is not intendend to appear on the main trunk. If you find it there,
906 // please tell me! frank.schoenheit@sun.com
907 if ( SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
908 const_cast< FormComponentPropertyHandler* >( this )->m_bHaveListSource = true;
909 break;
911 case PROPERTY_ID_COMMAND:
912 // no cursor source if no Base is installed. #124939#
913 // This fix is not intendend to appear on the main trunk. If you find it there,
914 // please tell me! frank.schoenheit@sun.com
915 if ( SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
916 const_cast< FormComponentPropertyHandler* >( this )->m_bHaveCommand = true;
917 break;
918 } // switch ( nPropId )
920 aProperties.push_back( *pProperty );
923 if ( aProperties.empty() )
924 return Sequence< Property >();
925 return Sequence< Property >( &(*aProperties.begin()), aProperties.size() );
928 //--------------------------------------------------------------------
929 Sequence< OUString > SAL_CALL FormComponentPropertyHandler::getSupersededProperties( ) throw (RuntimeException)
931 return Sequence< OUString >( );
934 //--------------------------------------------------------------------
935 Sequence< OUString > SAL_CALL FormComponentPropertyHandler::getActuatingProperties( ) throw (RuntimeException)
937 ::osl::MutexGuard aGuard( m_aMutex );
938 ::std::vector< OUString > aInterestingProperties;
939 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_DATASOURCE) );
940 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_COMMAND) );
941 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_COMMANDTYPE) );
942 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_LISTSOURCE) );
943 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_LISTSOURCETYPE) );
944 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_SUBMIT_ENCODING) );
945 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_REPEAT) );
946 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_TABSTOP) );
947 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_BORDER) );
948 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_CONTROLSOURCE) );
949 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_DROPDOWN) );
950 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_IMAGE_URL) );
951 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_TARGET_URL) );
952 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_STRINGITEMLIST) );
953 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_BUTTONTYPE) );
954 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_ESCAPE_PROCESSING) );
955 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_TRISTATE) );
956 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_DECIMAL_ACCURACY) );
957 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_SHOWTHOUSANDSEP) );
958 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_FORMATKEY) );
959 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_EMPTY_IS_NULL) );
960 aInterestingProperties.push_back( static_cast<const OUString&>(PROPERTY_TOGGLE) );
961 return Sequence< OUString >( &(*aInterestingProperties.begin()), aInterestingProperties.size() );
964 //--------------------------------------------------------------------
965 LineDescriptor SAL_CALL FormComponentPropertyHandler::describePropertyLine( const OUString& _rPropertyName,
966 const Reference< XPropertyControlFactory >& _rxControlFactory )
967 throw (UnknownPropertyException, NullPointerException, RuntimeException)
969 if ( !_rxControlFactory.is() )
970 throw NullPointerException();
972 ::osl::MutexGuard aGuard( m_aMutex );
973 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
974 Property aProperty( impl_getPropertyFromId_throw( nPropId ) );
976 //////////////////////////////////////////////////////////////////////
977 // for the MultiLine property, we have different UI translations depending on the control
978 // type
979 if ( nPropId == PROPERTY_ID_MULTILINE )
981 if ( ( m_nClassId == FormComponentType::FIXEDTEXT )
982 || ( m_nClassId == FormComponentType::COMMANDBUTTON )
983 || ( m_nClassId == FormComponentType::RADIOBUTTON )
984 || ( m_nClassId == FormComponentType::CHECKBOX )
986 nPropId = PROPERTY_ID_WORDBREAK;
989 String sDisplayName = m_pInfoService->getPropertyTranslation( nPropId );
990 if ( !sDisplayName.Len() )
992 OSL_FAIL( "FormComponentPropertyHandler::describePropertyLine: did getSupportedProperties not work properly?" );
993 throw UnknownPropertyException();
996 //////////////////////////////////////////////////////////////////////
998 LineDescriptor aDescriptor;
999 aDescriptor.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( nPropId ) );
1000 aDescriptor.DisplayName = sDisplayName;
1002 // for the moment, assume a text field
1003 sal_Int16 nControlType = PropertyControlType::TextField;
1004 sal_Bool bReadOnly = sal_False;
1005 aDescriptor.Control.clear();
1007 //////////////////////////////////////////////////////////////////////
1009 bool bNeedDefaultStringIfVoidAllowed = false;
1011 TypeClass eType = aProperty.Type.getTypeClass();
1013 switch ( nPropId )
1015 case PROPERTY_ID_DEFAULT_SELECT_SEQ:
1016 case PROPERTY_ID_SELECTEDITEMS:
1017 aDescriptor.PrimaryButtonId = OUString::createFromAscii(UID_PROP_DLG_SELECTION);
1018 break;
1020 case PROPERTY_ID_FILTER:
1021 aDescriptor.PrimaryButtonId = OUString::createFromAscii(UID_PROP_DLG_FILTER);
1022 break;
1024 case PROPERTY_ID_SORT:
1025 aDescriptor.PrimaryButtonId = OUString::createFromAscii(UID_PROP_DLG_ORDER);
1026 break;
1028 case PROPERTY_ID_MASTERFIELDS:
1029 case PROPERTY_ID_DETAILFIELDS:
1030 nControlType = PropertyControlType::StringListField;
1031 aDescriptor.PrimaryButtonId = OUString::createFromAscii(UID_PROP_DLG_FORMLINKFIELDS);
1032 break;
1034 case PROPERTY_ID_COMMAND:
1035 aDescriptor.PrimaryButtonId = OUString::createFromAscii(UID_PROP_DLG_SQLCOMMAND);
1036 break;
1038 case PROPERTY_ID_TABINDEX:
1040 Reference< XControlContainer > xControlContext( impl_getContextControlContainer_nothrow() );
1041 if ( xControlContext.is() )
1042 aDescriptor.PrimaryButtonId = OUString::createFromAscii(UID_PROP_DLG_TABINDEX);
1043 nControlType = PropertyControlType::NumericField;
1045 break;
1047 case PROPERTY_ID_FONT:
1048 bReadOnly = sal_True;
1049 aDescriptor.PrimaryButtonId = OUString::createFromAscii(UID_PROP_DLG_FONT_TYPE);
1050 break;
1052 case PROPERTY_ID_TARGET_URL:
1053 case PROPERTY_ID_IMAGE_URL:
1055 aDescriptor.Control = new OFileUrlControl( impl_getDefaultDialogParent_nothrow(), WB_TABSTOP | WB_BORDER );
1057 aDescriptor.PrimaryButtonId = OUString::createFromAscii(( PROPERTY_ID_TARGET_URL == nPropId )
1058 ? UID_PROP_DLG_ATTR_TARGET_URL : UID_PROP_DLG_IMAGE_URL);
1060 break;
1062 case PROPERTY_ID_ECHO_CHAR:
1063 nControlType = PropertyControlType::CharacterField;
1064 break;
1066 case PROPERTY_ID_BACKGROUNDCOLOR:
1067 case PROPERTY_ID_FILLCOLOR:
1068 case PROPERTY_ID_SYMBOLCOLOR:
1069 case PROPERTY_ID_BORDERCOLOR:
1070 nControlType = PropertyControlType::ColorListBox;
1072 switch( nPropId )
1074 case PROPERTY_ID_BACKGROUNDCOLOR:
1075 aDescriptor.PrimaryButtonId = OUString::createFromAscii(UID_PROP_DLG_BACKGROUNDCOLOR); break;
1076 case PROPERTY_ID_FILLCOLOR:
1077 aDescriptor.PrimaryButtonId = OUString::createFromAscii(UID_PROP_DLG_FILLCOLOR); break;
1078 case PROPERTY_ID_SYMBOLCOLOR:
1079 aDescriptor.PrimaryButtonId = OUString::createFromAscii(UID_PROP_DLG_SYMBOLCOLOR); break;
1080 case PROPERTY_ID_BORDERCOLOR:
1081 aDescriptor.PrimaryButtonId = OUString::createFromAscii(UID_PROP_DLG_BORDERCOLOR); break;
1083 break;
1085 case PROPERTY_ID_LABEL:
1086 nControlType = PropertyControlType::MultiLineTextField;
1087 break;
1089 case PROPERTY_ID_DEFAULT_TEXT:
1091 if (FormComponentType::FILECONTROL == m_nClassId)
1092 nControlType = PropertyControlType::TextField;
1093 else
1094 nControlType = PropertyControlType::MultiLineTextField;
1096 break;
1098 case PROPERTY_ID_TEXT:
1099 if ( impl_componentHasProperty_throw( PROPERTY_MULTILINE ) )
1100 nControlType = PropertyControlType::MultiLineTextField;
1101 break;
1103 case PROPERTY_ID_CONTROLLABEL:
1104 bReadOnly = sal_True;
1105 aDescriptor.PrimaryButtonId = OUString::createFromAscii(UID_PROP_DLG_CONTROLLABEL);
1106 break;
1108 case PROPERTY_ID_FORMATKEY:
1109 case PROPERTY_ID_EFFECTIVE_MIN:
1110 case PROPERTY_ID_EFFECTIVE_MAX:
1111 case PROPERTY_ID_EFFECTIVE_DEFAULT:
1112 case PROPERTY_ID_EFFECTIVE_VALUE:
1114 // and the supplier is really available
1115 Reference< XNumberFormatsSupplier > xSupplier;
1116 m_xComponent->getPropertyValue( PROPERTY_FORMATSSUPPLIER ) >>= xSupplier;
1117 if (xSupplier.is())
1119 Reference< XUnoTunnel > xTunnel(xSupplier,UNO_QUERY);
1120 DBG_ASSERT(xTunnel.is(), "FormComponentPropertyHandler::describePropertyLine : xTunnel is invalid!");
1121 SvNumberFormatsSupplierObj* pSupplier = reinterpret_cast<SvNumberFormatsSupplierObj*>(xTunnel->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));
1123 if (pSupplier != NULL)
1125 sal_Bool bIsFormatKey = (PROPERTY_ID_FORMATKEY == nPropId);
1127 bReadOnly = bIsFormatKey;
1129 if ( bIsFormatKey )
1131 OFormatSampleControl* pControl = new OFormatSampleControl( impl_getDefaultDialogParent_nothrow(), WB_READONLY | WB_TABSTOP | WB_BORDER );
1132 aDescriptor.Control = pControl;
1133 pControl->SetFormatSupplier( pSupplier );
1135 aDescriptor.PrimaryButtonId = OUString::createFromAscii(UID_PROP_DLG_NUMBER_FORMAT);
1137 else
1139 OFormattedNumericControl* pControl = new OFormattedNumericControl( impl_getDefaultDialogParent_nothrow(), WB_TABSTOP | WB_BORDER );
1140 aDescriptor.Control = pControl;
1142 FormatDescription aDesc;
1143 aDesc.pSupplier = pSupplier;
1144 Any aFormatKeyValue = m_xComponent->getPropertyValue(PROPERTY_FORMATKEY);
1145 if ( !( aFormatKeyValue >>= aDesc.nKey ) )
1146 aDesc.nKey = 0;
1148 pControl->SetFormatDescription( aDesc );
1153 break;
1155 case PROPERTY_ID_DATEMIN:
1156 case PROPERTY_ID_DATEMAX:
1157 case PROPERTY_ID_DEFAULT_DATE:
1158 case PROPERTY_ID_DATE:
1159 nControlType = PropertyControlType::DateField;
1160 break;
1162 case PROPERTY_ID_TIMEMIN:
1163 case PROPERTY_ID_TIMEMAX:
1164 case PROPERTY_ID_DEFAULT_TIME:
1165 case PROPERTY_ID_TIME:
1166 nControlType = PropertyControlType::TimeField;
1167 break;
1169 case PROPERTY_ID_VALUEMIN:
1170 case PROPERTY_ID_VALUEMAX:
1171 case PROPERTY_ID_DEFAULT_VALUE:
1172 case PROPERTY_ID_VALUE:
1174 OFormattedNumericControl* pControl = new OFormattedNumericControl( impl_getDefaultDialogParent_nothrow(), WB_TABSTOP | WB_BORDER | WB_SPIN | WB_REPEAT );
1175 aDescriptor.Control = pControl;
1177 // we don't set a formatter so the control uses a default (which uses the application
1178 // language and a default numeric format)
1179 // but we set the decimal digits
1180 pControl->SetDecimalDigits(
1181 ::comphelper::getINT16( m_xComponent->getPropertyValue( PROPERTY_DECIMAL_ACCURACY ) )
1184 // and the thousands separator
1185 pControl->SetThousandsSep(
1186 ::comphelper::getBOOL( m_xComponent->getPropertyValue(PROPERTY_SHOWTHOUSANDSEP) )
1189 // and the default value for the property
1192 if (m_xPropertyState.is() && ((PROPERTY_ID_VALUEMIN == nPropId) || (PROPERTY_ID_VALUEMAX == nPropId)))
1194 double nDefault = 0;
1195 if ( m_xPropertyState->getPropertyDefault( aProperty.Name ) >>= nDefault )
1196 pControl->SetDefaultValue( nDefault );
1199 catch (const Exception&)
1201 // just ignore it
1204 // and allow empty values only for the default value and the value
1205 pControl->EnableEmptyField( ( PROPERTY_ID_DEFAULT_VALUE == nPropId )
1206 || ( PROPERTY_ID_VALUE == nPropId ) );
1208 break;
1210 default:
1211 if ( TypeClass_BYTE <= eType && eType <= TypeClass_DOUBLE )
1213 sal_Int16 nDigits = 0;
1214 sal_Int16 nValueUnit = -1;
1215 sal_Int16 nDisplayUnit = -1;
1216 if ( m_eComponentClass == eFormControl )
1218 if ( ( nPropId == PROPERTY_ID_WIDTH )
1219 || ( nPropId == PROPERTY_ID_ROWHEIGHT )
1220 || ( nPropId == PROPERTY_ID_HEIGHT )
1223 nValueUnit = MeasureUnit::MM_10TH;
1224 nDisplayUnit = impl_getDocumentMeasurementUnit_throw();
1225 nDigits = 2;
1229 Optional< double > aValueNotPresent( sal_False, 0 );
1230 aDescriptor.Control = PropertyHandlerHelper::createNumericControl(
1231 _rxControlFactory, nDigits, aValueNotPresent, aValueNotPresent, sal_False );
1233 Reference< XNumericControl > xNumericControl( aDescriptor.Control, UNO_QUERY_THROW );
1234 if ( nValueUnit != -1 )
1235 xNumericControl->setValueUnit( nValueUnit );
1236 if ( nDisplayUnit != -1 )
1237 xNumericControl->setDisplayUnit( nDisplayUnit );
1239 break;
1242 //////////////////////////////////////////////////////////////////////
1243 if ( eType == TypeClass_SEQUENCE )
1244 nControlType = PropertyControlType::StringListField;
1246 //////////////////////////////////////////////////////////////////////
1247 // boolean values
1248 if ( eType == TypeClass_BOOLEAN )
1250 sal_uInt16 nResId = RID_RSC_ENUM_YESNO;
1251 if ( ( nPropId == PROPERTY_ID_SHOW_POSITION )
1252 || ( nPropId == PROPERTY_ID_SHOW_NAVIGATION )
1253 || ( nPropId == PROPERTY_ID_SHOW_RECORDACTIONS )
1254 || ( nPropId == PROPERTY_ID_SHOW_FILTERSORT )
1256 nResId = RID_RSC_ENUM_SHOWHIDE;
1258 ::std::vector< OUString > aListEntries;
1259 tools::StringListResource aRes(PcrRes(nResId),aListEntries);
1260 aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
1261 bNeedDefaultStringIfVoidAllowed = true;
1264 //////////////////////////////////////////////////////////////////////
1265 // enum properties
1266 sal_uInt32 nPropertyUIFlags = m_pInfoService->getPropertyUIFlags( nPropId );
1267 bool bIsEnumProperty = ( nPropertyUIFlags & PROP_FLAG_ENUM ) != 0;
1268 if ( bIsEnumProperty || ( PROPERTY_ID_TARGET_FRAME == nPropId ) )
1270 ::std::vector< OUString > aEnumValues = m_pInfoService->getPropertyEnumRepresentations( nPropId );
1271 ::std::vector< OUString >::const_iterator pStart = aEnumValues.begin();
1272 ::std::vector< OUString >::const_iterator pEnd = aEnumValues.end();
1274 // for a checkbox: if "ambiguous" is not allowed, remove this from the sequence
1275 if ( ( PROPERTY_ID_DEFAULT_STATE == nPropId )
1276 || ( PROPERTY_ID_STATE == nPropId )
1279 if ( impl_componentHasProperty_throw( PROPERTY_TRISTATE ) )
1281 if ( !::comphelper::getBOOL( m_xComponent->getPropertyValue( PROPERTY_TRISTATE ) ) )
1282 { // remove the last sequence element
1283 if ( pEnd > pStart )
1284 --pEnd;
1287 else
1288 --pEnd;
1291 if ( PROPERTY_ID_LISTSOURCETYPE == nPropId )
1292 if ( FormComponentType::COMBOBOX == m_nClassId )
1293 // remove the first sequence element -> value list not possible for combo boxes
1294 ++pStart;
1296 // copy the sequence
1297 ::std::vector< OUString > aListEntries( pEnd - pStart );
1298 ::std::copy( pStart, pEnd, aListEntries.begin() );
1300 // create the control
1301 if ( PROPERTY_ID_TARGET_FRAME == nPropId )
1302 aDescriptor.Control = PropertyHandlerHelper::createComboBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
1303 else
1305 aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
1306 bNeedDefaultStringIfVoidAllowed = true;
1310 //////////////////////////////////////////////////////////////////////
1311 switch( nPropId )
1313 case PROPERTY_ID_REPEAT_DELAY:
1315 OTimeDurationControl* pControl = new OTimeDurationControl( impl_getDefaultDialogParent_nothrow(), WB_BORDER | WB_TABSTOP );
1316 aDescriptor.Control = pControl;
1318 pControl->setMinValue( Optional< double >( sal_True, 0 ) );
1319 pControl->setMaxValue( Optional< double >( sal_True, ::std::numeric_limits< double >::max() ) );
1321 break;
1323 case PROPERTY_ID_TABINDEX:
1324 case PROPERTY_ID_BOUNDCOLUMN:
1325 case PROPERTY_ID_VISIBLESIZE:
1326 case PROPERTY_ID_MAXTEXTLEN:
1327 case PROPERTY_ID_LINEINCREMENT:
1328 case PROPERTY_ID_BLOCKINCREMENT:
1329 case PROPERTY_ID_SPININCREMENT:
1331 Optional< double > aMinValue( sal_True, 0 );
1332 Optional< double > aMaxValue( sal_True, 0x7FFFFFFF );
1334 if ( nPropId == PROPERTY_ID_MAXTEXTLEN || nPropId == PROPERTY_ID_BOUNDCOLUMN )
1335 aMinValue.Value = -1;
1336 else if ( nPropId == PROPERTY_ID_VISIBLESIZE )
1337 aMinValue.Value = 1;
1338 else
1339 aMinValue.Value = 0;
1341 aDescriptor.Control = PropertyHandlerHelper::createNumericControl(
1342 _rxControlFactory, 0, aMinValue, aMaxValue, sal_False );
1344 break;
1346 case PROPERTY_ID_DECIMAL_ACCURACY:
1348 Optional< double > aMinValue( sal_True, 0 );
1349 Optional< double > aMaxValue( sal_True, 20 );
1351 aDescriptor.Control = PropertyHandlerHelper::createNumericControl(
1352 _rxControlFactory, 0, aMinValue, aMaxValue, sal_False );
1354 break;
1356 //////////////////////////////////////////////////////////////////////
1357 // DataSource
1358 case PROPERTY_ID_DATASOURCE:
1360 aDescriptor.PrimaryButtonId = OUString::createFromAscii(UID_PROP_DLG_ATTR_DATASOURCE);
1362 ::std::vector< OUString > aListEntries;
1364 Reference< XDatabaseContext > xDatabaseContext = sdb::DatabaseContext::create( m_aContext.getUNOContext() );
1365 Sequence< OUString > aDatasources = xDatabaseContext->getElementNames();
1366 aListEntries.resize( aDatasources.getLength() );
1367 ::std::copy( aDatasources.getConstArray(), aDatasources.getConstArray() + aDatasources.getLength(),
1368 aListEntries.begin() );
1369 aDescriptor.Control = PropertyHandlerHelper::createComboBoxControl(
1370 _rxControlFactory, aListEntries, sal_False, sal_True );
1372 break;
1374 case PROPERTY_ID_CONTROLSOURCE:
1376 ::std::vector< OUString > aFieldNames;
1377 impl_initFieldList_nothrow( aFieldNames );
1378 aDescriptor.Control = PropertyHandlerHelper::createComboBoxControl(
1379 _rxControlFactory, aFieldNames, sal_False, sal_False );
1381 break;
1383 case PROPERTY_ID_COMMAND:
1384 impl_describeCursorSource_nothrow( aDescriptor, _rxControlFactory );
1385 break;
1387 case PROPERTY_ID_LISTSOURCE:
1388 impl_describeListSourceUI_throw( aDescriptor, _rxControlFactory );
1389 break;
1392 if ( !aDescriptor.Control.is() )
1393 aDescriptor.Control = _rxControlFactory->createPropertyControl( nControlType, bReadOnly );
1395 if ( ( aProperty.Attributes & PropertyAttribute::MAYBEVOID ) != 0 )
1397 // insert the string "Default" string, if necessary
1398 if ( bNeedDefaultStringIfVoidAllowed || ( nControlType == PropertyControlType::ColorListBox ) )
1400 Reference< XStringListControl > xStringList( aDescriptor.Control, UNO_QUERY_THROW );
1401 xStringList->prependListEntry( m_sDefaultValueString );
1402 m_aPropertiesWithDefListEntry.insert( _rPropertyName );
1406 if ( !aDescriptor.PrimaryButtonId.isEmpty() )
1407 aDescriptor.HasPrimaryButton = sal_True;
1408 if ( !aDescriptor.SecondaryButtonId.isEmpty() )
1409 aDescriptor.HasSecondaryButton = sal_True;
1411 bool bIsDataProperty = ( nPropertyUIFlags & PROP_FLAG_DATA_PROPERTY ) != 0;
1412 aDescriptor.Category = bIsDataProperty ? OUString("Data") : OUString("General");
1413 return aDescriptor;
1416 //--------------------------------------------------------------------
1417 InteractiveSelectionResult SAL_CALL FormComponentPropertyHandler::onInteractivePropertySelection( const OUString& _rPropertyName, sal_Bool /*_bPrimary*/, Any& _rData, const Reference< XObjectInspectorUI >& _rxInspectorUI ) throw (UnknownPropertyException, NullPointerException, RuntimeException)
1419 if ( !_rxInspectorUI.is() )
1420 throw NullPointerException();
1422 ::osl::ClearableMutexGuard aGuard( m_aMutex );
1423 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
1425 InteractiveSelectionResult eResult = InteractiveSelectionResult_Cancelled;
1426 switch ( nPropId )
1428 case PROPERTY_ID_DEFAULT_SELECT_SEQ:
1429 case PROPERTY_ID_SELECTEDITEMS:
1430 if ( impl_dialogListSelection_nothrow( _rPropertyName, aGuard ) )
1431 eResult = InteractiveSelectionResult_Success;
1432 break;
1434 case PROPERTY_ID_FILTER:
1435 case PROPERTY_ID_SORT:
1437 OUString sClause;
1438 if ( impl_dialogFilterOrSort_nothrow( PROPERTY_ID_FILTER == nPropId, sClause, aGuard ) )
1440 _rData <<= sClause;
1441 eResult = InteractiveSelectionResult_ObtainedValue;
1444 break;
1446 case PROPERTY_ID_MASTERFIELDS:
1447 case PROPERTY_ID_DETAILFIELDS:
1448 if ( impl_dialogLinkedFormFields_nothrow( aGuard ) )
1449 eResult = InteractiveSelectionResult_Success;
1450 break;
1452 case PROPERTY_ID_FORMATKEY:
1453 if ( impl_dialogFormatting_nothrow( _rData, aGuard ) )
1454 eResult = InteractiveSelectionResult_ObtainedValue;
1455 break;
1457 case PROPERTY_ID_IMAGE_URL:
1458 if ( impl_browseForImage_nothrow( _rData, aGuard ) )
1459 eResult = InteractiveSelectionResult_ObtainedValue;
1460 break;
1462 case PROPERTY_ID_TARGET_URL:
1463 if ( impl_browseForTargetURL_nothrow( _rData, aGuard ) )
1464 eResult = InteractiveSelectionResult_ObtainedValue;
1465 break;
1467 case PROPERTY_ID_FONT:
1468 if ( impl_executeFontDialog_nothrow( _rData, aGuard ) )
1469 eResult = InteractiveSelectionResult_ObtainedValue;
1470 break;
1472 case PROPERTY_ID_DATASOURCE:
1473 if ( impl_browseForDatabaseDocument_throw( _rData, aGuard ) )
1474 eResult = InteractiveSelectionResult_ObtainedValue;
1475 break;
1477 case PROPERTY_ID_BACKGROUNDCOLOR:
1478 case PROPERTY_ID_FILLCOLOR:
1479 case PROPERTY_ID_SYMBOLCOLOR:
1480 case PROPERTY_ID_BORDERCOLOR:
1481 if ( impl_dialogColorChooser_throw( nPropId, _rData, aGuard ) )
1482 eResult = InteractiveSelectionResult_ObtainedValue;
1483 break;
1485 case PROPERTY_ID_CONTROLLABEL:
1486 if ( impl_dialogChooseLabelControl_nothrow( _rData, aGuard ) )
1487 eResult = InteractiveSelectionResult_ObtainedValue;
1488 break;
1490 case PROPERTY_ID_TABINDEX:
1491 if ( impl_dialogChangeTabOrder_nothrow( aGuard ) )
1492 eResult = InteractiveSelectionResult_Success;
1493 break;
1495 case PROPERTY_ID_COMMAND:
1496 case PROPERTY_ID_LISTSOURCE:
1497 if ( impl_doDesignSQLCommand_nothrow( _rxInspectorUI, nPropId ) )
1498 eResult = InteractiveSelectionResult_Pending;
1499 break;
1500 default:
1501 OSL_FAIL( "FormComponentPropertyHandler::onInteractivePropertySelection: request for a property which does not have dedicated UI!" );
1502 break;
1504 return eResult;
1507 //--------------------------------------------------------------------
1508 namespace
1510 void lcl_rebuildAndResetCommand( const Reference< XObjectInspectorUI >& _rxInspectorUI, const Reference< XPropertyHandler >& _rxHandler )
1512 OSL_PRECOND( _rxInspectorUI.is(), "lcl_rebuildAndResetCommand: invalid BrowserUI!" );
1513 OSL_PRECOND( _rxHandler.is(), "lcl_rebuildAndResetCommand: invalid handler!" );
1514 _rxInspectorUI->rebuildPropertyUI( PROPERTY_COMMAND );
1515 _rxHandler->setPropertyValue( PROPERTY_COMMAND, makeAny( OUString() ) );
1519 //--------------------------------------------------------------------
1520 void SAL_CALL FormComponentPropertyHandler::actuatingPropertyChanged( const OUString& _rActuatingPropertyName, const Any& _rNewValue, const Any& /*_rOldValue*/, const Reference< XObjectInspectorUI >& _rxInspectorUI, sal_Bool _bFirstTimeInit ) throw (NullPointerException, RuntimeException)
1522 if ( !_rxInspectorUI.is() )
1523 throw NullPointerException();
1525 ::osl::MutexGuard aGuard( m_aMutex );
1526 PropertyId nActuatingPropId( impl_getPropertyId_throw( _rActuatingPropertyName ) );
1528 ::std::vector< PropertyId > aDependentProperties;
1530 switch ( nActuatingPropId )
1532 // ----- EscapeProcessing -----
1533 case PROPERTY_ID_ESCAPE_PROCESSING:
1534 aDependentProperties.push_back( PROPERTY_ID_FILTER );
1535 aDependentProperties.push_back( PROPERTY_ID_SORT );
1536 break; // case PROPERTY_ID_ESCAPE_PROCESSING
1538 // ----- CommandType -----
1539 case PROPERTY_ID_COMMANDTYPE:
1540 // available commands (tables or queries) might have changed
1541 if ( !_bFirstTimeInit && m_bHaveCommand )
1542 lcl_rebuildAndResetCommand( _rxInspectorUI, this );
1543 aDependentProperties.push_back( PROPERTY_ID_COMMAND );
1544 break; // case PROPERTY_ID_COMMANDTYPE
1546 // ----- DataSourceName -----
1547 case PROPERTY_ID_DATASOURCE:
1548 // reset the connection, now that we have a new data source
1549 impl_clearRowsetConnection_nothrow();
1551 // available list source values (tables or queries) might have changed
1552 if ( !_bFirstTimeInit && m_bHaveListSource )
1553 _rxInspectorUI->rebuildPropertyUI( PROPERTY_LISTSOURCE );
1555 // available commands (tables or queries) might have changed
1556 if ( !_bFirstTimeInit && m_bHaveCommand )
1557 lcl_rebuildAndResetCommand( _rxInspectorUI, this );
1559 // Command also depends on DataSource
1560 aDependentProperties.push_back( PROPERTY_ID_COMMAND );
1561 // NO break!
1563 // ----- Command -----
1564 case PROPERTY_ID_COMMAND:
1565 aDependentProperties.push_back( PROPERTY_ID_FILTER );
1566 aDependentProperties.push_back( PROPERTY_ID_SORT );
1567 if ( m_bComponentIsSubForm )
1568 aDependentProperties.push_back( PROPERTY_ID_DETAILFIELDS );
1569 break;
1571 // ----- ListSourceType -----
1572 case PROPERTY_ID_LISTSOURCETYPE:
1573 if ( !_bFirstTimeInit && m_bHaveListSource )
1574 // available list source values (tables or queries) might have changed
1575 _rxInspectorUI->rebuildPropertyUI( PROPERTY_LISTSOURCE );
1576 aDependentProperties.push_back( PROPERTY_ID_STRINGITEMLIST );
1577 aDependentProperties.push_back( PROPERTY_ID_BOUNDCOLUMN );
1578 // NO break!
1580 // ----- StringItemList -----
1581 case PROPERTY_ID_STRINGITEMLIST:
1582 aDependentProperties.push_back( PROPERTY_ID_SELECTEDITEMS );
1583 aDependentProperties.push_back( PROPERTY_ID_DEFAULT_SELECT_SEQ );
1584 break;
1586 // ----- ListSource -----
1587 case PROPERTY_ID_LISTSOURCE:
1588 aDependentProperties.push_back( PROPERTY_ID_STRINGITEMLIST );
1589 break;
1591 // ----- DataField -----
1592 case PROPERTY_ID_CONTROLSOURCE:
1594 OUString sControlSource;
1595 _rNewValue >>= sControlSource;
1596 if ( impl_componentHasProperty_throw( PROPERTY_FILTERPROPOSAL ) )
1597 _rxInspectorUI->enablePropertyUI( PROPERTY_FILTERPROPOSAL, !sControlSource.isEmpty() );
1598 if ( impl_componentHasProperty_throw( PROPERTY_EMPTY_IS_NULL ) )
1599 _rxInspectorUI->enablePropertyUI( PROPERTY_EMPTY_IS_NULL, !sControlSource.isEmpty() );
1601 aDependentProperties.push_back( PROPERTY_ID_BOUNDCOLUMN );
1602 aDependentProperties.push_back( PROPERTY_ID_SCALEIMAGE );
1603 aDependentProperties.push_back( PROPERTY_ID_SCALE_MODE );
1604 aDependentProperties.push_back( PROPERTY_ID_INPUT_REQUIRED );
1606 break;
1608 case PROPERTY_ID_EMPTY_IS_NULL:
1609 aDependentProperties.push_back( PROPERTY_ID_INPUT_REQUIRED );
1610 break;
1612 // ----- SubmitEncoding -----
1613 case PROPERTY_ID_SUBMIT_ENCODING:
1615 FormSubmitEncoding eEncoding = FormSubmitEncoding_URL;
1616 OSL_VERIFY( _rNewValue >>= eEncoding );
1617 _rxInspectorUI->enablePropertyUI( PROPERTY_SUBMIT_METHOD, eEncoding == FormSubmitEncoding_URL );
1619 break;
1621 // ----- Repeat -----
1622 case PROPERTY_ID_REPEAT:
1624 sal_Bool bIsRepeating = sal_False;
1625 OSL_VERIFY( _rNewValue >>= bIsRepeating );
1626 _rxInspectorUI->enablePropertyUI( PROPERTY_REPEAT_DELAY, bIsRepeating );
1628 break;
1630 // ----- TabStop -----
1631 case PROPERTY_ID_TABSTOP:
1633 if ( !impl_componentHasProperty_throw( PROPERTY_TABINDEX ) )
1634 break;
1635 sal_Bool bHasTabStop = sal_False;
1636 _rNewValue >>= bHasTabStop;
1637 _rxInspectorUI->enablePropertyUI( PROPERTY_TABINDEX, bHasTabStop );
1639 break;
1641 // ----- Border -----
1642 case PROPERTY_ID_BORDER:
1644 sal_Int16 nBordeType = VisualEffect::NONE;
1645 OSL_VERIFY( _rNewValue >>= nBordeType );
1646 _rxInspectorUI->enablePropertyUI( PROPERTY_BORDERCOLOR, nBordeType == VisualEffect::FLAT );
1648 break;
1650 // ----- DropDown -----
1651 case PROPERTY_ID_DROPDOWN:
1653 if ( impl_isSupportedProperty_nothrow( PROPERTY_ID_LINECOUNT ) )
1655 sal_Bool bDropDown = sal_True;
1656 _rNewValue >>= bDropDown;
1657 _rxInspectorUI->enablePropertyUI( PROPERTY_LINECOUNT, bDropDown );
1660 break;
1662 // ----- ImageURL -----
1663 case PROPERTY_ID_IMAGE_URL:
1665 if ( impl_isSupportedProperty_nothrow( PROPERTY_ID_IMAGEPOSITION ) )
1667 OUString sImageURL;
1668 OSL_VERIFY( _rNewValue >>= sImageURL );
1669 _rxInspectorUI->enablePropertyUI( PROPERTY_IMAGEPOSITION, !sImageURL.isEmpty() );
1672 aDependentProperties.push_back( PROPERTY_ID_SCALEIMAGE );
1673 aDependentProperties.push_back( PROPERTY_ID_SCALE_MODE );
1675 break;
1677 // ----- ButtonType -----
1678 case PROPERTY_ID_BUTTONTYPE:
1680 FormButtonType eButtonType( FormButtonType_PUSH );
1681 OSL_VERIFY( _rNewValue >>= eButtonType );
1682 _rxInspectorUI->enablePropertyUI( PROPERTY_TARGET_URL, FormButtonType_URL == eButtonType );
1684 // NO break!
1686 // ----- TargetURL -----
1687 case PROPERTY_ID_TARGET_URL:
1688 aDependentProperties.push_back( PROPERTY_ID_TARGET_FRAME );
1689 break; // case PROPERTY_ID_TARGET_URL
1691 // ----- TriState -----
1692 case PROPERTY_ID_TRISTATE:
1693 if ( !_bFirstTimeInit )
1694 _rxInspectorUI->rebuildPropertyUI( m_eComponentClass == eFormControl ? OUString(PROPERTY_DEFAULT_STATE) : OUString(PROPERTY_STATE) );
1695 break; // case PROPERTY_ID_TRISTATE
1697 // ----- DecimalAccuracy -----
1698 case PROPERTY_ID_DECIMAL_ACCURACY:
1699 // ----- ShowThousandsSeparator -----
1700 case PROPERTY_ID_SHOWTHOUSANDSEP:
1702 sal_Bool bAccuracy = (PROPERTY_ID_DECIMAL_ACCURACY == nActuatingPropId);
1703 sal_uInt16 nNewDigits = 0;
1704 sal_Bool bUseSep = sal_False;
1705 if ( bAccuracy )
1706 OSL_VERIFY( _rNewValue >>= nNewDigits );
1707 else
1708 OSL_VERIFY( _rNewValue >>= bUseSep );
1710 // propagate the changes to the min/max/default fields
1711 Any aCurrentProp;
1712 OUString aAffectedProps[] = { OUString(PROPERTY_VALUE), OUString(PROPERTY_DEFAULT_VALUE), OUString(PROPERTY_VALUEMIN), OUString(PROPERTY_VALUEMAX) };
1713 for (sal_uInt16 i=0; i<SAL_N_ELEMENTS(aAffectedProps); ++i)
1715 Reference< XPropertyControl > xControl;
1718 xControl = _rxInspectorUI->getPropertyControl( aAffectedProps[i] );
1720 catch( const UnknownPropertyException& ) {}
1721 if ( xControl.is() )
1723 OFormattedNumericControl* pControl = dynamic_cast< OFormattedNumericControl* >( xControl.get() );
1724 DBG_ASSERT( pControl, "FormComponentPropertyHandler::actuatingPropertyChanged: invalid control!" );
1725 if ( pControl )
1727 if ( bAccuracy )
1728 pControl->SetDecimalDigits( nNewDigits );
1729 else
1730 pControl->SetThousandsSep( bUseSep );
1735 break;
1737 // ----- FormatKey -----
1738 case PROPERTY_ID_FORMATKEY:
1740 FormatDescription aNewDesc;
1742 Reference< XNumberFormatsSupplier > xSupplier;
1743 OSL_VERIFY( m_xComponent->getPropertyValue( PROPERTY_FORMATSSUPPLIER ) >>= xSupplier );
1745 Reference< XUnoTunnel > xTunnel( xSupplier, UNO_QUERY );
1746 DBG_ASSERT(xTunnel.is(), "FormComponentPropertyHandler::actuatingPropertyChanged: xTunnel is invalid!");
1747 if ( xTunnel.is() )
1749 SvNumberFormatsSupplierObj* pSupplier = reinterpret_cast<SvNumberFormatsSupplierObj*>(xTunnel->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));
1750 // the same again
1752 aNewDesc.pSupplier = pSupplier;
1753 if ( !( _rNewValue >>= aNewDesc.nKey ) )
1754 aNewDesc.nKey = 0;
1756 // give each control which has to know this an own copy of the description
1757 OUString aFormattedPropertyControls[] = {
1758 OUString(PROPERTY_EFFECTIVE_MIN), OUString(PROPERTY_EFFECTIVE_MAX), OUString(PROPERTY_EFFECTIVE_DEFAULT), OUString(PROPERTY_EFFECTIVE_VALUE)
1760 for ( sal_uInt16 i=0; i<SAL_N_ELEMENTS(aFormattedPropertyControls); ++i )
1762 Reference< XPropertyControl > xControl;
1765 xControl = _rxInspectorUI->getPropertyControl( aFormattedPropertyControls[i] );
1767 catch( const UnknownPropertyException& ) {}
1768 if ( xControl.is() )
1770 OFormattedNumericControl* pControl = dynamic_cast< OFormattedNumericControl* >( xControl.get() );
1771 DBG_ASSERT( pControl, "FormComponentPropertyHandler::actuatingPropertyChanged: invalid control!" );
1772 if ( pControl )
1773 pControl->SetFormatDescription( aNewDesc );
1778 break;
1780 case PROPERTY_ID_TOGGLE:
1782 sal_Bool bIsToggleButton = sal_False;
1783 OSL_VERIFY( _rNewValue >>= bIsToggleButton );
1784 _rxInspectorUI->enablePropertyUI( PROPERTY_DEFAULT_STATE, bIsToggleButton );
1786 break;
1788 default:
1789 OSL_FAIL( "FormComponentPropertyHandler::actuatingPropertyChanged: did not register for this property!" );
1790 break;
1792 } // switch ( nActuatingPropId )
1794 for ( ::std::vector< PropertyId >::const_iterator loopAffected = aDependentProperties.begin();
1795 loopAffected != aDependentProperties.end();
1796 ++loopAffected
1799 if ( impl_isSupportedProperty_nothrow( *loopAffected ) )
1800 impl_updateDependentProperty_nothrow( *loopAffected, _rxInspectorUI );
1804 //------------------------------------------------------------------------
1805 void FormComponentPropertyHandler::impl_updateDependentProperty_nothrow( PropertyId _nPropId, const Reference< XObjectInspectorUI >& _rxInspectorUI ) const
1809 switch ( _nPropId )
1811 // ----- StringItemList -----
1812 case PROPERTY_ID_STRINGITEMLIST:
1814 ListSourceType eLSType = ListSourceType_VALUELIST;
1815 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_LISTSOURCETYPE ) >>= eLSType );
1817 OUString sListSource;
1819 Sequence< OUString > aListSource;
1820 Any aListSourceValue( impl_getPropertyValue_throw( PROPERTY_LISTSOURCE ) );
1821 if ( aListSourceValue >>= aListSource )
1823 if ( aListSource.getLength() )
1824 sListSource = aListSource[0];
1826 else
1827 OSL_VERIFY( aListSourceValue >>= sListSource );
1830 sal_Bool bIsEnabled = ( ( eLSType == ListSourceType_VALUELIST )
1831 || ( sListSource.isEmpty() )
1833 _rxInspectorUI->enablePropertyUI( PROPERTY_STRINGITEMLIST, bIsEnabled );
1835 break; // case PROPERTY_ID_STRINGITEMLIST
1837 // ----- BoundColumn -----
1838 case PROPERTY_ID_BOUNDCOLUMN:
1840 ListSourceType eLSType = ListSourceType_VALUELIST;
1841 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_LISTSOURCETYPE ) >>= eLSType );
1843 _rxInspectorUI->enablePropertyUI( PROPERTY_BOUNDCOLUMN,
1844 ( eLSType != ListSourceType_VALUELIST )
1847 break; // case PROPERTY_ID_BOUNDCOLUMN
1849 // ----- ScaleImage, ScaleMode -----
1850 case PROPERTY_ID_SCALEIMAGE:
1851 case PROPERTY_ID_SCALE_MODE:
1853 OUString sControlSource;
1854 if ( impl_isSupportedProperty_nothrow( PROPERTY_ID_CONTROLSOURCE ) )
1855 impl_getPropertyValue_throw( PROPERTY_CONTROLSOURCE ) >>= sControlSource;
1857 OUString sImageURL;
1858 impl_getPropertyValue_throw( PROPERTY_IMAGE_URL ) >>= sImageURL;
1860 _rxInspectorUI->enablePropertyUI( impl_getPropertyNameFromId_nothrow( _nPropId ),
1861 ( !sControlSource.isEmpty() ) || ( !sImageURL.isEmpty() )
1864 break; // case PROPERTY_ID_SCALEIMAGE, PROPERTY_ID_SCALE_MODE
1866 // ----- InputRequired -----
1867 case PROPERTY_ID_INPUT_REQUIRED:
1869 OUString sControlSource;
1870 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_CONTROLSOURCE ) >>= sControlSource );
1872 sal_Bool bEmptyIsNULL = sal_False;
1873 sal_Bool bHasEmptyIsNULL = impl_componentHasProperty_throw( PROPERTY_EMPTY_IS_NULL );
1874 if ( bHasEmptyIsNULL )
1875 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_EMPTY_IS_NULL ) >>= bEmptyIsNULL );
1877 // if the control is not bound to a DB field, there is no sense in having the "Input required"
1878 // property
1879 // Also, if an empty input of this control are *not* written as NULL, but as empty strings,
1880 // then "Input required" does not make sense, too (since there's always an input, even if the control
1881 // is empty).
1882 _rxInspectorUI->enablePropertyUI( PROPERTY_INPUT_REQUIRED,
1883 ( !sControlSource.isEmpty() ) && ( !bHasEmptyIsNULL || bEmptyIsNULL )
1886 break;
1888 // ----- SelectedItems, DefaultSelection -----
1889 case PROPERTY_ID_SELECTEDITEMS:
1890 case PROPERTY_ID_DEFAULT_SELECT_SEQ:
1892 Sequence< OUString > aEntries;
1893 impl_getPropertyValue_throw( PROPERTY_STRINGITEMLIST ) >>= aEntries;
1894 bool isEnabled = aEntries.getLength() != 0;
1896 if ( ( m_nClassId == FormComponentType::LISTBOX ) && ( m_eComponentClass == eFormControl ) )
1898 ListSourceType eLSType = ListSourceType_VALUELIST;
1899 impl_getPropertyValue_throw( PROPERTY_LISTSOURCETYPE ) >>= eLSType;
1900 isEnabled &= ( eLSType == ListSourceType_VALUELIST );
1902 _rxInspectorUI->enablePropertyUIElements( impl_getPropertyNameFromId_nothrow( _nPropId ),
1903 PropertyLineElement::PrimaryButton, isEnabled );
1905 break; // case PROPERTY_ID_DEFAULT_SELECT_SEQ
1907 // ----- TargetFrame ------
1908 case PROPERTY_ID_TARGET_FRAME:
1910 OUString sTargetURL;
1911 impl_getPropertyValue_throw( PROPERTY_TARGET_URL ) >>= sTargetURL;
1912 FormButtonType eButtonType( FormButtonType_URL );
1913 if ( 0 != m_nClassId )
1915 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_BUTTONTYPE ) >>= eButtonType );
1917 // if m_nClassId is 0, then we're inspecting a form. In this case, eButtonType is always
1918 // FormButtonType_URL here
1919 _rxInspectorUI->enablePropertyUI( PROPERTY_TARGET_FRAME,
1920 ( eButtonType == FormButtonType_URL ) && ( !sTargetURL.isEmpty() )
1923 break;
1925 // ----- Order ------
1926 case PROPERTY_ID_SORT:
1927 // ----- Filter ------
1928 case PROPERTY_ID_FILTER:
1930 Reference< XConnection > xConnection;
1931 bool bAllowEmptyDS = ::dbtools::isEmbeddedInDatabase( m_xComponent, xConnection );
1933 // if there's no escape processing, we cannot enter any values for this property
1934 sal_Bool bDoEscapeProcessing( sal_False );
1935 impl_getPropertyValue_throw( PROPERTY_ESCAPE_PROCESSING ) >>= bDoEscapeProcessing;
1936 _rxInspectorUI->enablePropertyUI(
1937 impl_getPropertyNameFromId_nothrow( _nPropId ),
1938 bDoEscapeProcessing
1941 // also care for the browse button - enabled if we have escape processing, and a valid
1942 // data source signature
1943 _rxInspectorUI->enablePropertyUIElements(
1944 impl_getPropertyNameFromId_nothrow( _nPropId ),
1945 PropertyLineElement::PrimaryButton,
1946 impl_hasValidDataSourceSignature_nothrow( m_xComponent, bAllowEmptyDS )
1947 && bDoEscapeProcessing
1950 break; // case PROPERTY_ID_FILTER:
1952 // ----- Command -----
1953 case PROPERTY_ID_COMMAND:
1955 sal_Int32 nCommandType( CommandType::COMMAND );
1956 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_COMMANDTYPE ) >>= nCommandType );
1958 impl_ensureRowsetConnection_nothrow();
1959 Reference< XConnection > xConnection = m_xRowSetConnection.getTyped();
1960 bool bAllowEmptyDS = false;
1961 if ( !xConnection.is() )
1962 bAllowEmptyDS = ::dbtools::isEmbeddedInDatabase( m_xComponent, xConnection );
1964 bool doEnable = ( nCommandType == CommandType::COMMAND )
1965 && ( m_xRowSetConnection.is()
1966 || xConnection.is()
1967 || impl_hasValidDataSourceSignature_nothrow( m_xComponent, bAllowEmptyDS)
1970 _rxInspectorUI->enablePropertyUIElements(
1971 PROPERTY_COMMAND,
1972 PropertyLineElement::PrimaryButton,
1973 doEnable
1976 break; // case PROPERTY_ID_COMMAND
1978 // ----- DetailFields -----
1979 case PROPERTY_ID_DETAILFIELDS:
1981 Reference< XConnection > xConnection;
1982 bool bAllowEmptyDS = ::dbtools::isEmbeddedInDatabase( m_xComponent, xConnection );
1984 // both our current form, and it's parent form, need to have a valid
1985 // data source signature
1986 bool bDoEnableMasterDetailFields =
1987 impl_hasValidDataSourceSignature_nothrow( m_xComponent, bAllowEmptyDS )
1988 && impl_hasValidDataSourceSignature_nothrow( Reference< XPropertySet >( m_xObjectParent, UNO_QUERY ), bAllowEmptyDS );
1990 // in opposite to the other properties, here in real *two* properties are
1991 // affected
1992 _rxInspectorUI->enablePropertyUIElements( PROPERTY_DETAILFIELDS, PropertyLineElement::PrimaryButton, bDoEnableMasterDetailFields );
1993 _rxInspectorUI->enablePropertyUIElements( PROPERTY_MASTERFIELDS, PropertyLineElement::PrimaryButton, bDoEnableMasterDetailFields );
1995 break;
1997 default:
1998 OSL_FAIL( "FormComponentPropertyHandler::impl_updateDependentProperty_nothrow: unexpected property to update!" );
1999 break;
2001 } // switch
2003 catch( const Exception& )
2005 OSL_FAIL( "FormComponentPropertyHandler::impl_updateDependentProperty_nothrow: caught an exception!" );
2009 //------------------------------------------------------------------------
2010 void SAL_CALL FormComponentPropertyHandler::disposing()
2012 FormComponentPropertyHandler_Base::disposing();
2013 if ( m_xCommandDesigner.is() && m_xCommandDesigner->isActive() )
2014 m_xCommandDesigner->dispose();
2017 //------------------------------------------------------------------------
2018 sal_Bool SAL_CALL FormComponentPropertyHandler::suspend( sal_Bool _bSuspend ) throw (RuntimeException)
2020 ::osl::MutexGuard aGuard( m_aMutex );
2021 if ( _bSuspend )
2022 if ( m_xCommandDesigner.is() && m_xCommandDesigner->isActive() )
2023 return m_xCommandDesigner->suspend();
2024 return sal_True;
2027 //------------------------------------------------------------------------
2028 void FormComponentPropertyHandler::impl_initComponentMetaData_throw()
2032 //////////////////////////////////////////////////////////////////
2033 // component class
2034 m_eComponentClass = eUnknown;
2036 if ( impl_componentHasProperty_throw( PROPERTY_WIDTH )
2037 && impl_componentHasProperty_throw( PROPERTY_HEIGHT )
2038 && impl_componentHasProperty_throw( PROPERTY_POSITIONX )
2039 && impl_componentHasProperty_throw( PROPERTY_POSITIONY )
2040 && impl_componentHasProperty_throw( PROPERTY_STEP )
2041 && impl_componentHasProperty_throw( PROPERTY_TABINDEX )
2044 m_eComponentClass = eDialogControl;
2046 else
2048 m_eComponentClass = eFormControl;
2051 //////////////////////////////////////////////////////////////////
2052 // (database) sub form?
2053 Reference< XForm > xAsForm( m_xComponent, UNO_QUERY );
2054 if ( xAsForm.is() )
2056 Reference< XChild > xFormAsChild( xAsForm, UNO_QUERY );
2057 Reference< XForm > xFormsParent;
2058 if ( xFormAsChild.is() )
2059 xFormsParent = xFormsParent.query( xFormAsChild->getParent() );
2060 m_bComponentIsSubForm = xFormsParent.is();
2063 //////////////////////////////////////////////////////////////////
2064 // ClassId
2065 Reference< XChild > xCompAsChild( m_xComponent, UNO_QUERY );
2066 if ( xCompAsChild.is() )
2067 m_xObjectParent = xCompAsChild->getParent();
2069 //////////////////////////////////////////////////////////////////
2070 // ClassId
2071 impl_classifyControlModel_throw();
2073 catch( const RuntimeException& )
2075 throw;
2077 catch( const Exception& )
2079 OSL_FAIL( "FormComponentPropertyHandler::impl_initComponentMetaData_throw: caught an exception!" );
2083 //------------------------------------------------------------------------
2084 void FormComponentPropertyHandler::impl_classifyControlModel_throw( )
2086 if ( impl_componentHasProperty_throw( PROPERTY_CLASSID ) )
2088 OSL_VERIFY( m_xComponent->getPropertyValue( PROPERTY_CLASSID ) >>= m_nClassId );
2090 else if ( eDialogControl == m_eComponentClass )
2092 Reference< XControlModel > xControlModel( m_xComponent, UNO_QUERY );
2093 Reference< XServiceInfo > xServiceInfo( m_xComponent, UNO_QUERY );
2094 if ( xServiceInfo.is() )
2096 // it's a control model, and can tell about it's supported services
2097 m_nClassId = FormComponentType::CONTROL;
2099 const sal_Char* aControlModelServiceNames[] =
2101 "UnoControlButtonModel",
2102 "UnoControlCheckBoxModel",
2103 "UnoControlComboBoxModel",
2104 "UnoControlCurrencyFieldModel",
2105 "UnoControlDateFieldModel",
2106 "UnoControlEditModel",
2107 "UnoControlFileControlModel",
2108 "UnoControlFixedTextModel",
2109 "UnoControlGroupBoxModel",
2110 "UnoControlImageControlModel",
2111 "UnoControlListBoxModel",
2112 "UnoControlNumericFieldModel",
2113 "UnoControlPatternFieldModel",
2114 "UnoControlRadioButtonModel",
2115 "UnoControlScrollBarModel",
2116 "UnoControlSpinButtonModel",
2117 "UnoControlTimeFieldModel",
2119 "UnoControlFixedLineModel",
2120 "UnoControlFormattedFieldModel",
2121 "UnoControlProgressBarModel"
2123 const sal_Int16 nClassIDs[] =
2125 FormComponentType::COMMANDBUTTON,
2126 FormComponentType::CHECKBOX,
2127 FormComponentType::COMBOBOX,
2128 FormComponentType::CURRENCYFIELD,
2129 FormComponentType::DATEFIELD,
2130 FormComponentType::TEXTFIELD,
2131 FormComponentType::FILECONTROL,
2132 FormComponentType::FIXEDTEXT,
2133 FormComponentType::GROUPBOX,
2134 FormComponentType::IMAGECONTROL,
2135 FormComponentType::LISTBOX,
2136 FormComponentType::NUMERICFIELD,
2137 FormComponentType::PATTERNFIELD,
2138 FormComponentType::RADIOBUTTON,
2139 FormComponentType::SCROLLBAR,
2140 FormComponentType::SPINBUTTON,
2141 FormComponentType::TIMEFIELD,
2143 ControlType::FIXEDLINE,
2144 ControlType::FORMATTEDFIELD,
2145 ControlType::PROGRESSBAR
2148 sal_Int32 nKnownControlTypes = SAL_N_ELEMENTS( aControlModelServiceNames );
2149 OSL_ENSURE( nKnownControlTypes == SAL_N_ELEMENTS( nClassIDs ),
2150 "FormComponentPropertyHandler::impl_classifyControlModel_throw: inconsistence" );
2152 for ( sal_Int32 i = 0; i < nKnownControlTypes; ++i )
2154 OUString sServiceName( "com.sun.star.awt." );
2155 sServiceName += OUString::createFromAscii( aControlModelServiceNames[ i ] );
2157 if ( xServiceInfo->supportsService( sServiceName ) )
2159 m_nClassId = nClassIDs[ i ];
2160 break;
2167 //------------------------------------------------------------------------
2168 void FormComponentPropertyHandler::impl_normalizePropertyValue_nothrow( Any& _rValue, PropertyId _nPropId ) const
2170 switch ( _nPropId )
2172 case PROPERTY_ID_TABSTOP:
2173 if ( !_rValue.hasValue() )
2175 switch ( m_nClassId )
2177 case FormComponentType::COMMANDBUTTON:
2178 case FormComponentType::RADIOBUTTON:
2179 case FormComponentType::CHECKBOX:
2180 case FormComponentType::TEXTFIELD:
2181 case FormComponentType::LISTBOX:
2182 case FormComponentType::COMBOBOX:
2183 case FormComponentType::FILECONTROL:
2184 case FormComponentType::DATEFIELD:
2185 case FormComponentType::TIMEFIELD:
2186 case FormComponentType::NUMERICFIELD:
2187 case ControlType::FORMATTEDFIELD:
2188 case FormComponentType::CURRENCYFIELD:
2189 case FormComponentType::PATTERNFIELD:
2190 _rValue = makeAny( (sal_Bool)sal_True );
2191 break;
2192 default:
2193 _rValue = makeAny( (sal_Bool)sal_False );
2194 break;
2197 break;
2201 //------------------------------------------------------------------------
2202 bool FormComponentPropertyHandler::impl_shouldExcludeProperty_nothrow( const Property& _rProperty ) const
2204 OSL_ENSURE( _rProperty.Handle == m_pInfoService->getPropertyId( _rProperty.Name ),
2205 "FormComponentPropertyHandler::impl_shouldExcludeProperty_nothrow: insonsistency in the property!" );
2207 if ( _rProperty.Handle == PROPERTY_ID_CONTROLLABEL )
2208 // prevent that this is caught below
2209 return false;
2211 if ( ( _rProperty.Type.getTypeClass() == TypeClass_INTERFACE )
2212 || ( _rProperty.Type.getTypeClass() == TypeClass_ARRAY )
2213 || ( _rProperty.Type.getTypeClass() == TypeClass_UNKNOWN )
2215 return true;
2217 if ( ( _rProperty.Attributes & PropertyAttribute::TRANSIENT ) && ( m_eComponentClass != eDialogControl ) )
2218 // strange enough, dialog controls declare a lot of their properties as transient
2219 return true;
2221 if ( _rProperty.Attributes & PropertyAttribute::READONLY )
2222 return true;
2224 switch ( _rProperty.Handle )
2226 case PROPERTY_ID_MASTERFIELDS:
2227 case PROPERTY_ID_DETAILFIELDS:
2228 if ( !m_bComponentIsSubForm )
2229 // no master and detail fields for forms which are no sub forms
2230 return true;
2231 break;
2233 case PROPERTY_ID_DATASOURCE:
2235 // don't show DataSource if the component is part of an embedded form document
2236 Reference< XConnection > xConn;
2237 if ( isEmbeddedInDatabase( m_xComponent, xConn ) )
2238 return true;
2240 break;
2242 case PROPERTY_ID_TEXT:
2243 // don't show the "Text" property of formatted fields
2244 if ( ControlType::FORMATTEDFIELD == m_nClassId )
2245 return true;
2246 break;
2248 case PROPERTY_ID_FORMATKEY:
2249 case PROPERTY_ID_EFFECTIVE_MIN:
2250 case PROPERTY_ID_EFFECTIVE_MAX:
2251 case PROPERTY_ID_EFFECTIVE_DEFAULT:
2252 case PROPERTY_ID_EFFECTIVE_VALUE:
2253 // only if the set has a formats supplier, too
2254 if ( !impl_componentHasProperty_throw( PROPERTY_FORMATSSUPPLIER ) )
2255 return true;
2256 // (form) date and time fields also have a formats supplier, but the format itself
2257 // is reflected in another property
2258 if ( ( FormComponentType::DATEFIELD == m_nClassId )
2259 || ( FormComponentType::TIMEFIELD == m_nClassId )
2261 return true;
2262 break;
2264 case PROPERTY_ID_SCALEIMAGE:
2265 if ( impl_componentHasProperty_throw( PROPERTY_SCALE_MODE ) )
2266 // ScaleImage is superseded by ScaleMode
2267 return true;
2268 break;
2270 case PROPERTY_ID_WRITING_MODE:
2271 if ( !SvtCTLOptions().IsCTLFontEnabled() )
2272 return true;
2273 break;
2276 sal_uInt32 nPropertyUIFlags = m_pInfoService->getPropertyUIFlags( _rProperty.Handle );
2278 // don't show experimental properties unless allowed to do so
2279 if ( ( nPropertyUIFlags & PROP_FLAG_EXPERIMENTAL ) != 0 )
2281 if ( true ) // TODO
2282 return true;
2285 // no data properties if no Base is installed. #124939#
2286 // This fix is not intendend to appear on the main trunk. If you find it there,
2287 // please tell me! frank.schoenheit@sun.com
2288 if ( ( nPropertyUIFlags & PROP_FLAG_DATA_PROPERTY ) != 0 )
2289 if ( !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
2290 return true;
2292 return false;
2295 //------------------------------------------------------------------------
2296 Reference< XRowSet > FormComponentPropertyHandler::impl_getRowSet_throw( ) const
2298 Reference< XRowSet > xRowSet = m_xRowSet;
2299 if ( !xRowSet.is() )
2301 xRowSet.set( m_xComponent, UNO_QUERY );
2302 if ( !xRowSet.is() )
2304 xRowSet = Reference< XRowSet >( m_xObjectParent, UNO_QUERY );
2305 if ( !xRowSet.is() )
2307 // are we inspecting a grid column?
2308 if (Reference< XGridColumnFactory >( m_xObjectParent, UNO_QUERY) .is())
2309 { // yes
2310 Reference< XChild > xParentAsChild( m_xObjectParent, UNO_QUERY );
2311 if ( xParentAsChild.is() )
2312 xRowSet = Reference< XRowSet >( xParentAsChild->getParent(), UNO_QUERY );
2315 if ( !xRowSet.is() )
2316 xRowSet = m_xRowSet;
2318 DBG_ASSERT( xRowSet.is(), "FormComponentPropertyHandler::impl_getRowSet_throw: could not obtain the rowset for the introspectee!" );
2320 return xRowSet;
2323 //------------------------------------------------------------------------
2324 Reference< XRowSet > FormComponentPropertyHandler::impl_getRowSet_nothrow( ) const
2326 Reference< XRowSet > xReturn;
2329 xReturn = impl_getRowSet_throw();
2331 catch( const Exception& )
2333 OSL_FAIL( "FormComponentPropertyHandler::impl_getRowSet_nothrow: caught an exception!" );
2335 return xReturn;
2338 //------------------------------------------------------------------------
2339 void FormComponentPropertyHandler::impl_initFieldList_nothrow( ::std::vector< OUString >& _rFieldNames ) const
2341 clearContainer( _rFieldNames );
2344 WaitCursor aWaitCursor( impl_getDefaultDialogParent_nothrow() );
2346 Reference< XPreparedStatement > xStatement;
2348 // get the form of the control we're inspecting
2349 Reference< XPropertySet > xFormSet( impl_getRowSet_throw(), UNO_QUERY );
2350 if ( !xFormSet.is() )
2351 return;
2353 OUString sObjectName;
2354 OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_COMMAND ) >>= sObjectName );
2355 // when there is no command we don't need to ask for columns
2356 if ( !sObjectName.isEmpty() && impl_ensureRowsetConnection_nothrow() )
2358 OUString aDatabaseName;
2359 OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_DATASOURCE ) >>= aDatabaseName );
2360 sal_Int32 nObjectType = CommandType::COMMAND;
2361 OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_COMMANDTYPE ) >>= nObjectType );
2363 Sequence< OUString > aFields( ::dbtools::getFieldNamesByCommandDescriptor( m_xRowSetConnection, nObjectType, sObjectName ) );
2365 const OUString* pFields = aFields.getConstArray();
2366 for ( sal_Int32 i = 0; i < aFields.getLength(); ++i, ++pFields )
2367 _rFieldNames.push_back( *pFields );
2370 catch (const Exception&)
2372 OSL_FAIL( "FormComponentPropertyHandler::impl_initFieldList_nothrow: caught an exception!" );
2376 //------------------------------------------------------------------------
2377 void FormComponentPropertyHandler::impl_clearRowsetConnection_nothrow()
2379 m_xRowSetConnection.clear();
2382 //------------------------------------------------------------------------
2383 void FormComponentPropertyHandler::impl_displaySQLError_nothrow( const ::dbtools::SQLExceptionInfo& _rErrorDescriptor ) const
2385 ::dbtools::showError( _rErrorDescriptor, VCLUnoHelper::GetInterface( impl_getDefaultDialogParent_nothrow() ), m_aContext.getUNOContext() );
2388 //------------------------------------------------------------------------
2389 bool FormComponentPropertyHandler::impl_ensureRowsetConnection_nothrow() const
2391 if ( !m_xRowSetConnection.is() )
2393 uno::Reference<sdbc::XConnection> xConnection(m_aContext.getContextValueByAsciiName( "ActiveConnection" ),uno::UNO_QUERY);
2394 m_xRowSetConnection.reset(xConnection,::dbtools::SharedConnection::NoTakeOwnership);
2396 if ( m_xRowSetConnection.is() )
2397 return true;
2399 Reference< XRowSet > xRowSet( impl_getRowSet_throw() );
2400 Reference< XPropertySet > xRowSetProps( xRowSet, UNO_QUERY );
2402 // connect the row set - this is delegated to elsewhere - while observing errors
2403 SQLExceptionInfo aError;
2406 if ( xRowSetProps.is() )
2408 WaitCursor aWaitCursor( impl_getDefaultDialogParent_nothrow() );
2409 m_xRowSetConnection = ::dbtools::ensureRowSetConnection( xRowSet, m_aContext.getUNOContext(), false );
2412 catch ( const SQLException& ) { aError = SQLExceptionInfo( ::cppu::getCaughtException() ); }
2413 catch ( const WrappedTargetException& e ) { aError = SQLExceptionInfo( e.TargetException ); }
2414 catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
2416 // report errors, if necessary
2417 if ( aError.isValid() )
2419 OUString sDataSourceName;
2422 xRowSetProps->getPropertyValue( PROPERTY_DATASOURCE ) >>= sDataSourceName;
2424 catch( const Exception& )
2426 OSL_FAIL( "FormComponentPropertyHandler::impl_ensureRowsetConnection_nothrow: caught an exception during error handling!" );
2428 // additional info about what happended
2429 String sInfo( PcrRes( RID_STR_UNABLETOCONNECT ) );
2430 INetURLObject aParser( sDataSourceName );
2431 if ( aParser.GetProtocol() != INET_PROT_NOT_VALID )
2432 sDataSourceName = aParser.getBase( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
2433 sInfo.SearchAndReplaceAllAscii( "$name$", sDataSourceName );
2435 SQLContext aContext;
2436 aContext.Message = sInfo;
2437 aContext.NextException = aError.get();
2438 impl_displaySQLError_nothrow( aContext );
2441 return m_xRowSetConnection.is();
2444 //------------------------------------------------------------------------
2445 void FormComponentPropertyHandler::impl_describeCursorSource_nothrow( LineDescriptor& _out_rProperty, const Reference< XPropertyControlFactory >& _rxControlFactory ) const
2449 WaitCursor aWaitCursor( impl_getDefaultDialogParent_nothrow() );
2451 ////////////////////////////////////////////////////////////
2452 // Setzen der UI-Daten
2453 _out_rProperty.DisplayName = m_pInfoService->getPropertyTranslation( PROPERTY_ID_COMMAND );
2455 _out_rProperty.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( PROPERTY_ID_COMMAND ) );
2456 _out_rProperty.PrimaryButtonId = OUString::createFromAscii(UID_PROP_DLG_SQLCOMMAND);
2458 ////////////////////////////////////////////////////////////
2459 sal_Int32 nCommandType = CommandType::COMMAND;
2460 impl_getPropertyValue_throw( PROPERTY_COMMANDTYPE ) >>= nCommandType;
2462 switch ( nCommandType )
2464 case CommandType::TABLE:
2465 case CommandType::QUERY:
2467 ::std::vector< OUString > aNames;
2468 if ( impl_ensureRowsetConnection_nothrow() )
2470 if ( nCommandType == CommandType::TABLE )
2471 impl_fillTableNames_throw( aNames );
2472 else
2473 impl_fillQueryNames_throw( aNames );
2475 _out_rProperty.Control = PropertyHandlerHelper::createComboBoxControl( _rxControlFactory, aNames, sal_False, sal_True );
2477 break;
2479 default:
2480 _out_rProperty.Control = _rxControlFactory->createPropertyControl( PropertyControlType::MultiLineTextField, sal_False );
2481 break;
2484 catch (const Exception&)
2486 OSL_FAIL("FormComponentPropertyHandler::impl_describeCursorSource_nothrow: caught an exception !");
2490 //------------------------------------------------------------------------
2491 void FormComponentPropertyHandler::impl_fillTableNames_throw( ::std::vector< OUString >& _out_rNames ) const
2493 OSL_PRECOND( m_xRowSetConnection.is(), "FormComponentPropertyHandler::impl_fillTableNames_throw: need a connection!" );
2494 _out_rNames.resize( 0 );
2496 Reference< XTablesSupplier > xSupplyTables( m_xRowSetConnection, UNO_QUERY );
2497 Reference< XNameAccess > xTableNames;
2498 if ( xSupplyTables.is() )
2499 xTableNames = xSupplyTables->getTables();
2500 DBG_ASSERT( xTableNames.is(), "FormComponentPropertyHandler::impl_fillTableNames_throw: no way to obtain the tables of the connection!" );
2501 if ( !xTableNames.is() )
2502 return;
2504 Sequence< OUString> aTableNames = xTableNames->getElementNames();
2505 sal_uInt32 nCount = aTableNames.getLength();
2506 const OUString* pTableNames = aTableNames.getConstArray();
2508 for ( sal_uInt32 i=0; i<nCount; ++i ,++pTableNames )
2509 _out_rNames.push_back( *pTableNames );
2512 //------------------------------------------------------------------------
2513 void FormComponentPropertyHandler::impl_fillQueryNames_throw( ::std::vector< OUString >& _out_rNames ) const
2515 OSL_PRECOND( m_xRowSetConnection.is(), "FormComponentPropertyHandler::impl_fillQueryNames_throw: need a connection!" );
2516 _out_rNames.resize( 0 );
2518 Reference< XQueriesSupplier > xSupplyQueries( m_xRowSetConnection, UNO_QUERY );
2519 Reference< XNameAccess > xQueryNames;
2520 if ( xSupplyQueries.is() )
2522 xQueryNames = xSupplyQueries->getQueries();
2523 impl_fillQueryNames_throw(xQueryNames,_out_rNames);
2526 //------------------------------------------------------------------------
2527 void FormComponentPropertyHandler::impl_fillQueryNames_throw( const Reference< XNameAccess >& _xQueryNames,::std::vector< OUString >& _out_rNames,const OUString& _sName ) const
2529 DBG_ASSERT( _xQueryNames.is(), "FormComponentPropertyHandler::impl_fillQueryNames_throw: no way to obtain the queries of the connection!" );
2530 if ( !_xQueryNames.is() )
2531 return;
2533 Sequence< OUString> aQueryNames = _xQueryNames->getElementNames();
2534 sal_uInt32 nCount = aQueryNames.getLength();
2535 const OUString* pQueryNames = aQueryNames.getConstArray();
2536 sal_Bool bAdd = !_sName.isEmpty();
2538 for ( sal_uInt32 i=0; i<nCount; i++, ++pQueryNames )
2540 OUStringBuffer sTemp;
2541 if ( bAdd )
2543 sTemp.append(_sName);
2544 sTemp.appendAscii("/");
2546 sTemp.append(*pQueryNames);
2547 Reference< XNameAccess > xSubQueries(_xQueryNames->getByName(*pQueryNames),UNO_QUERY);
2548 if ( xSubQueries.is() )
2549 impl_fillQueryNames_throw(xSubQueries,_out_rNames,sTemp.makeStringAndClear());
2550 else
2551 _out_rNames.push_back( sTemp.makeStringAndClear() );
2555 //------------------------------------------------------------------------
2556 void FormComponentPropertyHandler::impl_describeListSourceUI_throw( LineDescriptor& _out_rDescriptor, const Reference< XPropertyControlFactory >& _rxControlFactory ) const
2558 OSL_PRECOND( m_xComponent.is(), "FormComponentPropertyHandler::impl_describeListSourceUI_throw: no component!" );
2560 ////////////////////////////////////////////////////////////
2561 // Auslesen des ListSourceTypes
2562 Any aListSourceType( m_xComponent->getPropertyValue( PROPERTY_LISTSOURCETYPE ) );
2564 sal_Int32 nListSourceType = ListSourceType_VALUELIST;
2565 ::cppu::enum2int( nListSourceType, aListSourceType );
2567 _out_rDescriptor.DisplayName = m_pInfoService->getPropertyTranslation( PROPERTY_ID_LISTSOURCE );
2568 _out_rDescriptor.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( PROPERTY_ID_LISTSOURCE ) );
2570 ////////////////////////////////////////////////////////////
2571 // Enums setzen
2572 switch( nListSourceType )
2574 case ListSourceType_VALUELIST:
2575 _out_rDescriptor.Control = _rxControlFactory->createPropertyControl( PropertyControlType::StringListField, sal_False );
2576 break;
2578 case ListSourceType_TABLEFIELDS:
2579 case ListSourceType_TABLE:
2580 case ListSourceType_QUERY:
2582 ::std::vector< OUString > aListEntries;
2583 if ( impl_ensureRowsetConnection_nothrow() )
2585 if ( nListSourceType == ListSourceType_QUERY )
2586 impl_fillQueryNames_throw( aListEntries );
2587 else
2588 impl_fillTableNames_throw( aListEntries );
2590 _out_rDescriptor.Control = PropertyHandlerHelper::createComboBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
2592 break;
2593 case ListSourceType_SQL:
2594 case ListSourceType_SQLPASSTHROUGH:
2595 impl_ensureRowsetConnection_nothrow();
2596 _out_rDescriptor.HasPrimaryButton = m_xRowSetConnection.is();
2597 break;
2601 //------------------------------------------------------------------------
2602 bool FormComponentPropertyHandler::impl_dialogListSelection_nothrow( const OUString& _rProperty, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2604 OSL_PRECOND( m_pInfoService.get(), "FormComponentPropertyHandler::impl_dialogListSelection_nothrow: no property meta data!" );
2606 String sPropertyUIName( m_pInfoService->getPropertyTranslation( m_pInfoService->getPropertyId( _rProperty ) ) );
2607 ListSelectionDialog aDialog( impl_getDefaultDialogParent_nothrow(), m_xComponent, _rProperty, sPropertyUIName );
2608 _rClearBeforeDialog.clear();
2609 return ( RET_OK == aDialog.Execute() );
2612 //------------------------------------------------------------------------
2613 bool FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow( bool _bFilter, OUString& _out_rSelectedClause, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2615 OSL_PRECOND( Reference< XRowSet >( m_xComponent, UNO_QUERY ).is(),
2616 "FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow: to be called for forms only!" );
2618 _out_rSelectedClause = OUString();
2619 bool bSuccess = false;
2620 SQLExceptionInfo aErrorInfo;
2623 if ( !impl_ensureRowsetConnection_nothrow() )
2624 return false;
2626 // get a composer for the statement which the form is currently based on
2627 Reference< XSingleSelectQueryComposer > xComposer( ::dbtools::getCurrentSettingsComposer( m_xComponent, m_aContext.getUNOContext() ) );
2628 OSL_ENSURE( xComposer.is(), "FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow: could not obtain a composer!" );
2629 if ( !xComposer.is() )
2630 return false;
2632 OUString sPropertyUIName( m_pInfoService->getPropertyTranslation( _bFilter ? PROPERTY_ID_FILTER : PROPERTY_ID_SORT ) );
2634 // create the dialog
2635 Reference< XExecutableDialog > xDialog;
2636 if ( _bFilter)
2638 xDialog.set( sdb::FilterDialog::createDefault(m_aContext.getUNOContext()) );
2640 else
2642 xDialog.set( sdb::OrderDialog::createDefault(m_aContext.getUNOContext()) );
2646 // initialize the dialog
2647 Reference< XPropertySet > xDialogProps( xDialog, UNO_QUERY_THROW );
2648 xDialogProps->setPropertyValue( OUString( "QueryComposer" ), makeAny( xComposer ) );
2649 xDialogProps->setPropertyValue( OUString( "RowSet" ), makeAny( m_xComponent ) );
2650 xDialogProps->setPropertyValue( OUString( "ParentWindow" ), makeAny( VCLUnoHelper::GetInterface( impl_getDefaultDialogParent_nothrow() ) ) );
2651 xDialogProps->setPropertyValue( OUString( "Title" ), makeAny( sPropertyUIName ) );
2653 _rClearBeforeDialog.clear();
2654 bSuccess = ( xDialog->execute() != 0 );
2655 if ( bSuccess )
2656 _out_rSelectedClause = _bFilter ? xComposer->getFilter() : xComposer->getOrder();
2658 catch (const SQLContext& e) { aErrorInfo = e; }
2659 catch (const SQLWarning& e) { aErrorInfo = e; }
2660 catch (const SQLException& e) { aErrorInfo = e; }
2661 catch( const Exception& )
2663 OSL_FAIL( "FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow: caught an exception!" );
2666 if ( aErrorInfo.isValid() )
2667 impl_displaySQLError_nothrow( aErrorInfo );
2669 return bSuccess;
2672 //------------------------------------------------------------------------
2673 bool FormComponentPropertyHandler::impl_dialogLinkedFormFields_nothrow( ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2675 Reference< XForm > xDetailForm( m_xComponent, UNO_QUERY );
2676 Reference< XForm > xMasterForm( m_xObjectParent, UNO_QUERY );
2677 uno::Reference<beans::XPropertySet> xMasterProp(m_xObjectParent,uno::UNO_QUERY);
2678 OSL_PRECOND( xDetailForm.is() && xMasterForm.is(), "FormComponentPropertyHandler::impl_dialogLinkedFormFields_nothrow: no forms!" );
2679 if ( !xDetailForm.is() || !xMasterForm.is() )
2680 return false;
2683 FormLinkDialog aDialog( impl_getDefaultDialogParent_nothrow(), m_xComponent, xMasterProp, m_aContext.getUNOContext() );
2684 _rClearBeforeDialog.clear();
2685 return ( RET_OK == aDialog.Execute() );
2688 //------------------------------------------------------------------------
2689 bool FormComponentPropertyHandler::impl_dialogFormatting_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2691 bool bChanged = false;
2694 // create the itemset for the dialog
2695 SfxItemSet aCoreSet(SFX_APP()->GetPool(),
2696 SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_VALUE,
2697 SID_ATTR_NUMBERFORMAT_INFO, SID_ATTR_NUMBERFORMAT_INFO,
2698 0); // ripped this somewhere ... don't understand it :(
2700 // get the number formats supplier
2701 Reference< XNumberFormatsSupplier > xSupplier;
2702 m_xComponent->getPropertyValue( PROPERTY_FORMATSSUPPLIER ) >>= xSupplier;
2704 DBG_ASSERT(xSupplier.is(), "FormComponentPropertyHandler::impl_dialogFormatting_nothrow: invalid call !" );
2705 Reference< XUnoTunnel > xTunnel( xSupplier, UNO_QUERY_THROW );
2706 SvNumberFormatsSupplierObj* pSupplier =
2707 reinterpret_cast< SvNumberFormatsSupplierObj* >( xTunnel->getSomething( SvNumberFormatsSupplierObj::getUnoTunnelId() ) );
2708 DBG_ASSERT( pSupplier != NULL, "FormComponentPropertyHandler::impl_dialogFormatting_nothrow: invalid call !" );
2710 sal_Int32 nFormatKey = 0;
2711 impl_getPropertyValue_throw( PROPERTY_FORMATKEY ) >>= nFormatKey;
2712 aCoreSet.Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, nFormatKey ) );
2714 SvNumberFormatter* pFormatter = pSupplier->GetNumberFormatter();
2715 double dPreviewVal = OFormatSampleControl::getPreviewValue(pFormatter,nFormatKey);
2716 SvxNumberInfoItem aFormatter( pFormatter, dPreviewVal, String( PcrRes( RID_STR_TEXT_FORMAT ) ), SID_ATTR_NUMBERFORMAT_INFO );
2717 aCoreSet.Put( aFormatter );
2719 // a tab dialog with a single page
2720 boost::scoped_ptr< SfxSingleTabDialog > xDialog(new SfxSingleTabDialog(impl_getDefaultDialogParent_nothrow(), aCoreSet));
2721 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
2722 DBG_ASSERT( pFact, "CreateFactory fail!" );
2723 ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc( RID_SVXPAGE_NUMBERFORMAT );
2724 if ( !fnCreatePage )
2725 throw RuntimeException(); // caught below
2727 SfxTabPage* pPage = (*fnCreatePage)( xDialog->get_content_area(), aCoreSet );
2728 xDialog->setTabPage( pPage );
2730 _rClearBeforeDialog.clear();
2731 if ( RET_OK == xDialog->Execute() )
2733 const SfxItemSet* pResult = xDialog->GetOutputItemSet();
2735 const SfxPoolItem* pItem = pResult->GetItem( SID_ATTR_NUMBERFORMAT_INFO );
2736 const SvxNumberInfoItem* pInfoItem = dynamic_cast< const SvxNumberInfoItem* >( pItem );
2737 if (pInfoItem && pInfoItem->GetDelCount())
2739 const sal_uInt32* pDeletedKeys = pInfoItem->GetDelArray();
2741 for (sal_uInt16 i=0; i< pInfoItem->GetDelCount(); ++i, ++pDeletedKeys)
2742 pFormatter->DeleteEntry(*pDeletedKeys);
2745 pItem = NULL;
2746 if ( SFX_ITEM_SET == pResult->GetItemState( SID_ATTR_NUMBERFORMAT_VALUE, sal_False, &pItem ) )
2748 _out_rNewValue <<= (sal_Int32)( static_cast< const SfxUInt32Item* >( pItem )->GetValue() );
2749 bChanged = true;
2753 catch( const Exception& )
2755 OSL_FAIL( "FormComponentPropertyHandler::impl_dialogFormatting_nothrow: : caught an exception!" );
2757 return bChanged;
2760 //------------------------------------------------------------------------
2761 bool FormComponentPropertyHandler::impl_browseForImage_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2763 bool bIsLink = true;// reflect the legacy behavior
2764 OUString aStrTrans = m_pInfoService->getPropertyTranslation( PROPERTY_ID_IMAGE_URL );
2766 ::sfx2::FileDialogHelper aFileDlg(
2767 ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW,
2768 SFXWB_GRAPHIC);
2770 aFileDlg.SetTitle(aStrTrans);
2771 // non-linked images ( e.g. those located in the document
2772 // stream ) only if document is available
2773 Reference< XModel > xModel( impl_getContextDocument_nothrow() );
2774 bool bHandleNonLink = false;
2776 Reference< XFilePickerControlAccess > xController(aFileDlg.GetFilePicker(), UNO_QUERY);
2777 DBG_ASSERT(xController.is(), "FormComponentPropertyHandler::impl_browseForImage_nothrow: missing the controller interface on the file picker!");
2778 if (xController.is())
2780 // do a preview by default
2781 xController->setValue(ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0, ::cppu::bool2any(sal_True));
2783 xController->setValue(ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, ::cppu::bool2any(bIsLink));
2784 xController->enableControl(ExtendedFilePickerElementIds::CHECKBOX_LINK, bHandleNonLink );
2788 OUString sCurValue;
2789 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_IMAGE_URL ) >>= sCurValue );
2790 if ( !sCurValue.isEmpty() && !sCurValue.startsWith(GRAPHOBJ_URLPREFIX) )
2792 aFileDlg.SetDisplayDirectory( sCurValue );
2793 // TODO: need to set the display directory _and_ the default name
2796 _rClearBeforeDialog.clear();
2797 bool bSuccess = ( 0 == aFileDlg.Execute() );
2798 if ( bSuccess )
2800 if ( bHandleNonLink && xController.is() )
2802 xController->getValue(ExtendedFilePickerElementIds::CHECKBOX_LINK, 0) >>= bIsLink;
2804 if ( !bIsLink )
2806 Graphic aGraphic;
2807 aFileDlg.GetGraphic( aGraphic );
2809 Reference< graphic::XGraphicObject > xGrfObj = graphic::GraphicObject::create( m_aContext.getUNOContext() );
2810 xGrfObj->setGraphic( aGraphic.GetXGraphic() );
2813 _out_rNewValue <<= xGrfObj;
2816 else
2817 _out_rNewValue <<= (OUString)aFileDlg.GetPath();
2819 return bSuccess;
2822 //------------------------------------------------------------------------
2823 bool FormComponentPropertyHandler::impl_browseForTargetURL_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2825 ::sfx2::FileDialogHelper aFileDlg(
2826 ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION, 0);
2828 OUString sURL;
2829 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_TARGET_URL ) >>= sURL );
2830 INetURLObject aParser( sURL );
2831 if ( INET_PROT_FILE == aParser.GetProtocol() )
2832 // set the initial directory only for file-URLs. Everything else
2833 // is considered to be potentially expensive
2834 aFileDlg.SetDisplayDirectory( sURL );
2836 _rClearBeforeDialog.clear();
2837 bool bSuccess = ( 0 == aFileDlg.Execute() );
2838 if ( bSuccess )
2839 _out_rNewValue <<= (OUString)aFileDlg.GetPath();
2840 return bSuccess;
2843 //------------------------------------------------------------------------
2844 bool FormComponentPropertyHandler::impl_executeFontDialog_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2846 bool bSuccess = false;
2848 // create an item set for use with the dialog
2849 SfxItemSet* pSet = NULL;
2850 SfxItemPool* pPool = NULL;
2851 SfxPoolItem** pDefaults = NULL;
2852 ControlCharacterDialog::createItemSet(pSet, pPool, pDefaults);
2853 ControlCharacterDialog::translatePropertiesToItems(m_xComponent, pSet);
2855 { // do this in an own block. The dialog needs to be destroyed before we call
2856 // destroyItemSet
2857 ControlCharacterDialog aDlg( impl_getDefaultDialogParent_nothrow(), *pSet );
2858 _rClearBeforeDialog.clear();
2859 if ( RET_OK == aDlg.Execute() )
2861 const SfxItemSet* pOut = aDlg.GetOutputItemSet();
2862 if ( pOut )
2864 Sequence< NamedValue > aFontPropertyValues;
2865 ControlCharacterDialog::translateItemsToProperties( *pOut, aFontPropertyValues );
2866 _out_rNewValue <<= aFontPropertyValues;
2867 bSuccess = true;
2872 ControlCharacterDialog::destroyItemSet(pSet, pPool, pDefaults);
2873 return bSuccess;
2876 //------------------------------------------------------------------------
2877 bool FormComponentPropertyHandler::impl_browseForDatabaseDocument_throw( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2879 ::sfx2::FileDialogHelper aFileDlg(
2880 ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION, 0,
2881 OUString("sdatabase"));
2883 OUString sDataSource;
2884 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_DATASOURCE ) >>= sDataSource );
2885 INetURLObject aParser( sDataSource );
2886 if ( INET_PROT_FILE == aParser.GetProtocol() )
2887 // set the initial directory only for file-URLs. Everything else
2888 // is considered to be potentially expensive
2889 aFileDlg.SetDisplayDirectory( sDataSource );
2891 const SfxFilter* pFilter = SfxFilter::GetFilterByName(OUString("StarOffice XML (Base)"));
2892 OSL_ENSURE(pFilter,"Filter: StarOffice XML (Base) could not be found!");
2893 if ( pFilter )
2895 aFileDlg.SetCurrentFilter(pFilter->GetUIName());
2896 //aFileDlg.AddFilter(pFilter->GetFilterName(),pFilter->GetDefaultExtension());
2899 _rClearBeforeDialog.clear();
2900 bool bSuccess = ( 0 == aFileDlg.Execute() );
2901 if ( bSuccess )
2902 _out_rNewValue <<= (OUString)aFileDlg.GetPath();
2903 return bSuccess;
2906 //------------------------------------------------------------------------
2907 bool FormComponentPropertyHandler::impl_dialogColorChooser_throw( sal_Int32 _nColorPropertyId, Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2909 sal_Int32 nColor = 0;
2910 OSL_VERIFY( impl_getPropertyValue_throw( impl_getPropertyNameFromId_nothrow( _nColorPropertyId ) ) >>= nColor );
2911 ::Color aColor( nColor );
2912 SvColorDialog aColorDlg( impl_getDefaultDialogParent_nothrow() );
2913 aColorDlg.SetColor( aColor );
2915 _rClearBeforeDialog.clear();
2916 if ( !aColorDlg.Execute() )
2917 return false;
2919 aColor = aColorDlg.GetColor();
2920 nColor = aColor.GetColor();
2921 _out_rNewValue <<= (sal_Int32)nColor;
2922 return true;
2925 //------------------------------------------------------------------------
2926 bool FormComponentPropertyHandler::impl_dialogChooseLabelControl_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2928 OSelectLabelDialog dlgSelectLabel( impl_getDefaultDialogParent_nothrow(), m_xComponent );
2929 _rClearBeforeDialog.clear();
2930 bool bSuccess = ( RET_OK == dlgSelectLabel.Execute() );
2931 if ( bSuccess )
2932 _out_rNewValue <<= dlgSelectLabel.GetSelected();
2933 return bSuccess;
2936 //------------------------------------------------------------------------
2937 Reference< XControlContainer > FormComponentPropertyHandler::impl_getContextControlContainer_nothrow() const
2939 Reference< XControlContainer > xControlContext(
2940 m_aContext.getContextValueByAsciiName( "ControlContext" ),
2941 UNO_QUERY );
2942 return xControlContext;
2945 //------------------------------------------------------------------------
2946 bool FormComponentPropertyHandler::impl_dialogChangeTabOrder_nothrow( ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2948 OSL_PRECOND( impl_getContextControlContainer_nothrow().is(), "FormComponentPropertyHandler::impl_dialogChangeTabOrder_nothrow: invalid control context!" );
2950 Reference< XTabControllerModel > xTabControllerModel( impl_getRowSet_nothrow(), UNO_QUERY );
2951 TabOrderDialog aDialog(
2952 impl_getDefaultDialogParent_nothrow(),
2953 xTabControllerModel,
2954 impl_getContextControlContainer_nothrow(),
2955 m_aContext.getUNOContext()
2957 _rClearBeforeDialog.clear();
2958 return ( RET_OK == aDialog.Execute() );
2961 //------------------------------------------------------------------------
2962 namespace
2964 //--------------------------------------------------------------------
2965 //- ISQLCommandPropertyUI
2966 //--------------------------------------------------------------------
2967 class ISQLCommandPropertyUI : public ISQLCommandAdapter
2969 public:
2970 /** returns the empty-string-terminated list of names of properties
2971 whose UI is to be disabled while the SQL command property is
2972 being edited.
2974 virtual OUString* getPropertiesToDisable() = 0;
2977 //--------------------------------------------------------------------
2978 //- SQLCommandPropertyUI
2979 //--------------------------------------------------------------------
2980 class SQLCommandPropertyUI : public ISQLCommandPropertyUI
2982 protected:
2983 SQLCommandPropertyUI( const Reference< XPropertySet >& _rxObject )
2984 :m_xObject( _rxObject )
2986 if ( !m_xObject.is() )
2987 throw NullPointerException();
2990 virtual oslInterlockedCount SAL_CALL acquire()
2992 return osl_atomic_increment( &m_refCount );
2995 virtual oslInterlockedCount SAL_CALL release()
2997 if ( 0 == osl_atomic_decrement( &m_refCount ) )
2999 delete this;
3000 return 0;
3002 return m_refCount;
3005 protected:
3006 Reference< XPropertySet > m_xObject;
3008 private:
3009 oslInterlockedCount m_refCount;
3012 //--------------------------------------------------------------------
3013 //- FormSQLCommandUI - declaration
3014 //--------------------------------------------------------------------
3015 class FormSQLCommandUI : public SQLCommandPropertyUI
3017 public:
3018 FormSQLCommandUI( const Reference< XPropertySet >& _rxForm );
3020 // ISQLCommandAdapter
3021 virtual OUString getSQLCommand() const;
3022 virtual sal_Bool getEscapeProcessing() const;
3023 virtual void setSQLCommand( const OUString& _rCommand ) const;
3024 virtual void setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const;
3026 // ISQLCommandPropertyUI
3027 virtual OUString* getPropertiesToDisable();
3030 //--------------------------------------------------------------------
3031 //- FormSQLCommandUI - implementation
3032 //--------------------------------------------------------------------
3033 //....................................................................
3034 FormSQLCommandUI::FormSQLCommandUI( const Reference< XPropertySet >& _rxForm )
3035 :SQLCommandPropertyUI( _rxForm )
3039 //....................................................................
3040 OUString FormSQLCommandUI::getSQLCommand() const
3042 OUString sCommand;
3043 OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_COMMAND ) >>= sCommand );
3044 return sCommand;
3047 //....................................................................
3048 sal_Bool FormSQLCommandUI::getEscapeProcessing() const
3050 sal_Bool bEscapeProcessing( sal_False );
3051 OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bEscapeProcessing );
3052 return bEscapeProcessing;
3055 //....................................................................
3056 void FormSQLCommandUI::setSQLCommand( const OUString& _rCommand ) const
3058 m_xObject->setPropertyValue( PROPERTY_COMMAND, makeAny( _rCommand ) );
3061 //....................................................................
3062 void FormSQLCommandUI::setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const
3064 m_xObject->setPropertyValue( PROPERTY_ESCAPE_PROCESSING, makeAny( _bEscapeProcessing ) );
3067 //....................................................................
3068 OUString* FormSQLCommandUI::getPropertiesToDisable()
3070 static OUString s_aCommandProps[] = {
3071 OUString(PROPERTY_DATASOURCE),
3072 OUString(PROPERTY_COMMAND),
3073 OUString(PROPERTY_COMMANDTYPE),
3074 OUString(PROPERTY_ESCAPE_PROCESSING),
3075 OUString()
3077 return s_aCommandProps;
3079 //--------------------------------------------------------------------
3080 //- ValueListCommandUI - declaration
3081 //--------------------------------------------------------------------
3082 class ValueListCommandUI : public SQLCommandPropertyUI
3084 public:
3085 ValueListCommandUI( const Reference< XPropertySet >& _rxListOrCombo );
3087 // ISQLCommandAdapter
3088 virtual OUString getSQLCommand() const;
3089 virtual sal_Bool getEscapeProcessing() const;
3090 virtual void setSQLCommand( const OUString& _rCommand ) const;
3091 virtual void setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const;
3093 // ISQLCommandPropertyUI
3094 virtual OUString* getPropertiesToDisable();
3095 private:
3096 mutable bool m_bPropertyValueIsList;
3099 //--------------------------------------------------------------------
3100 //- ValueListCommandUI - implementation
3101 //--------------------------------------------------------------------
3102 //....................................................................
3103 ValueListCommandUI::ValueListCommandUI( const Reference< XPropertySet >& _rxListOrCombo )
3104 :SQLCommandPropertyUI( _rxListOrCombo )
3105 ,m_bPropertyValueIsList( false )
3109 //....................................................................
3110 OUString ValueListCommandUI::getSQLCommand() const
3112 OUString sValue;
3113 m_bPropertyValueIsList = false;
3115 // for combo boxes, the property is a mere string
3116 Any aValue( m_xObject->getPropertyValue( PROPERTY_LISTSOURCE ) );
3117 if ( aValue >>= sValue )
3118 return sValue;
3120 Sequence< OUString > aValueList;
3121 if ( aValue >>= aValueList )
3123 m_bPropertyValueIsList = true;
3124 if ( aValueList.getLength() )
3125 sValue = aValueList[0];
3126 return sValue;
3129 OSL_FAIL( "ValueListCommandUI::getSQLCommand: unexpected property type!" );
3130 return sValue;
3133 //....................................................................
3134 sal_Bool ValueListCommandUI::getEscapeProcessing() const
3136 enum ListSourceType eType( ListSourceType_SQL );
3137 OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_LISTSOURCETYPE ) >>= eType );
3138 OSL_ENSURE( ( eType == ListSourceType_SQL ) || ( eType == ListSourceType_SQLPASSTHROUGH ),
3139 "ValueListCommandUI::getEscapeProcessing: unexpected list source type!" );
3140 return ( eType == ListSourceType_SQL );
3143 //....................................................................
3144 void ValueListCommandUI::setSQLCommand( const OUString& _rCommand ) const
3146 Any aValue;
3147 if ( m_bPropertyValueIsList )
3148 aValue <<= Sequence< OUString >( &_rCommand, 1 );
3149 else
3150 aValue <<= _rCommand;
3151 m_xObject->setPropertyValue( PROPERTY_LISTSOURCE, aValue );
3154 //....................................................................
3155 void ValueListCommandUI::setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const
3157 m_xObject->setPropertyValue( PROPERTY_LISTSOURCETYPE, makeAny(
3158 _bEscapeProcessing ? ListSourceType_SQL : ListSourceType_SQLPASSTHROUGH ) );
3161 //....................................................................
3162 OUString* ValueListCommandUI::getPropertiesToDisable()
3164 static OUString s_aListSourceProps[] = {
3165 OUString(PROPERTY_LISTSOURCETYPE),
3166 OUString(PROPERTY_LISTSOURCE),
3167 OUString()
3169 return s_aListSourceProps;
3173 //------------------------------------------------------------------------
3174 bool FormComponentPropertyHandler::impl_doDesignSQLCommand_nothrow( const Reference< XObjectInspectorUI >& _rxInspectorUI, PropertyId _nDesignForProperty )
3178 if ( m_xCommandDesigner.is() )
3180 if ( m_xCommandDesigner->isActive() )
3182 m_xCommandDesigner->raise();
3183 return true;
3185 m_xCommandDesigner->dispose();
3186 m_xCommandDesigner.set( NULL );
3189 if ( !impl_ensureRowsetConnection_nothrow() )
3190 return false;
3192 Reference< XPropertySet > xComponentProperties( m_xComponent, UNO_QUERY_THROW );
3194 ::rtl::Reference< ISQLCommandPropertyUI > xCommandUI;
3195 switch ( _nDesignForProperty )
3197 case PROPERTY_ID_COMMAND:
3198 xCommandUI = new FormSQLCommandUI( xComponentProperties );
3199 break;
3200 case PROPERTY_ID_LISTSOURCE:
3201 xCommandUI = new ValueListCommandUI( xComponentProperties );
3202 break;
3203 default:
3204 OSL_FAIL( "FormComponentPropertyHandler::OnDesignerClosed: invalid property id!" );
3205 return false;
3208 m_xCommandDesigner.set( new SQLCommandDesigner( m_aContext.getUNOContext(), xCommandUI.get(), m_xRowSetConnection, LINK( this, FormComponentPropertyHandler, OnDesignerClosed ) ) );
3210 DBG_ASSERT( _rxInspectorUI.is(), "FormComponentPropertyHandler::OnDesignerClosed: no access to the property browser ui!" );
3211 if ( m_xCommandDesigner->isActive() && _rxInspectorUI.is() )
3213 m_xBrowserUI = _rxInspectorUI;
3214 // disable everything which would affect this property
3215 const OUString* pToDisable = xCommandUI->getPropertiesToDisable();
3216 while ( !pToDisable->isEmpty() )
3218 m_xBrowserUI->enablePropertyUIElements( *pToDisable++, PropertyLineElement::All, sal_False );
3221 // but enable the browse button for the property itself - so it can be used to raise the query designer
3222 OUString sPropertyName( impl_getPropertyNameFromId_nothrow( _nDesignForProperty ) );
3223 m_xBrowserUI->enablePropertyUIElements( sPropertyName, PropertyLineElement::PrimaryButton, sal_True );
3226 catch( const Exception& )
3228 DBG_UNHANDLED_EXCEPTION();
3230 return m_xCommandDesigner.is();
3233 //------------------------------------------------------------------------
3234 IMPL_LINK( FormComponentPropertyHandler, OnDesignerClosed, void*, /*NOTINTERESTEDIN*/ )
3236 OSL_ENSURE( m_xBrowserUI.is() && m_xCommandDesigner.is(), "FormComponentPropertyHandler::OnDesignerClosed: too many NULLs!" );
3237 if ( m_xBrowserUI.is() && m_xCommandDesigner.is() )
3241 ::rtl::Reference< ISQLCommandPropertyUI > xCommandUI(
3242 dynamic_cast< ISQLCommandPropertyUI* >( m_xCommandDesigner->getPropertyAdapter().get() ) );
3243 if ( !xCommandUI.is() )
3244 throw NullPointerException();
3246 const OUString* pToEnable = xCommandUI->getPropertiesToDisable();
3247 while ( !pToEnable->isEmpty() )
3249 m_xBrowserUI->enablePropertyUIElements( *pToEnable++, PropertyLineElement::All, sal_True );
3252 catch( const Exception& )
3254 DBG_UNHANDLED_EXCEPTION();
3258 return 0L;
3261 //------------------------------------------------------------------------
3262 bool FormComponentPropertyHandler::impl_hasValidDataSourceSignature_nothrow( const Reference< XPropertySet >& _xFormProperties, bool _bAllowEmptyDataSourceName ) SAL_THROW(())
3264 bool bHas = false;
3265 if ( _xFormProperties.is() )
3269 OUString sPropertyValue;
3270 // first, we need the name of an existent data source
3271 if ( _xFormProperties->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATASOURCE) )
3272 _xFormProperties->getPropertyValue( PROPERTY_DATASOURCE ) >>= sPropertyValue;
3273 bHas = ( !sPropertyValue.isEmpty() ) || _bAllowEmptyDataSourceName;
3275 // then, the command should not be empty
3276 if ( bHas )
3278 if ( _xFormProperties->getPropertySetInfo()->hasPropertyByName(PROPERTY_COMMAND) )
3279 _xFormProperties->getPropertyValue( PROPERTY_COMMAND ) >>= sPropertyValue;
3280 bHas = !sPropertyValue.isEmpty();
3283 catch( const Exception& )
3285 OSL_FAIL( "FormComponentPropertyHandler::impl_hasValidDataSourceSignature_nothrow: caught an exception!" );
3288 return bHas;
3290 //------------------------------------------------------------------------
3291 OUString FormComponentPropertyHandler::impl_getDocumentURL_nothrow() const
3293 OUString sURL;
3296 Reference< XModel > xDocument( impl_getContextDocument_nothrow() );
3297 if ( xDocument.is() )
3298 sURL = xDocument->getURL();
3300 catch( const Exception& )
3302 DBG_UNHANDLED_EXCEPTION();
3304 return sURL;
3306 // -------------------------------------------------------------------------
3307 ::cppu::IPropertyArrayHelper* FormComponentPropertyHandler::createArrayHelper( ) const
3309 uno::Sequence< beans::Property > aProps;
3310 describeProperties(aProps);
3311 return new ::cppu::OPropertyArrayHelper(aProps);
3314 // -------------------------------------------------------------------------
3315 ::cppu::IPropertyArrayHelper & FormComponentPropertyHandler::getInfoHelper()
3317 return *const_cast<FormComponentPropertyHandler*>(this)->getArrayHelper();
3319 // -----------------------------------------------------------------------------
3320 uno::Reference< beans::XPropertySetInfo > SAL_CALL FormComponentPropertyHandler::getPropertySetInfo( ) throw(uno::RuntimeException)
3322 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
3325 //........................................................................
3326 } // namespace pcr
3327 //........................................................................
3329 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */