/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_forms.hxx" #include "Filter.hxx" #include "FormComponent.hxx" #include "frm_module.hxx" #include "frm_resource.hrc" #include "frm_resource.hxx" #include "property.hrc" #include "property.hxx" /** === begin UNO includes === **/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** === end UNO includes === **/ #include #include #include #include #include #include #include #include #include #include #include #include #include //-------------------------------------------------------------------------- extern "C" void SAL_CALL createRegistryInfo_OFilterControl() { static ::frm::OMultiInstanceAutoRegistration< ::frm::OFilterControl > aAutoRegistration; } //......................................................................... namespace frm { //......................................................................... using namespace ::com::sun::star::uno; using namespace ::com::sun::star::awt; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::sdb; using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::sdbcx; using namespace ::com::sun::star::util; using namespace ::com::sun::star::form; using namespace ::com::sun::star::container; using namespace ::com::sun::star::ui::dialogs; using namespace ::connectivity; //===================================================================== // OFilterControl //===================================================================== //--------------------------------------------------------------------- OFilterControl::OFilterControl( const Reference< XMultiServiceFactory >& _rxORB ) :m_aTextListeners( *this ) ,m_aContext( _rxORB ) ,m_aParser( _rxORB ) ,m_nControlClass( FormComponentType::TEXTFIELD ) ,m_bFilterList( sal_False ) ,m_bMultiLine( sal_False ) ,m_bFilterListFilled( sal_False ) { } //--------------------------------------------------------------------- sal_Bool OFilterControl::ensureInitialized( ) { if ( !m_xField.is() ) { OSL_ENSURE( sal_False, "OFilterControl::ensureInitialized: improperly initialized: no field!" ); return sal_False; } if ( !m_xConnection.is() ) { OSL_ENSURE( sal_False, "OFilterControl::ensureInitialized: improperly initialized: no connection!" ); return sal_False; } if ( !m_xFormatter.is() ) { // we can create one from the connection, if it's an SDB connection Reference< XNumberFormatsSupplier > xFormatSupplier = ::dbtools::getNumberFormats( m_xConnection, sal_True, m_aContext.getLegacyServiceFactory() ); if ( xFormatSupplier.is() ) { m_aContext.createComponent( "com.sun.star.util.NumberFormatter", m_xFormatter ); if ( m_xFormatter.is() ) m_xFormatter->attachNumberFormatsSupplier( xFormatSupplier ); } } if ( !m_xFormatter.is() ) { OSL_ENSURE( sal_False, "OFilterControl::ensureInitialized: no number formatter!" ); // no fallback anymore return sal_False; } return sal_True; } //--------------------------------------------------------------------- Any SAL_CALL OFilterControl::queryAggregation( const Type & rType ) throw(RuntimeException) { Any aRet = UnoControl::queryAggregation( rType); if(!aRet.hasValue()) aRet = OFilterControl_BASE::queryInterface(rType); return aRet; } //------------------------------------------------------------------ ::rtl::OUString OFilterControl::GetComponentServiceName() { ::rtl::OUString aServiceName; switch (m_nControlClass) { case FormComponentType::RADIOBUTTON: aServiceName = ::rtl::OUString::createFromAscii("radiobutton"); break; case FormComponentType::CHECKBOX: aServiceName = ::rtl::OUString::createFromAscii("checkbox"); break; case FormComponentType::COMBOBOX: aServiceName = ::rtl::OUString::createFromAscii("combobox"); break; case FormComponentType::LISTBOX: aServiceName = ::rtl::OUString::createFromAscii("listbox"); break; default: if (m_bMultiLine) aServiceName = ::rtl::OUString::createFromAscii("MultiLineEdit"); else aServiceName = ::rtl::OUString::createFromAscii("Edit"); } return aServiceName; } // XComponent //--------------------------------------------------------------------- void OFilterControl::dispose() throw( RuntimeException ) { EventObject aEvt(*this); m_aTextListeners.disposeAndClear( aEvt ); UnoControl::dispose(); } //--------------------------------------------------------------------- void OFilterControl::createPeer( const Reference< XToolkit > & rxToolkit, const Reference< XWindowPeer > & rParentPeer ) throw(RuntimeException) { UnoControl::createPeer( rxToolkit, rParentPeer ); try { Reference< XVclWindowPeer > xVclWindow( getPeer(), UNO_QUERY_THROW ); switch ( m_nControlClass ) { case FormComponentType::CHECKBOX: { // checkboxes always have a tristate-mode xVclWindow->setProperty( PROPERTY_TRISTATE, makeAny( sal_Bool( sal_True ) ) ); xVclWindow->setProperty( PROPERTY_STATE, makeAny( sal_Int32( STATE_DONTKNOW ) ) ); Reference< XCheckBox > xBox( getPeer(), UNO_QUERY_THROW ); xBox->addItemListener( this ); } break; case FormComponentType::RADIOBUTTON: { xVclWindow->setProperty( PROPERTY_STATE, makeAny( sal_Int32( STATE_NOCHECK ) ) ); Reference< XRadioButton > xRadio( getPeer(), UNO_QUERY_THROW ); xRadio->addItemListener( this ); } break; case FormComponentType::LISTBOX: { Reference< XListBox > xListBox( getPeer(), UNO_QUERY_THROW ); xListBox->addItemListener( this ); } // no break case FormComponentType::COMBOBOX: { xVclWindow->setProperty(PROPERTY_AUTOCOMPLETE, makeAny( sal_Bool( sal_True ) ) ); } // no break default: { Reference< XWindow > xWindow( getPeer(), UNO_QUERY ); xWindow->addFocusListener( this ); Reference< XTextComponent > xText( getPeer(), UNO_QUERY ); if (xText.is()) xText->setMaxTextLen(0); } break; } OControl::initFormControlPeer( getPeer() ); // filter controls are _never_ readonly // #107013# - 2002-02-03 - fs@openoffice.org Reference< XPropertySet > xModel( getModel(), UNO_QUERY_THROW ); Reference< XPropertySetInfo > xModelPSI( xModel->getPropertySetInfo(), UNO_SET_THROW ); if ( xModelPSI->hasPropertyByName( PROPERTY_READONLY ) ) xVclWindow->setProperty( PROPERTY_READONLY, makeAny( sal_Bool( sal_False ) ) ); } catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); } if (m_bFilterList) m_bFilterListFilled = sal_False; } //--------------------------------------------------------------------- void OFilterControl::PrepareWindowDescriptor( WindowDescriptor& rDescr ) { if (m_bFilterList) rDescr.WindowAttributes |= VclWindowPeerAttribute::DROPDOWN; } //--------------------------------------------------------------------- void OFilterControl::ImplSetPeerProperty( const ::rtl::OUString& rPropName, const Any& rVal ) { // these properties are ignored if (rPropName == PROPERTY_TEXT || rPropName == PROPERTY_STATE) return; UnoControl::ImplSetPeerProperty( rPropName, rVal ); } // XEventListener //--------------------------------------------------------------------- void SAL_CALL OFilterControl::disposing(const EventObject& Source) throw( RuntimeException ) { UnoControl::disposing(Source); } // XItemListener //--------------------------------------------------------------------- void SAL_CALL OFilterControl::itemStateChanged( const ItemEvent& rEvent ) throw(RuntimeException) { ::rtl::OUStringBuffer aText; switch (m_nControlClass) { case FormComponentType::CHECKBOX: { if ( ( rEvent.Selected == STATE_CHECK ) || ( rEvent.Selected == STATE_NOCHECK ) ) { sal_Int32 nBooleanComparisonMode = ::dbtools::DatabaseMetaData( m_xConnection ).getBooleanComparisonMode(); bool bSelected = ( rEvent.Selected == STATE_CHECK ); ::rtl::OUString sExpressionMarker( RTL_CONSTASCII_USTRINGPARAM( "$expression$" ) ); ::dbtools::getBoleanComparisonPredicate( sExpressionMarker, bSelected, nBooleanComparisonMode, aText ); ::rtl::OUString sText( aText.makeStringAndClear() ); sal_Int32 nMarkerPos( sText.indexOf( sExpressionMarker ) ); OSL_ENSURE( nMarkerPos == 0, "OFilterControl::itemStateChanged: unsupported boolean comparison mode!" ); // If this assertion fails, then getBoleanComparisonPredicate created a predicate which // does not start with the expression we gave it. The only known case is when // the comparison mode is ACCESS_COMPAT, and the value is TRUE. In this case, // the expression is rather complex. // Well, so this is a known issue - the filter controls (and thus the form based filter) // do not work with boolean MS Access fields. // To fix this, we would probably have to revert here to always return "1" or "0" as normalized // filter, and change our client code to properly translate this (which could be some effort). if ( nMarkerPos == 0 ) aText.append( sText.copy( sExpressionMarker.getLength() ) ); else { // fallback aText.appendAscii( bSelected ? "1" : "0" ); } } } break; case FormComponentType::LISTBOX: { Sequence< ::rtl::OUString> aValueSelection; Reference< XPropertySet > aPropertyPointer(getModel(), UNO_QUERY); aPropertyPointer->getPropertyValue(PROPERTY_VALUE_SEQ) >>= aValueSelection; if (rEvent.Selected <= aValueSelection.getLength()) aText.append( aValueSelection[ rEvent.Selected ] ); } break; case FormComponentType::RADIOBUTTON: { if ( rEvent.Selected == STATE_CHECK ) aText.append( ::comphelper::getString( Reference< XPropertySet >( getModel(), UNO_QUERY )->getPropertyValue( PROPERTY_REFVALUE ) ) ); } break; } ::rtl::OUString sText( aText.makeStringAndClear() ); if ( m_aText.compareTo( sText ) ) { m_aText = sText; TextEvent aEvt; aEvt.Source = *this; ::cppu::OInterfaceIteratorHelper aIt( m_aTextListeners ); while( aIt.hasMoreElements() ) ((XTextListener *)aIt.next())->textChanged( aEvt ); } } //--------------------------------------------------------------------- void OFilterControl::implInitFilterList() { if ( !ensureInitialized( ) ) // already asserted in ensureInitialized return; // ensure the cursor and the statement are disposed as soon as we leave ::utl::SharedUNOComponent< XResultSet > xListCursor; ::utl::SharedUNOComponent< XStatement > xStatement; try { m_bFilterListFilled = sal_True; if ( !m_xField.is() ) return; ::rtl::OUString sFieldName; m_xField->getPropertyValue( PROPERTY_NAME ) >>= sFieldName; // here we need a table to which the field belongs to const Reference< XChild > xModelAsChild( getModel(), UNO_QUERY_THROW ); const Reference< XRowSet > xForm( xModelAsChild->getParent(), UNO_QUERY_THROW ); const Reference< XPropertySet > xFormProps( xForm, UNO_QUERY_THROW ); // create a query composer Reference< XColumnsSupplier > xSuppColumns; xFormProps->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SingleSelectQueryComposer"))) >>= xSuppColumns; const Reference< XConnection > xConnection( ::dbtools::getConnection( xForm ), UNO_SET_THROW ); const Reference< XNameAccess > xFieldNames( xSuppColumns->getColumns(), UNO_SET_THROW ); if ( !xFieldNames->hasByName( sFieldName ) ) return; ::rtl::OUString sRealFieldName, sTableName; const Reference< XPropertySet > xComposerFieldProps( xFieldNames->getByName( sFieldName ), UNO_QUERY_THROW ); xComposerFieldProps->getPropertyValue( PROPERTY_REALNAME ) >>= sRealFieldName; xComposerFieldProps->getPropertyValue( PROPERTY_TABLENAME ) >>= sTableName; // obtain the table of the field const Reference< XTablesSupplier > xSuppTables( xSuppColumns, UNO_QUERY_THROW ); const Reference< XNameAccess > xTablesNames( xSuppTables->getTables(), UNO_SET_THROW ); const Reference< XNamed > xNamedTable( xTablesNames->getByName( sTableName ), UNO_QUERY_THROW ); sTableName = xNamedTable->getName(); // create a statement selecting all values for the given field ::rtl::OUStringBuffer aStatement; const Reference< XDatabaseMetaData > xMeta( xConnection->getMetaData(), UNO_SET_THROW ); const ::rtl::OUString sQuoteChar = xMeta->getIdentifierQuoteString(); aStatement.appendAscii( "SELECT DISTINCT " ); aStatement.append( sQuoteChar ); aStatement.append( sRealFieldName ); aStatement.append( sQuoteChar ); // if the field had an alias in our form's statement, give it this alias in the new statement, too if ( sFieldName.getLength() && ( sFieldName != sRealFieldName ) ) { aStatement.appendAscii(" AS "); aStatement.append( sQuoteChar ); aStatement.append( sFieldName ); aStatement.append( sQuoteChar ); } aStatement.appendAscii( " FROM " ); ::rtl::OUString sCatalog, sSchema, sTable; ::dbtools::qualifiedNameComponents( xMeta, sTableName, sCatalog, sSchema, sTable, ::dbtools::eInDataManipulation ); aStatement.append( ::dbtools::composeTableNameForSelect( xConnection, sCatalog, sSchema, sTable ) ); // execute the statement xStatement.reset( xConnection->createStatement() ); const ::rtl::OUString sSelectStatement( aStatement.makeStringAndClear( ) ); xListCursor.reset( xStatement->executeQuery( sSelectStatement ) ); // retrieve the one column which we take the values from const Reference< XColumnsSupplier > xSupplyCols( xListCursor, UNO_QUERY_THROW ); const Reference< XIndexAccess > xFields( xSupplyCols->getColumns(), UNO_QUERY_THROW ); const Reference< XPropertySet > xDataField( xFields->getByIndex(0), UNO_QUERY_THROW ); // ensure the values will be formatted according to the field format const ::dbtools::FormattedColumnValue aFormatter( m_xFormatter, xDataField ); ::std::vector< ::rtl::OUString > aProposals; aProposals.reserve(16); while ( xListCursor->next() && ( aProposals.size() < size_t( SHRT_MAX ) ) ) { const ::rtl::OUString sCurrentValue = aFormatter.getFormattedValue(); aProposals.push_back( sCurrentValue ); } // fill the list items into our peer Sequence< ::rtl::OUString> aStringSeq( aProposals.size() ); ::std::copy( aProposals.begin(), aProposals.end(), aStringSeq.getArray() ); const Reference< XComboBox > xComboBox( getPeer(), UNO_QUERY_THROW ); xComboBox->addItems( aStringSeq, 0 ); // set the drop down line count to something reasonable const sal_Int16 nLineCount = ::std::min( sal_Int16( 16 ), sal_Int16( aStringSeq.getLength() ) ); xComboBox->setDropDownLineCount( nLineCount ); } catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); } } // XFocusListener //--------------------------------------------------------------------- void SAL_CALL OFilterControl::focusGained(const FocusEvent& /*e*/) throw( RuntimeException ) { // should we fill the combobox? if (m_bFilterList && !m_bFilterListFilled) implInitFilterList(); } //--------------------------------------------------------------------- void SAL_CALL OFilterControl::focusLost(const FocusEvent& /*e*/) throw( RuntimeException ) { } //--------------------------------------------------------------------- sal_Bool SAL_CALL OFilterControl::commit() throw(RuntimeException) { if ( !ensureInitialized( ) ) // already asserted in ensureInitialized return sal_True; ::rtl::OUString aText; switch (m_nControlClass) { case FormComponentType::TEXTFIELD: case FormComponentType::COMBOBOX: { Reference< XTextComponent > xText( getPeer(), UNO_QUERY ); if (xText.is()) aText = xText->getText(); } break; default: return sal_True; } if (m_aText.compareTo(aText)) { // check the text with the SQL-Parser ::rtl::OUString aNewText(aText); aNewText.trim(); if ( aNewText.getLength() ) { ::dbtools::OPredicateInputController aPredicateInput( m_aContext.getLegacyServiceFactory(), m_xConnection, getParseContext() ); ::rtl::OUString sErrorMessage; if ( !aPredicateInput.normalizePredicateString( aNewText, m_xField, &sErrorMessage ) ) { // display the error and outta here SQLContext aError; aError.Message = String( FRM_RES_STRING( RID_STR_SYNTAXERROR ) ); aError.Details = sErrorMessage; displayException( aError ); return sal_False; } } setText(aNewText); TextEvent aEvt; aEvt.Source = *this; ::cppu::OInterfaceIteratorHelper aIt( m_aTextListeners ); while( aIt.hasMoreElements() ) static_cast< XTextListener* >( aIt.next() )->textChanged( aEvt ); } return sal_True; } // XTextComponent //--------------------------------------------------------------------- void SAL_CALL OFilterControl::addTextListener(const Reference< XTextListener > & l) throw(RuntimeException) { m_aTextListeners.addInterface( l ); } //--------------------------------------------------------------------- void SAL_CALL OFilterControl::removeTextListener(const Reference< XTextListener > & l) throw(RuntimeException) { m_aTextListeners.removeInterface( l ); } //--------------------------------------------------------------------- void SAL_CALL OFilterControl::setText( const ::rtl::OUString& aText ) throw(RuntimeException) { if ( !ensureInitialized( ) ) // already asserted in ensureInitialized return; switch (m_nControlClass) { case FormComponentType::CHECKBOX: { Reference< XVclWindowPeer > xVclWindow( getPeer(), UNO_QUERY ); if (xVclWindow.is()) { Any aValue; if ( aText.equalsAscii( "1" ) || aText.equalsIgnoreAsciiCaseAscii( "TRUE" ) || aText.equalsIgnoreAsciiCaseAscii( "IS TRUE" ) ) { aValue <<= (sal_Int32)STATE_CHECK; } else if ( aText.equalsAscii( "0" ) || aText.equalsIgnoreAsciiCaseAscii( "FALSE" ) ) { aValue <<= (sal_Int32)STATE_NOCHECK; } else aValue <<= (sal_Int32)STATE_DONTKNOW; m_aText = aText; xVclWindow->setProperty( PROPERTY_STATE, aValue ); } } break; case FormComponentType::RADIOBUTTON: { Reference< XVclWindowPeer > xVclWindow( getPeer(), UNO_QUERY ); if (xVclWindow.is()) { ::rtl::OUString aRefText = ::comphelper::getString(com::sun::star::uno::Reference< XPropertySet > (getModel(), UNO_QUERY)->getPropertyValue(PROPERTY_REFVALUE)); Any aValue; if (aText == aRefText) aValue <<= (sal_Int32)STATE_CHECK; else aValue <<= (sal_Int32)STATE_NOCHECK; m_aText = aText; xVclWindow->setProperty(PROPERTY_STATE, aValue); } } break; case FormComponentType::LISTBOX: { Reference< XListBox > xListBox( getPeer(), UNO_QUERY ); if (xListBox.is()) { m_aText = aText; xListBox->selectItem(m_aText, sal_True); } } break; default: { Reference< XTextComponent > xText( getPeer(), UNO_QUERY ); if (xText.is()) { m_aText = aText; xText->setText(aText); } } } } //--------------------------------------------------------------------- void SAL_CALL OFilterControl::insertText( const ::com::sun::star::awt::Selection& rSel, const ::rtl::OUString& aText ) throw(::com::sun::star::uno::RuntimeException) { Reference< XTextComponent > xText( getPeer(), UNO_QUERY ); if (xText.is()) { xText->insertText(rSel, aText); m_aText = xText->getText(); } } //--------------------------------------------------------------------- ::rtl::OUString SAL_CALL OFilterControl::getText() throw(RuntimeException) { return m_aText; } //--------------------------------------------------------------------- ::rtl::OUString SAL_CALL OFilterControl::getSelectedText( void ) throw(RuntimeException) { ::rtl::OUString aSelected; Reference< XTextComponent > xText( getPeer(), UNO_QUERY ); if (xText.is()) aSelected = xText->getSelectedText(); return aSelected; } //--------------------------------------------------------------------- void SAL_CALL OFilterControl::setSelection( const ::com::sun::star::awt::Selection& aSelection ) throw(::com::sun::star::uno::RuntimeException) { Reference< XTextComponent > xText( getPeer(), UNO_QUERY ); if (xText.is()) xText->setSelection( aSelection ); } //--------------------------------------------------------------------- ::com::sun::star::awt::Selection SAL_CALL OFilterControl::getSelection( void ) throw(::com::sun::star::uno::RuntimeException) { ::com::sun::star::awt::Selection aSel; Reference< XTextComponent > xText( getPeer(), UNO_QUERY ); if (xText.is()) aSel = xText->getSelection(); return aSel; } //--------------------------------------------------------------------- sal_Bool SAL_CALL OFilterControl::isEditable( void ) throw(RuntimeException) { Reference< XTextComponent > xText( getPeer(), UNO_QUERY ); return xText.is() && xText->isEditable(); } //--------------------------------------------------------------------- void SAL_CALL OFilterControl::setEditable( sal_Bool bEditable ) throw(RuntimeException) { Reference< XTextComponent > xText( getPeer(), UNO_QUERY ); if (xText.is()) xText->setEditable(bEditable); } //--------------------------------------------------------------------- sal_Int16 SAL_CALL OFilterControl::getMaxTextLen() throw(RuntimeException) { Reference< XTextComponent > xText( getPeer(), UNO_QUERY ); return xText.is() ? xText->getMaxTextLen() : 0; } //--------------------------------------------------------------------- void SAL_CALL OFilterControl::setMaxTextLen( sal_Int16 nLength ) throw(RuntimeException) { Reference< XTextComponent > xText( getPeer(), UNO_QUERY ); if (xText.is()) xText->setMaxTextLen(nLength); } //--------------------------------------------------------------------- void OFilterControl::displayException( const ::com::sun::star::sdb::SQLContext& _rExcept ) { try { Sequence< Any > aArgs(2); aArgs[0] <<= PropertyValue(::rtl::OUString::createFromAscii("SQLException"), 0, makeAny( _rExcept ), PropertyState_DIRECT_VALUE); aArgs[1] <<= PropertyValue(::rtl::OUString::createFromAscii("ParentWindow"), 0, makeAny( m_xMessageParent ), PropertyState_DIRECT_VALUE); static ::rtl::OUString s_sDialogServiceName = ::rtl::OUString::createFromAscii( "com.sun.star.sdb.ErrorMessageDialog" ); Reference< XExecutableDialog > xErrorDialog( m_aContext.createComponentWithArguments( s_sDialogServiceName, aArgs ), UNO_QUERY ); if ( xErrorDialog.is() ) xErrorDialog->execute(); else { Window* pMessageParent = VCLUnoHelper::GetWindow( m_xMessageParent ); ShowServiceNotAvailableError( pMessageParent, s_sDialogServiceName, sal_True ); } } catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); } } //--------------------------------------------------------------------- void SAL_CALL OFilterControl::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException) { const Any* pArguments = aArguments.getConstArray(); const Any* pArgumentsEnd = pArguments + aArguments.getLength(); PropertyValue aProp; NamedValue aValue; const ::rtl::OUString* pName = NULL; const Any* pValue = NULL; for ( ; pArguments != pArgumentsEnd; ++pArguments ) { // we recognize PropertyValues and NamedValues if ( *pArguments >>= aProp ) { pName = &aProp.Name; pValue = &aProp.Value; } else if ( *pArguments >>= aValue ) { pName = &aValue.Name; pValue = &aValue.Value; } else { DBG_ERROR( "OFilterControl::initialize: unrecognized argument!" ); continue; } if ( 0 == pName->compareToAscii( "MessageParent" ) ) { // the message parent *pValue >>= m_xMessageParent; OSL_ENSURE( m_xMessageParent.is(), "OFilterControl::initialize: invalid MessageParent!" ); } else if ( 0 == pName->compareToAscii( "NumberFormatter" ) ) { // the number format. This argument is optional. *pValue >>= m_xFormatter; OSL_ENSURE( m_xFormatter.is(), "OFilterControl::initialize: invalid NumberFormatter!" ); } else if ( 0 == pName->compareToAscii( "ControlModel" ) ) { // the control model for which we act as filter control Reference< XPropertySet > xControlModel; if ( !(*pValue >>= xControlModel ) || !xControlModel.is() ) { OSL_ENSURE( sal_False, "OFilterControl::initialize: invalid control model argument!" ); continue; } // some properties which are "derived" from the control model we're working for // ................................................... // the field m_xField.clear(); OSL_ENSURE( ::comphelper::hasProperty( PROPERTY_BOUNDFIELD, xControlModel ), "OFilterControl::initialize: control model needs a bound field property!" ); xControlModel->getPropertyValue( PROPERTY_BOUNDFIELD ) >>= m_xField; // ................................................... // filter list and control class m_bFilterList = ::comphelper::hasProperty( PROPERTY_FILTERPROPOSAL, xControlModel ) && ::comphelper::getBOOL( xControlModel->getPropertyValue( PROPERTY_FILTERPROPOSAL ) ); if ( m_bFilterList ) m_nControlClass = FormComponentType::COMBOBOX; else { sal_Int16 nClassId = ::comphelper::getINT16( xControlModel->getPropertyValue( PROPERTY_CLASSID ) ); switch (nClassId) { case FormComponentType::CHECKBOX: case FormComponentType::RADIOBUTTON: case FormComponentType::LISTBOX: case FormComponentType::COMBOBOX: m_nControlClass = nClassId; break; default: m_bMultiLine = ::comphelper::hasProperty( PROPERTY_MULTILINE, xControlModel ) && ::comphelper::getBOOL( xControlModel->getPropertyValue( PROPERTY_MULTILINE ) ); m_nControlClass = FormComponentType::TEXTFIELD; break; } } // ................................................... // the connection meta data for the form which we're working for Reference< XChild > xModel( xControlModel, UNO_QUERY ); Reference< XRowSet > xForm; if ( xModel.is() ) xForm = xForm.query( xModel->getParent() ); m_xConnection = ::dbtools::getConnection( xForm ); OSL_ENSURE( m_xConnection.is(), "OFilterControl::initialize: unable to determine the form's connection!" ); } } } //--------------------------------------------------------------------- ::rtl::OUString SAL_CALL OFilterControl::getImplementationName( ) throw (RuntimeException) { return getImplementationName_Static(); } //--------------------------------------------------------------------- sal_Bool SAL_CALL OFilterControl::supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException) { Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() ); const ::rtl::OUString* pArray = aSupported.getConstArray(); for( sal_Int32 i = 0; i < aSupported.getLength(); ++i, ++pArray ) if( pArray->equals( ServiceName ) ) return sal_True; return sal_False; } //--------------------------------------------------------------------- Sequence< ::rtl::OUString > SAL_CALL OFilterControl::getSupportedServiceNames( ) throw (RuntimeException) { return getSupportedServiceNames_Static(); } //--------------------------------------------------------------------- ::rtl::OUString SAL_CALL OFilterControl::getImplementationName_Static() { return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.forms.OFilterControl" ) ); } //--------------------------------------------------------------------- Sequence< ::rtl::OUString > SAL_CALL OFilterControl::getSupportedServiceNames_Static() { Sequence< ::rtl::OUString > aNames( 2 ); aNames[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.control.FilterControl" ) ); aNames[ 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControl" ) ); return aNames; } //--------------------------------------------------------------------- Reference< XInterface > SAL_CALL OFilterControl::Create( const Reference< XMultiServiceFactory >& _rxFactory ) { return static_cast< XServiceInfo* >( new OFilterControl( _rxFactory ) ); } //......................................................................... } // namespace frm //.........................................................................