1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <config_features.h>
23 #include <config_fuzzers.h>
26 #include <strings.hrc>
27 #include <frm_resource.hxx>
28 #include <frm_strings.hxx>
30 #include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
31 #include <com/sun/star/awt/XCheckBox.hpp>
32 #include <com/sun/star/awt/XComboBox.hpp>
33 #include <com/sun/star/awt/XListBox.hpp>
34 #include <com/sun/star/awt/XRadioButton.hpp>
35 #include <com/sun/star/awt/XVclWindowPeer.hpp>
36 #include <com/sun/star/beans/NamedValue.hpp>
37 #include <com/sun/star/beans/PropertyValue.hpp>
38 #include <com/sun/star/container/XChild.hpp>
39 #include <com/sun/star/container/XIndexAccess.hpp>
40 #include <com/sun/star/container/XNamed.hpp>
41 #include <com/sun/star/form/FormComponentType.hpp>
42 #include <com/sun/star/sdb/ErrorMessageDialog.hpp>
43 #include <com/sun/star/sdbc/XConnection.hpp>
44 #include <com/sun/star/sdbc/XRowSet.hpp>
45 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
46 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
47 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
48 #include <com/sun/star/util/NumberFormatter.hpp>
49 #include <com/sun/star/awt/XItemList.hpp>
51 #include <comphelper/property.hxx>
52 #include <comphelper/types.hxx>
53 #include <cppuhelper/supportsservice.hxx>
54 #include <connectivity/dbtools.hxx>
55 #include <connectivity/formattedcolumnvalue.hxx>
56 #include <connectivity/predicateinput.hxx>
57 #include <o3tl/safeint.hxx>
58 #include <rtl/ustrbuf.hxx>
59 #include <comphelper/diagnose_ex.hxx>
60 #include <tools/gen.hxx>
65 using namespace ::com::sun::star::uno
;
66 using namespace ::com::sun::star::awt
;
67 using namespace ::com::sun::star::lang
;
68 using namespace ::com::sun::star::beans
;
69 using namespace ::com::sun::star::sdb
;
70 using namespace ::com::sun::star::sdbc
;
71 using namespace ::com::sun::star::sdbcx
;
72 using namespace ::com::sun::star::util
;
73 using namespace ::com::sun::star::form
;
74 using namespace ::com::sun::star::container
;
75 using namespace ::com::sun::star::ui::dialogs
;
77 using namespace ::connectivity
;
79 OFilterControl::OFilterControl( const Reference
< XComponentContext
>& _rxORB
)
80 :m_aTextListeners( *this )
82 ,m_nControlClass( FormComponentType::TEXTFIELD
)
83 ,m_bFilterList( false )
84 ,m_bMultiLine( false )
85 ,m_bFilterListFilled( false )
90 bool OFilterControl::ensureInitialized( )
92 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
95 OSL_FAIL( "OFilterControl::ensureInitialized: improperly initialized: no field!" );
99 if ( !m_xConnection
.is() )
101 OSL_FAIL( "OFilterControl::ensureInitialized: improperly initialized: no connection!" );
105 if ( !m_xFormatter
.is() )
107 // we can create one from the connection, if it's an SDB connection
109 Reference
< XNumberFormatsSupplier
> xFormatSupplier
= ::dbtools::getNumberFormats( m_xConnection
, true, m_xContext
);
111 if ( xFormatSupplier
.is() )
113 m_xFormatter
.set(NumberFormatter::create(m_xContext
), UNO_QUERY_THROW
);
114 m_xFormatter
->attachNumberFormatsSupplier( xFormatSupplier
);
117 if ( !m_xFormatter
.is() )
119 OSL_FAIL( "OFilterControl::ensureInitialized: no number formatter!" );
120 // no fallback anymore
128 Any SAL_CALL
OFilterControl::queryAggregation( const Type
& rType
)
130 Any aRet
= UnoControl::queryAggregation( rType
);
132 aRet
= OFilterControl_BASE::queryInterface(rType
);
138 OUString
OFilterControl::GetComponentServiceName() const
140 OUString aServiceName
;
141 switch (m_nControlClass
)
143 case FormComponentType::RADIOBUTTON
:
144 aServiceName
= "radiobutton";
146 case FormComponentType::CHECKBOX
:
147 aServiceName
= "checkbox";
149 case FormComponentType::COMBOBOX
:
150 aServiceName
= "combobox";
152 case FormComponentType::LISTBOX
:
153 aServiceName
= "listbox";
157 aServiceName
= "MultiLineEdit";
159 aServiceName
= "Edit";
166 void OFilterControl::dispose()
168 EventObject
aEvt(*this);
169 m_aTextListeners
.disposeAndClear( aEvt
);
170 UnoControl::dispose();
174 void OFilterControl::createPeer( const Reference
< XToolkit
> & rxToolkit
, const Reference
< XWindowPeer
> & rParentPeer
)
176 UnoControl::createPeer( rxToolkit
, rParentPeer
);
180 Reference
< XVclWindowPeer
> xVclWindow( getPeer(), UNO_QUERY_THROW
);
181 switch ( m_nControlClass
)
183 case FormComponentType::CHECKBOX
:
185 // checkboxes always have a tristate-mode
186 xVclWindow
->setProperty( PROPERTY_TRISTATE
, Any( true ) );
187 xVclWindow
->setProperty( PROPERTY_STATE
, Any( sal_Int32( TRISTATE_INDET
) ) );
189 Reference
< XCheckBox
> xBox( getPeer(), UNO_QUERY_THROW
);
190 xBox
->addItemListener( this );
195 case FormComponentType::RADIOBUTTON
:
197 xVclWindow
->setProperty( PROPERTY_STATE
, Any( sal_Int32( TRISTATE_FALSE
) ) );
199 Reference
< XRadioButton
> xRadio( getPeer(), UNO_QUERY_THROW
);
200 xRadio
->addItemListener( this );
204 case FormComponentType::LISTBOX
:
206 Reference
< XListBox
> xListBox( getPeer(), UNO_QUERY_THROW
);
207 xListBox
->addItemListener( this );
211 case FormComponentType::COMBOBOX
:
213 xVclWindow
->setProperty(PROPERTY_AUTOCOMPLETE
, Any( true ) );
219 Reference
< XWindow
> xWindow( getPeer(), UNO_QUERY
);
220 xWindow
->addFocusListener( this );
222 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
224 xText
->setMaxTextLen(0);
229 // filter controls are _never_ readonly
230 Reference
< XPropertySet
> xModel( getModel(), UNO_QUERY_THROW
);
231 Reference
< XPropertySetInfo
> xModelPSI( xModel
->getPropertySetInfo(), UNO_SET_THROW
);
232 if ( xModelPSI
->hasPropertyByName( PROPERTY_READONLY
) )
233 xVclWindow
->setProperty( PROPERTY_READONLY
, Any( false ) );
235 catch( const Exception
& )
237 DBG_UNHANDLED_EXCEPTION("forms.component");
241 m_bFilterListFilled
= false;
245 void OFilterControl::PrepareWindowDescriptor( WindowDescriptor
& rDescr
)
248 rDescr
.WindowAttributes
|= VclWindowPeerAttribute::DROPDOWN
;
252 void OFilterControl::ImplSetPeerProperty( const OUString
& rPropName
, const Any
& rVal
)
254 // these properties are ignored
255 if (rPropName
== PROPERTY_TEXT
||
256 rPropName
== PROPERTY_STATE
)
259 UnoControl::ImplSetPeerProperty( rPropName
, rVal
);
264 void SAL_CALL
OFilterControl::disposing(const EventObject
& Source
)
266 UnoControl::disposing(Source
);
271 void SAL_CALL
OFilterControl::itemStateChanged( const ItemEvent
& rEvent
)
273 #if !HAVE_FEATURE_DBCONNECTIVITY || ENABLE_FUZZERS
276 OUStringBuffer aText
;
277 switch (m_nControlClass
)
279 case FormComponentType::CHECKBOX
:
281 if ( ( rEvent
.Selected
== TRISTATE_TRUE
) || ( rEvent
.Selected
== TRISTATE_FALSE
) )
283 sal_Int32 nBooleanComparisonMode
= ::dbtools::DatabaseMetaData( m_xConnection
).getBooleanComparisonMode();
285 bool bSelected
= ( rEvent
.Selected
== TRISTATE_TRUE
);
287 OUString
sExpressionMarker( "$expression$" );
288 ::dbtools::getBooleanComparisonPredicate(
291 nBooleanComparisonMode
,
295 OUString
sText( aText
.makeStringAndClear() );
296 sal_Int32
nMarkerPos( sText
.indexOf( sExpressionMarker
) );
297 OSL_ENSURE( nMarkerPos
== 0, "OFilterControl::itemStateChanged: unsupported boolean comparison mode!" );
298 // If this assertion fails, then getBooleanComparisonPredicate created a predicate which
299 // does not start with the expression we gave it. The only known case is when
300 // the comparison mode is ACCESS_COMPAT, and the value is TRUE. In this case,
301 // the expression is rather complex.
302 // Well, so this is a known issue - the filter controls (and thus the form based filter)
303 // do not work with boolean MS Access fields.
304 // To fix this, we would probably have to revert here to always return "1" or "0" as normalized
305 // filter, and change our client code to properly translate this (which could be some effort).
306 if ( nMarkerPos
== 0 )
307 aText
.append( sText
.subView(sExpressionMarker
.getLength()) );
311 aText
.appendAscii( bSelected
? "1" : "0" );
317 case FormComponentType::LISTBOX
:
321 const Reference
< XItemList
> xItemList( getModel(), UNO_QUERY_THROW
);
322 OUString
sItemText( xItemList
->getItemText( rEvent
.Selected
) );
324 const MapString2String::const_iterator itemPos
= m_aDisplayItemToValueItem
.find( sItemText
);
325 if ( itemPos
!= m_aDisplayItemToValueItem
.end() )
327 sItemText
= itemPos
->second
;
328 if ( !sItemText
.isEmpty() )
330 ::dbtools::OPredicateInputController
aPredicateInput( m_xContext
, m_xConnection
, getParseContext() );
331 OUString sErrorMessage
;
332 OSL_VERIFY( aPredicateInput
.normalizePredicateString( sItemText
, m_xField
, &sErrorMessage
) );
335 aText
.append( sItemText
);
337 catch( const Exception
& )
339 DBG_UNHANDLED_EXCEPTION("forms.component");
344 case FormComponentType::RADIOBUTTON
:
346 if ( rEvent
.Selected
== TRISTATE_TRUE
)
347 aText
.append( ::comphelper::getString( Reference
< XPropertySet
>( getModel(), UNO_QUERY_THROW
)->getPropertyValue( PROPERTY_REFVALUE
) ) );
352 OUString
sText( aText
.makeStringAndClear() );
353 if ( m_aText
!= sText
)
358 m_aTextListeners
.notifyEach(&css::awt::XTextListener::textChanged
, aEvt
);
364 void OFilterControl::implInitFilterList()
366 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
367 if ( !ensureInitialized( ) )
368 // already asserted in ensureInitialized
371 // ensure the cursor and the statement are disposed as soon as we leave
372 ::utl::SharedUNOComponent
< XResultSet
> xListCursor
;
373 ::utl::SharedUNOComponent
< XStatement
> xStatement
;
377 m_bFilterListFilled
= true;
379 if ( !m_xField
.is() )
383 m_xField
->getPropertyValue( PROPERTY_NAME
) >>= sFieldName
;
385 // here we need a table to which the field belongs to
386 const Reference
< XChild
> xModelAsChild( getModel(), UNO_QUERY_THROW
);
387 const Reference
< XRowSet
> xForm( xModelAsChild
->getParent(), UNO_QUERY_THROW
);
388 const Reference
< XPropertySet
> xFormProps( xForm
, UNO_QUERY_THROW
);
390 // create a query composer
391 Reference
< XColumnsSupplier
> xSuppColumns
;
392 xFormProps
->getPropertyValue("SingleSelectQueryComposer") >>= xSuppColumns
;
394 const Reference
< XConnection
> xConnection( ::dbtools::getConnection( xForm
), UNO_SET_THROW
);
395 const Reference
< XNameAccess
> xFieldNames( xSuppColumns
->getColumns(), UNO_SET_THROW
);
396 if ( !xFieldNames
->hasByName( sFieldName
) )
398 OUString sRealFieldName
, sTableName
;
399 const Reference
< XPropertySet
> xComposerFieldProps( xFieldNames
->getByName( sFieldName
), UNO_QUERY_THROW
);
400 xComposerFieldProps
->getPropertyValue( PROPERTY_REALNAME
) >>= sRealFieldName
;
401 xComposerFieldProps
->getPropertyValue( PROPERTY_TABLENAME
) >>= sTableName
;
403 // obtain the table of the field
404 const Reference
< XTablesSupplier
> xSuppTables( xSuppColumns
, UNO_QUERY_THROW
);
405 const Reference
< XNameAccess
> xTablesNames( xSuppTables
->getTables(), UNO_SET_THROW
);
406 const Reference
< XNamed
> xNamedTable( xTablesNames
->getByName( sTableName
), UNO_QUERY_THROW
);
407 sTableName
= xNamedTable
->getName();
409 // create a statement selecting all values for the given field
410 OUStringBuffer aStatement
;
412 const Reference
< XDatabaseMetaData
> xMeta( xConnection
->getMetaData(), UNO_SET_THROW
);
413 const OUString sQuoteChar
= xMeta
->getIdentifierQuoteString();
421 // if the field had an alias in our form's statement, give it this alias in the new statement, too
422 if ( !sFieldName
.isEmpty() && ( sFieldName
!= sRealFieldName
) )
424 aStatement
.append(" AS "+ sQuoteChar
+ sFieldName
+ sQuoteChar
);
427 aStatement
.append( " FROM " );
429 OUString sCatalog
, sSchema
, sTable
;
430 ::dbtools::qualifiedNameComponents( xMeta
, sTableName
, sCatalog
, sSchema
, sTable
, ::dbtools::EComposeRule::InDataManipulation
);
431 aStatement
.append( ::dbtools::composeTableNameForSelect( xConnection
, sCatalog
, sSchema
, sTable
) );
433 // execute the statement
434 xStatement
.reset( xConnection
->createStatement() );
435 const OUString
sSelectStatement( aStatement
.makeStringAndClear( ) );
436 xListCursor
.reset( xStatement
->executeQuery( sSelectStatement
) );
438 // retrieve the one column which we take the values from
439 const Reference
< XColumnsSupplier
> xSupplyCols( xListCursor
, UNO_QUERY_THROW
);
440 const Reference
< XIndexAccess
> xFields( xSupplyCols
->getColumns(), UNO_QUERY_THROW
);
441 const Reference
< XPropertySet
> xDataField( xFields
->getByIndex(0), UNO_QUERY_THROW
);
443 // ensure the values will be formatted according to the field format
444 const ::dbtools::FormattedColumnValue
aFormatter( m_xFormatter
, xDataField
);
446 ::std::vector
< OUString
> aProposals
;
447 aProposals
.reserve(16);
449 while ( xListCursor
->next() && ( aProposals
.size() < o3tl::make_unsigned( SHRT_MAX
) ) )
451 const OUString sCurrentValue
= aFormatter
.getFormattedValue();
452 aProposals
.push_back( sCurrentValue
);
455 // fill the list items into our peer
456 Sequence
< OUString
> aStringSeq( comphelper::containerToSequence(aProposals
) );
458 const Reference
< XComboBox
> xComboBox( getPeer(), UNO_QUERY_THROW
);
459 xComboBox
->addItems( aStringSeq
, 0 );
461 // set the drop down line count to something reasonable
462 const sal_Int16 nLineCount
= ::std::min( sal_Int16( 16 ), sal_Int16( aStringSeq
.getLength() ) );
463 xComboBox
->setDropDownLineCount( nLineCount
);
465 catch( const Exception
& )
467 DBG_UNHANDLED_EXCEPTION("forms.component");
474 void SAL_CALL
OFilterControl::focusGained(const FocusEvent
& /*e*/)
476 // should we fill the combobox?
477 if (m_bFilterList
&& !m_bFilterListFilled
)
478 implInitFilterList();
482 void SAL_CALL
OFilterControl::focusLost(const FocusEvent
& /*e*/)
487 sal_Bool SAL_CALL
OFilterControl::commit()
489 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
490 if ( !ensureInitialized( ) )
491 // already asserted in ensureInitialized
495 switch (m_nControlClass
)
497 case FormComponentType::TEXTFIELD
:
498 case FormComponentType::COMBOBOX
:
500 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
502 aText
= xText
->getText();
507 if ( m_aText
== aText
)
509 // check the text with the SQL-Parser
510 OUString aNewText
= aText
.trim();
511 if ( !aNewText
.isEmpty() )
513 ::dbtools::OPredicateInputController
aPredicateInput( m_xContext
, m_xConnection
, getParseContext() );
514 OUString sErrorMessage
;
515 if ( !aPredicateInput
.normalizePredicateString( aNewText
, m_xField
, &sErrorMessage
) )
517 // display the error and outta here
519 aError
.Message
= ResourceManager::loadString(RID_STR_SYNTAXERROR
);
520 aError
.Details
= sErrorMessage
;
521 displayException( aError
);
529 m_aTextListeners
.notifyEach(&css::awt::XTextListener::textChanged
, aEvt
);
536 void SAL_CALL
OFilterControl::addTextListener(const Reference
< XTextListener
> & l
)
538 m_aTextListeners
.addInterface( l
);
542 void SAL_CALL
OFilterControl::removeTextListener(const Reference
< XTextListener
> & l
)
544 m_aTextListeners
.removeInterface( l
);
548 void SAL_CALL
OFilterControl::setText( const OUString
& aText
)
550 if ( !ensureInitialized( ) )
551 // already asserted in ensureInitialized
554 switch (m_nControlClass
)
556 case FormComponentType::CHECKBOX
:
558 Reference
< XVclWindowPeer
> xVclWindow( getPeer(), UNO_QUERY
);
563 || aText
.equalsIgnoreAsciiCase("TRUE")
564 || aText
.equalsIgnoreAsciiCase("IS TRUE")
567 aValue
<<= sal_Int32(TRISTATE_TRUE
);
569 else if ( aText
== "0" || aText
.equalsIgnoreAsciiCase("FALSE") )
571 aValue
<<= sal_Int32(TRISTATE_FALSE
);
574 aValue
<<= sal_Int32(TRISTATE_INDET
);
577 xVclWindow
->setProperty( PROPERTY_STATE
, aValue
);
580 case FormComponentType::RADIOBUTTON
:
582 Reference
< XVclWindowPeer
> xVclWindow( getPeer(), UNO_QUERY
);
585 OUString aRefText
= ::comphelper::getString(css::uno::Reference
< XPropertySet
> (getModel(), UNO_QUERY_THROW
)->getPropertyValue(PROPERTY_REFVALUE
));
587 if (aText
== aRefText
)
588 aValue
<<= sal_Int32(TRISTATE_TRUE
);
590 aValue
<<= sal_Int32(TRISTATE_FALSE
);
592 xVclWindow
->setProperty(PROPERTY_STATE
, aValue
);
595 case FormComponentType::LISTBOX
:
597 Reference
< XListBox
> xListBox( getPeer(), UNO_QUERY
);
601 MapString2String::const_iterator itemPos
= m_aDisplayItemToValueItem
.find( m_aText
);
602 if ( itemPos
== m_aDisplayItemToValueItem
.end() )
604 const bool isQuoted
= ( m_aText
.getLength() > 1 )
605 && ( m_aText
[0] == '\'' )
606 && ( m_aText
[ m_aText
.getLength() - 1 ] == '\'' );
609 m_aText
= m_aText
.copy( 1, m_aText
.getLength() - 2 );
610 itemPos
= m_aDisplayItemToValueItem
.find( m_aText
);
614 OSL_ENSURE( ( itemPos
!= m_aDisplayItemToValueItem
.end() ) || m_aText
.isEmpty(),
615 "OFilterControl::setText: this text is not in my display list!" );
616 if ( itemPos
== m_aDisplayItemToValueItem
.end() )
619 if ( m_aText
.isEmpty() )
621 while ( xListBox
->getSelectedItemPos() >= 0 )
623 xListBox
->selectItemPos( xListBox
->getSelectedItemPos(), false );
628 xListBox
->selectItem( m_aText
, true );
636 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
640 xText
->setText(aText
);
647 void SAL_CALL
OFilterControl::insertText( const css::awt::Selection
& rSel
, const OUString
& aText
)
649 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
652 xText
->insertText(rSel
, aText
);
653 m_aText
= xText
->getText();
658 OUString SAL_CALL
OFilterControl::getText()
664 OUString SAL_CALL
OFilterControl::getSelectedText()
667 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
669 aSelected
= xText
->getSelectedText();
675 void SAL_CALL
OFilterControl::setSelection( const css::awt::Selection
& aSelection
)
677 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
679 xText
->setSelection( aSelection
);
683 css::awt::Selection SAL_CALL
OFilterControl::getSelection()
685 css::awt::Selection aSel
;
686 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
688 aSel
= xText
->getSelection();
693 sal_Bool SAL_CALL
OFilterControl::isEditable()
695 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
696 return xText
.is() && xText
->isEditable();
700 void SAL_CALL
OFilterControl::setEditable( sal_Bool bEditable
)
702 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
704 xText
->setEditable(bEditable
);
708 sal_Int16 SAL_CALL
OFilterControl::getMaxTextLen()
710 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
711 return xText
.is() ? xText
->getMaxTextLen() : 0;
715 void SAL_CALL
OFilterControl::setMaxTextLen( sal_Int16 nLength
)
717 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
719 xText
->setMaxTextLen(nLength
);
723 void OFilterControl::displayException( const css::sdb::SQLContext
& _rExcept
)
727 Reference
< XExecutableDialog
> xErrorDialog
= ErrorMessageDialog::create( m_xContext
, "", m_xMessageParent
, Any(_rExcept
));
728 xErrorDialog
->execute();
730 catch( const Exception
& )
732 DBG_UNHANDLED_EXCEPTION("forms.component");
737 void SAL_CALL
OFilterControl::initialize( const Sequence
< Any
>& aArguments
)
739 const Any
* pArguments
= aArguments
.getConstArray();
740 const Any
* pArgumentsEnd
= pArguments
+ aArguments
.getLength();
744 const OUString
* pName
= nullptr;
745 const Any
* pValue
= nullptr;
746 Reference
< XPropertySet
> xControlModel
;
748 if (aArguments
.getLength() == 3
749 && (aArguments
[0] >>= m_xMessageParent
)
750 && (aArguments
[1] >>= m_xFormatter
)
751 && (aArguments
[2] >>= xControlModel
))
753 initControlModel(xControlModel
);
755 else for ( ; pArguments
!= pArgumentsEnd
; ++pArguments
)
757 // we recognize PropertyValues and NamedValues
758 if ( *pArguments
>>= aProp
)
761 pValue
= &aProp
.Value
;
763 else if ( *pArguments
>>= aValue
)
765 pName
= &aValue
.Name
;
766 pValue
= &aValue
.Value
;
770 OSL_FAIL( "OFilterControl::initialize: unrecognized argument!" );
774 if ( *pName
== "MessageParent" )
776 // the message parent
777 *pValue
>>= m_xMessageParent
;
778 OSL_ENSURE( m_xMessageParent
.is(), "OFilterControl::initialize: invalid MessageParent!" );
780 else if ( *pName
== "NumberFormatter" )
782 // the number format. This argument is optional.
783 *pValue
>>= m_xFormatter
;
784 OSL_ENSURE( m_xFormatter
.is(), "OFilterControl::initialize: invalid NumberFormatter!" );
786 else if ( *pName
== "ControlModel" )
788 // the control model for which we act as filter control
789 if ( !(*pValue
>>= xControlModel
) )
791 OSL_FAIL( "OFilterControl::initialize: invalid control model argument!" );
794 initControlModel(xControlModel
);
799 void OFilterControl::initControlModel(Reference
< XPropertySet
> const & xControlModel
)
801 #if !HAVE_FEATURE_DBCONNECTIVITY || ENABLE_FUZZERS
802 (void) xControlModel
;
804 if ( !xControlModel
.is() )
806 OSL_FAIL( "OFilterControl::initialize: invalid control model argument!" );
809 // some properties which are "derived" from the control model we're working for
813 OSL_ENSURE( ::comphelper::hasProperty( PROPERTY_BOUNDFIELD
, xControlModel
), "OFilterControl::initialize: control model needs a bound field property!" );
814 xControlModel
->getPropertyValue( PROPERTY_BOUNDFIELD
) >>= m_xField
;
817 // filter list and control class
818 m_bFilterList
= ::comphelper::hasProperty( PROPERTY_FILTERPROPOSAL
, xControlModel
) && ::comphelper::getBOOL( xControlModel
->getPropertyValue( PROPERTY_FILTERPROPOSAL
) );
820 m_nControlClass
= FormComponentType::COMBOBOX
;
823 sal_Int16 nClassId
= ::comphelper::getINT16( xControlModel
->getPropertyValue( PROPERTY_CLASSID
) );
826 case FormComponentType::CHECKBOX
:
827 case FormComponentType::RADIOBUTTON
:
828 case FormComponentType::LISTBOX
:
829 case FormComponentType::COMBOBOX
:
830 m_nControlClass
= nClassId
;
831 if ( FormComponentType::LISTBOX
== nClassId
)
833 Sequence
< OUString
> aDisplayItems
;
834 OSL_VERIFY( xControlModel
->getPropertyValue( PROPERTY_STRINGITEMLIST
) >>= aDisplayItems
);
835 Sequence
< OUString
> aValueItems
;
836 OSL_VERIFY( xControlModel
->getPropertyValue( PROPERTY_VALUE_SEQ
) >>= aValueItems
);
837 OSL_ENSURE( aDisplayItems
.getLength() == aValueItems
.getLength(), "OFilterControl::initialize: inconsistent item lists!" );
838 for ( sal_Int32 i
=0; i
< ::std::min( aDisplayItems
.getLength(), aValueItems
.getLength() ); ++i
)
839 m_aDisplayItemToValueItem
[ aDisplayItems
[i
] ] = aValueItems
[i
];
843 m_bMultiLine
= ::comphelper::hasProperty( PROPERTY_MULTILINE
, xControlModel
) && ::comphelper::getBOOL( xControlModel
->getPropertyValue( PROPERTY_MULTILINE
) );
844 m_nControlClass
= FormComponentType::TEXTFIELD
;
850 // the connection meta data for the form which we're working for
851 Reference
< XChild
> xModel( xControlModel
, UNO_QUERY
);
852 Reference
< XRowSet
> xForm
;
854 xForm
.set(xModel
->getParent(), css::uno::UNO_QUERY
);
855 m_xConnection
= ::dbtools::getConnection( xForm
);
856 OSL_ENSURE( m_xConnection
.is(), "OFilterControl::initialize: unable to determine the form's connection!" );
860 OUString SAL_CALL
OFilterControl::getImplementationName( )
862 return "com.sun.star.comp.forms.OFilterControl";
865 sal_Bool SAL_CALL
OFilterControl::supportsService( const OUString
& ServiceName
)
867 return cppu::supportsService(this, ServiceName
);
870 Sequence
< OUString
> SAL_CALL
OFilterControl::getSupportedServiceNames( )
872 return { "com.sun.star.form.control.FilterControl",
873 "com.sun.star.awt.UnoControl" };
877 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
878 com_sun_star_comp_forms_OFilterControl_get_implementation(css::uno::XComponentContext
* context
,
879 css::uno::Sequence
<css::uno::Any
> const &)
881 return cppu::acquire(new frm::OFilterControl(context
));
884 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */