update credits
[LibreOffice.git] / forms / source / component / Filter.cxx
blobe7775267abb96bc86bb3c4b9da5f96c963323478
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "Filter.hxx"
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 //.........................................................................
73 namespace frm
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 //=====================================================================
92 // OFilterControl
93 //=====================================================================
94 //---------------------------------------------------------------------
95 OFilterControl::OFilterControl( const Reference< XComponentContext >& _rxORB )
96 :UnoControl()
97 ,m_aTextListeners( *this )
98 ,m_xContext( _rxORB )
99 ,m_aParser( _rxORB )
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!" );
113 return sal_False;
116 if ( !m_xConnection.is() )
118 OSL_FAIL( "OFilterControl::ensureInitialized: improperly initialized: no connection!" );
119 return sal_False;
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
138 return sal_False;
141 return sal_True;
144 //---------------------------------------------------------------------
145 Any SAL_CALL OFilterControl::queryAggregation( const Type & rType ) throw(RuntimeException)
147 Any aRet = UnoControl::queryAggregation( rType);
148 if(!aRet.hasValue())
149 aRet = OFilterControl_BASE::queryInterface(rType);
151 return aRet;
154 //------------------------------------------------------------------
155 OUString OFilterControl::GetComponentServiceName()
157 OUString aServiceName;
158 switch (m_nControlClass)
160 case FormComponentType::RADIOBUTTON:
161 aServiceName = OUString("radiobutton");
162 break;
163 case FormComponentType::CHECKBOX:
164 aServiceName = OUString("checkbox");
165 break;
166 case FormComponentType::COMBOBOX:
167 aServiceName = OUString("combobox");
168 break;
169 case FormComponentType::LISTBOX:
170 aServiceName = OUString("listbox");
171 break;
172 default:
173 if (m_bMultiLine)
174 aServiceName = OUString("MultiLineEdit");
175 else
176 aServiceName = OUString("Edit");
178 return aServiceName;
181 // XComponent
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 );
210 break;
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 );
219 break;
221 case FormComponentType::LISTBOX:
223 Reference< XListBox > xListBox( getPeer(), UNO_QUERY_THROW );
224 xListBox->addItemListener( this );
226 // no break
228 case FormComponentType::COMBOBOX:
230 xVclWindow->setProperty(PROPERTY_AUTOCOMPLETE, makeAny( sal_Bool( sal_True ) ) );
232 // no break
234 default:
236 Reference< XWindow > xWindow( getPeer(), UNO_QUERY );
237 xWindow->addFocusListener( this );
239 Reference< XTextComponent > xText( getPeer(), UNO_QUERY );
240 if (xText.is())
241 xText->setMaxTextLen(0);
243 break;
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();
259 if (m_bFilterList)
260 m_bFilterListFilled = sal_False;
263 //---------------------------------------------------------------------
264 void OFilterControl::PrepareWindowDescriptor( WindowDescriptor& rDescr )
266 if (m_bFilterList)
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)
276 return;
278 UnoControl::ImplSetPeerProperty( rPropName, rVal );
281 // XEventListener
282 //---------------------------------------------------------------------
283 void SAL_CALL OFilterControl::disposing(const EventObject& Source) throw( RuntimeException )
285 UnoControl::disposing(Source);
288 // XItemListener
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(
305 sExpressionMarker,
306 bSelected,
307 nBooleanComparisonMode,
308 aText
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() ) );
324 else
326 // fallback
327 aText.appendAscii( bSelected ? "1" : "0" );
331 break;
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();
358 break;
360 case FormComponentType::RADIOBUTTON:
362 if ( rEvent.Selected == STATE_CHECK )
363 aText.append( ::comphelper::getString( Reference< XPropertySet >( getModel(), UNO_QUERY )->getPropertyValue( PROPERTY_REFVALUE ) ) );
365 break;
368 OUString sText( aText.makeStringAndClear() );
369 if ( m_aText.compareTo( sText ) )
371 m_aText = sText;
372 TextEvent aEvt;
373 aEvt.Source = *this;
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
385 return;
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() )
396 return;
398 OUString sFieldName;
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 ) )
413 return;
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();
490 // XFocusListener
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
509 return sal_True;
511 OUString aText;
512 switch (m_nControlClass)
514 case FormComponentType::TEXTFIELD:
515 case FormComponentType::COMBOBOX:
517 Reference< XTextComponent > xText( getPeer(), UNO_QUERY );
518 if (xText.is())
519 aText = xText->getText();
520 } break;
521 default:
522 return sal_True;
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
536 SQLContext aError;
537 aError.Message = String( FRM_RES_STRING( RID_STR_SYNTAXERROR ) );
538 aError.Details = sErrorMessage;
539 displayException( aError );
540 return sal_False;
544 setText(aNewText);
545 TextEvent aEvt;
546 aEvt.Source = *this;
547 ::cppu::OInterfaceIteratorHelper aIt( m_aTextListeners );
548 while( aIt.hasMoreElements() )
549 static_cast< XTextListener* >( aIt.next() )->textChanged( aEvt );
551 return sal_True;
554 // XTextComponent
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
572 return;
574 switch (m_nControlClass)
576 case FormComponentType::CHECKBOX:
578 Reference< XVclWindowPeer > xVclWindow( getPeer(), UNO_QUERY );
579 if (xVclWindow.is())
581 Any aValue;
582 if ( aText == "1"
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;
593 else
594 aValue <<= (sal_Int32)STATE_DONTKNOW;
596 m_aText = aText;
597 xVclWindow->setProperty( PROPERTY_STATE, aValue );
599 } break;
600 case FormComponentType::RADIOBUTTON:
602 Reference< XVclWindowPeer > xVclWindow( getPeer(), UNO_QUERY );
603 if (xVclWindow.is())
605 OUString aRefText = ::comphelper::getString(com::sun::star::uno::Reference< XPropertySet > (getModel(), UNO_QUERY)->getPropertyValue(PROPERTY_REFVALUE));
606 Any aValue;
607 if (aText == aRefText)
608 aValue <<= (sal_Int32)STATE_CHECK;
609 else
610 aValue <<= (sal_Int32)STATE_NOCHECK;
611 m_aText = aText;
612 xVclWindow->setProperty(PROPERTY_STATE, aValue);
614 } break;
615 case FormComponentType::LISTBOX:
617 Reference< XListBox > xListBox( getPeer(), UNO_QUERY );
618 if (xListBox.is())
620 m_aText = aText;
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 ] == '\'' );
627 if ( isQuoted )
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 );
646 else
648 xListBox->selectItem( m_aText, sal_True );
652 break;
654 default:
656 Reference< XTextComponent > xText( getPeer(), UNO_QUERY );
657 if (xText.is())
659 m_aText = aText;
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 );
670 if (xText.is())
672 xText->insertText(rSel, aText);
673 m_aText = xText->getText();
677 //---------------------------------------------------------------------
678 OUString SAL_CALL OFilterControl::getText() throw(RuntimeException)
680 return m_aText;
683 //---------------------------------------------------------------------
684 OUString SAL_CALL OFilterControl::getSelectedText( void ) throw(RuntimeException)
686 OUString aSelected;
687 Reference< XTextComponent > xText( getPeer(), UNO_QUERY );
688 if (xText.is())
689 aSelected = xText->getSelectedText();
691 return aSelected;
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 );
698 if (xText.is())
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 );
707 if (xText.is())
708 aSel = xText->getSelection();
709 return aSel;
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 );
723 if (xText.is())
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 );
738 if (xText.is())
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();
762 PropertyValue aProp;
763 NamedValue aValue;
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 )
780 pName = &aProp.Name;
781 pValue = &aProp.Value;
783 else if ( *pArguments >>= aValue )
785 pName = &aValue.Name;
786 pValue = &aValue.Value;
788 else
790 OSL_FAIL( "OFilterControl::initialize: unrecognized argument!" );
791 continue;
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!" );
812 continue;
814 initControlModel(xControlModel);
819 void OFilterControl::initControlModel(Reference< XPropertySet >& xControlModel)
821 if ( !xControlModel.is() )
823 OSL_FAIL( "OFilterControl::initialize: invalid control model argument!" );
824 return;
826 // some properties which are "derived" from the control model we're working for
827 // ...................................................
828 // the field
829 m_xField.clear();
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 ) );
836 if ( m_bFilterList )
837 m_nControlClass = FormComponentType::COMBOBOX;
838 else
840 sal_Int16 nClassId = ::comphelper::getINT16( xControlModel->getPropertyValue( PROPERTY_CLASSID ) );
841 switch (nClassId)
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];
858 break;
859 default:
860 m_bMultiLine = ::comphelper::hasProperty( PROPERTY_MULTILINE, xControlModel ) && ::comphelper::getBOOL( xControlModel->getPropertyValue( PROPERTY_MULTILINE ) );
861 m_nControlClass = FormComponentType::TEXTFIELD;
862 break;
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;
870 if ( xModel.is() )
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 ) )
889 return sal_True;
890 return sal_False;
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" );
911 return aNames;
914 //---------------------------------------------------------------------
915 Reference< XInterface > SAL_CALL OFilterControl::Create( const Reference< XMultiServiceFactory >& _rxFactory )
917 return static_cast< XServiceInfo* >( new OFilterControl( comphelper::getComponentContext(_rxFactory) ) );
920 //.........................................................................
921 } // namespace frm
922 //.........................................................................
924 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */