1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #ifndef EXTENSIONS_SOURCE_PROPCTRLR_FORMCOMPONENTHANDLER_HXX
30 #define EXTENSIONS_SOURCE_PROPCTRLR_FORMCOMPONENTHANDLER_HXX
32 #include "propertyhandler.hxx"
33 #include "sqlcommanddesign.hxx"
34 #include "pcrcommon.hxx"
35 #include <comphelper/uno3.hxx>
36 #include <comphelper/proparrhlp.hxx>
37 #include <comphelper/propertycontainer.hxx>
38 /** === begin UNO includes === **/
39 #include <com/sun/star/frame/XModel.hpp>
40 #include <com/sun/star/beans/XPropertyState.hpp>
41 #include <com/sun/star/sdbc/XRowSet.hpp>
42 #include <com/sun/star/awt/XControlContainer.hpp>
43 #include <com/sun/star/form/XForm.hpp>
44 /** === end UNO includes === **/
45 #include <tools/fldunit.hxx>
46 #include <vcl/waitobj.hxx>
47 #include <connectivity/dbtools.hxx>
51 //........................................................................
54 //........................................................................
56 //====================================================================
57 //= ComponentClassification
58 //====================================================================
59 enum ComponentClassification
66 //====================================================================
67 //= FormComponentPropertyHandler
68 //====================================================================
69 class FormComponentPropertyHandler
;
70 typedef HandlerComponentBase
< FormComponentPropertyHandler
> FormComponentPropertyHandler_Base
;
71 typedef ::comphelper::OPropertyArrayUsageHelper
<FormComponentPropertyHandler
> FormComponentPropertyHandler_PROP
;
72 /** default ->XPropertyHandler for all form components.
74 class FormComponentPropertyHandler
: public FormComponentPropertyHandler_Base
,
75 public ::comphelper::OPropertyContainer
,
76 public FormComponentPropertyHandler_PROP
79 /// access to property states
80 ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertyState
> m_xPropertyState
;
81 /// the parent of our component
82 ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
> m_xObjectParent
;
84 /// the database connection. Owned by us if and only if we created it ourself.
85 mutable ::dbtools::SharedConnection m_xRowSetConnection
;
86 ::com::sun::star::uno::Reference
< ::com::sun::star::sdbc::XRowSet
> m_xRowSet
;
87 /** helper component encapsulating the handling for the QueryDesign component for
88 interactively designing an SQL command
90 ::rtl::Reference
< SQLCommandDesigner
> m_xCommandDesigner
;
91 ::com::sun::star::uno::Reference
< ::com::sun::star::inspection::XObjectInspectorUI
> m_xBrowserUI
;
93 /// the string indicating a "default" (VOID) value in list-like controls
94 ::rtl::OUString m_sDefaultValueString
;
95 /// all properties to whose control's we added ->m_sDefaultValueString
96 ::std::set
< ::rtl::OUString
> m_aPropertiesWithDefListEntry
;
97 /// type of our component
98 ComponentClassification m_eComponentClass
;
99 /// is our component a (database) sub form?
100 bool m_bComponentIsSubForm
: 1;
101 /// our component has a "ListSource" property
102 bool m_bHaveListSource
: 1;
103 /// our component has a "Command" property
104 bool m_bHaveCommand
: 1;
105 /// the class id of the component - if appliable
106 sal_Int16 m_nClassId
;
109 FormComponentPropertyHandler(
110 const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XComponentContext
>& _rxContext
113 DECLARE_XINTERFACE( )
116 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySetInfo
> SAL_CALL
getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException
);
118 static ::rtl::OUString SAL_CALL
getImplementationName_static( ) throw (::com::sun::star::uno::RuntimeException
);
119 static ::com::sun::star::uno::Sequence
< ::rtl::OUString
> SAL_CALL
getSupportedServiceNames_static( ) throw (::com::sun::star::uno::RuntimeException
);
122 ~FormComponentPropertyHandler();
125 virtual ::cppu::IPropertyArrayHelper
* createArrayHelper( ) const;
126 virtual ::cppu::IPropertyArrayHelper
& SAL_CALL
getInfoHelper();
127 // XPropertyHandler overridables
128 virtual ::com::sun::star::uno::Any SAL_CALL
getPropertyValue( const ::rtl::OUString
& _rPropertyName
) throw (::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::uno::RuntimeException
);
129 virtual void SAL_CALL
setPropertyValue( const ::rtl::OUString
& _rPropertyName
, const ::com::sun::star::uno::Any
& _rValue
) throw (::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::uno::RuntimeException
);
130 virtual ::com::sun::star::uno::Any SAL_CALL
convertToPropertyValue( const ::rtl::OUString
& _rPropertyName
, const ::com::sun::star::uno::Any
& _rControlValue
) throw (::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::uno::RuntimeException
);
131 virtual ::com::sun::star::uno::Any SAL_CALL
convertToControlValue( const ::rtl::OUString
& _rPropertyName
, const ::com::sun::star::uno::Any
& _rPropertyValue
, const ::com::sun::star::uno::Type
& _rControlValueType
) throw (::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::uno::RuntimeException
);
132 virtual ::com::sun::star::beans::PropertyState SAL_CALL
getPropertyState( const ::rtl::OUString
& _rPropertyName
) throw (::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::uno::RuntimeException
);
133 virtual void SAL_CALL
addPropertyChangeListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertyChangeListener
>& _rxListener
) throw (::com::sun::star::uno::RuntimeException
);
134 virtual void SAL_CALL
removePropertyChangeListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertyChangeListener
>& _rxListener
) throw (::com::sun::star::uno::RuntimeException
);
135 virtual ::com::sun::star::uno::Sequence
< ::rtl::OUString
> SAL_CALL
getSupersededProperties() throw (::com::sun::star::uno::RuntimeException
);
136 virtual ::com::sun::star::uno::Sequence
< ::rtl::OUString
> SAL_CALL
getActuatingProperties() throw (::com::sun::star::uno::RuntimeException
);
137 virtual ::com::sun::star::inspection::LineDescriptor SAL_CALL
describePropertyLine( const ::rtl::OUString
& _rPropertyName
, const ::com::sun::star::uno::Reference
< ::com::sun::star::inspection::XPropertyControlFactory
>& _rxControlFactory
) throw (::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::lang::NullPointerException
, ::com::sun::star::uno::RuntimeException
);
138 virtual ::com::sun::star::inspection::InteractiveSelectionResult
139 SAL_CALL
onInteractivePropertySelection( const ::rtl::OUString
& _rPropertyName
, sal_Bool _bPrimary
, ::com::sun::star::uno::Any
& _rData
, const ::com::sun::star::uno::Reference
< ::com::sun::star::inspection::XObjectInspectorUI
>& _rxInspectorUI
) throw (::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::lang::NullPointerException
, ::com::sun::star::uno::RuntimeException
);
140 virtual void SAL_CALL
actuatingPropertyChanged( const ::rtl::OUString
& _rActuatingPropertyName
, const ::com::sun::star::uno::Any
& _rNewValue
, const ::com::sun::star::uno::Any
& _rOldValue
, const ::com::sun::star::uno::Reference
< ::com::sun::star::inspection::XObjectInspectorUI
>& _rxInspectorUI
, sal_Bool _bFirstTimeInit
) throw (::com::sun::star::lang::NullPointerException
, ::com::sun::star::uno::RuntimeException
);
141 virtual sal_Bool SAL_CALL
suspend( sal_Bool _bSuspend
) throw (::com::sun::star::uno::RuntimeException
);
144 virtual void SAL_CALL
disposing();
147 virtual ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::Property
>
148 SAL_CALL
doDescribeSupportedProperties() const;
149 virtual void onNewComponent();
152 /** initializes some (cached) meta data about the component
153 @throws RuntimeException
154 if a serious error occurs, for instance if the component does not provide an XPropertySetInfo instance
156 void impl_initComponentMetaData_throw();
158 /** classifies our component, in case it's a control model, by ClassId
160 Note that UNO dialog controls are also classified, though they don't have the ClassId property
162 void impl_classifyControlModel_throw();
164 /** const-version of ->getPropertyValue
166 ::com::sun::star::uno::Any
impl_getPropertyValue_throw( const ::rtl::OUString
& _rPropertyName
) const;
168 // some property values are faked, and not used in the way they're provided by our component
169 void impl_normalizePropertyValue_nothrow( ::com::sun::star::uno::Any
& _rValue
, PropertyId _nPropId
) const;
171 /** determines whether we should exclude a given property from our "supported properties"
173 bool impl_shouldExcludeProperty_nothrow( const ::com::sun::star::beans::Property
& _rProperty
) const;
175 /** initializes the list of field names, if we're handling a control which supports the
178 void impl_initFieldList_nothrow( ::std::vector
< ::rtl::OUString
>& rFieldNames
) const;
180 /** obtaines the RowSet to which our component belongs
182 If the component is a RowSet itself, it's returned directly. Else, the parent
183 is examined for the XRowSet interface. If the parent is no XRowSet, then
184 a check is made whether our component is a grid control column, and if so,
185 the parent of the grid control is examied for the XRowSet interace.
187 Normally, at least one of those methods should succeed.
189 ::com::sun::star::uno::Reference
< ::com::sun::star::sdbc::XRowSet
> impl_getRowSet_throw( ) const;
191 /** nothrow-version of ->impl_getRowSet_throw
193 ::com::sun::star::uno::Reference
< ::com::sun::star::sdbc::XRowSet
> impl_getRowSet_nothrow( ) const;
195 /** connects the row set belonging to our introspected data aware form component,
196 and remembers the connection in ->m_xRowSetConnection.
198 If the row set already is connected, ->m_xRowSetConnection will be set, too, but
199 not take the ownership of the connection.
201 If ->m_xRowSetConnection is already set, nothing happens, so if you want to
202 force creation of a connection, you need to clear ->m_xRowSetConnection.
204 bool impl_ensureRowsetConnection_nothrow() const;
206 /** clears ->m_xRowSetConnection
208 void impl_clearRowsetConnection_nothrow();
210 /** fills an ->LineDescriptor with information to represent a cursor source
211 of our form - that is, a table, a query, or an SQL statement.
213 As an example, if our form has currently a CommandType of TABLE, then the
214 value list in the LineDescriptor will contain a list of all tables
215 of the data source which the form is bound to.
217 @seealso impl_fillTableNames_throw
218 @seealso impl_fillQueryNames_throw
220 void impl_describeCursorSource_nothrow(
221 ::com::sun::star::inspection::LineDescriptor
& _out_rProperty
,
222 const ::com::sun::star::uno::Reference
< ::com::sun::star::inspection::XPropertyControlFactory
>& _rxControlFactory
225 /** describes the UI for selecting a table name
228 m_xRowSetConnection is not <NULL/>
230 void impl_fillTableNames_throw( ::std::vector
< ::rtl::OUString
>& _out_rNames
) const;
232 /** describes the UI for selecting a query name
235 m_xRowSetConnection is not <NULL/>
237 void impl_fillQueryNames_throw( ::std::vector
< ::rtl::OUString
>& _out_rNames
) const;
239 /** describes the UI for selecting a query name
242 m_xRowSetConnection is not <NULL/>
244 void impl_fillQueryNames_throw( const ::com::sun::star::uno::Reference
< ::com::sun::star::container::XNameAccess
>& _xQueryNames
245 ,::std::vector
< ::rtl::OUString
>& _out_rNames
246 ,const ::rtl::OUString
& _sName
= ::rtl::OUString() ) const;
248 /** describes the UI for selecting a ListSource (for list-like form controls)
250 ->m_xRowSetConnection is not <NULL/>
252 ->m_xComponent is not <NULL/>
254 void impl_describeListSourceUI_throw(
255 ::com::sun::star::inspection::LineDescriptor
& _out_rDescriptor
,
256 const ::com::sun::star::uno::Reference
< ::com::sun::star::inspection::XPropertyControlFactory
>& _rxControlFactory
259 /** displays a datbase-related error to the user
261 void impl_displaySQLError_nothrow( const ::dbtools::SQLExceptionInfo
& _rErrorDescriptor
) const;
263 /** let's the user chose a selection of entries from a string list, and stores this
264 selection in the given property
266 <TRUE/> if and only if the user successfully changed the property
268 bool impl_dialogListSelection_nothrow( const ::rtl::OUString
& _rProperty
, ::osl::ClearableMutexGuard
& _rClearBeforeDialog
) const;
270 /** executes a dialog for chosing a filter or sort criterion for a database form
272 <TRUE/> if the Filter property should be used, <FALSE/> if it's the Order
274 @param _out_rSelectedClause
275 the filter or order clause as chosen by the user
277 we're really inspecting a database form (well, a RowSet at least)
279 <TRUE/> if and only if the user successfully chose a clause
281 bool impl_dialogFilterOrSort_nothrow( bool _bFilter
, ::rtl::OUString
& _out_rSelectedClause
, ::osl::ClearableMutexGuard
& _rClearBeforeDialog
) const;
283 /** executes a dialog which allows the user to chose the columns linking
284 a sub to a master form, and sets the respective MasterFields / SlaveFields
285 properties at the form.
287 we're inspecting (sub) database form
289 <TRUE/> if and only if the user successfully eneter master and slave fields
291 bool impl_dialogLinkedFormFields_nothrow( ::osl::ClearableMutexGuard
& _rClearBeforeDialog
) const;
293 /** executes a dialog which allows the user to modify the FormatKey
294 property of our component, by chosing a (number) format.
296 Our component actually has a FormatKey property.
297 @param _out_rNewValue
298 the new property value, if the user chose a new formatting
300 <TRUE/> if and only if a new formatting has been chosen by the user.
301 In this case, ->_out_rNewValue is filled with the new property value
303 bool impl_dialogFormatting_nothrow( ::com::sun::star::uno::Any
& _out_rNewValue
, ::osl::ClearableMutexGuard
& _rClearBeforeDialog
) const;
305 /** executes a dialog which allows to the user to change the ImageURL property
306 of our component by browsing for an image file.
308 our component actually has a ImageURL property
309 @param _out_rNewValue
310 the new property value, if the user chose a new image url
312 <TRUE/> if and only if a new image URL has been chosen by the user.
313 In this case, ->_out_rNewValue is filled with the new property value
315 bool impl_browseForImage_nothrow( ::com::sun::star::uno::Any
& _out_rNewValue
, ::osl::ClearableMutexGuard
& _rClearBeforeDialog
) const;
317 /** executes a dialog which allows the user to change the TargetURL property of
320 our component actually has a TargetURL property
321 @param _out_rNewValue
322 the new property value, if the user chose a new TargetURL
324 <TRUE/> if and only if a new TargetURL has been chosen by the user.
325 In this case, ->_out_rNewValue is filled with the new property value
327 bool impl_browseForTargetURL_nothrow( ::com::sun::star::uno::Any
& _out_rNewValue
, ::osl::ClearableMutexGuard
& _rClearBeforeDialog
) const;
329 /** executes a dialog which allows the user to change the font, plus related properties,
332 our component actually has a Font property
333 @param _out_rNewValue
334 a value desribing the new font, as <code>Sequence< NamedValue ></code>
336 <TRUE/> if and only if the user successfully changed the font of our component
338 bool impl_executeFontDialog_nothrow( ::com::sun::star::uno::Any
& _out_rNewValue
, ::osl::ClearableMutexGuard
& _rClearBeforeDialog
) const;
340 /** allows the user browsing for a database document
342 our component actually has a DataSource property
343 @param _out_rNewValue
344 the new property value, if the user chose a new DataSource
346 <TRUE/> if and only if a new DataSource has been chosen by the user.
347 In this case, ->_out_rNewValue is filled with the new property value
349 bool impl_browseForDatabaseDocument_throw( ::com::sun::star::uno::Any
& _out_rNewValue
, ::osl::ClearableMutexGuard
& _rClearBeforeDialog
) const;
351 /** raises a dialog which allows the user to choose a color
352 @param _nColorPropertyId
353 the ID of the color property
354 @param _out_rNewValue
355 the chosen color value
357 <TRUE/> if and only if a color was chosen by the user
359 bool impl_dialogColorChooser_throw( sal_Int32 _nColorPropertyId
, ::com::sun::star::uno::Any
& _out_rNewValue
, ::osl::ClearableMutexGuard
& _rClearBeforeDialog
) const;
361 /** raises a dialog which allows the user to choose a label control for our component
362 @param _out_rNewValue
363 the chosen label control, if any
365 <TRUE/> if and only if a label control was chosen by the user
367 bool impl_dialogChooseLabelControl_nothrow( ::com::sun::star::uno::Any
& _out_rNewValue
, ::osl::ClearableMutexGuard
& _rClearBeforeDialog
) const;
369 /** raises a dialog which lets the user chose the tab order of controls of a form
371 we have a view control container in which our controls live
373 <TRUE/> if and only if the user successfully changed the tab order
374 @seealso impl_getContextControlContainer_nothrow
376 bool impl_dialogChangeTabOrder_nothrow( ::osl::ClearableMutexGuard
& _rClearBeforeDialog
) const;
378 /** retrieves the context for controls, whose model(s) we're inspecting
380 If we're inspecting a control model, this is usually part of a set of controls
381 and control models, where the controls live in a certain context (a ->XControlContainer).
382 If we know this context, we can enable additional special functionality.
384 The ->XComponentContext in which we were created is examined for a value
385 named "ControlContext", and this value is returned.
387 ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlContainer
>
388 impl_getContextControlContainer_nothrow() const;
390 /** opens a query design window for interactively designing the SQL command of a
393 access to the property browser UI
394 @param _nDesignForProperty
395 the ID for the property for which the designer is opened
397 <TRUE/> if the window was successfully opened, or was previously open,
400 bool impl_doDesignSQLCommand_nothrow(
401 const ::com::sun::star::uno::Reference
< ::com::sun::star::inspection::XObjectInspectorUI
>& _rxInspectorUI
,
402 PropertyId _nDesignForProperty
405 /** updates a property (UI) whose state depends on more than one other property
407 ->actuatingPropertyChanged is called for certain properties in whose changes
408 we expressed interes (->getActuatingProperty). Now such a property change can
409 result in simple UI updates, for instance another property being enabled or disabled.
411 However, it can also result in a more complex change: The current (UI) state might
412 depend on the value of more than one other property. Those dependent properties (their
413 UI, more precisly) are updated in this method.
416 the ->PropertyId of the dependent property whose UI state is to be updated
418 @param _rxInspectorUI
419 provides access to the property browser UI. Must not be <NULL/>.
421 void impl_updateDependentProperty_nothrow( PropertyId _nPropId
, const ::com::sun::star::uno::Reference
< ::com::sun::star::inspection::XObjectInspectorUI
>& _rxInspectorUI
) const;
423 /** determines whether the given form has a valid data source signature.
425 Valid here means that the DataSource property denotes an existing data source, and the
426 Command property is not empty. No check is made whether the value of the Command property
427 denotes an existent object, since this would be way too expensive.
429 @param _xFormProperties
430 the form to check. Must not be <NULL/>.
431 @param _bAllowEmptyDataSourceName
432 determine whether an empty data source name is allowed (<TRUE/>), and should not
435 static bool impl_hasValidDataSourceSignature_nothrow(
436 const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
>& _xFormProperties
,
437 bool _bAllowEmptyDataSourceName
);
439 /** returns the URL of our context document
442 ::rtl::OUString
impl_getDocumentURL_nothrow() const;
445 DECL_LINK( OnDesignerClosed
, void* );
448 FormComponentPropertyHandler(); // never implemented
449 FormComponentPropertyHandler( const FormComponentPropertyHandler
& ); // never implemented
450 FormComponentPropertyHandler
& operator=( const FormComponentPropertyHandler
& ); // never implemented
453 using ::comphelper::OPropertyContainer::addPropertyChangeListener
;
454 using ::comphelper::OPropertyContainer::removePropertyChangeListener
;
457 //====================================================================
459 //====================================================================
460 /** wrapper around a ->WaitObject which can cope with a NULL window
465 ::std::auto_ptr
< WaitObject
> m_aWaitObject
;
468 WaitCursor( Window
* _pWindow
)
471 m_aWaitObject
.reset( new WaitObject( _pWindow
) );
475 //........................................................................
477 //........................................................................
479 #endif // EXTENSIONS_SOURCE_PROPCTRLR_FORMCOMPONENTHANDLER_HXX
481 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */