22#include <config_features.h>
23#include <config_fuzzers.h>
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>
58#include <rtl/ustrbuf.hxx>
80 :m_aTextListeners( *this )
82 ,m_nControlClass( FormComponentType::
TEXTFIELD )
83 ,m_bFilterList( false )
84 ,m_bMultiLine( false )
85 ,m_bFilterListFilled( false )
92#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
95 OSL_FAIL(
"OFilterControl::ensureInitialized: improperly initialized: no field!" );
101 OSL_FAIL(
"OFilterControl::ensureInitialized: improperly initialized: no connection!" );
109 Reference< XNumberFormatsSupplier > xFormatSupplier = ::dbtools::getNumberFormats(
m_xConnection,
true,
m_xContext );
111 if ( xFormatSupplier.is() )
114 m_xFormatter->attachNumberFormatsSupplier( xFormatSupplier );
119 OSL_FAIL(
"OFilterControl::ensureInitialized: no number formatter!" );
130 Any aRet = UnoControl::queryAggregation( rType);
140 OUString aServiceName;
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";
168 EventObject aEvt(*
this);
180 Reference< XVclWindowPeer > xVclWindow(
getPeer(), UNO_QUERY_THROW );
183 case FormComponentType::CHECKBOX:
189 Reference< XCheckBox > xBox(
getPeer(), UNO_QUERY_THROW );
190 xBox->addItemListener(
this );
195 case FormComponentType::RADIOBUTTON:
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:
219 Reference< XWindow > xWindow(
getPeer(), UNO_QUERY );
220 xWindow->addFocusListener(
this );
222 Reference< XTextComponent > xText(
getPeer(), UNO_QUERY );
224 xText->setMaxTextLen(0);
231 Reference< XPropertySetInfo > xModelPSI(
xModel->getPropertySetInfo(), UNO_SET_THROW );
248 rDescr.WindowAttributes |= VclWindowPeerAttribute::DROPDOWN;
273#if !HAVE_FEATURE_DBCONNECTIVITY || ENABLE_FUZZERS
276 OUStringBuffer aText;
279 case FormComponentType::CHECKBOX:
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!" );
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 ) );
327 sItemText = itemPos->second;
328 if ( !sItemText.isEmpty() )
331 OUString sErrorMessage;
335 aText.append( sItemText );
344 case FormComponentType::RADIOBUTTON:
352 OUString sText( aText.makeStringAndClear() );
366#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
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 );
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 );
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();
410 OUStringBuffer aStatement;
412 const Reference< XDatabaseMetaData > xMeta( xConnection->getMetaData(), UNO_SET_THROW );
413 const OUString sQuoteChar = xMeta->getIdentifierQuoteString();
422 if ( !sFieldName.isEmpty() && ( sFieldName != sRealFieldName ) )
424 aStatement.append(
" AS "+ sQuoteChar + sFieldName + sQuoteChar );
427 aStatement.append(
" FROM " );
430 ::dbtools::qualifiedNameComponents( xMeta, sTableName,
sCatalog,
sSchema, sTable, ::dbtools::EComposeRule::InDataManipulation );
431 aStatement.append( ::dbtools::composeTableNameForSelect( xConnection,
sCatalog,
sSchema, sTable ) );
434 xStatement.
reset( xConnection->createStatement() );
435 const OUString sSelectStatement( aStatement.makeStringAndClear( ) );
436 xListCursor.
reset( xStatement->executeQuery( sSelectStatement ) );
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 );
444 const ::dbtools::FormattedColumnValue aFormatter(
m_xFormatter, xDataField );
446 ::std::vector< OUString > aProposals;
447 aProposals.reserve(16);
451 const OUString sCurrentValue = aFormatter.getFormattedValue();
452 aProposals.push_back( sCurrentValue );
458 const Reference< XComboBox > xComboBox(
getPeer(), UNO_QUERY_THROW );
459 xComboBox->addItems( aStringSeq, 0 );
462 const sal_Int16 nLineCount = ::std::min( sal_Int16( 16 ), sal_Int16( aStringSeq.getLength() ) );
463 xComboBox->setDropDownLineCount( nLineCount );
489#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
497 case FormComponentType::TEXTFIELD:
498 case FormComponentType::COMBOBOX:
500 Reference< XTextComponent > xText(
getPeer(), UNO_QUERY );
502 aText = xText->getText();
510 OUString aNewText = aText.trim();
511 if ( !aNewText.isEmpty() )
514 OUString sErrorMessage;
520 aError.Details = sErrorMessage;
556 case FormComponentType::CHECKBOX:
558 Reference< XVclWindowPeer > xVclWindow(
getPeer(), UNO_QUERY );
563 || aText.equalsIgnoreAsciiCase(
"TRUE")
564 || aText.equalsIgnoreAsciiCase(
"IS TRUE")
569 else if ( aText ==
"0" || aText.equalsIgnoreAsciiCase(
"FALSE") )
580 case FormComponentType::RADIOBUTTON:
582 Reference< XVclWindowPeer > xVclWindow(
getPeer(), UNO_QUERY );
587 if (aText == aRefText)
595 case FormComponentType::LISTBOX:
597 Reference< XListBox > xListBox(
getPeer(), UNO_QUERY );
604 const bool isQuoted = (
m_aText.getLength() > 1 )
615 "OFilterControl::setText: this text is not in my display list!" );
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);
649 Reference< XTextComponent > xText(
getPeer(), UNO_QUERY );
652 xText->insertText(rSel, aText);
667 Reference< XTextComponent > xText(
getPeer(), UNO_QUERY );
669 aSelected = xText->getSelectedText();
677 Reference< XTextComponent > xText(
getPeer(), UNO_QUERY );
679 xText->setSelection( aSelection );
685 css::awt::Selection aSel;
686 Reference< XTextComponent > xText(
getPeer(), UNO_QUERY );
688 aSel = xText->getSelection();
695 Reference< XTextComponent > xText(
getPeer(), UNO_QUERY );
696 return xText.is() && xText->isEditable();
702 Reference< XTextComponent > xText(
getPeer(), UNO_QUERY );
704 xText->setEditable(bEditable);
710 Reference< XTextComponent > xText(
getPeer(), UNO_QUERY );
711 return xText.is() ? xText->getMaxTextLen() : 0;
717 Reference< XTextComponent > xText(
getPeer(), UNO_QUERY );
728 xErrorDialog->execute();
740 const Any* pArgumentsEnd = pArguments +
aArguments.getLength();
744 const OUString*
pName =
nullptr;
745 const Any* pValue =
nullptr;
746 Reference< XPropertySet > xControlModel;
755 else for ( ; pArguments != pArgumentsEnd; ++pArguments )
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" )
778 OSL_ENSURE(
m_xMessageParent.is(),
"OFilterControl::initialize: invalid MessageParent!" );
780 else if ( *
pName ==
"NumberFormatter" )
784 OSL_ENSURE(
m_xFormatter.is(),
"OFilterControl::initialize: invalid NumberFormatter!" );
786 else if ( *
pName ==
"ControlModel" )
789 if ( !(*pValue >>= xControlModel ) )
791 OSL_FAIL(
"OFilterControl::initialize: invalid control model argument!" );
801#if !HAVE_FEATURE_DBCONNECTIVITY || ENABLE_FUZZERS
802 (void) xControlModel;
804 if ( !xControlModel.is() )
806 OSL_FAIL(
"OFilterControl::initialize: invalid control model argument!" );
813 OSL_ENSURE( ::comphelper::hasProperty(
PROPERTY_BOUNDFIELD, xControlModel ),
"OFilterControl::initialize: control model needs a bound field property!" );
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:
831 if ( FormComponentType::LISTBOX == nClassId )
833 Sequence< OUString > aDisplayItems;
835 Sequence< OUString > 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 )
851 Reference< XChild >
xModel( xControlModel, UNO_QUERY );
852 Reference< XRowSet > xForm;
854 xForm.set(
xModel->getParent(), css::uno::UNO_QUERY);
856 OSL_ENSURE(
m_xConnection.is(),
"OFilterControl::initialize: unable to determine the form's connection!" );
862 return "com.sun.star.comp.forms.OFilterControl";
872 return {
"com.sun.star.form.control.FilterControl",
873 "com.sun.star.awt.UnoControl" };
877extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
879 css::uno::Sequence<css::uno::Any>
const &)
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_forms_OFilterControl_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
Reference< XComponentContext > m_xContext
css::uno::Reference< css::awt::XControlModel > SAL_CALL getModel() override
void SAL_CALL dispose() override
virtual void ImplSetPeerProperty(const OUString &rPropName, const css::uno::Any &rVal)
void SAL_CALL disposing(const css::lang::EventObject &Source) override
css::uno::Reference< css::awt::XWindowPeer > SAL_CALL getPeer() override
void SAL_CALL createPeer(const css::uno::Reference< css::awt::XToolkit > &Toolkit, const css::uno::Reference< css::awt::XWindowPeer > &Parent) override
virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const &rType) SAL_OVERRIDE
virtual void SAL_CALL setEditable(sal_Bool bEditable) override
void displayException(const css::sdb::SQLContext &_rExcept)
virtual void SAL_CALL setSelection(const css::awt::Selection &aSelection) override
MapString2String m_aDisplayItemToValueItem
virtual void SAL_CALL itemStateChanged(const css::awt::ItemEvent &rEvent) override
css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &rType) override
virtual void SAL_CALL insertText(const css::awt::Selection &rSel, const OUString &aText) override
css::uno::Reference< css::beans::XPropertySet > m_xField
virtual void SAL_CALL removeTextListener(const css::uno::Reference< css::awt::XTextListener > &l) override
virtual void PrepareWindowDescriptor(css::awt::WindowDescriptor &rDesc) override
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
sal_Int16 m_nControlClass
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
void initControlModel(css::uno::Reference< css::beans::XPropertySet > const &xControlModel)
virtual OUString SAL_CALL getImplementationName() override
virtual void SAL_CALL addTextListener(const css::uno::Reference< css::awt::XTextListener > &l) override
virtual OUString GetComponentServiceName() const override
void implInitFilterList()
virtual void SAL_CALL focusLost(const css::awt::FocusEvent &e) override
virtual OUString SAL_CALL getSelectedText() override
virtual sal_Bool SAL_CALL isEditable() override
virtual void SAL_CALL focusGained(const css::awt::FocusEvent &e) override
css::uno::Reference< css::util::XNumberFormatter > m_xFormatter
virtual sal_Bool SAL_CALL commit() override
css::uno::Reference< css::awt::XWindow > m_xMessageParent
virtual void SAL_CALL dispose() override
virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > &aArguments) override
virtual void SAL_CALL setMaxTextLen(sal_Int16 nLength) override
css::uno::Reference< css::uno::XComponentContext > m_xContext
TextListenerMultiplexer m_aTextListeners
virtual css::awt::Selection SAL_CALL getSelection() override
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
virtual void ImplSetPeerProperty(const OUString &rPropName, const css::uno::Any &rVal) override
virtual void SAL_CALL setText(const OUString &aText) override
virtual OUString SAL_CALL getText() override
css::uno::Reference< css::sdbc::XConnection > m_xConnection
virtual sal_Int16 SAL_CALL getMaxTextLen() override
virtual void SAL_CALL createPeer(const css::uno::Reference< css::awt::XToolkit > &rxToolkit, const css::uno::Reference< css::awt::XWindowPeer > &rParentPeer) override
OFilterControl(const css::uno::Reference< css::uno::XComponentContext > &_rxORB)
const OSystemParseContext * getParseContext() const
void reset(const css::uno::Reference< INTERFACE > &_rxComponent, AssignmentMode _eMode=TakeOwnership)
#define DBG_UNHANDLED_EXCEPTION(...)
constexpr OUStringLiteral PROPERTY_NAME
constexpr OUStringLiteral PROPERTY_FILTERPROPOSAL
constexpr OUStringLiteral PROPERTY_BOUNDFIELD
constexpr OUStringLiteral PROPERTY_AUTOCOMPLETE
constexpr OUStringLiteral PROPERTY_READONLY
constexpr OUStringLiteral PROPERTY_TEXT
constexpr OUStringLiteral PROPERTY_REFVALUE
constexpr OUStringLiteral PROPERTY_STATE
constexpr OUStringLiteral PROPERTY_CLASSID
constexpr OUStringLiteral PROPERTY_VALUE_SEQ
constexpr OUStringLiteral PROPERTY_TABLENAME
constexpr OUStringLiteral PROPERTY_TRISTATE
constexpr OUStringLiteral PROPERTY_REALNAME
constexpr OUStringLiteral PROPERTY_STRINGITEMLIST
constexpr OUStringLiteral PROPERTY_MULTILINE
Sequence< PropertyValue > aArguments
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
OUString loadString(TranslateId aResId)
loads the string with the specified resource id from the FormLayer mo file
ListBox is a bit confusing / different from other form components, so here are a few notes:
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
bool getPropertyValue(ValueType &rValue, css::uno::Reference< css::beans::XPropertySet > const &xPropSet, OUString const &propName)
Reference< XModel > xModel