23 #include <formcontroller.hxx>
29 #include <svx/strings.hrc>
34 #include <com/sun/star/awt/FocusChangeReason.hpp>
35 #include <com/sun/star/awt/XCheckBox.hpp>
36 #include <com/sun/star/awt/XComboBox.hpp>
37 #include <com/sun/star/awt/XListBox.hpp>
38 #include <com/sun/star/awt/XVclWindowPeer.hpp>
39 #include <com/sun/star/awt/TabController.hpp>
40 #include <com/sun/star/beans/PropertyAttribute.hpp>
41 #include <com/sun/star/container/XIdentifierReplace.hpp>
42 #include <com/sun/star/form/TabulatorCycle.hpp>
43 #include <com/sun/star/form/validation/XValidatableFormComponent.hpp>
44 #include <com/sun/star/form/XBoundComponent.hpp>
45 #include <com/sun/star/form/XBoundControl.hpp>
46 #include <com/sun/star/form/XGridControl.hpp>
47 #include <com/sun/star/form/XLoadable.hpp>
48 #include <com/sun/star/form/XReset.hpp>
49 #include <com/sun/star/form/control/FilterControl.hpp>
50 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
51 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
52 #include <com/sun/star/lang/NoSupportException.hpp>
53 #include <com/sun/star/sdb/ParametersRequest.hpp>
54 #include <com/sun/star/sdb/RowChangeAction.hpp>
55 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
56 #include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
57 #include <com/sun/star/sdbc/ColumnValue.hpp>
58 #include <com/sun/star/task/InteractionHandler.hpp>
59 #include <com/sun/star/form/runtime/FormOperations.hpp>
60 #include <com/sun/star/form/runtime/FormFeature.hpp>
61 #include <com/sun/star/container/XContainer.hpp>
62 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
63 #include <com/sun/star/util/NumberFormatter.hpp>
64 #include <com/sun/star/sdb/SQLContext.hpp>
65 #include <com/sun/star/sdb/XColumn.hpp>
87 #include <osl/mutex.hxx>
99 css::uno::Reference< css::uno::XInterface >
108 using ::com::sun::star::sdb::XColumn;
109 using ::com::sun::star::awt::XControl;
110 using ::com::sun::star::awt::TabController;
111 using ::com::sun::star::awt::XToolkit;
112 using ::com::sun::star::awt::XWindowPeer;
113 using ::com::sun::star::form::XGrid;
115 using ::com::sun::star::uno::UNO_SET_THROW;
116 using ::com::sun::star::uno::UNO_QUERY_THROW;
117 using ::com::sun::star::container::XIndexAccess;
118 using ::com::sun::star::uno::Exception;
119 using ::com::sun::star::uno::XInterface;
120 using ::com::sun::star::uno::UNO_QUERY;
121 using ::com::sun::star::uno::Sequence;
122 using ::com::sun::star::uno::Reference;
123 using ::com::sun::star::beans::XPropertySetInfo;
124 using ::com::sun::star::beans::PropertyValue;
125 using ::com::sun::star::lang::IndexOutOfBoundsException;
126 using ::com::sun::star::sdb::XInteractionSupplyParameters;
127 using ::com::sun::star::awt::XTextComponent;
128 using ::com::sun::star::awt::XTextListener;
129 using ::com::sun::star::uno::Any;
130 using ::com::sun::star::frame::XDispatch;
131 using ::com::sun::star::lang::XMultiServiceFactory;
132 using ::com::sun::star::uno::Type;
133 using ::com::sun::star::lang::IllegalArgumentException;
134 using ::com::sun::star::sdbc::XConnection;
135 using ::com::sun::star::sdbc::XRowSet;
136 using ::com::sun::star::sdbc::XDatabaseMetaData;
137 using ::com::sun::star::util::XNumberFormatsSupplier;
138 using ::com::sun::star::util::NumberFormatter;
139 using ::com::sun::star::util::XNumberFormatter;
140 using ::com::sun::star::sdbcx::XColumnsSupplier;
141 using ::com::sun::star::container::XNameAccess;
142 using ::com::sun::star::lang::EventObject;
143 using ::com::sun::star::beans::Property;
144 using ::com::sun::star::container::XEnumeration;
145 using ::com::sun::star::form::XFormComponent;
146 using ::com::sun::star::form::runtime::XFormOperations;
147 using ::com::sun::star::form::runtime::FilterEvent;
148 using ::com::sun::star::form::runtime::XFilterControllerListener;
149 using ::com::sun::star::awt::XControlContainer;
150 using ::com::sun::star::container::XIdentifierReplace;
151 using ::com::sun::star::form::XFormControllerListener;
152 using ::com::sun::star::awt::XWindow;
153 using ::com::sun::star::sdbc::XResultSet;
154 using ::com::sun::star::awt::XControlModel;
155 using ::com::sun::star::awt::XTabControllerModel;
156 using ::com::sun::star::beans::PropertyChangeEvent;
157 using ::com::sun::star::form::validation::XValidatableFormComponent;
158 using ::com::sun::star::form::XLoadable;
159 using ::com::sun::star::form::XBoundControl;
160 using ::com::sun::star::beans::XPropertyChangeListener;
161 using ::com::sun::star::awt::TextEvent;
162 using ::com::sun::star::form::XBoundComponent;
163 using ::com::sun::star::awt::XCheckBox;
164 using ::com::sun::star::awt::XComboBox;
165 using ::com::sun::star::awt::XListBox;
166 using ::com::sun::star::awt::ItemEvent;
167 using ::com::sun::star::util::XModifyListener;
168 using ::com::sun::star::form::XReset;
169 using ::com::sun::star::frame::XDispatchProviderInterception;
170 using ::com::sun::star::form::XGridControl;
171 using ::com::sun::star::awt::XVclWindowPeer;
172 using ::com::sun::star::form::validation::XValidator;
173 using ::com::sun::star::awt::FocusEvent;
174 using ::com::sun::star::sdb::SQLContext;
175 using ::com::sun::star::container::XChild;
176 using ::com::sun::star::form::TabulatorCycle_RECORDS;
177 using ::com::sun::star::container::ContainerEvent;
178 using ::com::sun::star::lang::DisposedException;
179 using ::com::sun::star::lang::Locale;
180 using ::com::sun::star::lang::NoSupportException;
181 using ::com::sun::star::sdb::RowChangeEvent;
182 using ::com::sun::star::frame::XStatusListener;
183 using ::com::sun::star::frame::XDispatchProviderInterceptor;
184 using ::com::sun::star::sdb::SQLErrorEvent;
185 using ::com::sun::star::form::DatabaseParameterEvent;
186 using ::com::sun::star::sdb::ParametersRequest;
187 using ::com::sun::star::task::XInteractionRequest;
188 using ::com::sun::star::util::URL;
189 using ::com::sun::star::frame::FeatureStateEvent;
190 using ::com::sun::star::form::runtime::XFormControllerContext;
191 using ::com::sun::star::task::InteractionHandler;
192 using ::com::sun::star::task::XInteractionHandler;
193 using ::com::sun::star::form::runtime::FormOperations;
194 using ::com::sun::star::container::XContainer;
195 using ::com::sun::star::sdbc::SQLWarning;
197 namespace ColumnValue = ::com::sun::star::sdbc::ColumnValue;
198 namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute;
199 namespace FocusChangeReason = ::com::sun::star::awt::FocusChangeReason;
200 namespace RowChangeAction = ::com::sun::star::sdb::RowChangeAction;
201 namespace FormFeature = ::com::sun::star::form::runtime::FormFeature;
229 ,nNullable( ColumnValue::NULLABLE_UNKNOWN )
230 ,bAutoIncrement( false )
233 ,xFirstControlWithInputRequired()
234 ,xFirstGridWithInputRequiredColumn()
235 ,nRequiredGridColumn( -1 )
245 explicit ColumnInfoCache(
const Reference< XColumnsSupplier >& _rxColSupplier );
263 ,m_bControlsInitialized( false )
269 Reference< XIndexAccess > xColumns( _rxColSupplier->getColumns(), UNO_QUERY_THROW );
270 sal_Int32 nColumnCount = xColumns->getCount();
274 for ( sal_Int32
i = 0;
i < nColumnCount; ++
i )
277 aColInfo.xColumn.set( xColumns->getByIndex(
i), UNO_QUERY_THROW );
279 xColumnProps.set( aColInfo.xColumn, UNO_QUERY_THROW );
280 OSL_VERIFY( xColumnProps->getPropertyValue(
FM_PROP_ISNULLABLE ) >>= aColInfo.nNullable );
282 OSL_VERIFY( xColumnProps->getPropertyValue(
FM_PROP_NAME ) >>= aColInfo.sName );
283 OSL_VERIFY( xColumnProps->getPropertyValue(
FM_PROP_ISREADONLY ) >>= aColInfo.bReadOnly );
299 Reference< XInterface > xNormBoundField( _rxControlModel->getPropertyValue(
FM_PROP_BOUNDFIELD ), UNO_QUERY );
300 return ( xNormBoundField == _rxNormDBField );
305 bool bInputRequired =
false;
307 return bInputRequired;
310 void lcl_resetColumnControlInfo(
ColumnInfo& _rColInfo )
312 _rColInfo.xFirstControlWithInputRequired.clear();
313 _rColInfo.xFirstGridWithInputRequiredColumn.clear();
314 _rColInfo.nRequiredGridColumn = -1;
323 lcl_resetColumnControlInfo( rCol );
336 OSL_ENSURE( !rCol.xFirstControlWithInputRequired.is() && !rCol.xFirstGridWithInputRequiredColumn.is()
337 && ( rCol.nRequiredGridColumn == -1 ),
"ColumnInfoCache::initializeControls: called me twice?" );
339 lcl_resetColumnControlInfo( rCol );
341 Reference< XInterface > xNormColumn( rCol.xColumn, UNO_QUERY_THROW );
343 const Reference< XControl >* pControl( _rControls.getConstArray() );
344 const Reference< XControl >* pControlEnd( pControl + _rControls.getLength() );
345 for ( ; pControl != pControlEnd; ++pControl )
347 if ( !pControl->is() )
351 Reference< XPropertySetInfo > xModelPSI(
xModel->getPropertySetInfo(), UNO_SET_THROW );
354 Reference< XGrid > xGrid( *pControl, UNO_QUERY );
357 Reference< XIndexAccess > xGridColAccess(
xModel, UNO_QUERY_THROW );
358 sal_Int32 gridColCount = xGridColAccess->getCount();
359 sal_Int32 gridCol = 0;
360 for ( gridCol = 0; gridCol < gridColCount; ++gridCol )
364 if ( !lcl_isBoundTo( xGridColumnModel, xNormColumn )
365 || !lcl_isInputRequired( xGridColumnModel )
372 if ( gridCol < gridColCount )
375 rCol.xFirstGridWithInputRequiredColumn = xGrid;
376 rCol.nRequiredGridColumn = gridCol;
384 || !lcl_isBoundTo(
xModel, xNormColumn )
385 || !lcl_isInputRequired(
xModel )
392 if ( pControl == pControlEnd )
396 rCol.xFirstControlWithInputRequired = *pControl;
411 throw IndexOutOfBoundsException();
418 class OParameterContinuation :
public OInteraction< XInteractionSupplyParameters >
423 OParameterContinuation() { }
425 const Sequence< PropertyValue >& getValues()
const {
return m_aValues; }
428 virtual void SAL_CALL setParameters(
const Sequence< PropertyValue >& _rValues )
override;
433 void SAL_CALL OParameterContinuation::setParameters(
const Sequence< PropertyValue >& _rValues )
463 virtual OUString GetComponentServiceName()
override {
return "Edit";}
464 virtual void SAL_CALL createPeer(
const Reference< XToolkit > & rxToolkit,
const Reference< XWindowPeer > & rParentPeer )
override;
467 virtual void ImplSetPeerProperty(
const OUString& rPropName,
const Any& rVal )
override;
472 void FmXAutoControl::createPeer(
const Reference< XToolkit > & rxToolkit,
const Reference< XWindowPeer > & rParentPeer )
476 Reference< XTextComponent > xText(getPeer() , UNO_QUERY);
479 xText->setText(
SvxResId(RID_STR_AUTOFIELD));
480 xText->setEditable(
false);
485 void FmXAutoControl::ImplSetPeerProperty(
const OUString& rPropName,
const Any& rVal )
502 struct UpdateAllListeners
504 bool operator()(
const Reference< XDispatch >& _rxDispatcher )
const
516 ::osl::MutexGuard aGuard(
m_aMutex );
517 for (
const auto& rFeature : m_aInvalidFeatures)
519 DispatcherContainer::const_iterator aDispatcherPos = m_aFeatureDispatchers.find( rFeature );
520 if ( aDispatcherPos != m_aFeatureDispatchers.end() )
524 UpdateAllListeners( )( aDispatcherPos->second );
532 ,OSQLParserClient( _rxORB )
538 ,m_aRowSetApproveListeners(
m_aMutex)
542 ,m_aMode( OUString(
"DataMode" ) )
543 ,m_aLoadEvent(
LINK( this, FormController, OnLoad ) )
544 ,m_aToggleEvent(
LINK( this, FormController, OnToggleAutoFields ) )
545 ,m_aActivationEvent(
LINK( this, FormController, OnActivated ) )
546 ,m_aDeactivationEvent(
LINK( this, FormController, OnDeactivated ) )
547 ,m_nCurrentFilterPosition(-1)
548 ,m_bCurrentRecordModified(false)
549 ,m_bCurrentRecordNew(false)
551 ,m_bDBConnection(false)
555 ,m_bCommitLock(false)
557 ,m_bControlsSorted(false)
559 ,m_bAttachEvents(true)
560 ,m_bDetachEvents(true)
561 ,m_bAttemptedHandlerCreation( false )
562 ,m_bSuspendFilterTextListening( false )
565 osl_atomic_increment(&m_refCount);
567 m_xTabController = TabController::create( m_xComponentContext );
568 m_xAggregate.set( m_xTabController, UNO_QUERY_THROW );
569 m_xAggregate->setDelegator( *
this );
571 osl_atomic_decrement(&m_refCount);
573 m_aTabActivationIdle.SetPriority( TaskPriority::LOWEST );
574 m_aTabActivationIdle.SetInvokeHandler(
LINK(
this, FormController, OnActivateTabOrder ) );
576 m_aFeatureInvalidationTimer.SetTimeout( 200 );
577 m_aFeatureInvalidationTimer.SetInvokeHandler(
LINK(
this, FormController, OnInvalidateFeatures ) );
581 FormController::~FormController()
584 ::osl::MutexGuard aGuard(
m_aMutex );
586 m_aLoadEvent.CancelPendingCall();
587 m_aToggleEvent.CancelPendingCall();
588 m_aActivationEvent.CancelPendingCall();
589 m_aDeactivationEvent.CancelPendingCall();
591 if ( m_aTabActivationIdle.IsActive() )
592 m_aTabActivationIdle.Stop();
595 if ( m_aFeatureInvalidationTimer.IsActive() )
596 m_aFeatureInvalidationTimer.Stop();
598 disposeAllFeaturesAndDispatchers();
600 if ( m_xFormOperations.is() )
601 m_xFormOperations->dispose();
602 m_xFormOperations.clear();
605 if ( m_xAggregate.is() )
607 m_xAggregate->setDelegator(
nullptr );
608 m_xAggregate.clear();
613 void SAL_CALL FormController::acquire() throw ()
615 FormController_BASE::acquire();
619 void SAL_CALL FormController::release() throw ()
621 FormController_BASE::release();
625 Any SAL_CALL FormController::queryInterface(
const Type& _rType )
627 Any aRet = FormController_BASE::queryInterface( _rType );
628 if ( !aRet.hasValue() )
629 aRet = OPropertySetHelper::queryInterface( _rType );
630 if ( !aRet.hasValue() )
631 aRet = m_xAggregate->queryAggregation( _rType );
638 return css::uno::Sequence<sal_Int8>();
641 Sequence< Type > SAL_CALL FormController::getTypes( )
644 FormController_BASE::getTypes(),
650 sal_Bool SAL_CALL FormController::supportsService(
const OUString& ServiceName)
655 OUString SAL_CALL FormController::getImplementationName()
657 return "org.openoffice.comp.svx.FormController";
664 Sequence<OUString> aNonCreatableServiceNames {
"com.sun.star.form.FormControllerDispatcher" };
668 return ::comphelper::concatSequences( aCreatableServiceNames, aNonCreatableServiceNames );
672 sal_Bool SAL_CALL FormController::approveReset(
const EventObject& )
678 void SAL_CALL FormController::resetted(
const EventObject& rEvent)
681 if (getCurrentControl().is() && (getCurrentControl()->getModel() == rEvent.Source))
690 "com.sun.star.form.runtime.FormController",
691 "com.sun.star.awt.control.TabController"
699 struct ResetComponentText
701 void operator()(
const Reference< XTextComponent >& _rxText )
703 _rxText->setText( OUString() );
707 struct RemoveComponentTextListener
709 explicit RemoveComponentTextListener(
const Reference< XTextListener >& _rxListener )
714 void operator()(
const Reference< XTextComponent >& _rxText )
725 void FormController::impl_setTextOnAllFilter_throw()
727 m_bSuspendFilterTextListening =
true;
731 ::std::for_each( m_aFilterComponents.begin(), m_aFilterComponents.end(), ResetComponentText() );
733 if ( m_aFilterRows.empty() )
737 if ( m_nCurrentFilterPosition < 0 )
742 "FormController::impl_setTextOnAllFilter_throw: m_nCurrentFilterPosition too big" );
746 FmFilterRow& rRow = m_aFilterRows[ m_nCurrentFilterPosition ];
747 for (
const auto& rEntry : rRow)
749 rEntry.first->setText( rEntry.second );
755 sal_Bool FormController::convertFastPropertyValue( Any & , Any & ,
756 sal_Int32 ,
const Any& )
762 void FormController::setFastPropertyValue_NoBroadcast( sal_Int32 ,
const Any& )
767 void FormController::getFastPropertyValue( Any& rValue, sal_Int32 nHandle )
const
773 OUStringBuffer aFilter;
775 if (xConnection.is())
777 Reference< XNumberFormatsSupplier> xFormatSupplier(
getNumberFormats( xConnection,
true ) );
779 xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
789 OUStringBuffer aRowFilter;
790 for ( FmFilterRow::const_iterator condition = rRow.begin(); condition != rRow.end(); ++condition )
793 Reference< XControl > xControl( condition->first, UNO_QUERY_THROW );
797 OUString sFilterValue( condition->second );
800 const std::unique_ptr< OSQLParseNode > pParseNode =
801 predicateTree( sErrorMsg, sFilterValue, xFormatter, xField );
802 OSL_ENSURE( pParseNode !=
nullptr,
"FormController::getFastPropertyValue: could not parse the field value predicate!" );
803 if ( pParseNode !=
nullptr )
807 pParseNode->parseNodeToStr( sCriteria, xConnection );
808 if ( condition != rRow.begin() )
809 aRowFilter.append(
" AND " );
810 aRowFilter.append( sCriteria );
813 if ( !aRowFilter.isEmpty() )
815 if ( !aFilter.isEmpty() )
816 aFilter.append(
" OR " );
818 aFilter.append(
"( " );
819 aFilter.append( aRowFilter.makeStringAndClear() );
820 aFilter.append(
" )" );
824 catch(
const Exception& )
827 aFilter.setLength(0);
830 rValue <<= aFilter.makeStringAndClear();
835 rValue <<= m_xFormOperations;
841 Reference< XPropertySetInfo > FormController::getPropertySetInfo()
843 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
848 void FormController::fillProperties(
849 Sequence< Property >& _rProps,
850 Sequence< Property >&
859 PropertyAttribute::READONLY);
862 PropertyAttribute::READONLY);
868 return *getArrayHelper();
873 void SAL_CALL FormController::addFilterControllerListener(
const Reference< XFilterControllerListener >& Listener )
875 m_aFilterListeners.addInterface( Listener );
879 void SAL_CALL FormController::removeFilterControllerListener(
const Reference< XFilterControllerListener >& Listener )
881 m_aFilterListeners.removeInterface( Listener );
885 ::sal_Int32 SAL_CALL FormController::getFilterComponents()
887 ::osl::MutexGuard aGuard(
m_aMutex );
888 impl_checkDisposed_throw();
890 return m_aFilterComponents.size();
894 ::sal_Int32 SAL_CALL FormController::getDisjunctiveTerms()
896 ::osl::MutexGuard aGuard(
m_aMutex );
897 impl_checkDisposed_throw();
899 return m_aFilterRows.size();
903 void SAL_CALL FormController::setPredicateExpression( ::sal_Int32
Component, ::sal_Int32 Term,
const OUString& PredicateExpression )
905 ::osl::MutexGuard aGuard(
m_aMutex );
906 impl_checkDisposed_throw();
908 if ( ( Component < 0 ) || ( Component >= getFilterComponents() ) || ( Term < 0 ) || ( Term >= getDisjunctiveTerms() ) )
909 throw IndexOutOfBoundsException( OUString(), *
this );
911 Reference< XTextComponent > xText( m_aFilterComponents[ Component ] );
912 xText->setText( PredicateExpression );
915 if ( !PredicateExpression.isEmpty() )
916 rFilterRow[ xText ] = PredicateExpression;
918 rFilterRow.erase( xText );
922 Reference< XControl > FormController::getFilterComponent( ::sal_Int32
Component )
924 ::osl::MutexGuard aGuard(
m_aMutex );
925 impl_checkDisposed_throw();
927 if ( ( Component < 0 ) || ( Component >= getFilterComponents() ) )
928 throw IndexOutOfBoundsException( OUString(), *
this );
930 return Reference< XControl >( m_aFilterComponents[ Component ], UNO_QUERY );
934 Sequence< Sequence< OUString > > FormController::getPredicateExpressions()
936 ::osl::MutexGuard aGuard(
m_aMutex );
937 impl_checkDisposed_throw();
939 Sequence< Sequence< OUString > > aExpressions( m_aFilterRows.size() );
940 sal_Int32 termIndex = 0;
944 sal_Int32 componentIndex = 0;
945 for (
const auto& rComp : m_aFilterComponents)
947 FmFilterRow::const_iterator predicate = rRow.find( rComp );
948 if ( predicate != rRow.end() )
949 aConjunction[ componentIndex ] = predicate->second;
953 aExpressions[ termIndex ] = aConjunction;
961 void SAL_CALL FormController::removeDisjunctiveTerm( ::sal_Int32 Term )
964 ::osl::ClearableMutexGuard aGuard(
m_aMutex );
965 impl_checkDisposed_throw();
967 if ( ( Term < 0 ) || ( Term >= getDisjunctiveTerms() ) )
968 throw IndexOutOfBoundsException( OUString(), *
this );
971 if ( Term == m_nCurrentFilterPosition )
973 if ( m_nCurrentFilterPosition < sal_Int32( m_aFilterRows.size() - 1 ) )
974 ++m_nCurrentFilterPosition;
976 --m_nCurrentFilterPosition;
979 FmFilterRows::iterator
pos = m_aFilterRows.begin() + Term;
980 m_aFilterRows.erase( pos );
983 if ( Term < m_nCurrentFilterPosition )
984 --m_nCurrentFilterPosition;
986 SAL_WARN_IF( !( ( m_nCurrentFilterPosition < 0 ) != ( m_aFilterRows.empty() ) ),
987 "svx.form",
"FormController::removeDisjunctiveTerm: inconsistency!" );
990 impl_setTextOnAllFilter_throw();
993 aEvent.Source = *
this;
994 aEvent.DisjunctiveTerm = Term;
998 m_aFilterListeners.notifyEach( &XFilterControllerListener::disjunctiveTermRemoved, aEvent );
1002 void SAL_CALL FormController::appendEmptyDisjunctiveTerm()
1005 ::osl::ClearableMutexGuard aGuard(
m_aMutex );
1006 impl_checkDisposed_throw();
1008 impl_appendEmptyFilterRow( aGuard );
1013 ::sal_Int32 SAL_CALL FormController::getActiveTerm()
1015 ::osl::MutexGuard aGuard(
m_aMutex );
1016 impl_checkDisposed_throw();
1018 return m_nCurrentFilterPosition;
1022 void SAL_CALL FormController::setActiveTerm( ::sal_Int32 ActiveTerm )
1024 ::osl::MutexGuard aGuard(
m_aMutex );
1025 impl_checkDisposed_throw();
1027 if ( ( ActiveTerm < 0 ) || ( ActiveTerm >= getDisjunctiveTerms() ) )
1028 throw IndexOutOfBoundsException( OUString(), *
this );
1030 if ( ActiveTerm == getActiveTerm() )
1033 m_nCurrentFilterPosition = ActiveTerm;
1034 impl_setTextOnAllFilter_throw();
1041 ::osl::MutexGuard aGuard(
m_aMutex );
1042 return !m_aChildren.empty();
1046 Type SAL_CALL FormController::getElementType()
1054 Reference< XEnumeration > SAL_CALL FormController::createEnumeration()
1056 ::osl::MutexGuard aGuard(
m_aMutex );
1057 return new ::comphelper::OEnumerationByIndex(
this);
1062 sal_Int32 SAL_CALL FormController::getCount()
1064 ::osl::MutexGuard aGuard(
m_aMutex );
1065 return m_aChildren.size();
1069 Any SAL_CALL FormController::getByIndex(sal_Int32
Index)
1071 ::osl::MutexGuard aGuard(
m_aMutex );
1073 Index >= static_cast<sal_Int32>(m_aChildren.size()))
1074 throw IndexOutOfBoundsException();
1076 return makeAny( m_aChildren[ Index ] );
1081 void SAL_CALL FormController::disposing(
const EventObject& e)
1084 ::osl::MutexGuard aGuard( m_aMutex );
1085 Reference< XControlContainer > xContainer(e.Source, UNO_QUERY);
1086 if (xContainer.is())
1088 setContainer(Reference< XControlContainer > ());
1093 Reference< XControl > xControl(e.Source, UNO_QUERY);
1096 if (getContainer().is())
1097 removeControl(xControl);
1104 void FormController::disposeAllFeaturesAndDispatchers()
1106 for (
auto& rDispatcher : m_aFeatureDispatchers)
1110 ::comphelper::disposeComponent( rDispatcher.second );
1117 m_aFeatureDispatchers.clear();
1121 void FormController::disposing()
1123 EventObject aEvt( *
this );
1126 if ( m_xActiveControl.is() )
1127 m_aActivateListeners.notifyEach( &XFormControllerListener::formDeactivated, aEvt );
1130 m_aActivateListeners.disposeAndClear(aEvt);
1131 m_aModifyListeners.disposeAndClear(aEvt);
1132 m_aErrorListeners.disposeAndClear(aEvt);
1133 m_aDeleteListeners.disposeAndClear(aEvt);
1134 m_aRowSetApproveListeners.disposeAndClear(aEvt);
1135 m_aParameterListeners.disposeAndClear(aEvt);
1136 m_aFilterListeners.disposeAndClear(aEvt);
1138 removeBoundFieldListener();
1141 m_aControlBorderManager.restoreAll();
1143 m_aFilterRows.clear();
1145 ::osl::MutexGuard aGuard(
m_aMutex );
1146 m_xActiveControl =
nullptr;
1147 implSetCurrentControl(
nullptr );
1150 for (
const auto& rpChild : m_aChildren)
1153 Reference< XFormComponent > xForm(rpChild->getModel(), UNO_QUERY);
1154 sal_uInt32
nPos = m_xModelAsIndex->getCount();
1155 Reference< XFormComponent > xTemp;
1159 m_xModelAsIndex->getByIndex( --nPos ) >>= xTemp;
1160 if ( xForm.get() == xTemp.get() )
1162 Reference< XInterface > xIfc( rpChild, UNO_QUERY );
1163 m_xModelAsManager->detach( nPos, xIfc );
1168 Reference< XComponent > (rpChild, UNO_QUERY_THROW)->
dispose();
1170 m_aChildren.clear();
1172 disposeAllFeaturesAndDispatchers();
1174 if ( m_xFormOperations.is() )
1175 m_xFormOperations->dispose();
1176 m_xFormOperations.clear();
1178 if (m_bDBConnection)
1181 setContainer(
nullptr );
1182 setModel(
nullptr );
1183 setParent(
nullptr );
1185 ::comphelper::disposeComponent( m_xComposer );
1187 m_bDBConnection =
false;
1193 bool lcl_shouldUseDynamicControlBorder(
const Reference< XInterface >& _rxForm,
const Any& _rDynamicColorProp )
1195 bool bDoUse =
false;
1196 if ( !( _rDynamicColorProp >>= bDoUse ) )
1198 DocumentType eDocType = DocumentClassification::classifyHostDocument( _rxForm );
1206 void SAL_CALL FormController::propertyChange(
const PropertyChangeEvent& evt)
1208 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1212 evt.OldValue >>= xOldBound;
1213 if ( !xOldBound.is() && evt.NewValue.hasValue() )
1215 Reference< XControlModel > xControlModel(evt.Source,UNO_QUERY);
1216 Reference< XControl > xControl = findControl(m_aControls,xControlModel,
false,
false);
1217 if ( xControl.is() )
1219 startControlModifyListening( xControl );
1230 if (bModifiedChanged || bNewChanged)
1232 ::osl::MutexGuard aGuard(
m_aMutex );
1233 if (bModifiedChanged)
1234 m_bCurrentRecordModified = ::comphelper::getBOOL(evt.NewValue);
1236 m_bCurrentRecordNew = ::comphelper::getBOOL(evt.NewValue);
1239 if (m_bLocked != determineLockState())
1241 m_bLocked = !m_bLocked;
1243 if (isListeningForChanges())
1250 m_aToggleEvent.Call();
1252 if (!m_bCurrentRecordModified)
1253 m_bModified =
false;
1257 bool bEnable = lcl_shouldUseDynamicControlBorder( evt.Source, evt.NewValue );
1260 m_aControlBorderManager.enableDynamicBorderColor();
1261 if ( m_xActiveControl.is() )
1262 m_aControlBorderManager.focusGained( m_xActiveControl );
1266 m_aControlBorderManager.disableDynamicBorderColor();
1273 bool FormController::replaceControl(
const Reference< XControl >& _rxExistentControl,
const Reference< XControl >& _rxNewControl )
1275 bool bSuccess =
false;
1278 Reference< XIdentifierReplace > xContainer( getContainer(), UNO_QUERY );
1279 DBG_ASSERT( xContainer.is(),
"FormController::replaceControl: yes, it's not required by the service description, but XIdentifierReplace would be nice!" );
1280 if ( xContainer.is() )
1283 Sequence< sal_Int32 > aIdentifiers( xContainer->getIdentifiers() );
1284 const sal_Int32* pIdentifiers = std::find_if(aIdentifiers.begin(), aIdentifiers.end(),
1285 [&xContainer, &_rxExistentControl](
const sal_Int32
nId) {
1286 Reference< XControl > xCheck( xContainer->getByIdentifier(
nId ), UNO_QUERY );
1287 return xCheck == _rxExistentControl;
1289 DBG_ASSERT( pIdentifiers != aIdentifiers.end(),
"FormController::replaceControl: did not find the control in the container!" );
1290 if ( pIdentifiers != aIdentifiers.end() )
1292 bool bReplacedWasActive = ( m_xActiveControl.get() == _rxExistentControl.get() );
1293 bool bReplacedWasCurrent = ( m_xCurrentControl.get() == _rxExistentControl.get() );
1295 if ( bReplacedWasActive )
1297 m_xActiveControl =
nullptr;
1298 implSetCurrentControl(
nullptr );
1300 else if ( bReplacedWasCurrent )
1302 implSetCurrentControl( _rxNewControl );
1306 _rxNewControl->setModel( _rxExistentControl->getModel() );
1308 xContainer->replaceByIdentifer( *pIdentifiers,
makeAny( _rxNewControl ) );
1311 if ( bReplacedWasActive )
1313 Reference< XWindow > xControlWindow( _rxNewControl, UNO_QUERY );
1314 if ( xControlWindow.is() )
1315 xControlWindow->setFocus();
1325 Reference< XControl > xDisposeIt( bSuccess ? _rxExistentControl : _rxNewControl );
1326 ::comphelper::disposeComponent( xDisposeIt );
1331 void FormController::toggleAutoFields(
bool bAutoFields)
1333 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1336 Sequence< Reference< XControl > > aControlsCopy( m_aControls );
1337 const Reference< XControl >* pControls = aControlsCopy.getConstArray();
1338 sal_Int32 nControls = aControlsCopy.getLength();
1344 m_bAttachEvents =
false;
1345 for (sal_Int32
i = nControls;
i > 0;)
1347 Reference< XControl > xControl = pControls[--
i];
1363 replaceControl( xControl,
new FmXAutoControl() );
1368 m_bAttachEvents =
true;
1372 m_bDetachEvents =
false;
1373 for (sal_Int32
i = nControls;
i > 0;)
1375 Reference< XControl > xControl = pControls[--
i];
1394 replaceControl( xControl, xNewControl );
1399 m_bDetachEvents =
true;
1406 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1408 toggleAutoFields(m_bCurrentRecordNew);
1412 void SAL_CALL FormController::textChanged(
const TextEvent& e)
1415 ::osl::ClearableMutexGuard aGuard(
m_aMutex );
1416 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1417 if ( !m_bFiltering )
1423 if ( m_bSuspendFilterTextListening )
1426 Reference< XTextComponent > xText(e.Source,UNO_QUERY);
1427 OUString aText = xText->getText();
1429 if ( m_aFilterRows.empty() )
1430 appendEmptyDisjunctiveTerm();
1433 if ( ( m_nCurrentFilterPosition < 0 ) || (
o3tl::make_unsigned(m_nCurrentFilterPosition) >= m_aFilterRows.size() ) )
1435 OSL_ENSURE(
false,
"FormController::textChanged: m_nCurrentFilterPosition is wrong!" );
1439 FmFilterRow& rRow = m_aFilterRows[ m_nCurrentFilterPosition ];
1442 if (!aText.isEmpty())
1443 rRow[xText] = aText;
1447 FmFilterRow::iterator iter = rRow.find(xText);
1449 if (iter != rRow.end())
1455 aEvent.Source = *
this;
1456 aEvent.FilterComponent = ::std::find( m_aFilterComponents.begin(), m_aFilterComponents.end(), xText ) - m_aFilterComponents.begin();
1457 aEvent.DisjunctiveTerm = getActiveTerm();
1458 aEvent.PredicateExpression = aText;
1464 m_aFilterListeners.notifyEach( &XFilterControllerListener::predicateExpressionChanged, aEvent );
1468 void SAL_CALL FormController::itemStateChanged(
const ItemEvent& )
1470 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1475 void SAL_CALL FormController::addModifyListener(
const Reference< XModifyListener > & l)
1477 ::osl::MutexGuard aGuard(
m_aMutex );
1478 impl_checkDisposed_throw();
1479 m_aModifyListeners.addInterface( l );
1482 void FormController::removeModifyListener(
const Reference< XModifyListener > & l)
1484 ::osl::MutexGuard aGuard(
m_aMutex );
1485 impl_checkDisposed_throw();
1486 m_aModifyListeners.removeInterface( l );
1490 void FormController::modified(
const EventObject& _rEvent )
1492 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1496 if ( _rEvent.Source != m_xActiveControl )
1504 Reference< XWindow > xControlWindow( _rEvent.Source, UNO_QUERY_THROW );
1505 xControlWindow->setFocus();
1516 void FormController::impl_checkDisposed_throw()
const
1518 if ( impl_isDisposed_nofail() )
1519 throw DisposedException( OUString(), *const_cast< FormController* >(
this ) );
1522 void FormController::impl_onModify()
1524 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1527 ::osl::MutexGuard aGuard(
m_aMutex );
1532 EventObject aEvt(static_cast<cppu::OWeakObject*>(
this));
1533 m_aModifyListeners.notifyEach( &XModifyListener::modified, aEvt );
1538 m_aFilterRows.push_back( _row );
1540 if ( m_aFilterRows.size() == 1 )
1542 OSL_ENSURE( m_nCurrentFilterPosition == -1,
"FormController::impl_addFilterRow: inconsistency!" );
1543 m_nCurrentFilterPosition = 0;
1547 void FormController::impl_appendEmptyFilterRow( ::osl::ClearableMutexGuard& _rClearBeforeNotify )
1554 aEvent.Source = *
this;
1555 aEvent.DisjunctiveTerm =
static_cast<sal_Int32
>(m_aFilterRows.size()) - 1;
1556 _rClearBeforeNotify.clear();
1558 m_aFilterListeners.notifyEach( &XFilterControllerListener::disjunctiveTermAdded, aEvent );
1561 bool FormController::determineLockState()
const
1563 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1568 Reference< XResultSet > xResultSet(m_xModelAsIndex, UNO_QUERY);
1569 if (m_bFiltering || !xResultSet.is() || !
isRowSetAlive(xResultSet))
1572 return !(m_bCanInsert && m_bCurrentRecordNew)
1573 && (xResultSet->isBeforeFirst() || xResultSet->isAfterLast() || xResultSet->rowDeleted() || !m_bCanUpdate);
1577 void FormController::focusGained(
const FocusEvent& e)
1580 ::osl::ClearableMutexGuard aGuard(
m_aMutex );
1581 impl_checkDisposed_throw();
1583 m_aControlBorderManager.focusGained( e.Source );
1585 Reference< XControl > xControl(e.Source, UNO_QUERY);
1586 if (m_bDBConnection)
1591 m_bCommitLock = m_bCommitLock && xControl.get() != m_xCurrentControl.get();
1601 if ( ( m_bModified || m_bFiltering )
1602 && m_xCurrentControl.is()
1603 && ( ( xControl.get() != m_xCurrentControl.get() )
1604 || ( ( e.FocusFlags & FocusChangeReason::AROUND )
1605 && ( m_bCycle || m_bFiltering )
1611 #if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
1612 Reference< XBoundControl > xLockingTest(m_xCurrentControl, UNO_QUERY);
1613 bool bControlIsLocked = xLockingTest.is() && xLockingTest->getLock();
1614 assert(!bControlIsLocked &&
"FormController::Gained: I'm modified and the current control is locked ? How this ?");
1618 DBG_ASSERT(m_xCurrentControl.is(),
"no CurrentControl set");
1620 Reference< XBoundComponent > xBound(m_xCurrentControl, UNO_QUERY);
1621 if (!xBound.is() && m_xCurrentControl.is())
1622 xBound.set(m_xCurrentControl->getModel(), UNO_QUERY);
1625 m_bCommitLock =
true;
1628 if (xBound.is() && !xBound->commit())
1632 Reference< XWindow > xWindow(m_xCurrentControl, UNO_QUERY);
1634 xWindow->setFocus();
1639 m_bModified =
false;
1640 m_bCommitLock =
false;
1644 if (!m_bFiltering && m_bCycle && (e.FocusFlags & FocusChangeReason::AROUND) && m_xCurrentControl.is())
1646 OSL_ENSURE( m_xFormOperations.is(),
"FormController::focusGained: hmm?" );
1650 if ( e.FocusFlags & FocusChangeReason::FORWARD )
1652 if ( m_xFormOperations.is() && m_xFormOperations->isEnabled( FormFeature::MoveToNext ) )
1653 m_xFormOperations->execute( FormFeature::MoveToNext );
1657 if ( m_xFormOperations.is() && m_xFormOperations->isEnabled( FormFeature::MoveToPrevious ) )
1658 m_xFormOperations->execute( FormFeature::MoveToPrevious );
1670 if ( ( m_xActiveControl == xControl )
1671 && ( xControl == m_xCurrentControl )
1674 DBG_ASSERT(m_xCurrentControl.is(),
"No CurrentControl selected");
1678 bool bActivated = !m_xActiveControl.is() && xControl.is();
1680 m_xActiveControl = xControl;
1682 implSetCurrentControl( xControl );
1683 SAL_WARN_IF( !m_xCurrentControl.is(),
"svx.form",
"implSetCurrentControl did nonsense!" );
1688 m_aActivationEvent.Call();
1692 m_aModifyListeners.notifyEach( &XModifyListener::modified, EventObject( *
this ) );
1696 if ( m_bDBConnection && !m_bFiltering )
1697 implInvalidateCurrentControlDependentFeatures();
1699 if ( !m_xCurrentControl.is() )
1703 Reference< XFormControllerContext > xContext( m_xFormControllerContext );
1704 Reference< XControl > xCurrentControl( m_xCurrentControl );
1708 if ( xContext.is() )
1709 xContext->makeVisible( xCurrentControl );
1715 aEvent.Source = *
this;
1716 m_aActivateListeners.notifyEach( &XFormControllerListener::formActivated, aEvent );
1722 aEvent.Source = *
this;
1723 m_aActivateListeners.notifyEach( &XFormControllerListener::formDeactivated, aEvent );
1726 void FormController::focusLost(
const FocusEvent& e)
1728 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1730 m_aControlBorderManager.focusLost( e.Source );
1732 Reference< XWindowPeer > xNext(e.NextFocus, UNO_QUERY);
1736 Reference< XControl > xNextControl = isInList(xNext);
1737 if (!xNextControl.is())
1739 m_xActiveControl =
nullptr;
1740 m_aDeactivationEvent.Call();
1744 void SAL_CALL FormController::mousePressed(
const awt::MouseEvent& )
1749 void SAL_CALL FormController::mouseReleased(
const awt::MouseEvent& )
1754 void SAL_CALL FormController::mouseEntered(
const awt::MouseEvent& _rEvent )
1756 m_aControlBorderManager.mouseEntered( _rEvent.Source );
1759 void SAL_CALL FormController::mouseExited(
const awt::MouseEvent& _rEvent )
1761 m_aControlBorderManager.mouseExited( _rEvent.Source );
1764 void SAL_CALL FormController::componentValidityChanged(
const EventObject& _rSource )
1766 Reference< XControl > xControl( findControl( m_aControls, Reference< XControlModel >( _rSource.Source, UNO_QUERY ),
false,
false ) );
1767 Reference< XValidatableFormComponent > xValidatable( _rSource.Source, UNO_QUERY );
1769 OSL_ENSURE( xControl.is() && xValidatable.is(),
"FormController::componentValidityChanged: huh?" );
1771 if ( xControl.is() && xValidatable.is() )
1772 m_aControlBorderManager.validityChanged( xControl, xValidatable );
1776 void FormController::setModel(
const Reference< XTabControllerModel > & Model)
1778 ::osl::MutexGuard aGuard(
m_aMutex );
1779 impl_checkDisposed_throw();
1781 DBG_ASSERT(m_xTabController.is(),
"FormController::setModel : invalid aggregate !");
1786 if (m_xModelAsIndex.is())
1788 if (m_bDBConnection)
1791 EventObject aEvt(m_xModelAsIndex);
1795 Reference< XLoadable > xForm(m_xModelAsIndex, UNO_QUERY);
1797 xForm->removeLoadListener(
this);
1799 Reference< XSQLErrorBroadcaster > xBroadcaster(m_xModelAsIndex, UNO_QUERY);
1800 if (xBroadcaster.is())
1801 xBroadcaster->removeSQLErrorListener(
this);
1803 Reference< XDatabaseParameterBroadcaster > xParamBroadcaster(m_xModelAsIndex, UNO_QUERY);
1804 if (xParamBroadcaster.is())
1805 xParamBroadcaster->removeParameterListener(
this);
1809 disposeAllFeaturesAndDispatchers();
1811 if ( m_xFormOperations.is() )
1812 m_xFormOperations->dispose();
1813 m_xFormOperations.clear();
1816 if (m_xTabController.is())
1817 m_xTabController->setModel(Model);
1818 m_xModelAsIndex.set(Model, UNO_QUERY);
1819 m_xModelAsManager.set(Model, UNO_QUERY);
1822 if (!m_xModelAsIndex.is() || !m_xModelAsManager.is())
1824 m_xModelAsManager =
nullptr;
1825 m_xModelAsIndex =
nullptr;
1828 if (m_xModelAsIndex.is())
1831 m_xFormOperations = FormOperations::createWithFormController(
m_xComponentContext,
this );
1832 m_xFormOperations->setFeatureInvalidation(
this );
1835 Reference< XLoadable > xForm(Model, UNO_QUERY);
1837 xForm->addLoadListener(
this);
1839 Reference< XSQLErrorBroadcaster > xBroadcaster(Model, UNO_QUERY);
1840 if (xBroadcaster.is())
1841 xBroadcaster->addSQLErrorListener(
this);
1843 Reference< XDatabaseParameterBroadcaster > xParamBroadcaster(Model, UNO_QUERY);
1844 if (xParamBroadcaster.is())
1845 xParamBroadcaster->addParameterListener(
this);
1849 Reference< XLoadable > xCursor(m_xModelAsIndex, UNO_QUERY);
1850 if (xCursor.is() && xCursor->isLoaded())
1852 EventObject aEvt(xCursor);
1857 Reference< XPropertySetInfo > xPropInfo( xModelProps->getPropertySetInfo() );
1865 bool bEnableDynamicControlBorder = lcl_shouldUseDynamicControlBorder(
1867 if ( bEnableDynamicControlBorder )
1868 m_aControlBorderManager.enableDynamicBorderColor();
1870 m_aControlBorderManager.disableDynamicBorderColor();
1889 Reference< XTabControllerModel > FormController::getModel()
1891 ::osl::MutexGuard aGuard(
m_aMutex );
1892 impl_checkDisposed_throw();
1894 DBG_ASSERT(m_xTabController.is(),
"FormController::getModel : invalid aggregate !");
1895 if (!m_xTabController.is())
1896 return Reference< XTabControllerModel > ();
1897 return m_xTabController->getModel();
1901 void FormController::addToEventAttacher(
const Reference< XControl > & xControl)
1903 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1904 OSL_ENSURE( xControl.is(),
"FormController::addToEventAttacher: invalid control - how did you reach this?" );
1905 if ( !xControl.is() )
1909 Reference< XFormComponent > xComp(xControl->getModel(), UNO_QUERY);
1910 if (!(xComp.is() && m_xModelAsIndex.is()))
1914 sal_uInt32
nPos = m_xModelAsIndex->getCount();
1915 Reference< XFormComponent > xTemp;
1918 m_xModelAsIndex->getByIndex(--nPos) >>= xTemp;
1919 if (xComp.get() == xTemp.get())
1921 m_xModelAsManager->attach( nPos, Reference<XInterface>( xControl, UNO_QUERY ),
makeAny(xControl) );
1928 void FormController::removeFromEventAttacher(
const Reference< XControl > & xControl)
1930 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1931 OSL_ENSURE( xControl.is(),
"FormController::removeFromEventAttacher: invalid control - how did you reach this?" );
1932 if ( !xControl.is() )
1936 Reference< XFormComponent > xComp(xControl->getModel(), UNO_QUERY);
1937 if ( !(xComp.is() && m_xModelAsIndex.is()) )
1941 sal_uInt32
nPos = m_xModelAsIndex->getCount();
1942 Reference< XFormComponent > xTemp;
1945 m_xModelAsIndex->getByIndex(--nPos) >>= xTemp;
1946 if (xComp.get() == xTemp.get())
1948 m_xModelAsManager->detach( nPos, Reference<XInterface>( xControl, UNO_QUERY ) );
1955 void FormController::setContainer(
const Reference< XControlContainer > & xContainer)
1957 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1958 Reference< XTabControllerModel > xTabModel(getModel());
1959 DBG_ASSERT(xTabModel.is() || !xContainer.is(),
"No Model defined");
1961 DBG_ASSERT(m_xTabController.is(),
"FormController::setContainer : invalid aggregate !");
1963 ::osl::MutexGuard aGuard(
m_aMutex );
1964 Reference< XContainer > xCurrentContainer;
1965 if (m_xTabController.is())
1966 xCurrentContainer.set(m_xTabController->getContainer(), UNO_QUERY);
1967 if (xCurrentContainer.is())
1969 xCurrentContainer->removeContainerListener(
this);
1971 if ( m_aTabActivationIdle.IsActive() )
1972 m_aTabActivationIdle.Stop();
1975 ::std::for_each( m_aFilterComponents.begin(), m_aFilterComponents.end(), RemoveComponentTextListener(
this ) );
1976 m_aFilterComponents.clear();
1979 for (
const Reference< XControl >& rControl : std::as_const(m_aControls) )
1980 implControlRemoved( rControl,
true );
1983 if (m_bDBConnection && isListeningForChanges())
1986 m_aControls.realloc( 0 );
1989 if (m_xTabController.is())
1990 m_xTabController->setContainer(xContainer);
1993 if (xContainer.is() && xTabModel.is())
1995 const Sequence< Reference< XControlModel > > aModels = xTabModel->getControlModels();
1996 Sequence< Reference< XControl > > aAllControls = xContainer->getControls();
1998 sal_Int32
nCount = aModels.getLength();
1999 m_aControls = Sequence< Reference< XControl > >( nCount );
2000 Reference< XControl > * pControls = m_aControls.getArray();
2004 for (
const Reference< XControlModel >& rModel : aModels )
2006 Reference< XControl > xControl = findControl( aAllControls, rModel,
false,
true );
2007 if ( xControl.is() )
2009 pControls[j++] = xControl;
2010 implControlInserted( xControl,
true );
2016 m_aControls.realloc(j);
2019 Reference< XContainer > xNewContainer(xContainer, UNO_QUERY);
2020 if (xNewContainer.is())
2021 xNewContainer->addContainerListener(
this);
2024 if (m_bDBConnection)
2026 m_bLocked = determineLockState();
2033 m_bControlsSorted =
true;
2037 Reference< XControlContainer > FormController::getContainer()
2039 ::osl::MutexGuard aGuard(
m_aMutex );
2040 impl_checkDisposed_throw();
2042 DBG_ASSERT(m_xTabController.is(),
"FormController::getContainer : invalid aggregate !");
2043 if (!m_xTabController.is())
2044 return Reference< XControlContainer > ();
2045 return m_xTabController->getContainer();
2049 Sequence< Reference< XControl > > FormController::getControls()
2051 ::osl::MutexGuard aGuard(
m_aMutex );
2052 impl_checkDisposed_throw();
2054 if (!m_bControlsSorted)
2056 Reference< XTabControllerModel >
xModel = getModel();
2060 const Sequence< Reference< XControlModel > > aControlModels = xModel->getControlModels();
2061 sal_Int32 nModels = aControlModels.getLength();
2063 Sequence< Reference< XControl > > aNewControls(nModels);
2065 Reference< XControl > * pControls = aNewControls.getArray();
2066 Reference< XControl > xControl;
2070 for (
const Reference< XControlModel >& rModel : aControlModels )
2072 xControl = findControl( m_aControls, rModel,
true,
true );
2073 if ( xControl.is() )
2074 pControls[j++] = xControl;
2079 aNewControls.realloc( j );
2081 m_aControls = aNewControls;
2082 m_bControlsSorted =
true;
2088 void FormController::autoTabOrder()
2090 ::osl::MutexGuard aGuard(
m_aMutex );
2091 impl_checkDisposed_throw();
2093 DBG_ASSERT(m_xTabController.is(),
"FormController::autoTabOrder : invalid aggregate !");
2094 if (m_xTabController.is())
2095 m_xTabController->autoTabOrder();
2099 void FormController::activateTabOrder()
2101 ::osl::MutexGuard aGuard(
m_aMutex );
2102 impl_checkDisposed_throw();
2104 DBG_ASSERT(m_xTabController.is(),
"FormController::activateTabOrder : invalid aggregate !");
2105 if (m_xTabController.is())
2106 m_xTabController->activateTabOrder();
2110 void FormController::setControlLock(
const Reference< XControl > & xControl)
2112 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2113 bool bLocked = isLocked();
2118 Reference< XBoundControl > xBound(xControl, UNO_QUERY);
2119 if (!(xBound.is() &&
2120 ( (bLocked && bLocked != bool(xBound->getLock())) ||
2145 xBound->setLock(bLocked);
2151 if (aVal.hasValue() && ::comphelper::getBOOL(aVal))
2152 xBound->setLock(
true);
2154 xBound->setLock(bLocked);
2165 void FormController::setLocks()
2167 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2169 for (
const Reference< XControl >& rControl : std::as_const(m_aControls) )
2170 setControlLock( rControl );
2176 bool lcl_shouldListenForModifications(
const Reference< XControl >& _rxControl,
const Reference< XPropertyChangeListener >& _rxBoundFieldListener )
2178 bool bShould =
false;
2180 Reference< XBoundComponent > xBound( _rxControl, UNO_QUERY );
2185 else if ( _rxControl.is() )
2188 if ( xModelProps.is() && ::comphelper::hasProperty(
FM_PROP_BOUNDFIELD, xModelProps ) )
2192 bShould = xField.is();
2194 if ( !bShould && _rxBoundFieldListener.is() )
2204 void FormController::startControlModifyListening(
const Reference< XControl > & xControl)
2206 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2208 bool bModifyListening = lcl_shouldListenForModifications( xControl,
this );
2211 while ( bModifyListening )
2213 Reference< XModifyBroadcaster > xMod(xControl, UNO_QUERY);
2216 xMod->addModifyListener(
this);
2221 Reference< XTextComponent > xText(xControl, UNO_QUERY);
2224 xText->addTextListener(
this);
2228 Reference< XCheckBox > xBox(xControl, UNO_QUERY);
2231 xBox->addItemListener(
this);
2235 Reference< XComboBox > xCbBox(xControl, UNO_QUERY);
2238 xCbBox->addItemListener(
this);
2242 Reference< XListBox > xListBox(xControl, UNO_QUERY);
2245 xListBox->addItemListener(
this);
2253 void FormController::stopControlModifyListening(
const Reference< XControl > & xControl)
2255 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2257 bool bModifyListening = lcl_shouldListenForModifications( xControl,
nullptr );
2260 while (bModifyListening)
2262 Reference< XModifyBroadcaster > xMod(xControl, UNO_QUERY);
2265 xMod->removeModifyListener(
this);
2269 Reference< XTextComponent > xText(xControl, UNO_QUERY);
2272 xText->removeTextListener(
this);
2276 Reference< XCheckBox > xBox(xControl, UNO_QUERY);
2279 xBox->removeItemListener(
this);
2283 Reference< XComboBox > xCbBox(xControl, UNO_QUERY);
2286 xCbBox->removeItemListener(
this);
2290 Reference< XListBox > xListBox(xControl, UNO_QUERY);
2293 xListBox->removeItemListener(
this);
2301 void FormController::startListening()
2303 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2304 m_bModified =
false;
2307 for (
const Reference< XControl >& rControl : std::as_const(m_aControls) )
2308 startControlModifyListening( rControl );
2312 void FormController::stopListening()
2314 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2315 m_bModified =
false;
2318 for (
const Reference< XControl >& rControl : std::as_const(m_aControls) )
2319 stopControlModifyListening( rControl );
2323 Reference< XControl > FormController::findControl(Sequence< Reference< XControl > >& _rControls,
const Reference< XControlModel > & xCtrlModel ,
bool _bRemove,
bool _bOverWrite)
const
2325 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2326 DBG_ASSERT( xCtrlModel.is(),
"findControl - which ?!" );
2328 Reference< XControl >* pControls = std::find_if(_rControls.begin(), _rControls.end(),
2329 [&xCtrlModel](
const Reference< XControl >& rControl) {
2330 return rControl.is() && rControl->getModel().get() == xCtrlModel.get(); });
2331 if (pControls != _rControls.end())
2333 Reference< XControl > xControl( *pControls );
2336 auto i =
static_cast<sal_Int32
>(std::distance(_rControls.begin(), pControls));
2337 ::comphelper::removeElementAt( _rControls,
i );
2339 else if ( _bOverWrite )
2343 return Reference< XControl > ();
2347 void FormController::implControlInserted(
const Reference< XControl>& _rxControl,
bool _bAddToEventAttacher )
2349 Reference< XWindow > xWindow( _rxControl, UNO_QUERY );
2352 xWindow->addFocusListener(
this );
2353 xWindow->addMouseListener(
this );
2355 if ( _bAddToEventAttacher )
2356 addToEventAttacher( _rxControl );
2360 Reference< XDispatchProviderInterception > xInterception( _rxControl, UNO_QUERY );
2361 if ( xInterception.is() )
2362 createInterceptor( xInterception );
2364 if ( !_rxControl.is() )
2367 Reference< XControlModel >
xModel( _rxControl->getModel() );
2371 Reference< XReset > xReset(
xModel, UNO_QUERY );
2373 xReset->addResetListener(
this );
2376 Reference< XValidatableFormComponent > xValidatable(
xModel, UNO_QUERY );
2377 if ( xValidatable.is() )
2379 xValidatable->addFormComponentValidityListener(
this );
2380 m_aControlBorderManager.validityChanged( _rxControl, xValidatable );
2386 void FormController::implControlRemoved(
const Reference< XControl>& _rxControl,
bool _bRemoveFromEventAttacher )
2388 Reference< XWindow > xWindow( _rxControl, UNO_QUERY );
2391 xWindow->removeFocusListener(
this );
2392 xWindow->removeMouseListener(
this );
2394 if ( _bRemoveFromEventAttacher )
2395 removeFromEventAttacher( _rxControl );
2398 Reference< XDispatchProviderInterception > xInterception( _rxControl, UNO_QUERY);
2399 if ( xInterception.is() )
2400 deleteInterceptor( xInterception );
2402 if ( _rxControl.is() )
2404 Reference< XControlModel >
xModel( _rxControl->getModel() );
2406 Reference< XReset > xReset(
xModel, UNO_QUERY );
2408 xReset->removeResetListener(
this );
2410 Reference< XValidatableFormComponent > xValidatable(
xModel, UNO_QUERY );
2411 if ( xValidatable.is() )
2412 xValidatable->removeFormComponentValidityListener(
this );
2417 void FormController::implSetCurrentControl(
const Reference< XControl >& _rxControl )
2419 if ( m_xCurrentControl.get() == _rxControl.get() )
2422 Reference< XGridControl > xGridControl( m_xCurrentControl, UNO_QUERY );
2423 if ( xGridControl.is() )
2424 xGridControl->removeGridControlListener(
this );
2426 m_xCurrentControl = _rxControl;
2428 xGridControl.set( m_xCurrentControl, UNO_QUERY );
2429 if ( xGridControl.is() )
2430 xGridControl->addGridControlListener(
this );
2434 void FormController::insertControl(
const Reference< XControl > & xControl)
2436 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2437 m_bControlsSorted =
false;
2438 m_aControls.realloc(m_aControls.getLength() + 1);
2439 m_aControls.getArray()[m_aControls.getLength() - 1] = xControl;
2441 if (m_pColumnInfoCache)
2442 m_pColumnInfoCache->deinitializeControls();
2444 implControlInserted( xControl, m_bAttachEvents );
2446 if (m_bDBConnection && !m_bFiltering)
2447 setControlLock(xControl);
2449 if (isListeningForChanges() && m_bAttachEvents)
2450 startControlModifyListening( xControl );
2454 void FormController::removeControl(
const Reference< XControl > & xControl)
2456 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2457 auto pControl = std::find_if(m_aControls.begin(), m_aControls.end(),
2458 [&xControl](
const Reference< XControl >& rControl) {
return xControl.get() == rControl.get(); });
2459 if (pControl != m_aControls.end())
2461 auto nIndex =
static_cast<sal_Int32
>(std::distance(m_aControls.begin(), pControl));
2462 ::comphelper::removeElementAt( m_aControls,
nIndex );
2465 FilterComponents::iterator componentPos = ::std::find( m_aFilterComponents.begin(), m_aFilterComponents.end(), xControl );
2466 if ( componentPos != m_aFilterComponents.end() )
2467 m_aFilterComponents.erase( componentPos );
2469 implControlRemoved( xControl, m_bDetachEvents );
2471 if ( isListeningForChanges() && m_bDetachEvents )
2472 stopControlModifyListening( xControl );
2477 void FormController::loaded(
const EventObject& rEvent)
2479 OSL_ENSURE( rEvent.Source == m_xModelAsIndex,
"FormController::loaded: where did this come from?" );
2481 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2482 ::osl::MutexGuard aGuard(
m_aMutex );
2483 Reference< XRowSet > xForm(rEvent.Source, UNO_QUERY);
2491 sal_Int32 aVal2 = 0;
2492 ::cppu::enum2int(aVal2,aVal);
2493 m_bCycle = !aVal.hasValue() ||
static_cast<form::TabulatorCycle
>(aVal2) == TabulatorCycle_RECORDS;
2496 m_bCurrentRecordModified = ::comphelper::getBOOL(xSet->getPropertyValue(
FM_PROP_ISMODIFIED));
2497 m_bCurrentRecordNew = ::comphelper::getBOOL(xSet->getPropertyValue(
FM_PROP_ISNEW));
2499 startFormListening( xSet,
false );
2502 if (getContainer().is())
2504 m_aLoadEvent.Call();
2509 m_bCanInsert = m_bCanUpdate = m_bCycle =
false;
2510 m_bCurrentRecordModified =
false;
2511 m_bCurrentRecordNew =
false;
2514 m_bDBConnection =
true;
2518 m_bDBConnection =
false;
2519 m_bCanInsert = m_bCanUpdate = m_bCycle =
false;
2520 m_bCurrentRecordModified =
false;
2521 m_bCurrentRecordNew =
false;
2525 Reference< XColumnsSupplier > xFormColumns( xForm, UNO_QUERY );
2526 m_pColumnInfoCache.reset( xFormColumns.is() ?
new ColumnInfoCache( xFormColumns ) : nullptr );
2528 updateAllDispatchers();
2532 void FormController::updateAllDispatchers()
const
2535 m_aFeatureDispatchers.begin(),
2536 m_aFeatureDispatchers.end(),
2537 [] (
const DispatcherContainer::value_type& dispatcher) {
2538 UpdateAllListeners()(dispatcher.second);
2545 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2546 m_bLocked = determineLockState();
2554 if (m_bCurrentRecordNew)
2555 toggleAutoFields(
true);
2559 void FormController::unloaded(
const EventObject& )
2561 ::osl::MutexGuard aGuard(
m_aMutex );
2562 impl_checkDisposed_throw();
2564 updateAllDispatchers();
2568 void FormController::reloading(
const EventObject& )
2570 ::osl::MutexGuard aGuard(
m_aMutex );
2571 impl_checkDisposed_throw();
2575 m_aToggleEvent.CancelPendingCall();
2580 void FormController::reloaded(
const EventObject& aEvent)
2582 ::osl::MutexGuard aGuard(
m_aMutex );
2583 impl_checkDisposed_throw();
2589 void FormController::unloading(
const EventObject& )
2591 ::osl::MutexGuard aGuard(
m_aMutex );
2592 impl_checkDisposed_throw();
2598 void FormController::unload()
2600 ::osl::MutexGuard aGuard(
m_aMutex );
2601 impl_checkDisposed_throw();
2603 m_aLoadEvent.CancelPendingCall();
2606 if (m_bCurrentRecordNew)
2607 toggleAutoFields(
false);
2610 removeBoundFieldListener();
2612 if (m_bDBConnection && isListeningForChanges())
2616 if ( m_bDBConnection && xSet.is() )
2617 stopFormListening( xSet,
false );
2619 m_bDBConnection =
false;
2620 m_bCanInsert = m_bCanUpdate = m_bCycle =
false;
2621 m_bCurrentRecordModified = m_bCurrentRecordNew = m_bLocked =
false;
2623 m_pColumnInfoCache.reset();
2627 void FormController::removeBoundFieldListener()
2629 for (
const Reference< XControl >& rControl : std::as_const(m_aControls) )
2642 if ( m_bCanInsert || m_bCanUpdate )
2647 if ( !_bPropertiesOnly )
2650 Reference< XRowSetApproveBroadcaster > xApprove( _rxForm, UNO_QUERY );
2651 if ( xApprove.is() )
2652 xApprove->addRowSetApproveListener(
this );
2655 Reference< XRowSet > xRowSet( _rxForm, UNO_QUERY );
2657 xRowSet->addRowSetListener(
this );
2661 Reference< XPropertySetInfo > xInfo = _rxForm->getPropertySetInfo();
2676 if ( m_bCanInsert || m_bCanUpdate )
2678 _rxForm->removePropertyChangeListener(
FM_PROP_ISNEW,
this );
2681 if ( !_bPropertiesOnly )
2683 Reference< XRowSetApproveBroadcaster > xApprove( _rxForm, UNO_QUERY );
2685 xApprove->removeRowSetApproveListener(
this);
2687 Reference< XRowSet > xRowSet( _rxForm, UNO_QUERY );
2689 xRowSet->removeRowSetListener(
this );
2693 Reference< XPropertySetInfo > xInfo = _rxForm->getPropertySetInfo();
2705 void FormController::cursorMoved(
const EventObject& )
2707 ::osl::MutexGuard aGuard(
m_aMutex );
2708 impl_checkDisposed_throw();
2711 if (m_bLocked != determineLockState())
2713 m_bLocked = !m_bLocked;
2715 if (isListeningForChanges())
2722 m_bCurrentRecordModified = m_bModified =
false;
2726 void FormController::rowChanged(
const EventObject& )
2731 void FormController::rowSetChanged(
const EventObject& )
2739 void SAL_CALL FormController::elementInserted(
const ContainerEvent& evt)
2741 ::osl::MutexGuard aGuard(
m_aMutex );
2742 impl_checkDisposed_throw();
2744 Reference< XControl > xControl( evt.Element, UNO_QUERY );
2745 if ( !xControl.is() )
2748 Reference< XFormComponent >
xModel(xControl->getModel(), UNO_QUERY);
2749 if (
xModel.is() && m_xModelAsIndex ==
xModel->getParent())
2751 insertControl(xControl);
2753 if ( m_aTabActivationIdle.IsActive() )
2754 m_aTabActivationIdle.Stop();
2756 m_aTabActivationIdle.Start();
2759 else if (m_bFiltering && Reference< XModeSelector > (evt.Source, UNO_QUERY).is())
2761 xModel.set(evt.Source, UNO_QUERY);
2762 if (
xModel.is() && m_xModelAsIndex ==
xModel->getParent())
2771 Reference< XTextComponent > xText(xControl, UNO_QUERY);
2773 if (xText.is() && xField.is() && ::comphelper::hasProperty(
FM_PROP_SEARCHABLE, xField) &&
2776 m_aFilterComponents.push_back( xText );
2777 xText->addTextListener(
this );
2785 void SAL_CALL FormController::elementReplaced(
const ContainerEvent& evt)
2788 ContainerEvent aRemoveEvent( evt );
2789 aRemoveEvent.Element = evt.ReplacedElement;
2790 aRemoveEvent.ReplacedElement =
Any();
2794 ContainerEvent aInsertEvent( evt );
2795 aInsertEvent.ReplacedElement =
Any();
2800 void SAL_CALL FormController::elementRemoved(
const ContainerEvent& evt)
2802 ::osl::MutexGuard aGuard(
m_aMutex );
2803 impl_checkDisposed_throw();
2805 Reference< XControl > xControl;
2806 evt.Element >>= xControl;
2810 Reference< XFormComponent >
xModel(xControl->getModel(), UNO_QUERY);
2811 if (
xModel.is() && m_xModelAsIndex ==
xModel->getParent())
2813 removeControl(xControl);
2817 else if (m_bFiltering && Reference< XModeSelector > (evt.Source, UNO_QUERY).is())
2819 FilterComponents::iterator componentPos = ::std::find(
2820 m_aFilterComponents.begin(), m_aFilterComponents.end(), xControl );
2821 if ( componentPos != m_aFilterComponents.end() )
2822 m_aFilterComponents.erase( componentPos );
2827 Reference< XControl > FormController::isInList(
const Reference< XWindowPeer > & xPeer)
const
2829 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2830 const Reference< XControl >* pControls = m_aControls.getConstArray();
2832 sal_uInt32 nCtrls = m_aControls.getLength();
2833 for ( sal_uInt32
n = 0;
n < nCtrls && xPeer.is(); ++
n, ++pControls )
2835 if ( pControls->is() )
2837 Reference< XVclWindowPeer > xCtrlPeer( (*pControls)->getPeer(), UNO_QUERY);
2838 if ( ( xCtrlPeer.get() == xPeer.get() ) || xCtrlPeer->isChild( xPeer ) )
2842 return Reference< XControl > ();
2846 void FormController::activateFirst()
2848 ::osl::MutexGuard aGuard(
m_aMutex );
2849 impl_checkDisposed_throw();
2851 DBG_ASSERT(m_xTabController.is(),
"FormController::activateFirst : invalid aggregate !");
2852 if (m_xTabController.is())
2853 m_xTabController->activateFirst();
2857 void FormController::activateLast()
2859 ::osl::MutexGuard aGuard(
m_aMutex );
2860 impl_checkDisposed_throw();
2862 DBG_ASSERT(m_xTabController.is(),
"FormController::activateLast : invalid aggregate !");
2863 if (m_xTabController.is())
2864 m_xTabController->activateLast();
2869 Reference< XFormOperations > SAL_CALL FormController::getFormOperations()
2871 ::osl::MutexGuard aGuard(
m_aMutex );
2872 impl_checkDisposed_throw();
2874 return m_xFormOperations;
2878 Reference< XControl> SAL_CALL FormController::getCurrentControl()
2880 ::osl::MutexGuard aGuard(
m_aMutex );
2881 impl_checkDisposed_throw();
2882 return m_xCurrentControl;
2886 void SAL_CALL FormController::addActivateListener(
const Reference< XFormControllerListener > & l)
2888 ::osl::MutexGuard aGuard(
m_aMutex );
2889 impl_checkDisposed_throw();
2890 m_aActivateListeners.addInterface(l);
2893 void SAL_CALL FormController::removeActivateListener(
const Reference< XFormControllerListener > & l)
2895 ::osl::MutexGuard aGuard(
m_aMutex );
2896 impl_checkDisposed_throw();
2897 m_aActivateListeners.removeInterface(l);
2901 void SAL_CALL FormController::addChildController(
const Reference< XFormController >& ChildController )
2903 ::osl::MutexGuard aGuard(
m_aMutex );
2904 impl_checkDisposed_throw();
2906 if ( !ChildController.is() )
2907 throw IllegalArgumentException( OUString(), *
this, 1 );
2911 Reference< XFormComponent > xFormOfChild( ChildController->getModel(), UNO_QUERY );
2912 if ( !xFormOfChild.is() )
2913 throw IllegalArgumentException( OUString(), *
this, 1 );
2916 if ( xFormOfChild->getParent() != m_xModelAsIndex )
2917 throw IllegalArgumentException( OUString(), *
this, 1 );
2920 m_aChildren.push_back( ChildController );
2921 ChildController->setParent( *
this );
2924 sal_uInt32
nPos = m_xModelAsIndex->getCount();
2925 Reference< XFormComponent > xTemp;
2928 m_xModelAsIndex->getByIndex(--nPos) >>= xTemp;
2929 if ( xFormOfChild == xTemp )
2931 m_xModelAsManager->attach( nPos, Reference<XInterface>( ChildController, UNO_QUERY ),
makeAny( ChildController) );
2938 Reference< XFormControllerContext > SAL_CALL FormController::getContext()
2940 ::osl::MutexGuard aGuard(
m_aMutex );
2941 impl_checkDisposed_throw();
2942 return m_xFormControllerContext;
2946 void SAL_CALL FormController::setContext(
const Reference< XFormControllerContext >& _context )
2948 ::osl::MutexGuard aGuard(
m_aMutex );
2949 impl_checkDisposed_throw();
2950 m_xFormControllerContext = _context;
2956 ::osl::MutexGuard aGuard(
m_aMutex );
2957 impl_checkDisposed_throw();
2964 ::osl::MutexGuard aGuard(
m_aMutex );
2965 impl_checkDisposed_throw();
2970 void FormController::setFilter(::std::vector<FmFieldInfo>& rFieldInfos)
2972 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2974 Reference< XRowSet > xForm(m_xModelAsIndex, UNO_QUERY);
2980 Reference< XMultiServiceFactory >
xFactory( xConnection, UNO_QUERY_THROW );
2982 xFactory->createInstance(
"com.sun.star.sdb.SingleSelectQueryComposer"),
2987 OUString sFilter = ::comphelper::getString( xSet->getPropertyValue(
FM_PROP_FILTER ) );
2988 m_xComposer->setElementaryQuery( sStatement );
2989 m_xComposer->setFilter( sFilter );
2997 if (m_xComposer.is())
2999 const Sequence< Sequence < PropertyValue > > aFilterRows = m_xComposer->getStructuredFilter();
3007 Reference< XColumnsSupplier >( m_xComposer, UNO_QUERY_THROW )->getColumns();
3009 for (
auto& rFieldInfo : rFieldInfos)
3011 if ( xQueryColumns->hasByName(rFieldInfo.aFieldName) )
3013 if ( (xQueryColumns->getByName(rFieldInfo.aFieldName) >>= rFieldInfo.xField) && rFieldInfo.xField.is() )
3014 rFieldInfo.xField->getPropertyValue(
FM_PROP_REALNAME) >>= rFieldInfo.aFieldName;
3018 Reference< XDatabaseMetaData> xMetaData(xConnection->getMetaData());
3023 Reference< XNumberFormatsSupplier> xFormatSupplier(
getNumberFormats(xConnection,
true));
3025 xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
3031 for (
const Sequence < PropertyValue >& rRow : aFilterRows)
3036 for (
const PropertyValue& rRefValue : rRow)
3046 if (xQueryColumns->hasByName(rRefValue.Name))
3048 xQueryColumns->getByName(rRefValue.Name) >>= xSet;
3051 xSet->getPropertyValue(
"RealName") >>= aRealName;
3054 if (aCompare(aRealName, rRefValue.Name))
3060 Reference< XIndexAccess > xColumnsByIndex(xQueryColumns, UNO_QUERY);
3061 for (sal_Int32
n = 0,
nCount = xColumnsByIndex->getCount();
n <
nCount;
n++)
3063 xColumnsByIndex->getByIndex(
n) >>= xSet;
3064 xSet->getPropertyValue(
"RealName") >>= aRealName;
3065 if (aCompare(aRealName, rRefValue.Name))
3082 for (
const auto& rFieldInfo : rFieldInfos)
3085 if (rFieldInfo.xField == xField)
3088 if (aRow.find(rFieldInfo.xText) != aRow.end())
3090 OString aVal = m_pParser->getContext().getIntlKeywordAscii(IParseContext::InternationalKeyCode::And);
3091 OUString aCompText = aRow[rFieldInfo.xText] +
" " +
3092 OUString(aVal.getStr(),aVal.getLength(),RTL_TEXTENCODING_ASCII_US) +
" " +
3094 aRow[rFieldInfo.xText] = aCompText;
3098 OUString sPredicate,sErrorMsg;
3099 rRefValue.Value >>= sPredicate;
3100 std::unique_ptr< OSQLParseNode > pParseNode = predicateTree(sErrorMsg, sPredicate, xFormatter, xField);
3101 if ( pParseNode !=
nullptr )
3104 switch (rRefValue.Handle)
3106 case css::sdb::SQLFilterOperator::EQUAL:
3109 case css::sdb::SQLFilterOperator::NOT_EQUAL:
3112 case css::sdb::SQLFilterOperator::LESS:
3115 case css::sdb::SQLFilterOperator::GREATER:
3118 case css::sdb::SQLFilterOperator::LESS_EQUAL:
3121 case css::sdb::SQLFilterOperator::GREATER_EQUAL:
3124 case css::sdb::SQLFilterOperator::LIKE:
3125 sCriteria +=
"LIKE ";
3127 case css::sdb::SQLFilterOperator::NOT_LIKE:
3128 sCriteria +=
"NOT LIKE ";
3130 case css::sdb::SQLFilterOperator::SQLNULL:
3131 sCriteria +=
"IS NULL";
3133 case css::sdb::SQLFilterOperator::NOT_SQLNULL:
3134 sCriteria +=
"IS NOT NULL";
3137 pParseNode->parseNodeToPredicateStr( sCriteria
3143 ,strDecimalSeparator
3144 ,getParseContext());
3145 aRow[rFieldInfo.xText] = sCriteria;
3155 impl_addFilterRow( aRow );
3160 for (
const auto& rFieldInfo : rFieldInfos)
3162 m_aFilterComponents.push_back( rFieldInfo.xText );
3167 void FormController::startFiltering()
3169 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
3172 if ( !xConnection.is() )
3177 if (isListeningForChanges())
3180 m_bFiltering =
true;
3184 m_bAttachEvents =
false;
3187 Sequence< Reference< XControl > > aControlsCopy( m_aControls );
3188 const Reference< XControl >* pControls = aControlsCopy.getConstArray();
3189 sal_Int32 nControlCount = aControlsCopy.getLength();
3192 Reference< XNumberFormatsSupplier > xFormatSupplier =
getNumberFormats(xConnection,
true);
3194 xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
3197 ::std::vector<FmFieldInfo> aFieldInfos;
3199 for (sal_Int32
i = nControlCount;
i > 0;)
3201 Reference< XControl > xControl = pControls[--
i];
3205 removeFromEventAttacher(xControl);
3208 Reference< XModeSelector > xSelector(xControl, UNO_QUERY);
3211 xSelector->setMode(
"FilterMode" );
3214 Reference< XContainer > xContainer(xSelector, UNO_QUERY);
3215 if (xContainer.is())
3216 xContainer->addContainerListener(
this);
3218 Reference< XEnumerationAccess > xElementAccess(xSelector, UNO_QUERY);
3219 if (xElementAccess.is())
3221 Reference< XEnumeration > xEnumeration(xElementAccess->createEnumeration());
3222 Reference< XControl > xSubControl;
3223 while (xEnumeration->hasMoreElements())
3225 xEnumeration->nextElement() >>= xSubControl;
3226 if (xSubControl.is())
3235 Reference< XTextComponent > xText(xSubControl, UNO_QUERY);
3237 if (xText.is() && xField.is() && ::comphelper::hasProperty(
FM_PROP_SEARCHABLE, xField) &&
3240 aFieldInfos.emplace_back(xField, xText);
3241 xText->addTextListener(
this);
3266 Reference< XControl > xFilterControl = form::control::FilterControl::createWithFormat(
3272 if ( replaceControl( xControl, xFilterControl ) )
3274 Reference< XTextComponent > xFilterText( xFilterControl, UNO_QUERY );
3275 aFieldInfos.emplace_back( xField, xFilterText );
3276 xFilterText->addTextListener(
this);
3289 setFilter(aFieldInfos);
3293 stopFormListening( xSet,
true );
3295 impl_setTextOnAllFilter_throw();
3298 m_bLocked = determineLockState();
3300 m_bAttachEvents =
true;
3304 void FormController::stopFiltering()
3306 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
3307 if ( !m_bFiltering )
3312 m_bFiltering =
false;
3313 m_bDetachEvents =
false;
3315 ::comphelper::disposeComponent(m_xComposer);
3318 Sequence< Reference< XControl > > aControlsCopy( m_aControls );
3319 const Reference< XControl > * pControls = aControlsCopy.getConstArray();
3320 sal_Int32 nControlCount = aControlsCopy.getLength();
3323 ::std::for_each( m_aFilterComponents.begin(), m_aFilterComponents.end(), RemoveComponentTextListener(
this ) );
3324 m_aFilterComponents.clear();
3326 for ( sal_Int32
i = nControlCount;
i > 0; )
3328 Reference< XControl > xControl = pControls[--
i];
3332 addToEventAttacher(xControl);
3334 Reference< XModeSelector > xSelector(xControl, UNO_QUERY);
3337 xSelector->setMode(
"DataMode" );
3340 Reference< XContainer > xContainer(xSelector, UNO_QUERY);
3341 if (xContainer.is())
3342 xContainer->removeContainerListener(
this);
3362 replaceControl( xControl, xNewControl );
3370 startFormListening( xSet,
true );
3372 m_bDetachEvents =
true;
3374 m_aFilterRows.clear();
3375 m_nCurrentFilterPosition = -1;
3379 m_bLocked = determineLockState();
3383 if (isListeningForChanges())
3389 void FormController::setMode(
const OUString&
Mode)
3391 ::osl::MutexGuard aGuard(
m_aMutex );
3392 impl_checkDisposed_throw();
3394 if (!supportsMode(Mode))
3395 throw NoSupportException();
3397 if (Mode == m_aMode)
3402 if ( Mode ==
"FilterMode" )
3407 for (
const auto& rChild : m_aChildren)
3409 Reference< XModeSelector > xMode(rChild, UNO_QUERY);
3411 xMode->setMode(Mode);
3416 OUString SAL_CALL FormController::getMode()
3418 ::osl::MutexGuard aGuard(
m_aMutex );
3419 impl_checkDisposed_throw();
3427 ::osl::MutexGuard aGuard(
m_aMutex );
3428 impl_checkDisposed_throw();
3441 ::osl::MutexGuard aGuard(
m_aMutex );
3442 impl_checkDisposed_throw();
3451 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
3455 Reference< XControl > xContainerControl( getContainer(), UNO_QUERY_THROW );
3456 Reference< XWindowPeer > xContainerPeer( xContainerControl->getPeer(), UNO_SET_THROW );
3463 return pParentWindow;
3466 bool FormController::checkFormComponentValidity( OUString& _rFirstInvalidityExplanation, Reference< XControlModel >& _rxFirstInvalidModel )
3470 Reference< XEnumerationAccess > xControlEnumAcc( getModel(), UNO_QUERY );
3471 Reference< XEnumeration > xControlEnumeration;
3472 if ( xControlEnumAcc.is() )
3473 xControlEnumeration = xControlEnumAcc->createEnumeration();
3474 OSL_ENSURE( xControlEnumeration.is(),
"FormController::checkFormComponentValidity: cannot enumerate the controls!" );
3475 if ( !xControlEnumeration.is() )
3479 Reference< XValidatableFormComponent > xValidatable;
3480 while ( xControlEnumeration->hasMoreElements() )
3482 if ( !( xControlEnumeration->nextElement() >>= xValidatable ) )
3486 if ( xValidatable->isValid() )
3489 Reference< XValidator > xValidator( xValidatable->getValidator() );
3490 OSL_ENSURE( xValidator.is(),
"FormController::checkFormComponentValidity: invalid, but no validator?" );
3491 if ( !xValidator.is() )
3495 _rFirstInvalidityExplanation = xValidator->explainInvalid( xValidatable->getCurrentValue() );
3496 _rxFirstInvalidModel.set(xValidatable, css::uno::UNO_QUERY);
3508 Reference< XControl > FormController::locateControl(
const Reference< XControlModel >& _rxModel )
3512 const Sequence< Reference< XControl > > aControls( getControls() );
3514 for (
auto const &
control : aControls )
3516 OSL_ENSURE(
control.is(),
"FormController::locateControl: NULL-control?" );
3519 if (
control->getModel() == _rxModel )
3523 OSL_FAIL(
"FormController::locateControl: did not find a control for this model!" );
3535 void displayErrorSetFocus(
const OUString& _rMessage,
const Reference< XControl >& _rxFocusControl,
vcl::Window* _pDialogParent )
3538 aError.Message =
SvxResId(RID_STR_WRITEERROR);
3539 aError.Details = _rMessage;
3542 if ( _rxFocusControl.is() )
3544 Reference< XWindow > xControlWindow( _rxFocusControl, UNO_QUERY );
3545 OSL_ENSURE( xControlWindow.is(),
"displayErrorSetFocus: invalid control!" );
3546 if ( xControlWindow.is() )
3547 xControlWindow->setFocus();
3551 bool lcl_shouldValidateRequiredFields_nothrow(
const Reference< XInterface >& _rxForm )
3555 static constexpr OUStringLiteral s_sFormsCheckRequiredFields =
u"FormsCheckRequiredFields";
3561 Reference< XPropertySetInfo > xPSI( xFormProps->getPropertySetInfo() );
3562 if ( xPSI->hasPropertyByName( s_sFormsCheckRequiredFields ) )
3564 bool bShouldValidate =
true;
3565 OSL_VERIFY( xFormProps->getPropertyValue( s_sFormsCheckRequiredFields ) >>= bShouldValidate );
3566 return bShouldValidate;
3572 if ( !xDataSource.is() )
3577 xDataSource->getPropertyValue(
"Settings"),
3580 bool bShouldValidate =
true;
3581 OSL_VERIFY( xDataSourceSettings->getPropertyValue( s_sFormsCheckRequiredFields ) >>= bShouldValidate );
3582 return bShouldValidate;
3584 catch(
const Exception& )
3595 sal_Bool SAL_CALL FormController::approveRowChange(
const RowChangeEvent& _rEvent)
3597 ::osl::ClearableMutexGuard aGuard(
m_aMutex );
3598 impl_checkDisposed_throw();
3604 RowChangeEvent aEvt( _rEvent );
3605 aEvt.Source = *
this;
3606 bValid =
static_cast<XRowSetApproveListener*
>(aIter.
next())->approveRowChange(aEvt);
3612 if ( ( _rEvent.Action != RowChangeAction::INSERT )
3613 && ( _rEvent.Action != RowChangeAction::UPDATE )
3618 OUString sInvalidityExplanation;
3619 Reference< XControlModel > xInvalidModel;
3620 if ( !checkFormComponentValidity( sInvalidityExplanation, xInvalidModel ) )
3622 Reference< XControl > xControl( locateControl( xInvalidModel ) );
3624 displayErrorSetFocus( sInvalidityExplanation, xControl, getDialogParentWindow() );
3629 if ( !lcl_shouldValidateRequiredFields_nothrow( _rEvent.Source ) )
3632 OSL_ENSURE(m_pColumnInfoCache,
"FormController::approveRowChange: no column infos!");
3633 if (!m_pColumnInfoCache)
3638 if ( !m_pColumnInfoCache->controlsInitialized() )
3639 m_pColumnInfoCache->initializeControls( getControls() );
3641 size_t colCount = m_pColumnInfoCache->getColumnCount();
3642 for (
size_t col = 0; col < colCount; ++col )
3644 const ColumnInfo& rColInfo = m_pColumnInfoCache->getColumnInfo( col );
3646 if ( rColInfo.bAutoIncrement )
3649 if ( rColInfo.bReadOnly )
3652 if ( !rColInfo.xFirstControlWithInputRequired.is() && !rColInfo.xFirstGridWithInputRequiredColumn.is() )
3658 if ( !rColInfo.xColumn->wasNull() || !rColInfo.xColumn->getString().isEmpty() )
3662 sMessage = sMessage.replaceFirst(
"#", rColInfo.sName );
3665 Reference< XControl > xControl( rColInfo.xFirstControlWithInputRequired );
3666 if ( !xControl.is() )
3667 xControl.set( rColInfo.xFirstGridWithInputRequiredColumn, UNO_QUERY );
3670 displayErrorSetFocus( sMessage, rColInfo.xFirstControlWithInputRequired, getDialogParentWindow() );
3683 sal_Bool SAL_CALL FormController::approveCursorMove(
const EventObject& event)
3685 ::osl::MutexGuard aGuard(
m_aMutex );
3686 impl_checkDisposed_throw();
3691 EventObject aEvt(event);
3692 aEvt.Source = *
this;
3693 return static_cast<XRowSetApproveListener*
>(aIter.
next())->approveCursorMove(aEvt);
3700 sal_Bool SAL_CALL FormController::approveRowSetChange(
const EventObject& event)
3702 ::osl::MutexGuard aGuard(
m_aMutex );
3703 impl_checkDisposed_throw();
3708 EventObject aEvt(event);
3709 aEvt.Source = *
this;
3710 return static_cast<XRowSetApproveListener*
>(aIter.
next())->approveRowSetChange(aEvt);
3718 void SAL_CALL FormController::addRowSetApproveListener(
const Reference< XRowSetApproveListener > & _rxListener)
3720 ::osl::MutexGuard aGuard(
m_aMutex );
3721 impl_checkDisposed_throw();
3723 m_aRowSetApproveListeners.addInterface(_rxListener);
3727 void SAL_CALL FormController::removeRowSetApproveListener(
const Reference< XRowSetApproveListener > & _rxListener)
3729 ::osl::MutexGuard aGuard(
m_aMutex );
3730 impl_checkDisposed_throw();
3732 m_aRowSetApproveListeners.removeInterface(_rxListener);
3737 void SAL_CALL FormController::errorOccured(
const SQLErrorEvent& aEvent)
3739 ::osl::ClearableMutexGuard aGuard(
m_aMutex );
3740 impl_checkDisposed_throw();
3745 SQLErrorEvent aEvt(aEvent);
3746 aEvt.Source = *
this;
3747 static_cast<XSQLErrorListener*
>(aIter.
next())->errorOccured(aEvt);
3758 void SAL_CALL FormController::addSQLErrorListener(
const Reference< XSQLErrorListener > & aListener)
3760 ::osl::MutexGuard aGuard(
m_aMutex );
3761 impl_checkDisposed_throw();
3763 m_aErrorListeners.addInterface(aListener);
3767 void SAL_CALL FormController::removeSQLErrorListener(
const Reference< XSQLErrorListener > & aListener)
3769 ::osl::MutexGuard aGuard(
m_aMutex );
3770 impl_checkDisposed_throw();
3772 m_aErrorListeners.removeInterface(aListener);
3777 void SAL_CALL FormController::addDatabaseParameterListener(
const Reference< XDatabaseParameterListener > & aListener)
3779 ::osl::MutexGuard aGuard(
m_aMutex );
3780 impl_checkDisposed_throw();
3782 m_aParameterListeners.addInterface(aListener);
3786 void SAL_CALL FormController::removeDatabaseParameterListener(
const Reference< XDatabaseParameterListener > & aListener)
3788 ::osl::MutexGuard aGuard(
m_aMutex );
3789 impl_checkDisposed_throw();
3791 m_aParameterListeners.removeInterface(aListener);
3796 void SAL_CALL FormController::addParameterListener(
const Reference< XDatabaseParameterListener > & aListener)
3798 FormController::addDatabaseParameterListener( aListener );
3802 void SAL_CALL FormController::removeParameterListener(
const Reference< XDatabaseParameterListener > & aListener)
3804 FormController::removeDatabaseParameterListener( aListener );
3809 sal_Bool SAL_CALL FormController::approveParameter(
const DatabaseParameterEvent& aEvent)
3812 ::osl::MutexGuard aGuard(
m_aMutex );
3813 impl_checkDisposed_throw();
3818 DatabaseParameterEvent aEvt(aEvent);
3819 aEvt.Source = *
this;
3820 return static_cast<XDatabaseParameterListener*
>(aIter.
next())->approveParameter(aEvt);
3827 if ( !ensureInteractionHandler() )
3834 ParametersRequest aRequest;
3835 aRequest.Parameters = aEvent.Parameters;
3836 aRequest.Connection =
getConnection(Reference< XRowSet >(aEvent.Source, UNO_QUERY));
3839 pParamRequest->addContinuation(pParamValues);
3840 pParamRequest->addContinuation(pAbort);
3845 if (!pParamValues->wasSelected())
3850 Sequence< PropertyValue > aFinalValues = pParamValues->getValues();
3851 if (aFinalValues.getLength() != aRequest.Parameters->getCount())
3853 OSL_FAIL(
"FormController::approveParameter: the InteractionHandler returned nonsense!");
3856 const PropertyValue* pFinalValues = aFinalValues.getConstArray();
3857 for (sal_Int32
i=0;
i<aFinalValues.getLength(); ++
i, ++pFinalValues)
3860 aRequest.Parameters->getByIndex(
i), css::uno::UNO_QUERY);
3866 DBG_ASSERT(sName == pFinalValues->Name,
"FormController::approveParameter: suspicious value names!");
3868 try { xParam->setPropertyValue(
FM_PROP_VALUE, pFinalValues->Value); }
3871 OSL_FAIL(
"FormController::approveParameter: setting one of the properties failed!");
3886 void SAL_CALL FormController::addConfirmDeleteListener(
const Reference< XConfirmDeleteListener > & aListener)
3888 ::osl::MutexGuard aGuard(
m_aMutex );
3889 impl_checkDisposed_throw();
3891 m_aDeleteListeners.addInterface(aListener);
3895 void SAL_CALL FormController::removeConfirmDeleteListener(
const Reference< XConfirmDeleteListener > & aListener)
3897 ::osl::MutexGuard aGuard(
m_aMutex );
3898 impl_checkDisposed_throw();
3900 m_aDeleteListeners.removeInterface(aListener);
3905 sal_Bool SAL_CALL FormController::confirmDelete(
const RowChangeEvent& aEvent)
3907 ::osl::MutexGuard aGuard(
m_aMutex );
3908 impl_checkDisposed_throw();
3913 RowChangeEvent aEvt(aEvent);
3914 aEvt.Source = *
this;
3915 return static_cast<XConfirmDeleteListener*
>(aIter.
next())->confirmDelete(aEvt);
3920 sal_Int32
nLength = aEvent.Rows;
3923 sTitle =
SvxResId( RID_STR_DELETECONFIRM_RECORDS );
3924 sTitle = sTitle.replaceFirst(
"#", OUString::number(nLength) );
3927 sTitle =
SvxResId( RID_STR_DELETECONFIRM_RECORD );
3931 if ( !ensureInteractionHandler() )
3939 SQLWarning aWarning;
3940 aWarning.Message = sTitle;
3941 SQLWarning aDetails;
3942 aDetails.Message =
SvxResId(RID_STR_DELETECONFIRM);
3943 aWarning.NextException <<= aDetails;
3948 pRequest->addContinuation( pApprove );
3949 pRequest->addContinuation( pDisapprove );
3954 if ( pApprove->wasSelected() )
3966 void SAL_CALL FormController::invalidateFeatures(
const Sequence< ::sal_Int16 >& Features )
3968 ::osl::MutexGuard aGuard(
m_aMutex );
3970 m_aInvalidFeatures.insert( Features.begin(), Features.end() );
3973 if ( !m_aFeatureInvalidationTimer.IsActive() )
3974 m_aFeatureInvalidationTimer.Start();
3978 void SAL_CALL FormController::invalidateAllFeatures( )
3980 ::osl::ClearableMutexGuard aGuard(
m_aMutex );
3985 if ( aInterceptedFeatures.hasElements() )
3986 invalidateFeatures( aInterceptedFeatures );
3990 Reference< XDispatch >
3991 FormController::interceptedQueryDispatch(
const URL& aURL,
3992 const OUString& , sal_Int32 )
3994 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
3995 Reference< XDispatch > xReturn;
3998 || ( ( aURL.Complete ==
"private:/InteractionHandler" )
3999 && ensureInteractionHandler()
4002 xReturn =
static_cast< XDispatch*
>( this );
4005 if ( !xReturn.is() && m_xFormOperations.is() )
4010 if ( nFormFeature > 0 )
4013 DispatcherContainer::const_iterator aDispatcherPos = m_aFeatureDispatchers.find( nFormFeature );
4014 if ( aDispatcherPos == m_aFeatureDispatchers.end() )
4016 aDispatcherPos = m_aFeatureDispatchers.emplace(
4021 OSL_ENSURE( aDispatcherPos->second.is(),
"FormController::interceptedQueryDispatch: should have a dispatcher by now!" );
4022 return aDispatcherPos->second;
4031 void SAL_CALL FormController::dispatch(
const URL& _rURL,
const Sequence< PropertyValue >& _rArgs )
4033 if ( _rArgs.getLength() != 1 )
4035 OSL_FAIL(
"FormController::dispatch: no arguments -> no dispatch!" );
4039 if ( _rURL.Complete ==
"private:/InteractionHandler" )
4041 Reference< XInteractionRequest > xRequest;
4042 OSL_VERIFY( _rArgs[0].
Value >>= xRequest );
4043 if ( xRequest.is() )
4050 OSL_FAIL(
"FormController::dispatch: How do you expect me to return something via this call?" );
4055 OSL_FAIL(
"FormController::dispatch: unknown URL!" );
4059 void SAL_CALL FormController::addStatusListener(
const Reference< XStatusListener >& _rxListener,
const URL& _rURL )
4063 if (_rxListener.is())
4065 FeatureStateEvent
aEvent;
4066 aEvent.FeatureURL = _rURL;
4067 aEvent.IsEnabled =
true;
4068 _rxListener->statusChanged(aEvent);
4073 OSL_FAIL(
"FormController::addStatusListener: invalid (unsupported) URL!");
4077 Reference< XInterface > SAL_CALL FormController::getParent()
4083 void SAL_CALL FormController::setParent(
const Reference< XInterface >& Parent)
4089 void SAL_CALL FormController::removeStatusListener(
const Reference< XStatusListener >& ,
const URL& _rURL )
4091 OSL_ENSURE(_rURL.Complete ==
FMURL_CONFIRM_DELETION,
"FormController::removeStatusListener: invalid (unsupported) URL!");
4096 Reference< XDispatchProviderInterceptor > FormController::createInterceptor(
const Reference< XDispatchProviderInterception > & _xInterception)
4098 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
4101 for (
const auto & it : m_aControlDispatchInterceptors )
4103 if (it->getIntercepted() == _xInterception)
4104 OSL_FAIL(
"FormController::createInterceptor : we already do intercept this objects dispatches !");
4109 m_aControlDispatchInterceptors.push_back( pInterceptor );
4111 return pInterceptor;
4115 bool FormController::ensureInteractionHandler()
4119 if ( m_bAttemptedHandlerCreation )
4121 m_bAttemptedHandlerCreation =
true;
4129 void SAL_CALL FormController::handle(
const Reference< XInteractionRequest >& _rRequest )
4131 if ( !ensureInteractionHandler() )
4137 void FormController::deleteInterceptor(
const Reference< XDispatchProviderInterception > & _xInterception)
4139 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
4141 auto aIter = std::find_if(m_aControlDispatchInterceptors.begin(), m_aControlDispatchInterceptors.end(),
4143 return rpInterceptor->getIntercepted() == _xInterception;
4145 if (aIter != m_aControlDispatchInterceptors.end())
4148 (*aIter)->dispose();
4150 m_aControlDispatchInterceptors.erase(aIter);
4155 void FormController::implInvalidateCurrentControlDependentFeatures()
4157 Sequence< sal_Int16 > aCurrentControlDependentFeatures(4);
4159 aCurrentControlDependentFeatures[0] = FormFeature::SortAscending;
4160 aCurrentControlDependentFeatures[1] = FormFeature::SortDescending;
4161 aCurrentControlDependentFeatures[2] = FormFeature::AutoFilter;
4162 aCurrentControlDependentFeatures[3] = FormFeature::RefreshCurrentControl;
4164 invalidateFeatures( aCurrentControlDependentFeatures );
4168 void SAL_CALL FormController::columnChanged(
const EventObject& )
4170 implInvalidateCurrentControlDependentFeatures();
#define LINK(Instance, Class, Member)
virtual void ImplSetPeerProperty(const OUString &rPropName, const css::uno::Any &rVal)
exports com.sun.star.form. control
const LanguageTag & GetUILanguageTag() const
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
bool hasMoreElements() const
#define FM_PROP_ISMODIFIED
OInteraction< css::task::XInteractionAbort > OInteractionAbort
static const AllSettings & GetSettings()
#define FM_PROP_DYNAMIC_CONTROL_BORDER
bool getBOOL(const Any &_rAny)
Reference< XInteractionHandler > m_xInteractionHandler
#define FM_PROP_AUTOINCREMENT
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
#define FM_PROP_CONTROL_BORDER_COLOR_FOCUS
OUString SvxResId(const char *pId)
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
static vcl::Window * GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
constexpr OUStringLiteral sServiceName
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
OInteraction< css::task::XInteractionDisapprove > OInteractionDisapprove
#define FM_PROP_BOUNDFIELD
#define FMURL_CONFIRM_DELETION
#define FM_PROP_CONTROL_BORDER_COLOR_MOUSE
Reference< XComponentContext > const m_xComponentContext
const OUString & getNumDecimalSep() const
#define DBG_UNHANDLED_EXCEPTION(...)
#define FM_PROP_SEARCHABLE
#define DBG_ASSERT(sCon, aError)
#define FM_PROP_FORM_OPERATIONS
class SAL_NO_VTABLE XPropertySet
css::uno::Sequence< css::uno::Type > getTypes()
#define FM_PROP_ISNULLABLE
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
static sal_Int32 getControllerFeatureSlotIdForURL(const OUString &_rMainURL)
retrieves the feature id for a given feature URL
void SAL_CALL elementRemoved(const css::container::ContainerEvent &Event) override
DECL_LISTENERMULTIPLEXER_END void SAL_CALL elementInserted(const css::container::ContainerEvent &Event) override
css::uno::Type const & get()
Reference< XComponentContext > getComponentContext(Reference< XMultiServiceFactory > const &factory)
css::uno::Sequence< T > concatSequences(const css::uno::Sequence< T > &rS1, const Ss &...rSn)
#define SAL_WARN_IF(condition, area, stream)
#define FM_PROP_ACTIVE_CONNECTION
#define FM_PROP_CONTROL_BORDER_COLOR_INVALID
#define FM_PROP_ACTIVECOMMAND
#define FM_PROP_INPUT_REQUIRED
#define FM_PROP_ISREADONLY
static sal_Int16 getFormFeatureForSlotId(sal_Int32 _nSlotId)
retrieves the css.form.runtime.FormFeature ID for a given slot ID
::std::pair< MetaAction *, int > Component
bool hasProperty(const OUString &_rName, const Reference< XPropertySet > &_rxSet)
Reference< XSingleServiceFactory > xFactory
Reference< XModel > xModel
css::uno::XInterface * next()
#define FM_PROP_DEFAULTCONTROL
OUString getString(const Any &_rAny)
static css::uno::Reference< css::awt::XWindow > GetInterface(vcl::Window *pWindow)
#define FM_ATTR_FORM_OPERATIONS
OInteraction< css::task::XInteractionApprove > OInteractionApprove
void SAL_CALL createPeer(const css::uno::Reference< css::awt::XToolkit > &Toolkit, const css::uno::Reference< css::awt::XWindowPeer > &Parent) override
css::uno::Sequence< typename M::key_type > mapKeysToSequence(M const &map)
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)