1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_extensions.hxx"
26 
27 #include "controltype.hxx"
28 #include "propctrlr.hrc"
29 #include "extensio.hrc"
30 #include "fontdialog.hxx"
31 #include "formcomponenthandler.hxx"
32 #include "formlinkdialog.hxx"
33 #include "formmetadata.hxx"
34 #include "formresid.hrc"
35 #include "formstrings.hxx"
36 #include "handlerhelper.hxx"
37 #include "listselectiondlg.hxx"
38 #include "pcrcommon.hxx"
39 #include "selectlabeldialog.hxx"
40 #include "taborder.hxx"
41 #include "usercontrol.hxx"
42 
43 /** === begin UNO includes === **/
44 #include <com/sun/star/lang/NullPointerException.hpp>
45 #include <com/sun/star/awt/XControlModel.hpp>
46 #include <com/sun/star/lang/XServiceInfo.hpp>
47 #include <com/sun/star/form/FormComponentType.hpp>
48 #include <com/sun/star/beans/PropertyAttribute.hpp>
49 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
50 #include <com/sun/star/container/XNameAccess.hpp>
51 #include <com/sun/star/form/XForm.hpp>
52 #include <com/sun/star/container/XChild.hpp>
53 #include <com/sun/star/sdbc/XConnection.hpp>
54 #include <com/sun/star/sdb/CommandType.hpp>
55 #include <com/sun/star/form/XGridColumnFactory.hpp>
56 #include <com/sun/star/sdb/SQLContext.hpp>
57 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
58 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
59 #include <com/sun/star/form/ListSourceType.hpp>
60 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
61 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
62 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
63 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
64 #include <com/sun/star/awt/XTabControllerModel.hpp>
65 #include <com/sun/star/form/FormSubmitEncoding.hpp>
66 #include <com/sun/star/awt/VisualEffect.hpp>
67 #include <com/sun/star/form/FormButtonType.hpp>
68 #include <com/sun/star/inspection/PropertyControlType.hpp>
69 #include <com/sun/star/util/MeasureUnit.hpp>
70 #include <com/sun/star/inspection/XObjectInspectorUI.hpp>
71 #include <com/sun/star/inspection/PropertyLineElement.hpp>
72 #include <com/sun/star/resource/XStringResourceManager.hpp>
73 #include <com/sun/star/resource/MissingResourceException.hpp>
74 #include <com/sun/star/graphic/GraphicObject.hpp>
75 #include <com/sun/star/text/WritingMode2.hpp>
76 /** === end UNO includes === **/
77 
78 #include <comphelper/extract.hxx>
79 #include <connectivity/dbconversion.hxx>
80 #include <connectivity/dbexception.hxx>
81 #include <cppuhelper/exc_hlp.hxx>
82 #include <sfx2/app.hxx>
83 #include <sfx2/basedlgs.hxx>
84 #include <sfx2/docfilt.hxx>
85 #include <sfx2/filedlghelper.hxx>
86 #include <svl/ctloptions.hxx>
87 #include <svtools/colrdlg.hxx>
88 #include <svl/filenotation.hxx>
89 #include <svl/intitem.hxx>
90 #include <svl/itemset.hxx>
91 #include <unotools/moduleoptions.hxx>
92 #include <svl/numuno.hxx>
93 #include <svl/urihelper.hxx>
94 #include <svx/dialogs.hrc>
95 #include <svx/numinf.hxx>
96 #include <svx/svxdlg.hxx>
97 #include <svx/svxids.hrc>
98 #include <toolkit/helper/vclunohelper.hxx>
99 #include <tools/diagnose_ex.h>
100 #include <vcl/msgbox.hxx>
101 #include <vcl/stdtext.hxx>
102 #include <vcl/wrkwin.hxx>
103 #include <tools/StringListResource.hxx>
104 
105 #include <limits>
106 
107 #define GRAPHOBJ_URLPREFIX "vnd.sun.star.GraphicObject:"
108 //------------------------------------------------------------------------
createRegistryInfo_FormComponentPropertyHandler()109 extern "C" void SAL_CALL createRegistryInfo_FormComponentPropertyHandler()
110 {
111     ::pcr::FormComponentPropertyHandler::registerImplementation();
112 }
113 
114 //........................................................................
115 namespace pcr
116 {
117 //........................................................................
118 
119     using namespace ::com::sun::star;
120     using namespace uno;
121     using namespace lang;
122     using namespace beans;
123     using namespace frame;
124     using namespace script;
125     using namespace form;
126     using namespace util;
127     using namespace awt;
128     using namespace sdb;
129     using namespace sdbc;
130     using namespace sdbcx;
131     using namespace form;
132     using namespace container;
133     using namespace ui::dialogs;
134     using namespace inspection;
135     using namespace ::dbtools;
136 
137     namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
138 
139     //====================================================================
140     //= FormComponentPropertyHandler
141     //====================================================================
DBG_NAME(FormComponentPropertyHandler)142     DBG_NAME( FormComponentPropertyHandler )
143 #define PROPERTY_ID_ROWSET 1
144     //--------------------------------------------------------------------
145     FormComponentPropertyHandler::FormComponentPropertyHandler( const Reference< XComponentContext >& _rxContext )
146         :FormComponentPropertyHandler_Base( _rxContext )
147         ,::comphelper::OPropertyContainer(FormComponentPropertyHandler_Base::rBHelper)
148         ,m_sDefaultValueString( String( PcrRes( RID_STR_STANDARD ) ) )
149         ,m_eComponentClass( eUnknown )
150         ,m_bComponentIsSubForm( false )
151         ,m_bHaveListSource( false )
152         ,m_bHaveCommand( false )
153         ,m_nClassId( 0 )
154     {
155         DBG_CTOR( FormComponentPropertyHandler, NULL );
156         registerProperty(PROPERTY_ROWSET,PROPERTY_ID_ROWSET,0,&m_xRowSet,::getCppuType(&m_xRowSet));
157     }
158 
159     //--------------------------------------------------------------------
~FormComponentPropertyHandler()160     FormComponentPropertyHandler::~FormComponentPropertyHandler()
161     {
162         DBG_DTOR( FormComponentPropertyHandler, NULL );
163     }
164     //--------------------------------------------------------------------
IMPLEMENT_FORWARD_XINTERFACE2(FormComponentPropertyHandler,FormComponentPropertyHandler_Base,::comphelper::OPropertyContainer)165     IMPLEMENT_FORWARD_XINTERFACE2(FormComponentPropertyHandler,FormComponentPropertyHandler_Base,::comphelper::OPropertyContainer)
166     //--------------------------------------------------------------------
167     ::rtl::OUString SAL_CALL FormComponentPropertyHandler::getImplementationName_static(  ) throw (RuntimeException)
168     {
169         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.FormComponentPropertyHandler" ) );
170     }
171 
172     //--------------------------------------------------------------------
getSupportedServiceNames_static()173     Sequence< ::rtl::OUString > SAL_CALL FormComponentPropertyHandler::getSupportedServiceNames_static(  ) throw (RuntimeException)
174     {
175         Sequence< ::rtl::OUString > aSupported( 1 );
176         aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.inspection.FormComponentPropertyHandler" ) );
177         return aSupported;
178     }
179 
180 	//============================================
181 	// TODO: -> export from toolkit
182 	struct LanguageDependentProp
183 	{
184 		const char* pPropName;
185 		sal_Int32   nPropNameLength;
186 	};
187 
188 	static LanguageDependentProp aLanguageDependentProp[] =
189 	{
190 		{ "Text",            4 },
191 		{ "Label",           5 },
192 		{ "Title",           5 },
193 		{ "HelpText",        8 },
194 		{ "CurrencySymbol", 14 },
195 	    { "StringItemList", 14 },
196 		{ 0, 0                 }
197 	};
198 
199     namespace
200     {
lcl_isLanguageDependentProperty(::rtl::OUString aName)201 		bool lcl_isLanguageDependentProperty( ::rtl::OUString aName )
202 		{
203 			bool bRet = false;
204 
205 			LanguageDependentProp* pLangDepProp = aLanguageDependentProp;
206 			while( pLangDepProp->pPropName != 0 )
207 			{
208 				if( aName.equalsAsciiL( pLangDepProp->pPropName, pLangDepProp->nPropNameLength ))
209 				{
210 					bRet = true;
211 					break;
212 				}
213 				pLangDepProp++;
214 			}
215 			return bRet;
216 		}
217 
lcl_getStringResourceResolverForProperty(Reference<XPropertySet> _xComponent,const::rtl::OUString & _rPropertyName,const Any & _rPropertyValue)218 		Reference< resource::XStringResourceResolver > lcl_getStringResourceResolverForProperty
219 			( Reference< XPropertySet > _xComponent, const ::rtl::OUString& _rPropertyName,
220 			  const Any& _rPropertyValue )
221 		{
222             Reference< resource::XStringResourceResolver > xRet;
223             const TypeClass eType = _rPropertyValue.getValueType().getTypeClass();
224             if ( (eType == TypeClass_STRING || eType == TypeClass_SEQUENCE) &&
225 				    lcl_isLanguageDependentProperty( _rPropertyName ) )
226             {
227                 static const ::rtl::OUString s_sResourceResolverPropName(RTL_CONSTASCII_USTRINGPARAM("ResourceResolver"));
228 
229 			    Reference< resource::XStringResourceResolver > xStringResourceResolver;
230 			    try
231 			    {
232 				    xStringResourceResolver.set( _xComponent->getPropertyValue( s_sResourceResolverPropName ),UNO_QUERY);
233                     if( xStringResourceResolver.is() &&
234 				        xStringResourceResolver->getLocales().getLength() > 0 )
235 			        {
236 				        xRet = xStringResourceResolver;
237 			        }
238 			    }
239 			    catch(UnknownPropertyException&)
240 			    {
241                     // nii
242                 }
243             }
244 
245 			return xRet;
246 		}
247 	}
248 
249     //--------------------------------------------------------------------
impl_getPropertyValue_throw(const::rtl::OUString & _rPropertyName) const250     Any FormComponentPropertyHandler::impl_getPropertyValue_throw( const ::rtl::OUString& _rPropertyName ) const
251     {
252         const PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
253 
254         Any aPropertyValue( m_xComponent->getPropertyValue( _rPropertyName ) );
255 
256 		Reference< resource::XStringResourceResolver > xStringResourceResolver
257 			= lcl_getStringResourceResolverForProperty( m_xComponent, _rPropertyName, aPropertyValue );
258 		if( xStringResourceResolver.is() )
259 	    {
260 	        TypeClass eType = aPropertyValue.getValueType().getTypeClass();
261 			if( eType == TypeClass_STRING )
262 			{
263 				::rtl::OUString aPropStr;
264 				aPropertyValue >>= aPropStr;
265 				if( aPropStr.getLength() > 1 )
266 				{
267 					::rtl::OUString aPureIdStr = aPropStr.copy( 1 );
268 					if( xStringResourceResolver->hasEntryForId( aPureIdStr ) )
269 					{
270 						::rtl::OUString aResourceStr = xStringResourceResolver->resolveString( aPureIdStr );
271 						aPropertyValue <<= aResourceStr;
272 					}
273 				}
274 			}
275 			// StringItemList?
276 			else if( eType == TypeClass_SEQUENCE )
277 			{
278                 Sequence< ::rtl::OUString > aStrings;
279 				aPropertyValue >>= aStrings;
280 
281                 const ::rtl::OUString* pStrings = aStrings.getConstArray();
282 				sal_Int32 nCount = aStrings.getLength();
283 
284                 Sequence< ::rtl::OUString > aResolvedStrings;
285 				aResolvedStrings.realloc( nCount );
286                 ::rtl::OUString* pResolvedStrings = aResolvedStrings.getArray();
287 				try
288 				{
289 					for ( sal_Int32 i = 0; i < nCount; ++i )
290 					{
291 						::rtl::OUString aIdStr = pStrings[i];
292 						::rtl::OUString aPureIdStr = aIdStr.copy( 1 );
293 						if( xStringResourceResolver->hasEntryForId( aPureIdStr ) )
294 							pResolvedStrings[i] = xStringResourceResolver->resolveString( aPureIdStr );
295 						else
296 							pResolvedStrings[i] = aIdStr;
297 					}
298 				}
299 				catch( resource::MissingResourceException & )
300 				{}
301 				aPropertyValue <<= aResolvedStrings;
302 			}
303 	    }
304 		else
305 	        impl_normalizePropertyValue_nothrow( aPropertyValue, nPropId );
306 
307         return aPropertyValue;
308     }
309 
310     //--------------------------------------------------------------------
getPropertyValue(const::rtl::OUString & _rPropertyName)311     Any SAL_CALL FormComponentPropertyHandler::getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
312     {
313         if( _rPropertyName == PROPERTY_ROWSET )
314             return ::comphelper::OPropertyContainer::getPropertyValue( _rPropertyName );
315 
316         ::osl::MutexGuard aGuard( m_aMutex );
317         return impl_getPropertyValue_throw( _rPropertyName );
318     }
319 
320     //--------------------------------------------------------------------
setPropertyValue(const::rtl::OUString & _rPropertyName,const Any & _rValue)321     void SAL_CALL FormComponentPropertyHandler::setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw (UnknownPropertyException, RuntimeException)
322     {
323         if( _rPropertyName == PROPERTY_ROWSET )
324         {
325             ::comphelper::OPropertyContainer::setPropertyValue( _rPropertyName, _rValue );
326             return;
327         }
328 
329         ::osl::MutexGuard aGuard( m_aMutex );
330         PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) ); // check if property is known by the handler
331 
332         Reference< graphic::XGraphicObject > xGrfObj;
333         if ( PROPERTY_ID_IMAGE_URL == nPropId && ( _rValue >>= xGrfObj ) )
334         {
335             DBG_ASSERT( xGrfObj.is(), "FormComponentPropertyHandler::setPropertyValue() xGrfObj is invalid");
336             rtl::OUString sObjectID( RTL_CONSTASCII_USTRINGPARAM( GRAPHOBJ_URLPREFIX ) );
337             sObjectID = sObjectID + xGrfObj->getUniqueID();
338             m_xComponent->setPropertyValue( _rPropertyName, uno::makeAny( sObjectID ) );
339         }
340         else if ( PROPERTY_ID_FONT == nPropId )
341         {
342             // special handling, the value is a faked value we generated ourself in impl_executeFontDialog_nothrow
343             Sequence< NamedValue > aFontPropertyValues;
344             OSL_VERIFY( _rValue >>= aFontPropertyValues );
345             const NamedValue* fontPropertyValue = aFontPropertyValues.getConstArray();
346             const NamedValue* fontPropertyValueEnd = fontPropertyValue + aFontPropertyValues.getLength();
347             for ( ; fontPropertyValue != fontPropertyValueEnd; ++fontPropertyValue )
348                 m_xComponent->setPropertyValue( fontPropertyValue->Name, fontPropertyValue->Value );
349         }
350         else
351         {
352 			Any aValue = _rValue;
353 
354 			Reference< resource::XStringResourceResolver > xStringResourceResolver
355 				= lcl_getStringResourceResolverForProperty( m_xComponent, _rPropertyName, _rValue );
356 			if( xStringResourceResolver.is() )
357 			{
358 				Reference< resource::XStringResourceManager >
359 					xStringResourceManager( xStringResourceResolver, UNO_QUERY );
360 				if( xStringResourceManager.is() )
361 				{
362 					Any aPropertyValue( m_xComponent->getPropertyValue( _rPropertyName ) );
363 					TypeClass eType = aPropertyValue.getValueType().getTypeClass();
364 					if( eType == TypeClass_STRING )
365 					{
366 						::rtl::OUString aPropStr;
367 						aPropertyValue >>= aPropStr;
368 						if( aPropStr.getLength() > 1 )
369 						{
370 							::rtl::OUString aPureIdStr = aPropStr.copy( 1 );
371 							::rtl::OUString aValueStr;
372 							_rValue >>= aValueStr;
373 							xStringResourceManager->setString( aPureIdStr, aValueStr );
374 							aValue = aPropertyValue;	// set value to force modified
375 						}
376 					}
377 					// StringItemList?
378 					else if( eType == TypeClass_SEQUENCE )
379 					{
380 						static ::rtl::OUString aDot = ::rtl::OUString::createFromAscii( "." );
381 						static ::rtl::OUString aEsc = ::rtl::OUString::createFromAscii( "&" );
382 
383 						// Put strings into resource using new ids
384 						Sequence< ::rtl::OUString > aNewStrings;
385 						_rValue >>= aNewStrings;
386 
387 						const ::rtl::OUString* pNewStrings = aNewStrings.getConstArray();
388 						sal_Int32 nNewCount = aNewStrings.getLength();
389 
390 						// Create new Ids
391 						::rtl::OUString* pNewPureIds = new ::rtl::OUString[nNewCount];
392 						::rtl::OUString aIdStrBase = aDot;
393 						Any aNameAny = m_xComponent->getPropertyValue(PROPERTY_NAME);
394 						::rtl::OUString sControlName;
395 						aNameAny >>= sControlName;
396 						aIdStrBase += sControlName;
397 						aIdStrBase += aDot;
398 						aIdStrBase += _rPropertyName;
399 						sal_Int32 i;
400 						::rtl::OUString aDummyStr;
401 						for ( i = 0; i < nNewCount; ++i )
402 						{
403 							sal_Int32 nUniqueId = xStringResourceManager->getUniqueNumericId();
404 							::rtl::OUString aPureIdStr = ::rtl::OUString::valueOf( nUniqueId );
405 							aPureIdStr += aIdStrBase;
406 							pNewPureIds[i] = aPureIdStr;
407 							// Force usage of next Unique Id
408 							xStringResourceManager->setString( aPureIdStr, aDummyStr );
409 						}
410 
411 						// Move strings to new Ids for all locales
412 						Sequence< Locale > aLocaleSeq = xStringResourceManager->getLocales();
413 						const Locale* pLocale = aLocaleSeq.getConstArray();
414 						sal_Int32 nLocaleCount = aLocaleSeq.getLength();
415 						Sequence< ::rtl::OUString > aOldIdStrings;
416 						aPropertyValue >>= aOldIdStrings;
417 						try
418 						{
419 							const ::rtl::OUString* pOldIdStrings = aOldIdStrings.getConstArray();
420 							sal_Int32 nOldIdCount = aOldIdStrings.getLength();
421 							for ( i = 0; i < nNewCount; ++i )
422 							{
423 								::rtl::OUString aOldIdStr;
424 								::rtl::OUString aOldPureIdStr;
425 								if( i < nOldIdCount )
426 								{
427 									aOldIdStr = pOldIdStrings[i];
428 									aOldPureIdStr = aOldIdStr.copy( 1 );
429 								}
430 								::rtl::OUString aNewPureIdStr = pNewPureIds[i];
431 
432 								for ( sal_Int32 iLocale = 0; iLocale < nLocaleCount; ++iLocale )
433 								{
434 									Locale aLocale = pLocale[iLocale];
435 
436 									::rtl::OUString aResourceStr;
437 									if( aOldPureIdStr.getLength() != 0 )
438 									{
439 										if( xStringResourceManager->hasEntryForIdAndLocale( aOldPureIdStr, aLocale ) )
440 										{
441 											aResourceStr = xStringResourceManager->
442 												resolveStringForLocale( aOldPureIdStr, aLocale );
443 										}
444 									}
445 									xStringResourceManager->setStringForLocale( aNewPureIdStr, aResourceStr, aLocale );
446 								}
447 							}
448 						}
449 						catch( resource::MissingResourceException & )
450 						{}
451 
452 
453 						// Set new strings for current locale and create
454 						// new Id sequence as new property value
455 						Sequence< ::rtl::OUString > aNewIdStrings;
456 						aNewIdStrings.realloc( nNewCount );
457 						::rtl::OUString* pNewIdStrings = aNewIdStrings.getArray();
458 						for ( i = 0; i < nNewCount; ++i )
459 						{
460 							::rtl::OUString aPureIdStr = pNewPureIds[i];
461 							::rtl::OUString aStr = pNewStrings[i];
462 							xStringResourceManager->setString( aPureIdStr, aStr );
463 
464 							::rtl::OUString aIdStr = aEsc;
465 							aIdStr += aPureIdStr;
466 							pNewIdStrings[i] = aIdStr;
467 						}
468 						aValue <<= aNewIdStrings;
469 
470 						// Remove old ids from resource for all locales
471 						const ::rtl::OUString* pOldIdStrings = aOldIdStrings.getConstArray();
472 						sal_Int32 nOldIdCount = aOldIdStrings.getLength();
473 						for( i = 0 ; i < nOldIdCount ; ++i )
474 						{
475 							::rtl::OUString aIdStr = pOldIdStrings[i];
476 							::rtl::OUString aPureIdStr = aIdStr.copy( 1 );
477 							for ( sal_Int32 iLocale = 0; iLocale < nLocaleCount; ++iLocale )
478 							{
479 								Locale aLocale = pLocale[iLocale];
480 								try
481 								{
482 									xStringResourceManager->removeIdForLocale( aPureIdStr, aLocale );
483 								}
484 								catch( resource::MissingResourceException & )
485 								{}
486 							}
487 						}
488 						delete[] pNewPureIds;
489 					}
490 				}
491 			}
492 
493             m_xComponent->setPropertyValue( _rPropertyName, aValue );
494         }
495     }
496 
497     //--------------------------------------------------------------------
convertToPropertyValue(const::rtl::OUString & _rPropertyName,const Any & _rControlValue)498     Any SAL_CALL FormComponentPropertyHandler::convertToPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rControlValue ) throw (UnknownPropertyException, RuntimeException)
499     {
500         ::osl::MutexGuard aGuard( m_aMutex );
501         PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
502         Property aProperty( impl_getPropertyFromId_throw( nPropId ) );
503 
504         Any aPropertyValue( _rControlValue );
505         if ( !aPropertyValue.hasValue() )
506         {
507             if ( ( aProperty.Attributes & PropertyAttribute::MAYBEVOID ) == 0 )
508                 // default construct an instance of the proper type
509                 aPropertyValue = Any( NULL, aProperty.Type );
510             // nothing to do
511             return aPropertyValue;
512         }
513 
514         /// care for the special "default" string, translate it to VOID
515         if ( m_aPropertiesWithDefListEntry.find( _rPropertyName ) != m_aPropertiesWithDefListEntry.end() )
516         {
517             // it's a control with a string list
518             ::rtl::OUString sStringValue;
519             if ( _rControlValue >>= sStringValue )
520             {   // note that ColorListBoxes might transfer values either as string or as css.util.Color,
521                 // so this check here is important
522                 if ( sStringValue == m_sDefaultValueString )
523                     return Any();
524             }
525         }
526 
527         switch ( nPropId )
528         {
529         case PROPERTY_ID_DATASOURCE:
530         {
531             ::rtl::OUString sControlValue;
532             OSL_VERIFY( _rControlValue >>= sControlValue );
533 
534             if ( sControlValue.getLength() )
535             {
536                 Reference< XNameAccess > xDatabaseContext;
537                 m_aContext.createComponent( (::rtl::OUString)SERVICE_DATABASE_CONTEXT, xDatabaseContext );
538                 if ( !xDatabaseContext.is() || !xDatabaseContext->hasByName( sControlValue ) )
539                 {
540                     ::svt::OFileNotation aTransformer(sControlValue);
541                     aPropertyValue <<= ::rtl::OUString( aTransformer.get( ::svt::OFileNotation::N_URL ) );
542                 }
543             }
544         }
545         break;  // case PROPERTY_ID_DATASOURCE
546 
547         case PROPERTY_ID_SHOW_POSITION:
548         case PROPERTY_ID_SHOW_NAVIGATION:
549         case PROPERTY_ID_SHOW_RECORDACTIONS:
550         case PROPERTY_ID_SHOW_FILTERSORT:
551         {
552             ::rtl::OUString sControlValue;
553             OSL_VERIFY( _rControlValue >>= sControlValue );
554 
555             ::std::vector< ::rtl::OUString > aListEntries;
556             tools::StringListResource aRes( PcrRes( RID_RSC_ENUM_SHOWHIDE ), aListEntries );
557             OSL_ENSURE( aListEntries.size() == 2, "FormComponentPropertyHandler::convertToPropertyValue: broken resource for Show/Hide!" );
558             sal_Bool bShow = ( aListEntries.size() < 2 ) || ( sControlValue == aListEntries[1] );
559 
560             aPropertyValue <<= bShow;
561         }
562         break;
563 
564         case PROPERTY_ID_TARGET_URL:
565         case PROPERTY_ID_IMAGE_URL:
566         {
567             ::rtl::OUString sControlValue;
568             OSL_VERIFY( _rControlValue >>= sControlValue );
569             // Don't convert a placeholder
570             if ( nPropId == PROPERTY_ID_IMAGE_URL && sControlValue.equals( String( PcrRes( RID_EMBED_IMAGE_PLACEHOLDER ) ) ) )
571                 aPropertyValue <<= sControlValue;
572             else
573             {
574                 INetURLObject aDocURL( impl_getDocumentURL_nothrow() );
575                 aPropertyValue <<= (::rtl::OUString)URIHelper::SmartRel2Abs( aDocURL, sControlValue, Link(), false, true, INetURLObject::WAS_ENCODED, INetURLObject::DECODE_TO_IURI );
576             }
577         }
578         break;
579 
580         case PROPERTY_ID_DATEMIN:
581         case PROPERTY_ID_DATEMAX:
582         case PROPERTY_ID_DEFAULT_DATE:
583         case PROPERTY_ID_DATE:
584         {
585             util::Date aDate;
586             OSL_VERIFY( _rControlValue >>= aDate );
587             aPropertyValue <<= (sal_Int32)DBTypeConversion::toINT32( aDate );
588         }
589         break;
590 
591         case PROPERTY_ID_TIMEMIN:
592         case PROPERTY_ID_TIMEMAX:
593         case PROPERTY_ID_DEFAULT_TIME:
594         case PROPERTY_ID_TIME:
595         {
596             util::Time aTime;
597             OSL_VERIFY( _rControlValue >>= aTime );
598             aPropertyValue <<= (sal_Int32)DBTypeConversion::toINT32( aTime );
599         }
600         break;
601 
602         case PROPERTY_ID_WRITING_MODE:
603         {
604             aPropertyValue = FormComponentPropertyHandler_Base::convertToPropertyValue( _rPropertyName, _rControlValue );
605 
606             sal_Int16 nNormalizedValue( 2 );
607             OSL_VERIFY( aPropertyValue >>= nNormalizedValue );
608             sal_Int16 nWritingMode = WritingMode2::CONTEXT;
609             switch ( nNormalizedValue )
610             {
611             case 0: nWritingMode = WritingMode2::LR_TB;      break;
612             case 1: nWritingMode = WritingMode2::RL_TB;      break;
613             case 2: nWritingMode = WritingMode2::CONTEXT;    break;
614             default:
615                 OSL_ENSURE( false, "FormComponentPropertyHandler::convertToPropertyValue: unexpected 'normalized value' for WritingMode!" );
616                 nWritingMode = WritingMode2::CONTEXT;
617                 break;
618             }
619 
620             aPropertyValue <<= nWritingMode;
621         }
622         break;
623 
624         default:
625             aPropertyValue = FormComponentPropertyHandler_Base::convertToPropertyValue( _rPropertyName, _rControlValue );
626             break;  // default
627 
628         }   // switch ( nPropId )
629 
630         return aPropertyValue;
631     }
632 
633     //--------------------------------------------------------------------
convertToControlValue(const::rtl::OUString & _rPropertyName,const Any & _rPropertyValue,const Type & _rControlValueType)634     Any SAL_CALL FormComponentPropertyHandler::convertToControlValue( const ::rtl::OUString& _rPropertyName, const Any& _rPropertyValue, const Type& _rControlValueType ) throw (UnknownPropertyException, RuntimeException)
635     {
636         ::osl::MutexGuard aGuard( m_aMutex );
637         sal_Int32 nPropId = m_pInfoService->getPropertyId( _rPropertyName );
638         DBG_ASSERT( nPropId != -1, "FormComponentPropertyHandler::convertToPropertyValue: not one of my properties!!" );
639 
640         Property aProperty( impl_getPropertyFromId_throw( nPropId ) );
641 
642         Any aControlValue( _rPropertyValue );
643         if ( !aControlValue.hasValue() )
644         {
645             // if the property is represented with a list box or color list box, we need to
646             // translate this into the string "Default"
647             if ( m_aPropertiesWithDefListEntry.find( _rPropertyName ) != m_aPropertiesWithDefListEntry.end() )
648                 aControlValue <<= m_sDefaultValueString;
649 
650             return aControlValue;
651         }
652 
653         switch ( nPropId )
654         {
655         //////////////////////////////////////////////////////////////
656         case PROPERTY_ID_SHOW_POSITION:
657         case PROPERTY_ID_SHOW_NAVIGATION:
658         case PROPERTY_ID_SHOW_RECORDACTIONS:
659         case PROPERTY_ID_SHOW_FILTERSORT:
660         {
661             ::std::vector< ::rtl::OUString > aListEntries;
662             tools::StringListResource aRes( PcrRes( RID_RSC_ENUM_SHOWHIDE ), aListEntries );
663             OSL_ENSURE( aListEntries.size() == 2, "FormComponentPropertyHandler::convertToControlValue: broken resource for Show/Hide!" );
664 
665             if ( aListEntries.size() == 2 )
666             {
667                 ::rtl::OUString sControlValue =     ::comphelper::getBOOL( _rPropertyValue )
668                                                 ?   aListEntries[1]
669                                                 :   aListEntries[0];
670                 aControlValue <<= sControlValue;
671             }
672         }
673         break;
674 
675         //////////////////////////////////////////////////////////////
676         case PROPERTY_ID_DATASOURCE:
677         {
678             OSL_ENSURE( _rControlValueType.getTypeClass() == TypeClass_STRING,
679                 "FormComponentPropertyHandler::convertToControlValue: wrong ControlValueType!" );
680 
681             ::rtl::OUString sDataSource;
682             _rPropertyValue >>= sDataSource;
683             if ( sDataSource.getLength() )
684             {
685                 ::svt::OFileNotation aTransformer( sDataSource );
686                 sDataSource = aTransformer.get( ::svt::OFileNotation::N_SYSTEM );
687             }
688             aControlValue <<= sDataSource;
689         }
690         break;
691 
692         //////////////////////////////////////////////////////////////
693         case PROPERTY_ID_CONTROLLABEL:
694         {
695             ::rtl::OUString sControlValue;
696 
697             Reference< XPropertySet >  xSet;
698             _rPropertyValue >>= xSet;
699             Reference< XPropertySetInfo > xPSI;
700             if ( xSet.is() )
701                 xPSI = xSet->getPropertySetInfo();
702             if ( xPSI.is() && xPSI->hasPropertyByName( PROPERTY_LABEL ) )
703             {
704                 ::rtl::OUStringBuffer aValue;
705                 aValue.append( (sal_Unicode)'<' );
706                 ::rtl::OUString sLabel;
707                 OSL_VERIFY( xSet->getPropertyValue( PROPERTY_LABEL ) >>= sLabel );
708                 aValue.append( sLabel );
709                 aValue.append( (sal_Unicode)'>' );
710                 sControlValue = aValue.makeStringAndClear();
711             }
712 
713             aControlValue <<= sControlValue;
714         }
715         break;
716 
717         //////////////////////////////////////////////////////////////
718         case PROPERTY_ID_DATEMIN:
719         case PROPERTY_ID_DATEMAX:
720         case PROPERTY_ID_DEFAULT_DATE:
721         case PROPERTY_ID_DATE:
722         {
723             sal_Int32 nDate = 0;
724             OSL_VERIFY( _rPropertyValue >>= nDate );
725             aControlValue <<= DBTypeConversion::toDate( nDate );
726         }
727         break;
728 
729         case PROPERTY_ID_TIMEMIN:
730         case PROPERTY_ID_TIMEMAX:
731         case PROPERTY_ID_DEFAULT_TIME:
732         case PROPERTY_ID_TIME:
733         {
734             sal_Int32 nTime = 0;
735             OSL_VERIFY( _rPropertyValue >>= nTime );
736             aControlValue <<= DBTypeConversion::toTime( nTime );
737         }
738         break;
739 
740         case PROPERTY_ID_WRITING_MODE:
741         {
742             sal_Int16 nWritingMode( WritingMode2::CONTEXT );
743             OSL_VERIFY( _rPropertyValue >>= nWritingMode );
744             sal_Int16 nNormalized = 2;
745             switch ( nWritingMode )
746             {
747             case WritingMode2::LR_TB:   nNormalized = 0;    break;
748             case WritingMode2::RL_TB:   nNormalized = 1;    break;
749             case WritingMode2::CONTEXT: nNormalized = 2;    break;
750             default:
751                 OSL_ENSURE( false, "FormComponentPropertyHandler::convertToControlValue: unsupported API value for WritingMode!" );
752                 nNormalized = 2;
753                 break;
754             }
755 
756             aControlValue = FormComponentPropertyHandler_Base::convertToControlValue( _rPropertyName, makeAny( nNormalized ), _rControlValueType );
757         }
758         break;
759 
760         case PROPERTY_ID_FONT:
761         {
762             FontDescriptor aFont;
763             OSL_VERIFY( _rPropertyValue >>= aFont );
764 
765             ::rtl::OUStringBuffer displayName;
766             if ( !aFont.Name.getLength() )
767             {
768                 displayName.append( String( PcrRes( RID_STR_FONT_DEFAULT ) ) );
769             }
770             else
771             {
772                 // font name
773                 displayName.append( aFont.Name );
774                 displayName.appendAscii( ", " );
775 
776                 // font style
777                 ::FontWeight  eWeight = VCLUnoHelper::ConvertFontWeight( aFont.Weight );
778                 sal_uInt16 nStyleResID = RID_STR_FONTSTYLE_REGULAR;
779                 if ( aFont.Slant == FontSlant_ITALIC )
780                 {
781                     if ( eWeight > WEIGHT_NORMAL )
782                         nStyleResID = RID_STR_FONTSTYLE_BOLD_ITALIC;
783                     else
784                         nStyleResID = RID_STR_FONTSTYLE_ITALIC;
785                 }
786                 else
787                 {
788                     if ( eWeight > WEIGHT_NORMAL )
789                         nStyleResID = RID_STR_FONTSTYLE_BOLD;
790                 }
791                 displayName.append( String( PcrRes( nStyleResID ) ) );
792 
793                 // font size
794                 if ( aFont.Height )
795                 {
796                     displayName.appendAscii( ", " );
797                     displayName.append( sal_Int32( aFont.Height ) );
798                 }
799             }
800 
801             aControlValue <<= displayName.makeStringAndClear();
802         }
803         break;
804 
805         default:
806             aControlValue = FormComponentPropertyHandler_Base::convertToControlValue( _rPropertyName, _rPropertyValue, _rControlValueType );
807             break;
808 
809         }   // switch ( nPropId )
810 
811         return aControlValue;
812     }
813 
814     //--------------------------------------------------------------------
getPropertyState(const::rtl::OUString & _rPropertyName)815     PropertyState SAL_CALL FormComponentPropertyHandler::getPropertyState( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
816     {
817         ::osl::MutexGuard aGuard( m_aMutex );
818         if ( m_xPropertyState.is() )
819             return m_xPropertyState->getPropertyState( _rPropertyName );
820         return PropertyState_DIRECT_VALUE;
821     }
822 
823     //--------------------------------------------------------------------
addPropertyChangeListener(const Reference<XPropertyChangeListener> & _rxListener)824     void SAL_CALL FormComponentPropertyHandler::addPropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
825     {
826         ::osl::MutexGuard aGuard( m_aMutex );
827         FormComponentPropertyHandler_Base::addPropertyChangeListener( _rxListener );
828         if ( m_xComponent.is() )
829             m_xComponent->addPropertyChangeListener( ::rtl::OUString(), _rxListener );
830     }
831 
832     //--------------------------------------------------------------------
removePropertyChangeListener(const Reference<XPropertyChangeListener> & _rxListener)833     void SAL_CALL FormComponentPropertyHandler::removePropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
834     {
835         ::osl::MutexGuard aGuard( m_aMutex );
836         if ( m_xComponent.is() )
837             m_xComponent->removePropertyChangeListener( ::rtl::OUString(), _rxListener );
838         FormComponentPropertyHandler_Base::removePropertyChangeListener( _rxListener );
839     }
840 
841     //--------------------------------------------------------------------
onNewComponent()842     void FormComponentPropertyHandler::onNewComponent()
843     {
844         FormComponentPropertyHandler_Base::onNewComponent();
845         if ( !m_xComponentPropertyInfo.is() && m_xComponent.is() )
846             throw NullPointerException();
847 
848         m_xPropertyState.set( m_xComponent, UNO_QUERY );
849         m_eComponentClass = eUnknown;
850         m_bComponentIsSubForm = m_bHaveListSource = m_bHaveCommand = false;
851         m_nClassId = 0;
852 
853         impl_initComponentMetaData_throw();
854     }
855 
856     //--------------------------------------------------------------------
doDescribeSupportedProperties() const857     Sequence< Property > SAL_CALL FormComponentPropertyHandler::doDescribeSupportedProperties() const
858     {
859         if ( !m_xComponentPropertyInfo.is() )
860             return Sequence< Property >();
861 
862         ::std::vector< Property > aProperties;
863 
864         Sequence< Property > aAllProperties( m_xComponentPropertyInfo->getProperties() );
865         aProperties.reserve( aAllProperties.getLength() );
866 
867         // filter the properties
868         PropertyId nPropId( 0 );
869         ::rtl::OUString sDisplayName;
870 
871         Property* pProperty = aAllProperties.getArray();
872         Property* pPropertiesEnd = pProperty + aAllProperties.getLength();
873         for ( ; pProperty != pPropertiesEnd; ++pProperty )
874         {
875             nPropId = m_pInfoService->getPropertyId( pProperty->Name );
876             if ( nPropId == -1 )
877                 continue;
878             pProperty->Handle = nPropId;
879 
880             sDisplayName = m_pInfoService->getPropertyTranslation( nPropId );
881             if ( !sDisplayName.getLength() )
882                 continue;
883 
884             sal_uInt32  nPropertyUIFlags = m_pInfoService->getPropertyUIFlags( nPropId );
885             bool bIsVisibleForForms   = ( nPropertyUIFlags & PROP_FLAG_FORM_VISIBLE   ) != 0;
886             bool bIsVisibleForDialogs = ( nPropertyUIFlags & PROP_FLAG_DIALOG_VISIBLE ) != 0;
887 
888             // depending on whether we're working for a form or a UNO dialog, some
889             // properties are not displayed
890             if  (  ( m_eComponentClass == eFormControl   && !bIsVisibleForForms )
891                 || ( m_eComponentClass == eDialogControl && !bIsVisibleForDialogs )
892                 )
893                 continue;
894 
895             // some generic sanity checks
896             if ( impl_shouldExcludeProperty_nothrow( *pProperty ) )
897                 continue;
898 
899             switch ( nPropId )
900             {
901             case PROPERTY_ID_BORDER:
902             case PROPERTY_ID_TABSTOP:
903                 // BORDER and TABSTOP are normalized (see impl_normalizePropertyValue_nothrow)
904                 // to not allow VOID values
905                 pProperty->Attributes &= ~( PropertyAttribute::MAYBEVOID );
906                 break;
907 
908             case PROPERTY_ID_LISTSOURCE:
909                 // no cursor source if no Base is installed. #124939#
910                 // This fix is not intendend to appear on the main trunk. If you find it there,
911                 // please tell me! frank.schoenheit@sun.com
912                 if ( SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
913                     const_cast< FormComponentPropertyHandler* >( this )->m_bHaveListSource = true;
914                 break;
915 
916             case PROPERTY_ID_COMMAND:
917                 // no cursor source if no Base is installed. #124939#
918                 // This fix is not intendend to appear on the main trunk. If you find it there,
919                 // please tell me! frank.schoenheit@sun.com
920                 if ( SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
921                     const_cast< FormComponentPropertyHandler* >( this )->m_bHaveCommand = true;
922                 break;
923             }   // switch ( nPropId )
924 
925             aProperties.push_back( *pProperty );
926         }
927 
928         if ( aProperties.empty() )
929             return Sequence< Property >();
930         return Sequence< Property >( &(*aProperties.begin()), aProperties.size() );
931     }
932 
933     //--------------------------------------------------------------------
getSupersededProperties()934     Sequence< ::rtl::OUString > SAL_CALL FormComponentPropertyHandler::getSupersededProperties( ) throw (RuntimeException)
935     {
936         return Sequence< ::rtl::OUString >( );
937     }
938 
939     //--------------------------------------------------------------------
getActuatingProperties()940     Sequence< ::rtl::OUString > SAL_CALL FormComponentPropertyHandler::getActuatingProperties( ) throw (RuntimeException)
941     {
942         ::osl::MutexGuard aGuard( m_aMutex );
943         ::std::vector< ::rtl::OUString > aInterestingProperties;
944         aInterestingProperties.push_back( PROPERTY_DATASOURCE );
945         aInterestingProperties.push_back( PROPERTY_COMMAND );
946         aInterestingProperties.push_back( PROPERTY_COMMANDTYPE );
947         aInterestingProperties.push_back( PROPERTY_LISTSOURCE );
948         aInterestingProperties.push_back( PROPERTY_LISTSOURCETYPE );
949         aInterestingProperties.push_back( PROPERTY_SUBMIT_ENCODING );
950         aInterestingProperties.push_back( PROPERTY_REPEAT );
951         aInterestingProperties.push_back( PROPERTY_TABSTOP );
952         aInterestingProperties.push_back( PROPERTY_BORDER );
953         aInterestingProperties.push_back( PROPERTY_CONTROLSOURCE );
954         aInterestingProperties.push_back( PROPERTY_DROPDOWN );
955         aInterestingProperties.push_back( PROPERTY_IMAGE_URL );
956         aInterestingProperties.push_back( PROPERTY_TARGET_URL );
957         aInterestingProperties.push_back( PROPERTY_STRINGITEMLIST );
958         aInterestingProperties.push_back( PROPERTY_BUTTONTYPE );
959         aInterestingProperties.push_back( PROPERTY_ESCAPE_PROCESSING );
960         aInterestingProperties.push_back( PROPERTY_TRISTATE );
961         aInterestingProperties.push_back( PROPERTY_DECIMAL_ACCURACY );
962         aInterestingProperties.push_back( PROPERTY_SHOWTHOUSANDSEP );
963         aInterestingProperties.push_back( PROPERTY_FORMATKEY );
964         aInterestingProperties.push_back( PROPERTY_EMPTY_IS_NULL );
965         aInterestingProperties.push_back( PROPERTY_TOGGLE );
966         return Sequence< ::rtl::OUString >( &(*aInterestingProperties.begin()), aInterestingProperties.size() );
967     }
968 
969     //--------------------------------------------------------------------
describePropertyLine(const::rtl::OUString & _rPropertyName,const Reference<XPropertyControlFactory> & _rxControlFactory)970     LineDescriptor SAL_CALL FormComponentPropertyHandler::describePropertyLine( const ::rtl::OUString& _rPropertyName,
971         const Reference< XPropertyControlFactory >& _rxControlFactory )
972         throw (UnknownPropertyException, NullPointerException, RuntimeException)
973     {
974         if ( !_rxControlFactory.is() )
975             throw NullPointerException();
976 
977         ::osl::MutexGuard aGuard( m_aMutex );
978         PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
979         Property aProperty( impl_getPropertyFromId_throw( nPropId ) );
980 
981         //////////////////////////////////////////////////////////////////////
982         // for the MultiLine property, we have different UI translations depending on the control
983         // type
984         if ( nPropId == PROPERTY_ID_MULTILINE )
985         {
986             if (  ( m_nClassId == FormComponentType::FIXEDTEXT )
987                || ( m_nClassId == FormComponentType::COMMANDBUTTON )
988                || ( m_nClassId == FormComponentType::RADIOBUTTON )
989                || ( m_nClassId == FormComponentType::CHECKBOX )
990                )
991                 nPropId = PROPERTY_ID_WORDBREAK;
992         }
993 
994         String sDisplayName = m_pInfoService->getPropertyTranslation( nPropId );
995         if ( !sDisplayName.Len() )
996         {
997             DBG_ERROR( "FormComponentPropertyHandler::describePropertyLine: did getSupportedProperties not work properly?" );
998             throw UnknownPropertyException();
999         }
1000 
1001         //////////////////////////////////////////////////////////////////////
1002 
1003         LineDescriptor aDescriptor;
1004         aDescriptor.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( nPropId ) );
1005         aDescriptor.DisplayName = sDisplayName;
1006 
1007         // for the moment, assume a text field
1008         sal_Int16 nControlType = PropertyControlType::TextField;
1009         sal_Bool bReadOnly = sal_False;
1010         aDescriptor.Control.clear();
1011 
1012         //////////////////////////////////////////////////////////////////////
1013 
1014         bool bNeedDefaultStringIfVoidAllowed = false;
1015 
1016         TypeClass eType = aProperty.Type.getTypeClass();
1017 
1018         switch ( nPropId )
1019         {
1020         case PROPERTY_ID_DEFAULT_SELECT_SEQ:
1021         case PROPERTY_ID_SELECTEDITEMS:
1022             aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_SELECTION);
1023             break;
1024 
1025         case PROPERTY_ID_FILTER:
1026             aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_FILTER);
1027             break;
1028 
1029         case PROPERTY_ID_SORT:
1030             aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_ORDER);
1031             break;
1032 
1033         case PROPERTY_ID_MASTERFIELDS:
1034         case PROPERTY_ID_DETAILFIELDS:
1035             nControlType = PropertyControlType::StringListField;
1036             aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_FORMLINKFIELDS);
1037             break;
1038 
1039         case PROPERTY_ID_COMMAND:
1040             aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_SQLCOMMAND);
1041             break;
1042 
1043         case PROPERTY_ID_TABINDEX:
1044         {
1045             Reference< XControlContainer > xControlContext( impl_getContextControlContainer_nothrow() );
1046             if ( xControlContext.is() )
1047                 aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_TABINDEX);
1048             nControlType = PropertyControlType::NumericField;
1049         };
1050         break;
1051 
1052         case PROPERTY_ID_FONT:
1053             bReadOnly = sal_True;
1054             aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_FONT_TYPE);
1055             break;
1056 
1057         case PROPERTY_ID_TARGET_URL:
1058         case PROPERTY_ID_IMAGE_URL:
1059         {
1060             aDescriptor.Control = new OFileUrlControl( impl_getDefaultDialogParent_nothrow(), WB_TABSTOP | WB_BORDER );
1061 
1062             aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(( PROPERTY_ID_TARGET_URL == nPropId )
1063                 ? UID_PROP_DLG_ATTR_TARGET_URL : UID_PROP_DLG_IMAGE_URL);
1064         }
1065         break;
1066 
1067         case PROPERTY_ID_ECHO_CHAR:
1068             nControlType = PropertyControlType::CharacterField;
1069             break;
1070 
1071         case PROPERTY_ID_BACKGROUNDCOLOR:
1072         case PROPERTY_ID_FILLCOLOR:
1073         case PROPERTY_ID_SYMBOLCOLOR:
1074         case PROPERTY_ID_BORDERCOLOR:
1075             nControlType = PropertyControlType::ColorListBox;
1076 
1077             switch( nPropId )
1078             {
1079             case PROPERTY_ID_BACKGROUNDCOLOR:
1080                 aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_BACKGROUNDCOLOR); break;
1081             case PROPERTY_ID_FILLCOLOR:
1082                 aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_FILLCOLOR); break;
1083             case PROPERTY_ID_SYMBOLCOLOR:
1084                 aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_SYMBOLCOLOR); break;
1085             case PROPERTY_ID_BORDERCOLOR:
1086                 aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_BORDERCOLOR); break;
1087             }
1088             break;
1089 
1090         case PROPERTY_ID_LABEL:
1091             nControlType = PropertyControlType::MultiLineTextField;
1092             break;
1093 
1094         case PROPERTY_ID_DEFAULT_TEXT:
1095         {
1096             if (FormComponentType::FILECONTROL == m_nClassId)
1097                 nControlType = PropertyControlType::TextField;
1098             else
1099                 nControlType = PropertyControlType::MultiLineTextField;
1100         }
1101         break;
1102 
1103         case PROPERTY_ID_TEXT:
1104             if ( impl_componentHasProperty_throw( PROPERTY_MULTILINE ) )
1105                 nControlType = PropertyControlType::MultiLineTextField;
1106             break;
1107 
1108         case PROPERTY_ID_CONTROLLABEL:
1109             bReadOnly = sal_True;
1110             aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_CONTROLLABEL);
1111             break;
1112 
1113         case PROPERTY_ID_FORMATKEY:
1114         case PROPERTY_ID_EFFECTIVE_MIN:
1115         case PROPERTY_ID_EFFECTIVE_MAX:
1116         case PROPERTY_ID_EFFECTIVE_DEFAULT:
1117         case PROPERTY_ID_EFFECTIVE_VALUE:
1118         {
1119             // and the supplier is really available
1120             Reference< XNumberFormatsSupplier >  xSupplier;
1121             m_xComponent->getPropertyValue( PROPERTY_FORMATSSUPPLIER ) >>= xSupplier;
1122             if (xSupplier.is())
1123             {
1124                 Reference< XUnoTunnel > xTunnel(xSupplier,UNO_QUERY);
1125                 DBG_ASSERT(xTunnel.is(), "FormComponentPropertyHandler::describePropertyLine : xTunnel is invalid!");
1126                 SvNumberFormatsSupplierObj* pSupplier = reinterpret_cast<SvNumberFormatsSupplierObj*>(xTunnel->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));
1127 
1128                 if (pSupplier != NULL)
1129                 {
1130                     sal_Bool bIsFormatKey = (PROPERTY_ID_FORMATKEY == nPropId);
1131 
1132                     bReadOnly = bIsFormatKey;
1133 
1134                     if ( bIsFormatKey )
1135                     {
1136                         OFormatSampleControl* pControl = new OFormatSampleControl( impl_getDefaultDialogParent_nothrow(), WB_READONLY | WB_TABSTOP | WB_BORDER );
1137                         aDescriptor.Control = pControl;
1138                         pControl->SetFormatSupplier( pSupplier );
1139 
1140                         aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_NUMBER_FORMAT);
1141                     }
1142                     else
1143                     {
1144                         OFormattedNumericControl* pControl = new OFormattedNumericControl( impl_getDefaultDialogParent_nothrow(), WB_TABSTOP | WB_BORDER );
1145                         aDescriptor.Control = pControl;
1146 
1147                         FormatDescription aDesc;
1148                         aDesc.pSupplier = pSupplier;
1149                         Any aFormatKeyValue = m_xComponent->getPropertyValue(PROPERTY_FORMATKEY);
1150                         if ( !( aFormatKeyValue >>= aDesc.nKey ) )
1151                             aDesc.nKey = 0;
1152 
1153                         pControl->SetFormatDescription( aDesc );
1154                     }
1155                 }
1156             }
1157         }
1158         break;
1159 
1160         case PROPERTY_ID_DATEMIN:
1161         case PROPERTY_ID_DATEMAX:
1162         case PROPERTY_ID_DEFAULT_DATE:
1163         case PROPERTY_ID_DATE:
1164             nControlType = PropertyControlType::DateField;
1165             break;
1166 
1167         case PROPERTY_ID_TIMEMIN:
1168         case PROPERTY_ID_TIMEMAX:
1169         case PROPERTY_ID_DEFAULT_TIME:
1170         case PROPERTY_ID_TIME:
1171             nControlType = PropertyControlType::TimeField;
1172             break;
1173 
1174         case PROPERTY_ID_VALUEMIN:
1175         case PROPERTY_ID_VALUEMAX:
1176         case PROPERTY_ID_DEFAULT_VALUE:
1177         case PROPERTY_ID_VALUE:
1178             {
1179                 OFormattedNumericControl* pControl = new OFormattedNumericControl( impl_getDefaultDialogParent_nothrow(), WB_TABSTOP | WB_BORDER | WB_SPIN | WB_REPEAT );
1180                 aDescriptor.Control = pControl;
1181 
1182                 // we don't set a formatter so the control uses a default (which uses the application
1183                 // language and a default numeric format)
1184                 // but we set the decimal digits
1185                 pControl->SetDecimalDigits(
1186                     ::comphelper::getINT16( m_xComponent->getPropertyValue( PROPERTY_DECIMAL_ACCURACY ) )
1187                 );
1188 
1189                 // and the thousands separator
1190                 pControl->SetThousandsSep(
1191                     ::comphelper::getBOOL( m_xComponent->getPropertyValue(PROPERTY_SHOWTHOUSANDSEP) )
1192                 );
1193 
1194                 // and the default value for the property
1195                 try
1196                 {
1197                     if (m_xPropertyState.is() && ((PROPERTY_ID_VALUEMIN == nPropId) || (PROPERTY_ID_VALUEMAX == nPropId)))
1198                     {
1199                         double nDefault = 0;
1200                         if ( m_xPropertyState->getPropertyDefault( aProperty.Name ) >>= nDefault )
1201                             pControl->SetDefaultValue( nDefault );
1202                     }
1203                 }
1204                 catch (Exception&)
1205                 {
1206                     // just ignore it
1207                 }
1208 
1209                 // and allow empty values only for the default value and the value
1210                 pControl->EnableEmptyField( ( PROPERTY_ID_DEFAULT_VALUE == nPropId )
1211                                         ||  ( PROPERTY_ID_VALUE == nPropId ) );
1212             }
1213             break;
1214 
1215         default:
1216             if ( TypeClass_BYTE <= eType && eType <= TypeClass_DOUBLE )
1217             {
1218                 sal_Int16 nDigits = 0;
1219                 sal_Int16 nValueUnit = -1;
1220                 sal_Int16 nDisplayUnit = -1;
1221                 if ( m_eComponentClass == eFormControl )
1222                 {
1223                     if  (  ( nPropId == PROPERTY_ID_WIDTH )
1224                         || ( nPropId == PROPERTY_ID_ROWHEIGHT )
1225                         || ( nPropId == PROPERTY_ID_HEIGHT )
1226                         )
1227                     {
1228                         nValueUnit = MeasureUnit::MM_10TH;
1229                         nDisplayUnit = impl_getDocumentMeasurementUnit_throw();
1230                         nDigits = 2;
1231                     }
1232                 }
1233 
1234                 Optional< double > aValueNotPresent( sal_False, 0 );
1235                 aDescriptor.Control = PropertyHandlerHelper::createNumericControl(
1236                     _rxControlFactory, nDigits, aValueNotPresent, aValueNotPresent, sal_False );
1237 
1238                 Reference< XNumericControl > xNumericControl( aDescriptor.Control, UNO_QUERY_THROW );
1239                 if ( nValueUnit != -1 )
1240                     xNumericControl->setValueUnit( nValueUnit );
1241                 if ( nDisplayUnit != -1 )
1242                     xNumericControl->setDisplayUnit( nDisplayUnit );
1243             }
1244             break;
1245         }
1246 
1247         //////////////////////////////////////////////////////////////////////
1248         if ( eType == TypeClass_SEQUENCE )
1249             nControlType = PropertyControlType::StringListField;
1250 
1251         //////////////////////////////////////////////////////////////////////
1252         // boolean values
1253         if ( eType == TypeClass_BOOLEAN )
1254         {
1255             sal_uInt16 nResId = RID_RSC_ENUM_YESNO;
1256             if  (   ( nPropId == PROPERTY_ID_SHOW_POSITION )
1257                 ||  ( nPropId == PROPERTY_ID_SHOW_NAVIGATION )
1258                 ||  ( nPropId == PROPERTY_ID_SHOW_RECORDACTIONS )
1259                 ||  ( nPropId == PROPERTY_ID_SHOW_FILTERSORT )
1260                 )
1261                 nResId = RID_RSC_ENUM_SHOWHIDE;
1262 
1263             ::std::vector< ::rtl::OUString > aListEntries;
1264             tools::StringListResource aRes(PcrRes(nResId),aListEntries);
1265             aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
1266             bNeedDefaultStringIfVoidAllowed = true;
1267         }
1268 
1269         //////////////////////////////////////////////////////////////////////
1270         // enum properties
1271         sal_uInt32 nPropertyUIFlags = m_pInfoService->getPropertyUIFlags( nPropId );
1272         bool bIsEnumProperty = ( nPropertyUIFlags & PROP_FLAG_ENUM ) != 0;
1273         if ( bIsEnumProperty || ( PROPERTY_ID_TARGET_FRAME == nPropId ) )
1274         {
1275             ::std::vector< ::rtl::OUString > aEnumValues = m_pInfoService->getPropertyEnumRepresentations( nPropId );
1276             ::std::vector< ::rtl::OUString >::const_iterator pStart = aEnumValues.begin();
1277             ::std::vector< ::rtl::OUString >::const_iterator pEnd = aEnumValues.end();
1278 
1279             // for a checkbox: if "ambiguous" is not allowed, remove this from the sequence
1280             if  (   ( PROPERTY_ID_DEFAULT_STATE == nPropId )
1281                 ||  ( PROPERTY_ID_STATE == nPropId )
1282                 )
1283             {
1284                 if ( impl_componentHasProperty_throw( PROPERTY_TRISTATE ) )
1285                 {
1286                     if ( !::comphelper::getBOOL( m_xComponent->getPropertyValue( PROPERTY_TRISTATE ) ) )
1287                     {   // remove the last sequence element
1288                         if ( pEnd > pStart )
1289                             --pEnd;
1290                     }
1291                 }
1292                 else
1293                     --pEnd;
1294             }
1295 
1296             if ( PROPERTY_ID_LISTSOURCETYPE == nPropId )
1297                 if ( FormComponentType::COMBOBOX == m_nClassId )
1298                     // remove the first sequence element -> value list not possible for combo boxes
1299                     ++pStart;
1300 
1301             // copy the sequence
1302             ::std::vector< ::rtl::OUString > aListEntries( pEnd - pStart );
1303             ::std::copy( pStart, pEnd, aListEntries.begin() );
1304 
1305             // create the control
1306             if ( PROPERTY_ID_TARGET_FRAME == nPropId )
1307                 aDescriptor.Control = PropertyHandlerHelper::createComboBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
1308             else
1309             {
1310                 aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
1311                 bNeedDefaultStringIfVoidAllowed = true;
1312             }
1313         }
1314 
1315         //////////////////////////////////////////////////////////////////////
1316         switch( nPropId )
1317         {
1318             case PROPERTY_ID_REPEAT_DELAY:
1319             {
1320                 OTimeDurationControl* pControl = new OTimeDurationControl( impl_getDefaultDialogParent_nothrow(), WB_BORDER | WB_TABSTOP );
1321                 aDescriptor.Control = pControl;
1322 
1323                 pControl->setMinValue( Optional< double >( sal_True, 0 ) );
1324                 pControl->setMaxValue( Optional< double >( sal_True, ::std::numeric_limits< double >::max() ) );
1325             }
1326             break;
1327 
1328             case PROPERTY_ID_TABINDEX:
1329             case PROPERTY_ID_BOUNDCOLUMN:
1330             case PROPERTY_ID_VISIBLESIZE:
1331             case PROPERTY_ID_MAXTEXTLEN:
1332             case PROPERTY_ID_LINEINCREMENT:
1333             case PROPERTY_ID_BLOCKINCREMENT:
1334             case PROPERTY_ID_SPININCREMENT:
1335             {
1336                 Optional< double > aMinValue( sal_True, 0 );
1337                 Optional< double > aMaxValue( sal_True, 0x7FFFFFFF );
1338 
1339                 if ( nPropId == PROPERTY_ID_MAXTEXTLEN )
1340                     aMinValue.Value = -1;
1341                 else if ( nPropId == PROPERTY_ID_VISIBLESIZE )
1342                     aMinValue.Value = 1;
1343                 else
1344                     aMinValue.Value = 0;
1345 
1346                 aDescriptor.Control = PropertyHandlerHelper::createNumericControl(
1347                     _rxControlFactory, 0, aMinValue, aMaxValue, sal_False );
1348             }
1349             break;
1350 
1351             case PROPERTY_ID_DECIMAL_ACCURACY:
1352             {
1353                 Optional< double > aMinValue( sal_True, 0 );
1354                 Optional< double > aMaxValue( sal_True, 20 );
1355 
1356                 aDescriptor.Control = PropertyHandlerHelper::createNumericControl(
1357                     _rxControlFactory, 0, aMinValue, aMaxValue, sal_False );
1358             }
1359             break;
1360 
1361             //////////////////////////////////////////////////////////////////////
1362             // DataSource
1363             case PROPERTY_ID_DATASOURCE:
1364             {
1365                 aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_ATTR_DATASOURCE);
1366 
1367                 ::std::vector< ::rtl::OUString > aListEntries;
1368 
1369                 Reference< XNameAccess > xDatabaseContext;
1370                 m_aContext.createComponent( (rtl::OUString)SERVICE_DATABASE_CONTEXT, xDatabaseContext );
1371                 if (xDatabaseContext.is())
1372                 {
1373                     Sequence< ::rtl::OUString > aDatasources = xDatabaseContext->getElementNames();
1374                     aListEntries.resize( aDatasources.getLength() );
1375                     ::std::copy( aDatasources.getConstArray(), aDatasources.getConstArray() + aDatasources.getLength(),
1376                         aListEntries.begin() );
1377                 }
1378                 aDescriptor.Control = PropertyHandlerHelper::createComboBoxControl(
1379                     _rxControlFactory, aListEntries, sal_False, sal_True );
1380             }
1381             break;
1382 
1383             case PROPERTY_ID_CONTROLSOURCE:
1384             {
1385                 ::std::vector< ::rtl::OUString > aFieldNames;
1386                 impl_initFieldList_nothrow( aFieldNames );
1387                 aDescriptor.Control = PropertyHandlerHelper::createComboBoxControl(
1388                     _rxControlFactory, aFieldNames, sal_False, sal_False );
1389             }
1390             break;
1391 
1392             case PROPERTY_ID_COMMAND:
1393                 impl_describeCursorSource_nothrow( aDescriptor, _rxControlFactory );
1394                 break;
1395 
1396             case PROPERTY_ID_LISTSOURCE:
1397                 impl_describeListSourceUI_throw( aDescriptor, _rxControlFactory );
1398                 break;
1399         }
1400 
1401         if ( !aDescriptor.Control.is() )
1402             aDescriptor.Control = _rxControlFactory->createPropertyControl( nControlType, bReadOnly );
1403 
1404         if ( ( aProperty.Attributes & PropertyAttribute::MAYBEVOID ) != 0 )
1405         {
1406             // insert the string "Default" string, if necessary
1407             if ( bNeedDefaultStringIfVoidAllowed || ( nControlType == PropertyControlType::ColorListBox ) )
1408             {
1409                 Reference< XStringListControl > xStringList( aDescriptor.Control, UNO_QUERY_THROW );
1410                 xStringList->prependListEntry( m_sDefaultValueString );
1411                 m_aPropertiesWithDefListEntry.insert( _rPropertyName );
1412             }
1413         }
1414 
1415         if ( aDescriptor.PrimaryButtonId.getLength() )
1416             aDescriptor.HasPrimaryButton = sal_True;
1417         if ( aDescriptor.SecondaryButtonId.getLength() )
1418             aDescriptor.HasSecondaryButton = sal_True;
1419 
1420         bool bIsDataProperty = ( nPropertyUIFlags & PROP_FLAG_DATA_PROPERTY ) != 0;
1421         aDescriptor.Category = ::rtl::OUString::createFromAscii( bIsDataProperty ? "Data" : "General" );
1422         return aDescriptor;
1423     }
1424 
1425     //--------------------------------------------------------------------
onInteractivePropertySelection(const::rtl::OUString & _rPropertyName,sal_Bool,Any & _rData,const Reference<XObjectInspectorUI> & _rxInspectorUI)1426     InteractiveSelectionResult SAL_CALL FormComponentPropertyHandler::onInteractivePropertySelection( const ::rtl::OUString& _rPropertyName, sal_Bool /*_bPrimary*/, Any& _rData, const Reference< XObjectInspectorUI >& _rxInspectorUI ) throw (UnknownPropertyException, NullPointerException, RuntimeException)
1427     {
1428         if ( !_rxInspectorUI.is() )
1429             throw NullPointerException();
1430 
1431         ::osl::ClearableMutexGuard aGuard( m_aMutex );
1432         PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
1433 
1434         InteractiveSelectionResult eResult = InteractiveSelectionResult_Cancelled;
1435         switch ( nPropId )
1436         {
1437         case PROPERTY_ID_DEFAULT_SELECT_SEQ:
1438         case PROPERTY_ID_SELECTEDITEMS:
1439             if ( impl_dialogListSelection_nothrow( _rPropertyName, aGuard ) )
1440                 eResult = InteractiveSelectionResult_Success;
1441             break;
1442 
1443         case PROPERTY_ID_FILTER:
1444         case PROPERTY_ID_SORT:
1445         {
1446             ::rtl::OUString sClause;
1447             if ( impl_dialogFilterOrSort_nothrow( PROPERTY_ID_FILTER == nPropId, sClause, aGuard ) )
1448             {
1449                 _rData <<= sClause;
1450                 eResult = InteractiveSelectionResult_ObtainedValue;
1451             }
1452         }
1453         break;
1454 
1455         case PROPERTY_ID_MASTERFIELDS:
1456         case PROPERTY_ID_DETAILFIELDS:
1457             if ( impl_dialogLinkedFormFields_nothrow( aGuard ) )
1458                 eResult = InteractiveSelectionResult_Success;
1459             break;
1460 
1461         case PROPERTY_ID_FORMATKEY:
1462             if ( impl_dialogFormatting_nothrow( _rData, aGuard ) )
1463                 eResult = InteractiveSelectionResult_ObtainedValue;
1464             break;
1465 
1466         case PROPERTY_ID_IMAGE_URL:
1467             if ( impl_browseForImage_nothrow( _rData, aGuard ) )
1468                 eResult = InteractiveSelectionResult_ObtainedValue;
1469             break;
1470 
1471         case PROPERTY_ID_TARGET_URL:
1472             if ( impl_browseForTargetURL_nothrow( _rData, aGuard ) )
1473                 eResult = InteractiveSelectionResult_ObtainedValue;
1474             break;
1475 
1476         case PROPERTY_ID_FONT:
1477             if ( impl_executeFontDialog_nothrow( _rData, aGuard ) )
1478                 eResult = InteractiveSelectionResult_ObtainedValue;
1479             break;
1480 
1481         case PROPERTY_ID_DATASOURCE:
1482             if ( impl_browseForDatabaseDocument_throw( _rData, aGuard ) )
1483                 eResult = InteractiveSelectionResult_ObtainedValue;
1484             break;
1485 
1486         case PROPERTY_ID_BACKGROUNDCOLOR:
1487         case PROPERTY_ID_FILLCOLOR:
1488         case PROPERTY_ID_SYMBOLCOLOR:
1489         case PROPERTY_ID_BORDERCOLOR:
1490             if ( impl_dialogColorChooser_throw( nPropId, _rData, aGuard ) )
1491                 eResult = InteractiveSelectionResult_ObtainedValue;
1492             break;
1493 
1494         case PROPERTY_ID_CONTROLLABEL:
1495             if ( impl_dialogChooseLabelControl_nothrow( _rData, aGuard ) )
1496                 eResult = InteractiveSelectionResult_ObtainedValue;
1497             break;
1498 
1499         case PROPERTY_ID_TABINDEX:
1500             if ( impl_dialogChangeTabOrder_nothrow( aGuard ) )
1501                 eResult = InteractiveSelectionResult_Success;
1502             break;
1503 
1504         case PROPERTY_ID_COMMAND:
1505         case PROPERTY_ID_LISTSOURCE:
1506             if ( impl_doDesignSQLCommand_nothrow( _rxInspectorUI, nPropId ) )
1507                 eResult = InteractiveSelectionResult_Pending;
1508             break;
1509         default:
1510             DBG_ERROR( "FormComponentPropertyHandler::onInteractivePropertySelection: request for a property which does not have dedicated UI!" );
1511             break;
1512         }
1513         return eResult;
1514     }
1515 
1516     //--------------------------------------------------------------------
1517     namespace
1518     {
lcl_rebuildAndResetCommand(const Reference<XObjectInspectorUI> & _rxInspectorUI,const Reference<XPropertyHandler> & _rxHandler)1519         void lcl_rebuildAndResetCommand( const Reference< XObjectInspectorUI >& _rxInspectorUI, const Reference< XPropertyHandler >& _rxHandler )
1520         {
1521             OSL_PRECOND( _rxInspectorUI.is(), "lcl_rebuildAndResetCommand: invalid BrowserUI!" );
1522             OSL_PRECOND( _rxHandler.is(), "lcl_rebuildAndResetCommand: invalid handler!" );
1523             _rxInspectorUI->rebuildPropertyUI( PROPERTY_COMMAND );
1524             _rxHandler->setPropertyValue( PROPERTY_COMMAND, makeAny( ::rtl::OUString() ) );
1525         }
1526     }
1527 
1528     //--------------------------------------------------------------------
actuatingPropertyChanged(const::rtl::OUString & _rActuatingPropertyName,const Any & _rNewValue,const Any &,const Reference<XObjectInspectorUI> & _rxInspectorUI,sal_Bool _bFirstTimeInit)1529     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)
1530     {
1531         if ( !_rxInspectorUI.is() )
1532             throw NullPointerException();
1533 
1534         ::osl::MutexGuard aGuard( m_aMutex );
1535         PropertyId nActuatingPropId( impl_getPropertyId_throw( _rActuatingPropertyName ) );
1536 
1537         ::std::vector< PropertyId > aDependentProperties;
1538 
1539         switch ( nActuatingPropId )
1540         {
1541         // ----- EscapeProcessing -----
1542         case PROPERTY_ID_ESCAPE_PROCESSING:
1543             aDependentProperties.push_back( PROPERTY_ID_FILTER );
1544             aDependentProperties.push_back( PROPERTY_ID_SORT );
1545             break;  // case PROPERTY_ID_ESCAPE_PROCESSING
1546 
1547         // ----- CommandType -----
1548         case PROPERTY_ID_COMMANDTYPE:
1549             // available commands (tables or queries) might have changed
1550             if ( !_bFirstTimeInit && m_bHaveCommand )
1551                 lcl_rebuildAndResetCommand( _rxInspectorUI, this );
1552             aDependentProperties.push_back( PROPERTY_ID_COMMAND );
1553             break;  // case PROPERTY_ID_COMMANDTYPE
1554 
1555         // ----- DataSourceName -----
1556         case PROPERTY_ID_DATASOURCE:
1557             // reset the connection, now that we have a new data source
1558             impl_clearRowsetConnection_nothrow();
1559 
1560             // available list source values (tables or queries) might have changed
1561             if ( !_bFirstTimeInit && m_bHaveListSource )
1562                 _rxInspectorUI->rebuildPropertyUI( PROPERTY_LISTSOURCE );
1563 
1564             // available commands (tables or queries) might have changed
1565             if ( !_bFirstTimeInit && m_bHaveCommand )
1566                 lcl_rebuildAndResetCommand( _rxInspectorUI, this );
1567 
1568             // Command also depends on DataSource
1569             aDependentProperties.push_back( PROPERTY_ID_COMMAND );
1570             // NO break!
1571 
1572         // ----- Command -----
1573         case PROPERTY_ID_COMMAND:
1574             aDependentProperties.push_back( PROPERTY_ID_FILTER );
1575             aDependentProperties.push_back( PROPERTY_ID_SORT );
1576             if ( m_bComponentIsSubForm )
1577                 aDependentProperties.push_back( PROPERTY_ID_DETAILFIELDS );
1578             break;
1579 
1580         // ----- ListSourceType -----
1581         case PROPERTY_ID_LISTSOURCETYPE:
1582             if ( !_bFirstTimeInit && m_bHaveListSource )
1583                 // available list source values (tables or queries) might have changed
1584                 _rxInspectorUI->rebuildPropertyUI( PROPERTY_LISTSOURCE );
1585             aDependentProperties.push_back( PROPERTY_ID_BOUNDCOLUMN );
1586             aDependentProperties.push_back( PROPERTY_ID_STRINGITEMLIST );
1587             // NO break!
1588 
1589         // ----- StringItemList -----
1590         case PROPERTY_ID_STRINGITEMLIST:
1591             aDependentProperties.push_back( PROPERTY_ID_SELECTEDITEMS );
1592             aDependentProperties.push_back( PROPERTY_ID_DEFAULT_SELECT_SEQ );
1593             break;
1594 
1595         // ----- ListSource -----
1596         case PROPERTY_ID_LISTSOURCE:
1597             aDependentProperties.push_back( PROPERTY_ID_STRINGITEMLIST );
1598             break;
1599 
1600         // ----- DataField -----
1601         case PROPERTY_ID_CONTROLSOURCE:
1602         {
1603             ::rtl::OUString sControlSource;
1604             _rNewValue >>= sControlSource;
1605             if ( impl_componentHasProperty_throw( PROPERTY_FILTERPROPOSAL ) )
1606                 _rxInspectorUI->enablePropertyUI( PROPERTY_FILTERPROPOSAL, sControlSource.getLength() > 0 );
1607             if ( impl_componentHasProperty_throw( PROPERTY_EMPTY_IS_NULL ) )
1608                 _rxInspectorUI->enablePropertyUI( PROPERTY_EMPTY_IS_NULL, sControlSource.getLength() > 0 );
1609 
1610             aDependentProperties.push_back( PROPERTY_ID_BOUNDCOLUMN );
1611             aDependentProperties.push_back( PROPERTY_ID_SCALEIMAGE );
1612             aDependentProperties.push_back( PROPERTY_ID_SCALE_MODE );
1613             aDependentProperties.push_back( PROPERTY_ID_INPUT_REQUIRED );
1614         }
1615         break;
1616 
1617         case PROPERTY_ID_EMPTY_IS_NULL:
1618             aDependentProperties.push_back( PROPERTY_ID_INPUT_REQUIRED );
1619             break;
1620 
1621         // ----- SubmitEncoding -----
1622         case PROPERTY_ID_SUBMIT_ENCODING:
1623         {
1624             FormSubmitEncoding eEncoding = FormSubmitEncoding_URL;
1625             OSL_VERIFY( _rNewValue >>= eEncoding );
1626             _rxInspectorUI->enablePropertyUI( PROPERTY_SUBMIT_METHOD, eEncoding == FormSubmitEncoding_URL );
1627         }
1628         break;
1629 
1630         // ----- Repeat -----
1631         case PROPERTY_ID_REPEAT:
1632         {
1633             sal_Bool bIsRepeating = sal_False;
1634             OSL_VERIFY( _rNewValue >>= bIsRepeating );
1635             _rxInspectorUI->enablePropertyUI( PROPERTY_REPEAT_DELAY, bIsRepeating );
1636         }
1637         break;
1638 
1639         // ----- TabStop -----
1640         case PROPERTY_ID_TABSTOP:
1641         {
1642             if ( !impl_componentHasProperty_throw( PROPERTY_TABINDEX ) )
1643                 break;
1644             sal_Bool bHasTabStop = sal_False;
1645             _rNewValue >>= bHasTabStop;
1646             _rxInspectorUI->enablePropertyUI( PROPERTY_TABINDEX, bHasTabStop );
1647         }
1648         break;
1649 
1650         // ----- Border -----
1651         case PROPERTY_ID_BORDER:
1652         {
1653             sal_Int16 nBordeType = VisualEffect::NONE;
1654             OSL_VERIFY( _rNewValue >>= nBordeType );
1655             _rxInspectorUI->enablePropertyUI( PROPERTY_BORDERCOLOR, nBordeType == VisualEffect::FLAT );
1656         }
1657         break;
1658 
1659         // ----- DropDown -----
1660         case PROPERTY_ID_DROPDOWN:
1661         {
1662             if ( impl_isSupportedProperty_nothrow( PROPERTY_ID_LINECOUNT ) )
1663             {
1664                 sal_Bool bDropDown = sal_True;
1665                 _rNewValue >>= bDropDown;
1666                 _rxInspectorUI->enablePropertyUI( PROPERTY_LINECOUNT, bDropDown );
1667             }
1668         }
1669         break;
1670 
1671         // ----- ImageURL -----
1672         case PROPERTY_ID_IMAGE_URL:
1673         {
1674             if ( impl_isSupportedProperty_nothrow( PROPERTY_ID_IMAGEPOSITION ) )
1675             {
1676                 ::rtl::OUString sImageURL;
1677                 OSL_VERIFY( _rNewValue >>= sImageURL );
1678                 _rxInspectorUI->enablePropertyUI( PROPERTY_IMAGEPOSITION, sImageURL.getLength() != 0 );
1679             }
1680 
1681             aDependentProperties.push_back( PROPERTY_ID_SCALEIMAGE );
1682             aDependentProperties.push_back( PROPERTY_ID_SCALE_MODE );
1683         }
1684         break;
1685 
1686         // ----- ButtonType -----
1687         case PROPERTY_ID_BUTTONTYPE:
1688         {
1689             FormButtonType eButtonType( FormButtonType_PUSH );
1690             OSL_VERIFY( _rNewValue >>= eButtonType );
1691             _rxInspectorUI->enablePropertyUI( PROPERTY_TARGET_URL, FormButtonType_URL == eButtonType );
1692         }
1693         // NO break!
1694 
1695         // ----- TargetURL -----
1696         case PROPERTY_ID_TARGET_URL:
1697             aDependentProperties.push_back( PROPERTY_ID_TARGET_FRAME );
1698             break;  // case PROPERTY_ID_TARGET_URL
1699 
1700         // ----- TriState -----
1701         case PROPERTY_ID_TRISTATE:
1702             if ( !_bFirstTimeInit )
1703                 _rxInspectorUI->rebuildPropertyUI( m_eComponentClass == eFormControl ? PROPERTY_DEFAULT_STATE : PROPERTY_STATE );
1704             break;  // case PROPERTY_ID_TRISTATE
1705 
1706         // ----- DecimalAccuracy -----
1707         case PROPERTY_ID_DECIMAL_ACCURACY:
1708         // ----- ShowThousandsSeparator -----
1709         case PROPERTY_ID_SHOWTHOUSANDSEP:
1710         {
1711             sal_Bool bAccuracy = (PROPERTY_ID_DECIMAL_ACCURACY == nActuatingPropId);
1712             sal_uInt16  nNewDigits = 0;
1713             sal_Bool    bUseSep = sal_False;
1714             if ( bAccuracy )
1715                 OSL_VERIFY( _rNewValue >>= nNewDigits );
1716             else
1717                 OSL_VERIFY( _rNewValue >>= bUseSep );
1718 
1719             // propagate the changes to the min/max/default fields
1720             Any aCurrentProp;
1721             ::rtl::OUString aAffectedProps[] = { PROPERTY_VALUE, PROPERTY_DEFAULT_VALUE, PROPERTY_VALUEMIN, PROPERTY_VALUEMAX };
1722             for (sal_uInt16 i=0; i<sizeof(aAffectedProps)/sizeof(aAffectedProps[0]); ++i)
1723             {
1724                 Reference< XPropertyControl > xControl;
1725                 try
1726                 {
1727                     xControl = _rxInspectorUI->getPropertyControl( aAffectedProps[i] );
1728                 }
1729                 catch( const UnknownPropertyException& e ) { (void)e; }
1730                 if ( xControl.is() )
1731                 {
1732                     OFormattedNumericControl* pControl = dynamic_cast< OFormattedNumericControl* >( xControl.get() );
1733                     DBG_ASSERT( pControl, "FormComponentPropertyHandler::actuatingPropertyChanged: invalid control!" );
1734                     if ( pControl )
1735                     {
1736                         if ( bAccuracy )
1737                             pControl->SetDecimalDigits( nNewDigits );
1738                         else
1739                             pControl->SetThousandsSep( bUseSep );
1740                     }
1741                 }
1742             }
1743         }
1744         break;
1745 
1746         // ----- FormatKey -----
1747         case PROPERTY_ID_FORMATKEY:
1748         {
1749             FormatDescription aNewDesc;
1750 
1751             Reference< XNumberFormatsSupplier >  xSupplier;
1752             OSL_VERIFY( m_xComponent->getPropertyValue( PROPERTY_FORMATSSUPPLIER ) >>= xSupplier );
1753 
1754             Reference< XUnoTunnel > xTunnel( xSupplier, UNO_QUERY );
1755             DBG_ASSERT(xTunnel.is(), "FormComponentPropertyHandler::actuatingPropertyChanged: xTunnel is invalid!");
1756             if ( xTunnel.is() )
1757             {
1758                 SvNumberFormatsSupplierObj* pSupplier = reinterpret_cast<SvNumberFormatsSupplierObj*>(xTunnel->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));
1759                     // the same again
1760 
1761                 aNewDesc.pSupplier = pSupplier;
1762                 if ( !( _rNewValue >>= aNewDesc.nKey ) )
1763                     aNewDesc.nKey = 0;
1764 
1765                 // give each control which has to know this an own copy of the description
1766                 ::rtl::OUString aFormattedPropertyControls[] = {
1767                     PROPERTY_EFFECTIVE_MIN, PROPERTY_EFFECTIVE_MAX, PROPERTY_EFFECTIVE_DEFAULT, PROPERTY_EFFECTIVE_VALUE
1768                 };
1769                 for ( sal_uInt16 i=0; i<sizeof(aFormattedPropertyControls)/sizeof(aFormattedPropertyControls[0]); ++i )
1770                 {
1771                     Reference< XPropertyControl > xControl;
1772                     try
1773                     {
1774                         xControl = _rxInspectorUI->getPropertyControl( aFormattedPropertyControls[i] );
1775                     }
1776                     catch( const UnknownPropertyException& e ) { (void)e; }
1777                     if ( xControl.is() )
1778                     {
1779                         OFormattedNumericControl* pControl = dynamic_cast< OFormattedNumericControl* >( xControl.get() );
1780                         DBG_ASSERT( pControl, "FormComponentPropertyHandler::actuatingPropertyChanged: invalid control!" );
1781                         if ( pControl )
1782                             pControl->SetFormatDescription( aNewDesc );
1783                     }
1784                 }
1785             }
1786         }
1787         break;
1788 
1789         case PROPERTY_ID_TOGGLE:
1790         {
1791             sal_Bool bIsToggleButton = sal_False;
1792             OSL_VERIFY( _rNewValue >>= bIsToggleButton );
1793             _rxInspectorUI->enablePropertyUI( PROPERTY_DEFAULT_STATE, bIsToggleButton );
1794         }
1795         break;
1796 
1797         default:
1798             DBG_ERROR( "FormComponentPropertyHandler::actuatingPropertyChanged: did not register for this property!" );
1799             break;
1800 
1801         }   // switch ( nActuatingPropId )
1802 
1803         for ( ::std::vector< PropertyId >::const_iterator loopAffected = aDependentProperties.begin();
1804               loopAffected != aDependentProperties.end();
1805               ++loopAffected
1806             )
1807         {
1808             if ( impl_isSupportedProperty_nothrow( *loopAffected ) )
1809                 impl_updateDependentProperty_nothrow( *loopAffected, _rxInspectorUI );
1810         }
1811     }
1812 
1813     //------------------------------------------------------------------------
impl_updateDependentProperty_nothrow(PropertyId _nPropId,const Reference<XObjectInspectorUI> & _rxInspectorUI) const1814     void FormComponentPropertyHandler::impl_updateDependentProperty_nothrow( PropertyId _nPropId, const Reference< XObjectInspectorUI >& _rxInspectorUI ) const
1815     {
1816         try
1817         {
1818             switch ( _nPropId )
1819             {
1820             // ----- StringItemList -----
1821             case PROPERTY_ID_STRINGITEMLIST:
1822             {
1823                 ListSourceType eLSType = ListSourceType_VALUELIST;
1824                 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_LISTSOURCETYPE ) >>= eLSType );
1825 
1826                 ::rtl::OUString sListSource;
1827                 {
1828                     Sequence< ::rtl::OUString > aListSource;
1829                     Any aListSourceValue( impl_getPropertyValue_throw( PROPERTY_LISTSOURCE ) );
1830                     if ( aListSourceValue >>= aListSource )
1831                     {
1832                         if ( aListSource.getLength() )
1833                             sListSource = aListSource[0];
1834                     }
1835                     else
1836                         OSL_VERIFY( aListSourceValue >>= sListSource );
1837                 }
1838 
1839                 sal_Bool bIsEnabled =   (  ( eLSType == ListSourceType_VALUELIST )
1840                                         || ( sListSource.getLength() == 0 )
1841                                         );
1842                 _rxInspectorUI->enablePropertyUI( PROPERTY_STRINGITEMLIST, bIsEnabled );
1843             }
1844             break;  // case PROPERTY_ID_STRINGITEMLIST
1845 
1846             // ----- BoundColumn -----
1847             case PROPERTY_ID_BOUNDCOLUMN:
1848             {
1849                 ::rtl::OUString sControlSource;
1850                 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_CONTROLSOURCE ) >>= sControlSource );
1851 
1852                 ListSourceType eLSType = ListSourceType_VALUELIST;
1853                 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_LISTSOURCETYPE ) >>= eLSType );
1854 
1855                 _rxInspectorUI->enablePropertyUI( PROPERTY_BOUNDCOLUMN,
1856                         ( sControlSource.getLength() > 0 )
1857                     &&  ( eLSType != ListSourceType_TABLEFIELDS )
1858                     &&  ( eLSType != ListSourceType_VALUELIST )
1859                 );
1860             }
1861             break;  // case PROPERTY_ID_BOUNDCOLUMN
1862 
1863             // ----- ScaleImage, ScaleMode -----
1864             case PROPERTY_ID_SCALEIMAGE:
1865             case PROPERTY_ID_SCALE_MODE:
1866             {
1867                 ::rtl::OUString sControlSource;
1868                 if ( impl_isSupportedProperty_nothrow( PROPERTY_ID_CONTROLSOURCE ) )
1869                     impl_getPropertyValue_throw( PROPERTY_CONTROLSOURCE ) >>= sControlSource;
1870 
1871                 ::rtl::OUString sImageURL;
1872                 impl_getPropertyValue_throw( PROPERTY_IMAGE_URL ) >>= sImageURL;
1873 
1874                 _rxInspectorUI->enablePropertyUI( impl_getPropertyNameFromId_nothrow( _nPropId ),
1875                     ( sControlSource.getLength() != 0 ) || ( sImageURL.getLength() != 0 )
1876                 );
1877             }
1878             break;  // case PROPERTY_ID_SCALEIMAGE, PROPERTY_ID_SCALE_MODE
1879 
1880             // ----- InputRequired -----
1881             case PROPERTY_ID_INPUT_REQUIRED:
1882             {
1883                 ::rtl::OUString sControlSource;
1884                 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_CONTROLSOURCE ) >>= sControlSource );
1885 
1886                 sal_Bool bEmptyIsNULL = sal_False;
1887                 sal_Bool bHasEmptyIsNULL = impl_componentHasProperty_throw( PROPERTY_EMPTY_IS_NULL );
1888                 if ( bHasEmptyIsNULL )
1889                     OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_EMPTY_IS_NULL ) >>= bEmptyIsNULL );
1890 
1891                 // if the control is not bound to a DB field, there is no sense in having the "Input required"
1892                 // property
1893                 // Also, if an empty input of this control are *not* written as NULL, but as empty strings,
1894                 // then "Input required" does not make sense, too (since there's always an input, even if the control
1895                 // is empty).
1896                 _rxInspectorUI->enablePropertyUI( PROPERTY_INPUT_REQUIRED,
1897                     ( sControlSource.getLength() != 0 ) && ( !bHasEmptyIsNULL || bEmptyIsNULL )
1898                 );
1899             }
1900             break;
1901 
1902             // ----- SelectedItems, DefaultSelection -----
1903             case PROPERTY_ID_SELECTEDITEMS:
1904             case PROPERTY_ID_DEFAULT_SELECT_SEQ:
1905             {
1906                 Sequence< ::rtl::OUString > aEntries;
1907                 impl_getPropertyValue_throw( PROPERTY_STRINGITEMLIST ) >>= aEntries;
1908                 bool isEnabled = aEntries.getLength() != 0;
1909 
1910                 if ( ( m_nClassId == FormComponentType::LISTBOX ) && ( m_eComponentClass == eFormControl ) )
1911                 {
1912                     ListSourceType eLSType = ListSourceType_VALUELIST;
1913                     impl_getPropertyValue_throw( PROPERTY_LISTSOURCETYPE ) >>= eLSType;
1914                     isEnabled &= ( eLSType == ListSourceType_VALUELIST );
1915                 }
1916                 _rxInspectorUI->enablePropertyUIElements( impl_getPropertyNameFromId_nothrow( _nPropId ),
1917                     PropertyLineElement::PrimaryButton, isEnabled );
1918             }
1919             break;  // case PROPERTY_ID_DEFAULT_SELECT_SEQ
1920 
1921             // ----- TargetFrame ------
1922             case PROPERTY_ID_TARGET_FRAME:
1923             {
1924                 ::rtl::OUString sTargetURL;
1925                 impl_getPropertyValue_throw( PROPERTY_TARGET_URL ) >>= sTargetURL;
1926                 FormButtonType eButtonType( FormButtonType_URL );
1927                 if ( 0 != m_nClassId )
1928                 {
1929                     OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_BUTTONTYPE ) >>= eButtonType );
1930                 }
1931                 // if m_nClassId is 0, then we're inspecting a form. In this case, eButtonType is always
1932                 // FormButtonType_URL here
1933                 _rxInspectorUI->enablePropertyUI( PROPERTY_TARGET_FRAME,
1934                     ( eButtonType == FormButtonType_URL ) && ( sTargetURL.getLength() > 0 )
1935                 );
1936             }
1937             break;
1938 
1939             // ----- Order ------
1940             case PROPERTY_ID_SORT:
1941             // ----- Filter ------
1942             case PROPERTY_ID_FILTER:
1943             {
1944                 Reference< XConnection > xConnection;
1945                 bool bAllowEmptyDS = ::dbtools::isEmbeddedInDatabase( m_xComponent, xConnection );
1946 
1947                 // if there's no escape processing, we cannot enter any values for this property
1948                 sal_Bool  bDoEscapeProcessing( sal_False );
1949                 impl_getPropertyValue_throw( PROPERTY_ESCAPE_PROCESSING ) >>= bDoEscapeProcessing;
1950                 _rxInspectorUI->enablePropertyUI(
1951                     impl_getPropertyNameFromId_nothrow( _nPropId ),
1952                     bDoEscapeProcessing
1953                 );
1954 
1955                 // also care for the browse button - enabled if we have escape processing, and a valid
1956                 // data source signature
1957                 _rxInspectorUI->enablePropertyUIElements(
1958                     impl_getPropertyNameFromId_nothrow( _nPropId ),
1959                     PropertyLineElement::PrimaryButton,
1960                         impl_hasValidDataSourceSignature_nothrow( m_xComponent, bAllowEmptyDS )
1961                     &&  bDoEscapeProcessing
1962                 );
1963             }
1964             break;  // case PROPERTY_ID_FILTER:
1965 
1966             // ----- Command -----
1967             case PROPERTY_ID_COMMAND:
1968             {
1969                 sal_Int32   nCommandType( CommandType::COMMAND );
1970                 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_COMMANDTYPE ) >>= nCommandType );
1971 
1972                 impl_ensureRowsetConnection_nothrow();
1973                 Reference< XConnection > xConnection = m_xRowSetConnection.getTyped();
1974                 bool bAllowEmptyDS = false;
1975                 if ( !xConnection.is() )
1976                     bAllowEmptyDS = ::dbtools::isEmbeddedInDatabase( m_xComponent, xConnection );
1977 
1978                 bool doEnable = ( nCommandType == CommandType::COMMAND )
1979                             &&  (  m_xRowSetConnection.is()
1980                                 || xConnection.is()
1981 								|| impl_hasValidDataSourceSignature_nothrow( m_xComponent, bAllowEmptyDS)
1982                                 );
1983 
1984                 _rxInspectorUI->enablePropertyUIElements(
1985                     PROPERTY_COMMAND,
1986                     PropertyLineElement::PrimaryButton,
1987                     doEnable
1988                 );
1989             }
1990             break;  // case PROPERTY_ID_COMMAND
1991 
1992             // ----- DetailFields -----
1993             case PROPERTY_ID_DETAILFIELDS:
1994             {
1995                 Reference< XConnection > xConnection;
1996                 bool bAllowEmptyDS = ::dbtools::isEmbeddedInDatabase( m_xComponent, xConnection );
1997 
1998                 // both our current form, and it's parent form, need to have a valid
1999                 // data source signature
2000                 bool bDoEnableMasterDetailFields =
2001                         impl_hasValidDataSourceSignature_nothrow( m_xComponent, bAllowEmptyDS )
2002                     &&  impl_hasValidDataSourceSignature_nothrow( Reference< XPropertySet >( m_xObjectParent, UNO_QUERY ), bAllowEmptyDS );
2003 
2004                 // in opposite to the other properties, here in real *two* properties are
2005                 // affected
2006                 _rxInspectorUI->enablePropertyUIElements( PROPERTY_DETAILFIELDS, PropertyLineElement::PrimaryButton, bDoEnableMasterDetailFields );
2007                 _rxInspectorUI->enablePropertyUIElements( PROPERTY_MASTERFIELDS, PropertyLineElement::PrimaryButton, bDoEnableMasterDetailFields );
2008             }
2009             break;
2010 
2011             default:
2012                 OSL_ENSURE( false, "FormComponentPropertyHandler::impl_updateDependentProperty_nothrow: unexpected property to update!" );
2013                 break;
2014 
2015             }   // switch
2016         }
2017         catch( const Exception& )
2018         {
2019         	OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_updateDependentProperty_nothrow: caught an exception!" );
2020         }
2021     }
2022 
2023     //------------------------------------------------------------------------
disposing()2024     void SAL_CALL FormComponentPropertyHandler::disposing()
2025     {
2026         FormComponentPropertyHandler_Base::disposing();
2027         if ( m_xCommandDesigner.is() && m_xCommandDesigner->isActive() )
2028             m_xCommandDesigner->dispose();
2029     }
2030 
2031     //------------------------------------------------------------------------
suspend(sal_Bool _bSuspend)2032     sal_Bool SAL_CALL FormComponentPropertyHandler::suspend( sal_Bool _bSuspend ) throw (RuntimeException)
2033     {
2034         ::osl::MutexGuard aGuard( m_aMutex );
2035         if ( _bSuspend )
2036             if ( m_xCommandDesigner.is() && m_xCommandDesigner->isActive() )
2037                 return m_xCommandDesigner->suspend();
2038         return sal_True;
2039     }
2040 
2041     //------------------------------------------------------------------------
impl_initComponentMetaData_throw()2042     void FormComponentPropertyHandler::impl_initComponentMetaData_throw()
2043     {
2044         try
2045         {
2046             //////////////////////////////////////////////////////////////////
2047             // component class
2048             m_eComponentClass = eUnknown;
2049 
2050             if  (   impl_componentHasProperty_throw( PROPERTY_WIDTH )
2051                 &&  impl_componentHasProperty_throw( PROPERTY_HEIGHT )
2052                 &&  impl_componentHasProperty_throw( PROPERTY_POSITIONX )
2053                 &&  impl_componentHasProperty_throw( PROPERTY_POSITIONY )
2054                 &&  impl_componentHasProperty_throw( PROPERTY_STEP )
2055                 &&  impl_componentHasProperty_throw( PROPERTY_TABINDEX )
2056                 )
2057             {
2058                 m_eComponentClass = eDialogControl;
2059             }
2060             else
2061             {
2062                 m_eComponentClass = eFormControl;
2063             }
2064 
2065             //////////////////////////////////////////////////////////////////
2066             // (database) sub form?
2067             Reference< XForm > xAsForm( m_xComponent, UNO_QUERY );
2068             if ( xAsForm.is() )
2069             {
2070                 Reference< XChild > xFormAsChild( xAsForm, UNO_QUERY );
2071                 Reference< XForm > xFormsParent;
2072                 if ( xFormAsChild.is() )
2073                     xFormsParent = xFormsParent.query( xFormAsChild->getParent() );
2074                 m_bComponentIsSubForm = xFormsParent.is();
2075             }
2076 
2077             //////////////////////////////////////////////////////////////////
2078             // ClassId
2079             Reference< XChild > xCompAsChild( m_xComponent, UNO_QUERY );
2080             if ( xCompAsChild.is() )
2081                 m_xObjectParent = xCompAsChild->getParent();
2082 
2083             //////////////////////////////////////////////////////////////////
2084             // ClassId
2085             impl_classifyControlModel_throw();
2086         }
2087         catch( const RuntimeException& )
2088         {
2089             throw;
2090         }
2091         catch( const Exception& )
2092         {
2093             OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_initComponentMetaData_throw: caught an exception!" );
2094         }
2095     }
2096 
2097     //------------------------------------------------------------------------
impl_classifyControlModel_throw()2098     void FormComponentPropertyHandler::impl_classifyControlModel_throw( )
2099     {
2100         if ( impl_componentHasProperty_throw( PROPERTY_CLASSID ) )
2101         {
2102             OSL_VERIFY( m_xComponent->getPropertyValue( PROPERTY_CLASSID ) >>= m_nClassId );
2103         }
2104         else if ( eDialogControl == m_eComponentClass )
2105         {
2106             Reference< XControlModel > xControlModel( m_xComponent, UNO_QUERY );
2107             Reference< XServiceInfo > xServiceInfo( m_xComponent, UNO_QUERY );
2108             if ( xServiceInfo.is() )
2109             {
2110                 // it's a control model, and can tell about it's supported services
2111                 m_nClassId = FormComponentType::CONTROL;
2112 
2113                 const sal_Char* aControlModelServiceNames[] =
2114                 {
2115                     "UnoControlButtonModel",
2116                     "UnoControlCheckBoxModel",
2117                     "UnoControlComboBoxModel",
2118                     "UnoControlCurrencyFieldModel",
2119                     "UnoControlDateFieldModel",
2120                     "UnoControlEditModel",
2121                     "UnoControlFileControlModel",
2122                     "UnoControlFixedTextModel",
2123                     "UnoControlGroupBoxModel",
2124                     "UnoControlImageControlModel",
2125                     "UnoControlListBoxModel",
2126                     "UnoControlNumericFieldModel",
2127                     "UnoControlPatternFieldModel",
2128                     "UnoControlRadioButtonModel",
2129                     "UnoControlScrollBarModel",
2130                     "UnoControlSpinButtonModel",
2131                     "UnoControlTimeFieldModel",
2132 
2133                     "UnoControlFixedLineModel",
2134                     "UnoControlFormattedFieldModel",
2135                     "UnoControlProgressBarModel"
2136                 };
2137                 const sal_Int16 nClassIDs[] =
2138                 {
2139                     FormComponentType::COMMANDBUTTON,
2140                     FormComponentType::CHECKBOX,
2141                     FormComponentType::COMBOBOX,
2142                     FormComponentType::CURRENCYFIELD,
2143                     FormComponentType::DATEFIELD,
2144                     FormComponentType::TEXTFIELD,
2145                     FormComponentType::FILECONTROL,
2146                     FormComponentType::FIXEDTEXT,
2147                     FormComponentType::GROUPBOX,
2148                     FormComponentType::IMAGECONTROL,
2149                     FormComponentType::LISTBOX,
2150                     FormComponentType::NUMERICFIELD,
2151                     FormComponentType::PATTERNFIELD,
2152                     FormComponentType::RADIOBUTTON,
2153                     FormComponentType::SCROLLBAR,
2154                     FormComponentType::SPINBUTTON,
2155                     FormComponentType::TIMEFIELD,
2156 
2157                     ControlType::FIXEDLINE,
2158                     ControlType::FORMATTEDFIELD,
2159                     ControlType::PROGRESSBAR
2160                 };
2161 
2162                 sal_Int32 nKnownControlTypes = sizeof( aControlModelServiceNames ) / sizeof( aControlModelServiceNames[ 0 ] );
2163                 OSL_ENSURE( nKnownControlTypes == sizeof( nClassIDs ) / sizeof( nClassIDs[ 0 ] ),
2164                     "FormComponentPropertyHandler::impl_classifyControlModel_throw: inconsistence" );
2165 
2166                 for ( sal_Int32 i = 0; i < nKnownControlTypes; ++i )
2167                 {
2168                     ::rtl::OUString sServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt." ) );
2169                     sServiceName += ::rtl::OUString::createFromAscii( aControlModelServiceNames[ i ] );
2170 
2171                     if ( xServiceInfo->supportsService( sServiceName ) )
2172                     {
2173                         m_nClassId = nClassIDs[ i ];
2174                         break;
2175                     }
2176                 }
2177             }
2178         }
2179     }
2180 
2181     //------------------------------------------------------------------------
impl_normalizePropertyValue_nothrow(Any & _rValue,PropertyId _nPropId) const2182     void FormComponentPropertyHandler::impl_normalizePropertyValue_nothrow( Any& _rValue, PropertyId _nPropId ) const
2183     {
2184         switch ( _nPropId )
2185         {
2186         case PROPERTY_ID_TABSTOP:
2187             if ( !_rValue.hasValue() )
2188             {
2189                 switch ( m_nClassId )
2190                 {
2191                 case FormComponentType::COMMANDBUTTON:
2192                 case FormComponentType::RADIOBUTTON:
2193                 case FormComponentType::CHECKBOX:
2194                 case FormComponentType::TEXTFIELD:
2195                 case FormComponentType::LISTBOX:
2196                 case FormComponentType::COMBOBOX:
2197                 case FormComponentType::FILECONTROL:
2198                 case FormComponentType::DATEFIELD:
2199                 case FormComponentType::TIMEFIELD:
2200                 case FormComponentType::NUMERICFIELD:
2201                 case ControlType::FORMATTEDFIELD:
2202                 case FormComponentType::CURRENCYFIELD:
2203                 case FormComponentType::PATTERNFIELD:
2204                     _rValue = makeAny( (sal_Bool)sal_True );
2205                     break;
2206                 default:
2207                     _rValue = makeAny( (sal_Bool)sal_False );
2208                     break;
2209                 }
2210             }
2211             break;
2212         }
2213     }
2214 
2215     //------------------------------------------------------------------------
impl_shouldExcludeProperty_nothrow(const Property & _rProperty) const2216     bool FormComponentPropertyHandler::impl_shouldExcludeProperty_nothrow( const Property& _rProperty ) const
2217     {
2218         OSL_ENSURE( _rProperty.Handle == m_pInfoService->getPropertyId( _rProperty.Name ),
2219             "FormComponentPropertyHandler::impl_shouldExcludeProperty_nothrow: insonsistency in the property!" );
2220 
2221         if ( _rProperty.Handle == PROPERTY_ID_CONTROLLABEL )
2222             // prevent that this is caught below
2223             return false;
2224 
2225         if  (   ( _rProperty.Type.getTypeClass() == TypeClass_INTERFACE )
2226             ||  ( _rProperty.Type.getTypeClass() == TypeClass_ARRAY )
2227             ||  ( _rProperty.Type.getTypeClass() == TypeClass_UNKNOWN )
2228             )
2229             return true;
2230 
2231         if ( ( _rProperty.Attributes & PropertyAttribute::TRANSIENT ) && ( m_eComponentClass != eDialogControl ) )
2232             // strange enough, dialog controls declare a lot of their properties as transient
2233             return true;
2234 
2235         if ( _rProperty.Attributes & PropertyAttribute::READONLY )
2236             return true;
2237 
2238         switch ( _rProperty.Handle )
2239         {
2240         case PROPERTY_ID_MASTERFIELDS:
2241         case PROPERTY_ID_DETAILFIELDS:
2242             if ( !m_bComponentIsSubForm )
2243                 // no master and detail fields for forms which are no sub forms
2244                 return true;
2245             break;
2246 
2247         case PROPERTY_ID_DATASOURCE:
2248         {
2249             // don't show DataSource if the component is part of an embedded form document
2250             Reference< XConnection > xConn;
2251             if ( isEmbeddedInDatabase( m_xComponent, xConn ) )
2252                 return true;
2253         }
2254         break;
2255 
2256         case PROPERTY_ID_TEXT:
2257             // don't show the "Text" property of formatted fields
2258             if ( ControlType::FORMATTEDFIELD == m_nClassId )
2259                 return true;
2260             break;
2261 
2262         case PROPERTY_ID_FORMATKEY:
2263         case PROPERTY_ID_EFFECTIVE_MIN:
2264         case PROPERTY_ID_EFFECTIVE_MAX:
2265         case PROPERTY_ID_EFFECTIVE_DEFAULT:
2266         case PROPERTY_ID_EFFECTIVE_VALUE:
2267             // only if the set has a formats supplier, too
2268             if  ( !impl_componentHasProperty_throw( PROPERTY_FORMATSSUPPLIER ) )
2269                 return true;
2270             // (form) date and time fields also have a formats supplier, but the format itself
2271             // is reflected in another property
2272             if  (   ( FormComponentType::DATEFIELD == m_nClassId )
2273                 ||  ( FormComponentType::TIMEFIELD == m_nClassId )
2274                 )
2275                 return true;
2276             break;
2277 
2278         case PROPERTY_ID_SCALEIMAGE:
2279             if ( impl_componentHasProperty_throw( PROPERTY_SCALE_MODE ) )
2280                 // ScaleImage is superseded by ScaleMode
2281                 return true;
2282             break;
2283 
2284         case PROPERTY_ID_WRITING_MODE:
2285             if ( !SvtCTLOptions().IsCTLFontEnabled() )
2286                 return true;
2287             break;
2288         }
2289 
2290         sal_uInt32 nPropertyUIFlags = m_pInfoService->getPropertyUIFlags( _rProperty.Handle );
2291 
2292         // don't show experimental properties unless allowed to do so
2293         if ( ( nPropertyUIFlags & PROP_FLAG_EXPERIMENTAL ) != 0 )
2294         {
2295             if ( true ) // TODO
2296                 return true;
2297         }
2298 
2299         // no data properties if no Base is installed. #124939#
2300         // This fix is not intendend to appear on the main trunk. If you find it there,
2301         // please tell me! frank.schoenheit@sun.com
2302         if ( ( nPropertyUIFlags & PROP_FLAG_DATA_PROPERTY ) != 0 )
2303             if ( !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
2304                 return true;
2305 
2306         return false;
2307     }
2308 
2309     //------------------------------------------------------------------------
impl_getRowSet_throw() const2310     Reference< XRowSet > FormComponentPropertyHandler::impl_getRowSet_throw( ) const
2311     {
2312         Reference< XRowSet > xRowSet = m_xRowSet;
2313         if ( !xRowSet.is() )
2314         {
2315             xRowSet.set( m_xComponent, UNO_QUERY );
2316             if ( !xRowSet.is() )
2317             {
2318                 xRowSet = Reference< XRowSet >( m_xObjectParent, UNO_QUERY );
2319                 if ( !xRowSet.is() )
2320                 {
2321                     // are we inspecting a grid column?
2322                     if (Reference< XGridColumnFactory >( m_xObjectParent, UNO_QUERY) .is())
2323                     {   // yes
2324                         Reference< XChild > xParentAsChild( m_xObjectParent, UNO_QUERY );
2325                         if ( xParentAsChild.is() )
2326                             xRowSet = Reference< XRowSet >( xParentAsChild->getParent(), UNO_QUERY );
2327                     }
2328                 }
2329                 if ( !xRowSet.is() )
2330                     xRowSet = m_xRowSet;
2331             }
2332             DBG_ASSERT( xRowSet.is(), "FormComponentPropertyHandler::impl_getRowSet_throw: could not obtain the rowset for the introspectee!" );
2333         }
2334         return xRowSet;
2335     }
2336 
2337     //------------------------------------------------------------------------
impl_getRowSet_nothrow() const2338     Reference< XRowSet > FormComponentPropertyHandler::impl_getRowSet_nothrow( ) const
2339     {
2340         Reference< XRowSet > xReturn;
2341         try
2342         {
2343             xReturn = impl_getRowSet_throw();
2344         }
2345         catch( const Exception& )
2346         {
2347             OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_getRowSet_nothrow: caught an exception!" );
2348         }
2349         return xReturn;
2350     }
2351 
2352     //------------------------------------------------------------------------
impl_initFieldList_nothrow(::std::vector<::rtl::OUString> & _rFieldNames) const2353     void FormComponentPropertyHandler::impl_initFieldList_nothrow( ::std::vector< ::rtl::OUString >& _rFieldNames ) const
2354     {
2355         clearContainer( _rFieldNames );
2356         try
2357         {
2358             WaitCursor aWaitCursor( impl_getDefaultDialogParent_nothrow() );
2359 
2360             Reference< XPreparedStatement >  xStatement;
2361 
2362             // get the form of the control we're inspecting
2363             Reference< XPropertySet > xFormSet( impl_getRowSet_throw(), UNO_QUERY );
2364             if ( !xFormSet.is() )
2365                 return;
2366 
2367             ::rtl::OUString sObjectName;
2368             OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_COMMAND ) >>= sObjectName );
2369             // when there is no command we don't need to ask for columns
2370             if ( sObjectName.getLength() && impl_ensureRowsetConnection_nothrow() )
2371             {
2372                 ::rtl::OUString aDatabaseName;
2373                 OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_DATASOURCE ) >>= aDatabaseName );
2374                 sal_Int32 nObjectType = CommandType::COMMAND;
2375                 OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_COMMANDTYPE ) >>= nObjectType );
2376 
2377                 Sequence< ::rtl::OUString > aFields( ::dbtools::getFieldNamesByCommandDescriptor( m_xRowSetConnection, nObjectType, sObjectName ) );
2378 
2379                 const ::rtl::OUString* pFields = aFields.getConstArray();
2380                 for ( sal_Int32 i = 0; i < aFields.getLength(); ++i, ++pFields )
2381                     _rFieldNames.push_back( *pFields );
2382             }
2383         }
2384         catch (Exception&)
2385         {
2386             DBG_ERROR( "FormComponentPropertyHandler::impl_initFieldList_nothrow: caught an exception!" );
2387         }
2388     }
2389 
2390     //------------------------------------------------------------------------
impl_clearRowsetConnection_nothrow()2391     void FormComponentPropertyHandler::impl_clearRowsetConnection_nothrow()
2392     {
2393         m_xRowSetConnection.clear();
2394     }
2395 
2396     //------------------------------------------------------------------------
impl_displaySQLError_nothrow(const::dbtools::SQLExceptionInfo & _rErrorDescriptor) const2397     void FormComponentPropertyHandler::impl_displaySQLError_nothrow( const ::dbtools::SQLExceptionInfo& _rErrorDescriptor ) const
2398     {
2399         ::dbtools::showError( _rErrorDescriptor, VCLUnoHelper::GetInterface( impl_getDefaultDialogParent_nothrow() ), m_aContext.getLegacyServiceFactory() );
2400     }
2401 
2402     //------------------------------------------------------------------------
impl_ensureRowsetConnection_nothrow() const2403     bool FormComponentPropertyHandler::impl_ensureRowsetConnection_nothrow() const
2404     {
2405         if ( !m_xRowSetConnection.is() )
2406         {
2407             uno::Reference<sdbc::XConnection> xConnection(m_aContext.getContextValueByAsciiName( "ActiveConnection" ),uno::UNO_QUERY);
2408             m_xRowSetConnection.reset(xConnection,::dbtools::SharedConnection::NoTakeOwnership);
2409         }
2410         if ( m_xRowSetConnection.is() )
2411             return true;
2412 
2413         Reference< XRowSet > xRowSet( impl_getRowSet_throw() );
2414         Reference< XPropertySet > xRowSetProps( xRowSet, UNO_QUERY );
2415 
2416         // connect the row set - this is delegated to elsewhere - while observing errors
2417         SQLExceptionInfo aError;
2418         try
2419         {
2420             if ( xRowSetProps.is() )
2421             {
2422                 WaitCursor aWaitCursor( impl_getDefaultDialogParent_nothrow() );
2423                 m_xRowSetConnection = ::dbtools::ensureRowSetConnection( xRowSet, m_aContext.getLegacyServiceFactory(), false );
2424             }
2425         }
2426         catch ( const SQLException& ) { aError = SQLExceptionInfo( ::cppu::getCaughtException() ); }
2427         catch ( const WrappedTargetException& e ) { aError = SQLExceptionInfo( e.TargetException ); }
2428         catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
2429 
2430         // report errors, if necessary
2431         if ( aError.isValid() )
2432         {
2433             ::rtl::OUString sDataSourceName;
2434             try
2435             {
2436                 xRowSetProps->getPropertyValue( PROPERTY_DATASOURCE ) >>= sDataSourceName;
2437             }
2438             catch( const Exception& )
2439             {
2440                 DBG_ERROR( "FormComponentPropertyHandler::impl_ensureRowsetConnection_nothrow: caught an exception during error handling!" );
2441             }
2442             // additional info about what happened
2443             String sInfo( PcrRes( RID_STR_UNABLETOCONNECT ) );
2444             INetURLObject aParser( sDataSourceName );
2445             if ( aParser.GetProtocol() != INET_PROT_NOT_VALID )
2446                 sDataSourceName = aParser.getBase( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
2447             sInfo.SearchAndReplaceAllAscii( "$name$", sDataSourceName );
2448 
2449             SQLContext aContext;
2450             aContext.Message = sInfo;
2451             aContext.NextException = aError.get();
2452             impl_displaySQLError_nothrow( aContext );
2453         }
2454 
2455         return m_xRowSetConnection.is();
2456     }
2457 
2458     //------------------------------------------------------------------------
impl_describeCursorSource_nothrow(LineDescriptor & _out_rProperty,const Reference<XPropertyControlFactory> & _rxControlFactory) const2459     void FormComponentPropertyHandler::impl_describeCursorSource_nothrow( LineDescriptor& _out_rProperty, const Reference< XPropertyControlFactory >& _rxControlFactory ) const
2460     {
2461         try
2462         {
2463             WaitCursor aWaitCursor( impl_getDefaultDialogParent_nothrow() );
2464 
2465             ////////////////////////////////////////////////////////////
2466             // Setzen der UI-Daten
2467             _out_rProperty.DisplayName = m_pInfoService->getPropertyTranslation( PROPERTY_ID_COMMAND );
2468 
2469             _out_rProperty.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( PROPERTY_ID_COMMAND ) );
2470             _out_rProperty.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_SQLCOMMAND);
2471 
2472             ////////////////////////////////////////////////////////////
2473             sal_Int32 nCommandType = CommandType::COMMAND;
2474             impl_getPropertyValue_throw( PROPERTY_COMMANDTYPE ) >>= nCommandType;
2475 
2476             switch ( nCommandType )
2477             {
2478             case CommandType::TABLE:
2479             case CommandType::QUERY:
2480             {
2481                 ::std::vector< ::rtl::OUString > aNames;
2482                 if ( impl_ensureRowsetConnection_nothrow() )
2483                 {
2484                     if ( nCommandType == CommandType::TABLE )
2485                         impl_fillTableNames_throw( aNames );
2486                     else
2487                         impl_fillQueryNames_throw( aNames );
2488                 }
2489                 _out_rProperty.Control = PropertyHandlerHelper::createComboBoxControl( _rxControlFactory, aNames, sal_False, sal_True );
2490             }
2491             break;
2492 
2493             default:
2494                 _out_rProperty.Control = _rxControlFactory->createPropertyControl( PropertyControlType::MultiLineTextField, sal_False );
2495                 break;
2496             }
2497         }
2498         catch (Exception&)
2499         {
2500             DBG_ERROR("FormComponentPropertyHandler::impl_describeCursorSource_nothrow: caught an exception !");
2501         }
2502     }
2503 
2504     //------------------------------------------------------------------------
impl_fillTableNames_throw(::std::vector<::rtl::OUString> & _out_rNames) const2505     void FormComponentPropertyHandler::impl_fillTableNames_throw( ::std::vector< ::rtl::OUString >& _out_rNames ) const
2506     {
2507         OSL_PRECOND( m_xRowSetConnection.is(), "FormComponentPropertyHandler::impl_fillTableNames_throw: need a connection!" );
2508         _out_rNames.resize( 0 );
2509 
2510         Reference< XTablesSupplier > xSupplyTables( m_xRowSetConnection, UNO_QUERY );
2511         Reference< XNameAccess > xTableNames;
2512         if ( xSupplyTables.is() )
2513             xTableNames = xSupplyTables->getTables();
2514         DBG_ASSERT( xTableNames.is(), "FormComponentPropertyHandler::impl_fillTableNames_throw: no way to obtain the tables of the connection!" );
2515         if ( !xTableNames.is() )
2516             return;
2517 
2518         Sequence< ::rtl::OUString> aTableNames = xTableNames->getElementNames();
2519         sal_uInt32 nCount = aTableNames.getLength();
2520         const ::rtl::OUString* pTableNames = aTableNames.getConstArray();
2521 
2522         for ( sal_uInt32 i=0; i<nCount; ++i ,++pTableNames )
2523             _out_rNames.push_back( *pTableNames );
2524     }
2525 
2526     //------------------------------------------------------------------------
impl_fillQueryNames_throw(::std::vector<::rtl::OUString> & _out_rNames) const2527     void FormComponentPropertyHandler::impl_fillQueryNames_throw( ::std::vector< ::rtl::OUString >& _out_rNames ) const
2528     {
2529         OSL_PRECOND( m_xRowSetConnection.is(), "FormComponentPropertyHandler::impl_fillQueryNames_throw: need a connection!" );
2530         _out_rNames.resize( 0 );
2531 
2532         Reference< XQueriesSupplier > xSupplyQueries( m_xRowSetConnection, UNO_QUERY );
2533         Reference< XNameAccess > xQueryNames;
2534         if ( xSupplyQueries.is() )
2535         {
2536             xQueryNames = xSupplyQueries->getQueries();
2537             impl_fillQueryNames_throw(xQueryNames,_out_rNames);
2538         }
2539     }
2540     //------------------------------------------------------------------------
impl_fillQueryNames_throw(const Reference<XNameAccess> & _xQueryNames,::std::vector<::rtl::OUString> & _out_rNames,const::rtl::OUString & _sName) const2541     void FormComponentPropertyHandler::impl_fillQueryNames_throw( const Reference< XNameAccess >& _xQueryNames,::std::vector< ::rtl::OUString >& _out_rNames,const ::rtl::OUString& _sName ) const
2542     {
2543         DBG_ASSERT( _xQueryNames.is(), "FormComponentPropertyHandler::impl_fillQueryNames_throw: no way to obtain the queries of the connection!" );
2544         if ( !_xQueryNames.is() )
2545             return;
2546 
2547         Sequence< ::rtl::OUString> aQueryNames = _xQueryNames->getElementNames();
2548         sal_uInt32 nCount = aQueryNames.getLength();
2549         const ::rtl::OUString* pQueryNames = aQueryNames.getConstArray();
2550         sal_Bool bAdd = _sName.getLength();
2551 
2552         for ( sal_uInt32 i=0; i<nCount; i++, ++pQueryNames )
2553         {
2554             ::rtl::OUStringBuffer sTemp;
2555             if ( bAdd )
2556             {
2557                 sTemp.append(_sName);
2558                 sTemp.appendAscii("/");
2559             }
2560             sTemp.append(*pQueryNames);
2561             Reference< XNameAccess > xSubQueries(_xQueryNames->getByName(*pQueryNames),UNO_QUERY);
2562             if ( xSubQueries.is() )
2563                 impl_fillQueryNames_throw(xSubQueries,_out_rNames,sTemp.makeStringAndClear());
2564             else
2565                 _out_rNames.push_back( sTemp.makeStringAndClear() );
2566         }
2567     }
2568 
2569     //------------------------------------------------------------------------
impl_describeListSourceUI_throw(LineDescriptor & _out_rDescriptor,const Reference<XPropertyControlFactory> & _rxControlFactory) const2570     void FormComponentPropertyHandler::impl_describeListSourceUI_throw( LineDescriptor& _out_rDescriptor, const Reference< XPropertyControlFactory >& _rxControlFactory ) const
2571     {
2572         OSL_PRECOND( m_xComponent.is(), "FormComponentPropertyHandler::impl_describeListSourceUI_throw: no component!" );
2573 
2574         ////////////////////////////////////////////////////////////
2575         // Auslesen des ListSourceTypes
2576         Any aListSourceType( m_xComponent->getPropertyValue( PROPERTY_LISTSOURCETYPE ) );
2577 
2578         sal_Int32 nListSourceType = ListSourceType_VALUELIST;
2579         ::cppu::enum2int( nListSourceType, aListSourceType );
2580 
2581         _out_rDescriptor.DisplayName = m_pInfoService->getPropertyTranslation( PROPERTY_ID_LISTSOURCE );
2582         _out_rDescriptor.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( PROPERTY_ID_LISTSOURCE ) );
2583 
2584         ////////////////////////////////////////////////////////////
2585         // Enums setzen
2586         switch( nListSourceType )
2587         {
2588         case ListSourceType_VALUELIST:
2589             _out_rDescriptor.Control = _rxControlFactory->createPropertyControl( PropertyControlType::StringListField, sal_False );
2590             break;
2591 
2592         case ListSourceType_TABLEFIELDS:
2593         case ListSourceType_TABLE:
2594         case ListSourceType_QUERY:
2595         {
2596             ::std::vector< ::rtl::OUString > aListEntries;
2597             if ( impl_ensureRowsetConnection_nothrow() )
2598             {
2599                 if ( nListSourceType == ListSourceType_QUERY )
2600                     impl_fillQueryNames_throw( aListEntries );
2601                 else
2602                     impl_fillTableNames_throw( aListEntries );
2603             }
2604             _out_rDescriptor.Control = PropertyHandlerHelper::createComboBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
2605         }
2606         break;
2607         case ListSourceType_SQL:
2608         case ListSourceType_SQLPASSTHROUGH:
2609             impl_ensureRowsetConnection_nothrow();
2610             _out_rDescriptor.HasPrimaryButton = m_xRowSetConnection.is();
2611             break;
2612         }
2613     }
2614 
2615     //------------------------------------------------------------------------
impl_dialogListSelection_nothrow(const::rtl::OUString & _rProperty,::osl::ClearableMutexGuard & _rClearBeforeDialog) const2616     bool FormComponentPropertyHandler::impl_dialogListSelection_nothrow( const ::rtl::OUString& _rProperty, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2617     {
2618         OSL_PRECOND( m_pInfoService.get(), "FormComponentPropertyHandler::impl_dialogListSelection_nothrow: no property meta data!" );
2619 
2620         String sPropertyUIName( m_pInfoService->getPropertyTranslation( m_pInfoService->getPropertyId( _rProperty ) ) );
2621         ListSelectionDialog aDialog( impl_getDefaultDialogParent_nothrow(), m_xComponent, _rProperty, sPropertyUIName );
2622         _rClearBeforeDialog.clear();
2623         return ( RET_OK == aDialog.Execute() );
2624     }
2625 
2626     //------------------------------------------------------------------------
impl_dialogFilterOrSort_nothrow(bool _bFilter,::rtl::OUString & _out_rSelectedClause,::osl::ClearableMutexGuard & _rClearBeforeDialog) const2627     bool FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow( bool _bFilter, ::rtl::OUString& _out_rSelectedClause, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2628     {
2629         OSL_PRECOND( Reference< XRowSet >( m_xComponent, UNO_QUERY ).is(),
2630             "FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow: to be called for forms only!" );
2631 
2632         _out_rSelectedClause = ::rtl::OUString();
2633         bool bSuccess = false;
2634         SQLExceptionInfo aErrorInfo;
2635         try
2636         {
2637             if ( !impl_ensureRowsetConnection_nothrow() )
2638                 return false;
2639 
2640             // get a composer for the statement which the form is currently based on
2641             Reference< XSingleSelectQueryComposer > xComposer( ::dbtools::getCurrentSettingsComposer( m_xComponent, m_aContext.getLegacyServiceFactory() ) );
2642             OSL_ENSURE( xComposer.is(), "FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow: could not obtain a composer!" );
2643             if ( !xComposer.is() )
2644                 return false;
2645 
2646             ::rtl::OUString sPropertyUIName( m_pInfoService->getPropertyTranslation( _bFilter ? PROPERTY_ID_FILTER : PROPERTY_ID_SORT ) );
2647 
2648             const sal_Char* pAsciiServiceName = _bFilter ? "com.sun.star.sdb.FilterDialog" : "com.sun.star.sdb.OrderDialog";
2649 
2650             // create the dialog
2651             Reference< XExecutableDialog > xDialog;
2652             if ( !m_aContext.createComponent( pAsciiServiceName, xDialog ) )
2653             {
2654                 ShowServiceNotAvailableError( impl_getDefaultDialogParent_nothrow(), ::rtl::OUString::createFromAscii( pAsciiServiceName ), sal_True );
2655                 return false;
2656             }
2657 
2658             // initialize the dialog
2659             Reference< XPropertySet > xDialogProps( xDialog, UNO_QUERY_THROW );
2660             xDialogProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "QueryComposer" ) ), makeAny( xComposer ) );
2661             xDialogProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RowSet" ) ),        makeAny( m_xComponent ) );
2662             xDialogProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ) ),  makeAny( VCLUnoHelper::GetInterface( impl_getDefaultDialogParent_nothrow() ) ) );
2663             xDialogProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),         makeAny( sPropertyUIName ) );
2664 
2665             _rClearBeforeDialog.clear();
2666             bSuccess = ( xDialog->execute() != 0 );
2667             if ( bSuccess )
2668                 _out_rSelectedClause = _bFilter ? xComposer->getFilter() : xComposer->getOrder();
2669         }
2670         catch (SQLContext& e) { aErrorInfo = e; }
2671         catch (SQLWarning& e) { aErrorInfo = e; }
2672         catch (SQLException& e) { aErrorInfo = e; }
2673         catch( const Exception& )
2674         {
2675             OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow: caught an exception!" );
2676         }
2677 
2678         if ( aErrorInfo.isValid() )
2679             impl_displaySQLError_nothrow( aErrorInfo );
2680 
2681         return bSuccess;
2682     }
2683 
2684     //------------------------------------------------------------------------
impl_dialogLinkedFormFields_nothrow(::osl::ClearableMutexGuard & _rClearBeforeDialog) const2685     bool FormComponentPropertyHandler::impl_dialogLinkedFormFields_nothrow( ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2686     {
2687         Reference< XForm > xDetailForm( m_xComponent, UNO_QUERY );
2688         Reference< XForm > xMasterForm( m_xObjectParent, UNO_QUERY );
2689         uno::Reference<beans::XPropertySet> xMasterProp(m_xObjectParent,uno::UNO_QUERY);
2690         OSL_PRECOND( xDetailForm.is() && xMasterForm.is(), "FormComponentPropertyHandler::impl_dialogLinkedFormFields_nothrow: no forms!" );
2691         if ( !xDetailForm.is() || !xMasterForm.is() )
2692             return false;
2693 
2694 
2695         FormLinkDialog aDialog( impl_getDefaultDialogParent_nothrow(), m_xComponent, xMasterProp, m_aContext.getLegacyServiceFactory() );
2696         _rClearBeforeDialog.clear();
2697         return ( RET_OK == aDialog.Execute() );
2698     }
2699 
2700     //------------------------------------------------------------------------
impl_dialogFormatting_nothrow(Any & _out_rNewValue,::osl::ClearableMutexGuard & _rClearBeforeDialog) const2701     bool FormComponentPropertyHandler::impl_dialogFormatting_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2702     {
2703         bool bChanged = false;
2704         try
2705         {
2706             // create the itemset for the dialog
2707             SfxItemSet aCoreSet(SFX_APP()->GetPool(),
2708                 SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_VALUE,
2709                 SID_ATTR_NUMBERFORMAT_INFO, SID_ATTR_NUMBERFORMAT_INFO,
2710                 0);     // ripped this somewhere ... don't understand it :(
2711 
2712             // get the number formats supplier
2713             Reference< XNumberFormatsSupplier >  xSupplier;
2714             m_xComponent->getPropertyValue( PROPERTY_FORMATSSUPPLIER ) >>= xSupplier;
2715 
2716             DBG_ASSERT(xSupplier.is(), "FormComponentPropertyHandler::impl_dialogFormatting_nothrow: invalid call !" );
2717             Reference< XUnoTunnel > xTunnel( xSupplier, UNO_QUERY_THROW );
2718             SvNumberFormatsSupplierObj* pSupplier =
2719                 reinterpret_cast< SvNumberFormatsSupplierObj* >( xTunnel->getSomething( SvNumberFormatsSupplierObj::getUnoTunnelId() ) );
2720             DBG_ASSERT( pSupplier != NULL, "FormComponentPropertyHandler::impl_dialogFormatting_nothrow: invalid call !" );
2721 
2722             sal_Int32 nFormatKey = 0;
2723             impl_getPropertyValue_throw( PROPERTY_FORMATKEY ) >>= nFormatKey;
2724             aCoreSet.Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, nFormatKey ) );
2725 
2726             SvNumberFormatter* pFormatter = pSupplier->GetNumberFormatter();
2727             double dPreviewVal = OFormatSampleControl::getPreviewValue(pFormatter,nFormatKey);
2728             SvxNumberInfoItem aFormatter( pFormatter, dPreviewVal, String( PcrRes( RID_STR_TEXT_FORMAT ) ), SID_ATTR_NUMBERFORMAT_INFO );
2729             aCoreSet.Put( aFormatter );
2730 
2731             // a tab dialog with a single page
2732             ::std::auto_ptr< SfxSingleTabDialog > pDialog( new SfxSingleTabDialog( impl_getDefaultDialogParent_nothrow(), aCoreSet, 0 ) );
2733             SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
2734             DBG_ASSERT( pFact, "CreateFactory fail!" );
2735             ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc( RID_SVXPAGE_NUMBERFORMAT );
2736             if ( !fnCreatePage )
2737                 throw RuntimeException();   // caught below
2738 
2739             SfxTabPage* pPage = (*fnCreatePage)( pDialog.get(), aCoreSet );
2740             pDialog->SetTabPage( pPage );
2741 
2742             _rClearBeforeDialog.clear();
2743             if ( RET_OK == pDialog->Execute() )
2744             {
2745                 const SfxItemSet* pResult = pDialog->GetOutputItemSet();
2746 
2747                 const SfxPoolItem* pItem = pResult->GetItem( SID_ATTR_NUMBERFORMAT_INFO );
2748                 const SvxNumberInfoItem* pInfoItem = dynamic_cast< const SvxNumberInfoItem* >( pItem );
2749                 if (pInfoItem && pInfoItem->GetDelCount())
2750                 {
2751                     const sal_uInt32* pDeletedKeys = pInfoItem->GetDelArray();
2752 
2753                     for (sal_uInt16 i=0; i< pInfoItem->GetDelCount(); ++i, ++pDeletedKeys)
2754                         pFormatter->DeleteEntry(*pDeletedKeys);
2755                 }
2756 
2757                 pItem = NULL;
2758                 if ( SFX_ITEM_SET == pResult->GetItemState( SID_ATTR_NUMBERFORMAT_VALUE, sal_False, &pItem ) )
2759                 {
2760                     _out_rNewValue <<= (sal_Int32)( static_cast< const SfxUInt32Item* >( pItem )->GetValue() );
2761                     bChanged = true;
2762                 }
2763             }
2764         }
2765         catch( const Exception& )
2766         {
2767             OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_dialogFormatting_nothrow: : caught an exception!" );
2768         }
2769         return bChanged;
2770     }
2771 
2772     //------------------------------------------------------------------------
impl_browseForImage_nothrow(Any & _out_rNewValue,::osl::ClearableMutexGuard & _rClearBeforeDialog) const2773     bool FormComponentPropertyHandler::impl_browseForImage_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2774     {
2775         bool bIsLink = true;// reflect the legacy behavior
2776         ::rtl::OUString aStrTrans = m_pInfoService->getPropertyTranslation( PROPERTY_ID_IMAGE_URL );
2777 
2778         ::sfx2::FileDialogHelper aFileDlg(SFXWB_GRAPHIC);
2779 
2780         aFileDlg.SetTitle(aStrTrans);
2781         // non-linked images ( e.g. those located in the document
2782         // stream ) cannot *currently* be handled by openoffice basic dialogs.
2783         bool bHandleNonLink = ( m_eComponentClass == eFormControl );
2784 
2785         Reference< XFilePickerControlAccess > xController(aFileDlg.GetFilePicker(), UNO_QUERY);
2786         DBG_ASSERT(xController.is(), "FormComponentPropertyHandler::impl_browseForImage_nothrow: missing the controller interface on the file picker!");
2787         if (xController.is())
2788         {
2789             // do a preview by default
2790             xController->setValue(ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0, ::cppu::bool2any(sal_True));
2791 
2792             xController->setValue(ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, ::cppu::bool2any(bIsLink));
2793             xController->enableControl(ExtendedFilePickerElementIds::CHECKBOX_LINK, bHandleNonLink );
2794 
2795         }
2796 
2797         ::rtl::OUString sCurValue;
2798         OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_IMAGE_URL ) >>= sCurValue );
2799         if ( sCurValue.getLength() != 0 && sCurValue.compareToAscii(GRAPHOBJ_URLPREFIX, RTL_CONSTASCII_LENGTH(GRAPHOBJ_URLPREFIX) ) != 0 )
2800         {
2801             aFileDlg.SetDisplayDirectory( sCurValue );
2802             // TODO: need to set the display directory _and_ the default name
2803         }
2804 
2805         _rClearBeforeDialog.clear();
2806         bool bSuccess = ( 0 == aFileDlg.Execute() );
2807         if ( bSuccess )
2808         {
2809             if ( bHandleNonLink && xController.is() )
2810             {
2811                 xController->getValue(ExtendedFilePickerElementIds::CHECKBOX_LINK, 0) >>= bIsLink;
2812             }
2813             if ( !bIsLink )
2814             {
2815                 Graphic aGraphic;
2816                 aFileDlg.GetGraphic( aGraphic );
2817 
2818                 Reference< graphic::XGraphicObject > xGrfObj = graphic::GraphicObject::create( m_aContext.getUNOContext() );
2819                 xGrfObj->setGraphic( aGraphic.GetXGraphic() );
2820 
2821 
2822                 _out_rNewValue <<= xGrfObj;
2823 
2824             }
2825             else
2826                 _out_rNewValue <<= (::rtl::OUString)aFileDlg.GetPath();
2827         }
2828         return bSuccess;
2829     }
2830 
2831     //------------------------------------------------------------------------
impl_browseForTargetURL_nothrow(Any & _out_rNewValue,::osl::ClearableMutexGuard & _rClearBeforeDialog) const2832     bool FormComponentPropertyHandler::impl_browseForTargetURL_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2833     {
2834         ::sfx2::FileDialogHelper aFileDlg( WB_3DLOOK );
2835 
2836         ::rtl::OUString sURL;
2837         OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_TARGET_URL ) >>= sURL );
2838         INetURLObject aParser( sURL );
2839         if ( INET_PROT_FILE == aParser.GetProtocol() )
2840             // set the initial directory only for file-URLs. Everything else
2841             // is considered to be potentially expensive
2842             // 106126 - 2002/12/10 - fs@openoffice.org
2843             aFileDlg.SetDisplayDirectory( sURL );
2844 
2845         _rClearBeforeDialog.clear();
2846         bool bSuccess = ( 0 == aFileDlg.Execute() );
2847         if ( bSuccess )
2848             _out_rNewValue <<= (::rtl::OUString)aFileDlg.GetPath();
2849         return bSuccess;
2850     }
2851 
2852     //------------------------------------------------------------------------
impl_executeFontDialog_nothrow(Any & _out_rNewValue,::osl::ClearableMutexGuard & _rClearBeforeDialog) const2853     bool FormComponentPropertyHandler::impl_executeFontDialog_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2854     {
2855         bool bSuccess = false;
2856 
2857         // create an item set for use with the dialog
2858         SfxItemSet* pSet = NULL;
2859         SfxItemPool* pPool = NULL;
2860         SfxPoolItem** pDefaults = NULL;
2861         ControlCharacterDialog::createItemSet(pSet, pPool, pDefaults);
2862         ControlCharacterDialog::translatePropertiesToItems(m_xComponent, pSet);
2863 
2864         {   // do this in an own block. The dialog needs to be destroyed before we call
2865             // destroyItemSet
2866             ControlCharacterDialog aDlg( impl_getDefaultDialogParent_nothrow(), *pSet );
2867             _rClearBeforeDialog.clear();
2868             if ( RET_OK == aDlg.Execute() )
2869             {
2870                 const SfxItemSet* pOut = aDlg.GetOutputItemSet();
2871                 if ( pOut )
2872                 {
2873                     Sequence< NamedValue > aFontPropertyValues;
2874                     ControlCharacterDialog::translateItemsToProperties( *pOut, aFontPropertyValues );
2875                     _out_rNewValue <<= aFontPropertyValues;
2876                     bSuccess = true;
2877                 }
2878             }
2879         }
2880 
2881         ControlCharacterDialog::destroyItemSet(pSet, pPool, pDefaults);
2882         return bSuccess;
2883     }
2884 
2885     //------------------------------------------------------------------------
impl_browseForDatabaseDocument_throw(Any & _out_rNewValue,::osl::ClearableMutexGuard & _rClearBeforeDialog) const2886     bool FormComponentPropertyHandler::impl_browseForDatabaseDocument_throw( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2887     {
2888         ::sfx2::FileDialogHelper aFileDlg(WB_3DLOOK|WB_OPEN,::String::CreateFromAscii("sdatabase"));
2889 
2890         ::rtl::OUString sDataSource;
2891         OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_DATASOURCE ) >>= sDataSource );
2892         INetURLObject aParser( sDataSource );
2893         if ( INET_PROT_FILE == aParser.GetProtocol() )
2894             // set the initial directory only for file-URLs. Everything else
2895             // is considered to be potentially expensive
2896             // 106126 - 2002/12/10 - fs@openoffice.org
2897             aFileDlg.SetDisplayDirectory( sDataSource );
2898 
2899         const String s_sDatabaseType = String::CreateFromAscii("StarOffice XML (Base)");
2900         const SfxFilter* pFilter = SfxFilter::GetFilterByName( s_sDatabaseType);
2901         OSL_ENSURE(pFilter,"Filter: StarOffice XML (Base) could not be found!");
2902         if ( pFilter )
2903         {
2904             aFileDlg.SetCurrentFilter(pFilter->GetUIName());
2905             //aFileDlg.AddFilter(pFilter->GetFilterName(),pFilter->GetDefaultExtension());
2906         }
2907 
2908         _rClearBeforeDialog.clear();
2909         bool bSuccess = ( 0 == aFileDlg.Execute() );
2910         if ( bSuccess )
2911             _out_rNewValue <<= (::rtl::OUString)aFileDlg.GetPath();
2912         return bSuccess;
2913     }
2914 
2915     //------------------------------------------------------------------------
impl_dialogColorChooser_throw(sal_Int32 _nColorPropertyId,Any & _out_rNewValue,::osl::ClearableMutexGuard & _rClearBeforeDialog) const2916     bool FormComponentPropertyHandler::impl_dialogColorChooser_throw( sal_Int32 _nColorPropertyId, Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2917     {
2918         sal_Int32 nColor = 0;
2919         OSL_VERIFY( impl_getPropertyValue_throw( impl_getPropertyNameFromId_nothrow( _nColorPropertyId ) ) >>= nColor );
2920         ::Color aColor( nColor );
2921         SvColorDialog aColorDlg( impl_getDefaultDialogParent_nothrow() );
2922         aColorDlg.SetColor( aColor );
2923 
2924         _rClearBeforeDialog.clear();
2925         if ( !aColorDlg.Execute() )
2926             return false;
2927 
2928         aColor = aColorDlg.GetColor();
2929         nColor = aColor.GetColor();
2930         _out_rNewValue <<= (sal_Int32)nColor;
2931         return true;
2932     }
2933 
2934     //------------------------------------------------------------------------
impl_dialogChooseLabelControl_nothrow(Any & _out_rNewValue,::osl::ClearableMutexGuard & _rClearBeforeDialog) const2935     bool FormComponentPropertyHandler::impl_dialogChooseLabelControl_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2936     {
2937         OSelectLabelDialog dlgSelectLabel( impl_getDefaultDialogParent_nothrow(), m_xComponent );
2938         _rClearBeforeDialog.clear();
2939         bool bSuccess = ( RET_OK == dlgSelectLabel.Execute() );
2940         if ( bSuccess )
2941             _out_rNewValue <<= dlgSelectLabel.GetSelected();
2942         return bSuccess;
2943     }
2944 
2945     //------------------------------------------------------------------------
impl_getContextControlContainer_nothrow() const2946     Reference< XControlContainer > FormComponentPropertyHandler::impl_getContextControlContainer_nothrow() const
2947     {
2948         Reference< XControlContainer > xControlContext(
2949             m_aContext.getContextValueByAsciiName( "ControlContext" ),
2950             UNO_QUERY );
2951         return xControlContext;
2952     }
2953 
2954     //------------------------------------------------------------------------
impl_dialogChangeTabOrder_nothrow(::osl::ClearableMutexGuard & _rClearBeforeDialog) const2955     bool FormComponentPropertyHandler::impl_dialogChangeTabOrder_nothrow( ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2956     {
2957         OSL_PRECOND( impl_getContextControlContainer_nothrow().is(), "FormComponentPropertyHandler::impl_dialogChangeTabOrder_nothrow: invalid control context!" );
2958 
2959         Reference< XTabControllerModel > xTabControllerModel( impl_getRowSet_nothrow(), UNO_QUERY );
2960         TabOrderDialog aDialog(
2961             impl_getDefaultDialogParent_nothrow(),
2962             xTabControllerModel,
2963             impl_getContextControlContainer_nothrow(),
2964             m_aContext.getLegacyServiceFactory()
2965         );
2966         _rClearBeforeDialog.clear();
2967         return ( RET_OK == aDialog.Execute() );
2968     }
2969 
2970     //------------------------------------------------------------------------
2971     namespace
2972     {
2973         //--------------------------------------------------------------------
2974         //- ISQLCommandPropertyUI
2975         //--------------------------------------------------------------------
2976         class ISQLCommandPropertyUI : public ISQLCommandAdapter
2977         {
2978         public:
2979             /** returns the empty-string-terminated list of names of properties
2980                 whose UI is to be disabled while the SQL command property is
2981                 being edited.
2982             */
2983             virtual ::rtl::OUString*    getPropertiesToDisable() = 0;
2984         };
2985 
2986         //--------------------------------------------------------------------
2987         //- SQLCommandPropertyUI
2988         //--------------------------------------------------------------------
2989         class SQLCommandPropertyUI : public ISQLCommandPropertyUI
2990         {
2991         protected:
SQLCommandPropertyUI(const Reference<XPropertySet> & _rxObject)2992             SQLCommandPropertyUI( const Reference< XPropertySet >& _rxObject )
2993                 :m_xObject( _rxObject )
2994             {
2995                 if ( !m_xObject.is() )
2996                     throw NullPointerException();
2997             }
2998 
acquire()2999             virtual oslInterlockedCount SAL_CALL acquire()
3000             {
3001                 return osl_incrementInterlockedCount( &m_refCount );
3002             }
3003 
release()3004             virtual oslInterlockedCount SAL_CALL release()
3005             {
3006                 if ( 0 == osl_decrementInterlockedCount( &m_refCount ) )
3007                 {
3008                     delete this;
3009                     return 0;
3010                 }
3011                 return m_refCount;
3012             }
3013 
3014         protected:
3015             Reference< XPropertySet >   m_xObject;
3016 
3017         private:
3018             oslInterlockedCount         m_refCount;
3019         };
3020 
3021         //--------------------------------------------------------------------
3022         //- FormSQLCommandUI - declaration
3023         //--------------------------------------------------------------------
3024         class FormSQLCommandUI : public SQLCommandPropertyUI
3025         {
3026         public:
3027             FormSQLCommandUI( const Reference< XPropertySet >& _rxForm );
3028 
3029             // ISQLCommandAdapter
3030             virtual ::rtl::OUString getSQLCommand() const;
3031             virtual sal_Bool        getEscapeProcessing() const;
3032             virtual void            setSQLCommand( const ::rtl::OUString& _rCommand ) const;
3033             virtual void            setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const;
3034 
3035             // ISQLCommandPropertyUI
3036             virtual ::rtl::OUString*    getPropertiesToDisable();
3037         };
3038 
3039         //--------------------------------------------------------------------
3040         //- FormSQLCommandUI - implementation
3041         //--------------------------------------------------------------------
3042         //....................................................................
FormSQLCommandUI(const Reference<XPropertySet> & _rxForm)3043         FormSQLCommandUI::FormSQLCommandUI( const Reference< XPropertySet >& _rxForm )
3044             :SQLCommandPropertyUI( _rxForm )
3045         {
3046         }
3047 
3048         //....................................................................
getSQLCommand() const3049         ::rtl::OUString FormSQLCommandUI::getSQLCommand() const
3050         {
3051             ::rtl::OUString sCommand;
3052             OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_COMMAND ) >>= sCommand );
3053             return sCommand;
3054         }
3055 
3056         //....................................................................
getEscapeProcessing() const3057         sal_Bool FormSQLCommandUI::getEscapeProcessing() const
3058         {
3059             sal_Bool bEscapeProcessing( sal_False );
3060             OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bEscapeProcessing );
3061             return bEscapeProcessing;
3062         }
3063 
3064         //....................................................................
setSQLCommand(const::rtl::OUString & _rCommand) const3065         void FormSQLCommandUI::setSQLCommand( const ::rtl::OUString& _rCommand ) const
3066         {
3067             m_xObject->setPropertyValue( PROPERTY_COMMAND, makeAny( _rCommand ) );
3068         }
3069 
3070         //....................................................................
setEscapeProcessing(const sal_Bool _bEscapeProcessing) const3071         void FormSQLCommandUI::setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const
3072         {
3073             m_xObject->setPropertyValue( PROPERTY_ESCAPE_PROCESSING, makeAny( _bEscapeProcessing ) );
3074         }
3075 
3076         //....................................................................
getPropertiesToDisable()3077         ::rtl::OUString* FormSQLCommandUI::getPropertiesToDisable()
3078         {
3079             static ::rtl::OUString s_aCommandProps[] = {
3080                 PROPERTY_DATASOURCE,
3081                 PROPERTY_COMMAND,
3082                 PROPERTY_COMMANDTYPE,
3083                 PROPERTY_ESCAPE_PROCESSING,
3084                 ::rtl::OUString()
3085             };
3086             return s_aCommandProps;
3087         }
3088         //--------------------------------------------------------------------
3089         //- ValueListCommandUI - declaration
3090         //--------------------------------------------------------------------
3091         class ValueListCommandUI : public SQLCommandPropertyUI
3092         {
3093         public:
3094             ValueListCommandUI( const Reference< XPropertySet >& _rxListOrCombo );
3095 
3096             // ISQLCommandAdapter
3097             virtual ::rtl::OUString getSQLCommand() const;
3098             virtual sal_Bool        getEscapeProcessing() const;
3099             virtual void            setSQLCommand( const ::rtl::OUString& _rCommand ) const;
3100             virtual void            setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const;
3101 
3102             // ISQLCommandPropertyUI
3103             virtual ::rtl::OUString*    getPropertiesToDisable();
3104         private:
3105             mutable bool    m_bPropertyValueIsList;
3106         };
3107 
3108         //--------------------------------------------------------------------
3109         //- ValueListCommandUI - implementation
3110         //--------------------------------------------------------------------
3111         //....................................................................
ValueListCommandUI(const Reference<XPropertySet> & _rxListOrCombo)3112         ValueListCommandUI::ValueListCommandUI( const Reference< XPropertySet >& _rxListOrCombo )
3113             :SQLCommandPropertyUI( _rxListOrCombo )
3114             ,m_bPropertyValueIsList( false )
3115         {
3116         }
3117 
3118         //....................................................................
getSQLCommand() const3119         ::rtl::OUString ValueListCommandUI::getSQLCommand() const
3120         {
3121             ::rtl::OUString sValue;
3122             m_bPropertyValueIsList = false;
3123 
3124             // for combo boxes, the property is a mere string
3125             Any aValue( m_xObject->getPropertyValue( PROPERTY_LISTSOURCE ) );
3126             if ( aValue >>= sValue )
3127                 return sValue;
3128 
3129             Sequence< ::rtl::OUString > aValueList;
3130             if ( aValue >>= aValueList )
3131             {
3132                 m_bPropertyValueIsList = true;
3133                 if ( aValueList.getLength() )
3134                     sValue = aValueList[0];
3135                 return sValue;
3136             }
3137 
3138             OSL_ENSURE( false, "ValueListCommandUI::getSQLCommand: unexpected property type!" );
3139             return sValue;
3140         }
3141 
3142         //....................................................................
getEscapeProcessing() const3143         sal_Bool ValueListCommandUI::getEscapeProcessing() const
3144         {
3145             enum ListSourceType eType( ListSourceType_SQL );
3146             OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_LISTSOURCETYPE ) >>= eType );
3147             OSL_ENSURE( ( eType == ListSourceType_SQL ) || ( eType == ListSourceType_SQLPASSTHROUGH ),
3148                 "ValueListCommandUI::getEscapeProcessing: unexpected list source type!" );
3149             return ( eType == ListSourceType_SQL );
3150         }
3151 
3152         //....................................................................
setSQLCommand(const::rtl::OUString & _rCommand) const3153         void ValueListCommandUI::setSQLCommand( const ::rtl::OUString& _rCommand ) const
3154         {
3155             Any aValue;
3156             if ( m_bPropertyValueIsList )
3157                 aValue <<= Sequence< ::rtl::OUString >( &_rCommand, 1 );
3158             else
3159                 aValue <<= _rCommand;
3160             m_xObject->setPropertyValue( PROPERTY_LISTSOURCE, aValue );
3161         }
3162 
3163         //....................................................................
setEscapeProcessing(const sal_Bool _bEscapeProcessing) const3164         void ValueListCommandUI::setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const
3165         {
3166             m_xObject->setPropertyValue( PROPERTY_LISTSOURCETYPE, makeAny(
3167                 _bEscapeProcessing ? ListSourceType_SQL : ListSourceType_SQLPASSTHROUGH ) );
3168         }
3169 
3170         //....................................................................
getPropertiesToDisable()3171         ::rtl::OUString* ValueListCommandUI::getPropertiesToDisable()
3172         {
3173             static ::rtl::OUString s_aListSourceProps[] = {
3174                 PROPERTY_LISTSOURCETYPE,
3175                 PROPERTY_LISTSOURCE,
3176                 ::rtl::OUString()
3177             };
3178             return s_aListSourceProps;
3179         }
3180     }
3181 
3182     //------------------------------------------------------------------------
impl_doDesignSQLCommand_nothrow(const Reference<XObjectInspectorUI> & _rxInspectorUI,PropertyId _nDesignForProperty)3183     bool FormComponentPropertyHandler::impl_doDesignSQLCommand_nothrow( const Reference< XObjectInspectorUI >& _rxInspectorUI, PropertyId _nDesignForProperty )
3184     {
3185         try
3186         {
3187             if ( m_xCommandDesigner.is() )
3188             {
3189                 if ( m_xCommandDesigner->isActive() )
3190                 {
3191                     m_xCommandDesigner->raise();
3192                     return true;
3193                 }
3194                 m_xCommandDesigner->dispose();
3195                 m_xCommandDesigner.set( NULL );
3196             }
3197 
3198             if ( !impl_ensureRowsetConnection_nothrow() )
3199                 return false;
3200 
3201             Reference< XPropertySet > xComponentProperties( m_xComponent, UNO_QUERY_THROW );
3202 
3203             ::rtl::Reference< ISQLCommandPropertyUI > xCommandUI;
3204             switch ( _nDesignForProperty )
3205             {
3206             case PROPERTY_ID_COMMAND:
3207                 xCommandUI = new FormSQLCommandUI( xComponentProperties );
3208                 break;
3209             case PROPERTY_ID_LISTSOURCE:
3210                 xCommandUI = new ValueListCommandUI( xComponentProperties );
3211                 break;
3212             default:
3213                 OSL_ENSURE( false, "FormComponentPropertyHandler::OnDesignerClosed: invalid property id!" );
3214                 return false;
3215             }
3216 
3217             m_xCommandDesigner.set( new SQLCommandDesigner( m_aContext.getUNOContext(), xCommandUI.get(), m_xRowSetConnection, LINK( this, FormComponentPropertyHandler, OnDesignerClosed ) ) );
3218 
3219             DBG_ASSERT( _rxInspectorUI.is(), "FormComponentPropertyHandler::OnDesignerClosed: no access to the property browser ui!" );
3220             if ( m_xCommandDesigner->isActive() && _rxInspectorUI.is() )
3221             {
3222                 m_xBrowserUI = _rxInspectorUI;
3223                 // disable everything which would affect this property
3224                 const ::rtl::OUString* pToDisable = xCommandUI->getPropertiesToDisable();
3225                 while ( pToDisable->getLength() )
3226                 {
3227                     m_xBrowserUI->enablePropertyUIElements( *pToDisable++, PropertyLineElement::All, sal_False );
3228                 }
3229 
3230                 // but enable the browse button for the property itself - so it can be used to raise the query designer
3231                 ::rtl::OUString sPropertyName( impl_getPropertyNameFromId_nothrow( _nDesignForProperty ) );
3232                 m_xBrowserUI->enablePropertyUIElements( sPropertyName, PropertyLineElement::PrimaryButton, sal_True );
3233             }
3234         }
3235         catch( const Exception& )
3236         {
3237             DBG_UNHANDLED_EXCEPTION();
3238         }
3239         return m_xCommandDesigner.is();
3240     }
3241 
3242     //------------------------------------------------------------------------
3243     IMPL_LINK( FormComponentPropertyHandler, OnDesignerClosed, void*, /*NOTINTERESTEDIN*/ )
3244     {
3245         OSL_ENSURE( m_xBrowserUI.is() && m_xCommandDesigner.is(), "FormComponentPropertyHandler::OnDesignerClosed: too many NULLs!" );
3246         if ( m_xBrowserUI.is() && m_xCommandDesigner.is() )
3247         {
3248             try
3249             {
3250                 ::rtl::Reference< ISQLCommandPropertyUI > xCommandUI(
3251                     dynamic_cast< ISQLCommandPropertyUI* >( m_xCommandDesigner->getPropertyAdapter().get() ) );
3252                 if ( !xCommandUI.is() )
3253                     throw NullPointerException();
3254 
3255                 const ::rtl::OUString* pToEnable = xCommandUI->getPropertiesToDisable();
3256                 while ( pToEnable->getLength() )
3257                 {
3258                     m_xBrowserUI->enablePropertyUIElements( *pToEnable++, PropertyLineElement::All, sal_True );
3259                 }
3260             }
3261             catch( const Exception& )
3262             {
3263             	DBG_UNHANDLED_EXCEPTION();
3264             }
3265         }
3266 
3267         return 0L;
3268     }
3269 
3270 	//------------------------------------------------------------------------
impl_hasValidDataSourceSignature_nothrow(const Reference<XPropertySet> & _xFormProperties,bool _bAllowEmptyDataSourceName)3271     bool FormComponentPropertyHandler::impl_hasValidDataSourceSignature_nothrow( const Reference< XPropertySet >& _xFormProperties, bool _bAllowEmptyDataSourceName ) SAL_THROW(())
3272     {
3273         bool bHas = false;
3274         if ( _xFormProperties.is() )
3275         {
3276             try
3277             {
3278                 ::rtl::OUString sPropertyValue;
3279                 // first, we need the name of an existent data source
3280                 if ( _xFormProperties->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATASOURCE) )
3281                     _xFormProperties->getPropertyValue( PROPERTY_DATASOURCE ) >>= sPropertyValue;
3282                 bHas = ( sPropertyValue.getLength() != 0 ) || _bAllowEmptyDataSourceName;
3283 
3284                 // then, the command should not be empty
3285                 if ( bHas )
3286                 {
3287                     if ( _xFormProperties->getPropertySetInfo()->hasPropertyByName(PROPERTY_COMMAND) )
3288                         _xFormProperties->getPropertyValue( PROPERTY_COMMAND ) >>= sPropertyValue;
3289                     bHas = ( sPropertyValue.getLength() != 0 );
3290                 }
3291             }
3292             catch( const Exception& )
3293             {
3294                 OSL_ENSURE( false, "FormComponentPropertyHandler::impl_hasValidDataSourceSignature_nothrow: caught an exception!" );
3295             }
3296         }
3297         return bHas;
3298     }
3299     //------------------------------------------------------------------------
impl_getDocumentURL_nothrow() const3300     ::rtl::OUString FormComponentPropertyHandler::impl_getDocumentURL_nothrow() const
3301     {
3302         ::rtl::OUString sURL;
3303         try
3304         {
3305             Reference< XModel > xDocument( impl_getContextDocument_nothrow() );
3306             if ( xDocument.is() )
3307                 sURL = xDocument->getURL();
3308         }
3309         catch( const Exception& )
3310         {
3311             DBG_UNHANDLED_EXCEPTION();
3312         }
3313         return sURL;
3314     }
3315     // -------------------------------------------------------------------------
createArrayHelper() const3316     ::cppu::IPropertyArrayHelper* FormComponentPropertyHandler::createArrayHelper( ) const
3317     {
3318         uno::Sequence< beans::Property > aProps;
3319 	    describeProperties(aProps);
3320 	    return new ::cppu::OPropertyArrayHelper(aProps);
3321 
3322     }
3323     // -------------------------------------------------------------------------
getInfoHelper()3324     ::cppu::IPropertyArrayHelper & FormComponentPropertyHandler::getInfoHelper()
3325     {
3326 	    return *const_cast<FormComponentPropertyHandler*>(this)->getArrayHelper();
3327     }
3328     // -----------------------------------------------------------------------------
getPropertySetInfo()3329     uno::Reference< beans::XPropertySetInfo > SAL_CALL FormComponentPropertyHandler::getPropertySetInfo(  ) throw(uno::RuntimeException)
3330     {
3331 	    return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
3332     }
3333 
3334 //........................................................................
3335 } // namespace pcr
3336 //........................................................................
3337 
3338