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_module.hxx"
23 #include "frm_resource.hrc"
24 #include "frm_resource.hxx"
25 #include "property.hrc"
26 #include "property.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 <connectivity/dbconversion.hxx>
55 #include <connectivity/dbtools.hxx>
56 #include <connectivity/formattedcolumnvalue.hxx>
57 #include <connectivity/predicateinput.hxx>
58 #include <rtl/ustrbuf.hxx>
59 #include <toolkit/helper/vclunohelper.hxx>
60 #include <tools/diagnose_ex.h>
61 #include <unotools/localedatawrapper.hxx>
62 #include <vcl/stdtext.hxx>
63 #include <vcl/svapp.hxx>
64 #include <tools/wintypes.hxx>
66 //--------------------------------------------------------------------------
67 extern "C" void SAL_CALL
createRegistryInfo_OFilterControl()
69 static ::frm::OMultiInstanceAutoRegistration
< ::frm::OFilterControl
> aAutoRegistration
;
72 //.........................................................................
75 //.........................................................................
77 using namespace ::com::sun::star::uno
;
78 using namespace ::com::sun::star::awt
;
79 using namespace ::com::sun::star::lang
;
80 using namespace ::com::sun::star::beans
;
81 using namespace ::com::sun::star::sdb
;
82 using namespace ::com::sun::star::sdbc
;
83 using namespace ::com::sun::star::sdbcx
;
84 using namespace ::com::sun::star::util
;
85 using namespace ::com::sun::star::form
;
86 using namespace ::com::sun::star::container
;
87 using namespace ::com::sun::star::ui::dialogs
;
89 using namespace ::connectivity
;
91 //=====================================================================
93 //=====================================================================
94 //---------------------------------------------------------------------
95 OFilterControl::OFilterControl( const Reference
< XComponentContext
>& _rxORB
)
97 ,m_aTextListeners( *this )
100 ,m_nControlClass( FormComponentType::TEXTFIELD
)
101 ,m_bFilterList( sal_False
)
102 ,m_bMultiLine( sal_False
)
103 ,m_bFilterListFilled( sal_False
)
107 //---------------------------------------------------------------------
108 sal_Bool
OFilterControl::ensureInitialized( )
110 if ( !m_xField
.is() )
112 OSL_FAIL( "OFilterControl::ensureInitialized: improperly initialized: no field!" );
116 if ( !m_xConnection
.is() )
118 OSL_FAIL( "OFilterControl::ensureInitialized: improperly initialized: no connection!" );
122 if ( !m_xFormatter
.is() )
124 // we can create one from the connection, if it's an SDB connection
126 Reference
< XNumberFormatsSupplier
> xFormatSupplier
= ::dbtools::getNumberFormats( m_xConnection
, sal_True
, m_xContext
);
128 if ( xFormatSupplier
.is() )
130 m_xFormatter
.set(NumberFormatter::create(m_xContext
), UNO_QUERY_THROW
);
131 m_xFormatter
->attachNumberFormatsSupplier( xFormatSupplier
);
134 if ( !m_xFormatter
.is() )
136 OSL_FAIL( "OFilterControl::ensureInitialized: no number formatter!" );
137 // no fallback anymore
144 //---------------------------------------------------------------------
145 Any SAL_CALL
OFilterControl::queryAggregation( const Type
& rType
) throw(RuntimeException
)
147 Any aRet
= UnoControl::queryAggregation( rType
);
149 aRet
= OFilterControl_BASE::queryInterface(rType
);
154 //------------------------------------------------------------------
155 OUString
OFilterControl::GetComponentServiceName()
157 OUString aServiceName
;
158 switch (m_nControlClass
)
160 case FormComponentType::RADIOBUTTON
:
161 aServiceName
= OUString("radiobutton");
163 case FormComponentType::CHECKBOX
:
164 aServiceName
= OUString("checkbox");
166 case FormComponentType::COMBOBOX
:
167 aServiceName
= OUString("combobox");
169 case FormComponentType::LISTBOX
:
170 aServiceName
= OUString("listbox");
174 aServiceName
= OUString("MultiLineEdit");
176 aServiceName
= OUString("Edit");
182 //---------------------------------------------------------------------
183 void OFilterControl::dispose() throw( RuntimeException
)
185 EventObject
aEvt(*this);
186 m_aTextListeners
.disposeAndClear( aEvt
);
187 UnoControl::dispose();
190 //---------------------------------------------------------------------
191 void OFilterControl::createPeer( const Reference
< XToolkit
> & rxToolkit
, const Reference
< XWindowPeer
> & rParentPeer
) throw(RuntimeException
)
193 UnoControl::createPeer( rxToolkit
, rParentPeer
);
197 Reference
< XVclWindowPeer
> xVclWindow( getPeer(), UNO_QUERY_THROW
);
198 switch ( m_nControlClass
)
200 case FormComponentType::CHECKBOX
:
202 // checkboxes always have a tristate-mode
203 xVclWindow
->setProperty( PROPERTY_TRISTATE
, makeAny( sal_Bool( sal_True
) ) );
204 xVclWindow
->setProperty( PROPERTY_STATE
, makeAny( sal_Int32( STATE_DONTKNOW
) ) );
206 Reference
< XCheckBox
> xBox( getPeer(), UNO_QUERY_THROW
);
207 xBox
->addItemListener( this );
212 case FormComponentType::RADIOBUTTON
:
214 xVclWindow
->setProperty( PROPERTY_STATE
, makeAny( sal_Int32( STATE_NOCHECK
) ) );
216 Reference
< XRadioButton
> xRadio( getPeer(), UNO_QUERY_THROW
);
217 xRadio
->addItemListener( this );
221 case FormComponentType::LISTBOX
:
223 Reference
< XListBox
> xListBox( getPeer(), UNO_QUERY_THROW
);
224 xListBox
->addItemListener( this );
228 case FormComponentType::COMBOBOX
:
230 xVclWindow
->setProperty(PROPERTY_AUTOCOMPLETE
, makeAny( sal_Bool( sal_True
) ) );
236 Reference
< XWindow
> xWindow( getPeer(), UNO_QUERY
);
237 xWindow
->addFocusListener( this );
239 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
241 xText
->setMaxTextLen(0);
246 OControl::initFormControlPeer( getPeer() );
248 // filter controls are _never_ readonly
249 Reference
< XPropertySet
> xModel( getModel(), UNO_QUERY_THROW
);
250 Reference
< XPropertySetInfo
> xModelPSI( xModel
->getPropertySetInfo(), UNO_SET_THROW
);
251 if ( xModelPSI
->hasPropertyByName( PROPERTY_READONLY
) )
252 xVclWindow
->setProperty( PROPERTY_READONLY
, makeAny( sal_Bool( sal_False
) ) );
254 catch( const Exception
& )
256 DBG_UNHANDLED_EXCEPTION();
260 m_bFilterListFilled
= sal_False
;
263 //---------------------------------------------------------------------
264 void OFilterControl::PrepareWindowDescriptor( WindowDescriptor
& rDescr
)
267 rDescr
.WindowAttributes
|= VclWindowPeerAttribute::DROPDOWN
;
270 //---------------------------------------------------------------------
271 void OFilterControl::ImplSetPeerProperty( const OUString
& rPropName
, const Any
& rVal
)
273 // these properties are ignored
274 if (rPropName
== PROPERTY_TEXT
||
275 rPropName
== PROPERTY_STATE
)
278 UnoControl::ImplSetPeerProperty( rPropName
, rVal
);
282 //---------------------------------------------------------------------
283 void SAL_CALL
OFilterControl::disposing(const EventObject
& Source
) throw( RuntimeException
)
285 UnoControl::disposing(Source
);
289 //---------------------------------------------------------------------
290 void SAL_CALL
OFilterControl::itemStateChanged( const ItemEvent
& rEvent
) throw(RuntimeException
)
292 OUStringBuffer aText
;
293 switch (m_nControlClass
)
295 case FormComponentType::CHECKBOX
:
297 if ( ( rEvent
.Selected
== STATE_CHECK
) || ( rEvent
.Selected
== STATE_NOCHECK
) )
299 sal_Int32 nBooleanComparisonMode
= ::dbtools::DatabaseMetaData( m_xConnection
).getBooleanComparisonMode();
301 bool bSelected
= ( rEvent
.Selected
== STATE_CHECK
);
303 OUString
sExpressionMarker( "$expression$" );
304 ::dbtools::getBoleanComparisonPredicate(
307 nBooleanComparisonMode
,
311 OUString
sText( aText
.makeStringAndClear() );
312 sal_Int32
nMarkerPos( sText
.indexOf( sExpressionMarker
) );
313 OSL_ENSURE( nMarkerPos
== 0, "OFilterControl::itemStateChanged: unsupported boolean comparison mode!" );
314 // If this assertion fails, then getBoleanComparisonPredicate created a predicate which
315 // does not start with the expression we gave it. The only known case is when
316 // the comparison mode is ACCESS_COMPAT, and the value is TRUE. In this case,
317 // the expression is rather complex.
318 // Well, so this is a known issue - the filter controls (and thus the form based filter)
319 // do not work with boolean MS Access fields.
320 // To fix this, we would probably have to revert here to always return "1" or "0" as normalized
321 // filter, and change our client code to properly translate this (which could be some effort).
322 if ( nMarkerPos
== 0 )
323 aText
.append( sText
.copy( sExpressionMarker
.getLength() ) );
327 aText
.appendAscii( bSelected
? "1" : "0" );
333 case FormComponentType::LISTBOX
:
337 const Reference
< XItemList
> xItemList( getModel(), UNO_QUERY_THROW
);
338 OUString
sItemText( xItemList
->getItemText( rEvent
.Selected
) );
340 const MapString2String::const_iterator itemPos
= m_aDisplayItemToValueItem
.find( sItemText
);
341 if ( itemPos
!= m_aDisplayItemToValueItem
.end() )
343 sItemText
= itemPos
->second
;
344 if ( !sItemText
.isEmpty() )
346 ::dbtools::OPredicateInputController
aPredicateInput( m_xContext
, m_xConnection
, getParseContext() );
347 OUString sErrorMessage
;
348 OSL_VERIFY( aPredicateInput
.normalizePredicateString( sItemText
, m_xField
, &sErrorMessage
) );
351 aText
.append( sItemText
);
353 catch( const Exception
& )
355 DBG_UNHANDLED_EXCEPTION();
360 case FormComponentType::RADIOBUTTON
:
362 if ( rEvent
.Selected
== STATE_CHECK
)
363 aText
.append( ::comphelper::getString( Reference
< XPropertySet
>( getModel(), UNO_QUERY
)->getPropertyValue( PROPERTY_REFVALUE
) ) );
368 OUString
sText( aText
.makeStringAndClear() );
369 if ( m_aText
.compareTo( sText
) )
374 ::cppu::OInterfaceIteratorHelper
aIt( m_aTextListeners
);
375 while( aIt
.hasMoreElements() )
376 ((XTextListener
*)aIt
.next())->textChanged( aEvt
);
380 //---------------------------------------------------------------------
381 void OFilterControl::implInitFilterList()
383 if ( !ensureInitialized( ) )
384 // already asserted in ensureInitialized
387 // ensure the cursor and the statement are disposed as soon as we leave
388 ::utl::SharedUNOComponent
< XResultSet
> xListCursor
;
389 ::utl::SharedUNOComponent
< XStatement
> xStatement
;
393 m_bFilterListFilled
= sal_True
;
395 if ( !m_xField
.is() )
399 m_xField
->getPropertyValue( PROPERTY_NAME
) >>= sFieldName
;
401 // here we need a table to which the field belongs to
402 const Reference
< XChild
> xModelAsChild( getModel(), UNO_QUERY_THROW
);
403 const Reference
< XRowSet
> xForm( xModelAsChild
->getParent(), UNO_QUERY_THROW
);
404 const Reference
< XPropertySet
> xFormProps( xForm
, UNO_QUERY_THROW
);
406 // create a query composer
407 Reference
< XColumnsSupplier
> xSuppColumns
;
408 xFormProps
->getPropertyValue(OUString("SingleSelectQueryComposer")) >>= xSuppColumns
;
410 const Reference
< XConnection
> xConnection( ::dbtools::getConnection( xForm
), UNO_SET_THROW
);
411 const Reference
< XNameAccess
> xFieldNames( xSuppColumns
->getColumns(), UNO_SET_THROW
);
412 if ( !xFieldNames
->hasByName( sFieldName
) )
414 OUString sRealFieldName
, sTableName
;
415 const Reference
< XPropertySet
> xComposerFieldProps( xFieldNames
->getByName( sFieldName
), UNO_QUERY_THROW
);
416 xComposerFieldProps
->getPropertyValue( PROPERTY_REALNAME
) >>= sRealFieldName
;
417 xComposerFieldProps
->getPropertyValue( PROPERTY_TABLENAME
) >>= sTableName
;
419 // obtain the table of the field
420 const Reference
< XTablesSupplier
> xSuppTables( xSuppColumns
, UNO_QUERY_THROW
);
421 const Reference
< XNameAccess
> xTablesNames( xSuppTables
->getTables(), UNO_SET_THROW
);
422 const Reference
< XNamed
> xNamedTable( xTablesNames
->getByName( sTableName
), UNO_QUERY_THROW
);
423 sTableName
= xNamedTable
->getName();
425 // create a statement selecting all values for the given field
426 OUStringBuffer aStatement
;
428 const Reference
< XDatabaseMetaData
> xMeta( xConnection
->getMetaData(), UNO_SET_THROW
);
429 const OUString sQuoteChar
= xMeta
->getIdentifierQuoteString();
431 aStatement
.appendAscii( "SELECT DISTINCT " );
432 aStatement
.append( sQuoteChar
);
433 aStatement
.append( sRealFieldName
);
434 aStatement
.append( sQuoteChar
);
436 // if the field had an alias in our form's statement, give it this alias in the new statement, too
437 if ( !sFieldName
.isEmpty() && ( sFieldName
!= sRealFieldName
) )
439 aStatement
.appendAscii(" AS ");
440 aStatement
.append( sQuoteChar
);
441 aStatement
.append( sFieldName
);
442 aStatement
.append( sQuoteChar
);
445 aStatement
.appendAscii( " FROM " );
447 OUString sCatalog
, sSchema
, sTable
;
448 ::dbtools::qualifiedNameComponents( xMeta
, sTableName
, sCatalog
, sSchema
, sTable
, ::dbtools::eInDataManipulation
);
449 aStatement
.append( ::dbtools::composeTableNameForSelect( xConnection
, sCatalog
, sSchema
, sTable
) );
451 // execute the statement
452 xStatement
.reset( xConnection
->createStatement() );
453 const OUString
sSelectStatement( aStatement
.makeStringAndClear( ) );
454 xListCursor
.reset( xStatement
->executeQuery( sSelectStatement
) );
456 // retrieve the one column which we take the values from
457 const Reference
< XColumnsSupplier
> xSupplyCols( xListCursor
, UNO_QUERY_THROW
);
458 const Reference
< XIndexAccess
> xFields( xSupplyCols
->getColumns(), UNO_QUERY_THROW
);
459 const Reference
< XPropertySet
> xDataField( xFields
->getByIndex(0), UNO_QUERY_THROW
);
461 // ensure the values will be formatted according to the field format
462 const ::dbtools::FormattedColumnValue
aFormatter( m_xFormatter
, xDataField
);
464 ::std::vector
< OUString
> aProposals
;
465 aProposals
.reserve(16);
467 while ( xListCursor
->next() && ( aProposals
.size() < size_t( SHRT_MAX
) ) )
469 const OUString sCurrentValue
= aFormatter
.getFormattedValue();
470 aProposals
.push_back( sCurrentValue
);
473 // fill the list items into our peer
474 Sequence
< OUString
> aStringSeq( aProposals
.size() );
475 ::std::copy( aProposals
.begin(), aProposals
.end(), aStringSeq
.getArray() );
477 const Reference
< XComboBox
> xComboBox( getPeer(), UNO_QUERY_THROW
);
478 xComboBox
->addItems( aStringSeq
, 0 );
480 // set the drop down line count to something reasonable
481 const sal_Int16 nLineCount
= ::std::min( sal_Int16( 16 ), sal_Int16( aStringSeq
.getLength() ) );
482 xComboBox
->setDropDownLineCount( nLineCount
);
484 catch( const Exception
& )
486 DBG_UNHANDLED_EXCEPTION();
491 //---------------------------------------------------------------------
492 void SAL_CALL
OFilterControl::focusGained(const FocusEvent
& /*e*/) throw( RuntimeException
)
494 // should we fill the combobox?
495 if (m_bFilterList
&& !m_bFilterListFilled
)
496 implInitFilterList();
499 //---------------------------------------------------------------------
500 void SAL_CALL
OFilterControl::focusLost(const FocusEvent
& /*e*/) throw( RuntimeException
)
504 //---------------------------------------------------------------------
505 sal_Bool SAL_CALL
OFilterControl::commit() throw(RuntimeException
)
507 if ( !ensureInitialized( ) )
508 // already asserted in ensureInitialized
512 switch (m_nControlClass
)
514 case FormComponentType::TEXTFIELD
:
515 case FormComponentType::COMBOBOX
:
517 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
519 aText
= xText
->getText();
524 if (m_aText
.compareTo(aText
))
526 // check the text with the SQL-Parser
527 OUString
aNewText(aText
);
528 aNewText
= aNewText
.trim();
529 if ( !aNewText
.isEmpty() )
531 ::dbtools::OPredicateInputController
aPredicateInput( m_xContext
, m_xConnection
, getParseContext() );
532 OUString sErrorMessage
;
533 if ( !aPredicateInput
.normalizePredicateString( aNewText
, m_xField
, &sErrorMessage
) )
535 // display the error and outta here
537 aError
.Message
= String( FRM_RES_STRING( RID_STR_SYNTAXERROR
) );
538 aError
.Details
= sErrorMessage
;
539 displayException( aError
);
547 ::cppu::OInterfaceIteratorHelper
aIt( m_aTextListeners
);
548 while( aIt
.hasMoreElements() )
549 static_cast< XTextListener
* >( aIt
.next() )->textChanged( aEvt
);
555 //---------------------------------------------------------------------
556 void SAL_CALL
OFilterControl::addTextListener(const Reference
< XTextListener
> & l
) throw(RuntimeException
)
558 m_aTextListeners
.addInterface( l
);
561 //---------------------------------------------------------------------
562 void SAL_CALL
OFilterControl::removeTextListener(const Reference
< XTextListener
> & l
) throw(RuntimeException
)
564 m_aTextListeners
.removeInterface( l
);
567 //---------------------------------------------------------------------
568 void SAL_CALL
OFilterControl::setText( const OUString
& aText
) throw(RuntimeException
)
570 if ( !ensureInitialized( ) )
571 // already asserted in ensureInitialized
574 switch (m_nControlClass
)
576 case FormComponentType::CHECKBOX
:
578 Reference
< XVclWindowPeer
> xVclWindow( getPeer(), UNO_QUERY
);
583 || aText
.equalsIgnoreAsciiCase("TRUE")
584 || aText
.equalsIgnoreAsciiCase("IS TRUE")
587 aValue
<<= (sal_Int32
)STATE_CHECK
;
589 else if ( aText
== "0" || aText
.equalsIgnoreAsciiCase("FALSE") )
591 aValue
<<= (sal_Int32
)STATE_NOCHECK
;
594 aValue
<<= (sal_Int32
)STATE_DONTKNOW
;
597 xVclWindow
->setProperty( PROPERTY_STATE
, aValue
);
600 case FormComponentType::RADIOBUTTON
:
602 Reference
< XVclWindowPeer
> xVclWindow( getPeer(), UNO_QUERY
);
605 OUString aRefText
= ::comphelper::getString(com::sun::star::uno::Reference
< XPropertySet
> (getModel(), UNO_QUERY
)->getPropertyValue(PROPERTY_REFVALUE
));
607 if (aText
== aRefText
)
608 aValue
<<= (sal_Int32
)STATE_CHECK
;
610 aValue
<<= (sal_Int32
)STATE_NOCHECK
;
612 xVclWindow
->setProperty(PROPERTY_STATE
, aValue
);
615 case FormComponentType::LISTBOX
:
617 Reference
< XListBox
> xListBox( getPeer(), UNO_QUERY
);
621 MapString2String::const_iterator itemPos
= m_aDisplayItemToValueItem
.find( m_aText
);
622 if ( itemPos
== m_aDisplayItemToValueItem
.end() )
624 const bool isQuoted
= ( m_aText
.getLength() > 1 )
625 && ( m_aText
[0] == '\'' )
626 && ( m_aText
[ m_aText
.getLength() - 1 ] == '\'' );
629 m_aText
= m_aText
.copy( 1, m_aText
.getLength() - 2 );
630 itemPos
= m_aDisplayItemToValueItem
.find( m_aText
);
634 OSL_ENSURE( ( itemPos
!= m_aDisplayItemToValueItem
.end() ) || m_aText
.isEmpty(),
635 "OFilterControl::setText: this text is not in my display list!" );
636 if ( itemPos
== m_aDisplayItemToValueItem
.end() )
637 m_aText
= OUString();
639 if ( m_aText
.isEmpty() )
641 while ( xListBox
->getSelectedItemPos() >= 0 )
643 xListBox
->selectItemPos( xListBox
->getSelectedItemPos(), sal_False
);
648 xListBox
->selectItem( m_aText
, sal_True
);
656 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
660 xText
->setText(aText
);
666 //---------------------------------------------------------------------
667 void SAL_CALL
OFilterControl::insertText( const ::com::sun::star::awt::Selection
& rSel
, const OUString
& aText
) throw(::com::sun::star::uno::RuntimeException
)
669 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
672 xText
->insertText(rSel
, aText
);
673 m_aText
= xText
->getText();
677 //---------------------------------------------------------------------
678 OUString SAL_CALL
OFilterControl::getText() throw(RuntimeException
)
683 //---------------------------------------------------------------------
684 OUString SAL_CALL
OFilterControl::getSelectedText( void ) throw(RuntimeException
)
687 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
689 aSelected
= xText
->getSelectedText();
694 //---------------------------------------------------------------------
695 void SAL_CALL
OFilterControl::setSelection( const ::com::sun::star::awt::Selection
& aSelection
) throw(::com::sun::star::uno::RuntimeException
)
697 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
699 xText
->setSelection( aSelection
);
702 //---------------------------------------------------------------------
703 ::com::sun::star::awt::Selection SAL_CALL
OFilterControl::getSelection( void ) throw(::com::sun::star::uno::RuntimeException
)
705 ::com::sun::star::awt::Selection aSel
;
706 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
708 aSel
= xText
->getSelection();
712 //---------------------------------------------------------------------
713 sal_Bool SAL_CALL
OFilterControl::isEditable( void ) throw(RuntimeException
)
715 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
716 return xText
.is() && xText
->isEditable();
719 //---------------------------------------------------------------------
720 void SAL_CALL
OFilterControl::setEditable( sal_Bool bEditable
) throw(RuntimeException
)
722 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
724 xText
->setEditable(bEditable
);
727 //---------------------------------------------------------------------
728 sal_Int16 SAL_CALL
OFilterControl::getMaxTextLen() throw(RuntimeException
)
730 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
731 return xText
.is() ? xText
->getMaxTextLen() : 0;
734 //---------------------------------------------------------------------
735 void SAL_CALL
OFilterControl::setMaxTextLen( sal_Int16 nLength
) throw(RuntimeException
)
737 Reference
< XTextComponent
> xText( getPeer(), UNO_QUERY
);
739 xText
->setMaxTextLen(nLength
);
742 //---------------------------------------------------------------------
743 void OFilterControl::displayException( const ::com::sun::star::sdb::SQLContext
& _rExcept
)
747 Reference
< XExecutableDialog
> xErrorDialog
= ErrorMessageDialog::create( m_xContext
, "", m_xMessageParent
, makeAny(_rExcept
));
748 xErrorDialog
->execute();
750 catch( const Exception
& )
752 DBG_UNHANDLED_EXCEPTION();
756 //---------------------------------------------------------------------
757 void SAL_CALL
OFilterControl::initialize( const Sequence
< Any
>& aArguments
) throw (Exception
, RuntimeException
)
759 const Any
* pArguments
= aArguments
.getConstArray();
760 const Any
* pArgumentsEnd
= pArguments
+ aArguments
.getLength();
764 const OUString
* pName
= NULL
;
765 const Any
* pValue
= NULL
;
766 Reference
< XPropertySet
> xControlModel
;
768 if (aArguments
.getLength() == 3
769 && (aArguments
[0] >>= m_xMessageParent
)
770 && (aArguments
[1] >>= m_xFormatter
)
771 && (aArguments
[2] >>= xControlModel
))
773 initControlModel(xControlModel
);
775 else for ( ; pArguments
!= pArgumentsEnd
; ++pArguments
)
777 // we recognize PropertyValues and NamedValues
778 if ( *pArguments
>>= aProp
)
781 pValue
= &aProp
.Value
;
783 else if ( *pArguments
>>= aValue
)
785 pName
= &aValue
.Name
;
786 pValue
= &aValue
.Value
;
790 OSL_FAIL( "OFilterControl::initialize: unrecognized argument!" );
794 if ( 0 == pName
->compareToAscii( "MessageParent" ) )
796 // the message parent
797 *pValue
>>= m_xMessageParent
;
798 OSL_ENSURE( m_xMessageParent
.is(), "OFilterControl::initialize: invalid MessageParent!" );
800 else if ( 0 == pName
->compareToAscii( "NumberFormatter" ) )
802 // the number format. This argument is optional.
803 *pValue
>>= m_xFormatter
;
804 OSL_ENSURE( m_xFormatter
.is(), "OFilterControl::initialize: invalid NumberFormatter!" );
806 else if ( 0 == pName
->compareToAscii( "ControlModel" ) )
808 // the control model for which we act as filter control
809 if ( !(*pValue
>>= xControlModel
) )
811 OSL_FAIL( "OFilterControl::initialize: invalid control model argument!" );
814 initControlModel(xControlModel
);
819 void OFilterControl::initControlModel(Reference
< XPropertySet
>& xControlModel
)
821 if ( !xControlModel
.is() )
823 OSL_FAIL( "OFilterControl::initialize: invalid control model argument!" );
826 // some properties which are "derived" from the control model we're working for
827 // ...................................................
830 OSL_ENSURE( ::comphelper::hasProperty( PROPERTY_BOUNDFIELD
, xControlModel
), "OFilterControl::initialize: control model needs a bound field property!" );
831 xControlModel
->getPropertyValue( PROPERTY_BOUNDFIELD
) >>= m_xField
;
833 // ...................................................
834 // filter list and control class
835 m_bFilterList
= ::comphelper::hasProperty( PROPERTY_FILTERPROPOSAL
, xControlModel
) && ::comphelper::getBOOL( xControlModel
->getPropertyValue( PROPERTY_FILTERPROPOSAL
) );
837 m_nControlClass
= FormComponentType::COMBOBOX
;
840 sal_Int16 nClassId
= ::comphelper::getINT16( xControlModel
->getPropertyValue( PROPERTY_CLASSID
) );
843 case FormComponentType::CHECKBOX
:
844 case FormComponentType::RADIOBUTTON
:
845 case FormComponentType::LISTBOX
:
846 case FormComponentType::COMBOBOX
:
847 m_nControlClass
= nClassId
;
848 if ( FormComponentType::LISTBOX
== nClassId
)
850 Sequence
< OUString
> aDisplayItems
;
851 OSL_VERIFY( xControlModel
->getPropertyValue( PROPERTY_STRINGITEMLIST
) >>= aDisplayItems
);
852 Sequence
< OUString
> aValueItems
;
853 OSL_VERIFY( xControlModel
->getPropertyValue( PROPERTY_VALUE_SEQ
) >>= aValueItems
);
854 OSL_ENSURE( aDisplayItems
.getLength() == aValueItems
.getLength(), "OFilterControl::initialize: inconsistent item lists!" );
855 for ( sal_Int32 i
=0; i
< ::std::min( aDisplayItems
.getLength(), aValueItems
.getLength() ); ++i
)
856 m_aDisplayItemToValueItem
[ aDisplayItems
[i
] ] = aValueItems
[i
];
860 m_bMultiLine
= ::comphelper::hasProperty( PROPERTY_MULTILINE
, xControlModel
) && ::comphelper::getBOOL( xControlModel
->getPropertyValue( PROPERTY_MULTILINE
) );
861 m_nControlClass
= FormComponentType::TEXTFIELD
;
866 // ...................................................
867 // the connection meta data for the form which we're working for
868 Reference
< XChild
> xModel( xControlModel
, UNO_QUERY
);
869 Reference
< XRowSet
> xForm
;
871 xForm
= xForm
.query( xModel
->getParent() );
872 m_xConnection
= ::dbtools::getConnection( xForm
);
873 OSL_ENSURE( m_xConnection
.is(), "OFilterControl::initialize: unable to determine the form's connection!" );
876 //---------------------------------------------------------------------
877 OUString SAL_CALL
OFilterControl::getImplementationName( ) throw (RuntimeException
)
879 return getImplementationName_Static();
882 //---------------------------------------------------------------------
883 sal_Bool SAL_CALL
OFilterControl::supportsService( const OUString
& ServiceName
) throw (RuntimeException
)
885 Sequence
< OUString
> aSupported( getSupportedServiceNames() );
886 const OUString
* pArray
= aSupported
.getConstArray();
887 for( sal_Int32 i
= 0; i
< aSupported
.getLength(); ++i
, ++pArray
)
888 if( pArray
->equals( ServiceName
) )
893 //---------------------------------------------------------------------
894 Sequence
< OUString
> SAL_CALL
OFilterControl::getSupportedServiceNames( ) throw (RuntimeException
)
896 return getSupportedServiceNames_Static();
899 //---------------------------------------------------------------------
900 OUString SAL_CALL
OFilterControl::getImplementationName_Static()
902 return OUString( "com.sun.star.comp.forms.OFilterControl" );
905 //---------------------------------------------------------------------
906 Sequence
< OUString
> SAL_CALL
OFilterControl::getSupportedServiceNames_Static()
908 Sequence
< OUString
> aNames( 2 );
909 aNames
[ 0 ] = OUString( "com.sun.star.form.control.FilterControl" );
910 aNames
[ 1 ] = OUString( "com.sun.star.awt.UnoControl" );
914 //---------------------------------------------------------------------
915 Reference
< XInterface
> SAL_CALL
OFilterControl::Create( const Reference
< XMultiServiceFactory
>& _rxFactory
)
917 return static_cast< XServiceInfo
* >( new OFilterControl( comphelper::getComponentContext(_rxFactory
) ) );
920 //.........................................................................
922 //.........................................................................
924 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */