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 .
21 #include "FormComponent.hxx"
22 #include "frm_resource.hrc"
23 #include "frm_resource.hxx"
24 #include "property.hrc"
25 #include "property.hxx"
26 #include "services.hxx"
28 #include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
29 #include <com/sun/star/awt/XCheckBox.hpp>
30 #include <com/sun/star/awt/XComboBox.hpp>
31 #include <com/sun/star/awt/XListBox.hpp>
32 #include <com/sun/star/awt/XRadioButton.hpp>
33 #include <com/sun/star/awt/XVclWindowPeer.hpp>
34 #include <com/sun/star/beans/NamedValue.hpp>
35 #include <com/sun/star/container/XChild.hpp>
36 #include <com/sun/star/container/XIndexAccess.hpp>
37 #include <com/sun/star/container/XNamed.hpp>
38 #include <com/sun/star/form/FormComponentType.hpp>
39 #include <com/sun/star/sdb/BooleanComparisonMode.hpp>
40 #include <com/sun/star/sdb/ErrorMessageDialog.hpp>
41 #include <com/sun/star/sdb/XColumn.hpp>
42 #include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
43 #include <com/sun/star/sdbc/DataType.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/numbers.hxx>
52 #include <comphelper/processfactory.hxx>
53 #include <comphelper/property.hxx>
54 #include <cppuhelper/supportsservice.hxx>
55 #include <connectivity/dbconversion.hxx>
56 #include <connectivity/dbtools.hxx>
57 #include <connectivity/formattedcolumnvalue.hxx>
58 #include <connectivity/predicateinput.hxx>
59 #include <rtl/ustrbuf.hxx>
60 #include <toolkit/helper/vclunohelper.hxx>
61 #include <tools/diagnose_ex.h>
62 #include <unotools/localedatawrapper.hxx>
63 #include <vcl/stdtext.hxx>
64 #include <vcl/svapp.hxx>
65 #include <tools/wintypes.hxx>
70 using namespace ::com::sun::star::uno
;
71 using namespace ::com::sun::star::awt
;
72 using namespace ::com::sun::star::lang
;
73 using namespace ::com::sun::star::beans
;
74 using namespace ::com::sun::star::sdb
;
75 using namespace ::com::sun::star::sdbc
;
76 using namespace ::com::sun::star::sdbcx
;
77 using namespace ::com::sun::star::util
;
78 using namespace ::com::sun::star::form
;
79 using namespace ::com::sun::star::container
;
80 using namespace ::com::sun::star::ui::dialogs
;
82 using namespace ::connectivity
;
84 OFilterControl::OFilterControl( const Reference
< XComponentContext
>& _rxORB
)
86 ,m_aTextListeners( *this )
88 #if HAVE_FEATURE_DBCONNECTIVITY
91 ,m_nControlClass( FormComponentType::TEXTFIELD
)
92 ,m_bFilterList( false )
93 ,m_bMultiLine( false )
94 ,m_bFilterListFilled( false )
99 bool OFilterControl::ensureInitialized( )
101 #if HAVE_FEATURE_DBCONNECTIVITY
102 if ( !m_xField
.is() )
104 OSL_FAIL( "OFilterControl::ensureInitialized: improperly initialized: no field!" );
108 if ( !m_xConnection
.is() )
110 OSL_FAIL( "OFilterControl::ensureInitialized: improperly initialized: no connection!" );
114 if ( !m_xFormatter
.is() )
116 // we can create one from the connection, if it's an SDB connection
118 Reference
< XNumberFormatsSupplier
> xFormatSupplier
= ::dbtools::getNumberFormats( m_xConnection
, true, m_xContext
);
120 if ( xFormatSupplier
.is() )
122 m_xFormatter
.set(NumberFormatter::create(m_xContext
), UNO_QUERY_THROW
);
123 m_xFormatter
->attachNumberFormatsSupplier( xFormatSupplier
);
126 if ( !m_xFormatter
.is() )
128 OSL_FAIL( "OFilterControl::ensureInitialized: no number formatter!" );
129 // no fallback anymore
137 Any SAL_CALL
OFilterControl::queryAggregation( const Type
& rType
) throw(RuntimeException
, std::exception
)
139 Any aRet
= UnoControl::queryAggregation( rType
);
141 aRet
= OFilterControl_BASE::queryInterface(rType
);
147 OUString
OFilterControl::GetComponentServiceName()
149 OUString aServiceName
;
150 switch (m_nControlClass
)
152 case FormComponentType::RADIOBUTTON
:
153 aServiceName
= "radiobutton";
155 case FormComponentType::CHECKBOX
:
156 aServiceName
= "checkbox";
158 case FormComponentType::COMBOBOX
:
159 aServiceName
= "combobox";
161 case FormComponentType::LISTBOX
:
162 aServiceName
= "listbox";
166 aServiceName
= "MultiLineEdit";
168 aServiceName
= "Edit";
175 void OFilterControl::dispose() throw( RuntimeException
, std::exception
)
177 EventObject
aEvt(*this);
178 m_aTextListeners
.disposeAndClear( aEvt
);
179 UnoControl::dispose();
183 void OFilterControl::createPeer( const Reference
< XToolkit
> & rxToolkit
, const Reference
< XWindowPeer
> & rParentPeer
) throw(RuntimeException
, std::exception
)
185 UnoControl::createPeer( rxToolkit
, rParentPeer
);
189 Reference
< XVclWindowPeer
> xVclWindow( getPeer(), UNO_QUERY_THROW
);
190 switch ( m_nControlClass
)
192 case FormComponentType::CHECKBOX
:
194 // checkboxes always have a tristate-mode
195 xVclWindow
->setProperty( PROPERTY_TRISTATE
, makeAny( true ) );
196 xVclWindow
->setProperty( PROPERTY_STATE
, makeAny( sal_Int32( TRISTATE_INDET
) ) );
198 Reference
< XCheckBox
> xBox( getPeer(), UNO_QUERY_THROW
);
199 xBox
->addItemListener( this );
204 case FormComponentType::RADIOBUTTON
:
206 xVclWindow
->setProperty( PROPERTY_STATE
, makeAny( sal_Int32( TRISTATE_FALSE
) ) );
208 Reference
< XRadioButton
> xRadio( getPeer(), UNO_QUERY_THROW
);
209 xRadio
->addItemListener( this );
213 case FormComponentType::LISTBOX
:
215 Reference
< XListBox
> xListBox( getPeer(), UNO_QUERY_THROW
);
216 xListBox
->addItemListener( this );
220 case FormComponentType::COMBOBOX
:
222 xVclWindow
->setProperty(PROPERTY_AUTOCOMPLETE
, makeAny( true ) );
228 Reference
< XWindow
> xWindow( getPeer(), UNO_QUERY
);
229 xWindow
->addFocusListener( this );
231 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
233 xText
->setMaxTextLen(0);
238 // filter controls are _never_ readonly
239 Reference
< XPropertySet
> xModel( getModel(), UNO_QUERY_THROW
);
240 Reference
< XPropertySetInfo
> xModelPSI( xModel
->getPropertySetInfo(), UNO_SET_THROW
);
241 if ( xModelPSI
->hasPropertyByName( PROPERTY_READONLY
) )
242 xVclWindow
->setProperty( PROPERTY_READONLY
, makeAny( false ) );
244 catch( const Exception
& )
246 DBG_UNHANDLED_EXCEPTION();
250 m_bFilterListFilled
= false;
254 void OFilterControl::PrepareWindowDescriptor( WindowDescriptor
& rDescr
)
257 rDescr
.WindowAttributes
|= VclWindowPeerAttribute::DROPDOWN
;
261 void OFilterControl::ImplSetPeerProperty( const OUString
& rPropName
, const Any
& rVal
)
263 // these properties are ignored
264 if (rPropName
== PROPERTY_TEXT
||
265 rPropName
== PROPERTY_STATE
)
268 UnoControl::ImplSetPeerProperty( rPropName
, rVal
);
273 void SAL_CALL
OFilterControl::disposing(const EventObject
& Source
) throw( RuntimeException
, std::exception
)
275 UnoControl::disposing(Source
);
280 void SAL_CALL
OFilterControl::itemStateChanged( const ItemEvent
& rEvent
) throw(RuntimeException
, std::exception
)
282 #if !HAVE_FEATURE_DBCONNECTIVITY
285 OUStringBuffer aText
;
286 switch (m_nControlClass
)
288 case FormComponentType::CHECKBOX
:
290 if ( ( rEvent
.Selected
== TRISTATE_TRUE
) || ( rEvent
.Selected
== TRISTATE_FALSE
) )
292 sal_Int32 nBooleanComparisonMode
= ::dbtools::DatabaseMetaData( m_xConnection
).getBooleanComparisonMode();
294 bool bSelected
= ( rEvent
.Selected
== TRISTATE_TRUE
);
296 OUString
sExpressionMarker( "$expression$" );
297 ::dbtools::getBooleanComparisonPredicate(
300 nBooleanComparisonMode
,
304 OUString
sText( aText
.makeStringAndClear() );
305 sal_Int32
nMarkerPos( sText
.indexOf( sExpressionMarker
) );
306 OSL_ENSURE( nMarkerPos
== 0, "OFilterControl::itemStateChanged: unsupported boolean comparison mode!" );
307 // If this assertion fails, then getBoleanComparisonPredicate created a predicate which
308 // does not start with the expression we gave it. The only known case is when
309 // the comparison mode is ACCESS_COMPAT, and the value is TRUE. In this case,
310 // the expression is rather complex.
311 // Well, so this is a known issue - the filter controls (and thus the form based filter)
312 // do not work with boolean MS Access fields.
313 // To fix this, we would probably have to revert here to always return "1" or "0" as normalized
314 // filter, and change our client code to properly translate this (which could be some effort).
315 if ( nMarkerPos
== 0 )
316 aText
.append( sText
.copy( sExpressionMarker
.getLength() ) );
320 aText
.appendAscii( bSelected
? "1" : "0" );
326 case FormComponentType::LISTBOX
:
330 const Reference
< XItemList
> xItemList( getModel(), UNO_QUERY_THROW
);
331 OUString
sItemText( xItemList
->getItemText( rEvent
.Selected
) );
333 const MapString2String::const_iterator itemPos
= m_aDisplayItemToValueItem
.find( sItemText
);
334 if ( itemPos
!= m_aDisplayItemToValueItem
.end() )
336 sItemText
= itemPos
->second
;
337 if ( !sItemText
.isEmpty() )
339 ::dbtools::OPredicateInputController
aPredicateInput( m_xContext
, m_xConnection
, getParseContext() );
340 OUString sErrorMessage
;
341 OSL_VERIFY( aPredicateInput
.normalizePredicateString( sItemText
, m_xField
, &sErrorMessage
) );
344 aText
.append( sItemText
);
346 catch( const Exception
& )
348 DBG_UNHANDLED_EXCEPTION();
353 case FormComponentType::RADIOBUTTON
:
355 if ( rEvent
.Selected
== TRISTATE_TRUE
)
356 aText
.append( ::comphelper::getString( Reference
< XPropertySet
>( getModel(), UNO_QUERY
)->getPropertyValue( PROPERTY_REFVALUE
) ) );
361 OUString
sText( aText
.makeStringAndClear() );
362 if ( m_aText
.compareTo( sText
) )
367 ::cppu::OInterfaceIteratorHelper
aIt( m_aTextListeners
);
368 while( aIt
.hasMoreElements() )
369 static_cast<XTextListener
*>(aIt
.next())->textChanged( aEvt
);
375 void OFilterControl::implInitFilterList()
377 #if HAVE_FEATURE_DBCONNECTIVITY
378 if ( !ensureInitialized( ) )
379 // already asserted in ensureInitialized
382 // ensure the cursor and the statement are disposed as soon as we leave
383 ::utl::SharedUNOComponent
< XResultSet
> xListCursor
;
384 ::utl::SharedUNOComponent
< XStatement
> xStatement
;
388 m_bFilterListFilled
= true;
390 if ( !m_xField
.is() )
394 m_xField
->getPropertyValue( PROPERTY_NAME
) >>= sFieldName
;
396 // here we need a table to which the field belongs to
397 const Reference
< XChild
> xModelAsChild( getModel(), UNO_QUERY_THROW
);
398 const Reference
< XRowSet
> xForm( xModelAsChild
->getParent(), UNO_QUERY_THROW
);
399 const Reference
< XPropertySet
> xFormProps( xForm
, UNO_QUERY_THROW
);
401 // create a query composer
402 Reference
< XColumnsSupplier
> xSuppColumns
;
403 xFormProps
->getPropertyValue("SingleSelectQueryComposer") >>= xSuppColumns
;
405 const Reference
< XConnection
> xConnection( ::dbtools::getConnection( xForm
), UNO_SET_THROW
);
406 const Reference
< XNameAccess
> xFieldNames( xSuppColumns
->getColumns(), UNO_SET_THROW
);
407 if ( !xFieldNames
->hasByName( sFieldName
) )
409 OUString sRealFieldName
, sTableName
;
410 const Reference
< XPropertySet
> xComposerFieldProps( xFieldNames
->getByName( sFieldName
), UNO_QUERY_THROW
);
411 xComposerFieldProps
->getPropertyValue( PROPERTY_REALNAME
) >>= sRealFieldName
;
412 xComposerFieldProps
->getPropertyValue( PROPERTY_TABLENAME
) >>= sTableName
;
414 // obtain the table of the field
415 const Reference
< XTablesSupplier
> xSuppTables( xSuppColumns
, UNO_QUERY_THROW
);
416 const Reference
< XNameAccess
> xTablesNames( xSuppTables
->getTables(), UNO_SET_THROW
);
417 const Reference
< XNamed
> xNamedTable( xTablesNames
->getByName( sTableName
), UNO_QUERY_THROW
);
418 sTableName
= xNamedTable
->getName();
420 // create a statement selecting all values for the given field
421 OUStringBuffer aStatement
;
423 const Reference
< XDatabaseMetaData
> xMeta( xConnection
->getMetaData(), UNO_SET_THROW
);
424 const OUString sQuoteChar
= xMeta
->getIdentifierQuoteString();
426 aStatement
.appendAscii( "SELECT DISTINCT " );
427 aStatement
.append( sQuoteChar
);
428 aStatement
.append( sRealFieldName
);
429 aStatement
.append( sQuoteChar
);
431 // if the field had an alias in our form's statement, give it this alias in the new statement, too
432 if ( !sFieldName
.isEmpty() && ( sFieldName
!= sRealFieldName
) )
434 aStatement
.appendAscii(" AS ");
435 aStatement
.append( sQuoteChar
);
436 aStatement
.append( sFieldName
);
437 aStatement
.append( sQuoteChar
);
440 aStatement
.appendAscii( " FROM " );
442 OUString sCatalog
, sSchema
, sTable
;
443 ::dbtools::qualifiedNameComponents( xMeta
, sTableName
, sCatalog
, sSchema
, sTable
, ::dbtools::eInDataManipulation
);
444 aStatement
.append( ::dbtools::composeTableNameForSelect( xConnection
, sCatalog
, sSchema
, sTable
) );
446 // execute the statement
447 xStatement
.reset( xConnection
->createStatement() );
448 const OUString
sSelectStatement( aStatement
.makeStringAndClear( ) );
449 xListCursor
.reset( xStatement
->executeQuery( sSelectStatement
) );
451 // retrieve the one column which we take the values from
452 const Reference
< XColumnsSupplier
> xSupplyCols( xListCursor
, UNO_QUERY_THROW
);
453 const Reference
< XIndexAccess
> xFields( xSupplyCols
->getColumns(), UNO_QUERY_THROW
);
454 const Reference
< XPropertySet
> xDataField( xFields
->getByIndex(0), UNO_QUERY_THROW
);
456 // ensure the values will be formatted according to the field format
457 const ::dbtools::FormattedColumnValue
aFormatter( m_xFormatter
, xDataField
);
459 ::std::vector
< OUString
> aProposals
;
460 aProposals
.reserve(16);
462 while ( xListCursor
->next() && ( aProposals
.size() < size_t( SHRT_MAX
) ) )
464 const OUString sCurrentValue
= aFormatter
.getFormattedValue();
465 aProposals
.push_back( sCurrentValue
);
468 // fill the list items into our peer
469 Sequence
< OUString
> aStringSeq( aProposals
.size() );
470 ::std::copy( aProposals
.begin(), aProposals
.end(), aStringSeq
.getArray() );
472 const Reference
< XComboBox
> xComboBox( getPeer(), UNO_QUERY_THROW
);
473 xComboBox
->addItems( aStringSeq
, 0 );
475 // set the drop down line count to something reasonable
476 const sal_Int16 nLineCount
= ::std::min( sal_Int16( 16 ), sal_Int16( aStringSeq
.getLength() ) );
477 xComboBox
->setDropDownLineCount( nLineCount
);
479 catch( const Exception
& )
481 DBG_UNHANDLED_EXCEPTION();
488 void SAL_CALL
OFilterControl::focusGained(const FocusEvent
& /*e*/) throw( RuntimeException
, std::exception
)
490 // should we fill the combobox?
491 if (m_bFilterList
&& !m_bFilterListFilled
)
492 implInitFilterList();
496 void SAL_CALL
OFilterControl::focusLost(const FocusEvent
& /*e*/) throw( RuntimeException
, std::exception
)
501 sal_Bool SAL_CALL
OFilterControl::commit() throw(RuntimeException
, std::exception
)
503 #if HAVE_FEATURE_DBCONNECTIVITY
504 if ( !ensureInitialized( ) )
505 // already asserted in ensureInitialized
509 switch (m_nControlClass
)
511 case FormComponentType::TEXTFIELD
:
512 case FormComponentType::COMBOBOX
:
514 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
516 aText
= xText
->getText();
521 if (m_aText
.compareTo(aText
))
523 // check the text with the SQL-Parser
524 OUString
aNewText(aText
);
525 aNewText
= aNewText
.trim();
526 if ( !aNewText
.isEmpty() )
528 ::dbtools::OPredicateInputController
aPredicateInput( m_xContext
, m_xConnection
, getParseContext() );
529 OUString sErrorMessage
;
530 if ( !aPredicateInput
.normalizePredicateString( aNewText
, m_xField
, &sErrorMessage
) )
532 // display the error and outta here
534 aError
.Message
= FRM_RES_STRING( RID_STR_SYNTAXERROR
);
535 aError
.Details
= sErrorMessage
;
536 displayException( aError
);
544 ::cppu::OInterfaceIteratorHelper
aIt( m_aTextListeners
);
545 while( aIt
.hasMoreElements() )
546 static_cast< XTextListener
* >( aIt
.next() )->textChanged( aEvt
);
554 void SAL_CALL
OFilterControl::addTextListener(const Reference
< XTextListener
> & l
) throw(RuntimeException
, std::exception
)
556 m_aTextListeners
.addInterface( l
);
560 void SAL_CALL
OFilterControl::removeTextListener(const Reference
< XTextListener
> & l
) throw(RuntimeException
, std::exception
)
562 m_aTextListeners
.removeInterface( l
);
566 void SAL_CALL
OFilterControl::setText( const OUString
& aText
) throw(RuntimeException
, std::exception
)
568 if ( !ensureInitialized( ) )
569 // already asserted in ensureInitialized
572 switch (m_nControlClass
)
574 case FormComponentType::CHECKBOX
:
576 Reference
< XVclWindowPeer
> xVclWindow( getPeer(), UNO_QUERY
);
581 || aText
.equalsIgnoreAsciiCase("TRUE")
582 || aText
.equalsIgnoreAsciiCase("IS TRUE")
585 aValue
<<= (sal_Int32
)TRISTATE_TRUE
;
587 else if ( aText
== "0" || aText
.equalsIgnoreAsciiCase("FALSE") )
589 aValue
<<= (sal_Int32
)TRISTATE_FALSE
;
592 aValue
<<= (sal_Int32
)TRISTATE_INDET
;
595 xVclWindow
->setProperty( PROPERTY_STATE
, aValue
);
598 case FormComponentType::RADIOBUTTON
:
600 Reference
< XVclWindowPeer
> xVclWindow( getPeer(), UNO_QUERY
);
603 OUString aRefText
= ::comphelper::getString(com::sun::star::uno::Reference
< XPropertySet
> (getModel(), UNO_QUERY
)->getPropertyValue(PROPERTY_REFVALUE
));
605 if (aText
== aRefText
)
606 aValue
<<= (sal_Int32
)TRISTATE_TRUE
;
608 aValue
<<= (sal_Int32
)TRISTATE_FALSE
;
610 xVclWindow
->setProperty(PROPERTY_STATE
, aValue
);
613 case FormComponentType::LISTBOX
:
615 Reference
< XListBox
> xListBox( getPeer(), UNO_QUERY
);
619 MapString2String::const_iterator itemPos
= m_aDisplayItemToValueItem
.find( m_aText
);
620 if ( itemPos
== m_aDisplayItemToValueItem
.end() )
622 const bool isQuoted
= ( m_aText
.getLength() > 1 )
623 && ( m_aText
[0] == '\'' )
624 && ( m_aText
[ m_aText
.getLength() - 1 ] == '\'' );
627 m_aText
= m_aText
.copy( 1, m_aText
.getLength() - 2 );
628 itemPos
= m_aDisplayItemToValueItem
.find( m_aText
);
632 OSL_ENSURE( ( itemPos
!= m_aDisplayItemToValueItem
.end() ) || m_aText
.isEmpty(),
633 "OFilterControl::setText: this text is not in my display list!" );
634 if ( itemPos
== m_aDisplayItemToValueItem
.end() )
637 if ( m_aText
.isEmpty() )
639 while ( xListBox
->getSelectedItemPos() >= 0 )
641 xListBox
->selectItemPos( xListBox
->getSelectedItemPos(), sal_False
);
646 xListBox
->selectItem( m_aText
, sal_True
);
654 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
658 xText
->setText(aText
);
665 void SAL_CALL
OFilterControl::insertText( const ::com::sun::star::awt::Selection
& rSel
, const OUString
& aText
) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
667 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
670 xText
->insertText(rSel
, aText
);
671 m_aText
= xText
->getText();
676 OUString SAL_CALL
OFilterControl::getText() throw(RuntimeException
, std::exception
)
682 OUString SAL_CALL
OFilterControl::getSelectedText() throw(RuntimeException
, std::exception
)
685 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
687 aSelected
= xText
->getSelectedText();
693 void SAL_CALL
OFilterControl::setSelection( const ::com::sun::star::awt::Selection
& aSelection
) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
695 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
697 xText
->setSelection( aSelection
);
701 ::com::sun::star::awt::Selection SAL_CALL
OFilterControl::getSelection() throw(::com::sun::star::uno::RuntimeException
, std::exception
)
703 ::com::sun::star::awt::Selection aSel
;
704 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
706 aSel
= xText
->getSelection();
711 sal_Bool SAL_CALL
OFilterControl::isEditable() throw(RuntimeException
, std::exception
)
713 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
714 return xText
.is() && xText
->isEditable();
718 void SAL_CALL
OFilterControl::setEditable( sal_Bool bEditable
) throw(RuntimeException
, std::exception
)
720 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
722 xText
->setEditable(bEditable
);
726 sal_Int16 SAL_CALL
OFilterControl::getMaxTextLen() throw(RuntimeException
, std::exception
)
728 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
729 return xText
.is() ? xText
->getMaxTextLen() : 0;
733 void SAL_CALL
OFilterControl::setMaxTextLen( sal_Int16 nLength
) throw(RuntimeException
, std::exception
)
735 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
737 xText
->setMaxTextLen(nLength
);
741 void OFilterControl::displayException( const ::com::sun::star::sdb::SQLContext
& _rExcept
)
745 Reference
< XExecutableDialog
> xErrorDialog
= ErrorMessageDialog::create( m_xContext
, "", m_xMessageParent
, makeAny(_rExcept
));
746 xErrorDialog
->execute();
748 catch( const Exception
& )
750 DBG_UNHANDLED_EXCEPTION();
755 void SAL_CALL
OFilterControl::initialize( const Sequence
< Any
>& aArguments
) throw (Exception
, RuntimeException
, std::exception
)
757 const Any
* pArguments
= aArguments
.getConstArray();
758 const Any
* pArgumentsEnd
= pArguments
+ aArguments
.getLength();
762 const OUString
* pName
= NULL
;
763 const Any
* pValue
= NULL
;
764 Reference
< XPropertySet
> xControlModel
;
766 if (aArguments
.getLength() == 3
767 && (aArguments
[0] >>= m_xMessageParent
)
768 && (aArguments
[1] >>= m_xFormatter
)
769 && (aArguments
[2] >>= xControlModel
))
771 initControlModel(xControlModel
);
773 else for ( ; pArguments
!= pArgumentsEnd
; ++pArguments
)
775 // we recognize PropertyValues and NamedValues
776 if ( *pArguments
>>= aProp
)
779 pValue
= &aProp
.Value
;
781 else if ( *pArguments
>>= aValue
)
783 pName
= &aValue
.Name
;
784 pValue
= &aValue
.Value
;
788 OSL_FAIL( "OFilterControl::initialize: unrecognized argument!" );
792 if ( *pName
== "MessageParent" )
794 // the message parent
795 *pValue
>>= m_xMessageParent
;
796 OSL_ENSURE( m_xMessageParent
.is(), "OFilterControl::initialize: invalid MessageParent!" );
798 else if ( *pName
== "NumberFormatter" )
800 // the number format. This argument is optional.
801 *pValue
>>= m_xFormatter
;
802 OSL_ENSURE( m_xFormatter
.is(), "OFilterControl::initialize: invalid NumberFormatter!" );
804 else if ( *pName
== "ControlModel" )
806 // the control model for which we act as filter control
807 if ( !(*pValue
>>= xControlModel
) )
809 OSL_FAIL( "OFilterControl::initialize: invalid control model argument!" );
812 initControlModel(xControlModel
);
817 void OFilterControl::initControlModel(Reference
< XPropertySet
>& xControlModel
)
819 #if !HAVE_FEATURE_DBCONNECTIVITY
820 (void) xControlModel
;
822 if ( !xControlModel
.is() )
824 OSL_FAIL( "OFilterControl::initialize: invalid control model argument!" );
827 // some properties which are "derived" from the control model we're working for
831 OSL_ENSURE( ::comphelper::hasProperty( PROPERTY_BOUNDFIELD
, xControlModel
), "OFilterControl::initialize: control model needs a bound field property!" );
832 xControlModel
->getPropertyValue( PROPERTY_BOUNDFIELD
) >>= m_xField
;
835 // filter list and control class
836 m_bFilterList
= ::comphelper::hasProperty( PROPERTY_FILTERPROPOSAL
, xControlModel
) && ::comphelper::getBOOL( xControlModel
->getPropertyValue( PROPERTY_FILTERPROPOSAL
) );
838 m_nControlClass
= FormComponentType::COMBOBOX
;
841 sal_Int16 nClassId
= ::comphelper::getINT16( xControlModel
->getPropertyValue( PROPERTY_CLASSID
) );
844 case FormComponentType::CHECKBOX
:
845 case FormComponentType::RADIOBUTTON
:
846 case FormComponentType::LISTBOX
:
847 case FormComponentType::COMBOBOX
:
848 m_nControlClass
= nClassId
;
849 if ( FormComponentType::LISTBOX
== nClassId
)
851 Sequence
< OUString
> aDisplayItems
;
852 OSL_VERIFY( xControlModel
->getPropertyValue( PROPERTY_STRINGITEMLIST
) >>= aDisplayItems
);
853 Sequence
< OUString
> aValueItems
;
854 OSL_VERIFY( xControlModel
->getPropertyValue( PROPERTY_VALUE_SEQ
) >>= aValueItems
);
855 OSL_ENSURE( aDisplayItems
.getLength() == aValueItems
.getLength(), "OFilterControl::initialize: inconsistent item lists!" );
856 for ( sal_Int32 i
=0; i
< ::std::min( aDisplayItems
.getLength(), aValueItems
.getLength() ); ++i
)
857 m_aDisplayItemToValueItem
[ aDisplayItems
[i
] ] = aValueItems
[i
];
861 m_bMultiLine
= ::comphelper::hasProperty( PROPERTY_MULTILINE
, xControlModel
) && ::comphelper::getBOOL( xControlModel
->getPropertyValue( PROPERTY_MULTILINE
) );
862 m_nControlClass
= FormComponentType::TEXTFIELD
;
868 // the connection meta data for the form which we're working for
869 Reference
< XChild
> xModel( xControlModel
, UNO_QUERY
);
870 Reference
< XRowSet
> xForm
;
872 xForm
.set(xModel
->getParent(), css::uno::UNO_QUERY
);
873 m_xConnection
= ::dbtools::getConnection( xForm
);
874 OSL_ENSURE( m_xConnection
.is(), "OFilterControl::initialize: unable to determine the form's connection!" );
878 OUString SAL_CALL
OFilterControl::getImplementationName( ) throw (RuntimeException
, std::exception
)
880 return getImplementationName_Static();
883 sal_Bool SAL_CALL
OFilterControl::supportsService( const OUString
& ServiceName
) throw (RuntimeException
, std::exception
)
885 return cppu::supportsService(this, ServiceName
);
888 Sequence
< OUString
> SAL_CALL
OFilterControl::getSupportedServiceNames( ) throw (RuntimeException
, std::exception
)
890 return getSupportedServiceNames_Static();
893 OUString SAL_CALL
OFilterControl::getImplementationName_Static()
895 return OUString( "com.sun.star.comp.forms.OFilterControl" );
898 Sequence
< OUString
> SAL_CALL
OFilterControl::getSupportedServiceNames_Static()
900 Sequence
< OUString
> aNames( 2 );
901 aNames
[ 0 ] = "com.sun.star.form.control.FilterControl";
902 aNames
[ 1 ] = "com.sun.star.awt.UnoControl";
907 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
* SAL_CALL
908 com_sun_star_comp_forms_OFilterControl_get_implementation(css::uno::XComponentContext
* context
,
909 css::uno::Sequence
<css::uno::Any
> const &)
911 return cppu::acquire(new frm::OFilterControl(context
));
914 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */