xref: /trunk/main/extensions/source/propctrlr/formcomponenthandler.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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(  )
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(  )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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( )
935     {
936         return Sequence< ::rtl::OUString >( );
937     }
938 
939     //--------------------------------------------------------------------
getActuatingProperties()940     Sequence< ::rtl::OUString > SAL_CALL FormComponentPropertyHandler::getActuatingProperties( )
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     {
973         if ( !_rxControlFactory.is() )
974             throw NullPointerException();
975 
976         ::osl::MutexGuard aGuard( m_aMutex );
977         PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
978         Property aProperty( impl_getPropertyFromId_throw( nPropId ) );
979 
980         //////////////////////////////////////////////////////////////////////
981         // for the MultiLine property, we have different UI translations depending on the control
982         // type
983         if ( nPropId == PROPERTY_ID_MULTILINE )
984         {
985             if (  ( m_nClassId == FormComponentType::FIXEDTEXT )
986                || ( m_nClassId == FormComponentType::COMMANDBUTTON )
987                || ( m_nClassId == FormComponentType::RADIOBUTTON )
988                || ( m_nClassId == FormComponentType::CHECKBOX )
989                )
990                 nPropId = PROPERTY_ID_WORDBREAK;
991         }
992 
993         String sDisplayName = m_pInfoService->getPropertyTranslation( nPropId );
994         if ( !sDisplayName.Len() )
995         {
996             DBG_ERROR( "FormComponentPropertyHandler::describePropertyLine: did getSupportedProperties not work properly?" );
997             throw UnknownPropertyException();
998         }
999 
1000         //////////////////////////////////////////////////////////////////////
1001 
1002         LineDescriptor aDescriptor;
1003         aDescriptor.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( nPropId ) );
1004         aDescriptor.DisplayName = sDisplayName;
1005 
1006         // for the moment, assume a text field
1007         sal_Int16 nControlType = PropertyControlType::TextField;
1008         sal_Bool bReadOnly = sal_False;
1009         aDescriptor.Control.clear();
1010 
1011         //////////////////////////////////////////////////////////////////////
1012 
1013         bool bNeedDefaultStringIfVoidAllowed = false;
1014 
1015         TypeClass eType = aProperty.Type.getTypeClass();
1016 
1017         switch ( nPropId )
1018         {
1019         case PROPERTY_ID_DEFAULT_SELECT_SEQ:
1020         case PROPERTY_ID_SELECTEDITEMS:
1021             aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_SELECTION);
1022             break;
1023 
1024         case PROPERTY_ID_FILTER:
1025             aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_FILTER);
1026             break;
1027 
1028         case PROPERTY_ID_SORT:
1029             aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_ORDER);
1030             break;
1031 
1032         case PROPERTY_ID_MASTERFIELDS:
1033         case PROPERTY_ID_DETAILFIELDS:
1034             nControlType = PropertyControlType::StringListField;
1035             aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_FORMLINKFIELDS);
1036             break;
1037 
1038         case PROPERTY_ID_COMMAND:
1039             aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_SQLCOMMAND);
1040             break;
1041 
1042         case PROPERTY_ID_TABINDEX:
1043         {
1044             Reference< XControlContainer > xControlContext( impl_getContextControlContainer_nothrow() );
1045             if ( xControlContext.is() )
1046                 aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_TABINDEX);
1047             nControlType = PropertyControlType::NumericField;
1048         };
1049         break;
1050 
1051         case PROPERTY_ID_FONT:
1052             bReadOnly = sal_True;
1053             aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_FONT_TYPE);
1054             break;
1055 
1056         case PROPERTY_ID_TARGET_URL:
1057         case PROPERTY_ID_IMAGE_URL:
1058         {
1059             aDescriptor.Control = new OFileUrlControl( impl_getDefaultDialogParent_nothrow(), WB_TABSTOP | WB_BORDER );
1060 
1061             aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(( PROPERTY_ID_TARGET_URL == nPropId )
1062                 ? UID_PROP_DLG_ATTR_TARGET_URL : UID_PROP_DLG_IMAGE_URL);
1063         }
1064         break;
1065 
1066         case PROPERTY_ID_ECHO_CHAR:
1067             nControlType = PropertyControlType::CharacterField;
1068             break;
1069 
1070         case PROPERTY_ID_BACKGROUNDCOLOR:
1071         case PROPERTY_ID_FILLCOLOR:
1072         case PROPERTY_ID_SYMBOLCOLOR:
1073         case PROPERTY_ID_BORDERCOLOR:
1074             nControlType = PropertyControlType::ColorListBox;
1075 
1076             switch( nPropId )
1077             {
1078             case PROPERTY_ID_BACKGROUNDCOLOR:
1079                 aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_BACKGROUNDCOLOR); break;
1080             case PROPERTY_ID_FILLCOLOR:
1081                 aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_FILLCOLOR); break;
1082             case PROPERTY_ID_SYMBOLCOLOR:
1083                 aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_SYMBOLCOLOR); break;
1084             case PROPERTY_ID_BORDERCOLOR:
1085                 aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_BORDERCOLOR); break;
1086             }
1087             break;
1088 
1089         case PROPERTY_ID_LABEL:
1090             nControlType = PropertyControlType::MultiLineTextField;
1091             break;
1092 
1093         case PROPERTY_ID_DEFAULT_TEXT:
1094         {
1095             if (FormComponentType::FILECONTROL == m_nClassId)
1096                 nControlType = PropertyControlType::TextField;
1097             else
1098                 nControlType = PropertyControlType::MultiLineTextField;
1099         }
1100         break;
1101 
1102         case PROPERTY_ID_TEXT:
1103             if ( impl_componentHasProperty_throw( PROPERTY_MULTILINE ) )
1104                 nControlType = PropertyControlType::MultiLineTextField;
1105             break;
1106 
1107         case PROPERTY_ID_CONTROLLABEL:
1108             bReadOnly = sal_True;
1109             aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_CONTROLLABEL);
1110             break;
1111 
1112         case PROPERTY_ID_FORMATKEY:
1113         case PROPERTY_ID_EFFECTIVE_MIN:
1114         case PROPERTY_ID_EFFECTIVE_MAX:
1115         case PROPERTY_ID_EFFECTIVE_DEFAULT:
1116         case PROPERTY_ID_EFFECTIVE_VALUE:
1117         {
1118             // and the supplier is really available
1119             Reference< XNumberFormatsSupplier >  xSupplier;
1120             m_xComponent->getPropertyValue( PROPERTY_FORMATSSUPPLIER ) >>= xSupplier;
1121             if (xSupplier.is())
1122             {
1123                 Reference< XUnoTunnel > xTunnel(xSupplier,UNO_QUERY);
1124                 DBG_ASSERT(xTunnel.is(), "FormComponentPropertyHandler::describePropertyLine : xTunnel is invalid!");
1125                 SvNumberFormatsSupplierObj* pSupplier = reinterpret_cast<SvNumberFormatsSupplierObj*>(xTunnel->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));
1126 
1127                 if (pSupplier != NULL)
1128                 {
1129                     sal_Bool bIsFormatKey = (PROPERTY_ID_FORMATKEY == nPropId);
1130 
1131                     bReadOnly = bIsFormatKey;
1132 
1133                     if ( bIsFormatKey )
1134                     {
1135                         OFormatSampleControl* pControl = new OFormatSampleControl( impl_getDefaultDialogParent_nothrow(), WB_READONLY | WB_TABSTOP | WB_BORDER );
1136                         aDescriptor.Control = pControl;
1137                         pControl->SetFormatSupplier( pSupplier );
1138 
1139                         aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_NUMBER_FORMAT);
1140                     }
1141                     else
1142                     {
1143                         OFormattedNumericControl* pControl = new OFormattedNumericControl( impl_getDefaultDialogParent_nothrow(), WB_TABSTOP | WB_BORDER );
1144                         aDescriptor.Control = pControl;
1145 
1146                         FormatDescription aDesc;
1147                         aDesc.pSupplier = pSupplier;
1148                         Any aFormatKeyValue = m_xComponent->getPropertyValue(PROPERTY_FORMATKEY);
1149                         if ( !( aFormatKeyValue >>= aDesc.nKey ) )
1150                             aDesc.nKey = 0;
1151 
1152                         pControl->SetFormatDescription( aDesc );
1153                     }
1154                 }
1155             }
1156         }
1157         break;
1158 
1159         case PROPERTY_ID_DATEMIN:
1160         case PROPERTY_ID_DATEMAX:
1161         case PROPERTY_ID_DEFAULT_DATE:
1162         case PROPERTY_ID_DATE:
1163             nControlType = PropertyControlType::DateField;
1164             break;
1165 
1166         case PROPERTY_ID_TIMEMIN:
1167         case PROPERTY_ID_TIMEMAX:
1168         case PROPERTY_ID_DEFAULT_TIME:
1169         case PROPERTY_ID_TIME:
1170             nControlType = PropertyControlType::TimeField;
1171             break;
1172 
1173         case PROPERTY_ID_VALUEMIN:
1174         case PROPERTY_ID_VALUEMAX:
1175         case PROPERTY_ID_DEFAULT_VALUE:
1176         case PROPERTY_ID_VALUE:
1177             {
1178                 OFormattedNumericControl* pControl = new OFormattedNumericControl( impl_getDefaultDialogParent_nothrow(), WB_TABSTOP | WB_BORDER | WB_SPIN | WB_REPEAT );
1179                 aDescriptor.Control = pControl;
1180 
1181                 // we don't set a formatter so the control uses a default (which uses the application
1182                 // language and a default numeric format)
1183                 // but we set the decimal digits
1184                 pControl->SetDecimalDigits(
1185                     ::comphelper::getINT16( m_xComponent->getPropertyValue( PROPERTY_DECIMAL_ACCURACY ) )
1186                 );
1187 
1188                 // and the thousands separator
1189                 pControl->SetThousandsSep(
1190                     ::comphelper::getBOOL( m_xComponent->getPropertyValue(PROPERTY_SHOWTHOUSANDSEP) )
1191                 );
1192 
1193                 // and the default value for the property
1194                 try
1195                 {
1196                     if (m_xPropertyState.is() && ((PROPERTY_ID_VALUEMIN == nPropId) || (PROPERTY_ID_VALUEMAX == nPropId)))
1197                     {
1198                         double nDefault = 0;
1199                         if ( m_xPropertyState->getPropertyDefault( aProperty.Name ) >>= nDefault )
1200                             pControl->SetDefaultValue( nDefault );
1201                     }
1202                 }
1203                 catch (Exception&)
1204                 {
1205                     // just ignore it
1206                 }
1207 
1208                 // and allow empty values only for the default value and the value
1209                 pControl->EnableEmptyField( ( PROPERTY_ID_DEFAULT_VALUE == nPropId )
1210                                         ||  ( PROPERTY_ID_VALUE == nPropId ) );
1211             }
1212             break;
1213 
1214         default:
1215             if ( TypeClass_BYTE <= eType && eType <= TypeClass_DOUBLE )
1216             {
1217                 sal_Int16 nDigits = 0;
1218                 sal_Int16 nValueUnit = -1;
1219                 sal_Int16 nDisplayUnit = -1;
1220                 if ( m_eComponentClass == eFormControl )
1221                 {
1222                     if  (  ( nPropId == PROPERTY_ID_WIDTH )
1223                         || ( nPropId == PROPERTY_ID_ROWHEIGHT )
1224                         || ( nPropId == PROPERTY_ID_HEIGHT )
1225                         )
1226                     {
1227                         nValueUnit = MeasureUnit::MM_10TH;
1228                         nDisplayUnit = impl_getDocumentMeasurementUnit_throw();
1229                         nDigits = 2;
1230                     }
1231                 }
1232 
1233                 Optional< double > aValueNotPresent( sal_False, 0 );
1234                 aDescriptor.Control = PropertyHandlerHelper::createNumericControl(
1235                     _rxControlFactory, nDigits, aValueNotPresent, aValueNotPresent, sal_False );
1236 
1237                 Reference< XNumericControl > xNumericControl( aDescriptor.Control, UNO_QUERY_THROW );
1238                 if ( nValueUnit != -1 )
1239                     xNumericControl->setValueUnit( nValueUnit );
1240                 if ( nDisplayUnit != -1 )
1241                     xNumericControl->setDisplayUnit( nDisplayUnit );
1242             }
1243             break;
1244         }
1245 
1246         //////////////////////////////////////////////////////////////////////
1247         if ( eType == TypeClass_SEQUENCE )
1248             nControlType = PropertyControlType::StringListField;
1249 
1250         //////////////////////////////////////////////////////////////////////
1251         // boolean values
1252         if ( eType == TypeClass_BOOLEAN )
1253         {
1254             sal_uInt16 nResId = RID_RSC_ENUM_YESNO;
1255             if  (   ( nPropId == PROPERTY_ID_SHOW_POSITION )
1256                 ||  ( nPropId == PROPERTY_ID_SHOW_NAVIGATION )
1257                 ||  ( nPropId == PROPERTY_ID_SHOW_RECORDACTIONS )
1258                 ||  ( nPropId == PROPERTY_ID_SHOW_FILTERSORT )
1259                 )
1260                 nResId = RID_RSC_ENUM_SHOWHIDE;
1261 
1262             ::std::vector< ::rtl::OUString > aListEntries;
1263             tools::StringListResource aRes(PcrRes(nResId),aListEntries);
1264             aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
1265             bNeedDefaultStringIfVoidAllowed = true;
1266         }
1267 
1268         //////////////////////////////////////////////////////////////////////
1269         // enum properties
1270         sal_uInt32 nPropertyUIFlags = m_pInfoService->getPropertyUIFlags( nPropId );
1271         bool bIsEnumProperty = ( nPropertyUIFlags & PROP_FLAG_ENUM ) != 0;
1272         if ( bIsEnumProperty || ( PROPERTY_ID_TARGET_FRAME == nPropId ) )
1273         {
1274             ::std::vector< ::rtl::OUString > aEnumValues = m_pInfoService->getPropertyEnumRepresentations( nPropId );
1275             ::std::vector< ::rtl::OUString >::const_iterator pStart = aEnumValues.begin();
1276             ::std::vector< ::rtl::OUString >::const_iterator pEnd = aEnumValues.end();
1277 
1278             // for a checkbox: if "ambiguous" is not allowed, remove this from the sequence
1279             if  (   ( PROPERTY_ID_DEFAULT_STATE == nPropId )
1280                 ||  ( PROPERTY_ID_STATE == nPropId )
1281                 )
1282             {
1283                 if ( impl_componentHasProperty_throw( PROPERTY_TRISTATE ) )
1284                 {
1285                     if ( !::comphelper::getBOOL( m_xComponent->getPropertyValue( PROPERTY_TRISTATE ) ) )
1286                     {   // remove the last sequence element
1287                         if ( pEnd > pStart )
1288                             --pEnd;
1289                     }
1290                 }
1291                 else
1292                     --pEnd;
1293             }
1294 
1295             if ( PROPERTY_ID_LISTSOURCETYPE == nPropId )
1296                 if ( FormComponentType::COMBOBOX == m_nClassId )
1297                     // remove the first sequence element -> value list not possible for combo boxes
1298                     ++pStart;
1299 
1300             // copy the sequence
1301             ::std::vector< ::rtl::OUString > aListEntries( pEnd - pStart );
1302             ::std::copy( pStart, pEnd, aListEntries.begin() );
1303 
1304             // create the control
1305             if ( PROPERTY_ID_TARGET_FRAME == nPropId )
1306                 aDescriptor.Control = PropertyHandlerHelper::createComboBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
1307             else
1308             {
1309                 aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
1310                 bNeedDefaultStringIfVoidAllowed = true;
1311             }
1312         }
1313 
1314         //////////////////////////////////////////////////////////////////////
1315         switch( nPropId )
1316         {
1317             case PROPERTY_ID_REPEAT_DELAY:
1318             {
1319                 OTimeDurationControl* pControl = new OTimeDurationControl( impl_getDefaultDialogParent_nothrow(), WB_BORDER | WB_TABSTOP );
1320                 aDescriptor.Control = pControl;
1321 
1322                 pControl->setMinValue( Optional< double >( sal_True, 0 ) );
1323                 pControl->setMaxValue( Optional< double >( sal_True, ::std::numeric_limits< double >::max() ) );
1324             }
1325             break;
1326 
1327             case PROPERTY_ID_TABINDEX:
1328             case PROPERTY_ID_BOUNDCOLUMN:
1329             case PROPERTY_ID_VISIBLESIZE:
1330             case PROPERTY_ID_MAXTEXTLEN:
1331             case PROPERTY_ID_LINEINCREMENT:
1332             case PROPERTY_ID_BLOCKINCREMENT:
1333             case PROPERTY_ID_SPININCREMENT:
1334             {
1335                 Optional< double > aMinValue( sal_True, 0 );
1336                 Optional< double > aMaxValue( sal_True, 0x7FFFFFFF );
1337 
1338                 if ( nPropId == PROPERTY_ID_MAXTEXTLEN )
1339                     aMinValue.Value = -1;
1340                 else if ( nPropId == PROPERTY_ID_VISIBLESIZE )
1341                     aMinValue.Value = 1;
1342                 else
1343                     aMinValue.Value = 0;
1344 
1345                 aDescriptor.Control = PropertyHandlerHelper::createNumericControl(
1346                     _rxControlFactory, 0, aMinValue, aMaxValue, sal_False );
1347             }
1348             break;
1349 
1350             case PROPERTY_ID_DECIMAL_ACCURACY:
1351             {
1352                 Optional< double > aMinValue( sal_True, 0 );
1353                 Optional< double > aMaxValue( sal_True, 20 );
1354 
1355                 aDescriptor.Control = PropertyHandlerHelper::createNumericControl(
1356                     _rxControlFactory, 0, aMinValue, aMaxValue, sal_False );
1357             }
1358             break;
1359 
1360             //////////////////////////////////////////////////////////////////////
1361             // DataSource
1362             case PROPERTY_ID_DATASOURCE:
1363             {
1364                 aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_ATTR_DATASOURCE);
1365 
1366                 ::std::vector< ::rtl::OUString > aListEntries;
1367 
1368                 Reference< XNameAccess > xDatabaseContext;
1369                 m_aContext.createComponent( (rtl::OUString)SERVICE_DATABASE_CONTEXT, xDatabaseContext );
1370                 if (xDatabaseContext.is())
1371                 {
1372                     Sequence< ::rtl::OUString > aDatasources = xDatabaseContext->getElementNames();
1373                     aListEntries.resize( aDatasources.getLength() );
1374                     ::std::copy( aDatasources.getConstArray(), aDatasources.getConstArray() + aDatasources.getLength(),
1375                         aListEntries.begin() );
1376                 }
1377                 aDescriptor.Control = PropertyHandlerHelper::createComboBoxControl(
1378                     _rxControlFactory, aListEntries, sal_False, sal_True );
1379             }
1380             break;
1381 
1382             case PROPERTY_ID_CONTROLSOURCE:
1383             {
1384                 ::std::vector< ::rtl::OUString > aFieldNames;
1385                 impl_initFieldList_nothrow( aFieldNames );
1386                 aDescriptor.Control = PropertyHandlerHelper::createComboBoxControl(
1387                     _rxControlFactory, aFieldNames, sal_False, sal_False );
1388             }
1389             break;
1390 
1391             case PROPERTY_ID_COMMAND:
1392                 impl_describeCursorSource_nothrow( aDescriptor, _rxControlFactory );
1393                 break;
1394 
1395             case PROPERTY_ID_LISTSOURCE:
1396                 impl_describeListSourceUI_throw( aDescriptor, _rxControlFactory );
1397                 break;
1398         }
1399 
1400         if ( !aDescriptor.Control.is() )
1401             aDescriptor.Control = _rxControlFactory->createPropertyControl( nControlType, bReadOnly );
1402 
1403         if ( ( aProperty.Attributes & PropertyAttribute::MAYBEVOID ) != 0 )
1404         {
1405             // insert the string "Default" string, if necessary
1406             if ( bNeedDefaultStringIfVoidAllowed || ( nControlType == PropertyControlType::ColorListBox ) )
1407             {
1408                 Reference< XStringListControl > xStringList( aDescriptor.Control, UNO_QUERY_THROW );
1409                 xStringList->prependListEntry( m_sDefaultValueString );
1410                 m_aPropertiesWithDefListEntry.insert( _rPropertyName );
1411             }
1412         }
1413 
1414         if ( aDescriptor.PrimaryButtonId.getLength() )
1415             aDescriptor.HasPrimaryButton = sal_True;
1416         if ( aDescriptor.SecondaryButtonId.getLength() )
1417             aDescriptor.HasSecondaryButton = sal_True;
1418 
1419         bool bIsDataProperty = ( nPropertyUIFlags & PROP_FLAG_DATA_PROPERTY ) != 0;
1420         aDescriptor.Category = ::rtl::OUString::createFromAscii( bIsDataProperty ? "Data" : "General" );
1421         return aDescriptor;
1422     }
1423 
1424     //--------------------------------------------------------------------
onInteractivePropertySelection(const::rtl::OUString & _rPropertyName,sal_Bool,Any & _rData,const Reference<XObjectInspectorUI> & _rxInspectorUI)1425     InteractiveSelectionResult SAL_CALL FormComponentPropertyHandler::onInteractivePropertySelection( const ::rtl::OUString& _rPropertyName, sal_Bool /*_bPrimary*/, Any& _rData, const Reference< XObjectInspectorUI >& _rxInspectorUI )
1426     {
1427         if ( !_rxInspectorUI.is() )
1428             throw NullPointerException();
1429 
1430         ::osl::ClearableMutexGuard aGuard( m_aMutex );
1431         PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
1432 
1433         InteractiveSelectionResult eResult = InteractiveSelectionResult_Cancelled;
1434         switch ( nPropId )
1435         {
1436         case PROPERTY_ID_DEFAULT_SELECT_SEQ:
1437         case PROPERTY_ID_SELECTEDITEMS:
1438             if ( impl_dialogListSelection_nothrow( _rPropertyName, aGuard ) )
1439                 eResult = InteractiveSelectionResult_Success;
1440             break;
1441 
1442         case PROPERTY_ID_FILTER:
1443         case PROPERTY_ID_SORT:
1444         {
1445             ::rtl::OUString sClause;
1446             if ( impl_dialogFilterOrSort_nothrow( PROPERTY_ID_FILTER == nPropId, sClause, aGuard ) )
1447             {
1448                 _rData <<= sClause;
1449                 eResult = InteractiveSelectionResult_ObtainedValue;
1450             }
1451         }
1452         break;
1453 
1454         case PROPERTY_ID_MASTERFIELDS:
1455         case PROPERTY_ID_DETAILFIELDS:
1456             if ( impl_dialogLinkedFormFields_nothrow( aGuard ) )
1457                 eResult = InteractiveSelectionResult_Success;
1458             break;
1459 
1460         case PROPERTY_ID_FORMATKEY:
1461             if ( impl_dialogFormatting_nothrow( _rData, aGuard ) )
1462                 eResult = InteractiveSelectionResult_ObtainedValue;
1463             break;
1464 
1465         case PROPERTY_ID_IMAGE_URL:
1466             if ( impl_browseForImage_nothrow( _rData, aGuard ) )
1467                 eResult = InteractiveSelectionResult_ObtainedValue;
1468             break;
1469 
1470         case PROPERTY_ID_TARGET_URL:
1471             if ( impl_browseForTargetURL_nothrow( _rData, aGuard ) )
1472                 eResult = InteractiveSelectionResult_ObtainedValue;
1473             break;
1474 
1475         case PROPERTY_ID_FONT:
1476             if ( impl_executeFontDialog_nothrow( _rData, aGuard ) )
1477                 eResult = InteractiveSelectionResult_ObtainedValue;
1478             break;
1479 
1480         case PROPERTY_ID_DATASOURCE:
1481             if ( impl_browseForDatabaseDocument_throw( _rData, aGuard ) )
1482                 eResult = InteractiveSelectionResult_ObtainedValue;
1483             break;
1484 
1485         case PROPERTY_ID_BACKGROUNDCOLOR:
1486         case PROPERTY_ID_FILLCOLOR:
1487         case PROPERTY_ID_SYMBOLCOLOR:
1488         case PROPERTY_ID_BORDERCOLOR:
1489             if ( impl_dialogColorChooser_throw( nPropId, _rData, aGuard ) )
1490                 eResult = InteractiveSelectionResult_ObtainedValue;
1491             break;
1492 
1493         case PROPERTY_ID_CONTROLLABEL:
1494             if ( impl_dialogChooseLabelControl_nothrow( _rData, aGuard ) )
1495                 eResult = InteractiveSelectionResult_ObtainedValue;
1496             break;
1497 
1498         case PROPERTY_ID_TABINDEX:
1499             if ( impl_dialogChangeTabOrder_nothrow( aGuard ) )
1500                 eResult = InteractiveSelectionResult_Success;
1501             break;
1502 
1503         case PROPERTY_ID_COMMAND:
1504         case PROPERTY_ID_LISTSOURCE:
1505             if ( impl_doDesignSQLCommand_nothrow( _rxInspectorUI, nPropId ) )
1506                 eResult = InteractiveSelectionResult_Pending;
1507             break;
1508         default:
1509             DBG_ERROR( "FormComponentPropertyHandler::onInteractivePropertySelection: request for a property which does not have dedicated UI!" );
1510             break;
1511         }
1512         return eResult;
1513     }
1514 
1515     //--------------------------------------------------------------------
1516     namespace
1517     {
lcl_rebuildAndResetCommand(const Reference<XObjectInspectorUI> & _rxInspectorUI,const Reference<XPropertyHandler> & _rxHandler)1518         void lcl_rebuildAndResetCommand( const Reference< XObjectInspectorUI >& _rxInspectorUI, const Reference< XPropertyHandler >& _rxHandler )
1519         {
1520             OSL_PRECOND( _rxInspectorUI.is(), "lcl_rebuildAndResetCommand: invalid BrowserUI!" );
1521             OSL_PRECOND( _rxHandler.is(), "lcl_rebuildAndResetCommand: invalid handler!" );
1522             _rxInspectorUI->rebuildPropertyUI( PROPERTY_COMMAND );
1523             _rxHandler->setPropertyValue( PROPERTY_COMMAND, makeAny( ::rtl::OUString() ) );
1524         }
1525     }
1526 
1527     //--------------------------------------------------------------------
actuatingPropertyChanged(const::rtl::OUString & _rActuatingPropertyName,const Any & _rNewValue,const Any &,const Reference<XObjectInspectorUI> & _rxInspectorUI,sal_Bool _bFirstTimeInit)1528     void SAL_CALL FormComponentPropertyHandler::actuatingPropertyChanged( const ::rtl::OUString& _rActuatingPropertyName, const Any& _rNewValue, const Any& /*_rOldValue*/, const Reference< XObjectInspectorUI >& _rxInspectorUI, sal_Bool _bFirstTimeInit )
1529     {
1530         if ( !_rxInspectorUI.is() )
1531             throw NullPointerException();
1532 
1533         ::osl::MutexGuard aGuard( m_aMutex );
1534         PropertyId nActuatingPropId( impl_getPropertyId_throw( _rActuatingPropertyName ) );
1535 
1536         ::std::vector< PropertyId > aDependentProperties;
1537 
1538         switch ( nActuatingPropId )
1539         {
1540         // ----- EscapeProcessing -----
1541         case PROPERTY_ID_ESCAPE_PROCESSING:
1542             aDependentProperties.push_back( PROPERTY_ID_FILTER );
1543             aDependentProperties.push_back( PROPERTY_ID_SORT );
1544             break;  // case PROPERTY_ID_ESCAPE_PROCESSING
1545 
1546         // ----- CommandType -----
1547         case PROPERTY_ID_COMMANDTYPE:
1548             // available commands (tables or queries) might have changed
1549             if ( !_bFirstTimeInit && m_bHaveCommand )
1550                 lcl_rebuildAndResetCommand( _rxInspectorUI, this );
1551             aDependentProperties.push_back( PROPERTY_ID_COMMAND );
1552             break;  // case PROPERTY_ID_COMMANDTYPE
1553 
1554         // ----- DataSourceName -----
1555         case PROPERTY_ID_DATASOURCE:
1556             // reset the connection, now that we have a new data source
1557             impl_clearRowsetConnection_nothrow();
1558 
1559             // available list source values (tables or queries) might have changed
1560             if ( !_bFirstTimeInit && m_bHaveListSource )
1561                 _rxInspectorUI->rebuildPropertyUI( PROPERTY_LISTSOURCE );
1562 
1563             // available commands (tables or queries) might have changed
1564             if ( !_bFirstTimeInit && m_bHaveCommand )
1565                 lcl_rebuildAndResetCommand( _rxInspectorUI, this );
1566 
1567             // Command also depends on DataSource
1568             aDependentProperties.push_back( PROPERTY_ID_COMMAND );
1569             // NO break!
1570 
1571         // ----- Command -----
1572         case PROPERTY_ID_COMMAND:
1573             aDependentProperties.push_back( PROPERTY_ID_FILTER );
1574             aDependentProperties.push_back( PROPERTY_ID_SORT );
1575             if ( m_bComponentIsSubForm )
1576                 aDependentProperties.push_back( PROPERTY_ID_DETAILFIELDS );
1577             break;
1578 
1579         // ----- ListSourceType -----
1580         case PROPERTY_ID_LISTSOURCETYPE:
1581             if ( !_bFirstTimeInit && m_bHaveListSource )
1582                 // available list source values (tables or queries) might have changed
1583                 _rxInspectorUI->rebuildPropertyUI( PROPERTY_LISTSOURCE );
1584             aDependentProperties.push_back( PROPERTY_ID_BOUNDCOLUMN );
1585             aDependentProperties.push_back( PROPERTY_ID_STRINGITEMLIST );
1586             // NO break!
1587 
1588         // ----- StringItemList -----
1589         case PROPERTY_ID_STRINGITEMLIST:
1590             aDependentProperties.push_back( PROPERTY_ID_SELECTEDITEMS );
1591             aDependentProperties.push_back( PROPERTY_ID_DEFAULT_SELECT_SEQ );
1592             break;
1593 
1594         // ----- ListSource -----
1595         case PROPERTY_ID_LISTSOURCE:
1596             aDependentProperties.push_back( PROPERTY_ID_STRINGITEMLIST );
1597             break;
1598 
1599         // ----- DataField -----
1600         case PROPERTY_ID_CONTROLSOURCE:
1601         {
1602             ::rtl::OUString sControlSource;
1603             _rNewValue >>= sControlSource;
1604             if ( impl_componentHasProperty_throw( PROPERTY_FILTERPROPOSAL ) )
1605                 _rxInspectorUI->enablePropertyUI( PROPERTY_FILTERPROPOSAL, sControlSource.getLength() > 0 );
1606             if ( impl_componentHasProperty_throw( PROPERTY_EMPTY_IS_NULL ) )
1607                 _rxInspectorUI->enablePropertyUI( PROPERTY_EMPTY_IS_NULL, sControlSource.getLength() > 0 );
1608 
1609             aDependentProperties.push_back( PROPERTY_ID_BOUNDCOLUMN );
1610             aDependentProperties.push_back( PROPERTY_ID_SCALEIMAGE );
1611             aDependentProperties.push_back( PROPERTY_ID_SCALE_MODE );
1612             aDependentProperties.push_back( PROPERTY_ID_INPUT_REQUIRED );
1613         }
1614         break;
1615 
1616         case PROPERTY_ID_EMPTY_IS_NULL:
1617             aDependentProperties.push_back( PROPERTY_ID_INPUT_REQUIRED );
1618             break;
1619 
1620         // ----- SubmitEncoding -----
1621         case PROPERTY_ID_SUBMIT_ENCODING:
1622         {
1623             FormSubmitEncoding eEncoding = FormSubmitEncoding_URL;
1624             OSL_VERIFY( _rNewValue >>= eEncoding );
1625             _rxInspectorUI->enablePropertyUI( PROPERTY_SUBMIT_METHOD, eEncoding == FormSubmitEncoding_URL );
1626         }
1627         break;
1628 
1629         // ----- Repeat -----
1630         case PROPERTY_ID_REPEAT:
1631         {
1632             sal_Bool bIsRepeating = sal_False;
1633             OSL_VERIFY( _rNewValue >>= bIsRepeating );
1634             _rxInspectorUI->enablePropertyUI( PROPERTY_REPEAT_DELAY, bIsRepeating );
1635         }
1636         break;
1637 
1638         // ----- TabStop -----
1639         case PROPERTY_ID_TABSTOP:
1640         {
1641             if ( !impl_componentHasProperty_throw( PROPERTY_TABINDEX ) )
1642                 break;
1643             sal_Bool bHasTabStop = sal_False;
1644             _rNewValue >>= bHasTabStop;
1645             _rxInspectorUI->enablePropertyUI( PROPERTY_TABINDEX, bHasTabStop );
1646         }
1647         break;
1648 
1649         // ----- Border -----
1650         case PROPERTY_ID_BORDER:
1651         {
1652             sal_Int16 nBordeType = VisualEffect::NONE;
1653             OSL_VERIFY( _rNewValue >>= nBordeType );
1654             _rxInspectorUI->enablePropertyUI( PROPERTY_BORDERCOLOR, nBordeType == VisualEffect::FLAT );
1655         }
1656         break;
1657 
1658         // ----- DropDown -----
1659         case PROPERTY_ID_DROPDOWN:
1660         {
1661             if ( impl_isSupportedProperty_nothrow( PROPERTY_ID_LINECOUNT ) )
1662             {
1663                 sal_Bool bDropDown = sal_True;
1664                 _rNewValue >>= bDropDown;
1665                 _rxInspectorUI->enablePropertyUI( PROPERTY_LINECOUNT, bDropDown );
1666             }
1667         }
1668         break;
1669 
1670         // ----- ImageURL -----
1671         case PROPERTY_ID_IMAGE_URL:
1672         {
1673             if ( impl_isSupportedProperty_nothrow( PROPERTY_ID_IMAGEPOSITION ) )
1674             {
1675                 ::rtl::OUString sImageURL;
1676                 OSL_VERIFY( _rNewValue >>= sImageURL );
1677                 _rxInspectorUI->enablePropertyUI( PROPERTY_IMAGEPOSITION, sImageURL.getLength() != 0 );
1678             }
1679 
1680             aDependentProperties.push_back( PROPERTY_ID_SCALEIMAGE );
1681             aDependentProperties.push_back( PROPERTY_ID_SCALE_MODE );
1682         }
1683         break;
1684 
1685         // ----- ButtonType -----
1686         case PROPERTY_ID_BUTTONTYPE:
1687         {
1688             FormButtonType eButtonType( FormButtonType_PUSH );
1689             OSL_VERIFY( _rNewValue >>= eButtonType );
1690             _rxInspectorUI->enablePropertyUI( PROPERTY_TARGET_URL, FormButtonType_URL == eButtonType );
1691         }
1692         // NO break!
1693 
1694         // ----- TargetURL -----
1695         case PROPERTY_ID_TARGET_URL:
1696             aDependentProperties.push_back( PROPERTY_ID_TARGET_FRAME );
1697             break;  // case PROPERTY_ID_TARGET_URL
1698 
1699         // ----- TriState -----
1700         case PROPERTY_ID_TRISTATE:
1701             if ( !_bFirstTimeInit )
1702                 _rxInspectorUI->rebuildPropertyUI( m_eComponentClass == eFormControl ? PROPERTY_DEFAULT_STATE : PROPERTY_STATE );
1703             break;  // case PROPERTY_ID_TRISTATE
1704 
1705         // ----- DecimalAccuracy -----
1706         case PROPERTY_ID_DECIMAL_ACCURACY:
1707         // ----- ShowThousandsSeparator -----
1708         case PROPERTY_ID_SHOWTHOUSANDSEP:
1709         {
1710             sal_Bool bAccuracy = (PROPERTY_ID_DECIMAL_ACCURACY == nActuatingPropId);
1711             sal_uInt16  nNewDigits = 0;
1712             sal_Bool    bUseSep = sal_False;
1713             if ( bAccuracy )
1714                 OSL_VERIFY( _rNewValue >>= nNewDigits );
1715             else
1716                 OSL_VERIFY( _rNewValue >>= bUseSep );
1717 
1718             // propagate the changes to the min/max/default fields
1719             Any aCurrentProp;
1720             ::rtl::OUString aAffectedProps[] = { PROPERTY_VALUE, PROPERTY_DEFAULT_VALUE, PROPERTY_VALUEMIN, PROPERTY_VALUEMAX };
1721             for (sal_uInt16 i=0; i<sizeof(aAffectedProps)/sizeof(aAffectedProps[0]); ++i)
1722             {
1723                 Reference< XPropertyControl > xControl;
1724                 try
1725                 {
1726                     xControl = _rxInspectorUI->getPropertyControl( aAffectedProps[i] );
1727                 }
1728                 catch( const UnknownPropertyException& e ) { (void)e; }
1729                 if ( xControl.is() )
1730                 {
1731                     OFormattedNumericControl* pControl = dynamic_cast< OFormattedNumericControl* >( xControl.get() );
1732                     DBG_ASSERT( pControl, "FormComponentPropertyHandler::actuatingPropertyChanged: invalid control!" );
1733                     if ( pControl )
1734                     {
1735                         if ( bAccuracy )
1736                             pControl->SetDecimalDigits( nNewDigits );
1737                         else
1738                             pControl->SetThousandsSep( bUseSep );
1739                     }
1740                 }
1741             }
1742         }
1743         break;
1744 
1745         // ----- FormatKey -----
1746         case PROPERTY_ID_FORMATKEY:
1747         {
1748             FormatDescription aNewDesc;
1749 
1750             Reference< XNumberFormatsSupplier >  xSupplier;
1751             OSL_VERIFY( m_xComponent->getPropertyValue( PROPERTY_FORMATSSUPPLIER ) >>= xSupplier );
1752 
1753             Reference< XUnoTunnel > xTunnel( xSupplier, UNO_QUERY );
1754             DBG_ASSERT(xTunnel.is(), "FormComponentPropertyHandler::actuatingPropertyChanged: xTunnel is invalid!");
1755             if ( xTunnel.is() )
1756             {
1757                 SvNumberFormatsSupplierObj* pSupplier = reinterpret_cast<SvNumberFormatsSupplierObj*>(xTunnel->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));
1758                     // the same again
1759 
1760                 aNewDesc.pSupplier = pSupplier;
1761                 if ( !( _rNewValue >>= aNewDesc.nKey ) )
1762                     aNewDesc.nKey = 0;
1763 
1764                 // give each control which has to know this an own copy of the description
1765                 ::rtl::OUString aFormattedPropertyControls[] = {
1766                     PROPERTY_EFFECTIVE_MIN, PROPERTY_EFFECTIVE_MAX, PROPERTY_EFFECTIVE_DEFAULT, PROPERTY_EFFECTIVE_VALUE
1767                 };
1768                 for ( sal_uInt16 i=0; i<sizeof(aFormattedPropertyControls)/sizeof(aFormattedPropertyControls[0]); ++i )
1769                 {
1770                     Reference< XPropertyControl > xControl;
1771                     try
1772                     {
1773                         xControl = _rxInspectorUI->getPropertyControl( aFormattedPropertyControls[i] );
1774                     }
1775                     catch( const UnknownPropertyException& e ) { (void)e; }
1776                     if ( xControl.is() )
1777                     {
1778                         OFormattedNumericControl* pControl = dynamic_cast< OFormattedNumericControl* >( xControl.get() );
1779                         DBG_ASSERT( pControl, "FormComponentPropertyHandler::actuatingPropertyChanged: invalid control!" );
1780                         if ( pControl )
1781                             pControl->SetFormatDescription( aNewDesc );
1782                     }
1783                 }
1784             }
1785         }
1786         break;
1787 
1788         case PROPERTY_ID_TOGGLE:
1789         {
1790             sal_Bool bIsToggleButton = sal_False;
1791             OSL_VERIFY( _rNewValue >>= bIsToggleButton );
1792             _rxInspectorUI->enablePropertyUI( PROPERTY_DEFAULT_STATE, bIsToggleButton );
1793         }
1794         break;
1795 
1796         default:
1797             DBG_ERROR( "FormComponentPropertyHandler::actuatingPropertyChanged: did not register for this property!" );
1798             break;
1799 
1800         }   // switch ( nActuatingPropId )
1801 
1802         for ( ::std::vector< PropertyId >::const_iterator loopAffected = aDependentProperties.begin();
1803               loopAffected != aDependentProperties.end();
1804               ++loopAffected
1805             )
1806         {
1807             if ( impl_isSupportedProperty_nothrow( *loopAffected ) )
1808                 impl_updateDependentProperty_nothrow( *loopAffected, _rxInspectorUI );
1809         }
1810     }
1811 
1812     //------------------------------------------------------------------------
impl_updateDependentProperty_nothrow(PropertyId _nPropId,const Reference<XObjectInspectorUI> & _rxInspectorUI) const1813     void FormComponentPropertyHandler::impl_updateDependentProperty_nothrow( PropertyId _nPropId, const Reference< XObjectInspectorUI >& _rxInspectorUI ) const
1814     {
1815         try
1816         {
1817             switch ( _nPropId )
1818             {
1819             // ----- StringItemList -----
1820             case PROPERTY_ID_STRINGITEMLIST:
1821             {
1822                 ListSourceType eLSType = ListSourceType_VALUELIST;
1823                 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_LISTSOURCETYPE ) >>= eLSType );
1824 
1825                 ::rtl::OUString sListSource;
1826                 {
1827                     Sequence< ::rtl::OUString > aListSource;
1828                     Any aListSourceValue( impl_getPropertyValue_throw( PROPERTY_LISTSOURCE ) );
1829                     if ( aListSourceValue >>= aListSource )
1830                     {
1831                         if ( aListSource.getLength() )
1832                             sListSource = aListSource[0];
1833                     }
1834                     else
1835                         OSL_VERIFY( aListSourceValue >>= sListSource );
1836                 }
1837 
1838                 sal_Bool bIsEnabled =   (  ( eLSType == ListSourceType_VALUELIST )
1839                                         || ( sListSource.getLength() == 0 )
1840                                         );
1841                 _rxInspectorUI->enablePropertyUI( PROPERTY_STRINGITEMLIST, bIsEnabled );
1842             }
1843             break;  // case PROPERTY_ID_STRINGITEMLIST
1844 
1845             // ----- BoundColumn -----
1846             case PROPERTY_ID_BOUNDCOLUMN:
1847             {
1848                 ::rtl::OUString sControlSource;
1849                 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_CONTROLSOURCE ) >>= sControlSource );
1850 
1851                 ListSourceType eLSType = ListSourceType_VALUELIST;
1852                 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_LISTSOURCETYPE ) >>= eLSType );
1853 
1854                 _rxInspectorUI->enablePropertyUI( PROPERTY_BOUNDCOLUMN,
1855                         ( sControlSource.getLength() > 0 )
1856                     &&  ( eLSType != ListSourceType_TABLEFIELDS )
1857                     &&  ( eLSType != ListSourceType_VALUELIST )
1858                 );
1859             }
1860             break;  // case PROPERTY_ID_BOUNDCOLUMN
1861 
1862             // ----- ScaleImage, ScaleMode -----
1863             case PROPERTY_ID_SCALEIMAGE:
1864             case PROPERTY_ID_SCALE_MODE:
1865             {
1866                 ::rtl::OUString sControlSource;
1867                 if ( impl_isSupportedProperty_nothrow( PROPERTY_ID_CONTROLSOURCE ) )
1868                     impl_getPropertyValue_throw( PROPERTY_CONTROLSOURCE ) >>= sControlSource;
1869 
1870                 ::rtl::OUString sImageURL;
1871                 impl_getPropertyValue_throw( PROPERTY_IMAGE_URL ) >>= sImageURL;
1872 
1873                 _rxInspectorUI->enablePropertyUI( impl_getPropertyNameFromId_nothrow( _nPropId ),
1874                     ( sControlSource.getLength() != 0 ) || ( sImageURL.getLength() != 0 )
1875                 );
1876             }
1877             break;  // case PROPERTY_ID_SCALEIMAGE, PROPERTY_ID_SCALE_MODE
1878 
1879             // ----- InputRequired -----
1880             case PROPERTY_ID_INPUT_REQUIRED:
1881             {
1882                 ::rtl::OUString sControlSource;
1883                 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_CONTROLSOURCE ) >>= sControlSource );
1884 
1885                 sal_Bool bEmptyIsNULL = sal_False;
1886                 sal_Bool bHasEmptyIsNULL = impl_componentHasProperty_throw( PROPERTY_EMPTY_IS_NULL );
1887                 if ( bHasEmptyIsNULL )
1888                     OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_EMPTY_IS_NULL ) >>= bEmptyIsNULL );
1889 
1890                 // if the control is not bound to a DB field, there is no sense in having the "Input required"
1891                 // property
1892                 // Also, if an empty input of this control are *not* written as NULL, but as empty strings,
1893                 // then "Input required" does not make sense, too (since there's always an input, even if the control
1894                 // is empty).
1895                 _rxInspectorUI->enablePropertyUI( PROPERTY_INPUT_REQUIRED,
1896                     ( sControlSource.getLength() != 0 ) && ( !bHasEmptyIsNULL || bEmptyIsNULL )
1897                 );
1898             }
1899             break;
1900 
1901             // ----- SelectedItems, DefaultSelection -----
1902             case PROPERTY_ID_SELECTEDITEMS:
1903             case PROPERTY_ID_DEFAULT_SELECT_SEQ:
1904             {
1905                 Sequence< ::rtl::OUString > aEntries;
1906                 impl_getPropertyValue_throw( PROPERTY_STRINGITEMLIST ) >>= aEntries;
1907                 bool isEnabled = aEntries.getLength() != 0;
1908 
1909                 if ( ( m_nClassId == FormComponentType::LISTBOX ) && ( m_eComponentClass == eFormControl ) )
1910                 {
1911                     ListSourceType eLSType = ListSourceType_VALUELIST;
1912                     impl_getPropertyValue_throw( PROPERTY_LISTSOURCETYPE ) >>= eLSType;
1913                     isEnabled &= ( eLSType == ListSourceType_VALUELIST );
1914                 }
1915                 _rxInspectorUI->enablePropertyUIElements( impl_getPropertyNameFromId_nothrow( _nPropId ),
1916                     PropertyLineElement::PrimaryButton, isEnabled );
1917             }
1918             break;  // case PROPERTY_ID_DEFAULT_SELECT_SEQ
1919 
1920             // ----- TargetFrame ------
1921             case PROPERTY_ID_TARGET_FRAME:
1922             {
1923                 ::rtl::OUString sTargetURL;
1924                 impl_getPropertyValue_throw( PROPERTY_TARGET_URL ) >>= sTargetURL;
1925                 FormButtonType eButtonType( FormButtonType_URL );
1926                 if ( 0 != m_nClassId )
1927                 {
1928                     OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_BUTTONTYPE ) >>= eButtonType );
1929                 }
1930                 // if m_nClassId is 0, then we're inspecting a form. In this case, eButtonType is always
1931                 // FormButtonType_URL here
1932                 _rxInspectorUI->enablePropertyUI( PROPERTY_TARGET_FRAME,
1933                     ( eButtonType == FormButtonType_URL ) && ( sTargetURL.getLength() > 0 )
1934                 );
1935             }
1936             break;
1937 
1938             // ----- Order ------
1939             case PROPERTY_ID_SORT:
1940             // ----- Filter ------
1941             case PROPERTY_ID_FILTER:
1942             {
1943                 Reference< XConnection > xConnection;
1944                 bool bAllowEmptyDS = ::dbtools::isEmbeddedInDatabase( m_xComponent, xConnection );
1945 
1946                 // if there's no escape processing, we cannot enter any values for this property
1947                 sal_Bool  bDoEscapeProcessing( sal_False );
1948                 impl_getPropertyValue_throw( PROPERTY_ESCAPE_PROCESSING ) >>= bDoEscapeProcessing;
1949                 _rxInspectorUI->enablePropertyUI(
1950                     impl_getPropertyNameFromId_nothrow( _nPropId ),
1951                     bDoEscapeProcessing
1952                 );
1953 
1954                 // also care for the browse button - enabled if we have escape processing, and a valid
1955                 // data source signature
1956                 _rxInspectorUI->enablePropertyUIElements(
1957                     impl_getPropertyNameFromId_nothrow( _nPropId ),
1958                     PropertyLineElement::PrimaryButton,
1959                         impl_hasValidDataSourceSignature_nothrow( m_xComponent, bAllowEmptyDS )
1960                     &&  bDoEscapeProcessing
1961                 );
1962             }
1963             break;  // case PROPERTY_ID_FILTER:
1964 
1965             // ----- Command -----
1966             case PROPERTY_ID_COMMAND:
1967             {
1968                 sal_Int32   nCommandType( CommandType::COMMAND );
1969                 OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_COMMANDTYPE ) >>= nCommandType );
1970 
1971                 impl_ensureRowsetConnection_nothrow();
1972                 Reference< XConnection > xConnection = m_xRowSetConnection.getTyped();
1973                 bool bAllowEmptyDS = false;
1974                 if ( !xConnection.is() )
1975                     bAllowEmptyDS = ::dbtools::isEmbeddedInDatabase( m_xComponent, xConnection );
1976 
1977                 bool doEnable = ( nCommandType == CommandType::COMMAND )
1978                             &&  (  m_xRowSetConnection.is()
1979                                 || xConnection.is()
1980                                 || impl_hasValidDataSourceSignature_nothrow( m_xComponent, bAllowEmptyDS)
1981                                 );
1982 
1983                 _rxInspectorUI->enablePropertyUIElements(
1984                     PROPERTY_COMMAND,
1985                     PropertyLineElement::PrimaryButton,
1986                     doEnable
1987                 );
1988             }
1989             break;  // case PROPERTY_ID_COMMAND
1990 
1991             // ----- DetailFields -----
1992             case PROPERTY_ID_DETAILFIELDS:
1993             {
1994                 Reference< XConnection > xConnection;
1995                 bool bAllowEmptyDS = ::dbtools::isEmbeddedInDatabase( m_xComponent, xConnection );
1996 
1997                 // both our current form, and it's parent form, need to have a valid
1998                 // data source signature
1999                 bool bDoEnableMasterDetailFields =
2000                         impl_hasValidDataSourceSignature_nothrow( m_xComponent, bAllowEmptyDS )
2001                     &&  impl_hasValidDataSourceSignature_nothrow( Reference< XPropertySet >( m_xObjectParent, UNO_QUERY ), bAllowEmptyDS );
2002 
2003                 // in opposite to the other properties, here in real *two* properties are
2004                 // affected
2005                 _rxInspectorUI->enablePropertyUIElements( PROPERTY_DETAILFIELDS, PropertyLineElement::PrimaryButton, bDoEnableMasterDetailFields );
2006                 _rxInspectorUI->enablePropertyUIElements( PROPERTY_MASTERFIELDS, PropertyLineElement::PrimaryButton, bDoEnableMasterDetailFields );
2007             }
2008             break;
2009 
2010             default:
2011                 OSL_ENSURE( false, "FormComponentPropertyHandler::impl_updateDependentProperty_nothrow: unexpected property to update!" );
2012                 break;
2013 
2014             }   // switch
2015         }
2016         catch( const Exception& )
2017         {
2018             OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_updateDependentProperty_nothrow: caught an exception!" );
2019         }
2020     }
2021 
2022     //------------------------------------------------------------------------
disposing()2023     void SAL_CALL FormComponentPropertyHandler::disposing()
2024     {
2025         FormComponentPropertyHandler_Base::disposing();
2026         if ( m_xCommandDesigner.is() && m_xCommandDesigner->isActive() )
2027             m_xCommandDesigner->dispose();
2028     }
2029 
2030     //------------------------------------------------------------------------
suspend(sal_Bool _bSuspend)2031     sal_Bool SAL_CALL FormComponentPropertyHandler::suspend( sal_Bool _bSuspend )
2032     {
2033         ::osl::MutexGuard aGuard( m_aMutex );
2034         if ( _bSuspend )
2035             if ( m_xCommandDesigner.is() && m_xCommandDesigner->isActive() )
2036                 return m_xCommandDesigner->suspend();
2037         return sal_True;
2038     }
2039 
2040     //------------------------------------------------------------------------
impl_initComponentMetaData_throw()2041     void FormComponentPropertyHandler::impl_initComponentMetaData_throw()
2042     {
2043         try
2044         {
2045             //////////////////////////////////////////////////////////////////
2046             // component class
2047             m_eComponentClass = eUnknown;
2048 
2049             if  (   impl_componentHasProperty_throw( PROPERTY_WIDTH )
2050                 &&  impl_componentHasProperty_throw( PROPERTY_HEIGHT )
2051                 &&  impl_componentHasProperty_throw( PROPERTY_POSITIONX )
2052                 &&  impl_componentHasProperty_throw( PROPERTY_POSITIONY )
2053                 &&  impl_componentHasProperty_throw( PROPERTY_STEP )
2054                 &&  impl_componentHasProperty_throw( PROPERTY_TABINDEX )
2055                 )
2056             {
2057                 m_eComponentClass = eDialogControl;
2058             }
2059             else
2060             {
2061                 m_eComponentClass = eFormControl;
2062             }
2063 
2064             //////////////////////////////////////////////////////////////////
2065             // (database) sub form?
2066             Reference< XForm > xAsForm( m_xComponent, UNO_QUERY );
2067             if ( xAsForm.is() )
2068             {
2069                 Reference< XChild > xFormAsChild( xAsForm, UNO_QUERY );
2070                 Reference< XForm > xFormsParent;
2071                 if ( xFormAsChild.is() )
2072                     xFormsParent = xFormsParent.query( xFormAsChild->getParent() );
2073                 m_bComponentIsSubForm = xFormsParent.is();
2074             }
2075 
2076             //////////////////////////////////////////////////////////////////
2077             // ClassId
2078             Reference< XChild > xCompAsChild( m_xComponent, UNO_QUERY );
2079             if ( xCompAsChild.is() )
2080                 m_xObjectParent = xCompAsChild->getParent();
2081 
2082             //////////////////////////////////////////////////////////////////
2083             // ClassId
2084             impl_classifyControlModel_throw();
2085         }
2086         catch( const RuntimeException& )
2087         {
2088             throw;
2089         }
2090         catch( const Exception& )
2091         {
2092             OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_initComponentMetaData_throw: caught an exception!" );
2093         }
2094     }
2095 
2096     //------------------------------------------------------------------------
impl_classifyControlModel_throw()2097     void FormComponentPropertyHandler::impl_classifyControlModel_throw( )
2098     {
2099         if ( impl_componentHasProperty_throw( PROPERTY_CLASSID ) )
2100         {
2101             OSL_VERIFY( m_xComponent->getPropertyValue( PROPERTY_CLASSID ) >>= m_nClassId );
2102         }
2103         else if ( eDialogControl == m_eComponentClass )
2104         {
2105             Reference< XControlModel > xControlModel( m_xComponent, UNO_QUERY );
2106             Reference< XServiceInfo > xServiceInfo( m_xComponent, UNO_QUERY );
2107             if ( xServiceInfo.is() )
2108             {
2109                 // it's a control model, and can tell about it's supported services
2110                 m_nClassId = FormComponentType::CONTROL;
2111 
2112                 const sal_Char* aControlModelServiceNames[] =
2113                 {
2114                     "UnoControlButtonModel",
2115                     "UnoControlCheckBoxModel",
2116                     "UnoControlComboBoxModel",
2117                     "UnoControlCurrencyFieldModel",
2118                     "UnoControlDateFieldModel",
2119                     "UnoControlEditModel",
2120                     "UnoControlFileControlModel",
2121                     "UnoControlFixedTextModel",
2122                     "UnoControlGroupBoxModel",
2123                     "UnoControlImageControlModel",
2124                     "UnoControlListBoxModel",
2125                     "UnoControlNumericFieldModel",
2126                     "UnoControlPatternFieldModel",
2127                     "UnoControlRadioButtonModel",
2128                     "UnoControlScrollBarModel",
2129                     "UnoControlSpinButtonModel",
2130                     "UnoControlTimeFieldModel",
2131 
2132                     "UnoControlFixedLineModel",
2133                     "UnoControlFormattedFieldModel",
2134                     "UnoControlProgressBarModel"
2135                 };
2136                 const sal_Int16 nClassIDs[] =
2137                 {
2138                     FormComponentType::COMMANDBUTTON,
2139                     FormComponentType::CHECKBOX,
2140                     FormComponentType::COMBOBOX,
2141                     FormComponentType::CURRENCYFIELD,
2142                     FormComponentType::DATEFIELD,
2143                     FormComponentType::TEXTFIELD,
2144                     FormComponentType::FILECONTROL,
2145                     FormComponentType::FIXEDTEXT,
2146                     FormComponentType::GROUPBOX,
2147                     FormComponentType::IMAGECONTROL,
2148                     FormComponentType::LISTBOX,
2149                     FormComponentType::NUMERICFIELD,
2150                     FormComponentType::PATTERNFIELD,
2151                     FormComponentType::RADIOBUTTON,
2152                     FormComponentType::SCROLLBAR,
2153                     FormComponentType::SPINBUTTON,
2154                     FormComponentType::TIMEFIELD,
2155 
2156                     ControlType::FIXEDLINE,
2157                     ControlType::FORMATTEDFIELD,
2158                     ControlType::PROGRESSBAR
2159                 };
2160 
2161                 sal_Int32 nKnownControlTypes = sizeof( aControlModelServiceNames ) / sizeof( aControlModelServiceNames[ 0 ] );
2162                 OSL_ENSURE( nKnownControlTypes == sizeof( nClassIDs ) / sizeof( nClassIDs[ 0 ] ),
2163                     "FormComponentPropertyHandler::impl_classifyControlModel_throw: inconsistence" );
2164 
2165                 for ( sal_Int32 i = 0; i < nKnownControlTypes; ++i )
2166                 {
2167                     ::rtl::OUString sServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt." ) );
2168                     sServiceName += ::rtl::OUString::createFromAscii( aControlModelServiceNames[ i ] );
2169 
2170                     if ( xServiceInfo->supportsService( sServiceName ) )
2171                     {
2172                         m_nClassId = nClassIDs[ i ];
2173                         break;
2174                     }
2175                 }
2176             }
2177         }
2178     }
2179 
2180     //------------------------------------------------------------------------
impl_normalizePropertyValue_nothrow(Any & _rValue,PropertyId _nPropId) const2181     void FormComponentPropertyHandler::impl_normalizePropertyValue_nothrow( Any& _rValue, PropertyId _nPropId ) const
2182     {
2183         switch ( _nPropId )
2184         {
2185         case PROPERTY_ID_TABSTOP:
2186             if ( !_rValue.hasValue() )
2187             {
2188                 switch ( m_nClassId )
2189                 {
2190                 case FormComponentType::COMMANDBUTTON:
2191                 case FormComponentType::RADIOBUTTON:
2192                 case FormComponentType::CHECKBOX:
2193                 case FormComponentType::TEXTFIELD:
2194                 case FormComponentType::LISTBOX:
2195                 case FormComponentType::COMBOBOX:
2196                 case FormComponentType::FILECONTROL:
2197                 case FormComponentType::DATEFIELD:
2198                 case FormComponentType::TIMEFIELD:
2199                 case FormComponentType::NUMERICFIELD:
2200                 case ControlType::FORMATTEDFIELD:
2201                 case FormComponentType::CURRENCYFIELD:
2202                 case FormComponentType::PATTERNFIELD:
2203                     _rValue = makeAny( (sal_Bool)sal_True );
2204                     break;
2205                 default:
2206                     _rValue = makeAny( (sal_Bool)sal_False );
2207                     break;
2208                 }
2209             }
2210             break;
2211         }
2212     }
2213 
2214     //------------------------------------------------------------------------
impl_shouldExcludeProperty_nothrow(const Property & _rProperty) const2215     bool FormComponentPropertyHandler::impl_shouldExcludeProperty_nothrow( const Property& _rProperty ) const
2216     {
2217         OSL_ENSURE( _rProperty.Handle == m_pInfoService->getPropertyId( _rProperty.Name ),
2218             "FormComponentPropertyHandler::impl_shouldExcludeProperty_nothrow: inconsistency in the property!" );
2219 
2220         if ( _rProperty.Handle == PROPERTY_ID_CONTROLLABEL )
2221             // prevent that this is caught below
2222             return false;
2223 
2224         if  (   ( _rProperty.Type.getTypeClass() == TypeClass_INTERFACE )
2225             ||  ( _rProperty.Type.getTypeClass() == TypeClass_ARRAY )
2226             ||  ( _rProperty.Type.getTypeClass() == TypeClass_UNKNOWN )
2227             )
2228             return true;
2229 
2230         if ( ( _rProperty.Attributes & PropertyAttribute::TRANSIENT ) && ( m_eComponentClass != eDialogControl ) )
2231             // strange enough, dialog controls declare a lot of their properties as transient
2232             return true;
2233 
2234         if ( _rProperty.Attributes & PropertyAttribute::READONLY )
2235             return true;
2236 
2237         switch ( _rProperty.Handle )
2238         {
2239         case PROPERTY_ID_MASTERFIELDS:
2240         case PROPERTY_ID_DETAILFIELDS:
2241             if ( !m_bComponentIsSubForm )
2242                 // no master and detail fields for forms which are no sub forms
2243                 return true;
2244             break;
2245 
2246         case PROPERTY_ID_DATASOURCE:
2247         {
2248             // don't show DataSource if the component is part of an embedded form document
2249             Reference< XConnection > xConn;
2250             if ( isEmbeddedInDatabase( m_xComponent, xConn ) )
2251                 return true;
2252         }
2253         break;
2254 
2255         case PROPERTY_ID_TEXT:
2256             // don't show the "Text" property of formatted fields
2257             if ( ControlType::FORMATTEDFIELD == m_nClassId )
2258                 return true;
2259             break;
2260 
2261         case PROPERTY_ID_FORMATKEY:
2262         case PROPERTY_ID_EFFECTIVE_MIN:
2263         case PROPERTY_ID_EFFECTIVE_MAX:
2264         case PROPERTY_ID_EFFECTIVE_DEFAULT:
2265         case PROPERTY_ID_EFFECTIVE_VALUE:
2266             // only if the set has a formats supplier, too
2267             if  ( !impl_componentHasProperty_throw( PROPERTY_FORMATSSUPPLIER ) )
2268                 return true;
2269             // (form) date and time fields also have a formats supplier, but the format itself
2270             // is reflected in another property
2271             if  (   ( FormComponentType::DATEFIELD == m_nClassId )
2272                 ||  ( FormComponentType::TIMEFIELD == m_nClassId )
2273                 )
2274                 return true;
2275             break;
2276 
2277         case PROPERTY_ID_SCALEIMAGE:
2278             if ( impl_componentHasProperty_throw( PROPERTY_SCALE_MODE ) )
2279                 // ScaleImage is superseded by ScaleMode
2280                 return true;
2281             break;
2282 
2283         case PROPERTY_ID_WRITING_MODE:
2284             if ( !SvtCTLOptions().IsCTLFontEnabled() )
2285                 return true;
2286             break;
2287         }
2288 
2289         sal_uInt32 nPropertyUIFlags = m_pInfoService->getPropertyUIFlags( _rProperty.Handle );
2290 
2291         // don't show experimental properties unless allowed to do so
2292         if ( ( nPropertyUIFlags & PROP_FLAG_EXPERIMENTAL ) != 0 )
2293         {
2294             if ( true ) // TODO
2295                 return true;
2296         }
2297 
2298         // no data properties if no Base is installed. #124939#
2299         // This fix is not intendend to appear on the main trunk. If you find it there,
2300         // please tell me! frank.schoenheit@sun.com
2301         if ( ( nPropertyUIFlags & PROP_FLAG_DATA_PROPERTY ) != 0 )
2302             if ( !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
2303                 return true;
2304 
2305         return false;
2306     }
2307 
2308     //------------------------------------------------------------------------
impl_getRowSet_throw() const2309     Reference< XRowSet > FormComponentPropertyHandler::impl_getRowSet_throw( ) const
2310     {
2311         Reference< XRowSet > xRowSet = m_xRowSet;
2312         if ( !xRowSet.is() )
2313         {
2314             xRowSet.set( m_xComponent, UNO_QUERY );
2315             if ( !xRowSet.is() )
2316             {
2317                 xRowSet = Reference< XRowSet >( m_xObjectParent, UNO_QUERY );
2318                 if ( !xRowSet.is() )
2319                 {
2320                     // are we inspecting a grid column?
2321                     if (Reference< XGridColumnFactory >( m_xObjectParent, UNO_QUERY) .is())
2322                     {   // yes
2323                         Reference< XChild > xParentAsChild( m_xObjectParent, UNO_QUERY );
2324                         if ( xParentAsChild.is() )
2325                             xRowSet = Reference< XRowSet >( xParentAsChild->getParent(), UNO_QUERY );
2326                     }
2327                 }
2328                 if ( !xRowSet.is() )
2329                     xRowSet = m_xRowSet;
2330             }
2331             DBG_ASSERT( xRowSet.is(), "FormComponentPropertyHandler::impl_getRowSet_throw: could not obtain the rowset for the introspectee!" );
2332         }
2333         return xRowSet;
2334     }
2335 
2336     //------------------------------------------------------------------------
impl_getRowSet_nothrow() const2337     Reference< XRowSet > FormComponentPropertyHandler::impl_getRowSet_nothrow( ) const
2338     {
2339         Reference< XRowSet > xReturn;
2340         try
2341         {
2342             xReturn = impl_getRowSet_throw();
2343         }
2344         catch( const Exception& )
2345         {
2346             OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_getRowSet_nothrow: caught an exception!" );
2347         }
2348         return xReturn;
2349     }
2350 
2351     //------------------------------------------------------------------------
impl_initFieldList_nothrow(::std::vector<::rtl::OUString> & _rFieldNames) const2352     void FormComponentPropertyHandler::impl_initFieldList_nothrow( ::std::vector< ::rtl::OUString >& _rFieldNames ) const
2353     {
2354         clearContainer( _rFieldNames );
2355         try
2356         {
2357             WaitCursor aWaitCursor( impl_getDefaultDialogParent_nothrow() );
2358 
2359             Reference< XPreparedStatement >  xStatement;
2360 
2361             // get the form of the control we're inspecting
2362             Reference< XPropertySet > xFormSet( impl_getRowSet_throw(), UNO_QUERY );
2363             if ( !xFormSet.is() )
2364                 return;
2365 
2366             ::rtl::OUString sObjectName;
2367             OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_COMMAND ) >>= sObjectName );
2368             // when there is no command we don't need to ask for columns
2369             if ( sObjectName.getLength() && impl_ensureRowsetConnection_nothrow() )
2370             {
2371                 ::rtl::OUString aDatabaseName;
2372                 OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_DATASOURCE ) >>= aDatabaseName );
2373                 sal_Int32 nObjectType = CommandType::COMMAND;
2374                 OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_COMMANDTYPE ) >>= nObjectType );
2375 
2376                 Sequence< ::rtl::OUString > aFields( ::dbtools::getFieldNamesByCommandDescriptor( m_xRowSetConnection, nObjectType, sObjectName ) );
2377 
2378                 const ::rtl::OUString* pFields = aFields.getConstArray();
2379                 for ( sal_Int32 i = 0; i < aFields.getLength(); ++i, ++pFields )
2380                     _rFieldNames.push_back( *pFields );
2381             }
2382         }
2383         catch (Exception&)
2384         {
2385             DBG_ERROR( "FormComponentPropertyHandler::impl_initFieldList_nothrow: caught an exception!" );
2386         }
2387     }
2388 
2389     //------------------------------------------------------------------------
impl_clearRowsetConnection_nothrow()2390     void FormComponentPropertyHandler::impl_clearRowsetConnection_nothrow()
2391     {
2392         m_xRowSetConnection.clear();
2393     }
2394 
2395     //------------------------------------------------------------------------
impl_displaySQLError_nothrow(const::dbtools::SQLExceptionInfo & _rErrorDescriptor) const2396     void FormComponentPropertyHandler::impl_displaySQLError_nothrow( const ::dbtools::SQLExceptionInfo& _rErrorDescriptor ) const
2397     {
2398         ::dbtools::showError( _rErrorDescriptor, VCLUnoHelper::GetInterface( impl_getDefaultDialogParent_nothrow() ), m_aContext.getLegacyServiceFactory() );
2399     }
2400 
2401     //------------------------------------------------------------------------
impl_ensureRowsetConnection_nothrow() const2402     bool FormComponentPropertyHandler::impl_ensureRowsetConnection_nothrow() const
2403     {
2404         if ( !m_xRowSetConnection.is() )
2405         {
2406             uno::Reference<sdbc::XConnection> xConnection(m_aContext.getContextValueByAsciiName( "ActiveConnection" ),uno::UNO_QUERY);
2407             m_xRowSetConnection.reset(xConnection,::dbtools::SharedConnection::NoTakeOwnership);
2408         }
2409         if ( m_xRowSetConnection.is() )
2410             return true;
2411 
2412         Reference< XRowSet > xRowSet( impl_getRowSet_throw() );
2413         Reference< XPropertySet > xRowSetProps( xRowSet, UNO_QUERY );
2414 
2415         // connect the row set - this is delegated to elsewhere - while observing errors
2416         SQLExceptionInfo aError;
2417         try
2418         {
2419             if ( xRowSetProps.is() )
2420             {
2421                 WaitCursor aWaitCursor( impl_getDefaultDialogParent_nothrow() );
2422                 m_xRowSetConnection = ::dbtools::ensureRowSetConnection( xRowSet, m_aContext.getLegacyServiceFactory(), false );
2423             }
2424         }
2425         catch ( const SQLException& ) { aError = SQLExceptionInfo( ::cppu::getCaughtException() ); }
2426         catch ( const WrappedTargetException& e ) { aError = SQLExceptionInfo( e.TargetException ); }
2427         catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
2428 
2429         // report errors, if necessary
2430         if ( aError.isValid() )
2431         {
2432             ::rtl::OUString sDataSourceName;
2433             try
2434             {
2435                 xRowSetProps->getPropertyValue( PROPERTY_DATASOURCE ) >>= sDataSourceName;
2436             }
2437             catch( const Exception& )
2438             {
2439                 DBG_ERROR( "FormComponentPropertyHandler::impl_ensureRowsetConnection_nothrow: caught an exception during error handling!" );
2440             }
2441             // additional info about what happened
2442             String sInfo( PcrRes( RID_STR_UNABLETOCONNECT ) );
2443             INetURLObject aParser( sDataSourceName );
2444             if ( aParser.GetProtocol() != INET_PROT_NOT_VALID )
2445                 sDataSourceName = aParser.getBase( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
2446             sInfo.SearchAndReplaceAllAscii( "$name$", sDataSourceName );
2447 
2448             SQLContext aContext;
2449             aContext.Message = sInfo;
2450             aContext.NextException = aError.get();
2451             impl_displaySQLError_nothrow( aContext );
2452         }
2453 
2454         return m_xRowSetConnection.is();
2455     }
2456 
2457     //------------------------------------------------------------------------
impl_describeCursorSource_nothrow(LineDescriptor & _out_rProperty,const Reference<XPropertyControlFactory> & _rxControlFactory) const2458     void FormComponentPropertyHandler::impl_describeCursorSource_nothrow( LineDescriptor& _out_rProperty, const Reference< XPropertyControlFactory >& _rxControlFactory ) const
2459     {
2460         try
2461         {
2462             WaitCursor aWaitCursor( impl_getDefaultDialogParent_nothrow() );
2463 
2464             ////////////////////////////////////////////////////////////
2465             // Setzen der UI-Daten
2466             _out_rProperty.DisplayName = m_pInfoService->getPropertyTranslation( PROPERTY_ID_COMMAND );
2467 
2468             _out_rProperty.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( PROPERTY_ID_COMMAND ) );
2469             _out_rProperty.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_SQLCOMMAND);
2470 
2471             ////////////////////////////////////////////////////////////
2472             sal_Int32 nCommandType = CommandType::COMMAND;
2473             impl_getPropertyValue_throw( PROPERTY_COMMANDTYPE ) >>= nCommandType;
2474 
2475             switch ( nCommandType )
2476             {
2477             case CommandType::TABLE:
2478             case CommandType::QUERY:
2479             {
2480                 ::std::vector< ::rtl::OUString > aNames;
2481                 if ( impl_ensureRowsetConnection_nothrow() )
2482                 {
2483                     if ( nCommandType == CommandType::TABLE )
2484                         impl_fillTableNames_throw( aNames );
2485                     else
2486                         impl_fillQueryNames_throw( aNames );
2487                 }
2488                 _out_rProperty.Control = PropertyHandlerHelper::createComboBoxControl( _rxControlFactory, aNames, sal_False, sal_True );
2489             }
2490             break;
2491 
2492             default:
2493                 _out_rProperty.Control = _rxControlFactory->createPropertyControl( PropertyControlType::MultiLineTextField, sal_False );
2494                 break;
2495             }
2496         }
2497         catch (Exception&)
2498         {
2499             DBG_ERROR("FormComponentPropertyHandler::impl_describeCursorSource_nothrow: caught an exception !");
2500         }
2501     }
2502 
2503     //------------------------------------------------------------------------
impl_fillTableNames_throw(::std::vector<::rtl::OUString> & _out_rNames) const2504     void FormComponentPropertyHandler::impl_fillTableNames_throw( ::std::vector< ::rtl::OUString >& _out_rNames ) const
2505     {
2506         OSL_PRECOND( m_xRowSetConnection.is(), "FormComponentPropertyHandler::impl_fillTableNames_throw: need a connection!" );
2507         _out_rNames.resize( 0 );
2508 
2509         Reference< XTablesSupplier > xSupplyTables( m_xRowSetConnection, UNO_QUERY );
2510         Reference< XNameAccess > xTableNames;
2511         if ( xSupplyTables.is() )
2512             xTableNames = xSupplyTables->getTables();
2513         DBG_ASSERT( xTableNames.is(), "FormComponentPropertyHandler::impl_fillTableNames_throw: no way to obtain the tables of the connection!" );
2514         if ( !xTableNames.is() )
2515             return;
2516 
2517         Sequence< ::rtl::OUString> aTableNames = xTableNames->getElementNames();
2518         sal_uInt32 nCount = aTableNames.getLength();
2519         const ::rtl::OUString* pTableNames = aTableNames.getConstArray();
2520 
2521         for ( sal_uInt32 i=0; i<nCount; ++i ,++pTableNames )
2522             _out_rNames.push_back( *pTableNames );
2523     }
2524 
2525     //------------------------------------------------------------------------
impl_fillQueryNames_throw(::std::vector<::rtl::OUString> & _out_rNames) const2526     void FormComponentPropertyHandler::impl_fillQueryNames_throw( ::std::vector< ::rtl::OUString >& _out_rNames ) const
2527     {
2528         OSL_PRECOND( m_xRowSetConnection.is(), "FormComponentPropertyHandler::impl_fillQueryNames_throw: need a connection!" );
2529         _out_rNames.resize( 0 );
2530 
2531         Reference< XQueriesSupplier > xSupplyQueries( m_xRowSetConnection, UNO_QUERY );
2532         Reference< XNameAccess > xQueryNames;
2533         if ( xSupplyQueries.is() )
2534         {
2535             xQueryNames = xSupplyQueries->getQueries();
2536             impl_fillQueryNames_throw(xQueryNames,_out_rNames);
2537         }
2538     }
2539     //------------------------------------------------------------------------
impl_fillQueryNames_throw(const Reference<XNameAccess> & _xQueryNames,::std::vector<::rtl::OUString> & _out_rNames,const::rtl::OUString & _sName) const2540     void FormComponentPropertyHandler::impl_fillQueryNames_throw( const Reference< XNameAccess >& _xQueryNames,::std::vector< ::rtl::OUString >& _out_rNames,const ::rtl::OUString& _sName ) const
2541     {
2542         DBG_ASSERT( _xQueryNames.is(), "FormComponentPropertyHandler::impl_fillQueryNames_throw: no way to obtain the queries of the connection!" );
2543         if ( !_xQueryNames.is() )
2544             return;
2545 
2546         Sequence< ::rtl::OUString> aQueryNames = _xQueryNames->getElementNames();
2547         sal_uInt32 nCount = aQueryNames.getLength();
2548         const ::rtl::OUString* pQueryNames = aQueryNames.getConstArray();
2549         sal_Bool bAdd = _sName.getLength();
2550 
2551         for ( sal_uInt32 i=0; i<nCount; i++, ++pQueryNames )
2552         {
2553             ::rtl::OUStringBuffer sTemp;
2554             if ( bAdd )
2555             {
2556                 sTemp.append(_sName);
2557                 sTemp.appendAscii("/");
2558             }
2559             sTemp.append(*pQueryNames);
2560             Reference< XNameAccess > xSubQueries(_xQueryNames->getByName(*pQueryNames),UNO_QUERY);
2561             if ( xSubQueries.is() )
2562                 impl_fillQueryNames_throw(xSubQueries,_out_rNames,sTemp.makeStringAndClear());
2563             else
2564                 _out_rNames.push_back( sTemp.makeStringAndClear() );
2565         }
2566     }
2567 
2568     //------------------------------------------------------------------------
impl_describeListSourceUI_throw(LineDescriptor & _out_rDescriptor,const Reference<XPropertyControlFactory> & _rxControlFactory) const2569     void FormComponentPropertyHandler::impl_describeListSourceUI_throw( LineDescriptor& _out_rDescriptor, const Reference< XPropertyControlFactory >& _rxControlFactory ) const
2570     {
2571         OSL_PRECOND( m_xComponent.is(), "FormComponentPropertyHandler::impl_describeListSourceUI_throw: no component!" );
2572 
2573         ////////////////////////////////////////////////////////////
2574         // Auslesen des ListSourceTypes
2575         Any aListSourceType( m_xComponent->getPropertyValue( PROPERTY_LISTSOURCETYPE ) );
2576 
2577         sal_Int32 nListSourceType = ListSourceType_VALUELIST;
2578         ::cppu::enum2int( nListSourceType, aListSourceType );
2579 
2580         _out_rDescriptor.DisplayName = m_pInfoService->getPropertyTranslation( PROPERTY_ID_LISTSOURCE );
2581         _out_rDescriptor.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( PROPERTY_ID_LISTSOURCE ) );
2582 
2583         ////////////////////////////////////////////////////////////
2584         // Enums setzen
2585         switch( nListSourceType )
2586         {
2587         case ListSourceType_VALUELIST:
2588             _out_rDescriptor.Control = _rxControlFactory->createPropertyControl( PropertyControlType::StringListField, sal_False );
2589             break;
2590 
2591         case ListSourceType_TABLEFIELDS:
2592         case ListSourceType_TABLE:
2593         case ListSourceType_QUERY:
2594         {
2595             ::std::vector< ::rtl::OUString > aListEntries;
2596             if ( impl_ensureRowsetConnection_nothrow() )
2597             {
2598                 if ( nListSourceType == ListSourceType_QUERY )
2599                     impl_fillQueryNames_throw( aListEntries );
2600                 else
2601                     impl_fillTableNames_throw( aListEntries );
2602             }
2603             _out_rDescriptor.Control = PropertyHandlerHelper::createComboBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
2604         }
2605         break;
2606         case ListSourceType_SQL:
2607         case ListSourceType_SQLPASSTHROUGH:
2608             impl_ensureRowsetConnection_nothrow();
2609             _out_rDescriptor.HasPrimaryButton = m_xRowSetConnection.is();
2610             break;
2611         }
2612     }
2613 
2614     //------------------------------------------------------------------------
impl_dialogListSelection_nothrow(const::rtl::OUString & _rProperty,::osl::ClearableMutexGuard & _rClearBeforeDialog) const2615     bool FormComponentPropertyHandler::impl_dialogListSelection_nothrow( const ::rtl::OUString& _rProperty, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2616     {
2617         OSL_PRECOND( m_pInfoService.get(), "FormComponentPropertyHandler::impl_dialogListSelection_nothrow: no property meta data!" );
2618 
2619         String sPropertyUIName( m_pInfoService->getPropertyTranslation( m_pInfoService->getPropertyId( _rProperty ) ) );
2620         ListSelectionDialog aDialog( impl_getDefaultDialogParent_nothrow(), m_xComponent, _rProperty, sPropertyUIName );
2621         _rClearBeforeDialog.clear();
2622         return ( RET_OK == aDialog.Execute() );
2623     }
2624 
2625     //------------------------------------------------------------------------
impl_dialogFilterOrSort_nothrow(bool _bFilter,::rtl::OUString & _out_rSelectedClause,::osl::ClearableMutexGuard & _rClearBeforeDialog) const2626     bool FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow( bool _bFilter, ::rtl::OUString& _out_rSelectedClause, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2627     {
2628         OSL_PRECOND( Reference< XRowSet >( m_xComponent, UNO_QUERY ).is(),
2629             "FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow: to be called for forms only!" );
2630 
2631         _out_rSelectedClause = ::rtl::OUString();
2632         bool bSuccess = false;
2633         SQLExceptionInfo aErrorInfo;
2634         try
2635         {
2636             if ( !impl_ensureRowsetConnection_nothrow() )
2637                 return false;
2638 
2639             // get a composer for the statement which the form is currently based on
2640             Reference< XSingleSelectQueryComposer > xComposer( ::dbtools::getCurrentSettingsComposer( m_xComponent, m_aContext.getLegacyServiceFactory() ) );
2641             OSL_ENSURE( xComposer.is(), "FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow: could not obtain a composer!" );
2642             if ( !xComposer.is() )
2643                 return false;
2644 
2645             ::rtl::OUString sPropertyUIName( m_pInfoService->getPropertyTranslation( _bFilter ? PROPERTY_ID_FILTER : PROPERTY_ID_SORT ) );
2646 
2647             const sal_Char* pAsciiServiceName = _bFilter ? "com.sun.star.sdb.FilterDialog" : "com.sun.star.sdb.OrderDialog";
2648 
2649             // create the dialog
2650             Reference< XExecutableDialog > xDialog;
2651             if ( !m_aContext.createComponent( pAsciiServiceName, xDialog ) )
2652             {
2653                 ShowServiceNotAvailableError( impl_getDefaultDialogParent_nothrow(), ::rtl::OUString::createFromAscii( pAsciiServiceName ), sal_True );
2654                 return false;
2655             }
2656 
2657             // initialize the dialog
2658             Reference< XPropertySet > xDialogProps( xDialog, UNO_QUERY_THROW );
2659             xDialogProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "QueryComposer" ) ), makeAny( xComposer ) );
2660             xDialogProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RowSet" ) ),        makeAny( m_xComponent ) );
2661             xDialogProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ) ),  makeAny( VCLUnoHelper::GetInterface( impl_getDefaultDialogParent_nothrow() ) ) );
2662             xDialogProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),         makeAny( sPropertyUIName ) );
2663 
2664             _rClearBeforeDialog.clear();
2665             bSuccess = ( xDialog->execute() != 0 );
2666             if ( bSuccess )
2667                 _out_rSelectedClause = _bFilter ? xComposer->getFilter() : xComposer->getOrder();
2668         }
2669         catch (SQLContext& e) { aErrorInfo = e; }
2670         catch (SQLWarning& e) { aErrorInfo = e; }
2671         catch (SQLException& e) { aErrorInfo = e; }
2672         catch( const Exception& )
2673         {
2674             OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow: caught an exception!" );
2675         }
2676 
2677         if ( aErrorInfo.isValid() )
2678             impl_displaySQLError_nothrow( aErrorInfo );
2679 
2680         return bSuccess;
2681     }
2682 
2683     //------------------------------------------------------------------------
impl_dialogLinkedFormFields_nothrow(::osl::ClearableMutexGuard & _rClearBeforeDialog) const2684     bool FormComponentPropertyHandler::impl_dialogLinkedFormFields_nothrow( ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2685     {
2686         Reference< XForm > xDetailForm( m_xComponent, UNO_QUERY );
2687         Reference< XForm > xMasterForm( m_xObjectParent, UNO_QUERY );
2688         uno::Reference<beans::XPropertySet> xMasterProp(m_xObjectParent,uno::UNO_QUERY);
2689         OSL_PRECOND( xDetailForm.is() && xMasterForm.is(), "FormComponentPropertyHandler::impl_dialogLinkedFormFields_nothrow: no forms!" );
2690         if ( !xDetailForm.is() || !xMasterForm.is() )
2691             return false;
2692 
2693 
2694         FormLinkDialog aDialog( impl_getDefaultDialogParent_nothrow(), m_xComponent, xMasterProp, m_aContext.getLegacyServiceFactory() );
2695         _rClearBeforeDialog.clear();
2696         return ( RET_OK == aDialog.Execute() );
2697     }
2698 
2699     //------------------------------------------------------------------------
impl_dialogFormatting_nothrow(Any & _out_rNewValue,::osl::ClearableMutexGuard & _rClearBeforeDialog) const2700     bool FormComponentPropertyHandler::impl_dialogFormatting_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2701     {
2702         bool bChanged = false;
2703         try
2704         {
2705             // create the itemset for the dialog
2706             SfxItemSet aCoreSet(SFX_APP()->GetPool(),
2707                 SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_VALUE,
2708                 SID_ATTR_NUMBERFORMAT_INFO, SID_ATTR_NUMBERFORMAT_INFO,
2709                 0);     // ripped this somewhere ... don't understand it :(
2710 
2711             // get the number formats supplier
2712             Reference< XNumberFormatsSupplier >  xSupplier;
2713             m_xComponent->getPropertyValue( PROPERTY_FORMATSSUPPLIER ) >>= xSupplier;
2714 
2715             DBG_ASSERT(xSupplier.is(), "FormComponentPropertyHandler::impl_dialogFormatting_nothrow: invalid call !" );
2716             Reference< XUnoTunnel > xTunnel( xSupplier, UNO_QUERY_THROW );
2717             SvNumberFormatsSupplierObj* pSupplier =
2718                 reinterpret_cast< SvNumberFormatsSupplierObj* >( xTunnel->getSomething( SvNumberFormatsSupplierObj::getUnoTunnelId() ) );
2719             DBG_ASSERT( pSupplier != NULL, "FormComponentPropertyHandler::impl_dialogFormatting_nothrow: invalid call !" );
2720 
2721             sal_Int32 nFormatKey = 0;
2722             impl_getPropertyValue_throw( PROPERTY_FORMATKEY ) >>= nFormatKey;
2723             aCoreSet.Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, nFormatKey ) );
2724 
2725             SvNumberFormatter* pFormatter = pSupplier->GetNumberFormatter();
2726             double dPreviewVal = OFormatSampleControl::getPreviewValue(pFormatter,nFormatKey);
2727             SvxNumberInfoItem aFormatter( pFormatter, dPreviewVal, String( PcrRes( RID_STR_TEXT_FORMAT ) ), SID_ATTR_NUMBERFORMAT_INFO );
2728             aCoreSet.Put( aFormatter );
2729 
2730             // a tab dialog with a single page
2731             ::std::auto_ptr< SfxSingleTabDialog > pDialog( new SfxSingleTabDialog( impl_getDefaultDialogParent_nothrow(), aCoreSet, 0 ) );
2732             SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
2733             DBG_ASSERT( pFact, "CreateFactory fail!" );
2734             ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc( RID_SVXPAGE_NUMBERFORMAT );
2735             if ( !fnCreatePage )
2736                 throw RuntimeException();   // caught below
2737 
2738             SfxTabPage* pPage = (*fnCreatePage)( pDialog.get(), aCoreSet );
2739             pDialog->SetTabPage( pPage );
2740 
2741             _rClearBeforeDialog.clear();
2742             if ( RET_OK == pDialog->Execute() )
2743             {
2744                 const SfxItemSet* pResult = pDialog->GetOutputItemSet();
2745 
2746                 const SfxPoolItem* pItem = pResult->GetItem( SID_ATTR_NUMBERFORMAT_INFO );
2747                 const SvxNumberInfoItem* pInfoItem = dynamic_cast< const SvxNumberInfoItem* >( pItem );
2748                 if (pInfoItem && pInfoItem->GetDelCount())
2749                 {
2750                     const sal_uInt32* pDeletedKeys = pInfoItem->GetDelArray();
2751 
2752                     for (sal_uInt16 i=0; i< pInfoItem->GetDelCount(); ++i, ++pDeletedKeys)
2753                         pFormatter->DeleteEntry(*pDeletedKeys);
2754                 }
2755 
2756                 pItem = NULL;
2757                 if ( SFX_ITEM_SET == pResult->GetItemState( SID_ATTR_NUMBERFORMAT_VALUE, sal_False, &pItem ) )
2758                 {
2759                     _out_rNewValue <<= (sal_Int32)( static_cast< const SfxUInt32Item* >( pItem )->GetValue() );
2760                     bChanged = true;
2761                 }
2762             }
2763         }
2764         catch( const Exception& )
2765         {
2766             OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_dialogFormatting_nothrow: : caught an exception!" );
2767         }
2768         return bChanged;
2769     }
2770 
2771     //------------------------------------------------------------------------
impl_browseForImage_nothrow(Any & _out_rNewValue,::osl::ClearableMutexGuard & _rClearBeforeDialog) const2772     bool FormComponentPropertyHandler::impl_browseForImage_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2773     {
2774         bool bIsLink = true;// reflect the legacy behavior
2775         ::rtl::OUString aStrTrans = m_pInfoService->getPropertyTranslation( PROPERTY_ID_IMAGE_URL );
2776 
2777         ::sfx2::FileDialogHelper aFileDlg(SFXWB_GRAPHIC);
2778 
2779         aFileDlg.SetTitle(aStrTrans);
2780         // non-linked images ( e.g. those located in the document
2781         // stream ) cannot *currently* be handled by openoffice basic dialogs.
2782         bool bHandleNonLink = ( m_eComponentClass == eFormControl );
2783 
2784         Reference< XFilePickerControlAccess > xController(aFileDlg.GetFilePicker(), UNO_QUERY);
2785         DBG_ASSERT(xController.is(), "FormComponentPropertyHandler::impl_browseForImage_nothrow: missing the controller interface on the file picker!");
2786         if (xController.is())
2787         {
2788             // do a preview by default
2789             xController->setValue(ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0, ::cppu::bool2any(sal_True));
2790 
2791             xController->setValue(ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, ::cppu::bool2any(bIsLink));
2792             xController->enableControl(ExtendedFilePickerElementIds::CHECKBOX_LINK, bHandleNonLink );
2793 
2794         }
2795 
2796         ::rtl::OUString sCurValue;
2797         OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_IMAGE_URL ) >>= sCurValue );
2798         if ( sCurValue.getLength() != 0 && sCurValue.compareToAscii(GRAPHOBJ_URLPREFIX, RTL_CONSTASCII_LENGTH(GRAPHOBJ_URLPREFIX) ) != 0 )
2799         {
2800             aFileDlg.SetDisplayDirectory( sCurValue );
2801             // TODO: need to set the display directory _and_ the default name
2802         }
2803 
2804         _rClearBeforeDialog.clear();
2805         bool bSuccess = ( 0 == aFileDlg.Execute() );
2806         if ( bSuccess )
2807         {
2808             if ( bHandleNonLink && xController.is() )
2809             {
2810                 xController->getValue(ExtendedFilePickerElementIds::CHECKBOX_LINK, 0) >>= bIsLink;
2811             }
2812             if ( !bIsLink )
2813             {
2814                 Graphic aGraphic;
2815                 aFileDlg.GetGraphic( aGraphic );
2816 
2817                 Reference< graphic::XGraphicObject > xGrfObj = graphic::GraphicObject::create( m_aContext.getUNOContext() );
2818                 xGrfObj->setGraphic( aGraphic.GetXGraphic() );
2819 
2820 
2821                 _out_rNewValue <<= xGrfObj;
2822 
2823             }
2824             else
2825                 _out_rNewValue <<= (::rtl::OUString)aFileDlg.GetPath();
2826         }
2827         return bSuccess;
2828     }
2829 
2830     //------------------------------------------------------------------------
impl_browseForTargetURL_nothrow(Any & _out_rNewValue,::osl::ClearableMutexGuard & _rClearBeforeDialog) const2831     bool FormComponentPropertyHandler::impl_browseForTargetURL_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2832     {
2833         ::sfx2::FileDialogHelper aFileDlg( WB_3DLOOK );
2834 
2835         ::rtl::OUString sURL;
2836         OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_TARGET_URL ) >>= sURL );
2837         INetURLObject aParser( sURL );
2838         if ( INET_PROT_FILE == aParser.GetProtocol() )
2839             // set the initial directory only for file-URLs. Everything else
2840             // is considered to be potentially expensive
2841             // 106126 - 2002/12/10 - fs@openoffice.org
2842             aFileDlg.SetDisplayDirectory( sURL );
2843 
2844         _rClearBeforeDialog.clear();
2845         bool bSuccess = ( 0 == aFileDlg.Execute() );
2846         if ( bSuccess )
2847             _out_rNewValue <<= (::rtl::OUString)aFileDlg.GetPath();
2848         return bSuccess;
2849     }
2850 
2851     //------------------------------------------------------------------------
impl_executeFontDialog_nothrow(Any & _out_rNewValue,::osl::ClearableMutexGuard & _rClearBeforeDialog) const2852     bool FormComponentPropertyHandler::impl_executeFontDialog_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2853     {
2854         bool bSuccess = false;
2855 
2856         // create an item set for use with the dialog
2857         SfxItemSet* pSet = NULL;
2858         SfxItemPool* pPool = NULL;
2859         SfxPoolItem** pDefaults = NULL;
2860         ControlCharacterDialog::createItemSet(pSet, pPool, pDefaults);
2861         ControlCharacterDialog::translatePropertiesToItems(m_xComponent, pSet);
2862 
2863         {   // do this in an own block. The dialog needs to be destroyed before we call
2864             // destroyItemSet
2865             ControlCharacterDialog aDlg( impl_getDefaultDialogParent_nothrow(), *pSet );
2866             _rClearBeforeDialog.clear();
2867             if ( RET_OK == aDlg.Execute() )
2868             {
2869                 const SfxItemSet* pOut = aDlg.GetOutputItemSet();
2870                 if ( pOut )
2871                 {
2872                     Sequence< NamedValue > aFontPropertyValues;
2873                     ControlCharacterDialog::translateItemsToProperties( *pOut, aFontPropertyValues );
2874                     _out_rNewValue <<= aFontPropertyValues;
2875                     bSuccess = true;
2876                 }
2877             }
2878         }
2879 
2880         ControlCharacterDialog::destroyItemSet(pSet, pPool, pDefaults);
2881         return bSuccess;
2882     }
2883 
2884     //------------------------------------------------------------------------
impl_browseForDatabaseDocument_throw(Any & _out_rNewValue,::osl::ClearableMutexGuard & _rClearBeforeDialog) const2885     bool FormComponentPropertyHandler::impl_browseForDatabaseDocument_throw( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2886     {
2887         ::sfx2::FileDialogHelper aFileDlg(WB_3DLOOK|WB_OPEN,::String::CreateFromAscii("sdatabase"));
2888 
2889         ::rtl::OUString sDataSource;
2890         OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_DATASOURCE ) >>= sDataSource );
2891         INetURLObject aParser( sDataSource );
2892         if ( INET_PROT_FILE == aParser.GetProtocol() )
2893             // set the initial directory only for file-URLs. Everything else
2894             // is considered to be potentially expensive
2895             // 106126 - 2002/12/10 - fs@openoffice.org
2896             aFileDlg.SetDisplayDirectory( sDataSource );
2897 
2898         const String s_sDatabaseType = String::CreateFromAscii("StarOffice XML (Base)");
2899         const SfxFilter* pFilter = SfxFilter::GetFilterByName( s_sDatabaseType);
2900         OSL_ENSURE(pFilter,"Filter: StarOffice XML (Base) could not be found!");
2901         if ( pFilter )
2902         {
2903             aFileDlg.SetCurrentFilter(pFilter->GetUIName());
2904             //aFileDlg.AddFilter(pFilter->GetFilterName(),pFilter->GetDefaultExtension());
2905         }
2906 
2907         _rClearBeforeDialog.clear();
2908         bool bSuccess = ( 0 == aFileDlg.Execute() );
2909         if ( bSuccess )
2910             _out_rNewValue <<= (::rtl::OUString)aFileDlg.GetPath();
2911         return bSuccess;
2912     }
2913 
2914     //------------------------------------------------------------------------
impl_dialogColorChooser_throw(sal_Int32 _nColorPropertyId,Any & _out_rNewValue,::osl::ClearableMutexGuard & _rClearBeforeDialog) const2915     bool FormComponentPropertyHandler::impl_dialogColorChooser_throw( sal_Int32 _nColorPropertyId, Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2916     {
2917         sal_Int32 nColor = 0;
2918         OSL_VERIFY( impl_getPropertyValue_throw( impl_getPropertyNameFromId_nothrow( _nColorPropertyId ) ) >>= nColor );
2919         ::Color aColor( nColor );
2920         SvColorDialog aColorDlg( impl_getDefaultDialogParent_nothrow() );
2921         aColorDlg.SetColor( aColor );
2922 
2923         _rClearBeforeDialog.clear();
2924         if ( !aColorDlg.Execute() )
2925             return false;
2926 
2927         aColor = aColorDlg.GetColor();
2928         nColor = aColor.GetColor();
2929         _out_rNewValue <<= (sal_Int32)nColor;
2930         return true;
2931     }
2932 
2933     //------------------------------------------------------------------------
impl_dialogChooseLabelControl_nothrow(Any & _out_rNewValue,::osl::ClearableMutexGuard & _rClearBeforeDialog) const2934     bool FormComponentPropertyHandler::impl_dialogChooseLabelControl_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2935     {
2936         OSelectLabelDialog dlgSelectLabel( impl_getDefaultDialogParent_nothrow(), m_xComponent );
2937         _rClearBeforeDialog.clear();
2938         bool bSuccess = ( RET_OK == dlgSelectLabel.Execute() );
2939         if ( bSuccess )
2940             _out_rNewValue <<= dlgSelectLabel.GetSelected();
2941         return bSuccess;
2942     }
2943 
2944     //------------------------------------------------------------------------
impl_getContextControlContainer_nothrow() const2945     Reference< XControlContainer > FormComponentPropertyHandler::impl_getContextControlContainer_nothrow() const
2946     {
2947         Reference< XControlContainer > xControlContext(
2948             m_aContext.getContextValueByAsciiName( "ControlContext" ),
2949             UNO_QUERY );
2950         return xControlContext;
2951     }
2952 
2953     //------------------------------------------------------------------------
impl_dialogChangeTabOrder_nothrow(::osl::ClearableMutexGuard & _rClearBeforeDialog) const2954     bool FormComponentPropertyHandler::impl_dialogChangeTabOrder_nothrow( ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
2955     {
2956         OSL_PRECOND( impl_getContextControlContainer_nothrow().is(), "FormComponentPropertyHandler::impl_dialogChangeTabOrder_nothrow: invalid control context!" );
2957 
2958         Reference< XTabControllerModel > xTabControllerModel( impl_getRowSet_nothrow(), UNO_QUERY );
2959         TabOrderDialog aDialog(
2960             impl_getDefaultDialogParent_nothrow(),
2961             xTabControllerModel,
2962             impl_getContextControlContainer_nothrow(),
2963             m_aContext.getLegacyServiceFactory()
2964         );
2965         _rClearBeforeDialog.clear();
2966         return ( RET_OK == aDialog.Execute() );
2967     }
2968 
2969     //------------------------------------------------------------------------
2970     namespace
2971     {
2972         //--------------------------------------------------------------------
2973         //- ISQLCommandPropertyUI
2974         //--------------------------------------------------------------------
2975         class ISQLCommandPropertyUI : public ISQLCommandAdapter
2976         {
2977         public:
2978             /** returns the empty-string-terminated list of names of properties
2979                 whose UI is to be disabled while the SQL command property is
2980                 being edited.
2981             */
2982             virtual ::rtl::OUString*    getPropertiesToDisable() = 0;
2983         };
2984 
2985         //--------------------------------------------------------------------
2986         //- SQLCommandPropertyUI
2987         //--------------------------------------------------------------------
2988         class SQLCommandPropertyUI : public ISQLCommandPropertyUI
2989         {
2990         protected:
SQLCommandPropertyUI(const Reference<XPropertySet> & _rxObject)2991             SQLCommandPropertyUI( const Reference< XPropertySet >& _rxObject )
2992                 :m_xObject( _rxObject )
2993             {
2994                 if ( !m_xObject.is() )
2995                     throw NullPointerException();
2996             }
2997 
acquire()2998             virtual oslInterlockedCount SAL_CALL acquire()
2999             {
3000                 return osl_incrementInterlockedCount( &m_refCount );
3001             }
3002 
release()3003             virtual oslInterlockedCount SAL_CALL release()
3004             {
3005                 if ( 0 == osl_decrementInterlockedCount( &m_refCount ) )
3006                 {
3007                     delete this;
3008                     return 0;
3009                 }
3010                 return m_refCount;
3011             }
3012 
3013         protected:
3014             Reference< XPropertySet >   m_xObject;
3015 
3016         private:
3017             oslInterlockedCount         m_refCount;
3018         };
3019 
3020         //--------------------------------------------------------------------
3021         //- FormSQLCommandUI - declaration
3022         //--------------------------------------------------------------------
3023         class FormSQLCommandUI : public SQLCommandPropertyUI
3024         {
3025         public:
3026             FormSQLCommandUI( const Reference< XPropertySet >& _rxForm );
3027 
3028             // ISQLCommandAdapter
3029             virtual ::rtl::OUString getSQLCommand() const;
3030             virtual sal_Bool        getEscapeProcessing() const;
3031             virtual void            setSQLCommand( const ::rtl::OUString& _rCommand ) const;
3032             virtual void            setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const;
3033 
3034             // ISQLCommandPropertyUI
3035             virtual ::rtl::OUString*    getPropertiesToDisable();
3036         };
3037 
3038         //--------------------------------------------------------------------
3039         //- FormSQLCommandUI - implementation
3040         //--------------------------------------------------------------------
3041         //....................................................................
FormSQLCommandUI(const Reference<XPropertySet> & _rxForm)3042         FormSQLCommandUI::FormSQLCommandUI( const Reference< XPropertySet >& _rxForm )
3043             :SQLCommandPropertyUI( _rxForm )
3044         {
3045         }
3046 
3047         //....................................................................
getSQLCommand() const3048         ::rtl::OUString FormSQLCommandUI::getSQLCommand() const
3049         {
3050             ::rtl::OUString sCommand;
3051             OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_COMMAND ) >>= sCommand );
3052             return sCommand;
3053         }
3054 
3055         //....................................................................
getEscapeProcessing() const3056         sal_Bool FormSQLCommandUI::getEscapeProcessing() const
3057         {
3058             sal_Bool bEscapeProcessing( sal_False );
3059             OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bEscapeProcessing );
3060             return bEscapeProcessing;
3061         }
3062 
3063         //....................................................................
setSQLCommand(const::rtl::OUString & _rCommand) const3064         void FormSQLCommandUI::setSQLCommand( const ::rtl::OUString& _rCommand ) const
3065         {
3066             m_xObject->setPropertyValue( PROPERTY_COMMAND, makeAny( _rCommand ) );
3067         }
3068 
3069         //....................................................................
setEscapeProcessing(const sal_Bool _bEscapeProcessing) const3070         void FormSQLCommandUI::setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const
3071         {
3072             m_xObject->setPropertyValue( PROPERTY_ESCAPE_PROCESSING, makeAny( _bEscapeProcessing ) );
3073         }
3074 
3075         //....................................................................
getPropertiesToDisable()3076         ::rtl::OUString* FormSQLCommandUI::getPropertiesToDisable()
3077         {
3078             static ::rtl::OUString s_aCommandProps[] = {
3079                 PROPERTY_DATASOURCE,
3080                 PROPERTY_COMMAND,
3081                 PROPERTY_COMMANDTYPE,
3082                 PROPERTY_ESCAPE_PROCESSING,
3083                 ::rtl::OUString()
3084             };
3085             return s_aCommandProps;
3086         }
3087         //--------------------------------------------------------------------
3088         //- ValueListCommandUI - declaration
3089         //--------------------------------------------------------------------
3090         class ValueListCommandUI : public SQLCommandPropertyUI
3091         {
3092         public:
3093             ValueListCommandUI( const Reference< XPropertySet >& _rxListOrCombo );
3094 
3095             // ISQLCommandAdapter
3096             virtual ::rtl::OUString getSQLCommand() const;
3097             virtual sal_Bool        getEscapeProcessing() const;
3098             virtual void            setSQLCommand( const ::rtl::OUString& _rCommand ) const;
3099             virtual void            setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const;
3100 
3101             // ISQLCommandPropertyUI
3102             virtual ::rtl::OUString*    getPropertiesToDisable();
3103         private:
3104             mutable bool    m_bPropertyValueIsList;
3105         };
3106 
3107         //--------------------------------------------------------------------
3108         //- ValueListCommandUI - implementation
3109         //--------------------------------------------------------------------
3110         //....................................................................
ValueListCommandUI(const Reference<XPropertySet> & _rxListOrCombo)3111         ValueListCommandUI::ValueListCommandUI( const Reference< XPropertySet >& _rxListOrCombo )
3112             :SQLCommandPropertyUI( _rxListOrCombo )
3113             ,m_bPropertyValueIsList( false )
3114         {
3115         }
3116 
3117         //....................................................................
getSQLCommand() const3118         ::rtl::OUString ValueListCommandUI::getSQLCommand() const
3119         {
3120             ::rtl::OUString sValue;
3121             m_bPropertyValueIsList = false;
3122 
3123             // for combo boxes, the property is a mere string
3124             Any aValue( m_xObject->getPropertyValue( PROPERTY_LISTSOURCE ) );
3125             if ( aValue >>= sValue )
3126                 return sValue;
3127 
3128             Sequence< ::rtl::OUString > aValueList;
3129             if ( aValue >>= aValueList )
3130             {
3131                 m_bPropertyValueIsList = true;
3132                 if ( aValueList.getLength() )
3133                     sValue = aValueList[0];
3134                 return sValue;
3135             }
3136 
3137             OSL_ENSURE( false, "ValueListCommandUI::getSQLCommand: unexpected property type!" );
3138             return sValue;
3139         }
3140 
3141         //....................................................................
getEscapeProcessing() const3142         sal_Bool ValueListCommandUI::getEscapeProcessing() const
3143         {
3144             enum ListSourceType eType( ListSourceType_SQL );
3145             OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_LISTSOURCETYPE ) >>= eType );
3146             OSL_ENSURE( ( eType == ListSourceType_SQL ) || ( eType == ListSourceType_SQLPASSTHROUGH ),
3147                 "ValueListCommandUI::getEscapeProcessing: unexpected list source type!" );
3148             return ( eType == ListSourceType_SQL );
3149         }
3150 
3151         //....................................................................
setSQLCommand(const::rtl::OUString & _rCommand) const3152         void ValueListCommandUI::setSQLCommand( const ::rtl::OUString& _rCommand ) const
3153         {
3154             Any aValue;
3155             if ( m_bPropertyValueIsList )
3156                 aValue <<= Sequence< ::rtl::OUString >( &_rCommand, 1 );
3157             else
3158                 aValue <<= _rCommand;
3159             m_xObject->setPropertyValue( PROPERTY_LISTSOURCE, aValue );
3160         }
3161 
3162         //....................................................................
setEscapeProcessing(const sal_Bool _bEscapeProcessing) const3163         void ValueListCommandUI::setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const
3164         {
3165             m_xObject->setPropertyValue( PROPERTY_LISTSOURCETYPE, makeAny(
3166                 _bEscapeProcessing ? ListSourceType_SQL : ListSourceType_SQLPASSTHROUGH ) );
3167         }
3168 
3169         //....................................................................
getPropertiesToDisable()3170         ::rtl::OUString* ValueListCommandUI::getPropertiesToDisable()
3171         {
3172             static ::rtl::OUString s_aListSourceProps[] = {
3173                 PROPERTY_LISTSOURCETYPE,
3174                 PROPERTY_LISTSOURCE,
3175                 ::rtl::OUString()
3176             };
3177             return s_aListSourceProps;
3178         }
3179     }
3180 
3181     //------------------------------------------------------------------------
impl_doDesignSQLCommand_nothrow(const Reference<XObjectInspectorUI> & _rxInspectorUI,PropertyId _nDesignForProperty)3182     bool FormComponentPropertyHandler::impl_doDesignSQLCommand_nothrow( const Reference< XObjectInspectorUI >& _rxInspectorUI, PropertyId _nDesignForProperty )
3183     {
3184         try
3185         {
3186             if ( m_xCommandDesigner.is() )
3187             {
3188                 if ( m_xCommandDesigner->isActive() )
3189                 {
3190                     m_xCommandDesigner->raise();
3191                     return true;
3192                 }
3193                 m_xCommandDesigner->dispose();
3194                 m_xCommandDesigner.set( NULL );
3195             }
3196 
3197             if ( !impl_ensureRowsetConnection_nothrow() )
3198                 return false;
3199 
3200             Reference< XPropertySet > xComponentProperties( m_xComponent, UNO_QUERY_THROW );
3201 
3202             ::rtl::Reference< ISQLCommandPropertyUI > xCommandUI;
3203             switch ( _nDesignForProperty )
3204             {
3205             case PROPERTY_ID_COMMAND:
3206                 xCommandUI = new FormSQLCommandUI( xComponentProperties );
3207                 break;
3208             case PROPERTY_ID_LISTSOURCE:
3209                 xCommandUI = new ValueListCommandUI( xComponentProperties );
3210                 break;
3211             default:
3212                 OSL_ENSURE( false, "FormComponentPropertyHandler::OnDesignerClosed: invalid property id!" );
3213                 return false;
3214             }
3215 
3216             m_xCommandDesigner.set( new SQLCommandDesigner( m_aContext.getUNOContext(), xCommandUI.get(), m_xRowSetConnection, LINK( this, FormComponentPropertyHandler, OnDesignerClosed ) ) );
3217 
3218             DBG_ASSERT( _rxInspectorUI.is(), "FormComponentPropertyHandler::OnDesignerClosed: no access to the property browser ui!" );
3219             if ( m_xCommandDesigner->isActive() && _rxInspectorUI.is() )
3220             {
3221                 m_xBrowserUI = _rxInspectorUI;
3222                 // disable everything which would affect this property
3223                 const ::rtl::OUString* pToDisable = xCommandUI->getPropertiesToDisable();
3224                 while ( pToDisable->getLength() )
3225                 {
3226                     m_xBrowserUI->enablePropertyUIElements( *pToDisable++, PropertyLineElement::All, sal_False );
3227                 }
3228 
3229                 // but enable the browse button for the property itself - so it can be used to raise the query designer
3230                 ::rtl::OUString sPropertyName( impl_getPropertyNameFromId_nothrow( _nDesignForProperty ) );
3231                 m_xBrowserUI->enablePropertyUIElements( sPropertyName, PropertyLineElement::PrimaryButton, sal_True );
3232             }
3233         }
3234         catch( const Exception& )
3235         {
3236             DBG_UNHANDLED_EXCEPTION();
3237         }
3238         return m_xCommandDesigner.is();
3239     }
3240 
3241     //------------------------------------------------------------------------
3242     IMPL_LINK( FormComponentPropertyHandler, OnDesignerClosed, void*, /*NOTINTERESTEDIN*/ )
3243     {
3244         OSL_ENSURE( m_xBrowserUI.is() && m_xCommandDesigner.is(), "FormComponentPropertyHandler::OnDesignerClosed: too many NULLs!" );
3245         if ( m_xBrowserUI.is() && m_xCommandDesigner.is() )
3246         {
3247             try
3248             {
3249                 ::rtl::Reference< ISQLCommandPropertyUI > xCommandUI(
3250                     dynamic_cast< ISQLCommandPropertyUI* >( m_xCommandDesigner->getPropertyAdapter().get() ) );
3251                 if ( !xCommandUI.is() )
3252                     throw NullPointerException();
3253 
3254                 const ::rtl::OUString* pToEnable = xCommandUI->getPropertiesToDisable();
3255                 while ( pToEnable->getLength() )
3256                 {
3257                     m_xBrowserUI->enablePropertyUIElements( *pToEnable++, PropertyLineElement::All, sal_True );
3258                 }
3259             }
3260             catch( const Exception& )
3261             {
3262                 DBG_UNHANDLED_EXCEPTION();
3263             }
3264         }
3265 
3266         return 0L;
3267     }
3268 
3269     //------------------------------------------------------------------------
impl_hasValidDataSourceSignature_nothrow(const Reference<XPropertySet> & _xFormProperties,bool _bAllowEmptyDataSourceName)3270     bool FormComponentPropertyHandler::impl_hasValidDataSourceSignature_nothrow( const Reference< XPropertySet >& _xFormProperties, bool _bAllowEmptyDataSourceName ) SAL_THROW(())
3271     {
3272         bool bHas = false;
3273         if ( _xFormProperties.is() )
3274         {
3275             try
3276             {
3277                 ::rtl::OUString sPropertyValue;
3278                 // first, we need the name of an existent data source
3279                 if ( _xFormProperties->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATASOURCE) )
3280                     _xFormProperties->getPropertyValue( PROPERTY_DATASOURCE ) >>= sPropertyValue;
3281                 bHas = ( sPropertyValue.getLength() != 0 ) || _bAllowEmptyDataSourceName;
3282 
3283                 // then, the command should not be empty
3284                 if ( bHas )
3285                 {
3286                     if ( _xFormProperties->getPropertySetInfo()->hasPropertyByName(PROPERTY_COMMAND) )
3287                         _xFormProperties->getPropertyValue( PROPERTY_COMMAND ) >>= sPropertyValue;
3288                     bHas = ( sPropertyValue.getLength() != 0 );
3289                 }
3290             }
3291             catch( const Exception& )
3292             {
3293                 OSL_ENSURE( false, "FormComponentPropertyHandler::impl_hasValidDataSourceSignature_nothrow: caught an exception!" );
3294             }
3295         }
3296         return bHas;
3297     }
3298     //------------------------------------------------------------------------
impl_getDocumentURL_nothrow() const3299     ::rtl::OUString FormComponentPropertyHandler::impl_getDocumentURL_nothrow() const
3300     {
3301         ::rtl::OUString sURL;
3302         try
3303         {
3304             Reference< XModel > xDocument( impl_getContextDocument_nothrow() );
3305             if ( xDocument.is() )
3306                 sURL = xDocument->getURL();
3307         }
3308         catch( const Exception& )
3309         {
3310             DBG_UNHANDLED_EXCEPTION();
3311         }
3312         return sURL;
3313     }
3314     // -------------------------------------------------------------------------
createArrayHelper() const3315     ::cppu::IPropertyArrayHelper* FormComponentPropertyHandler::createArrayHelper( ) const
3316     {
3317         uno::Sequence< beans::Property > aProps;
3318         describeProperties(aProps);
3319         return new ::cppu::OPropertyArrayHelper(aProps);
3320 
3321     }
3322     // -------------------------------------------------------------------------
getInfoHelper()3323     ::cppu::IPropertyArrayHelper & FormComponentPropertyHandler::getInfoHelper()
3324     {
3325         return *const_cast<FormComponentPropertyHandler*>(this)->getArrayHelper();
3326     }
3327     // -----------------------------------------------------------------------------
getPropertySetInfo()3328     uno::Reference< beans::XPropertySetInfo > SAL_CALL FormComponentPropertyHandler::getPropertySetInfo(  )
3329     {
3330         return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
3331     }
3332 
3333 //........................................................................
3334 } // namespace pcr
3335 //........................................................................
3336