Update ooo320-m1
[ooovba.git] / extensions / source / propctrlr / formcomponenthandler.cxx
blobb12854b036edb15bb6d7f091ac6e7cb94f328fb0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: formcomponenthandler.cxx,v $
10 * $Revision: 1.18 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
34 #include "controltype.hxx"
35 #include "extensio.hrc"
36 #include "fontdialog.hxx"
37 #include "formcomponenthandler.hxx"
38 #include "formlinkdialog.hxx"
39 #include "formmetadata.hxx"
40 #include "formresid.hrc"
41 #include "formstrings.hxx"
42 #include "handlerhelper.hxx"
43 #include "listselectiondlg.hxx"
44 #include "pcrcommon.hxx"
45 #include "selectlabeldialog.hxx"
46 #include "taborder.hxx"
47 #include "usercontrol.hxx"
49 /** === begin UNO includes === **/
50 #include <com/sun/star/lang/NullPointerException.hpp>
51 #include <com/sun/star/awt/XControlModel.hpp>
52 #include <com/sun/star/lang/XServiceInfo.hpp>
53 #include <com/sun/star/form/FormComponentType.hpp>
54 #include <com/sun/star/beans/PropertyAttribute.hpp>
55 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
56 #include <com/sun/star/container/XNameAccess.hpp>
57 #include <com/sun/star/form/XForm.hpp>
58 #include <com/sun/star/container/XChild.hpp>
59 #include <com/sun/star/sdbc/XConnection.hpp>
60 #include <com/sun/star/sdb/CommandType.hpp>
61 #include <com/sun/star/form/XGridColumnFactory.hpp>
62 #include <com/sun/star/sdb/SQLContext.hpp>
63 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
64 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
65 #include <com/sun/star/form/ListSourceType.hpp>
66 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
67 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
68 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
69 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
70 #include <com/sun/star/awt/XTabControllerModel.hpp>
71 #include <com/sun/star/form/FormSubmitEncoding.hpp>
72 #include <com/sun/star/awt/VisualEffect.hpp>
73 #include <com/sun/star/form/FormButtonType.hpp>
74 #include <com/sun/star/inspection/PropertyControlType.hpp>
75 #include <com/sun/star/util/MeasureUnit.hpp>
76 #include <com/sun/star/inspection/XObjectInspectorUI.hpp>
77 #include <com/sun/star/inspection/PropertyLineElement.hpp>
78 #include <com/sun/star/resource/XStringResourceManager.hpp>
79 #include <com/sun/star/resource/MissingResourceException.hpp>
80 #include <com/sun/star/graphic/GraphicObject.hpp>
81 #include <com/sun/star/text/WritingMode2.hpp>
82 /** === end UNO includes === **/
84 #include <comphelper/extract.hxx>
85 #include <connectivity/dbconversion.hxx>
86 #include <connectivity/dbexception.hxx>
87 #include <cppuhelper/exc_hlp.hxx>
88 #include <sfx2/app.hxx>
89 #include <sfx2/basedlgs.hxx>
90 #include <sfx2/docfilt.hxx>
91 #include <sfx2/filedlghelper.hxx>
92 #include <svtools/ctloptions.hxx>
93 #include <svtools/colrdlg.hxx>
94 #include <svtools/filenotation.hxx>
95 #include <svtools/intitem.hxx>
96 #include <svtools/itemset.hxx>
97 #include <svtools/moduleoptions.hxx>
98 #include <svtools/numuno.hxx>
99 #include <svtools/urihelper.hxx>
100 #include <svx/dialogs.hrc>
101 #include <svx/numinf.hxx>
102 #include <svx/svxdlg.hxx>
103 #include <svx/svxids.hrc>
104 #include <toolkit/helper/vclunohelper.hxx>
105 #include <tools/diagnose_ex.h>
106 #include <vcl/msgbox.hxx>
107 #include <vcl/stdtext.hxx>
108 #include <vcl/wrkwin.hxx>
109 #include <tools/StringListResource.hxx>
111 #include <limits>
113 #define GRAPHOBJ_URLPREFIX "vnd.sun.star.GraphicObject:"
114 //------------------------------------------------------------------------
115 extern "C" void SAL_CALL createRegistryInfo_FormComponentPropertyHandler()
117 ::pcr::FormComponentPropertyHandler::registerImplementation();
120 //........................................................................
121 namespace pcr
123 //........................................................................
125 using namespace ::com::sun::star;
126 using namespace uno;
127 using namespace lang;
128 using namespace beans;
129 using namespace frame;
130 using namespace script;
131 using namespace form;
132 using namespace util;
133 using namespace awt;
134 using namespace sdb;
135 using namespace sdbc;
136 using namespace sdbcx;
137 using namespace form;
138 using namespace container;
139 using namespace ui::dialogs;
140 using namespace inspection;
141 using namespace ::dbtools;
143 namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
145 //====================================================================
146 //= FormComponentPropertyHandler
147 //====================================================================
148 DBG_NAME( FormComponentPropertyHandler )
149 #define PROPERTY_ID_ROWSET 1
150 //--------------------------------------------------------------------
151 FormComponentPropertyHandler::FormComponentPropertyHandler( const Reference< XComponentContext >& _rxContext )
152 :FormComponentPropertyHandler_Base( _rxContext )
153 ,::comphelper::OPropertyContainer(FormComponentPropertyHandler_Base::rBHelper)
154 ,m_sDefaultValueString( String( PcrRes( RID_STR_STANDARD ) ) )
155 ,m_eComponentClass( eUnknown )
156 ,m_bComponentIsSubForm( false )
157 ,m_bHaveListSource( false )
158 ,m_bHaveCommand( false )
159 ,m_nClassId( 0 )
161 DBG_CTOR( FormComponentPropertyHandler, NULL );
162 registerProperty(PROPERTY_ROWSET,PROPERTY_ID_ROWSET,0,&m_xRowSet,::getCppuType(&m_xRowSet));
165 //--------------------------------------------------------------------
166 FormComponentPropertyHandler::~FormComponentPropertyHandler()
168 DBG_DTOR( FormComponentPropertyHandler, NULL );
170 //--------------------------------------------------------------------
171 IMPLEMENT_FORWARD_XINTERFACE2(FormComponentPropertyHandler,FormComponentPropertyHandler_Base,::comphelper::OPropertyContainer)
172 //--------------------------------------------------------------------
173 ::rtl::OUString SAL_CALL FormComponentPropertyHandler::getImplementationName_static( ) throw (RuntimeException)
175 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.FormComponentPropertyHandler" ) );
178 //--------------------------------------------------------------------
179 Sequence< ::rtl::OUString > SAL_CALL FormComponentPropertyHandler::getSupportedServiceNames_static( ) throw (RuntimeException)
181 Sequence< ::rtl::OUString > aSupported( 1 );
182 aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.inspection.FormComponentPropertyHandler" ) );
183 return aSupported;
186 //============================================
187 // TODO: -> export from toolkit
188 struct LanguageDependentProp
190 const char* pPropName;
191 sal_Int32 nPropNameLength;
194 static LanguageDependentProp aLanguageDependentProp[] =
196 { "Text", 4 },
197 { "Label", 5 },
198 { "Title", 5 },
199 { "HelpText", 8 },
200 { "CurrencySymbol", 14 },
201 { "StringItemList", 14 },
202 { 0, 0 }
205 namespace
207 bool lcl_isLanguageDependentProperty( ::rtl::OUString aName )
209 bool bRet = false;
211 LanguageDependentProp* pLangDepProp = aLanguageDependentProp;
212 while( pLangDepProp->pPropName != 0 )
214 if( aName.equalsAsciiL( pLangDepProp->pPropName, pLangDepProp->nPropNameLength ))
216 bRet = true;
217 break;
219 pLangDepProp++;
221 return bRet;
224 Reference< resource::XStringResourceResolver > lcl_getStringResourceResolverForProperty
225 ( Reference< XPropertySet > _xComponent, const ::rtl::OUString& _rPropertyName,
226 const Any& _rPropertyValue )
228 Reference< resource::XStringResourceResolver > xRet;
229 const TypeClass eType = _rPropertyValue.getValueType().getTypeClass();
230 if ( (eType == TypeClass_STRING || eType == TypeClass_SEQUENCE) &&
231 lcl_isLanguageDependentProperty( _rPropertyName ) )
233 static const ::rtl::OUString s_sResourceResolverPropName(RTL_CONSTASCII_USTRINGPARAM("ResourceResolver"));
235 Reference< resource::XStringResourceResolver > xStringResourceResolver;
238 xStringResourceResolver.set( _xComponent->getPropertyValue( s_sResourceResolverPropName ),UNO_QUERY);
239 if( xStringResourceResolver.is() &&
240 xStringResourceResolver->getLocales().getLength() > 0 )
242 xRet = xStringResourceResolver;
245 catch(UnknownPropertyException&)
247 // nii
251 return xRet;
255 //--------------------------------------------------------------------
256 Any FormComponentPropertyHandler::impl_getPropertyValue_throw( const ::rtl::OUString& _rPropertyName ) const
258 const PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
260 Any aPropertyValue( m_xComponent->getPropertyValue( _rPropertyName ) );
262 Reference< resource::XStringResourceResolver > xStringResourceResolver
263 = lcl_getStringResourceResolverForProperty( m_xComponent, _rPropertyName, aPropertyValue );
264 if( xStringResourceResolver.is() )
266 TypeClass eType = aPropertyValue.getValueType().getTypeClass();
267 if( eType == TypeClass_STRING )
269 ::rtl::OUString aPropStr;
270 aPropertyValue >>= aPropStr;
271 if( aPropStr.getLength() > 1 )
273 ::rtl::OUString aPureIdStr = aPropStr.copy( 1 );
274 if( xStringResourceResolver->hasEntryForId( aPureIdStr ) )
276 ::rtl::OUString aResourceStr = xStringResourceResolver->resolveString( aPureIdStr );
277 aPropertyValue <<= aResourceStr;
281 // StringItemList?
282 else if( eType == TypeClass_SEQUENCE )
284 Sequence< ::rtl::OUString > aStrings;
285 aPropertyValue >>= aStrings;
287 const ::rtl::OUString* pStrings = aStrings.getConstArray();
288 sal_Int32 nCount = aStrings.getLength();
290 Sequence< ::rtl::OUString > aResolvedStrings;
291 aResolvedStrings.realloc( nCount );
292 ::rtl::OUString* pResolvedStrings = aResolvedStrings.getArray();
295 for ( sal_Int32 i = 0; i < nCount; ++i )
297 ::rtl::OUString aIdStr = pStrings[i];
298 ::rtl::OUString aPureIdStr = aIdStr.copy( 1 );
299 if( xStringResourceResolver->hasEntryForId( aPureIdStr ) )
300 pResolvedStrings[i] = xStringResourceResolver->resolveString( aPureIdStr );
301 else
302 pResolvedStrings[i] = aIdStr;
305 catch( resource::MissingResourceException & )
307 aPropertyValue <<= aResolvedStrings;
310 else
311 impl_normalizePropertyValue_nothrow( aPropertyValue, nPropId );
313 return aPropertyValue;
316 //--------------------------------------------------------------------
317 Any SAL_CALL FormComponentPropertyHandler::getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
319 if( _rPropertyName == PROPERTY_ROWSET )
320 return ::comphelper::OPropertyContainer::getPropertyValue( _rPropertyName );
322 ::osl::MutexGuard aGuard( m_aMutex );
323 return impl_getPropertyValue_throw( _rPropertyName );
326 //--------------------------------------------------------------------
327 void SAL_CALL FormComponentPropertyHandler::setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw (UnknownPropertyException, RuntimeException)
329 if( _rPropertyName == PROPERTY_ROWSET )
331 ::comphelper::OPropertyContainer::setPropertyValue( _rPropertyName, _rValue );
332 return;
335 ::osl::MutexGuard aGuard( m_aMutex );
336 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) ); // check if property is known by the handler
338 Reference< graphic::XGraphicObject > xGrfObj;
339 if ( PROPERTY_ID_IMAGE_URL == nPropId && ( _rValue >>= xGrfObj ) )
341 DBG_ASSERT( xGrfObj.is(), "FormComponentPropertyHandler::setPropertyValue() xGrfObj is invalid");
342 rtl::OUString sObjectID( RTL_CONSTASCII_USTRINGPARAM( GRAPHOBJ_URLPREFIX ) );
343 sObjectID = sObjectID + xGrfObj->getUniqueID();
344 m_xComponent->setPropertyValue( _rPropertyName, uno::makeAny( sObjectID ) );
346 else if ( PROPERTY_ID_FONT == nPropId )
348 // special handling, the value is a faked value we generated ourself in impl_executeFontDialog_nothrow
349 Sequence< NamedValue > aFontPropertyValues;
350 OSL_VERIFY( _rValue >>= aFontPropertyValues );
351 const NamedValue* fontPropertyValue = aFontPropertyValues.getConstArray();
352 const NamedValue* fontPropertyValueEnd = fontPropertyValue + aFontPropertyValues.getLength();
353 for ( ; fontPropertyValue != fontPropertyValueEnd; ++fontPropertyValue )
354 m_xComponent->setPropertyValue( fontPropertyValue->Name, fontPropertyValue->Value );
356 else
358 Any aValue = _rValue;
360 Reference< resource::XStringResourceResolver > xStringResourceResolver
361 = lcl_getStringResourceResolverForProperty( m_xComponent, _rPropertyName, _rValue );
362 if( xStringResourceResolver.is() )
364 Reference< resource::XStringResourceManager >
365 xStringResourceManager( xStringResourceResolver, UNO_QUERY );
366 if( xStringResourceManager.is() )
368 Any aPropertyValue( m_xComponent->getPropertyValue( _rPropertyName ) );
369 TypeClass eType = aPropertyValue.getValueType().getTypeClass();
370 if( eType == TypeClass_STRING )
372 ::rtl::OUString aPropStr;
373 aPropertyValue >>= aPropStr;
374 if( aPropStr.getLength() > 1 )
376 ::rtl::OUString aPureIdStr = aPropStr.copy( 1 );
377 ::rtl::OUString aValueStr;
378 _rValue >>= aValueStr;
379 xStringResourceManager->setString( aPureIdStr, aValueStr );
380 aValue = aPropertyValue; // set value to force modified
383 // StringItemList?
384 else if( eType == TypeClass_SEQUENCE )
386 static ::rtl::OUString aDot = ::rtl::OUString::createFromAscii( "." );
387 static ::rtl::OUString aEsc = ::rtl::OUString::createFromAscii( "&" );
389 // Put strings into resource using new ids
390 Sequence< ::rtl::OUString > aNewStrings;
391 _rValue >>= aNewStrings;
393 const ::rtl::OUString* pNewStrings = aNewStrings.getConstArray();
394 sal_Int32 nNewCount = aNewStrings.getLength();
396 // Create new Ids
397 ::rtl::OUString* pNewPureIds = new ::rtl::OUString[nNewCount];
398 ::rtl::OUString aIdStrBase = aDot;
399 Any aNameAny = m_xComponent->getPropertyValue(PROPERTY_NAME);
400 ::rtl::OUString sControlName;
401 aNameAny >>= sControlName;
402 aIdStrBase += sControlName;
403 aIdStrBase += aDot;
404 aIdStrBase += _rPropertyName;
405 sal_Int32 i;
406 ::rtl::OUString aDummyStr;
407 for ( i = 0; i < nNewCount; ++i )
409 sal_Int32 nUniqueId = xStringResourceManager->getUniqueNumericId();
410 ::rtl::OUString aPureIdStr = ::rtl::OUString::valueOf( nUniqueId );
411 aPureIdStr += aIdStrBase;
412 pNewPureIds[i] = aPureIdStr;
413 // Force usage of next Unique Id
414 xStringResourceManager->setString( aPureIdStr, aDummyStr );
417 // Move strings to new Ids for all locales
418 Sequence< Locale > aLocaleSeq = xStringResourceManager->getLocales();
419 const Locale* pLocale = aLocaleSeq.getConstArray();
420 sal_Int32 nLocaleCount = aLocaleSeq.getLength();
421 Sequence< ::rtl::OUString > aOldIdStrings;
422 aPropertyValue >>= aOldIdStrings;
425 const ::rtl::OUString* pOldIdStrings = aOldIdStrings.getConstArray();
426 sal_Int32 nOldIdCount = aOldIdStrings.getLength();
427 for ( i = 0; i < nNewCount; ++i )
429 ::rtl::OUString aOldIdStr;
430 ::rtl::OUString aOldPureIdStr;
431 if( i < nOldIdCount )
433 aOldIdStr = pOldIdStrings[i];
434 aOldPureIdStr = aOldIdStr.copy( 1 );
436 ::rtl::OUString aNewPureIdStr = pNewPureIds[i];
438 for ( sal_Int32 iLocale = 0; iLocale < nLocaleCount; ++iLocale )
440 Locale aLocale = pLocale[iLocale];
442 ::rtl::OUString aResourceStr;
443 if( aOldPureIdStr.getLength() != 0 )
445 if( xStringResourceManager->hasEntryForIdAndLocale( aOldPureIdStr, aLocale ) )
447 aResourceStr = xStringResourceManager->
448 resolveStringForLocale( aOldPureIdStr, aLocale );
451 xStringResourceManager->setStringForLocale( aNewPureIdStr, aResourceStr, aLocale );
455 catch( resource::MissingResourceException & )
459 // Set new strings for current locale and create
460 // new Id sequence as new property value
461 Sequence< ::rtl::OUString > aNewIdStrings;
462 aNewIdStrings.realloc( nNewCount );
463 ::rtl::OUString* pNewIdStrings = aNewIdStrings.getArray();
464 for ( i = 0; i < nNewCount; ++i )
466 ::rtl::OUString aPureIdStr = pNewPureIds[i];
467 ::rtl::OUString aStr = pNewStrings[i];
468 xStringResourceManager->setString( aPureIdStr, aStr );
470 ::rtl::OUString aIdStr = aEsc;
471 aIdStr += aPureIdStr;
472 pNewIdStrings[i] = aIdStr;
474 aValue <<= aNewIdStrings;
476 // Remove old ids from resource for all locales
477 const ::rtl::OUString* pOldIdStrings = aOldIdStrings.getConstArray();
478 sal_Int32 nOldIdCount = aOldIdStrings.getLength();
479 for( i = 0 ; i < nOldIdCount ; ++i )
481 ::rtl::OUString aIdStr = pOldIdStrings[i];
482 ::rtl::OUString aPureIdStr = aIdStr.copy( 1 );
483 for ( sal_Int32 iLocale = 0; iLocale < nLocaleCount; ++iLocale )
485 Locale aLocale = pLocale[iLocale];
488 xStringResourceManager->removeIdForLocale( aPureIdStr, aLocale );
490 catch( resource::MissingResourceException & )
494 delete[] pNewPureIds;
499 m_xComponent->setPropertyValue( _rPropertyName, aValue );
503 //--------------------------------------------------------------------
504 Any SAL_CALL FormComponentPropertyHandler::convertToPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rControlValue ) throw (UnknownPropertyException, RuntimeException)
506 ::osl::MutexGuard aGuard( m_aMutex );
507 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
508 Property aProperty( impl_getPropertyFromId_throw( nPropId ) );
510 Any aPropertyValue( _rControlValue );
511 if ( !aPropertyValue.hasValue() )
513 if ( ( aProperty.Attributes & PropertyAttribute::MAYBEVOID ) == 0 )
514 // default construct an instance of the proper type
515 aPropertyValue = Any( NULL, aProperty.Type );
516 // nothing to do
517 return aPropertyValue;
520 /// care for the special "default" string, translate it to VOID
521 if ( m_aPropertiesWithDefListEntry.find( _rPropertyName ) != m_aPropertiesWithDefListEntry.end() )
523 // it's a control with a string list
524 ::rtl::OUString sStringValue;
525 if ( _rControlValue >>= sStringValue )
526 { // note that ColorListBoxes might transfer values either as string or as css.util.Color,
527 // so this check here is important
528 if ( sStringValue == m_sDefaultValueString )
529 return Any();
533 switch ( nPropId )
535 case PROPERTY_ID_DATASOURCE:
537 ::rtl::OUString sControlValue;
538 OSL_VERIFY( _rControlValue >>= sControlValue );
540 if ( sControlValue.getLength() )
542 Reference< XNameAccess > xDatabaseContext;
543 m_aContext.createComponent( (::rtl::OUString)SERVICE_DATABASE_CONTEXT, xDatabaseContext );
544 if ( !xDatabaseContext.is() || !xDatabaseContext->hasByName( sControlValue ) )
546 ::svt::OFileNotation aTransformer(sControlValue);
547 aPropertyValue <<= ::rtl::OUString( aTransformer.get( ::svt::OFileNotation::N_URL ) );
551 break; // case PROPERTY_ID_DATASOURCE
553 case PROPERTY_ID_SHOW_POSITION:
554 case PROPERTY_ID_SHOW_NAVIGATION:
555 case PROPERTY_ID_SHOW_RECORDACTIONS:
556 case PROPERTY_ID_SHOW_FILTERSORT:
558 ::rtl::OUString sControlValue;
559 OSL_VERIFY( _rControlValue >>= sControlValue );
561 ::std::vector< ::rtl::OUString > aListEntries;
562 tools::StringListResource aRes( PcrRes( RID_RSC_ENUM_SHOWHIDE ), aListEntries );
563 OSL_ENSURE( aListEntries.size() == 2, "FormComponentPropertyHandler::convertToPropertyValue: broken resource for Show/Hide!" );
564 sal_Bool bShow = ( aListEntries.size() < 2 ) || ( sControlValue == aListEntries[1] );
566 aPropertyValue <<= bShow;
568 break;
570 case PROPERTY_ID_TARGET_URL:
571 case PROPERTY_ID_IMAGE_URL:
573 ::rtl::OUString sControlValue;
574 OSL_VERIFY( _rControlValue >>= sControlValue );
575 // Don't convert a placeholder
576 if ( nPropId == PROPERTY_ID_IMAGE_URL && sControlValue.equals( String( PcrRes( RID_EMBED_IMAGE_PLACEHOLDER ) ) ) )
577 aPropertyValue <<= sControlValue;
578 else
580 INetURLObject aDocURL( impl_getDocumentURL_nothrow() );
581 aPropertyValue <<= (::rtl::OUString)URIHelper::SmartRel2Abs( aDocURL, sControlValue, Link(), false, true, INetURLObject::WAS_ENCODED, INetURLObject::DECODE_TO_IURI );
584 break;
586 case PROPERTY_ID_DATEMIN:
587 case PROPERTY_ID_DATEMAX:
588 case PROPERTY_ID_DEFAULT_DATE:
589 case PROPERTY_ID_DATE:
591 util::Date aDate;
592 OSL_VERIFY( _rControlValue >>= aDate );
593 aPropertyValue <<= (sal_Int32)DBTypeConversion::toINT32( aDate );
595 break;
597 case PROPERTY_ID_TIMEMIN:
598 case PROPERTY_ID_TIMEMAX:
599 case PROPERTY_ID_DEFAULT_TIME:
600 case PROPERTY_ID_TIME:
602 util::Time aTime;
603 OSL_VERIFY( _rControlValue >>= aTime );
604 aPropertyValue <<= (sal_Int32)DBTypeConversion::toINT32( aTime );
606 break;
608 case PROPERTY_ID_WRITING_MODE:
610 aPropertyValue = FormComponentPropertyHandler_Base::convertToPropertyValue( _rPropertyName, _rControlValue );
612 sal_Int16 nNormalizedValue( 2 );
613 OSL_VERIFY( aPropertyValue >>= nNormalizedValue );
614 sal_Int16 nWritingMode = WritingMode2::CONTEXT;
615 switch ( nNormalizedValue )
617 case 0: nWritingMode = WritingMode2::LR_TB; break;
618 case 1: nWritingMode = WritingMode2::RL_TB; break;
619 case 2: nWritingMode = WritingMode2::CONTEXT; break;
620 default:
621 OSL_ENSURE( false, "FormComponentPropertyHandler::convertToPropertyValue: unexpected 'normalized value' for WritingMode!" );
622 nWritingMode = WritingMode2::CONTEXT;
623 break;
626 aPropertyValue <<= nWritingMode;
628 break;
630 default:
631 aPropertyValue = FormComponentPropertyHandler_Base::convertToPropertyValue( _rPropertyName, _rControlValue );
632 break; // default
634 } // switch ( nPropId )
636 return aPropertyValue;
639 //--------------------------------------------------------------------
640 Any SAL_CALL FormComponentPropertyHandler::convertToControlValue( const ::rtl::OUString& _rPropertyName, const Any& _rPropertyValue, const Type& _rControlValueType ) throw (UnknownPropertyException, RuntimeException)
642 ::osl::MutexGuard aGuard( m_aMutex );
643 sal_Int32 nPropId = m_pInfoService->getPropertyId( _rPropertyName );
644 DBG_ASSERT( nPropId != -1, "FormComponentPropertyHandler::convertToPropertyValue: not one of my properties!!" );
646 Property aProperty( impl_getPropertyFromId_throw( nPropId ) );
648 Any aControlValue( _rPropertyValue );
649 if ( !aControlValue.hasValue() )
651 // if the property is represented with a list box or color list box, we need to
652 // translate this into the string "Default"
653 if ( m_aPropertiesWithDefListEntry.find( _rPropertyName ) != m_aPropertiesWithDefListEntry.end() )
654 aControlValue <<= m_sDefaultValueString;
656 return aControlValue;
659 switch ( nPropId )
661 //////////////////////////////////////////////////////////////
662 case PROPERTY_ID_SHOW_POSITION:
663 case PROPERTY_ID_SHOW_NAVIGATION:
664 case PROPERTY_ID_SHOW_RECORDACTIONS:
665 case PROPERTY_ID_SHOW_FILTERSORT:
667 ::std::vector< ::rtl::OUString > aListEntries;
668 tools::StringListResource aRes( PcrRes( RID_RSC_ENUM_SHOWHIDE ), aListEntries );
669 OSL_ENSURE( aListEntries.size() == 2, "FormComponentPropertyHandler::convertToControlValue: broken resource for Show/Hide!" );
671 if ( aListEntries.size() == 2 )
673 ::rtl::OUString sControlValue = ::comphelper::getBOOL( _rPropertyValue )
674 ? aListEntries[1]
675 : aListEntries[0];
676 aControlValue <<= sControlValue;
679 break;
681 //////////////////////////////////////////////////////////////
682 case PROPERTY_ID_DATASOURCE:
684 OSL_ENSURE( _rControlValueType.getTypeClass() == TypeClass_STRING,
685 "FormComponentPropertyHandler::convertToControlValue: wrong ControlValueType!" );
687 ::rtl::OUString sDataSource;
688 _rPropertyValue >>= sDataSource;
689 if ( sDataSource.getLength() )
691 ::svt::OFileNotation aTransformer( sDataSource );
692 sDataSource = aTransformer.get( ::svt::OFileNotation::N_SYSTEM );
694 aControlValue <<= sDataSource;
696 break;
698 //////////////////////////////////////////////////////////////
699 case PROPERTY_ID_CONTROLLABEL:
701 ::rtl::OUString sControlValue;
703 Reference< XPropertySet > xSet;
704 _rPropertyValue >>= xSet;
705 Reference< XPropertySetInfo > xPSI;
706 if ( xSet.is() )
707 xPSI = xSet->getPropertySetInfo();
708 if ( xPSI.is() && xPSI->hasPropertyByName( PROPERTY_LABEL ) )
710 ::rtl::OUStringBuffer aValue;
711 aValue.append( (sal_Unicode)'<' );
712 ::rtl::OUString sLabel;
713 OSL_VERIFY( xSet->getPropertyValue( PROPERTY_LABEL ) >>= sLabel );
714 aValue.append( sLabel );
715 aValue.append( (sal_Unicode)'>' );
716 sControlValue = aValue.makeStringAndClear();
719 aControlValue <<= sControlValue;
721 break;
723 //////////////////////////////////////////////////////////////
724 case PROPERTY_ID_DATEMIN:
725 case PROPERTY_ID_DATEMAX:
726 case PROPERTY_ID_DEFAULT_DATE:
727 case PROPERTY_ID_DATE:
729 sal_Int32 nDate = 0;
730 OSL_VERIFY( _rPropertyValue >>= nDate );
731 aControlValue <<= DBTypeConversion::toDate( nDate );
733 break;
735 case PROPERTY_ID_TIMEMIN:
736 case PROPERTY_ID_TIMEMAX:
737 case PROPERTY_ID_DEFAULT_TIME:
738 case PROPERTY_ID_TIME:
740 sal_Int32 nTime = 0;
741 OSL_VERIFY( _rPropertyValue >>= nTime );
742 aControlValue <<= DBTypeConversion::toTime( nTime );
744 break;
746 case PROPERTY_ID_WRITING_MODE:
748 sal_Int16 nWritingMode( WritingMode2::CONTEXT );
749 OSL_VERIFY( _rPropertyValue >>= nWritingMode );
750 sal_Int16 nNormalized = 2;
751 switch ( nWritingMode )
753 case WritingMode2::LR_TB: nNormalized = 0; break;
754 case WritingMode2::RL_TB: nNormalized = 1; break;
755 case WritingMode2::CONTEXT: nNormalized = 2; break;
756 default:
757 OSL_ENSURE( false, "FormComponentPropertyHandler::convertToControlValue: unsupported API value for WritingMode!" );
758 nNormalized = 2;
759 break;
762 aControlValue = FormComponentPropertyHandler_Base::convertToControlValue( _rPropertyName, makeAny( nNormalized ), _rControlValueType );
764 break;
766 case PROPERTY_ID_FONT:
768 FontDescriptor aFont;
769 OSL_VERIFY( _rPropertyValue >>= aFont );
771 ::rtl::OUStringBuffer displayName;
772 if ( !aFont.Name.getLength() )
774 displayName.append( String( PcrRes( RID_STR_FONT_DEFAULT ) ) );
776 else
778 // font name
779 displayName.append( aFont.Name );
780 displayName.appendAscii( ", " );
782 // font style
783 ::FontWeight eWeight = VCLUnoHelper::ConvertFontWeight( aFont.Weight );
784 USHORT nStyleResID = RID_STR_FONTSTYLE_REGULAR;
785 if ( aFont.Slant == FontSlant_ITALIC )
787 if ( eWeight > WEIGHT_NORMAL )
788 nStyleResID = RID_STR_FONTSTYLE_BOLD_ITALIC;
789 else
790 nStyleResID = RID_STR_FONTSTYLE_ITALIC;
792 else
794 if ( eWeight > WEIGHT_NORMAL )
795 nStyleResID = RID_STR_FONTSTYLE_BOLD;
797 displayName.append( String( PcrRes( nStyleResID ) ) );
799 // font size
800 if ( aFont.Height )
802 displayName.appendAscii( ", " );
803 displayName.append( sal_Int32( aFont.Height ) );
807 aControlValue <<= displayName.makeStringAndClear();
809 break;
811 default:
812 aControlValue = FormComponentPropertyHandler_Base::convertToControlValue( _rPropertyName, _rPropertyValue, _rControlValueType );
813 break;
815 } // switch ( nPropId )
817 return aControlValue;
820 //--------------------------------------------------------------------
821 PropertyState SAL_CALL FormComponentPropertyHandler::getPropertyState( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
823 ::osl::MutexGuard aGuard( m_aMutex );
824 if ( m_xPropertyState.is() )
825 return m_xPropertyState->getPropertyState( _rPropertyName );
826 return PropertyState_DIRECT_VALUE;
829 //--------------------------------------------------------------------
830 void SAL_CALL FormComponentPropertyHandler::addPropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
832 ::osl::MutexGuard aGuard( m_aMutex );
833 FormComponentPropertyHandler_Base::addPropertyChangeListener( _rxListener );
834 if ( m_xComponent.is() )
835 m_xComponent->addPropertyChangeListener( ::rtl::OUString(), _rxListener );
838 //--------------------------------------------------------------------
839 void SAL_CALL FormComponentPropertyHandler::removePropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
841 ::osl::MutexGuard aGuard( m_aMutex );
842 if ( m_xComponent.is() )
843 m_xComponent->removePropertyChangeListener( ::rtl::OUString(), _rxListener );
844 FormComponentPropertyHandler_Base::removePropertyChangeListener( _rxListener );
847 //--------------------------------------------------------------------
848 void FormComponentPropertyHandler::onNewComponent()
850 FormComponentPropertyHandler_Base::onNewComponent();
851 if ( !m_xComponentPropertyInfo.is() && m_xComponent.is() )
852 throw NullPointerException();
854 m_xPropertyState.set( m_xComponent, UNO_QUERY );
855 m_eComponentClass = eUnknown;
856 m_bComponentIsSubForm = m_bHaveListSource = m_bHaveCommand = false;
857 m_nClassId = 0;
859 impl_initComponentMetaData_throw();
862 //--------------------------------------------------------------------
863 Sequence< Property > SAL_CALL FormComponentPropertyHandler::doDescribeSupportedProperties() const
865 if ( !m_xComponentPropertyInfo.is() )
866 return Sequence< Property >();
868 ::std::vector< Property > aProperties;
870 Sequence< Property > aAllProperties( m_xComponentPropertyInfo->getProperties() );
871 aProperties.reserve( aAllProperties.getLength() );
873 // filter the properties
874 PropertyId nPropId( 0 );
875 ::rtl::OUString sDisplayName;
877 Property* pProperty = aAllProperties.getArray();
878 Property* pPropertiesEnd = pProperty + aAllProperties.getLength();
879 for ( ; pProperty != pPropertiesEnd; ++pProperty )
881 nPropId = m_pInfoService->getPropertyId( pProperty->Name );
882 if ( nPropId == -1 )
883 continue;
884 pProperty->Handle = nPropId;
886 sDisplayName = m_pInfoService->getPropertyTranslation( nPropId );
887 if ( !sDisplayName.getLength() )
888 continue;
890 sal_uInt32 nPropertyUIFlags = m_pInfoService->getPropertyUIFlags( nPropId );
891 bool bIsVisibleForForms = ( nPropertyUIFlags & PROP_FLAG_FORM_VISIBLE ) != 0;
892 bool bIsVisibleForDialogs = ( nPropertyUIFlags & PROP_FLAG_DIALOG_VISIBLE ) != 0;
894 // depending on whether we're working for a form or a UNO dialog, some
895 // properties are not displayed
896 if ( ( m_eComponentClass == eFormControl && !bIsVisibleForForms )
897 || ( m_eComponentClass == eDialogControl && !bIsVisibleForDialogs )
899 continue;
901 // some generic sanity checks
902 if ( impl_shouldExcludeProperty_nothrow( *pProperty ) )
903 continue;
905 switch ( nPropId )
907 case PROPERTY_ID_BORDER:
908 case PROPERTY_ID_TABSTOP:
909 // BORDER and TABSTOP are normalized (see impl_normalizePropertyValue_nothrow)
910 // to not allow VOID values
911 pProperty->Attributes &= ~( PropertyAttribute::MAYBEVOID );
912 break;
914 case PROPERTY_ID_LISTSOURCE:
915 // no cursor source if no Base is installed. #124939#
916 // This fix is not intendend to appear on the main trunk. If you find it there,
917 // please tell me! frank.schoenheit@sun.com
918 if ( SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
919 const_cast< FormComponentPropertyHandler* >( this )->m_bHaveListSource = true;
920 break;
922 case PROPERTY_ID_COMMAND:
923 // no cursor source if no Base is installed. #124939#
924 // This fix is not intendend to appear on the main trunk. If you find it there,
925 // please tell me! frank.schoenheit@sun.com
926 if ( SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
927 const_cast< FormComponentPropertyHandler* >( this )->m_bHaveCommand = true;
928 break;
929 } // switch ( nPropId )
931 aProperties.push_back( *pProperty );
934 if ( aProperties.empty() )
935 return Sequence< Property >();
936 return Sequence< Property >( &(*aProperties.begin()), aProperties.size() );
939 //--------------------------------------------------------------------
940 Sequence< ::rtl::OUString > SAL_CALL FormComponentPropertyHandler::getSupersededProperties( ) throw (RuntimeException)
942 return Sequence< ::rtl::OUString >( );
945 //--------------------------------------------------------------------
946 Sequence< ::rtl::OUString > SAL_CALL FormComponentPropertyHandler::getActuatingProperties( ) throw (RuntimeException)
948 ::osl::MutexGuard aGuard( m_aMutex );
949 ::std::vector< ::rtl::OUString > aInterestingProperties;
950 aInterestingProperties.push_back( PROPERTY_DATASOURCE );
951 aInterestingProperties.push_back( PROPERTY_COMMAND );
952 aInterestingProperties.push_back( PROPERTY_COMMANDTYPE );
953 aInterestingProperties.push_back( PROPERTY_LISTSOURCE );
954 aInterestingProperties.push_back( PROPERTY_LISTSOURCETYPE );
955 aInterestingProperties.push_back( PROPERTY_SUBMIT_ENCODING );
956 aInterestingProperties.push_back( PROPERTY_REPEAT );
957 aInterestingProperties.push_back( PROPERTY_TABSTOP );
958 aInterestingProperties.push_back( PROPERTY_BORDER );
959 aInterestingProperties.push_back( PROPERTY_CONTROLSOURCE );
960 aInterestingProperties.push_back( PROPERTY_DROPDOWN );
961 aInterestingProperties.push_back( PROPERTY_IMAGE_URL );
962 aInterestingProperties.push_back( PROPERTY_TARGET_URL );
963 aInterestingProperties.push_back( PROPERTY_STRINGITEMLIST );
964 aInterestingProperties.push_back( PROPERTY_BUTTONTYPE );
965 aInterestingProperties.push_back( PROPERTY_ESCAPE_PROCESSING );
966 aInterestingProperties.push_back( PROPERTY_TRISTATE );
967 aInterestingProperties.push_back( PROPERTY_DECIMAL_ACCURACY );
968 aInterestingProperties.push_back( PROPERTY_SHOWTHOUSANDSEP );
969 aInterestingProperties.push_back( PROPERTY_FORMATKEY );
970 aInterestingProperties.push_back( PROPERTY_EMPTY_IS_NULL );
971 aInterestingProperties.push_back( PROPERTY_TOGGLE );
972 return Sequence< ::rtl::OUString >( &(*aInterestingProperties.begin()), aInterestingProperties.size() );
975 //--------------------------------------------------------------------
976 LineDescriptor SAL_CALL FormComponentPropertyHandler::describePropertyLine( const ::rtl::OUString& _rPropertyName,
977 const Reference< XPropertyControlFactory >& _rxControlFactory )
978 throw (UnknownPropertyException, NullPointerException, RuntimeException)
980 if ( !_rxControlFactory.is() )
981 throw NullPointerException();
983 ::osl::MutexGuard aGuard( m_aMutex );
984 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
985 Property aProperty( impl_getPropertyFromId_throw( nPropId ) );
987 //////////////////////////////////////////////////////////////////////
988 // for the MultiLine property, we have different UI translations depending on the control
989 // type
990 if ( nPropId == PROPERTY_ID_MULTILINE )
992 if ( ( m_nClassId == FormComponentType::FIXEDTEXT )
993 || ( m_nClassId == FormComponentType::COMMANDBUTTON )
994 || ( m_nClassId == FormComponentType::RADIOBUTTON )
995 || ( m_nClassId == FormComponentType::CHECKBOX )
997 nPropId = PROPERTY_ID_WORDBREAK;
1000 String sDisplayName = m_pInfoService->getPropertyTranslation( nPropId );
1001 if ( !sDisplayName.Len() )
1003 DBG_ERROR( "FormComponentPropertyHandler::describePropertyLine: did getSupportedProperties not work properly?" );
1004 throw UnknownPropertyException();
1007 //////////////////////////////////////////////////////////////////////
1009 LineDescriptor aDescriptor;
1010 aDescriptor.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( nPropId ) );
1011 aDescriptor.DisplayName = sDisplayName;
1013 // for the moment, assume a text field
1014 sal_Int16 nControlType = PropertyControlType::TextField;
1015 sal_Bool bReadOnly = sal_False;
1016 aDescriptor.Control.clear();
1018 //////////////////////////////////////////////////////////////////////
1020 bool bNeedDefaultStringIfVoidAllowed = false;
1022 TypeClass eType = aProperty.Type.getTypeClass();
1024 switch ( nPropId )
1026 case PROPERTY_ID_DEFAULT_SELECT_SEQ:
1027 case PROPERTY_ID_SELECTEDITEMS:
1028 aDescriptor.PrimaryButtonId = UID_PROP_DLG_SELECTION;
1029 break;
1031 case PROPERTY_ID_FILTER:
1032 aDescriptor.PrimaryButtonId = UID_PROP_DLG_FILTER;
1033 break;
1035 case PROPERTY_ID_SORT:
1036 aDescriptor.PrimaryButtonId = UID_PROP_DLG_ORDER;
1037 break;
1039 case PROPERTY_ID_MASTERFIELDS:
1040 case PROPERTY_ID_DETAILFIELDS:
1041 nControlType = PropertyControlType::StringListField;
1042 aDescriptor.PrimaryButtonId = UID_PROP_DLG_FORMLINKFIELDS;
1043 break;
1045 case PROPERTY_ID_COMMAND:
1046 aDescriptor.PrimaryButtonId = UID_PROP_DLG_SQLCOMMAND;
1047 break;
1049 case PROPERTY_ID_TABINDEX:
1051 Reference< XControlContainer > xControlContext( impl_getContextControlContainer_nothrow() );
1052 if ( xControlContext.is() )
1053 aDescriptor.PrimaryButtonId = UID_PROP_DLG_TABINDEX;
1054 nControlType = PropertyControlType::NumericField;
1056 break;
1058 case PROPERTY_ID_FONT:
1059 bReadOnly = sal_True;
1060 aDescriptor.PrimaryButtonId = UID_PROP_DLG_FONT_TYPE;
1061 break;
1063 case PROPERTY_ID_TARGET_URL:
1064 case PROPERTY_ID_IMAGE_URL:
1066 aDescriptor.Control = new OFileUrlControl( impl_getDefaultDialogParent_nothrow(), WB_TABSTOP | WB_BORDER );
1068 aDescriptor.PrimaryButtonId = ( PROPERTY_ID_TARGET_URL == nPropId )
1069 ? UID_PROP_DLG_ATTR_TARGET_URL : UID_PROP_DLG_IMAGE_URL;
1071 break;
1073 case PROPERTY_ID_ECHO_CHAR:
1074 nControlType = PropertyControlType::CharacterField;
1075 break;
1077 case PROPERTY_ID_BACKGROUNDCOLOR:
1078 case PROPERTY_ID_FILLCOLOR:
1079 case PROPERTY_ID_SYMBOLCOLOR:
1080 case PROPERTY_ID_BORDERCOLOR:
1081 nControlType = PropertyControlType::ColorListBox;
1083 switch( nPropId )
1085 case PROPERTY_ID_BACKGROUNDCOLOR:
1086 aDescriptor.PrimaryButtonId = UID_PROP_DLG_BACKGROUNDCOLOR; break;
1087 case PROPERTY_ID_FILLCOLOR:
1088 aDescriptor.PrimaryButtonId = UID_PROP_DLG_FILLCOLOR; break;
1089 case PROPERTY_ID_SYMBOLCOLOR:
1090 aDescriptor.PrimaryButtonId = UID_PROP_DLG_SYMBOLCOLOR; break;
1091 case PROPERTY_ID_BORDERCOLOR:
1092 aDescriptor.PrimaryButtonId = UID_PROP_DLG_BORDERCOLOR; break;
1094 break;
1096 case PROPERTY_ID_LABEL:
1097 nControlType = PropertyControlType::MultiLineTextField;
1098 break;
1100 case PROPERTY_ID_DEFAULT_TEXT:
1102 if (FormComponentType::FILECONTROL == m_nClassId)
1103 nControlType = PropertyControlType::TextField;
1104 else
1105 nControlType = PropertyControlType::MultiLineTextField;
1107 break;
1109 case PROPERTY_ID_TEXT:
1110 if ( impl_componentHasProperty_throw( PROPERTY_MULTILINE ) )
1111 nControlType = PropertyControlType::MultiLineTextField;
1112 break;
1114 case PROPERTY_ID_CONTROLLABEL:
1115 bReadOnly = sal_True;
1116 aDescriptor.PrimaryButtonId = UID_PROP_DLG_CONTROLLABEL;
1117 break;
1119 case PROPERTY_ID_FORMATKEY:
1120 case PROPERTY_ID_EFFECTIVE_MIN:
1121 case PROPERTY_ID_EFFECTIVE_MAX:
1122 case PROPERTY_ID_EFFECTIVE_DEFAULT:
1123 case PROPERTY_ID_EFFECTIVE_VALUE:
1125 // and the supplier is really available
1126 Reference< XNumberFormatsSupplier > xSupplier;
1127 m_xComponent->getPropertyValue( PROPERTY_FORMATSSUPPLIER ) >>= xSupplier;
1128 if (xSupplier.is())
1130 Reference< XUnoTunnel > xTunnel(xSupplier,UNO_QUERY);
1131 DBG_ASSERT(xTunnel.is(), "FormComponentPropertyHandler::describePropertyLine : xTunnel is invalid!");
1132 SvNumberFormatsSupplierObj* pSupplier = reinterpret_cast<SvNumberFormatsSupplierObj*>(xTunnel->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));
1134 if (pSupplier != NULL)
1136 sal_Bool bIsFormatKey = (PROPERTY_ID_FORMATKEY == nPropId);
1138 bReadOnly = bIsFormatKey;
1140 if ( bIsFormatKey )
1142 OFormatSampleControl* pControl = new OFormatSampleControl( impl_getDefaultDialogParent_nothrow(), WB_READONLY | WB_TABSTOP | WB_BORDER );
1143 aDescriptor.Control = pControl;
1144 pControl->SetFormatSupplier( pSupplier );
1146 aDescriptor.PrimaryButtonId = UID_PROP_DLG_NUMBER_FORMAT;
1148 else
1150 OFormattedNumericControl* pControl = new OFormattedNumericControl( impl_getDefaultDialogParent_nothrow(), WB_TABSTOP | WB_BORDER );
1151 aDescriptor.Control = pControl;
1153 FormatDescription aDesc;
1154 aDesc.pSupplier = pSupplier;
1155 Any aFormatKeyValue = m_xComponent->getPropertyValue(PROPERTY_FORMATKEY);
1156 if ( !( aFormatKeyValue >>= aDesc.nKey ) )
1157 aDesc.nKey = 0;
1159 pControl->SetFormatDescription( aDesc );
1164 break;
1166 case PROPERTY_ID_DATEMIN:
1167 case PROPERTY_ID_DATEMAX:
1168 case PROPERTY_ID_DEFAULT_DATE:
1169 case PROPERTY_ID_DATE:
1170 nControlType = PropertyControlType::DateField;
1171 break;
1173 case PROPERTY_ID_TIMEMIN:
1174 case PROPERTY_ID_TIMEMAX:
1175 case PROPERTY_ID_DEFAULT_TIME:
1176 case PROPERTY_ID_TIME:
1177 nControlType = PropertyControlType::TimeField;
1178 break;
1180 case PROPERTY_ID_VALUEMIN:
1181 case PROPERTY_ID_VALUEMAX:
1182 case PROPERTY_ID_DEFAULT_VALUE:
1183 case PROPERTY_ID_VALUE:
1185 OFormattedNumericControl* pControl = new OFormattedNumericControl( impl_getDefaultDialogParent_nothrow(), WB_TABSTOP | WB_BORDER | WB_SPIN | WB_REPEAT );
1186 aDescriptor.Control = pControl;
1188 // we don't set a formatter so the control uses a default (which uses the application
1189 // language and a default numeric format)
1190 // but we set the decimal digits
1191 pControl->SetDecimalDigits(
1192 ::comphelper::getINT16( m_xComponent->getPropertyValue( PROPERTY_DECIMAL_ACCURACY ) )
1195 // and the thousands separator
1196 pControl->SetThousandsSep(
1197 ::comphelper::getBOOL( m_xComponent->getPropertyValue(PROPERTY_SHOWTHOUSANDSEP) )
1200 // and the default value for the property
1203 if (m_xPropertyState.is() && ((PROPERTY_ID_VALUEMIN == nPropId) || (PROPERTY_ID_VALUEMAX == nPropId)))
1205 double nDefault = 0;
1206 if ( m_xPropertyState->getPropertyDefault( aProperty.Name ) >>= nDefault )
1207 pControl->SetDefaultValue( nDefault );
1210 catch (Exception&)
1212 // just ignore it
1215 // and allow empty values only for the default value and the value
1216 pControl->EnableEmptyField( ( PROPERTY_ID_DEFAULT_VALUE == nPropId )
1217 || ( PROPERTY_ID_VALUE == nPropId ) );
1219 break;
1221 default:
1222 if ( TypeClass_BYTE <= eType && eType <= TypeClass_DOUBLE )
1224 sal_Int16 nDigits = 0;
1225 sal_Int16 nValueUnit = -1;
1226 sal_Int16 nDisplayUnit = -1;
1227 if ( m_eComponentClass == eFormControl )
1229 if ( ( nPropId == PROPERTY_ID_WIDTH )
1230 || ( nPropId == PROPERTY_ID_ROWHEIGHT )
1231 || ( nPropId == PROPERTY_ID_HEIGHT )
1234 nValueUnit = MeasureUnit::MM_10TH;
1235 nDisplayUnit = impl_getDocumentMeasurementUnit_throw();
1236 nDigits = 2;
1240 Optional< double > aValueNotPresent( sal_False, 0 );
1241 aDescriptor.Control = PropertyHandlerHelper::createNumericControl(
1242 _rxControlFactory, nDigits, aValueNotPresent, aValueNotPresent, sal_False );
1244 Reference< XNumericControl > xNumericControl( aDescriptor.Control, UNO_QUERY_THROW );
1245 if ( nValueUnit != -1 )
1246 xNumericControl->setValueUnit( nValueUnit );
1247 if ( nDisplayUnit != -1 )
1248 xNumericControl->setDisplayUnit( nDisplayUnit );
1250 break;
1253 //////////////////////////////////////////////////////////////////////
1254 if ( eType == TypeClass_SEQUENCE )
1255 nControlType = PropertyControlType::StringListField;
1257 //////////////////////////////////////////////////////////////////////
1258 // boolean values
1259 if ( eType == TypeClass_BOOLEAN )
1261 USHORT nResId = RID_RSC_ENUM_YESNO;
1262 if ( ( nPropId == PROPERTY_ID_SHOW_POSITION )
1263 || ( nPropId == PROPERTY_ID_SHOW_NAVIGATION )
1264 || ( nPropId == PROPERTY_ID_SHOW_RECORDACTIONS )
1265 || ( nPropId == PROPERTY_ID_SHOW_FILTERSORT )
1267 nResId = RID_RSC_ENUM_SHOWHIDE;
1269 ::std::vector< ::rtl::OUString > aListEntries;
1270 tools::StringListResource aRes(PcrRes(nResId),aListEntries);
1271 aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
1272 bNeedDefaultStringIfVoidAllowed = true;
1275 //////////////////////////////////////////////////////////////////////
1276 // enum properties
1277 sal_uInt32 nPropertyUIFlags = m_pInfoService->getPropertyUIFlags( nPropId );
1278 bool bIsEnumProperty = ( nPropertyUIFlags & PROP_FLAG_ENUM ) != 0;
1279 if ( bIsEnumProperty || ( PROPERTY_ID_TARGET_FRAME == nPropId ) )
1281 ::std::vector< ::rtl::OUString > aEnumValues = m_pInfoService->getPropertyEnumRepresentations( nPropId );
1282 ::std::vector< ::rtl::OUString >::const_iterator pStart = aEnumValues.begin();
1283 ::std::vector< ::rtl::OUString >::const_iterator pEnd = aEnumValues.end();
1285 // for a checkbox: if "ambiguous" is not allowed, remove this from the sequence
1286 if ( ( PROPERTY_ID_DEFAULT_STATE == nPropId )
1287 || ( PROPERTY_ID_STATE == nPropId )
1290 if ( impl_componentHasProperty_throw( PROPERTY_TRISTATE ) )
1292 if ( !::comphelper::getBOOL( m_xComponent->getPropertyValue( PROPERTY_TRISTATE ) ) )
1293 { // remove the last sequence element
1294 if ( pEnd > pStart )
1295 --pEnd;
1298 else
1299 --pEnd;
1302 if ( PROPERTY_ID_LISTSOURCETYPE == nPropId )
1303 if ( FormComponentType::COMBOBOX == m_nClassId )
1304 // remove the first sequence element -> value list not possible for combo boxes
1305 ++pStart;
1307 // copy the sequence
1308 ::std::vector< ::rtl::OUString > aListEntries( pEnd - pStart );
1309 ::std::copy( pStart, pEnd, aListEntries.begin() );
1311 // create the control
1312 if ( PROPERTY_ID_TARGET_FRAME == nPropId )
1313 aDescriptor.Control = PropertyHandlerHelper::createComboBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
1314 else
1316 aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
1317 bNeedDefaultStringIfVoidAllowed = true;
1321 //////////////////////////////////////////////////////////////////////
1322 switch( nPropId )
1324 case PROPERTY_ID_REPEAT_DELAY:
1326 OTimeDurationControl* pControl = new OTimeDurationControl( impl_getDefaultDialogParent_nothrow(), WB_BORDER | WB_TABSTOP );
1327 aDescriptor.Control = pControl;
1329 pControl->setMinValue( Optional< double >( sal_True, 0 ) );
1330 pControl->setMaxValue( Optional< double >( sal_True, ::std::numeric_limits< double >::max() ) );
1332 break;
1334 case PROPERTY_ID_TABINDEX:
1335 case PROPERTY_ID_BOUNDCOLUMN:
1336 case PROPERTY_ID_VISIBLESIZE:
1337 case PROPERTY_ID_MAXTEXTLEN:
1338 case PROPERTY_ID_LINEINCREMENT:
1339 case PROPERTY_ID_BLOCKINCREMENT:
1340 case PROPERTY_ID_SPININCREMENT:
1342 Optional< double > aMinValue( sal_True, 0 );
1343 Optional< double > aMaxValue( sal_True, 0x7FFFFFFF );
1345 if ( nPropId == PROPERTY_ID_MAXTEXTLEN )
1346 aMinValue.Value = -1;
1347 else if ( ( nPropId == PROPERTY_ID_BOUNDCOLUMN ) || ( nPropId == PROPERTY_ID_VISIBLESIZE ) )
1348 aMinValue.Value = 1;
1349 else
1350 aMinValue.Value = 0;
1352 aDescriptor.Control = PropertyHandlerHelper::createNumericControl(
1353 _rxControlFactory, 0, aMinValue, aMaxValue, sal_False );
1355 break;
1357 case PROPERTY_ID_DECIMAL_ACCURACY:
1359 Optional< double > aMinValue( sal_True, 0 );
1360 Optional< double > aMaxValue( sal_True, 20 );
1362 aDescriptor.Control = PropertyHandlerHelper::createNumericControl(
1363 _rxControlFactory, 0, aMinValue, aMaxValue, sal_False );
1365 break;
1367 //////////////////////////////////////////////////////////////////////
1368 // DataSource
1369 case PROPERTY_ID_DATASOURCE:
1371 aDescriptor.PrimaryButtonId = UID_PROP_DLG_ATTR_DATASOURCE;
1373 ::std::vector< ::rtl::OUString > aListEntries;
1375 Reference< XNameAccess > xDatabaseContext;
1376 m_aContext.createComponent( (rtl::OUString)SERVICE_DATABASE_CONTEXT, xDatabaseContext );
1377 if (xDatabaseContext.is())
1379 Sequence< ::rtl::OUString > aDatasources = xDatabaseContext->getElementNames();
1380 aListEntries.resize( aDatasources.getLength() );
1381 ::std::copy( aDatasources.getConstArray(), aDatasources.getConstArray() + aDatasources.getLength(),
1382 aListEntries.begin() );
1384 aDescriptor.Control = PropertyHandlerHelper::createComboBoxControl(
1385 _rxControlFactory, aListEntries, sal_False, sal_True );
1387 break;
1389 case PROPERTY_ID_CONTROLSOURCE:
1391 ::std::vector< ::rtl::OUString > aFieldNames;
1392 impl_initFieldList_nothrow( aFieldNames );
1393 aDescriptor.Control = PropertyHandlerHelper::createComboBoxControl(
1394 _rxControlFactory, aFieldNames, sal_False, sal_False );
1396 break;
1398 case PROPERTY_ID_COMMAND:
1399 impl_describeCursorSource_nothrow( aDescriptor, _rxControlFactory );
1400 break;
1402 case PROPERTY_ID_LISTSOURCE:
1403 impl_describeListSourceUI_throw( aDescriptor, _rxControlFactory );
1404 break;
1407 if ( !aDescriptor.Control.is() )
1408 aDescriptor.Control = _rxControlFactory->createPropertyControl( nControlType, bReadOnly );
1410 if ( ( aProperty.Attributes & PropertyAttribute::MAYBEVOID ) != 0 )
1412 // insert the string "Default" string, if necessary
1413 if ( bNeedDefaultStringIfVoidAllowed || ( nControlType == PropertyControlType::ColorListBox ) )
1415 Reference< XStringListControl > xStringList( aDescriptor.Control, UNO_QUERY_THROW );
1416 xStringList->prependListEntry( m_sDefaultValueString );
1417 m_aPropertiesWithDefListEntry.insert( _rPropertyName );
1421 if ( aDescriptor.PrimaryButtonId )
1422 aDescriptor.HasPrimaryButton = sal_True;
1423 if ( aDescriptor.SecondaryButtonId )
1424 aDescriptor.HasSecondaryButton = sal_True;
1426 bool bIsDataProperty = ( nPropertyUIFlags & PROP_FLAG_DATA_PROPERTY ) != 0;
1427 aDescriptor.Category = ::rtl::OUString::createFromAscii( bIsDataProperty ? "Data" : "General" );
1428 return aDescriptor;
1431 //--------------------------------------------------------------------
1432 InteractiveSelectionResult SAL_CALL FormComponentPropertyHandler::onInteractivePropertySelection( const ::rtl::OUString& _rPropertyName, sal_Bool /*_bPrimary*/, Any& _rData, const Reference< XObjectInspectorUI >& _rxInspectorUI ) throw (UnknownPropertyException, NullPointerException, RuntimeException)
1434 if ( !_rxInspectorUI.is() )
1435 throw NullPointerException();
1437 ::osl::ClearableMutexGuard aGuard( m_aMutex );
1438 PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
1440 InteractiveSelectionResult eResult = InteractiveSelectionResult_Cancelled;
1441 switch ( nPropId )
1443 case PROPERTY_ID_DEFAULT_SELECT_SEQ:
1444 case PROPERTY_ID_SELECTEDITEMS:
1445 if ( impl_dialogListSelection_nothrow( _rPropertyName, aGuard ) )
1446 eResult = InteractiveSelectionResult_Success;
1447 break;
1449 case PROPERTY_ID_FILTER:
1450 case PROPERTY_ID_SORT:
1452 ::rtl::OUString sClause;
1453 if ( impl_dialogFilterOrSort_nothrow( PROPERTY_ID_FILTER == nPropId, sClause, aGuard ) )
1455 _rData <<= sClause;
1456 eResult = InteractiveSelectionResult_ObtainedValue;
1459 break;
1461 case PROPERTY_ID_MASTERFIELDS:
1462 case PROPERTY_ID_DETAILFIELDS:
1463 if ( impl_dialogLinkedFormFields_nothrow( aGuard ) )
1464 eResult = InteractiveSelectionResult_Success;
1465 break;
1467 case PROPERTY_ID_FORMATKEY:
1468 if ( impl_dialogFormatting_nothrow( _rData, aGuard ) )
1469 eResult = InteractiveSelectionResult_ObtainedValue;
1470 break;
1472 case PROPERTY_ID_IMAGE_URL:
1473 if ( impl_browseForImage_nothrow( _rData, aGuard ) )
1474 eResult = InteractiveSelectionResult_ObtainedValue;
1475 break;
1477 case PROPERTY_ID_TARGET_URL:
1478 if ( impl_browseForTargetURL_nothrow( _rData, aGuard ) )
1479 eResult = InteractiveSelectionResult_ObtainedValue;
1480 break;
1482 case PROPERTY_ID_FONT:
1483 if ( impl_executeFontDialog_nothrow( _rData, aGuard ) )
1484 eResult = InteractiveSelectionResult_ObtainedValue;
1485 break;
1487 case PROPERTY_ID_DATASOURCE:
1488 if ( impl_browseForDatabaseDocument_throw( _rData, aGuard ) )
1489 eResult = InteractiveSelectionResult_ObtainedValue;
1490 break;
1492 case PROPERTY_ID_BACKGROUNDCOLOR:
1493 case PROPERTY_ID_FILLCOLOR:
1494 case PROPERTY_ID_SYMBOLCOLOR:
1495 case PROPERTY_ID_BORDERCOLOR:
1496 if ( impl_dialogColorChooser_throw( nPropId, _rData, aGuard ) )
1497 eResult = InteractiveSelectionResult_ObtainedValue;
1498 break;
1500 case PROPERTY_ID_CONTROLLABEL:
1501 if ( impl_dialogChooseLabelControl_nothrow( _rData, aGuard ) )
1502 eResult = InteractiveSelectionResult_ObtainedValue;
1503 break;
1505 case PROPERTY_ID_TABINDEX:
1506 if ( impl_dialogChangeTabOrder_nothrow( aGuard ) )
1507 eResult = InteractiveSelectionResult_Success;
1508 break;
1510 case PROPERTY_ID_COMMAND:
1511 case PROPERTY_ID_LISTSOURCE:
1512 if ( impl_doDesignSQLCommand_nothrow( _rxInspectorUI, nPropId ) )
1513 eResult = InteractiveSelectionResult_Pending;
1514 break;
1515 default:
1516 DBG_ERROR( "FormComponentPropertyHandler::onInteractivePropertySelection: request for a property which does not have dedicated UI!" );
1517 break;
1519 return eResult;
1522 //--------------------------------------------------------------------
1523 namespace
1525 void lcl_rebuildAndResetCommand( const Reference< XObjectInspectorUI >& _rxInspectorUI, const Reference< XPropertyHandler >& _rxHandler )
1527 OSL_PRECOND( _rxInspectorUI.is(), "lcl_rebuildAndResetCommand: invalid BrowserUI!" );
1528 OSL_PRECOND( _rxHandler.is(), "lcl_rebuildAndResetCommand: invalid handler!" );
1529 _rxInspectorUI->rebuildPropertyUI( PROPERTY_COMMAND );
1530 _rxHandler->setPropertyValue( PROPERTY_COMMAND, makeAny( ::rtl::OUString() ) );
1534 //--------------------------------------------------------------------
1535 void SAL_CALL FormComponentPropertyHandler::actuatingPropertyChanged( const ::rtl::OUString& _rActuatingPropertyName, const Any& _rNewValue, const Any& /*_rOldValue*/, const Reference< XObjectInspectorUI >& _rxInspectorUI, sal_Bool _bFirstTimeInit ) throw (NullPointerException, RuntimeException)
1537 if ( !_rxInspectorUI.is() )
1538 throw NullPointerException();
1540 ::osl::MutexGuard aGuard( m_aMutex );
1541 PropertyId nActuatingPropId( impl_getPropertyId_throw( _rActuatingPropertyName ) );
1543 ::std::vector< PropertyId > aDependentProperties;
1545 switch ( nActuatingPropId )
1547 // ----- EscapeProcessing -----
1548 case PROPERTY_ID_ESCAPE_PROCESSING:
1549 aDependentProperties.push_back( PROPERTY_ID_FILTER );
1550 aDependentProperties.push_back( PROPERTY_ID_SORT );
1551 break; // case PROPERTY_ID_ESCAPE_PROCESSING
1553 // ----- CommandType -----
1554 case PROPERTY_ID_COMMANDTYPE:
1555 // available commands (tables or queries) might have changed
1556 if ( !_bFirstTimeInit && m_bHaveCommand )
1557 lcl_rebuildAndResetCommand( _rxInspectorUI, this );
1558 aDependentProperties.push_back( PROPERTY_ID_COMMAND );
1559 break; // case PROPERTY_ID_COMMANDTYPE
1561 // ----- DataSourceName -----
1562 case PROPERTY_ID_DATASOURCE:
1563 // reset the connection, now that we have a new data source
1564 impl_clearRowsetConnection_nothrow();
1566 // available list source values (tables or queries) might have changed
1567 if ( !_bFirstTimeInit && m_bHaveListSource )
1568 _rxInspectorUI->rebuildPropertyUI( PROPERTY_LISTSOURCE );
1570 // available commands (tables or queries) might have changed
1571 if ( !_bFirstTimeInit && m_bHaveCommand )
1572 lcl_rebuildAndResetCommand( _rxInspectorUI, this );
1574 // Command also depends on DataSource
1575 aDependentProperties.push_back( PROPERTY_ID_COMMAND );
1576 // NO break!
1578 // ----- Command -----
1579 case PROPERTY_ID_COMMAND:
1580 aDependentProperties.push_back( PROPERTY_ID_FILTER );
1581 aDependentProperties.push_back( PROPERTY_ID_SORT );
1582 if ( m_bComponentIsSubForm )
1583 aDependentProperties.push_back( PROPERTY_ID_DETAILFIELDS );
1584 break;
1586 // ----- ListSourceType -----
1587 case PROPERTY_ID_LISTSOURCETYPE:
1588 if ( !_bFirstTimeInit && m_bHaveListSource )
1589 // available list source values (tables or queries) might have changed
1590 _rxInspectorUI->rebuildPropertyUI( PROPERTY_LISTSOURCE );
1591 aDependentProperties.push_back( PROPERTY_ID_BOUNDCOLUMN );
1592 aDependentProperties.push_back( PROPERTY_ID_STRINGITEMLIST );
1593 // NO break!
1595 // ----- StringItemList -----
1596 case PROPERTY_ID_STRINGITEMLIST:
1597 aDependentProperties.push_back( PROPERTY_ID_SELECTEDITEMS );
1598 aDependentProperties.push_back( PROPERTY_ID_DEFAULT_SELECT_SEQ );
1599 break;
1601 // ----- ListSource -----
1602 case PROPERTY_ID_LISTSOURCE:
1603 aDependentProperties.push_back( PROPERTY_ID_STRINGITEMLIST );
1604 break;
1606 // ----- DataField -----
1607 case PROPERTY_ID_CONTROLSOURCE:
1609 ::rtl::OUString sControlSource;
1610 _rNewValue >>= sControlSource;
1611 if ( impl_componentHasProperty_throw( PROPERTY_FILTERPROPOSAL ) )
1612 _rxInspectorUI->enablePropertyUI( PROPERTY_FILTERPROPOSAL, sControlSource.getLength() > 0 );
1613 if ( impl_componentHasProperty_throw( PROPERTY_EMPTY_IS_NULL ) )
1614 _rxInspectorUI->enablePropertyUI( PROPERTY_EMPTY_IS_NULL, sControlSource.getLength() > 0 );
1616 aDependentProperties.push_back( PROPERTY_ID_BOUNDCOLUMN );
1617 aDependentProperties.push_back( PROPERTY_ID_SCALEIMAGE );
1618 aDependentProperties.push_back( PROPERTY_ID_SCALE_MODE );
1619 aDependentProperties.push_back( PROPERTY_ID_INPUT_REQUIRED );
1621 break;
1623 case PROPERTY_ID_EMPTY_IS_NULL:
1624 aDependentProperties.push_back( PROPERTY_ID_INPUT_REQUIRED );
1625 break;
1627 // ----- SubmitEncoding -----
1628 case PROPERTY_ID_SUBMIT_ENCODING:
1630 FormSubmitEncoding eEncoding = FormSubmitEncoding_URL;
1631 OSL_VERIFY( _rNewValue >>= eEncoding );
1632 _rxInspectorUI->enablePropertyUI( PROPERTY_SUBMIT_METHOD, eEncoding == FormSubmitEncoding_URL );
1634 break;
1636 // ----- Repeat -----
1637 case PROPERTY_ID_REPEAT:
1639 sal_Bool bIsRepeating = sal_False;
1640 OSL_VERIFY( _rNewValue >>= bIsRepeating );
1641 _rxInspectorUI->enablePropertyUI( PROPERTY_REPEAT_DELAY, bIsRepeating );
1643 break;
1645 // ----- TabStop -----
1646 case PROPERTY_ID_TABSTOP:
1648 if ( !impl_componentHasProperty_throw( PROPERTY_TABINDEX ) )
1649 break;
1650 sal_Bool bHasTabStop = sal_False;
1651 _rNewValue >>= bHasTabStop;
1652 _rxInspectorUI->enablePropertyUI( PROPERTY_TABINDEX, bHasTabStop );
1654 break;
1656 // ----- Border -----
1657 case PROPERTY_ID_BORDER:
1659 sal_Int16 nBordeType = VisualEffect::NONE;
1660 OSL_VERIFY( _rNewValue >>= nBordeType );
1661 _rxInspectorUI->enablePropertyUI( PROPERTY_BORDERCOLOR, nBordeType == VisualEffect::FLAT );
1663 break;
1665 // ----- DropDown -----
1666 case PROPERTY_ID_DROPDOWN:
1668 if ( impl_isSupportedProperty_nothrow( PROPERTY_ID_LINECOUNT ) )
1670 sal_Bool bDropDown = sal_True;
1671 _rNewValue >>= bDropDown;
1672 _rxInspectorUI->enablePropertyUI( PROPERTY_LINECOUNT, bDropDown );
1675 break;
1677 // ----- ImageURL -----
1678 case PROPERTY_ID_IMAGE_URL:
1680 if ( impl_isSupportedProperty_nothrow( PROPERTY_ID_IMAGEPOSITION ) )
1682 ::rtl::OUString sImageURL;
1683 OSL_VERIFY( _rNewValue >>= sImageURL );
1684 _rxInspectorUI->enablePropertyUI( PROPERTY_IMAGEPOSITION, sImageURL.getLength() != 0 );
1687 aDependentProperties.push_back( PROPERTY_ID_SCALEIMAGE );
1688 aDependentProperties.push_back( PROPERTY_ID_SCALE_MODE );
1690 break;
1692 // ----- ButtonType -----
1693 case PROPERTY_ID_BUTTONTYPE:
1695 FormButtonType eButtonType( FormButtonType_PUSH );
1696 OSL_VERIFY( _rNewValue >>= eButtonType );
1697 _rxInspectorUI->enablePropertyUI( PROPERTY_TARGET_URL, FormButtonType_URL == eButtonType );
1699 // NO break!
1701 // ----- TargetURL -----
1702 case PROPERTY_ID_TARGET_URL:
1703 aDependentProperties.push_back( PROPERTY_ID_TARGET_FRAME );
1704 break; // case PROPERTY_ID_TARGET_URL
1706 // ----- TriState -----
1707 case PROPERTY_ID_TRISTATE:
1708 if ( !_bFirstTimeInit )
1709 _rxInspectorUI->rebuildPropertyUI( m_eComponentClass == eFormControl ? PROPERTY_DEFAULT_STATE : PROPERTY_STATE );
1710 break; // case PROPERTY_ID_TRISTATE
1712 // ----- DecimalAccuracy -----
1713 case PROPERTY_ID_DECIMAL_ACCURACY:
1714 // ----- ShowThousandsSeparator -----
1715 case PROPERTY_ID_SHOWTHOUSANDSEP:
1717 sal_Bool bAccuracy = (PROPERTY_ID_DECIMAL_ACCURACY == nActuatingPropId);
1718 sal_uInt16 nNewDigits = 0;
1719 sal_Bool bUseSep = sal_False;
1720 if ( bAccuracy )
1721 OSL_VERIFY( _rNewValue >>= nNewDigits );
1722 else
1723 OSL_VERIFY( _rNewValue >>= bUseSep );
1725 // propagate the changes to the min/max/default fields
1726 Any aCurrentProp;
1727 ::rtl::OUString aAffectedProps[] = { PROPERTY_VALUE, PROPERTY_DEFAULT_VALUE, PROPERTY_VALUEMIN, PROPERTY_VALUEMAX };
1728 for (sal_uInt16 i=0; i<sizeof(aAffectedProps)/sizeof(aAffectedProps[0]); ++i)
1730 Reference< XPropertyControl > xControl;
1733 xControl = _rxInspectorUI->getPropertyControl( aAffectedProps[i] );
1735 catch( const UnknownPropertyException& e ) { (void)e; }
1736 if ( xControl.is() )
1738 OFormattedNumericControl* pControl = dynamic_cast< OFormattedNumericControl* >( xControl.get() );
1739 DBG_ASSERT( pControl, "FormComponentPropertyHandler::actuatingPropertyChanged: invalid control!" );
1740 if ( pControl )
1742 if ( bAccuracy )
1743 pControl->SetDecimalDigits( nNewDigits );
1744 else
1745 pControl->SetThousandsSep( bUseSep );
1750 break;
1752 // ----- FormatKey -----
1753 case PROPERTY_ID_FORMATKEY:
1755 FormatDescription aNewDesc;
1757 Reference< XNumberFormatsSupplier > xSupplier;
1758 OSL_VERIFY( m_xComponent->getPropertyValue( PROPERTY_FORMATSSUPPLIER ) >>= xSupplier );
1760 Reference< XUnoTunnel > xTunnel( xSupplier, UNO_QUERY );
1761 DBG_ASSERT(xTunnel.is(), "FormComponentPropertyHandler::actuatingPropertyChanged: xTunnel is invalid!");
1762 if ( xTunnel.is() )
1764 SvNumberFormatsSupplierObj* pSupplier = reinterpret_cast<SvNumberFormatsSupplierObj*>(xTunnel->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));
1765 // the same again
1767 aNewDesc.pSupplier = pSupplier;
1768 if ( !( _rNewValue >>= aNewDesc.nKey ) )
1769 aNewDesc.nKey = 0;
1771 // give each control which has to know this an own copy of the description
1772 ::rtl::OUString aFormattedPropertyControls[] = {
1773 PROPERTY_EFFECTIVE_MIN, PROPERTY_EFFECTIVE_MAX, PROPERTY_EFFECTIVE_DEFAULT, PROPERTY_EFFECTIVE_VALUE
1775 for ( sal_uInt16 i=0; i<sizeof(aFormattedPropertyControls)/sizeof(aFormattedPropertyControls[0]); ++i )
1777 Reference< XPropertyControl > xControl;
1780 xControl = _rxInspectorUI->getPropertyControl( aFormattedPropertyControls[i] );
1782 catch( const UnknownPropertyException& e ) { (void)e; }
1783 if ( xControl.is() )
1785 OFormattedNumericControl* pControl = dynamic_cast< OFormattedNumericControl* >( xControl.get() );
1786 DBG_ASSERT( pControl, "FormComponentPropertyHandler::actuatingPropertyChanged: invalid control!" );
1787 if ( pControl )
1788 pControl->SetFormatDescription( aNewDesc );
1793 break;
1795 case PROPERTY_ID_TOGGLE:
1797 sal_Bool bIsToggleButton = sal_False;
1798 OSL_VERIFY( _rNewValue >>= bIsToggleButton );
1799 _rxInspectorUI->enablePropertyUI( PROPERTY_DEFAULT_STATE, bIsToggleButton );
1801 break;
1803 default:
1804 DBG_ERROR( "FormComponentPropertyHandler::actuatingPropertyChanged: did not register for this property!" );
1805 break;
1807 } // switch ( nActuatingPropId )
1809 for ( ::std::vector< PropertyId >::const_iterator loopAffected = aDependentProperties.begin();
1810 loopAffected != aDependentProperties.end();
1811 ++loopAffected
1814 if ( impl_isSupportedProperty_nothrow( *loopAffected ) )
1815 impl_updateDependentProperty_nothrow( *loopAffected, _rxInspectorUI );
1819 //------------------------------------------------------------------------
1820 void FormComponentPropertyHandler::impl_updateDependentProperty_nothrow( PropertyId _nPropId, const Reference< XObjectInspectorUI >& _rxInspectorUI ) const
1824 switch ( _nPropId )
1826 // ----- StringItemList -----
1827 case PROPERTY_ID_STRINGITEMLIST:
1829 ListSourceType eLSType = ListSourceType_VALUELIST;
1830 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_LISTSOURCETYPE ) >>= eLSType );
1832 ::rtl::OUString sListSource;
1834 Sequence< ::rtl::OUString > aListSource;
1835 Any aListSourceValue( impl_getPropertyValue_throw( PROPERTY_LISTSOURCE ) );
1836 if ( aListSourceValue >>= aListSource )
1838 if ( aListSource.getLength() )
1839 sListSource = aListSource[0];
1841 else
1842 OSL_VERIFY( aListSourceValue >>= sListSource );
1845 sal_Bool bIsEnabled = ( ( eLSType == ListSourceType_VALUELIST )
1846 || ( sListSource.getLength() == 0 )
1848 _rxInspectorUI->enablePropertyUI( PROPERTY_STRINGITEMLIST, bIsEnabled );
1850 break; // case PROPERTY_ID_STRINGITEMLIST
1852 // ----- BoundColumn -----
1853 case PROPERTY_ID_BOUNDCOLUMN:
1855 ::rtl::OUString sControlSource;
1856 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_CONTROLSOURCE ) >>= sControlSource );
1858 ListSourceType eLSType = ListSourceType_VALUELIST;
1859 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_LISTSOURCETYPE ) >>= eLSType );
1861 _rxInspectorUI->enablePropertyUI( PROPERTY_BOUNDCOLUMN,
1862 ( sControlSource.getLength() > 0 )
1863 && ( eLSType != ListSourceType_TABLEFIELDS )
1864 && ( eLSType != ListSourceType_VALUELIST )
1867 break; // case PROPERTY_ID_BOUNDCOLUMN
1869 // ----- ScaleImage, ScaleMode -----
1870 case PROPERTY_ID_SCALEIMAGE:
1871 case PROPERTY_ID_SCALE_MODE:
1873 ::rtl::OUString sControlSource;
1874 if ( impl_isSupportedProperty_nothrow( PROPERTY_ID_CONTROLSOURCE ) )
1875 impl_getPropertyValue_throw( PROPERTY_CONTROLSOURCE ) >>= sControlSource;
1877 ::rtl::OUString sImageURL;
1878 impl_getPropertyValue_throw( PROPERTY_IMAGE_URL ) >>= sImageURL;
1880 _rxInspectorUI->enablePropertyUI( impl_getPropertyNameFromId_nothrow( _nPropId ),
1881 ( sControlSource.getLength() != 0 ) || ( sImageURL.getLength() != 0 )
1884 break; // case PROPERTY_ID_SCALEIMAGE, PROPERTY_ID_SCALE_MODE
1886 // ----- InputRequired -----
1887 case PROPERTY_ID_INPUT_REQUIRED:
1889 ::rtl::OUString sControlSource;
1890 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_CONTROLSOURCE ) >>= sControlSource );
1892 sal_Bool bEmptyIsNULL = sal_False;
1893 sal_Bool bHasEmptyIsNULL = impl_componentHasProperty_throw( PROPERTY_EMPTY_IS_NULL );
1894 if ( bHasEmptyIsNULL )
1895 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_EMPTY_IS_NULL ) >>= bEmptyIsNULL );
1897 // if the control is not bound to a DB field, there is no sense in having the "Input required"
1898 // property
1899 // Also, if an empty input of this control are *not* written as NULL, but as empty strings,
1900 // then "Input required" does not make sense, too (since there's always an input, even if the control
1901 // is empty).
1902 _rxInspectorUI->enablePropertyUI( PROPERTY_INPUT_REQUIRED,
1903 ( sControlSource.getLength() != 0 ) && ( !bHasEmptyIsNULL || bEmptyIsNULL )
1906 break;
1908 // ----- SelectedItems, DefaultSelection -----
1909 case PROPERTY_ID_SELECTEDITEMS:
1910 case PROPERTY_ID_DEFAULT_SELECT_SEQ:
1912 Sequence< ::rtl::OUString > aEntries;
1913 impl_getPropertyValue_throw( PROPERTY_STRINGITEMLIST ) >>= aEntries;
1914 bool isEnabled = aEntries.getLength() != 0;
1916 if ( ( m_nClassId == FormComponentType::LISTBOX ) && ( m_eComponentClass == eFormControl ) )
1918 ListSourceType eLSType = ListSourceType_VALUELIST;
1919 impl_getPropertyValue_throw( PROPERTY_LISTSOURCETYPE ) >>= eLSType;
1920 isEnabled &= ( eLSType == ListSourceType_VALUELIST );
1922 _rxInspectorUI->enablePropertyUIElements( impl_getPropertyNameFromId_nothrow( _nPropId ),
1923 PropertyLineElement::PrimaryButton, isEnabled );
1925 break; // case PROPERTY_ID_DEFAULT_SELECT_SEQ
1927 // ----- TargetFrame ------
1928 case PROPERTY_ID_TARGET_FRAME:
1930 ::rtl::OUString sTargetURL;
1931 impl_getPropertyValue_throw( PROPERTY_TARGET_URL ) >>= sTargetURL;
1932 FormButtonType eButtonType( FormButtonType_URL );
1933 if ( 0 != m_nClassId )
1935 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_BUTTONTYPE ) >>= eButtonType );
1937 // if m_nClassId is 0, then we're inspecting a form. In this case, eButtonType is always
1938 // FormButtonType_URL here
1939 _rxInspectorUI->enablePropertyUI( PROPERTY_TARGET_FRAME,
1940 ( eButtonType == FormButtonType_URL ) && ( sTargetURL.getLength() > 0 )
1943 break;
1945 // ----- Order ------
1946 case PROPERTY_ID_SORT:
1947 // ----- Filter ------
1948 case PROPERTY_ID_FILTER:
1950 Reference< XConnection > xConnection;
1951 bool bAllowEmptyDS = ::dbtools::isEmbeddedInDatabase( m_xComponent, xConnection );
1953 // if there's no escape processing, we cannot enter any values for this property
1954 sal_Bool bDoEscapeProcessing( sal_False );
1955 impl_getPropertyValue_throw( PROPERTY_ESCAPE_PROCESSING ) >>= bDoEscapeProcessing;
1956 _rxInspectorUI->enablePropertyUI(
1957 impl_getPropertyNameFromId_nothrow( _nPropId ),
1958 bDoEscapeProcessing
1961 // also care for the browse button - enabled if we have escape processing, and a valid
1962 // data source signature
1963 _rxInspectorUI->enablePropertyUIElements(
1964 impl_getPropertyNameFromId_nothrow( _nPropId ),
1965 PropertyLineElement::PrimaryButton,
1966 impl_hasValidDataSourceSignature_nothrow( m_xComponent, bAllowEmptyDS )
1967 && bDoEscapeProcessing
1970 break; // case PROPERTY_ID_FILTER:
1972 // ----- Command -----
1973 case PROPERTY_ID_COMMAND:
1975 sal_Int32 nCommandType( CommandType::COMMAND );
1976 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_COMMANDTYPE ) >>= nCommandType );
1978 impl_ensureRowsetConnection_nothrow();
1979 Reference< XConnection > xConnection = m_xRowSetConnection.getTyped();
1980 bool bAllowEmptyDS = false;
1981 if ( !xConnection.is() )
1982 bAllowEmptyDS = ::dbtools::isEmbeddedInDatabase( m_xComponent, xConnection );
1984 bool doEnable = ( nCommandType == CommandType::COMMAND )
1985 && ( m_xRowSetConnection.is()
1986 || xConnection.is()
1987 || impl_hasValidDataSourceSignature_nothrow( m_xComponent, bAllowEmptyDS)
1990 _rxInspectorUI->enablePropertyUIElements(
1991 PROPERTY_COMMAND,
1992 PropertyLineElement::PrimaryButton,
1993 doEnable
1996 break; // case PROPERTY_ID_COMMAND
1998 // ----- DetailFields -----
1999 case PROPERTY_ID_DETAILFIELDS:
2001 Reference< XConnection > xConnection;
2002 bool bAllowEmptyDS = ::dbtools::isEmbeddedInDatabase( m_xComponent, xConnection );
2004 // both our current form, and it's parent form, need to have a valid
2005 // data source signature
2006 bool bDoEnableMasterDetailFields =
2007 impl_hasValidDataSourceSignature_nothrow( m_xComponent, bAllowEmptyDS )
2008 && impl_hasValidDataSourceSignature_nothrow( Reference< XPropertySet >( m_xObjectParent, UNO_QUERY ), bAllowEmptyDS );
2010 // in opposite to the other properties, here in real *two* properties are
2011 // affected
2012 _rxInspectorUI->enablePropertyUIElements( PROPERTY_DETAILFIELDS, PropertyLineElement::PrimaryButton, bDoEnableMasterDetailFields );
2013 _rxInspectorUI->enablePropertyUIElements( PROPERTY_MASTERFIELDS, PropertyLineElement::PrimaryButton, bDoEnableMasterDetailFields );
2015 break;
2017 default:
2018 OSL_ENSURE( false, "FormComponentPropertyHandler::impl_updateDependentProperty_nothrow: unexpected property to update!" );
2019 break;
2021 } // switch
2023 catch( const Exception& )
2025 OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_updateDependentProperty_nothrow: caught an exception!" );
2029 //------------------------------------------------------------------------
2030 void SAL_CALL FormComponentPropertyHandler::disposing()
2032 FormComponentPropertyHandler_Base::disposing();
2033 if ( m_xCommandDesigner.is() && m_xCommandDesigner->isActive() )
2034 m_xCommandDesigner->dispose();
2037 //------------------------------------------------------------------------
2038 sal_Bool SAL_CALL FormComponentPropertyHandler::suspend( sal_Bool _bSuspend ) throw (RuntimeException)
2040 ::osl::MutexGuard aGuard( m_aMutex );
2041 if ( _bSuspend )
2042 if ( m_xCommandDesigner.is() && m_xCommandDesigner->isActive() )
2043 return m_xCommandDesigner->suspend();
2044 return sal_True;
2047 //------------------------------------------------------------------------
2048 void FormComponentPropertyHandler::impl_initComponentMetaData_throw()
2052 //////////////////////////////////////////////////////////////////
2053 // component class
2054 m_eComponentClass = eUnknown;
2056 if ( impl_componentHasProperty_throw( PROPERTY_WIDTH )
2057 && impl_componentHasProperty_throw( PROPERTY_HEIGHT )
2058 && impl_componentHasProperty_throw( PROPERTY_POSITIONX )
2059 && impl_componentHasProperty_throw( PROPERTY_POSITIONY )
2060 && impl_componentHasProperty_throw( PROPERTY_STEP )
2061 && impl_componentHasProperty_throw( PROPERTY_TABINDEX )
2064 m_eComponentClass = eDialogControl;
2066 else
2068 m_eComponentClass = eFormControl;
2071 //////////////////////////////////////////////////////////////////
2072 // (database) sub form?
2073 Reference< XForm > xAsForm( m_xComponent, UNO_QUERY );
2074 if ( xAsForm.is() )
2076 Reference< XChild > xFormAsChild( xAsForm, UNO_QUERY );
2077 Reference< XForm > xFormsParent;
2078 if ( xFormAsChild.is() )
2079 xFormsParent = xFormsParent.query( xFormAsChild->getParent() );
2080 m_bComponentIsSubForm = xFormsParent.is();
2083 //////////////////////////////////////////////////////////////////
2084 // ClassId
2085 Reference< XChild > xCompAsChild( m_xComponent, UNO_QUERY );
2086 if ( xCompAsChild.is() )
2087 m_xObjectParent = xCompAsChild->getParent();
2089 //////////////////////////////////////////////////////////////////
2090 // ClassId
2091 impl_classifyControlModel_throw();
2093 catch( const RuntimeException& )
2095 throw;
2097 catch( const Exception& )
2099 OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_initComponentMetaData_throw: caught an exception!" );
2103 //------------------------------------------------------------------------
2104 void FormComponentPropertyHandler::impl_classifyControlModel_throw( )
2106 if ( impl_componentHasProperty_throw( PROPERTY_CLASSID ) )
2108 OSL_VERIFY( m_xComponent->getPropertyValue( PROPERTY_CLASSID ) >>= m_nClassId );
2110 else if ( eDialogControl == m_eComponentClass )
2112 Reference< XControlModel > xControlModel( m_xComponent, UNO_QUERY );
2113 Reference< XServiceInfo > xServiceInfo( m_xComponent, UNO_QUERY );
2114 if ( xServiceInfo.is() )
2116 // it's a control model, and can tell about it's supported services
2117 m_nClassId = FormComponentType::CONTROL;
2119 const sal_Char* aControlModelServiceNames[] =
2121 "UnoControlButtonModel",
2122 "UnoControlCheckBoxModel",
2123 "UnoControlComboBoxModel",
2124 "UnoControlCurrencyFieldModel",
2125 "UnoControlDateFieldModel",
2126 "UnoControlEditModel",
2127 "UnoControlFileControlModel",
2128 "UnoControlFixedTextModel",
2129 "UnoControlGroupBoxModel",
2130 "UnoControlImageControlModel",
2131 "UnoControlListBoxModel",
2132 "UnoControlNumericFieldModel",
2133 "UnoControlPatternFieldModel",
2134 "UnoControlRadioButtonModel",
2135 "UnoControlScrollBarModel",
2136 "UnoControlSpinButtonModel",
2137 "UnoControlTimeFieldModel",
2139 "UnoControlFixedLineModel",
2140 "UnoControlFormattedFieldModel",
2141 "UnoControlProgressBarModel"
2143 const sal_Int16 nClassIDs[] =
2145 FormComponentType::COMMANDBUTTON,
2146 FormComponentType::CHECKBOX,
2147 FormComponentType::COMBOBOX,
2148 FormComponentType::CURRENCYFIELD,
2149 FormComponentType::DATEFIELD,
2150 FormComponentType::TEXTFIELD,
2151 FormComponentType::FILECONTROL,
2152 FormComponentType::FIXEDTEXT,
2153 FormComponentType::GROUPBOX,
2154 FormComponentType::IMAGECONTROL,
2155 FormComponentType::LISTBOX,
2156 FormComponentType::NUMERICFIELD,
2157 FormComponentType::PATTERNFIELD,
2158 FormComponentType::RADIOBUTTON,
2159 FormComponentType::SCROLLBAR,
2160 FormComponentType::SPINBUTTON,
2161 FormComponentType::TIMEFIELD,
2163 ControlType::FIXEDLINE,
2164 ControlType::FORMATTEDFIELD,
2165 ControlType::PROGRESSBAR
2168 sal_Int32 nKnownControlTypes = sizeof( aControlModelServiceNames ) / sizeof( aControlModelServiceNames[ 0 ] );
2169 OSL_ENSURE( nKnownControlTypes == sizeof( nClassIDs ) / sizeof( nClassIDs[ 0 ] ),
2170 "FormComponentPropertyHandler::impl_classifyControlModel_throw: inconsistence" );
2172 for ( sal_Int32 i = 0; i < nKnownControlTypes; ++i )
2174 ::rtl::OUString sServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt." ) );
2175 sServiceName += ::rtl::OUString::createFromAscii( aControlModelServiceNames[ i ] );
2177 if ( xServiceInfo->supportsService( sServiceName ) )
2179 m_nClassId = nClassIDs[ i ];
2180 break;
2187 //------------------------------------------------------------------------
2188 void FormComponentPropertyHandler::impl_normalizePropertyValue_nothrow( Any& _rValue, PropertyId _nPropId ) const
2190 switch ( _nPropId )
2192 case PROPERTY_ID_TABSTOP:
2193 if ( !_rValue.hasValue() )
2195 switch ( m_nClassId )
2197 case FormComponentType::COMMANDBUTTON:
2198 case FormComponentType::RADIOBUTTON:
2199 case FormComponentType::CHECKBOX:
2200 case FormComponentType::TEXTFIELD:
2201 case FormComponentType::LISTBOX:
2202 case FormComponentType::COMBOBOX:
2203 case FormComponentType::FILECONTROL:
2204 case FormComponentType::DATEFIELD:
2205 case FormComponentType::TIMEFIELD:
2206 case FormComponentType::NUMERICFIELD:
2207 case ControlType::FORMATTEDFIELD:
2208 case FormComponentType::CURRENCYFIELD:
2209 case FormComponentType::PATTERNFIELD:
2210 _rValue = makeAny( (sal_Bool)sal_True );
2211 break;
2212 default:
2213 _rValue = makeAny( (sal_Bool)sal_False );
2214 break;
2217 break;
2221 //------------------------------------------------------------------------
2222 bool FormComponentPropertyHandler::impl_shouldExcludeProperty_nothrow( const Property& _rProperty ) const
2224 OSL_ENSURE( _rProperty.Handle == m_pInfoService->getPropertyId( _rProperty.Name ),
2225 "FormComponentPropertyHandler::impl_shouldExcludeProperty_nothrow: insonsistency in the property!" );
2227 if ( _rProperty.Handle == PROPERTY_ID_CONTROLLABEL )
2228 // prevent that this is caught below
2229 return false;
2231 if ( ( _rProperty.Type.getTypeClass() == TypeClass_INTERFACE )
2232 || ( _rProperty.Type.getTypeClass() == TypeClass_ARRAY )
2233 || ( _rProperty.Type.getTypeClass() == TypeClass_UNKNOWN )
2235 return true;
2237 if ( ( _rProperty.Attributes & PropertyAttribute::TRANSIENT ) && ( m_eComponentClass != eDialogControl ) )
2238 // strange enough, dialog controls declare a lot of their properties as transient
2239 return true;
2241 if ( _rProperty.Attributes & PropertyAttribute::READONLY )
2242 return true;
2244 switch ( _rProperty.Handle )
2246 case PROPERTY_ID_MASTERFIELDS:
2247 case PROPERTY_ID_DETAILFIELDS:
2248 if ( !m_bComponentIsSubForm )
2249 // no master and detail fields for forms which are no sub forms
2250 return true;
2251 break;
2253 case PROPERTY_ID_DATASOURCE:
2255 // don't show DataSource if the component is part of an embedded form document
2256 Reference< XConnection > xConn;
2257 if ( isEmbeddedInDatabase( m_xComponent, xConn ) )
2258 return true;
2260 break;
2262 case PROPERTY_ID_TEXT:
2263 // don't show the "Text" property of formatted fields
2264 if ( ControlType::FORMATTEDFIELD == m_nClassId )
2265 return true;
2266 break;
2268 case PROPERTY_ID_FORMATKEY:
2269 case PROPERTY_ID_EFFECTIVE_MIN:
2270 case PROPERTY_ID_EFFECTIVE_MAX:
2271 case PROPERTY_ID_EFFECTIVE_DEFAULT:
2272 case PROPERTY_ID_EFFECTIVE_VALUE:
2273 // only if the set has a formats supplier, too
2274 if ( !impl_componentHasProperty_throw( PROPERTY_FORMATSSUPPLIER ) )
2275 return true;
2276 // (form) date and time fields also have a formats supplier, but the format itself
2277 // is reflected in another property
2278 if ( ( FormComponentType::DATEFIELD == m_nClassId )
2279 || ( FormComponentType::TIMEFIELD == m_nClassId )
2281 return true;
2282 break;
2284 case PROPERTY_ID_SCALEIMAGE:
2285 if ( impl_componentHasProperty_throw( PROPERTY_SCALE_MODE ) )
2286 // ScaleImage is superseded by ScaleMode
2287 return true;
2288 break;
2290 case PROPERTY_ID_WRITING_MODE:
2291 if ( !SvtCTLOptions().IsCTLFontEnabled() )
2292 return true;
2293 break;
2296 sal_uInt32 nPropertyUIFlags = m_pInfoService->getPropertyUIFlags( _rProperty.Handle );
2298 // don't show experimental properties unless allowed to do so
2299 if ( ( nPropertyUIFlags & PROP_FLAG_EXPERIMENTAL ) != 0 )
2301 if ( true ) // TODO
2302 return true;
2305 // no data properties if no Base is installed. #124939#
2306 // This fix is not intendend to appear on the main trunk. If you find it there,
2307 // please tell me! frank.schoenheit@sun.com
2308 if ( ( nPropertyUIFlags & PROP_FLAG_DATA_PROPERTY ) != 0 )
2309 if ( !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
2310 return true;
2312 return false;
2315 //------------------------------------------------------------------------
2316 Reference< XRowSet > FormComponentPropertyHandler::impl_getRowSet_throw( ) const
2318 Reference< XRowSet > xRowSet = m_xRowSet;
2319 if ( !xRowSet.is() )
2321 xRowSet.set( m_xComponent, UNO_QUERY );
2322 if ( !xRowSet.is() )
2324 xRowSet = Reference< XRowSet >( m_xObjectParent, UNO_QUERY );
2325 if ( !xRowSet.is() )
2327 // are we inspecting a grid column?
2328 if (Reference< XGridColumnFactory >( m_xObjectParent, UNO_QUERY) .is())
2329 { // yes
2330 Reference< XChild > xParentAsChild( m_xObjectParent, UNO_QUERY );
2331 if ( xParentAsChild.is() )
2332 xRowSet = Reference< XRowSet >( xParentAsChild->getParent(), UNO_QUERY );
2335 if ( !xRowSet.is() )
2336 xRowSet = m_xRowSet;
2338 DBG_ASSERT( xRowSet.is(), "FormComponentPropertyHandler::impl_getRowSet_throw: could not obtain the rowset for the introspectee!" );
2340 return xRowSet;
2343 //------------------------------------------------------------------------
2344 Reference< XRowSet > FormComponentPropertyHandler::impl_getRowSet_nothrow( ) const
2346 Reference< XRowSet > xReturn;
2349 xReturn = impl_getRowSet_throw();
2351 catch( const Exception& )
2353 OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_getRowSet_nothrow: caught an exception!" );
2355 return xReturn;
2358 //------------------------------------------------------------------------
2359 void FormComponentPropertyHandler::impl_initFieldList_nothrow( ::std::vector< ::rtl::OUString >& _rFieldNames ) const
2361 clearContainer( _rFieldNames );
2364 WaitCursor aWaitCursor( impl_getDefaultDialogParent_nothrow() );
2366 Reference< XPreparedStatement > xStatement;
2368 // get the form of the control we're inspecting
2369 Reference< XPropertySet > xFormSet( impl_getRowSet_throw(), UNO_QUERY );
2370 if ( !xFormSet.is() )
2371 return;
2373 ::rtl::OUString sObjectName;
2374 OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_COMMAND ) >>= sObjectName );
2375 // when there is no command we don't need to ask for columns
2376 if ( sObjectName.getLength() && impl_ensureRowsetConnection_nothrow() )
2378 ::rtl::OUString aDatabaseName;
2379 OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_DATASOURCE ) >>= aDatabaseName );
2380 sal_Int32 nObjectType = CommandType::COMMAND;
2381 OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_COMMANDTYPE ) >>= nObjectType );
2383 Sequence< ::rtl::OUString > aFields( ::dbtools::getFieldNamesByCommandDescriptor( m_xRowSetConnection, nObjectType, sObjectName ) );
2385 const ::rtl::OUString* pFields = aFields.getConstArray();
2386 for ( sal_Int32 i = 0; i < aFields.getLength(); ++i, ++pFields )
2387 _rFieldNames.push_back( *pFields );
2390 catch (Exception&)
2392 DBG_ERROR( "FormComponentPropertyHandler::impl_initFieldList_nothrow: caught an exception!" );
2396 //------------------------------------------------------------------------
2397 void FormComponentPropertyHandler::impl_clearRowsetConnection_nothrow()
2399 m_xRowSetConnection.clear();
2402 //------------------------------------------------------------------------
2403 void FormComponentPropertyHandler::impl_displaySQLError_nothrow( const ::dbtools::SQLExceptionInfo& _rErrorDescriptor ) const
2405 ::dbtools::showError( _rErrorDescriptor, VCLUnoHelper::GetInterface( impl_getDefaultDialogParent_nothrow() ), m_aContext.getLegacyServiceFactory() );
2408 //------------------------------------------------------------------------
2409 bool FormComponentPropertyHandler::impl_ensureRowsetConnection_nothrow() const
2411 if ( !m_xRowSetConnection.is() )
2413 uno::Reference<sdbc::XConnection> xConnection(m_aContext.getContextValueByAsciiName( "ActiveConnection" ),uno::UNO_QUERY);
2414 m_xRowSetConnection.reset(xConnection,::dbtools::SharedConnection::NoTakeOwnership);
2416 if ( m_xRowSetConnection.is() )
2417 return true;
2419 Reference< XRowSet > xRowSet( impl_getRowSet_throw() );
2420 Reference< XPropertySet > xRowSetProps( xRowSet, UNO_QUERY );
2422 // connect the row set - this is delegated to elsewhere - while observing errors
2423 SQLExceptionInfo aError;
2426 if ( xRowSetProps.is() )
2428 WaitCursor aWaitCursor( impl_getDefaultDialogParent_nothrow() );
2429 m_xRowSetConnection = ::dbtools::ensureRowSetConnection( xRowSet, m_aContext.getLegacyServiceFactory(), false );
2432 catch ( const SQLException& ) { aError = SQLExceptionInfo( ::cppu::getCaughtException() ); }
2433 catch ( const WrappedTargetException& e ) { aError = SQLExceptionInfo( e.TargetException ); }
2434 catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
2436 // report errors, if necessary
2437 if ( aError.isValid() )
2439 ::rtl::OUString sDataSourceName;
2442 xRowSetProps->getPropertyValue( PROPERTY_DATASOURCE ) >>= sDataSourceName;
2444 catch( const Exception& )
2446 DBG_ERROR( "FormComponentPropertyHandler::impl_ensureRowsetConnection_nothrow: caught an exception during error handling!" );
2448 // additional info about what happended
2449 String sInfo( PcrRes( RID_STR_UNABLETOCONNECT ) );
2450 INetURLObject aParser( sDataSourceName );
2451 if ( aParser.GetProtocol() != INET_PROT_NOT_VALID )
2452 sDataSourceName = aParser.getBase( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
2453 sInfo.SearchAndReplaceAllAscii( "$name$", sDataSourceName );
2455 SQLContext aContext;
2456 aContext.Message = sInfo;
2457 aContext.NextException = aError.get();
2458 impl_displaySQLError_nothrow( aContext );
2461 return m_xRowSetConnection.is();
2464 //------------------------------------------------------------------------
2465 void FormComponentPropertyHandler::impl_describeCursorSource_nothrow( LineDescriptor& _out_rProperty, const Reference< XPropertyControlFactory >& _rxControlFactory ) const
2469 WaitCursor aWaitCursor( impl_getDefaultDialogParent_nothrow() );
2471 ////////////////////////////////////////////////////////////
2472 // Setzen der UI-Daten
2473 _out_rProperty.DisplayName = m_pInfoService->getPropertyTranslation( PROPERTY_ID_COMMAND );
2475 _out_rProperty.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( PROPERTY_ID_COMMAND ) );
2476 _out_rProperty.PrimaryButtonId = UID_PROP_DLG_SQLCOMMAND;
2478 ////////////////////////////////////////////////////////////
2479 sal_Int32 nCommandType = CommandType::COMMAND;
2480 impl_getPropertyValue_throw( PROPERTY_COMMANDTYPE ) >>= nCommandType;
2482 switch ( nCommandType )
2484 case CommandType::TABLE:
2485 case CommandType::QUERY:
2487 ::std::vector< ::rtl::OUString > aNames;
2488 if ( impl_ensureRowsetConnection_nothrow() )
2490 if ( nCommandType == CommandType::TABLE )
2491 impl_fillTableNames_throw( aNames );
2492 else
2493 impl_fillQueryNames_throw( aNames );
2495 _out_rProperty.Control = PropertyHandlerHelper::createComboBoxControl( _rxControlFactory, aNames, sal_False, sal_True );
2497 break;
2499 default:
2500 _out_rProperty.Control = _rxControlFactory->createPropertyControl( PropertyControlType::MultiLineTextField, sal_False );
2501 break;
2504 catch (Exception&)
2506 DBG_ERROR("FormComponentPropertyHandler::impl_describeCursorSource_nothrow: caught an exception !");
2510 //------------------------------------------------------------------------
2511 void FormComponentPropertyHandler::impl_fillTableNames_throw( ::std::vector< ::rtl::OUString >& _out_rNames ) const
2513 OSL_PRECOND( m_xRowSetConnection.is(), "FormComponentPropertyHandler::impl_fillTableNames_throw: need a connection!" );
2514 _out_rNames.resize( 0 );
2516 Reference< XTablesSupplier > xSupplyTables( m_xRowSetConnection, UNO_QUERY );
2517 Reference< XNameAccess > xTableNames;
2518 if ( xSupplyTables.is() )
2519 xTableNames = xSupplyTables->getTables();
2520 DBG_ASSERT( xTableNames.is(), "FormComponentPropertyHandler::impl_fillTableNames_throw: no way to obtain the tables of the connection!" );
2521 if ( !xTableNames.is() )
2522 return;
2524 Sequence< ::rtl::OUString> aTableNames = xTableNames->getElementNames();
2525 sal_uInt32 nCount = aTableNames.getLength();
2526 const ::rtl::OUString* pTableNames = aTableNames.getConstArray();
2528 for ( sal_uInt32 i=0; i<nCount; ++i ,++pTableNames )
2529 _out_rNames.push_back( *pTableNames );
2532 //------------------------------------------------------------------------
2533 void FormComponentPropertyHandler::impl_fillQueryNames_throw( ::std::vector< ::rtl::OUString >& _out_rNames ) const
2535 OSL_PRECOND( m_xRowSetConnection.is(), "FormComponentPropertyHandler::impl_fillQueryNames_throw: need a connection!" );
2536 _out_rNames.resize( 0 );
2538 Reference< XQueriesSupplier > xSupplyQueries( m_xRowSetConnection, UNO_QUERY );
2539 Reference< XNameAccess > xQueryNames;
2540 if ( xSupplyQueries.is() )
2541 xQueryNames = xSupplyQueries->getQueries();
2542 DBG_ASSERT( xQueryNames.is(), "FormComponentPropertyHandler::impl_fillQueryNames_throw: no way to obtain the queries of the connection!" );
2543 if ( !xQueryNames.is() )
2544 return;
2546 Sequence< ::rtl::OUString> aQueryNames = xQueryNames->getElementNames();
2547 sal_uInt32 nCount = aQueryNames.getLength();
2548 const ::rtl::OUString* pQueryNames = aQueryNames.getConstArray();
2550 for ( sal_uInt32 i=0; i<nCount; i++, ++pQueryNames )
2551 _out_rNames.push_back( *pQueryNames );
2554 //------------------------------------------------------------------------
2555 void FormComponentPropertyHandler::impl_describeListSourceUI_throw( LineDescriptor& _out_rDescriptor, const Reference< XPropertyControlFactory >& _rxControlFactory ) const
2557 OSL_PRECOND( m_xComponent.is(), "FormComponentPropertyHandler::impl_describeListSourceUI_throw: no component!" );
2559 ////////////////////////////////////////////////////////////
2560 // Auslesen des ListSourceTypes
2561 Any aListSourceType( m_xComponent->getPropertyValue( PROPERTY_LISTSOURCETYPE ) );
2563 sal_Int32 nListSourceType = ListSourceType_VALUELIST;
2564 ::cppu::enum2int( nListSourceType, aListSourceType );
2566 _out_rDescriptor.DisplayName = m_pInfoService->getPropertyTranslation( PROPERTY_ID_LISTSOURCE );
2567 _out_rDescriptor.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( PROPERTY_ID_LISTSOURCE ) );
2569 ////////////////////////////////////////////////////////////
2570 // Enums setzen
2571 switch( nListSourceType )
2573 case ListSourceType_VALUELIST:
2574 _out_rDescriptor.Control = _rxControlFactory->createPropertyControl( PropertyControlType::StringListField, sal_False );
2575 break;
2577 case ListSourceType_TABLEFIELDS:
2578 case ListSourceType_TABLE:
2579 case ListSourceType_QUERY:
2581 ::std::vector< ::rtl::OUString > aListEntries;
2582 if ( impl_ensureRowsetConnection_nothrow() )
2584 if ( nListSourceType == ListSourceType_QUERY )
2585 impl_fillQueryNames_throw( aListEntries );
2586 else
2587 impl_fillTableNames_throw( aListEntries );
2589 _out_rDescriptor.Control = PropertyHandlerHelper::createComboBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
2591 break;
2592 case ListSourceType_SQL:
2593 case ListSourceType_SQLPASSTHROUGH:
2594 impl_ensureRowsetConnection_nothrow();
2595 _out_rDescriptor.HasPrimaryButton = m_xRowSetConnection.is();
2596 break;
2600 //------------------------------------------------------------------------
2601 bool FormComponentPropertyHandler::impl_dialogListSelection_nothrow( const ::rtl::OUString& _rProperty, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2603 OSL_PRECOND( m_pInfoService.get(), "FormComponentPropertyHandler::impl_dialogListSelection_nothrow: no property meta data!" );
2605 String sPropertyUIName( m_pInfoService->getPropertyTranslation( m_pInfoService->getPropertyId( _rProperty ) ) );
2606 ListSelectionDialog aDialog( impl_getDefaultDialogParent_nothrow(), m_xComponent, _rProperty, sPropertyUIName );
2607 _rClearBeforeDialog.clear();
2608 return ( RET_OK == aDialog.Execute() );
2611 //------------------------------------------------------------------------
2612 bool FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow( bool _bFilter, ::rtl::OUString& _out_rSelectedClause, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2614 OSL_PRECOND( Reference< XRowSet >( m_xComponent, UNO_QUERY ).is(),
2615 "FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow: to be called for forms only!" );
2617 _out_rSelectedClause = ::rtl::OUString();
2618 bool bSuccess = false;
2619 SQLExceptionInfo aErrorInfo;
2622 if ( !impl_ensureRowsetConnection_nothrow() )
2623 return false;
2625 // get a composer for the statement which the form is currently based on
2626 Reference< XSingleSelectQueryComposer > xComposer( ::dbtools::getCurrentSettingsComposer( m_xComponent, m_aContext.getLegacyServiceFactory() ) );
2627 OSL_ENSURE( xComposer.is(), "FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow: could not obtain a composer!" );
2628 if ( !xComposer.is() )
2629 return false;
2631 ::rtl::OUString sPropertyUIName( m_pInfoService->getPropertyTranslation( _bFilter ? PROPERTY_ID_FILTER : PROPERTY_ID_SORT ) );
2633 const sal_Char* pAsciiServiceName = _bFilter ? "com.sun.star.sdb.FilterDialog" : "com.sun.star.sdb.OrderDialog";
2635 // create the dialog
2636 Reference< XExecutableDialog > xDialog;
2637 if ( !m_aContext.createComponent( pAsciiServiceName, xDialog ) )
2639 ShowServiceNotAvailableError( impl_getDefaultDialogParent_nothrow(), ::rtl::OUString::createFromAscii( pAsciiServiceName ), sal_True );
2640 return false;
2643 // initialize the dialog
2644 Reference< XPropertySet > xDialogProps( xDialog, UNO_QUERY_THROW );
2645 xDialogProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "QueryComposer" ) ), makeAny( xComposer ) );
2646 xDialogProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RowSet" ) ), makeAny( m_xComponent ) );
2647 xDialogProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ) ), makeAny( VCLUnoHelper::GetInterface( impl_getDefaultDialogParent_nothrow() ) ) );
2648 xDialogProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ), makeAny( sPropertyUIName ) );
2650 _rClearBeforeDialog.clear();
2651 bSuccess = ( xDialog->execute() != 0 );
2652 if ( bSuccess )
2653 _out_rSelectedClause = _bFilter ? xComposer->getFilter() : xComposer->getOrder();
2655 catch (SQLContext& e) { aErrorInfo = e; }
2656 catch (SQLWarning& e) { aErrorInfo = e; }
2657 catch (SQLException& e) { aErrorInfo = e; }
2658 catch( const Exception& )
2660 OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow: caught an exception!" );
2663 if ( aErrorInfo.isValid() )
2664 impl_displaySQLError_nothrow( aErrorInfo );
2666 return bSuccess;
2669 //------------------------------------------------------------------------
2670 bool FormComponentPropertyHandler::impl_dialogLinkedFormFields_nothrow( ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2672 Reference< XForm > xDetailForm( m_xComponent, UNO_QUERY );
2673 Reference< XForm > xMasterForm( m_xObjectParent, UNO_QUERY );
2674 uno::Reference<beans::XPropertySet> xMasterProp(m_xObjectParent,uno::UNO_QUERY);
2675 OSL_PRECOND( xDetailForm.is() && xMasterForm.is(), "FormComponentPropertyHandler::impl_dialogLinkedFormFields_nothrow: no forms!" );
2676 if ( !xDetailForm.is() || !xMasterForm.is() )
2677 return false;
2680 FormLinkDialog aDialog( impl_getDefaultDialogParent_nothrow(), m_xComponent, xMasterProp, m_aContext.getLegacyServiceFactory() );
2681 _rClearBeforeDialog.clear();
2682 return ( RET_OK == aDialog.Execute() );
2685 //------------------------------------------------------------------------
2686 bool FormComponentPropertyHandler::impl_dialogFormatting_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2688 bool bChanged = false;
2691 // create the itemset for the dialog
2692 SfxItemSet aCoreSet(SFX_APP()->GetPool(),
2693 SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_VALUE,
2694 SID_ATTR_NUMBERFORMAT_INFO, SID_ATTR_NUMBERFORMAT_INFO,
2695 0); // ripped this somewhere ... don't understand it :(
2697 // get the number formats supplier
2698 Reference< XNumberFormatsSupplier > xSupplier;
2699 m_xComponent->getPropertyValue( PROPERTY_FORMATSSUPPLIER ) >>= xSupplier;
2701 DBG_ASSERT(xSupplier.is(), "FormComponentPropertyHandler::impl_dialogFormatting_nothrow: invalid call !" );
2702 Reference< XUnoTunnel > xTunnel( xSupplier, UNO_QUERY_THROW );
2703 SvNumberFormatsSupplierObj* pSupplier =
2704 reinterpret_cast< SvNumberFormatsSupplierObj* >( xTunnel->getSomething( SvNumberFormatsSupplierObj::getUnoTunnelId() ) );
2705 DBG_ASSERT( pSupplier != NULL, "FormComponentPropertyHandler::impl_dialogFormatting_nothrow: invalid call !" );
2707 sal_Int32 nFormatKey = 0;
2708 impl_getPropertyValue_throw( PROPERTY_FORMATKEY ) >>= nFormatKey;
2709 aCoreSet.Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, nFormatKey ) );
2711 SvNumberFormatter* pFormatter = pSupplier->GetNumberFormatter();
2712 double dPreviewVal = OFormatSampleControl::getPreviewValue(pFormatter,nFormatKey);
2713 SvxNumberInfoItem aFormatter( pFormatter, dPreviewVal, SID_ATTR_NUMBERFORMAT_INFO );
2714 aCoreSet.Put( aFormatter );
2716 // a tab dialog with a single page
2717 ::std::auto_ptr< SfxSingleTabDialog > pDialog( new SfxSingleTabDialog( impl_getDefaultDialogParent_nothrow(), aCoreSet, 0 ) );
2718 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
2719 DBG_ASSERT( pFact, "CreateFactory fail!" );
2720 ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc( RID_SVXPAGE_NUMBERFORMAT );
2721 if ( !fnCreatePage )
2722 throw RuntimeException(); // caught below
2724 SfxTabPage* pPage = (*fnCreatePage)( pDialog.get(), aCoreSet );
2725 pDialog->SetTabPage( pPage );
2727 _rClearBeforeDialog.clear();
2728 if ( RET_OK == pDialog->Execute() )
2730 const SfxItemSet* pResult = pDialog->GetOutputItemSet();
2732 const SfxPoolItem* pItem = pResult->GetItem( SID_ATTR_NUMBERFORMAT_INFO );
2733 const SvxNumberInfoItem* pInfoItem = dynamic_cast< const SvxNumberInfoItem* >( pItem );
2734 if (pInfoItem && pInfoItem->GetDelCount())
2736 const sal_uInt32* pDeletedKeys = pInfoItem->GetDelArray();
2738 for (sal_uInt16 i=0; i< pInfoItem->GetDelCount(); ++i, ++pDeletedKeys)
2739 pFormatter->DeleteEntry(*pDeletedKeys);
2742 pItem = NULL;
2743 if ( SFX_ITEM_SET == pResult->GetItemState( SID_ATTR_NUMBERFORMAT_VALUE, sal_False, &pItem ) )
2745 _out_rNewValue <<= (sal_Int32)( static_cast< const SfxUInt32Item* >( pItem )->GetValue() );
2746 bChanged = true;
2750 catch( const Exception& )
2752 OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_dialogFormatting_nothrow: : caught an exception!" );
2754 return bChanged;
2757 //------------------------------------------------------------------------
2758 bool FormComponentPropertyHandler::impl_browseForImage_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2760 bool bIsLink = true;// reflect the legacy behavior
2761 ::rtl::OUString aStrTrans = m_pInfoService->getPropertyTranslation( PROPERTY_ID_IMAGE_URL );
2763 ::sfx2::FileDialogHelper aFileDlg(SFXWB_GRAPHIC);
2765 aFileDlg.SetTitle(aStrTrans);
2766 // non-linked images ( e.g. those located in the document
2767 // stream ) cannot *currently* be handled by openoffice basic dialogs.
2768 bool bHandleNonLink = ( m_eComponentClass == eFormControl );
2770 Reference< XFilePickerControlAccess > xController(aFileDlg.GetFilePicker(), UNO_QUERY);
2771 DBG_ASSERT(xController.is(), "FormComponentPropertyHandler::impl_browseForImage_nothrow: missing the controller interface on the file picker!");
2772 if (xController.is())
2774 // do a preview by default
2775 xController->setValue(ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0, ::cppu::bool2any(sal_True));
2777 xController->setValue(ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, ::cppu::bool2any(bIsLink));
2778 xController->enableControl(ExtendedFilePickerElementIds::CHECKBOX_LINK, bHandleNonLink );
2782 ::rtl::OUString sCurValue;
2783 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_IMAGE_URL ) >>= sCurValue );
2784 if ( sCurValue.getLength() != 0 && sCurValue.compareToAscii(GRAPHOBJ_URLPREFIX, RTL_CONSTASCII_LENGTH(GRAPHOBJ_URLPREFIX) ) != 0 )
2786 aFileDlg.SetDisplayDirectory( sCurValue );
2787 // TODO: need to set the display directory _and_ the default name
2790 _rClearBeforeDialog.clear();
2791 bool bSuccess = ( 0 == aFileDlg.Execute() );
2792 if ( bSuccess )
2794 if ( bHandleNonLink && xController.is() )
2796 xController->getValue(ExtendedFilePickerElementIds::CHECKBOX_LINK, 0) >>= bIsLink;
2798 if ( !bIsLink )
2800 Graphic aGraphic;
2801 aFileDlg.GetGraphic( aGraphic );
2803 Reference< graphic::XGraphicObject > xGrfObj = graphic::GraphicObject::create( m_aContext.getUNOContext() );
2804 xGrfObj->setGraphic( aGraphic.GetXGraphic() );
2807 _out_rNewValue <<= xGrfObj;
2810 else
2811 _out_rNewValue <<= (::rtl::OUString)aFileDlg.GetPath();
2813 return bSuccess;
2816 //------------------------------------------------------------------------
2817 bool FormComponentPropertyHandler::impl_browseForTargetURL_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2819 ::sfx2::FileDialogHelper aFileDlg( WB_3DLOOK );
2821 ::rtl::OUString sURL;
2822 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_TARGET_URL ) >>= sURL );
2823 INetURLObject aParser( sURL );
2824 if ( INET_PROT_FILE == aParser.GetProtocol() )
2825 // set the initial directory only for file-URLs. Everything else
2826 // is considered to be potentially expensive
2827 // 106126 - 2002/12/10 - fs@openoffice.org
2828 aFileDlg.SetDisplayDirectory( sURL );
2830 _rClearBeforeDialog.clear();
2831 bool bSuccess = ( 0 == aFileDlg.Execute() );
2832 if ( bSuccess )
2833 _out_rNewValue <<= (::rtl::OUString)aFileDlg.GetPath();
2834 return bSuccess;
2837 //------------------------------------------------------------------------
2838 bool FormComponentPropertyHandler::impl_executeFontDialog_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2840 bool bSuccess = false;
2842 // create an item set for use with the dialog
2843 SfxItemSet* pSet = NULL;
2844 SfxItemPool* pPool = NULL;
2845 SfxPoolItem** pDefaults = NULL;
2846 ControlCharacterDialog::createItemSet(pSet, pPool, pDefaults);
2847 ControlCharacterDialog::translatePropertiesToItems(m_xComponent, pSet);
2849 { // do this in an own block. The dialog needs to be destroyed before we call
2850 // destroyItemSet
2851 ControlCharacterDialog aDlg( impl_getDefaultDialogParent_nothrow(), *pSet );
2852 _rClearBeforeDialog.clear();
2853 if ( RET_OK == aDlg.Execute() )
2855 const SfxItemSet* pOut = aDlg.GetOutputItemSet();
2856 if ( pOut )
2858 Sequence< NamedValue > aFontPropertyValues;
2859 ControlCharacterDialog::translateItemsToProperties( *pOut, aFontPropertyValues );
2860 _out_rNewValue <<= aFontPropertyValues;
2861 bSuccess = true;
2866 ControlCharacterDialog::destroyItemSet(pSet, pPool, pDefaults);
2867 return bSuccess;
2870 //------------------------------------------------------------------------
2871 bool FormComponentPropertyHandler::impl_browseForDatabaseDocument_throw( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2873 ::sfx2::FileDialogHelper aFileDlg(WB_3DLOOK|WB_OPEN,::String::CreateFromAscii("sdatabase"));
2875 ::rtl::OUString sDataSource;
2876 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_DATASOURCE ) >>= sDataSource );
2877 INetURLObject aParser( sDataSource );
2878 if ( INET_PROT_FILE == aParser.GetProtocol() )
2879 // set the initial directory only for file-URLs. Everything else
2880 // is considered to be potentially expensive
2881 // 106126 - 2002/12/10 - fs@openoffice.org
2882 aFileDlg.SetDisplayDirectory( sDataSource );
2884 const String s_sDatabaseType = String::CreateFromAscii("StarOffice XML (Base)");
2885 const SfxFilter* pFilter = SfxFilter::GetFilterByName( s_sDatabaseType);
2886 OSL_ENSURE(pFilter,"Filter: StarOffice XML (Base) could not be found!");
2887 if ( pFilter )
2889 aFileDlg.SetCurrentFilter(pFilter->GetUIName());
2890 //aFileDlg.AddFilter(pFilter->GetFilterName(),pFilter->GetDefaultExtension());
2893 _rClearBeforeDialog.clear();
2894 bool bSuccess = ( 0 == aFileDlg.Execute() );
2895 if ( bSuccess )
2896 _out_rNewValue <<= (::rtl::OUString)aFileDlg.GetPath();
2897 return bSuccess;
2900 //------------------------------------------------------------------------
2901 bool FormComponentPropertyHandler::impl_dialogColorChooser_throw( sal_Int32 _nColorPropertyId, Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2903 sal_Int32 nColor = 0;
2904 OSL_VERIFY( impl_getPropertyValue_throw( impl_getPropertyNameFromId_nothrow( _nColorPropertyId ) ) >>= nColor );
2905 ::Color aColor( nColor );
2906 SvColorDialog aColorDlg( impl_getDefaultDialogParent_nothrow() );
2907 aColorDlg.SetColor( aColor );
2909 _rClearBeforeDialog.clear();
2910 if ( !aColorDlg.Execute() )
2911 return false;
2913 aColor = aColorDlg.GetColor();
2914 nColor = aColor.GetColor();
2915 _out_rNewValue <<= (sal_Int32)nColor;
2916 return true;
2919 //------------------------------------------------------------------------
2920 bool FormComponentPropertyHandler::impl_dialogChooseLabelControl_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2922 OSelectLabelDialog dlgSelectLabel( impl_getDefaultDialogParent_nothrow(), m_xComponent );
2923 _rClearBeforeDialog.clear();
2924 bool bSuccess = ( RET_OK == dlgSelectLabel.Execute() );
2925 if ( bSuccess )
2926 _out_rNewValue <<= dlgSelectLabel.GetSelected();
2927 return bSuccess;
2930 //------------------------------------------------------------------------
2931 Reference< XControlContainer > FormComponentPropertyHandler::impl_getContextControlContainer_nothrow() const
2933 Reference< XControlContainer > xControlContext(
2934 m_aContext.getContextValueByAsciiName( "ControlContext" ),
2935 UNO_QUERY );
2936 return xControlContext;
2939 //------------------------------------------------------------------------
2940 bool FormComponentPropertyHandler::impl_dialogChangeTabOrder_nothrow( ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2942 OSL_PRECOND( impl_getContextControlContainer_nothrow().is(), "FormComponentPropertyHandler::impl_dialogChangeTabOrder_nothrow: invalid control context!" );
2944 Reference< XTabControllerModel > xTabControllerModel( impl_getRowSet_nothrow(), UNO_QUERY );
2945 TabOrderDialog aDialog(
2946 impl_getDefaultDialogParent_nothrow(),
2947 xTabControllerModel,
2948 impl_getContextControlContainer_nothrow(),
2949 m_aContext.getLegacyServiceFactory()
2951 _rClearBeforeDialog.clear();
2952 return ( RET_OK == aDialog.Execute() );
2955 //------------------------------------------------------------------------
2956 namespace
2958 //--------------------------------------------------------------------
2959 //- ISQLCommandPropertyUI
2960 //--------------------------------------------------------------------
2961 class ISQLCommandPropertyUI : public ISQLCommandAdapter
2963 public:
2964 /** returns the empty-string-terminated list of names of properties
2965 whose UI is to be disabled while the SQL command property is
2966 being edited.
2968 virtual ::rtl::OUString* getPropertiesToDisable() = 0;
2971 //--------------------------------------------------------------------
2972 //- SQLCommandPropertyUI
2973 //--------------------------------------------------------------------
2974 class SQLCommandPropertyUI : public ISQLCommandPropertyUI
2976 protected:
2977 SQLCommandPropertyUI( const Reference< XPropertySet >& _rxObject )
2978 :m_xObject( _rxObject )
2980 if ( !m_xObject.is() )
2981 throw NullPointerException();
2984 virtual oslInterlockedCount SAL_CALL acquire()
2986 return osl_incrementInterlockedCount( &m_refCount );
2989 virtual oslInterlockedCount SAL_CALL release()
2991 if ( 0 == osl_decrementInterlockedCount( &m_refCount ) )
2993 delete this;
2994 return 0;
2996 return m_refCount;
2999 protected:
3000 Reference< XPropertySet > m_xObject;
3002 private:
3003 oslInterlockedCount m_refCount;
3006 //--------------------------------------------------------------------
3007 //- FormSQLCommandUI - declaration
3008 //--------------------------------------------------------------------
3009 class FormSQLCommandUI : public SQLCommandPropertyUI
3011 public:
3012 FormSQLCommandUI( const Reference< XPropertySet >& _rxForm );
3014 // ISQLCommandAdapter
3015 virtual ::rtl::OUString getSQLCommand() const;
3016 virtual sal_Bool getEscapeProcessing() const;
3017 virtual void setSQLCommand( const ::rtl::OUString& _rCommand ) const;
3018 virtual void setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const;
3020 // ISQLCommandPropertyUI
3021 virtual ::rtl::OUString* getPropertiesToDisable();
3024 //--------------------------------------------------------------------
3025 //- FormSQLCommandUI - implementation
3026 //--------------------------------------------------------------------
3027 //....................................................................
3028 FormSQLCommandUI::FormSQLCommandUI( const Reference< XPropertySet >& _rxForm )
3029 :SQLCommandPropertyUI( _rxForm )
3033 //....................................................................
3034 ::rtl::OUString FormSQLCommandUI::getSQLCommand() const
3036 ::rtl::OUString sCommand;
3037 OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_COMMAND ) >>= sCommand );
3038 return sCommand;
3041 //....................................................................
3042 sal_Bool FormSQLCommandUI::getEscapeProcessing() const
3044 sal_Bool bEscapeProcessing( sal_False );
3045 OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bEscapeProcessing );
3046 return bEscapeProcessing;
3049 //....................................................................
3050 void FormSQLCommandUI::setSQLCommand( const ::rtl::OUString& _rCommand ) const
3052 m_xObject->setPropertyValue( PROPERTY_COMMAND, makeAny( _rCommand ) );
3055 //....................................................................
3056 void FormSQLCommandUI::setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const
3058 m_xObject->setPropertyValue( PROPERTY_ESCAPE_PROCESSING, makeAny( _bEscapeProcessing ) );
3061 //....................................................................
3062 ::rtl::OUString* FormSQLCommandUI::getPropertiesToDisable()
3064 static ::rtl::OUString s_aCommandProps[] = {
3065 PROPERTY_DATASOURCE,
3066 PROPERTY_COMMAND,
3067 PROPERTY_COMMANDTYPE,
3068 PROPERTY_ESCAPE_PROCESSING,
3069 ::rtl::OUString()
3071 return s_aCommandProps;
3073 //--------------------------------------------------------------------
3074 //- ValueListCommandUI - declaration
3075 //--------------------------------------------------------------------
3076 class ValueListCommandUI : public SQLCommandPropertyUI
3078 public:
3079 ValueListCommandUI( const Reference< XPropertySet >& _rxListOrCombo );
3081 // ISQLCommandAdapter
3082 virtual ::rtl::OUString getSQLCommand() const;
3083 virtual sal_Bool getEscapeProcessing() const;
3084 virtual void setSQLCommand( const ::rtl::OUString& _rCommand ) const;
3085 virtual void setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const;
3087 // ISQLCommandPropertyUI
3088 virtual ::rtl::OUString* getPropertiesToDisable();
3089 private:
3090 mutable bool m_bPropertyValueIsList;
3093 //--------------------------------------------------------------------
3094 //- ValueListCommandUI - implementation
3095 //--------------------------------------------------------------------
3096 //....................................................................
3097 ValueListCommandUI::ValueListCommandUI( const Reference< XPropertySet >& _rxListOrCombo )
3098 :SQLCommandPropertyUI( _rxListOrCombo )
3099 ,m_bPropertyValueIsList( false )
3103 //....................................................................
3104 ::rtl::OUString ValueListCommandUI::getSQLCommand() const
3106 ::rtl::OUString sValue;
3107 m_bPropertyValueIsList = false;
3109 // for combo boxes, the property is a mere string
3110 Any aValue( m_xObject->getPropertyValue( PROPERTY_LISTSOURCE ) );
3111 if ( aValue >>= sValue )
3112 return sValue;
3114 Sequence< ::rtl::OUString > aValueList;
3115 if ( aValue >>= aValueList )
3117 m_bPropertyValueIsList = true;
3118 if ( aValueList.getLength() )
3119 sValue = aValueList[0];
3120 return sValue;
3123 OSL_ENSURE( false, "ValueListCommandUI::getSQLCommand: unexpected property type!" );
3124 return sValue;
3127 //....................................................................
3128 sal_Bool ValueListCommandUI::getEscapeProcessing() const
3130 enum ListSourceType eType( ListSourceType_SQL );
3131 OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_LISTSOURCETYPE ) >>= eType );
3132 OSL_ENSURE( ( eType == ListSourceType_SQL ) || ( eType == ListSourceType_SQLPASSTHROUGH ),
3133 "ValueListCommandUI::getEscapeProcessing: unexpected list source type!" );
3134 return ( eType == ListSourceType_SQL );
3137 //....................................................................
3138 void ValueListCommandUI::setSQLCommand( const ::rtl::OUString& _rCommand ) const
3140 Any aValue;
3141 if ( m_bPropertyValueIsList )
3142 aValue <<= Sequence< ::rtl::OUString >( &_rCommand, 1 );
3143 else
3144 aValue <<= _rCommand;
3145 m_xObject->setPropertyValue( PROPERTY_LISTSOURCE, aValue );
3148 //....................................................................
3149 void ValueListCommandUI::setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const
3151 m_xObject->setPropertyValue( PROPERTY_LISTSOURCETYPE, makeAny(
3152 _bEscapeProcessing ? ListSourceType_SQL : ListSourceType_SQLPASSTHROUGH ) );
3155 //....................................................................
3156 ::rtl::OUString* ValueListCommandUI::getPropertiesToDisable()
3158 static ::rtl::OUString s_aListSourceProps[] = {
3159 PROPERTY_LISTSOURCETYPE,
3160 PROPERTY_LISTSOURCE,
3161 ::rtl::OUString()
3163 return s_aListSourceProps;
3167 //------------------------------------------------------------------------
3168 bool FormComponentPropertyHandler::impl_doDesignSQLCommand_nothrow( const Reference< XObjectInspectorUI >& _rxInspectorUI, PropertyId _nDesignForProperty )
3172 if ( m_xCommandDesigner.is() )
3174 if ( m_xCommandDesigner->isActive() )
3176 m_xCommandDesigner->raise();
3177 return true;
3179 m_xCommandDesigner->dispose();
3180 m_xCommandDesigner.set( NULL );
3183 if ( !impl_ensureRowsetConnection_nothrow() )
3184 return false;
3186 Reference< XPropertySet > xComponentProperties( m_xComponent, UNO_QUERY_THROW );
3188 ::rtl::Reference< ISQLCommandPropertyUI > xCommandUI;
3189 switch ( _nDesignForProperty )
3191 case PROPERTY_ID_COMMAND:
3192 xCommandUI = new FormSQLCommandUI( xComponentProperties );
3193 break;
3194 case PROPERTY_ID_LISTSOURCE:
3195 xCommandUI = new ValueListCommandUI( xComponentProperties );
3196 break;
3197 default:
3198 OSL_ENSURE( false, "FormComponentPropertyHandler::OnDesignerClosed: invalid property id!" );
3199 return false;
3202 m_xCommandDesigner.set( new SQLCommandDesigner( m_aContext.getUNOContext(), xCommandUI.get(), m_xRowSetConnection, LINK( this, FormComponentPropertyHandler, OnDesignerClosed ) ) );
3204 DBG_ASSERT( _rxInspectorUI.is(), "FormComponentPropertyHandler::OnDesignerClosed: no access to the property browser ui!" );
3205 if ( m_xCommandDesigner->isActive() && _rxInspectorUI.is() )
3207 m_xBrowserUI = _rxInspectorUI;
3208 // disable everything which would affect this property
3209 const ::rtl::OUString* pToDisable = xCommandUI->getPropertiesToDisable();
3210 while ( pToDisable->getLength() )
3212 m_xBrowserUI->enablePropertyUIElements( *pToDisable++, PropertyLineElement::All, sal_False );
3215 // but enable the browse button for the property itself - so it can be used to raise the query designer
3216 ::rtl::OUString sPropertyName( impl_getPropertyNameFromId_nothrow( _nDesignForProperty ) );
3217 m_xBrowserUI->enablePropertyUIElements( sPropertyName, PropertyLineElement::PrimaryButton, sal_True );
3220 catch( const Exception& )
3222 DBG_UNHANDLED_EXCEPTION();
3224 return m_xCommandDesigner.is();
3227 //------------------------------------------------------------------------
3228 IMPL_LINK( FormComponentPropertyHandler, OnDesignerClosed, void*, /*NOTINTERESTEDIN*/ )
3230 OSL_ENSURE( m_xBrowserUI.is() && m_xCommandDesigner.is(), "FormComponentPropertyHandler::OnDesignerClosed: too many NULLs!" );
3231 if ( m_xBrowserUI.is() && m_xCommandDesigner.is() )
3235 ::rtl::Reference< ISQLCommandPropertyUI > xCommandUI(
3236 dynamic_cast< ISQLCommandPropertyUI* >( m_xCommandDesigner->getPropertyAdapter().get() ) );
3237 if ( !xCommandUI.is() )
3238 throw NullPointerException();
3240 const ::rtl::OUString* pToEnable = xCommandUI->getPropertiesToDisable();
3241 while ( pToEnable->getLength() )
3243 m_xBrowserUI->enablePropertyUIElements( *pToEnable++, PropertyLineElement::All, sal_True );
3246 catch( const Exception& )
3248 DBG_UNHANDLED_EXCEPTION();
3252 return 0L;
3255 //------------------------------------------------------------------------
3256 bool FormComponentPropertyHandler::impl_hasValidDataSourceSignature_nothrow( const Reference< XPropertySet >& _xFormProperties, bool _bAllowEmptyDataSourceName ) SAL_THROW(())
3258 bool bHas = false;
3259 if ( _xFormProperties.is() )
3263 ::rtl::OUString sPropertyValue;
3264 // first, we need the name of an existent data source
3265 if ( _xFormProperties->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATASOURCE) )
3266 _xFormProperties->getPropertyValue( PROPERTY_DATASOURCE ) >>= sPropertyValue;
3267 bHas = ( sPropertyValue.getLength() != 0 ) || _bAllowEmptyDataSourceName;
3269 // then, the command should not be empty
3270 if ( bHas )
3272 if ( _xFormProperties->getPropertySetInfo()->hasPropertyByName(PROPERTY_COMMAND) )
3273 _xFormProperties->getPropertyValue( PROPERTY_COMMAND ) >>= sPropertyValue;
3274 bHas = ( sPropertyValue.getLength() != 0 );
3277 catch( const Exception& )
3279 OSL_ENSURE( false, "FormComponentPropertyHandler::impl_hasValidDataSourceSignature_nothrow: caught an exception!" );
3282 return bHas;
3284 //------------------------------------------------------------------------
3285 ::rtl::OUString FormComponentPropertyHandler::impl_getDocumentURL_nothrow() const
3287 ::rtl::OUString sURL;
3290 Reference< XModel > xDocument( impl_getContextDocument_nothrow() );
3291 if ( xDocument.is() )
3292 sURL = xDocument->getURL();
3294 catch( const Exception& )
3296 DBG_UNHANDLED_EXCEPTION();
3298 return sURL;
3300 // -------------------------------------------------------------------------
3301 ::cppu::IPropertyArrayHelper* FormComponentPropertyHandler::createArrayHelper( ) const
3303 uno::Sequence< beans::Property > aProps;
3304 describeProperties(aProps);
3305 return new ::cppu::OPropertyArrayHelper(aProps);
3308 // -------------------------------------------------------------------------
3309 ::cppu::IPropertyArrayHelper & FormComponentPropertyHandler::getInfoHelper()
3311 return *const_cast<FormComponentPropertyHandler*>(this)->getArrayHelper();
3313 // -----------------------------------------------------------------------------
3314 uno::Reference< beans::XPropertySetInfo > SAL_CALL FormComponentPropertyHandler::getPropertySetInfo( ) throw(uno::RuntimeException)
3316 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
3319 //........................................................................
3320 } // namespace pcr
3321 //........................................................................