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>
86#include <osl/mutex.hxx>
98css::uno::Reference< css::uno::XInterface >
107 using ::com::sun::star::sdb::XColumn;
108 using ::com::sun::star::awt::XControl;
109 using ::com::sun::star::awt::TabController;
110 using ::com::sun::star::awt::XToolkit;
111 using ::com::sun::star::awt::XWindowPeer;
112 using ::com::sun::star::form::XGrid;
114 using ::com::sun::star::uno::UNO_SET_THROW;
115 using ::com::sun::star::uno::UNO_QUERY_THROW;
116 using ::com::sun::star::container::XIndexAccess;
117 using ::com::sun::star::uno::Exception;
118 using ::com::sun::star::uno::XInterface;
119 using ::com::sun::star::uno::UNO_QUERY;
120 using ::com::sun::star::uno::Sequence;
121 using ::com::sun::star::uno::Reference;
122 using ::com::sun::star::beans::XPropertySetInfo;
123 using ::com::sun::star::beans::PropertyValue;
124 using ::com::sun::star::lang::IndexOutOfBoundsException;
125 using ::com::sun::star::sdb::XInteractionSupplyParameters;
126 using ::com::sun::star::awt::XTextComponent;
127 using ::com::sun::star::awt::XTextListener;
128 using ::com::sun::star::uno::Any;
129 using ::com::sun::star::frame::XDispatch;
130 using ::com::sun::star::lang::XMultiServiceFactory;
131 using ::com::sun::star::uno::Type;
132 using ::com::sun::star::lang::IllegalArgumentException;
133 using ::com::sun::star::sdbc::XConnection;
134 using ::com::sun::star::sdbc::XRowSet;
135 using ::com::sun::star::sdbc::XDatabaseMetaData;
136 using ::com::sun::star::util::XNumberFormatsSupplier;
137 using ::com::sun::star::util::NumberFormatter;
138 using ::com::sun::star::util::XNumberFormatter;
139 using ::com::sun::star::sdbcx::XColumnsSupplier;
140 using ::com::sun::star::container::XNameAccess;
141 using ::com::sun::star::lang::EventObject;
142 using ::com::sun::star::beans::Property;
143 using ::com::sun::star::container::XEnumeration;
144 using ::com::sun::star::form::XFormComponent;
145 using ::com::sun::star::form::runtime::XFormOperations;
146 using ::com::sun::star::form::runtime::FilterEvent;
147 using ::com::sun::star::form::runtime::XFilterControllerListener;
148 using ::com::sun::star::awt::XControlContainer;
149 using ::com::sun::star::container::XIdentifierReplace;
150 using ::com::sun::star::form::XFormControllerListener;
151 using ::com::sun::star::awt::XWindow;
152 using ::com::sun::star::sdbc::XResultSet;
153 using ::com::sun::star::awt::XControlModel;
154 using ::com::sun::star::awt::XTabControllerModel;
155 using ::com::sun::star::beans::PropertyChangeEvent;
156 using ::com::sun::star::form::validation::XValidatableFormComponent;
157 using ::com::sun::star::form::XLoadable;
158 using ::com::sun::star::form::XBoundControl;
159 using ::com::sun::star::beans::XPropertyChangeListener;
160 using ::com::sun::star::awt::TextEvent;
161 using ::com::sun::star::form::XBoundComponent;
162 using ::com::sun::star::awt::XCheckBox;
163 using ::com::sun::star::awt::XComboBox;
164 using ::com::sun::star::awt::XListBox;
165 using ::com::sun::star::awt::ItemEvent;
166 using ::com::sun::star::util::XModifyListener;
167 using ::com::sun::star::form::XReset;
168 using ::com::sun::star::frame::XDispatchProviderInterception;
169 using ::com::sun::star::form::XGridControl;
170 using ::com::sun::star::awt::XVclWindowPeer;
171 using ::com::sun::star::form::validation::XValidator;
172 using ::com::sun::star::awt::FocusEvent;
173 using ::com::sun::star::sdb::SQLContext;
174 using ::com::sun::star::container::XChild;
175 using ::com::sun::star::form::TabulatorCycle_RECORDS;
176 using ::com::sun::star::container::ContainerEvent;
177 using ::com::sun::star::lang::DisposedException;
178 using ::com::sun::star::lang::Locale;
179 using ::com::sun::star::lang::NoSupportException;
180 using ::com::sun::star::sdb::RowChangeEvent;
181 using ::com::sun::star::frame::XStatusListener;
182 using ::com::sun::star::frame::XDispatchProviderInterceptor;
183 using ::com::sun::star::sdb::SQLErrorEvent;
184 using ::com::sun::star::form::DatabaseParameterEvent;
185 using ::com::sun::star::sdb::ParametersRequest;
186 using ::com::sun::star::task::XInteractionRequest;
187 using ::com::sun::star::util::URL;
188 using ::com::sun::star::frame::FeatureStateEvent;
189 using ::com::sun::star::form::runtime::XFormControllerContext;
190 using ::com::sun::star::task::InteractionHandler;
191 using ::com::sun::star::task::XInteractionHandler;
192 using ::com::sun::star::form::runtime::FormOperations;
193 using ::com::sun::star::container::XContainer;
194 using ::com::sun::star::sdbc::SQLWarning;
196 namespace ColumnValue = ::com::sun::star::sdbc::ColumnValue;
197 namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute;
198 namespace FocusChangeReason = ::com::sun::star::awt::FocusChangeReason;
199 namespace RowChangeAction = ::com::sun::star::sdb::RowChangeAction;
200 namespace FormFeature = ::com::sun::star::form::runtime::FormFeature;
227 :
nNullable( ColumnValue::NULLABLE_UNKNOWN )
240 explicit ColumnInfoCache(
const Reference< XColumnsSupplier >& _rxColSupplier );
257 :m_bControlsInitialized( false )
263 Reference< XIndexAccess > xColumns( _rxColSupplier->getColumns(), UNO_QUERY_THROW );
264 sal_Int32 nColumnCount = xColumns->getCount();
267 Reference< XPropertySet > xColumnProps;
268 for ( sal_Int32
i = 0;
i < nColumnCount; ++
i )
271 aColInfo.xColumn.set( xColumns->getByIndex(
i), UNO_QUERY_THROW );
273 xColumnProps.set( aColInfo.xColumn, UNO_QUERY_THROW );
274 OSL_VERIFY( xColumnProps->getPropertyValue(
FM_PROP_ISNULLABLE ) >>= aColInfo.nNullable );
276 OSL_VERIFY( xColumnProps->getPropertyValue(
FM_PROP_NAME ) >>= aColInfo.sName );
277 OSL_VERIFY( xColumnProps->getPropertyValue(
FM_PROP_ISREADONLY ) >>= aColInfo.bReadOnly );
291 bool lcl_isBoundTo(
const Reference< XPropertySet >& _rxControlModel,
const Reference< XInterface >& _rxNormDBField )
293 Reference< XInterface > xNormBoundField( _rxControlModel->getPropertyValue(
FM_PROP_BOUNDFIELD ), UNO_QUERY );
294 return ( xNormBoundField == _rxNormDBField );
297 bool lcl_isInputRequired(
const Reference< XPropertySet >& _rxControlModel )
299 bool bInputRequired =
false;
301 return bInputRequired;
304 void lcl_resetColumnControlInfo(
ColumnInfo& _rColInfo )
306 _rColInfo.xFirstControlWithInputRequired.clear();
307 _rColInfo.xFirstGridWithInputRequiredColumn.clear();
308 _rColInfo.nRequiredGridColumn = -1;
317 lcl_resetColumnControlInfo( rCol );
330 OSL_ENSURE( !rCol.xFirstControlWithInputRequired.is() && !rCol.xFirstGridWithInputRequiredColumn.is()
331 && ( rCol.nRequiredGridColumn == -1 ),
"ColumnInfoCache::initializeControls: called me twice?" );
333 lcl_resetColumnControlInfo( rCol );
335 Reference< XInterface > xNormColumn( rCol.xColumn, UNO_QUERY_THROW );
337 const Reference< XControl >* pControl( _rControls.getConstArray() );
338 const Reference< XControl >* pControlEnd( pControl + _rControls.getLength() );
339 for ( ; pControl != pControlEnd; ++pControl )
341 if ( !pControl->is() )
344 Reference< XPropertySet >
xModel( (*pControl)->getModel(), UNO_QUERY_THROW );
345 Reference< XPropertySetInfo > xModelPSI(
xModel->getPropertySetInfo(), UNO_SET_THROW );
348 Reference< XGrid > xGrid( *pControl, UNO_QUERY );
351 Reference< XIndexAccess > xGridColAccess(
xModel, UNO_QUERY_THROW );
352 sal_Int32 gridColCount = xGridColAccess->getCount();
353 sal_Int32 gridCol = 0;
354 for ( gridCol = 0; gridCol < gridColCount; ++gridCol )
356 Reference< XPropertySet > xGridColumnModel( xGridColAccess->getByIndex( gridCol ), UNO_QUERY_THROW );
358 if ( !lcl_isBoundTo( xGridColumnModel, xNormColumn )
359 || !lcl_isInputRequired( xGridColumnModel )
366 if ( gridCol < gridColCount )
369 rCol.xFirstGridWithInputRequiredColumn = xGrid;
370 rCol.nRequiredGridColumn = gridCol;
378 || !lcl_isBoundTo(
xModel, xNormColumn )
379 || !lcl_isInputRequired(
xModel )
386 if ( pControl == pControlEnd )
390 rCol.xFirstControlWithInputRequired = *pControl;
405 throw IndexOutOfBoundsException();
412class OParameterContinuation :
public OInteraction< XInteractionSupplyParameters >
417 OParameterContinuation() { }
419 const Sequence< PropertyValue >& getValues()
const {
return m_aValues; }
422 virtual void SAL_CALL setParameters(
const Sequence< PropertyValue >& _rValues )
override;
427void SAL_CALL OParameterContinuation::setParameters(
const Sequence< PropertyValue >& _rValues )
441 FmFieldInfo(
const Reference< XPropertySet >& _xField,
const Reference< XTextComponent >& _xText)
457 virtual OUString GetComponentServiceName()
const override {
return "Edit";}
458 virtual void SAL_CALL createPeer(
const Reference< XToolkit > & rxToolkit,
const Reference< XWindowPeer > & rParentPeer )
override;
461 virtual void ImplSetPeerProperty(
const OUString& rPropName,
const Any& rVal )
override;
466void FmXAutoControl::createPeer(
const Reference< XToolkit > & rxToolkit,
const Reference< XWindowPeer > & rParentPeer )
470 Reference< XTextComponent > xText(getPeer() , UNO_QUERY);
473 xText->setText(
SvxResId(RID_STR_AUTOFIELD));
474 xText->setEditable(
false);
479void FmXAutoControl::ImplSetPeerProperty(
const OUString& rPropName,
const Any& rVal )
496struct UpdateAllListeners
498 bool operator()(
const Reference< XDispatch >& _rxDispatcher )
const
510 ::osl::MutexGuard aGuard(
m_aMutex );
511 for (
const auto& rFeature : m_aInvalidFeatures)
513 DispatcherContainer::const_iterator aDispatcherPos = m_aFeatureDispatchers.find( rFeature );
514 if ( aDispatcherPos != m_aFeatureDispatchers.end() )
518 UpdateAllListeners( )( aDispatcherPos->second );
526 ,OSQLParserClient( _rxORB )
532 ,m_aRowSetApproveListeners(
m_aMutex)
535 ,m_aTabActivationIdle(
"svx FormController m_aTabActivationIdle")
536 ,m_aFeatureInvalidationTimer(
"svx FormController m_aFeatureInvalidationTimer")
537 ,m_aMode( OUString(
"DataMode" ) )
538 ,m_aLoadEvent(
LINK( this, FormController, OnLoad ) )
539 ,m_aToggleEvent(
LINK( this, FormController, OnToggleAutoFields ) )
540 ,m_aActivationEvent(
LINK( this, FormController, OnActivated ) )
541 ,m_aDeactivationEvent(
LINK( this, FormController, OnDeactivated ) )
542 ,m_nCurrentFilterPosition(-1)
543 ,m_bCurrentRecordModified(false)
544 ,m_bCurrentRecordNew(false)
546 ,m_bDBConnection(false)
550 ,m_bCommitLock(false)
552 ,m_bControlsSorted(false)
554 ,m_bAttachEvents(true)
555 ,m_bDetachEvents(true)
556 ,m_bAttemptedHandlerCreation( false )
557 ,m_bSuspendFilterTextListening( false )
560 osl_atomic_increment(&m_refCount);
562 m_xTabController = TabController::create( m_xComponentContext );
563 m_xAggregate.set( m_xTabController, UNO_QUERY_THROW );
564 m_xAggregate->setDelegator( *
this );
566 osl_atomic_decrement(&m_refCount);
568 m_aTabActivationIdle.SetPriority( TaskPriority::LOWEST );
569 m_aTabActivationIdle.SetInvokeHandler(
LINK(
this, FormController, OnActivateTabOrder ) );
571 m_aFeatureInvalidationTimer.SetTimeout( 200 );
572 m_aFeatureInvalidationTimer.SetInvokeHandler(
LINK(
this, FormController, OnInvalidateFeatures ) );
576FormController::~FormController()
579 ::osl::MutexGuard aGuard(
m_aMutex );
581 m_aLoadEvent.CancelPendingCall();
582 m_aToggleEvent.CancelPendingCall();
583 m_aActivationEvent.CancelPendingCall();
584 m_aDeactivationEvent.CancelPendingCall();
586 if ( m_aTabActivationIdle.IsActive() )
587 m_aTabActivationIdle.Stop();
590 if ( m_aFeatureInvalidationTimer.IsActive() )
591 m_aFeatureInvalidationTimer.Stop();
593 disposeAllFeaturesAndDispatchers();
595 if ( m_xFormOperations.is() )
596 m_xFormOperations->dispose();
597 m_xFormOperations.clear();
600 if ( m_xAggregate.is() )
602 m_xAggregate->setDelegator(
nullptr );
603 m_xAggregate.clear();
608void SAL_CALL FormController::acquire() noexcept
610 FormController_BASE::acquire();
614void SAL_CALL FormController::release() noexcept
616 FormController_BASE::release();
620Any SAL_CALL FormController::queryInterface(
const Type& _rType )
622 Any aRet = FormController_BASE::queryInterface( _rType );
623 if ( !aRet.hasValue() )
624 aRet = OPropertySetHelper::queryInterface( _rType );
625 if ( !aRet.hasValue() )
626 aRet = m_xAggregate->queryAggregation( _rType );
633 return css::uno::Sequence<sal_Int8>();
636Sequence< Type > SAL_CALL FormController::getTypes( )
639 FormController_BASE::getTypes(),
645sal_Bool SAL_CALL FormController::supportsService(
const OUString& ServiceName)
650OUString SAL_CALL FormController::getImplementationName()
652 return "org.openoffice.comp.svx.FormController";
655Sequence< OUString> SAL_CALL FormController::getSupportedServiceNames()
659 Sequence<OUString> aNonCreatableServiceNames {
"com.sun.star.form.FormControllerDispatcher" };
662 Sequence< OUString > aCreatableServiceNames( getSupportedServiceNames_Static() );
663 return ::comphelper::concatSequences( aCreatableServiceNames, aNonCreatableServiceNames );
667sal_Bool SAL_CALL FormController::approveReset(
const EventObject& )
673void SAL_CALL FormController::resetted(
const EventObject& rEvent)
676 if (getCurrentControl().is() && (getCurrentControl()->getModel() == rEvent.Source))
681Sequence< OUString>
const & FormController::getSupportedServiceNames_Static()
683 static Sequence< OUString>
const aServices
685 "com.sun.star.form.runtime.FormController",
686 "com.sun.star.awt.control.TabController"
694 struct ResetComponentText
696 void operator()(
const Reference< XTextComponent >& _rxText )
698 _rxText->setText( OUString() );
702 struct RemoveComponentTextListener
704 explicit RemoveComponentTextListener(
const Reference< XTextListener >& _rxListener )
709 void operator()(
const Reference< XTextComponent >& _rxText )
720void FormController::impl_setTextOnAllFilter_throw()
722 m_bSuspendFilterTextListening =
true;
726 ::std::for_each( m_aFilterComponents.begin(), m_aFilterComponents.end(), ResetComponentText() );
728 if ( m_aFilterRows.empty() )
732 if ( m_nCurrentFilterPosition < 0 )
737 "FormController::impl_setTextOnAllFilter_throw: m_nCurrentFilterPosition too big" );
741 FmFilterRow& rRow = m_aFilterRows[ m_nCurrentFilterPosition ];
742 for (
const auto& rEntry : rRow)
744 rEntry.first->setText( rEntry.second );
750sal_Bool FormController::convertFastPropertyValue( Any & , Any & ,
751 sal_Int32 ,
const Any& )
757void FormController::setFastPropertyValue_NoBroadcast( sal_Int32 ,
const Any& )
762void FormController::getFastPropertyValue( Any& rValue, sal_Int32 nHandle )
const
768 OUStringBuffer aFilter;
769 Reference<XConnection> xConnection(
getConnection(Reference< XRowSet>(m_xModelAsIndex, UNO_QUERY)));
770 if (xConnection.is())
772 Reference< XNumberFormatsSupplier> xFormatSupplier(
getNumberFormats( xConnection,
true ) );
773 Reference< XNumberFormatter> xFormatter = NumberFormatter::create(m_xComponentContext);
774 xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
784 OUStringBuffer aRowFilter;
785 for ( FmFilterRow::const_iterator condition = rRow.begin(); condition != rRow.end(); ++condition )
788 Reference< XControl > xControl( condition->first, UNO_QUERY_THROW );
789 Reference< XPropertySet > xModelProps( xControl->getModel(), UNO_QUERY_THROW );
790 Reference< XPropertySet > xField( xModelProps->getPropertyValue(
FM_PROP_BOUNDFIELD ), UNO_QUERY_THROW );
792 OUString sFilterValue( condition->second );
795 const std::unique_ptr< OSQLParseNode > pParseNode =
796 predicateTree( sErrorMsg, sFilterValue, xFormatter, xField );
797 OSL_ENSURE( pParseNode !=
nullptr,
"FormController::getFastPropertyValue: could not parse the field value predicate!" );
798 if ( pParseNode !=
nullptr )
802 pParseNode->parseNodeToStr( sCriteria, xConnection );
803 if ( condition != rRow.begin() )
804 aRowFilter.append(
" AND " );
805 aRowFilter.append( sCriteria );
808 if ( !aRowFilter.isEmpty() )
810 if ( !aFilter.isEmpty() )
811 aFilter.append(
" OR " );
813 aFilter.append(
"( " );
814 aFilter.append( aRowFilter );
815 aFilter.append(
" )" );
819 catch(
const Exception& )
822 aFilter.setLength(0);
825 rValue <<= aFilter.makeStringAndClear();
830 rValue <<= m_xFormOperations;
836Reference< XPropertySetInfo > FormController::getPropertySetInfo()
838 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
843void FormController::fillProperties(
844 Sequence< Property >& _rProps,
845 Sequence< Property >&
850 Property* pDesc = _rProps.getArray();
854 PropertyAttribute::READONLY);
857 PropertyAttribute::READONLY);
863 return *getArrayHelper();
868void SAL_CALL FormController::addFilterControllerListener(
const Reference< XFilterControllerListener >& Listener )
870 m_aFilterListeners.addInterface( Listener );
874void SAL_CALL FormController::removeFilterControllerListener(
const Reference< XFilterControllerListener >& Listener )
876 m_aFilterListeners.removeInterface( Listener );
880::sal_Int32 SAL_CALL FormController::getFilterComponents()
882 ::osl::MutexGuard aGuard(
m_aMutex );
883 impl_checkDisposed_throw();
885 return m_aFilterComponents.size();
889::sal_Int32 SAL_CALL FormController::getDisjunctiveTerms()
891 ::osl::MutexGuard aGuard(
m_aMutex );
892 impl_checkDisposed_throw();
894 return m_aFilterRows.size();
898void SAL_CALL FormController::setPredicateExpression( ::sal_Int32
Component, ::sal_Int32 Term,
const OUString& PredicateExpression )
900 ::osl::MutexGuard aGuard(
m_aMutex );
901 impl_checkDisposed_throw();
903 if ( (
Component < 0 ) || (
Component >= getFilterComponents() ) || ( Term < 0 ) || ( Term >= getDisjunctiveTerms() ) )
904 throw IndexOutOfBoundsException( OUString(), *
this );
906 Reference< XTextComponent > xText( m_aFilterComponents[
Component ] );
907 xText->setText( PredicateExpression );
910 if ( !PredicateExpression.isEmpty() )
911 rFilterRow[ xText ] = PredicateExpression;
913 rFilterRow.erase( xText );
917Reference< XControl > FormController::getFilterComponent( ::sal_Int32
Component )
919 ::osl::MutexGuard aGuard(
m_aMutex );
920 impl_checkDisposed_throw();
923 throw IndexOutOfBoundsException( OUString(), *
this );
925 return Reference< XControl >( m_aFilterComponents[
Component ], UNO_QUERY );
929Sequence< Sequence< OUString > > FormController::getPredicateExpressions()
931 ::osl::MutexGuard aGuard(
m_aMutex );
932 impl_checkDisposed_throw();
934 Sequence< Sequence< OUString > > aExpressions( m_aFilterRows.size() );
935 auto aExpressionsRange = asNonConstRange(aExpressions);
936 sal_Int32 termIndex = 0;
939 Sequence< OUString > aConjunction( m_aFilterComponents.size() );
940 auto aConjunctionRange = asNonConstRange(aConjunction);
941 sal_Int32 componentIndex = 0;
942 for (
const auto& rComp : m_aFilterComponents)
944 FmFilterRow::const_iterator predicate = rRow.find( rComp );
945 if ( predicate != rRow.end() )
946 aConjunctionRange[ componentIndex ] = predicate->second;
950 aExpressionsRange[ termIndex ] = aConjunction;
958void SAL_CALL FormController::removeDisjunctiveTerm( ::sal_Int32 Term )
961 ::osl::ClearableMutexGuard aGuard(
m_aMutex );
962 impl_checkDisposed_throw();
964 if ( ( Term < 0 ) || ( Term >= getDisjunctiveTerms() ) )
965 throw IndexOutOfBoundsException( OUString(), *
this );
968 if ( Term == m_nCurrentFilterPosition )
970 if ( m_nCurrentFilterPosition < sal_Int32( m_aFilterRows.size() - 1 ) )
971 ++m_nCurrentFilterPosition;
973 --m_nCurrentFilterPosition;
976 FmFilterRows::iterator
pos = m_aFilterRows.begin() + Term;
977 m_aFilterRows.erase(
pos );
980 if ( Term < m_nCurrentFilterPosition )
981 --m_nCurrentFilterPosition;
983 SAL_WARN_IF( !( ( m_nCurrentFilterPosition < 0 ) != ( m_aFilterRows.empty() ) ),
984 "svx.form",
"FormController::removeDisjunctiveTerm: inconsistency!" );
987 impl_setTextOnAllFilter_throw();
991 aEvent.DisjunctiveTerm = Term;
995 m_aFilterListeners.notifyEach( &XFilterControllerListener::disjunctiveTermRemoved,
aEvent );
999void SAL_CALL FormController::appendEmptyDisjunctiveTerm()
1002 ::osl::ClearableMutexGuard aGuard(
m_aMutex );
1003 impl_checkDisposed_throw();
1005 impl_appendEmptyFilterRow( aGuard );
1010::sal_Int32 SAL_CALL FormController::getActiveTerm()
1012 ::osl::MutexGuard aGuard(
m_aMutex );
1013 impl_checkDisposed_throw();
1015 return m_nCurrentFilterPosition;
1019void SAL_CALL FormController::setActiveTerm( ::sal_Int32 ActiveTerm )
1021 ::osl::MutexGuard aGuard(
m_aMutex );
1022 impl_checkDisposed_throw();
1024 if ( ( ActiveTerm < 0 ) || ( ActiveTerm >= getDisjunctiveTerms() ) )
1025 throw IndexOutOfBoundsException( OUString(), *
this );
1027 if ( ActiveTerm == getActiveTerm() )
1030 m_nCurrentFilterPosition = ActiveTerm;
1031 impl_setTextOnAllFilter_throw();
1038 ::osl::MutexGuard aGuard(
m_aMutex );
1039 return !m_aChildren.empty();
1043Type SAL_CALL FormController::getElementType()
1051Reference< XEnumeration > SAL_CALL FormController::createEnumeration()
1053 ::osl::MutexGuard aGuard(
m_aMutex );
1054 return new ::comphelper::OEnumerationByIndex(
this);
1059sal_Int32 SAL_CALL FormController::getCount()
1061 ::osl::MutexGuard aGuard(
m_aMutex );
1062 return m_aChildren.size();
1066Any SAL_CALL FormController::getByIndex(sal_Int32
Index)
1068 ::osl::MutexGuard aGuard(
m_aMutex );
1071 throw IndexOutOfBoundsException();
1073 return Any( m_aChildren[
Index ] );
1078void SAL_CALL FormController::disposing(
const EventObject& e)
1081 ::osl::MutexGuard aGuard( m_aMutex );
1082 Reference< XControlContainer > xContainer(e.Source, UNO_QUERY);
1083 if (xContainer.is())
1085 setContainer(Reference< XControlContainer > ());
1090 Reference< XControl > xControl(e.Source, UNO_QUERY);
1093 if (getContainer().is())
1094 removeControl(xControl);
1101void FormController::disposeAllFeaturesAndDispatchers()
1103 for (
auto& rDispatcher : m_aFeatureDispatchers)
1107 ::comphelper::disposeComponent( rDispatcher.second );
1114 m_aFeatureDispatchers.clear();
1118void FormController::disposing()
1120 EventObject aEvt( *
this );
1123 if ( m_xActiveControl.is() )
1124 m_aActivateListeners.notifyEach( &XFormControllerListener::formDeactivated, aEvt );
1127 m_aActivateListeners.disposeAndClear(aEvt);
1128 m_aModifyListeners.disposeAndClear(aEvt);
1129 m_aErrorListeners.disposeAndClear(aEvt);
1130 m_aDeleteListeners.disposeAndClear(aEvt);
1131 m_aRowSetApproveListeners.disposeAndClear(aEvt);
1132 m_aParameterListeners.disposeAndClear(aEvt);
1133 m_aFilterListeners.disposeAndClear(aEvt);
1135 removeBoundFieldListener();
1138 m_aControlBorderManager.restoreAll();
1140 m_aFilterRows.clear();
1142 ::osl::MutexGuard aGuard(
m_aMutex );
1143 m_xActiveControl =
nullptr;
1144 implSetCurrentControl(
nullptr );
1147 for (
const auto& rpChild : m_aChildren)
1150 Reference< XFormComponent > xForm(rpChild->getModel(), UNO_QUERY);
1151 sal_uInt32
nPos = m_xModelAsIndex->getCount();
1152 Reference< XFormComponent > xTemp;
1156 m_xModelAsIndex->getByIndex( --
nPos ) >>= xTemp;
1157 if ( xForm.get() == xTemp.get() )
1159 Reference< XInterface > xIfc( rpChild, UNO_QUERY );
1160 m_xModelAsManager->detach(
nPos, xIfc );
1165 Reference< XComponent > (rpChild, UNO_QUERY_THROW)->dispose();
1167 m_aChildren.clear();
1169 disposeAllFeaturesAndDispatchers();
1171 if ( m_xFormOperations.is() )
1172 m_xFormOperations->dispose();
1173 m_xFormOperations.clear();
1175 if (m_bDBConnection)
1178 setContainer(
nullptr );
1179 setModel(
nullptr );
1180 setParent(
nullptr );
1182 ::comphelper::disposeComponent( m_xComposer );
1184 m_bDBConnection =
false;
1190 bool lcl_shouldUseDynamicControlBorder(
const Reference< XInterface >& _rxForm,
const Any& _rDynamicColorProp )
1192 bool bDoUse =
false;
1193 if ( !( _rDynamicColorProp >>= bDoUse ) )
1195 DocumentType eDocType = DocumentClassification::classifyHostDocument( _rxForm );
1203void SAL_CALL FormController::propertyChange(
const PropertyChangeEvent& evt)
1205 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1208 Reference<XPropertySet> xOldBound;
1209 evt.OldValue >>= xOldBound;
1210 if ( !xOldBound.is() && evt.NewValue.hasValue() )
1212 Reference< XControlModel > xControlModel(evt.Source,UNO_QUERY);
1213 Reference< XControl > xControl = findControl(m_aControls,xControlModel,
false,
false);
1214 if ( xControl.is() )
1216 startControlModifyListening( xControl );
1217 Reference<XPropertySet> xProp(xControlModel,UNO_QUERY);
1227 if (bModifiedChanged || bNewChanged)
1229 ::osl::MutexGuard aGuard(
m_aMutex );
1230 if (bModifiedChanged)
1231 m_bCurrentRecordModified = ::comphelper::getBOOL(evt.NewValue);
1233 m_bCurrentRecordNew = ::comphelper::getBOOL(evt.NewValue);
1236 if (m_bLocked != determineLockState())
1238 m_bLocked = !m_bLocked;
1240 if (isListeningForChanges())
1247 m_aToggleEvent.Call();
1249 if (!m_bCurrentRecordModified)
1250 m_bModified =
false;
1254 bool bEnable = lcl_shouldUseDynamicControlBorder( evt.Source, evt.NewValue );
1257 m_aControlBorderManager.enableDynamicBorderColor();
1258 if ( m_xActiveControl.is() )
1259 m_aControlBorderManager.focusGained( m_xActiveControl );
1263 m_aControlBorderManager.disableDynamicBorderColor();
1270bool FormController::replaceControl(
const Reference< XControl >& _rxExistentControl,
const Reference< XControl >& _rxNewControl )
1272 bool bSuccess =
false;
1275 Reference< XIdentifierReplace > xContainer( getContainer(), UNO_QUERY );
1276 DBG_ASSERT( xContainer.is(),
"FormController::replaceControl: yes, it's not required by the service description, but XIdentifierReplace would be nice!" );
1277 if ( xContainer.is() )
1280 const Sequence< sal_Int32 > aIdentifiers( xContainer->getIdentifiers() );
1281 const sal_Int32* pIdentifiers = std::find_if(aIdentifiers.begin(), aIdentifiers.end(),
1282 [&xContainer, &_rxExistentControl](
const sal_Int32
nId) {
1283 Reference< XControl > xCheck( xContainer->getByIdentifier( nId ), UNO_QUERY );
1284 return xCheck == _rxExistentControl;
1286 DBG_ASSERT( pIdentifiers != aIdentifiers.end(),
"FormController::replaceControl: did not find the control in the container!" );
1287 if ( pIdentifiers != aIdentifiers.end() )
1289 bool bReplacedWasActive = ( m_xActiveControl.get() == _rxExistentControl.get() );
1290 bool bReplacedWasCurrent = ( m_xCurrentControl.get() == _rxExistentControl.get() );
1292 if ( bReplacedWasActive )
1294 m_xActiveControl =
nullptr;
1295 implSetCurrentControl(
nullptr );
1297 else if ( bReplacedWasCurrent )
1299 implSetCurrentControl( _rxNewControl );
1303 _rxNewControl->setModel( _rxExistentControl->getModel() );
1305 xContainer->replaceByIdentifer( *pIdentifiers,
Any( _rxNewControl ) );
1308 if ( bReplacedWasActive )
1310 Reference< XWindow > xControlWindow( _rxNewControl, UNO_QUERY );
1311 if ( xControlWindow.is() )
1312 xControlWindow->setFocus();
1322 Reference< XControl > xDisposeIt( bSuccess ? _rxExistentControl : _rxNewControl );
1323 ::comphelper::disposeComponent( xDisposeIt );
1328void FormController::toggleAutoFields(
bool bAutoFields)
1330 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1333 Sequence< Reference< XControl > > aControlsCopy( m_aControls );
1334 const Reference< XControl >* pControls = aControlsCopy.getConstArray();
1335 sal_Int32 nControls = aControlsCopy.getLength();
1341 m_bAttachEvents =
false;
1342 for (sal_Int32
i = nControls;
i > 0;)
1344 Reference< XControl > xControl = pControls[--
i];
1347 Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
1351 Reference< XPropertySet > xField;
1360 replaceControl( xControl,
new FmXAutoControl() );
1365 m_bAttachEvents =
true;
1369 m_bDetachEvents =
false;
1370 for (sal_Int32
i = nControls;
i > 0;)
1372 Reference< XControl > xControl = pControls[--
i];
1375 Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
1379 Reference< XPropertySet > xField;
1391 replaceControl( xControl, xNewControl );
1396 m_bDetachEvents =
true;
1403 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1405 toggleAutoFields(m_bCurrentRecordNew);
1409void SAL_CALL FormController::textChanged(
const TextEvent& e)
1412 ::osl::ClearableMutexGuard aGuard(
m_aMutex );
1413 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1414 if ( !m_bFiltering )
1420 if ( m_bSuspendFilterTextListening )
1423 Reference< XTextComponent > xText(e.Source,UNO_QUERY);
1424 OUString aText = xText->getText();
1426 if ( m_aFilterRows.empty() )
1427 appendEmptyDisjunctiveTerm();
1430 if ( ( m_nCurrentFilterPosition < 0 ) || (
o3tl::make_unsigned(m_nCurrentFilterPosition) >= m_aFilterRows.size() ) )
1432 OSL_ENSURE(
false,
"FormController::textChanged: m_nCurrentFilterPosition is wrong!" );
1436 FmFilterRow& rRow = m_aFilterRows[ m_nCurrentFilterPosition ];
1439 if (!aText.isEmpty())
1440 rRow[xText] = aText;
1444 FmFilterRow::iterator iter = rRow.find(xText);
1446 if (iter != rRow.end())
1453 aEvent.FilterComponent = ::std::find( m_aFilterComponents.begin(), m_aFilterComponents.end(), xText ) - m_aFilterComponents.begin();
1454 aEvent.DisjunctiveTerm = getActiveTerm();
1455 aEvent.PredicateExpression = aText;
1461 m_aFilterListeners.notifyEach( &XFilterControllerListener::predicateExpressionChanged,
aEvent );
1465void SAL_CALL FormController::itemStateChanged(
const ItemEvent& )
1467 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1472void SAL_CALL FormController::addModifyListener(
const Reference< XModifyListener > & l)
1474 ::osl::MutexGuard aGuard(
m_aMutex );
1475 impl_checkDisposed_throw();
1476 m_aModifyListeners.addInterface( l );
1479void FormController::removeModifyListener(
const Reference< XModifyListener > & l)
1481 ::osl::MutexGuard aGuard(
m_aMutex );
1482 impl_checkDisposed_throw();
1483 m_aModifyListeners.removeInterface( l );
1487void FormController::modified(
const EventObject& _rEvent )
1489 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1493 if ( _rEvent.Source != m_xActiveControl )
1501 Reference< XWindow > xControlWindow( _rEvent.Source, UNO_QUERY_THROW );
1502 xControlWindow->setFocus();
1513void FormController::impl_checkDisposed_throw()
const
1515 if ( impl_isDisposed_nofail() )
1516 throw DisposedException( OUString(), *
const_cast< FormController*
>(
this ) );
1519void FormController::impl_onModify()
1521 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1524 ::osl::MutexGuard aGuard(
m_aMutex );
1530 m_aModifyListeners.notifyEach( &XModifyListener::modified, aEvt );
1535 m_aFilterRows.push_back( _row );
1537 if ( m_aFilterRows.size() == 1 )
1539 OSL_ENSURE( m_nCurrentFilterPosition == -1,
"FormController::impl_addFilterRow: inconsistency!" );
1540 m_nCurrentFilterPosition = 0;
1544void FormController::impl_appendEmptyFilterRow( ::osl::ClearableMutexGuard& _rClearBeforeNotify )
1552 aEvent.DisjunctiveTerm =
static_cast<sal_Int32
>(m_aFilterRows.size()) - 1;
1553 _rClearBeforeNotify.clear();
1555 m_aFilterListeners.notifyEach( &XFilterControllerListener::disjunctiveTermAdded,
aEvent );
1558bool FormController::determineLockState()
const
1560 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1565 Reference< XResultSet > xResultSet(m_xModelAsIndex, UNO_QUERY);
1566 if (m_bFiltering || !xResultSet.is() || !
isRowSetAlive(xResultSet))
1569 return !(m_bCanInsert && m_bCurrentRecordNew)
1570 && (xResultSet->isBeforeFirst() || xResultSet->isAfterLast() || xResultSet->rowDeleted() || !m_bCanUpdate);
1574void FormController::focusGained(
const FocusEvent& e)
1577 ::osl::ClearableMutexGuard aGuard(
m_aMutex );
1578 impl_checkDisposed_throw();
1580 m_aControlBorderManager.focusGained( e.Source );
1582 Reference< XControl > xControl(e.Source, UNO_QUERY);
1583 if (m_bDBConnection)
1588 m_bCommitLock = m_bCommitLock && xControl.get() != m_xCurrentControl.get();
1598 if ( ( m_bModified || m_bFiltering )
1599 && m_xCurrentControl.is()
1600 && ( ( xControl.get() != m_xCurrentControl.get() )
1601 || ( ( e.FocusFlags & FocusChangeReason::AROUND )
1602 && ( m_bCycle || m_bFiltering )
1608#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
1609 Reference< XBoundControl > xLockingTest(m_xCurrentControl, UNO_QUERY);
1610 bool bControlIsLocked = xLockingTest.is() && xLockingTest->getLock();
1611 assert(!bControlIsLocked &&
"FormController::Gained: I'm modified and the current control is locked ? How this ?");
1615 DBG_ASSERT(m_xCurrentControl.is(),
"no CurrentControl set");
1617 Reference< XBoundComponent > xBound(m_xCurrentControl, UNO_QUERY);
1618 if (!xBound.is() && m_xCurrentControl.is())
1619 xBound.set(m_xCurrentControl->getModel(), UNO_QUERY);
1622 m_bCommitLock =
true;
1625 if (xBound.is() && !xBound->commit())
1629 Reference< XWindow > xWindow(m_xCurrentControl, UNO_QUERY);
1631 xWindow->setFocus();
1636 m_bModified =
false;
1637 m_bCommitLock =
false;
1641 if (!m_bFiltering && m_bCycle && (e.FocusFlags & FocusChangeReason::AROUND) && m_xCurrentControl.is())
1643 OSL_ENSURE( m_xFormOperations.is(),
"FormController::focusGained: hmm?" );
1647 if ( e.FocusFlags & FocusChangeReason::FORWARD )
1649 if ( m_xFormOperations.is() && m_xFormOperations->isEnabled( FormFeature::MoveToNext ) )
1650 m_xFormOperations->execute( FormFeature::MoveToNext );
1654 if ( m_xFormOperations.is() && m_xFormOperations->isEnabled( FormFeature::MoveToPrevious ) )
1655 m_xFormOperations->execute( FormFeature::MoveToPrevious );
1667 if ( ( m_xActiveControl == xControl )
1668 && ( xControl == m_xCurrentControl )
1671 DBG_ASSERT(m_xCurrentControl.is(),
"No CurrentControl selected");
1675 bool bActivated = !m_xActiveControl.is() && xControl.is();
1677 m_xActiveControl = xControl;
1679 implSetCurrentControl( xControl );
1680 SAL_WARN_IF( !m_xCurrentControl.is(),
"svx.form",
"implSetCurrentControl did nonsense!" );
1685 m_aActivationEvent.Call();
1689 m_aModifyListeners.notifyEach( &XModifyListener::modified, EventObject( *
this ) );
1693 if ( m_bDBConnection && !m_bFiltering )
1694 implInvalidateCurrentControlDependentFeatures();
1696 if ( !m_xCurrentControl.is() )
1700 Reference< XFormControllerContext > xContext( m_xFormControllerContext );
1701 Reference< XControl > xCurrentControl( m_xCurrentControl );
1705 if ( xContext.is() )
1706 xContext->makeVisible( xCurrentControl );
1713 m_aActivateListeners.notifyEach( &XFormControllerListener::formActivated,
aEvent );
1720 m_aActivateListeners.notifyEach( &XFormControllerListener::formDeactivated,
aEvent );
1723void FormController::focusLost(
const FocusEvent& e)
1725 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1727 m_aControlBorderManager.focusLost( e.Source );
1729 Reference< XWindowPeer > xNext(e.NextFocus, UNO_QUERY);
1733 Reference< XControl > xNextControl = isInList(xNext);
1734 if (!xNextControl.is())
1736 m_xActiveControl =
nullptr;
1737 m_aDeactivationEvent.Call();
1741void SAL_CALL FormController::mousePressed(
const awt::MouseEvent& )
1746void SAL_CALL FormController::mouseReleased(
const awt::MouseEvent& )
1751void SAL_CALL FormController::mouseEntered(
const awt::MouseEvent& _rEvent )
1753 m_aControlBorderManager.mouseEntered( _rEvent.Source );
1756void SAL_CALL FormController::mouseExited(
const awt::MouseEvent& _rEvent )
1758 m_aControlBorderManager.mouseExited( _rEvent.Source );
1761void SAL_CALL FormController::componentValidityChanged(
const EventObject& _rSource )
1763 Reference< XControl > xControl( findControl( m_aControls, Reference< XControlModel >( _rSource.Source, UNO_QUERY ),
false,
false ) );
1764 Reference< XValidatableFormComponent > xValidatable( _rSource.Source, UNO_QUERY );
1766 OSL_ENSURE( xControl.is() && xValidatable.is(),
"FormController::componentValidityChanged: huh?" );
1768 if ( xControl.is() && xValidatable.is() )
1769 m_aControlBorderManager.validityChanged( xControl, xValidatable );
1773void FormController::setModel(
const Reference< XTabControllerModel > & Model)
1775 ::osl::MutexGuard aGuard(
m_aMutex );
1776 impl_checkDisposed_throw();
1778 DBG_ASSERT(m_xTabController.is(),
"FormController::setModel : invalid aggregate !");
1783 if (m_xModelAsIndex.is())
1785 if (m_bDBConnection)
1788 EventObject aEvt(m_xModelAsIndex);
1792 Reference< XLoadable > xForm(m_xModelAsIndex, UNO_QUERY);
1794 xForm->removeLoadListener(
this);
1796 Reference< XSQLErrorBroadcaster > xBroadcaster(m_xModelAsIndex, UNO_QUERY);
1797 if (xBroadcaster.is())
1798 xBroadcaster->removeSQLErrorListener(
this);
1800 Reference< XDatabaseParameterBroadcaster > xParamBroadcaster(m_xModelAsIndex, UNO_QUERY);
1801 if (xParamBroadcaster.is())
1802 xParamBroadcaster->removeParameterListener(
this);
1806 disposeAllFeaturesAndDispatchers();
1808 if ( m_xFormOperations.is() )
1809 m_xFormOperations->dispose();
1810 m_xFormOperations.clear();
1813 if (m_xTabController.is())
1814 m_xTabController->setModel(
Model);
1815 m_xModelAsIndex.set(
Model, UNO_QUERY);
1816 m_xModelAsManager.set(
Model, UNO_QUERY);
1819 if (!m_xModelAsIndex.is() || !m_xModelAsManager.is())
1821 m_xModelAsManager =
nullptr;
1822 m_xModelAsIndex =
nullptr;
1825 if (m_xModelAsIndex.is())
1828 m_xFormOperations = FormOperations::createWithFormController(
m_xComponentContext,
this );
1829 m_xFormOperations->setFeatureInvalidation(
this );
1832 Reference< XLoadable > xForm(
Model, UNO_QUERY);
1834 xForm->addLoadListener(
this);
1836 Reference< XSQLErrorBroadcaster > xBroadcaster(
Model, UNO_QUERY);
1837 if (xBroadcaster.is())
1838 xBroadcaster->addSQLErrorListener(
this);
1840 Reference< XDatabaseParameterBroadcaster > xParamBroadcaster(
Model, UNO_QUERY);
1841 if (xParamBroadcaster.is())
1842 xParamBroadcaster->addParameterListener(
this);
1846 Reference< XLoadable > xCursor(m_xModelAsIndex, UNO_QUERY);
1847 if (xCursor.is() && xCursor->isLoaded())
1849 EventObject aEvt(xCursor);
1853 Reference< XPropertySet > xModelProps( m_xModelAsIndex, UNO_QUERY );
1854 Reference< XPropertySetInfo > xPropInfo( xModelProps->getPropertySetInfo() );
1862 bool bEnableDynamicControlBorder = lcl_shouldUseDynamicControlBorder(
1864 if ( bEnableDynamicControlBorder )
1865 m_aControlBorderManager.enableDynamicBorderColor();
1867 m_aControlBorderManager.disableDynamicBorderColor();
1886Reference< XTabControllerModel > FormController::getModel()
1888 ::osl::MutexGuard aGuard(
m_aMutex );
1889 impl_checkDisposed_throw();
1891 DBG_ASSERT(m_xTabController.is(),
"FormController::getModel : invalid aggregate !");
1892 if (!m_xTabController.is())
1893 return Reference< XTabControllerModel > ();
1894 return m_xTabController->getModel();
1898void FormController::addToEventAttacher(
const Reference< XControl > & xControl)
1900 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1901 OSL_ENSURE( xControl.is(),
"FormController::addToEventAttacher: invalid control - how did you reach this?" );
1902 if ( !xControl.is() )
1906 Reference< XFormComponent > xComp(xControl->getModel(), UNO_QUERY);
1907 if (!(xComp.is() && m_xModelAsIndex.is()))
1911 sal_uInt32
nPos = m_xModelAsIndex->getCount();
1912 Reference< XFormComponent > xTemp;
1915 m_xModelAsIndex->getByIndex(--
nPos) >>= xTemp;
1916 if (xComp.get() == xTemp.get())
1918 m_xModelAsManager->attach(
nPos, Reference<XInterface>( xControl, UNO_QUERY ),
Any(xControl) );
1925void FormController::removeFromEventAttacher(
const Reference< XControl > & xControl)
1927 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1928 OSL_ENSURE( xControl.is(),
"FormController::removeFromEventAttacher: invalid control - how did you reach this?" );
1929 if ( !xControl.is() )
1933 Reference< XFormComponent > xComp(xControl->getModel(), UNO_QUERY);
1934 if ( !(xComp.is() && m_xModelAsIndex.is()) )
1938 sal_uInt32
nPos = m_xModelAsIndex->getCount();
1939 Reference< XFormComponent > xTemp;
1942 m_xModelAsIndex->getByIndex(--
nPos) >>= xTemp;
1943 if (xComp.get() == xTemp.get())
1945 m_xModelAsManager->detach(
nPos, Reference<XInterface>( xControl, UNO_QUERY ) );
1952void FormController::setContainer(
const Reference< XControlContainer > & xContainer)
1954 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
1955 Reference< XTabControllerModel > xTabModel(getModel());
1956 DBG_ASSERT(xTabModel.is() || !xContainer.is(),
"No Model defined");
1958 DBG_ASSERT(m_xTabController.is(),
"FormController::setContainer : invalid aggregate !");
1960 ::osl::MutexGuard aGuard(
m_aMutex );
1961 Reference< XContainer > xCurrentContainer;
1962 if (m_xTabController.is())
1963 xCurrentContainer.set(m_xTabController->getContainer(), UNO_QUERY);
1964 if (xCurrentContainer.is())
1966 xCurrentContainer->removeContainerListener(
this);
1968 if ( m_aTabActivationIdle.IsActive() )
1969 m_aTabActivationIdle.Stop();
1972 ::std::for_each( m_aFilterComponents.begin(), m_aFilterComponents.end(), RemoveComponentTextListener(
this ) );
1973 m_aFilterComponents.clear();
1976 for (
const Reference< XControl >& rControl : std::as_const(m_aControls) )
1977 implControlRemoved( rControl,
true );
1980 if (m_bDBConnection && isListeningForChanges())
1983 m_aControls.realloc( 0 );
1986 if (m_xTabController.is())
1987 m_xTabController->setContainer(xContainer);
1990 if (xContainer.is() && xTabModel.is())
1992 const Sequence< Reference< XControlModel > > aModels = xTabModel->getControlModels();
1993 Sequence< Reference< XControl > > aAllControls = xContainer->getControls();
1995 sal_Int32
nCount = aModels.getLength();
1996 m_aControls = Sequence< Reference< XControl > >(
nCount );
1997 Reference< XControl > * pControls = m_aControls.getArray();
2001 for (
const Reference< XControlModel >& rModel : aModels )
2003 Reference< XControl > xControl = findControl( aAllControls, rModel,
false,
true );
2004 if ( xControl.is() )
2006 pControls[j++] = xControl;
2007 implControlInserted( xControl,
true );
2013 m_aControls.realloc(j);
2016 Reference< XContainer > xNewContainer(xContainer, UNO_QUERY);
2017 if (xNewContainer.is())
2018 xNewContainer->addContainerListener(
this);
2021 if (m_bDBConnection)
2023 m_bLocked = determineLockState();
2030 m_bControlsSorted =
true;
2034Reference< XControlContainer > FormController::getContainer()
2036 ::osl::MutexGuard aGuard(
m_aMutex );
2037 impl_checkDisposed_throw();
2039 DBG_ASSERT(m_xTabController.is(),
"FormController::getContainer : invalid aggregate !");
2040 if (!m_xTabController.is())
2041 return Reference< XControlContainer > ();
2042 return m_xTabController->getContainer();
2046Sequence< Reference< XControl > > FormController::getControls()
2048 ::osl::MutexGuard aGuard(
m_aMutex );
2049 impl_checkDisposed_throw();
2051 if (!m_bControlsSorted)
2053 Reference< XTabControllerModel >
xModel = getModel();
2057 const Sequence< Reference< XControlModel > > aControlModels =
xModel->getControlModels();
2058 sal_Int32 nModels = aControlModels.getLength();
2060 Sequence< Reference< XControl > > aNewControls(nModels);
2062 Reference< XControl > * pControls = aNewControls.getArray();
2063 Reference< XControl > xControl;
2067 for (
const Reference< XControlModel >& rModel : aControlModels )
2069 xControl = findControl( m_aControls, rModel,
true,
true );
2070 if ( xControl.is() )
2071 pControls[j++] = xControl;
2076 aNewControls.realloc( j );
2078 m_aControls = aNewControls;
2079 m_bControlsSorted =
true;
2085void FormController::autoTabOrder()
2087 ::osl::MutexGuard aGuard(
m_aMutex );
2088 impl_checkDisposed_throw();
2090 DBG_ASSERT(m_xTabController.is(),
"FormController::autoTabOrder : invalid aggregate !");
2091 if (m_xTabController.is())
2092 m_xTabController->autoTabOrder();
2096void FormController::activateTabOrder()
2098 ::osl::MutexGuard aGuard(
m_aMutex );
2099 impl_checkDisposed_throw();
2101 DBG_ASSERT(m_xTabController.is(),
"FormController::activateTabOrder : invalid aggregate !");
2102 if (m_xTabController.is())
2103 m_xTabController->activateTabOrder();
2107void FormController::setControlLock(
const Reference< XControl > & xControl)
2109 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2110 bool bLocked = isLocked();
2115 Reference< XBoundControl > xBound(xControl, UNO_QUERY);
2116 if (!(xBound.is() &&
2117 ( (bLocked && bLocked !=
bool(xBound->getLock())) ||
2122 Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
2129 bTouch = ::comphelper::getBOOL(xSet->getPropertyValue(
FM_PROP_ENABLED));
2136 Reference< XPropertySet > xField;
2142 xBound->setLock(bLocked);
2148 if (aVal.hasValue() && ::comphelper::getBOOL(aVal))
2149 xBound->setLock(
true);
2151 xBound->setLock(bLocked);
2162void FormController::setLocks()
2164 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2166 for (
const Reference< XControl >& rControl : std::as_const(m_aControls) )
2167 setControlLock( rControl );
2173 bool lcl_shouldListenForModifications(
const Reference< XControl >& _rxControl,
const Reference< XPropertyChangeListener >& _rxBoundFieldListener )
2175 bool bShould =
false;
2177 Reference< XBoundComponent > xBound( _rxControl, UNO_QUERY );
2182 else if ( _rxControl.is() )
2184 Reference< XPropertySet > xModelProps( _rxControl->getModel(), UNO_QUERY );
2185 if ( xModelProps.is() && ::comphelper::hasProperty(
FM_PROP_BOUNDFIELD, xModelProps ) )
2187 Reference< XPropertySet > xField;
2189 bShould = xField.is();
2191 if ( !bShould && _rxBoundFieldListener.is() )
2201void FormController::startControlModifyListening(
const Reference< XControl > & xControl)
2203 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2205 bool bModifyListening = lcl_shouldListenForModifications( xControl,
this );
2208 while ( bModifyListening )
2210 Reference< XModifyBroadcaster > xMod(xControl, UNO_QUERY);
2213 xMod->addModifyListener(
this);
2218 Reference< XTextComponent > xText(xControl, UNO_QUERY);
2221 xText->addTextListener(
this);
2225 Reference< XCheckBox > xBox(xControl, UNO_QUERY);
2228 xBox->addItemListener(
this);
2232 Reference< XComboBox > xCbBox(xControl, UNO_QUERY);
2235 xCbBox->addItemListener(
this);
2239 Reference< XListBox > xListBox(xControl, UNO_QUERY);
2242 xListBox->addItemListener(
this);
2250void FormController::stopControlModifyListening(
const Reference< XControl > & xControl)
2252 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2254 bool bModifyListening = lcl_shouldListenForModifications( xControl,
nullptr );
2257 while (bModifyListening)
2259 Reference< XModifyBroadcaster > xMod(xControl, UNO_QUERY);
2262 xMod->removeModifyListener(
this);
2266 Reference< XTextComponent > xText(xControl, UNO_QUERY);
2269 xText->removeTextListener(
this);
2273 Reference< XCheckBox > xBox(xControl, UNO_QUERY);
2276 xBox->removeItemListener(
this);
2280 Reference< XComboBox > xCbBox(xControl, UNO_QUERY);
2283 xCbBox->removeItemListener(
this);
2287 Reference< XListBox > xListBox(xControl, UNO_QUERY);
2290 xListBox->removeItemListener(
this);
2298void FormController::startListening()
2300 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2301 m_bModified =
false;
2304 for (
const Reference< XControl >& rControl : std::as_const(m_aControls) )
2305 startControlModifyListening( rControl );
2309void FormController::stopListening()
2311 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2312 m_bModified =
false;
2315 for (
const Reference< XControl >& rControl : std::as_const(m_aControls) )
2316 stopControlModifyListening( rControl );
2320Reference< XControl > FormController::findControl(Sequence< Reference< XControl > >& _rControls,
const Reference< XControlModel > & xCtrlModel ,
bool _bRemove,
bool _bOverWrite)
const
2322 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2323 DBG_ASSERT( xCtrlModel.is(),
"findControl - which ?!" );
2325 const Reference< XControl >* pControls = std::find_if(std::cbegin(_rControls), std::cend(_rControls),
2326 [&xCtrlModel](
const Reference< XControl >& rControl) {
2327 return rControl.is() && rControl->getModel().get() == xCtrlModel.get(); });
2328 if (pControls != std::cend(_rControls))
2330 Reference< XControl > xControl( *pControls );
2331 auto i =
static_cast<sal_Int32
>(std::distance(std::cbegin(_rControls), pControls));
2333 ::comphelper::removeElementAt( _rControls,
i );
2334 else if ( _bOverWrite )
2335 _rControls.getArray()[
i].clear();
2338 return Reference< XControl > ();
2342void FormController::implControlInserted(
const Reference< XControl>& _rxControl,
bool _bAddToEventAttacher )
2344 Reference< XWindow > xWindow( _rxControl, UNO_QUERY );
2347 xWindow->addFocusListener(
this );
2348 xWindow->addMouseListener(
this );
2350 if ( _bAddToEventAttacher )
2351 addToEventAttacher( _rxControl );
2355 Reference< XDispatchProviderInterception > xInterception( _rxControl, UNO_QUERY );
2356 if ( xInterception.is() )
2357 createInterceptor( xInterception );
2359 if ( !_rxControl.is() )
2362 Reference< XControlModel >
xModel( _rxControl->getModel() );
2366 Reference< XReset > xReset(
xModel, UNO_QUERY );
2368 xReset->addResetListener(
this );
2371 Reference< XValidatableFormComponent > xValidatable(
xModel, UNO_QUERY );
2372 if ( xValidatable.is() )
2374 xValidatable->addFormComponentValidityListener(
this );
2375 m_aControlBorderManager.validityChanged( _rxControl, xValidatable );
2381void FormController::implControlRemoved(
const Reference< XControl>& _rxControl,
bool _bRemoveFromEventAttacher )
2383 Reference< XWindow > xWindow( _rxControl, UNO_QUERY );
2386 xWindow->removeFocusListener(
this );
2387 xWindow->removeMouseListener(
this );
2389 if ( _bRemoveFromEventAttacher )
2390 removeFromEventAttacher( _rxControl );
2393 Reference< XDispatchProviderInterception > xInterception( _rxControl, UNO_QUERY);
2394 if ( xInterception.is() )
2395 deleteInterceptor( xInterception );
2397 if ( _rxControl.is() )
2399 Reference< XControlModel >
xModel( _rxControl->getModel() );
2401 Reference< XReset > xReset(
xModel, UNO_QUERY );
2403 xReset->removeResetListener(
this );
2405 Reference< XValidatableFormComponent > xValidatable(
xModel, UNO_QUERY );
2406 if ( xValidatable.is() )
2407 xValidatable->removeFormComponentValidityListener(
this );
2412void FormController::implSetCurrentControl(
const Reference< XControl >& _rxControl )
2414 if ( m_xCurrentControl.get() == _rxControl.get() )
2417 Reference< XGridControl > xGridControl( m_xCurrentControl, UNO_QUERY );
2418 if ( xGridControl.is() )
2419 xGridControl->removeGridControlListener(
this );
2421 m_xCurrentControl = _rxControl;
2423 xGridControl.set( m_xCurrentControl, UNO_QUERY );
2424 if ( xGridControl.is() )
2425 xGridControl->addGridControlListener(
this );
2429void FormController::insertControl(
const Reference< XControl > & xControl)
2431 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2432 m_bControlsSorted =
false;
2433 m_aControls.realloc(m_aControls.getLength() + 1);
2434 m_aControls.getArray()[m_aControls.getLength() - 1] = xControl;
2436 if (m_pColumnInfoCache)
2437 m_pColumnInfoCache->deinitializeControls();
2439 implControlInserted( xControl, m_bAttachEvents );
2441 if (m_bDBConnection && !m_bFiltering)
2442 setControlLock(xControl);
2444 if (isListeningForChanges() && m_bAttachEvents)
2445 startControlModifyListening( xControl );
2449void FormController::removeControl(
const Reference< XControl > & xControl)
2451 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2452 auto pControl = std::find_if(std::cbegin(m_aControls), std::cend(m_aControls),
2453 [&xControl](
const Reference< XControl >& rControl) {
return xControl.get() == rControl.get(); });
2454 if (pControl != std::cend(m_aControls))
2456 auto nIndex =
static_cast<sal_Int32
>(std::distance(std::cbegin(m_aControls), pControl));
2457 ::comphelper::removeElementAt( m_aControls,
nIndex );
2460 FilterComponents::iterator componentPos = ::std::find( m_aFilterComponents.begin(), m_aFilterComponents.end(), xControl );
2461 if ( componentPos != m_aFilterComponents.end() )
2462 m_aFilterComponents.erase( componentPos );
2464 implControlRemoved( xControl, m_bDetachEvents );
2466 if ( isListeningForChanges() && m_bDetachEvents )
2467 stopControlModifyListening( xControl );
2472void FormController::loaded(
const EventObject& rEvent)
2474 OSL_ENSURE( rEvent.Source == m_xModelAsIndex,
"FormController::loaded: where did this come from?" );
2476 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2477 ::osl::MutexGuard aGuard(
m_aMutex );
2478 Reference< XRowSet > xForm(rEvent.Source, UNO_QUERY);
2482 Reference< XPropertySet > xSet(xForm, UNO_QUERY);
2486 sal_Int32 aVal2 = 0;
2487 ::cppu::enum2int(aVal2,aVal);
2488 m_bCycle = !aVal.hasValue() ||
static_cast<form::TabulatorCycle
>(aVal2) == TabulatorCycle_RECORDS;
2491 m_bCurrentRecordModified = ::comphelper::getBOOL(xSet->getPropertyValue(
FM_PROP_ISMODIFIED));
2492 m_bCurrentRecordNew = ::comphelper::getBOOL(xSet->getPropertyValue(
FM_PROP_ISNEW));
2494 startFormListening( xSet,
false );
2497 if (getContainer().is())
2499 m_aLoadEvent.Call();
2504 m_bCanInsert = m_bCanUpdate = m_bCycle =
false;
2505 m_bCurrentRecordModified =
false;
2506 m_bCurrentRecordNew =
false;
2509 m_bDBConnection =
true;
2513 m_bDBConnection =
false;
2514 m_bCanInsert = m_bCanUpdate = m_bCycle =
false;
2515 m_bCurrentRecordModified =
false;
2516 m_bCurrentRecordNew =
false;
2520 Reference< XColumnsSupplier > xFormColumns( xForm, UNO_QUERY );
2521 m_pColumnInfoCache.reset( xFormColumns.is() ?
new ColumnInfoCache( xFormColumns ) :
nullptr );
2523 updateAllDispatchers();
2527void FormController::updateAllDispatchers()
const
2530 m_aFeatureDispatchers.begin(),
2531 m_aFeatureDispatchers.end(),
2532 [] (
const DispatcherContainer::value_type& dispatcher) {
2533 UpdateAllListeners()(dispatcher.second);
2540 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2541 m_bLocked = determineLockState();
2549 if (m_bCurrentRecordNew)
2550 toggleAutoFields(
true);
2554void FormController::unloaded(
const EventObject& )
2556 ::osl::MutexGuard aGuard(
m_aMutex );
2557 impl_checkDisposed_throw();
2559 updateAllDispatchers();
2563void FormController::reloading(
const EventObject& )
2565 ::osl::MutexGuard aGuard(
m_aMutex );
2566 impl_checkDisposed_throw();
2570 m_aToggleEvent.CancelPendingCall();
2575void FormController::reloaded(
const EventObject& aEvent)
2577 ::osl::MutexGuard aGuard(
m_aMutex );
2578 impl_checkDisposed_throw();
2584void FormController::unloading(
const EventObject& )
2586 ::osl::MutexGuard aGuard(
m_aMutex );
2587 impl_checkDisposed_throw();
2593void FormController::unload()
2595 ::osl::MutexGuard aGuard(
m_aMutex );
2596 impl_checkDisposed_throw();
2598 m_aLoadEvent.CancelPendingCall();
2601 if (m_bCurrentRecordNew)
2602 toggleAutoFields(
false);
2605 removeBoundFieldListener();
2607 if (m_bDBConnection && isListeningForChanges())
2610 Reference< XPropertySet > xSet( m_xModelAsIndex, UNO_QUERY );
2611 if ( m_bDBConnection && xSet.is() )
2612 stopFormListening( xSet,
false );
2614 m_bDBConnection =
false;
2615 m_bCanInsert = m_bCanUpdate = m_bCycle =
false;
2616 m_bCurrentRecordModified = m_bCurrentRecordNew = m_bLocked =
false;
2618 m_pColumnInfoCache.reset();
2622void FormController::removeBoundFieldListener()
2624 for (
const Reference< XControl >& rControl : std::as_const(m_aControls) )
2626 Reference< XPropertySet > xProp( rControl, UNO_QUERY );
2633void FormController::startFormListening(
const Reference< XPropertySet >& _rxForm,
bool _bPropertiesOnly )
2637 if ( m_bCanInsert || m_bCanUpdate )
2642 if ( !_bPropertiesOnly )
2645 Reference< XRowSetApproveBroadcaster > xApprove( _rxForm, UNO_QUERY );
2646 if ( xApprove.is() )
2647 xApprove->addRowSetApproveListener(
this );
2650 Reference< XRowSet > xRowSet( _rxForm, UNO_QUERY );
2652 xRowSet->addRowSetListener(
this );
2656 Reference< XPropertySetInfo > xInfo = _rxForm->getPropertySetInfo();
2667void FormController::stopFormListening(
const Reference< XPropertySet >& _rxForm,
bool _bPropertiesOnly )
2671 if ( m_bCanInsert || m_bCanUpdate )
2673 _rxForm->removePropertyChangeListener(
FM_PROP_ISNEW,
this );
2676 if ( !_bPropertiesOnly )
2678 Reference< XRowSetApproveBroadcaster > xApprove( _rxForm, UNO_QUERY );
2680 xApprove->removeRowSetApproveListener(
this);
2682 Reference< XRowSet > xRowSet( _rxForm, UNO_QUERY );
2684 xRowSet->removeRowSetListener(
this );
2688 Reference< XPropertySetInfo > xInfo = _rxForm->getPropertySetInfo();
2700void FormController::cursorMoved(
const EventObject& )
2702 ::osl::MutexGuard aGuard(
m_aMutex );
2703 impl_checkDisposed_throw();
2706 if (m_bLocked != determineLockState())
2708 m_bLocked = !m_bLocked;
2710 if (isListeningForChanges())
2717 m_bCurrentRecordModified = m_bModified =
false;
2721void FormController::rowChanged(
const EventObject& )
2726void FormController::rowSetChanged(
const EventObject& )
2734void SAL_CALL FormController::elementInserted(
const ContainerEvent& evt)
2736 ::osl::MutexGuard aGuard(
m_aMutex );
2737 impl_checkDisposed_throw();
2739 Reference< XControl > xControl( evt.Element, UNO_QUERY );
2740 if ( !xControl.is() )
2743 Reference< XFormComponent >
xModel(xControl->getModel(), UNO_QUERY);
2744 if (
xModel.is() && m_xModelAsIndex ==
xModel->getParent())
2746 insertControl(xControl);
2748 if ( m_aTabActivationIdle.IsActive() )
2749 m_aTabActivationIdle.Stop();
2751 m_aTabActivationIdle.Start();
2754 else if (m_bFiltering && Reference< XModeSelector > (evt.Source, UNO_QUERY).is())
2756 xModel.set(evt.Source, UNO_QUERY);
2757 if (
xModel.is() && m_xModelAsIndex ==
xModel->getParent())
2759 Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
2763 Reference< XPropertySet > xField;
2766 Reference< XTextComponent > xText(xControl, UNO_QUERY);
2768 if (xText.is() && xField.is() && ::comphelper::hasProperty(
FM_PROP_SEARCHABLE, xField) &&
2771 m_aFilterComponents.push_back( xText );
2772 xText->addTextListener(
this );
2780void SAL_CALL FormController::elementReplaced(
const ContainerEvent& evt)
2783 ContainerEvent aRemoveEvent( evt );
2784 aRemoveEvent.Element = evt.ReplacedElement;
2785 aRemoveEvent.ReplacedElement =
Any();
2789 ContainerEvent aInsertEvent( evt );
2790 aInsertEvent.ReplacedElement =
Any();
2795void SAL_CALL FormController::elementRemoved(
const ContainerEvent& evt)
2797 ::osl::MutexGuard aGuard(
m_aMutex );
2798 impl_checkDisposed_throw();
2800 Reference< XControl > xControl;
2801 evt.Element >>= xControl;
2805 Reference< XFormComponent >
xModel(xControl->getModel(), UNO_QUERY);
2806 if (
xModel.is() && m_xModelAsIndex ==
xModel->getParent())
2808 removeControl(xControl);
2812 else if (m_bFiltering && Reference< XModeSelector > (evt.Source, UNO_QUERY).is())
2814 FilterComponents::iterator componentPos = ::std::find(
2815 m_aFilterComponents.begin(), m_aFilterComponents.end(), xControl );
2816 if ( componentPos != m_aFilterComponents.end() )
2817 m_aFilterComponents.erase( componentPos );
2822Reference< XControl > FormController::isInList(
const Reference< XWindowPeer > & xPeer)
const
2824 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2825 const Reference< XControl >* pControls = m_aControls.getConstArray();
2827 sal_uInt32 nCtrls = m_aControls.getLength();
2828 for ( sal_uInt32
n = 0;
n < nCtrls && xPeer.is(); ++
n, ++pControls )
2830 if ( pControls->is() )
2832 Reference< XVclWindowPeer > xCtrlPeer( (*pControls)->getPeer(), UNO_QUERY);
2833 if ( ( xCtrlPeer.get() == xPeer.get() ) || xCtrlPeer->isChild( xPeer ) )
2837 return Reference< XControl > ();
2841void FormController::activateFirst()
2843 ::osl::MutexGuard aGuard(
m_aMutex );
2844 impl_checkDisposed_throw();
2846 DBG_ASSERT(m_xTabController.is(),
"FormController::activateFirst : invalid aggregate !");
2847 if (m_xTabController.is())
2848 m_xTabController->activateFirst();
2852void FormController::activateLast()
2854 ::osl::MutexGuard aGuard(
m_aMutex );
2855 impl_checkDisposed_throw();
2857 DBG_ASSERT(m_xTabController.is(),
"FormController::activateLast : invalid aggregate !");
2858 if (m_xTabController.is())
2859 m_xTabController->activateLast();
2864Reference< XFormOperations > SAL_CALL FormController::getFormOperations()
2866 ::osl::MutexGuard aGuard(
m_aMutex );
2867 impl_checkDisposed_throw();
2869 return m_xFormOperations;
2873Reference< XControl> SAL_CALL FormController::getCurrentControl()
2875 ::osl::MutexGuard aGuard(
m_aMutex );
2876 impl_checkDisposed_throw();
2877 return m_xCurrentControl;
2881void SAL_CALL FormController::addActivateListener(
const Reference< XFormControllerListener > & l)
2883 ::osl::MutexGuard aGuard(
m_aMutex );
2884 impl_checkDisposed_throw();
2885 m_aActivateListeners.addInterface(l);
2888void SAL_CALL FormController::removeActivateListener(
const Reference< XFormControllerListener > & l)
2890 ::osl::MutexGuard aGuard(
m_aMutex );
2891 impl_checkDisposed_throw();
2892 m_aActivateListeners.removeInterface(l);
2896void SAL_CALL FormController::addChildController(
const Reference< XFormController >& ChildController )
2898 ::osl::MutexGuard aGuard(
m_aMutex );
2899 impl_checkDisposed_throw();
2901 if ( !ChildController.is() )
2902 throw IllegalArgumentException( OUString(), *
this, 1 );
2906 Reference< XFormComponent > xFormOfChild( ChildController->getModel(), UNO_QUERY );
2907 if ( !xFormOfChild.is() )
2908 throw IllegalArgumentException( OUString(), *
this, 1 );
2911 if ( xFormOfChild->getParent() != m_xModelAsIndex )
2912 throw IllegalArgumentException( OUString(), *
this, 1 );
2915 m_aChildren.push_back( ChildController );
2916 ChildController->setParent( *
this );
2919 sal_uInt32
nPos = m_xModelAsIndex->getCount();
2920 Reference< XFormComponent > xTemp;
2923 m_xModelAsIndex->getByIndex(--
nPos) >>= xTemp;
2924 if ( xFormOfChild == xTemp )
2926 m_xModelAsManager->attach(
nPos, Reference<XInterface>( ChildController, UNO_QUERY ),
Any( ChildController) );
2933Reference< XFormControllerContext > SAL_CALL FormController::getContext()
2935 ::osl::MutexGuard aGuard(
m_aMutex );
2936 impl_checkDisposed_throw();
2937 return m_xFormControllerContext;
2941void SAL_CALL FormController::setContext(
const Reference< XFormControllerContext >& _context )
2943 ::osl::MutexGuard aGuard(
m_aMutex );
2944 impl_checkDisposed_throw();
2945 m_xFormControllerContext = _context;
2949Reference< XInteractionHandler > SAL_CALL FormController::getInteractionHandler()
2951 ::osl::MutexGuard aGuard(
m_aMutex );
2952 impl_checkDisposed_throw();
2957void SAL_CALL FormController::setInteractionHandler(
const Reference< XInteractionHandler >& _interactionHandler )
2959 ::osl::MutexGuard aGuard(
m_aMutex );
2960 impl_checkDisposed_throw();
2965void FormController::setFilter(::std::vector<FmFieldInfo>& rFieldInfos)
2967 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
2969 Reference< XRowSet > xForm(m_xModelAsIndex, UNO_QUERY);
2975 Reference< XMultiServiceFactory >
xFactory( xConnection, UNO_QUERY_THROW );
2977 xFactory->createInstance(
"com.sun.star.sdb.SingleSelectQueryComposer"),
2980 Reference< XPropertySet > xSet( xForm, UNO_QUERY );
2982 OUString sFilter = ::comphelper::getString( xSet->getPropertyValue(
FM_PROP_FILTER ) );
2983 m_xComposer->setElementaryQuery( sStatement );
2984 m_xComposer->setFilter( sFilter );
2992 if (m_xComposer.is())
2994 const Sequence< Sequence < PropertyValue > > aFilterRows = m_xComposer->getStructuredFilter();
3001 Reference< XNameAccess > xQueryColumns =
3002 Reference< XColumnsSupplier >( m_xComposer, UNO_QUERY_THROW )->getColumns();
3004 for (
auto& rFieldInfo : rFieldInfos)
3006 if ( xQueryColumns->hasByName(rFieldInfo.aFieldName) )
3008 if ( (xQueryColumns->getByName(rFieldInfo.aFieldName) >>= rFieldInfo.xField) && rFieldInfo.xField.is() )
3009 rFieldInfo.xField->getPropertyValue(
FM_PROP_REALNAME) >>= rFieldInfo.aFieldName;
3013 Reference< XDatabaseMetaData> xMetaData(xConnection->getMetaData());
3018 Reference< XNumberFormatsSupplier> xFormatSupplier(
getNumberFormats(xConnection,
true));
3020 xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
3026 for (
const Sequence < PropertyValue >& rRow : aFilterRows)
3031 for (
const PropertyValue& rRefValue : rRow)
3034 Reference< XPropertySet > xField;
3037 Reference< XPropertySet > xSet;
3041 if (xQueryColumns->hasByName(rRefValue.Name))
3043 xQueryColumns->getByName(rRefValue.Name) >>= xSet;
3046 xSet->getPropertyValue(
"RealName") >>= aRealName;
3049 if (aCompare(aRealName, rRefValue.Name))
3055 Reference< XIndexAccess > xColumnsByIndex(xQueryColumns, UNO_QUERY);
3056 for (sal_Int32
n = 0,
nCount = xColumnsByIndex->getCount();
n <
nCount;
n++)
3058 xColumnsByIndex->getByIndex(
n) >>= xSet;
3059 xSet->getPropertyValue(
"RealName") >>= aRealName;
3060 if (aCompare(aRealName, rRefValue.Name))
3077 for (
const auto& rFieldInfo : rFieldInfos)
3080 if (rFieldInfo.xField == xField)
3083 if (aRow.find(rFieldInfo.xText) != aRow.end())
3085 OString aVal = m_pParser->getContext().getIntlKeywordAscii(IParseContext::InternationalKeyCode::And);
3086 OUString aCompText = aRow[rFieldInfo.xText] +
" " +
3087 OUString(aVal.getStr(),aVal.getLength(),RTL_TEXTENCODING_ASCII_US) +
" " +
3088 ::comphelper::getString(rRefValue.Value);
3089 aRow[rFieldInfo.xText] = aCompText;
3093 OUString sPredicate,sErrorMsg;
3094 rRefValue.Value >>= sPredicate;
3095 std::unique_ptr< OSQLParseNode > pParseNode = predicateTree(sErrorMsg, sPredicate, xFormatter, xField);
3096 if ( pParseNode !=
nullptr )
3099 switch (rRefValue.Handle)
3101 case css::sdb::SQLFilterOperator::EQUAL:
3104 case css::sdb::SQLFilterOperator::NOT_EQUAL:
3107 case css::sdb::SQLFilterOperator::LESS:
3110 case css::sdb::SQLFilterOperator::GREATER:
3113 case css::sdb::SQLFilterOperator::LESS_EQUAL:
3116 case css::sdb::SQLFilterOperator::GREATER_EQUAL:
3119 case css::sdb::SQLFilterOperator::LIKE:
3120 sCriteria +=
"LIKE ";
3122 case css::sdb::SQLFilterOperator::NOT_LIKE:
3123 sCriteria +=
"NOT LIKE ";
3125 case css::sdb::SQLFilterOperator::SQLNULL:
3126 sCriteria +=
"IS NULL";
3128 case css::sdb::SQLFilterOperator::NOT_SQLNULL:
3129 sCriteria +=
"IS NOT NULL";
3132 pParseNode->parseNodeToPredicateStr( sCriteria
3138 ,strDecimalSeparator
3139 ,getParseContext());
3140 aRow[rFieldInfo.xText] = sCriteria;
3150 impl_addFilterRow( aRow );
3155 for (
const auto& rFieldInfo : rFieldInfos)
3157 m_aFilterComponents.push_back( rFieldInfo.xText );
3162void FormController::startFiltering()
3164 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
3166 Reference< XConnection > xConnection(
getConnection( Reference< XRowSet >( m_xModelAsIndex, UNO_QUERY ) ) );
3167 if ( !xConnection.is() )
3172 if (isListeningForChanges())
3175 m_bFiltering =
true;
3179 m_bAttachEvents =
false;
3182 Sequence< Reference< XControl > > aControlsCopy( m_aControls );
3183 const Reference< XControl >* pControls = aControlsCopy.getConstArray();
3184 sal_Int32 nControlCount = aControlsCopy.getLength();
3187 Reference< XNumberFormatsSupplier > xFormatSupplier =
getNumberFormats(xConnection,
true);
3189 xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
3192 ::std::vector<FmFieldInfo> aFieldInfos;
3194 for (sal_Int32
i = nControlCount;
i > 0;)
3196 Reference< XControl > xControl = pControls[--
i];
3200 removeFromEventAttacher(xControl);
3203 Reference< XModeSelector > xSelector(xControl, UNO_QUERY);
3206 xSelector->setMode(
"FilterMode" );
3209 Reference< XContainer > xContainer(xSelector, UNO_QUERY);
3210 if (xContainer.is())
3211 xContainer->addContainerListener(
this);
3213 Reference< XEnumerationAccess > xElementAccess(xSelector, UNO_QUERY);
3214 if (xElementAccess.is())
3216 Reference< XEnumeration > xEnumeration(xElementAccess->createEnumeration());
3217 Reference< XControl > xSubControl;
3218 while (xEnumeration->hasMoreElements())
3220 xEnumeration->nextElement() >>= xSubControl;
3221 if (xSubControl.is())
3223 Reference< XPropertySet > xSet(xSubControl->getModel(), UNO_QUERY);
3227 Reference< XPropertySet > xField;
3230 Reference< XTextComponent > xText(xSubControl, UNO_QUERY);
3232 if (xText.is() && xField.is() && ::comphelper::hasProperty(
FM_PROP_SEARCHABLE, xField) &&
3235 aFieldInfos.emplace_back(xField, xText);
3236 xText->addTextListener(
this);
3245 Reference< XPropertySet >
xModel( xControl->getModel(), UNO_QUERY );
3250 Reference< XPropertySet > xField;
3261 Reference< XControl > xFilterControl = form::control::FilterControl::createWithFormat(
3263 getDialogParentWindow(
this),
3267 if ( replaceControl( xControl, xFilterControl ) )
3269 Reference< XTextComponent > xFilterText( xFilterControl, UNO_QUERY );
3270 aFieldInfos.emplace_back( xField, xFilterText );
3271 xFilterText->addTextListener(
this);
3284 setFilter(aFieldInfos);
3286 Reference< XPropertySet > xSet( m_xModelAsIndex, UNO_QUERY );
3288 stopFormListening( xSet,
true );
3290 impl_setTextOnAllFilter_throw();
3293 m_bLocked = determineLockState();
3295 m_bAttachEvents =
true;
3299void FormController::stopFiltering()
3301 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
3302 if ( !m_bFiltering )
3307 m_bFiltering =
false;
3308 m_bDetachEvents =
false;
3310 ::comphelper::disposeComponent(m_xComposer);
3313 Sequence< Reference< XControl > > aControlsCopy( m_aControls );
3314 const Reference< XControl > * pControls = aControlsCopy.getConstArray();
3315 sal_Int32 nControlCount = aControlsCopy.getLength();
3318 ::std::for_each( m_aFilterComponents.begin(), m_aFilterComponents.end(), RemoveComponentTextListener(
this ) );
3319 m_aFilterComponents.clear();
3321 for ( sal_Int32
i = nControlCount;
i > 0; )
3323 Reference< XControl > xControl = pControls[--
i];
3327 addToEventAttacher(xControl);
3329 Reference< XModeSelector > xSelector(xControl, UNO_QUERY);
3332 xSelector->setMode(
"DataMode" );
3335 Reference< XContainer > xContainer(xSelector, UNO_QUERY);
3336 if (xContainer.is())
3337 xContainer->removeContainerListener(
this);
3341 Reference< XPropertySet > xSet(xControl->getModel(), UNO_QUERY);
3345 Reference< XPropertySet > xField;
3357 replaceControl( xControl, xNewControl );
3363 Reference< XPropertySet > xSet( m_xModelAsIndex, UNO_QUERY );
3365 startFormListening( xSet,
true );
3367 m_bDetachEvents =
true;
3369 m_aFilterRows.clear();
3370 m_nCurrentFilterPosition = -1;
3374 m_bLocked = determineLockState();
3378 if (isListeningForChanges())
3384void FormController::setMode(
const OUString&
Mode)
3386 ::osl::MutexGuard aGuard(
m_aMutex );
3387 impl_checkDisposed_throw();
3389 if (!supportsMode(
Mode))
3390 throw NoSupportException();
3392 if (
Mode == m_aMode)
3397 if (
Mode ==
"FilterMode" )
3402 for (
const auto& rChild : m_aChildren)
3404 Reference< XModeSelector > xMode(rChild, UNO_QUERY);
3406 xMode->setMode(
Mode);
3411OUString SAL_CALL FormController::getMode()
3413 ::osl::MutexGuard aGuard(
m_aMutex );
3414 impl_checkDisposed_throw();
3420Sequence< OUString > SAL_CALL FormController::getSupportedModes()
3422 ::osl::MutexGuard aGuard(
m_aMutex );
3423 impl_checkDisposed_throw();
3425 static Sequence< OUString >
const aModes
3435 ::osl::MutexGuard aGuard(
m_aMutex );
3436 impl_checkDisposed_throw();
3438 Sequence< OUString > aModes(getSupportedModes());
3442css::uno::Reference<css::awt::XWindow> FormController::getDialogParentWindow(css::uno::Reference<css::form::runtime::XFormController> xFormController)
3446 Reference< XControl > xContainerControl( xFormController->getContainer(), UNO_QUERY_THROW );
3447 Reference<XWindow> xContainerWindow(xContainerControl->getPeer(), UNO_QUERY_THROW);
3448 return xContainerWindow;
3457bool FormController::checkFormComponentValidity( OUString& _rFirstInvalidityExplanation, Reference< XControlModel >& _rxFirstInvalidModel )
3461 Reference< XEnumerationAccess > xControlEnumAcc( getModel(), UNO_QUERY );
3462 Reference< XEnumeration > xControlEnumeration;
3463 if ( xControlEnumAcc.is() )
3464 xControlEnumeration = xControlEnumAcc->createEnumeration();
3465 OSL_ENSURE( xControlEnumeration.is(),
"FormController::checkFormComponentValidity: cannot enumerate the controls!" );
3466 if ( !xControlEnumeration.is() )
3470 Reference< XValidatableFormComponent > xValidatable;
3471 while ( xControlEnumeration->hasMoreElements() )
3473 if ( !( xControlEnumeration->nextElement() >>= xValidatable ) )
3477 if ( xValidatable->isValid() )
3480 Reference< XValidator > xValidator( xValidatable->getValidator() );
3481 OSL_ENSURE( xValidator.is(),
"FormController::checkFormComponentValidity: invalid, but no validator?" );
3482 if ( !xValidator.is() )
3486 _rFirstInvalidityExplanation = xValidator->explainInvalid( xValidatable->getCurrentValue() );
3487 _rxFirstInvalidModel.set(xValidatable, css::uno::UNO_QUERY);
3499Reference< XControl > FormController::locateControl(
const Reference< XControlModel >& _rxModel )
3503 const Sequence< Reference< XControl > > aControls( getControls() );
3505 for (
auto const & control : aControls )
3507 OSL_ENSURE( control.is(),
"FormController::locateControl: NULL-control?" );
3510 if ( control->getModel() == _rxModel )
3514 OSL_FAIL(
"FormController::locateControl: did not find a control for this model!" );
3526 void displayErrorSetFocus(
const OUString& _rMessage,
const Reference<XControl>& _rxFocusControl,
3527 const css::uno::Reference<css::awt::XWindow>& rDialogParent)
3530 aError.Message =
SvxResId(RID_STR_WRITEERROR);
3531 aError.Details = _rMessage;
3534 if ( _rxFocusControl.is() )
3536 Reference< XWindow > xControlWindow( _rxFocusControl, UNO_QUERY );
3537 OSL_ENSURE( xControlWindow.is(),
"displayErrorSetFocus: invalid control!" );
3538 if ( xControlWindow.is() )
3539 xControlWindow->setFocus();
3543 bool lcl_shouldValidateRequiredFields_nothrow(
const Reference< XInterface >& _rxForm )
3547 static constexpr OUStringLiteral s_sFormsCheckRequiredFields =
u"FormsCheckRequiredFields";
3552 Reference< XPropertySet > xFormProps( _rxForm, UNO_QUERY_THROW );
3553 Reference< XPropertySetInfo > xPSI( xFormProps->getPropertySetInfo() );
3554 if ( xPSI->hasPropertyByName( s_sFormsCheckRequiredFields ) )
3556 bool bShouldValidate =
true;
3557 OSL_VERIFY( xFormProps->getPropertyValue( s_sFormsCheckRequiredFields ) >>= bShouldValidate );
3558 return bShouldValidate;
3563 Reference< XPropertySet > xDataSource( xConnectionAsChild->getParent(), UNO_QUERY );
3564 if ( !xDataSource.is() )
3568 Reference< XPropertySet > xDataSourceSettings(
3569 xDataSource->getPropertyValue(
"Settings"),
3572 bool bShouldValidate =
true;
3573 OSL_VERIFY( xDataSourceSettings->getPropertyValue( s_sFormsCheckRequiredFields ) >>= bShouldValidate );
3574 return bShouldValidate;
3576 catch(
const Exception& )
3587sal_Bool SAL_CALL FormController::approveRowChange(
const RowChangeEvent& _rEvent)
3589 ::osl::ClearableMutexGuard aGuard(
m_aMutex );
3590 impl_checkDisposed_throw();
3596 RowChangeEvent aEvt( _rEvent );
3597 aEvt.Source = *
this;
3598 bValid = aIter.
next()->approveRowChange(aEvt);
3604 if ( ( _rEvent.Action != RowChangeAction::INSERT )
3605 && ( _rEvent.Action != RowChangeAction::UPDATE )
3610 OUString sInvalidityExplanation;
3611 Reference< XControlModel > xInvalidModel;
3612 if ( !checkFormComponentValidity( sInvalidityExplanation, xInvalidModel ) )
3614 Reference< XControl > xControl( locateControl( xInvalidModel ) );
3616 displayErrorSetFocus( sInvalidityExplanation, xControl, getDialogParentWindow(
this) );
3621 if ( !lcl_shouldValidateRequiredFields_nothrow( _rEvent.Source ) )
3624 OSL_ENSURE(m_pColumnInfoCache,
"FormController::approveRowChange: no column infos!");
3625 if (!m_pColumnInfoCache)
3630 if ( !m_pColumnInfoCache->controlsInitialized() )
3631 m_pColumnInfoCache->initializeControls( getControls() );
3633 size_t colCount = m_pColumnInfoCache->getColumnCount();
3634 for (
size_t col = 0;
col < colCount; ++
col )
3636 const ColumnInfo& rColInfo = m_pColumnInfoCache->getColumnInfo(
col );
3638 if ( rColInfo.bAutoIncrement )
3641 if ( rColInfo.bReadOnly )
3644 if ( !rColInfo.xFirstControlWithInputRequired.is() && !rColInfo.xFirstGridWithInputRequiredColumn.is() )
3650 if ( !rColInfo.xColumn->getString().isEmpty() || !rColInfo.xColumn->wasNull() )
3657 Reference< XControl > xControl( rColInfo.xFirstControlWithInputRequired );
3658 if ( !xControl.is() )
3659 xControl.set( rColInfo.xFirstGridWithInputRequiredColumn, UNO_QUERY );
3662 displayErrorSetFocus(
sMessage, rColInfo.xFirstControlWithInputRequired, getDialogParentWindow(
this) );
3675sal_Bool SAL_CALL FormController::approveCursorMove(
const EventObject& event)
3677 ::osl::MutexGuard aGuard(
m_aMutex );
3678 impl_checkDisposed_throw();
3683 EventObject aEvt(event);
3684 aEvt.Source = *
this;
3685 return aIter.
next()->approveCursorMove(aEvt);
3692sal_Bool SAL_CALL FormController::approveRowSetChange(
const EventObject& event)
3694 ::osl::MutexGuard aGuard(
m_aMutex );
3695 impl_checkDisposed_throw();
3700 EventObject aEvt(event);
3701 aEvt.Source = *
this;
3702 return aIter.
next()->approveRowSetChange(aEvt);
3710void SAL_CALL FormController::addRowSetApproveListener(
const Reference< XRowSetApproveListener > & _rxListener)
3712 ::osl::MutexGuard aGuard(
m_aMutex );
3713 impl_checkDisposed_throw();
3715 m_aRowSetApproveListeners.addInterface(_rxListener);
3719void SAL_CALL FormController::removeRowSetApproveListener(
const Reference< XRowSetApproveListener > & _rxListener)
3721 ::osl::MutexGuard aGuard(
m_aMutex );
3722 impl_checkDisposed_throw();
3724 m_aRowSetApproveListeners.removeInterface(_rxListener);
3729void SAL_CALL FormController::errorOccured(
const SQLErrorEvent& aEvent)
3731 ::osl::ClearableMutexGuard aGuard(
m_aMutex );
3732 impl_checkDisposed_throw();
3737 SQLErrorEvent aEvt(
aEvent);
3738 aEvt.Source = *
this;
3739 aIter.
next()->errorOccured(aEvt);
3750void SAL_CALL FormController::addSQLErrorListener(
const Reference< XSQLErrorListener > & aListener)
3752 ::osl::MutexGuard aGuard(
m_aMutex );
3753 impl_checkDisposed_throw();
3755 m_aErrorListeners.addInterface(aListener);
3759void SAL_CALL FormController::removeSQLErrorListener(
const Reference< XSQLErrorListener > & aListener)
3761 ::osl::MutexGuard aGuard(
m_aMutex );
3762 impl_checkDisposed_throw();
3764 m_aErrorListeners.removeInterface(aListener);
3769void SAL_CALL FormController::addDatabaseParameterListener(
const Reference< XDatabaseParameterListener > & aListener)
3771 ::osl::MutexGuard aGuard(
m_aMutex );
3772 impl_checkDisposed_throw();
3774 m_aParameterListeners.addInterface(aListener);
3778void SAL_CALL FormController::removeDatabaseParameterListener(
const Reference< XDatabaseParameterListener > & aListener)
3780 ::osl::MutexGuard aGuard(
m_aMutex );
3781 impl_checkDisposed_throw();
3783 m_aParameterListeners.removeInterface(aListener);
3788void SAL_CALL FormController::addParameterListener(
const Reference< XDatabaseParameterListener > & aListener)
3790 FormController::addDatabaseParameterListener( aListener );
3794void SAL_CALL FormController::removeParameterListener(
const Reference< XDatabaseParameterListener > & aListener)
3796 FormController::removeDatabaseParameterListener( aListener );
3801sal_Bool SAL_CALL FormController::approveParameter(
const DatabaseParameterEvent& aEvent)
3804 ::osl::MutexGuard aGuard(
m_aMutex );
3805 impl_checkDisposed_throw();
3810 DatabaseParameterEvent aEvt(
aEvent);
3811 aEvt.Source = *
this;
3812 return aIter.
next()->approveParameter(aEvt);
3819 if ( !ensureInteractionHandler() )
3826 ParametersRequest aRequest;
3827 aRequest.Parameters =
aEvent.Parameters;
3831 pParamRequest->addContinuation(pParamValues);
3832 pParamRequest->addContinuation(pAbort);
3837 if (!pParamValues->wasSelected())
3842 Sequence< PropertyValue > aFinalValues = pParamValues->getValues();
3843 if (aFinalValues.getLength() != aRequest.Parameters->getCount())
3845 OSL_FAIL(
"FormController::approveParameter: the InteractionHandler returned nonsense!");
3848 const PropertyValue* pFinalValues = aFinalValues.getConstArray();
3849 for (sal_Int32
i=0;
i<aFinalValues.getLength(); ++
i, ++pFinalValues)
3851 Reference< XPropertySet > xParam(
3852 aRequest.Parameters->getByIndex(
i), css::uno::UNO_QUERY);
3858 DBG_ASSERT(
sName == pFinalValues->Name,
"FormController::approveParameter: suspicious value names!");
3860 try { xParam->setPropertyValue(
FM_PROP_VALUE, pFinalValues->Value); }
3863 OSL_FAIL(
"FormController::approveParameter: setting one of the properties failed!");
3878void SAL_CALL FormController::addConfirmDeleteListener(
const Reference< XConfirmDeleteListener > & aListener)
3880 ::osl::MutexGuard aGuard(
m_aMutex );
3881 impl_checkDisposed_throw();
3883 m_aDeleteListeners.addInterface(aListener);
3887void SAL_CALL FormController::removeConfirmDeleteListener(
const Reference< XConfirmDeleteListener > & aListener)
3889 ::osl::MutexGuard aGuard(
m_aMutex );
3890 impl_checkDisposed_throw();
3892 m_aDeleteListeners.removeInterface(aListener);
3897sal_Bool SAL_CALL FormController::confirmDelete(
const RowChangeEvent& aEvent)
3899 ::osl::MutexGuard aGuard(
m_aMutex );
3900 impl_checkDisposed_throw();
3905 RowChangeEvent aEvt(
aEvent);
3906 aEvt.Source = *
this;
3907 return aIter.
next()->confirmDelete(aEvt);
3915 sTitle =
SvxResId( RID_STR_DELETECONFIRM_RECORDS );
3916 sTitle = sTitle.replaceFirst(
"#", OUString::number(
nLength) );
3919 sTitle =
SvxResId( RID_STR_DELETECONFIRM_RECORD );
3923 if ( !ensureInteractionHandler() )
3931 SQLWarning aWarning;
3932 aWarning.Message = sTitle;
3933 SQLWarning aDetails;
3934 aDetails.Message =
SvxResId(RID_STR_DELETECONFIRM);
3935 aWarning.NextException <<= aDetails;
3940 pRequest->addContinuation( pApprove );
3941 pRequest->addContinuation( pDisapprove );
3946 if ( pApprove->wasSelected() )
3958void SAL_CALL FormController::invalidateFeatures(
const Sequence< ::sal_Int16 >& Features )
3960 ::osl::MutexGuard aGuard(
m_aMutex );
3962 m_aInvalidFeatures.insert( Features.begin(), Features.end() );
3965 if ( !m_aFeatureInvalidationTimer.IsActive() )
3966 m_aFeatureInvalidationTimer.Start();
3970void SAL_CALL FormController::invalidateAllFeatures( )
3972 ::osl::ClearableMutexGuard aGuard(
m_aMutex );
3977 if ( aInterceptedFeatures.hasElements() )
3978 invalidateFeatures( aInterceptedFeatures );
3982Reference< XDispatch >
3983FormController::interceptedQueryDispatch(
const URL& aURL,
3984 const OUString& , sal_Int32 )
3986 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
3987 Reference< XDispatch > xReturn;
3990 || ( (
aURL.Complete ==
"private:/InteractionHandler" )
3991 && ensureInteractionHandler()
3994 xReturn =
static_cast< XDispatch*
>( this );
3997 if ( !xReturn.is() && m_xFormOperations.is() )
4005 DispatcherContainer::const_iterator aDispatcherPos = m_aFeatureDispatchers.find(
nFormFeature );
4006 if ( aDispatcherPos == m_aFeatureDispatchers.end() )
4008 aDispatcherPos = m_aFeatureDispatchers.emplace(
4013 OSL_ENSURE( aDispatcherPos->second.is(),
"FormController::interceptedQueryDispatch: should have a dispatcher by now!" );
4014 return aDispatcherPos->second;
4023void SAL_CALL FormController::dispatch(
const URL& _rURL,
const Sequence< PropertyValue >& _rArgs )
4025 if ( _rArgs.getLength() != 1 )
4027 OSL_FAIL(
"FormController::dispatch: no arguments -> no dispatch!" );
4031 if ( _rURL.Complete ==
"private:/InteractionHandler" )
4033 Reference< XInteractionRequest > xRequest;
4034 OSL_VERIFY( _rArgs[0].
Value >>= xRequest );
4035 if ( xRequest.is() )
4042 OSL_FAIL(
"FormController::dispatch: How do you expect me to return something via this call?" );
4047 OSL_FAIL(
"FormController::dispatch: unknown URL!" );
4051void SAL_CALL FormController::addStatusListener(
const Reference< XStatusListener >& _rxListener,
const URL& _rURL )
4055 if (_rxListener.is())
4057 FeatureStateEvent
aEvent;
4058 aEvent.FeatureURL = _rURL;
4060 _rxListener->statusChanged(
aEvent);
4065 OSL_FAIL(
"FormController::addStatusListener: invalid (unsupported) URL!");
4069Reference< XInterface > SAL_CALL FormController::getParent()
4075void SAL_CALL FormController::setParent(
const Reference< XInterface >& Parent)
4081void SAL_CALL FormController::removeStatusListener(
const Reference< XStatusListener >& ,
const URL& _rURL )
4083 OSL_ENSURE(_rURL.Complete ==
FMURL_CONFIRM_DELETION,
"FormController::removeStatusListener: invalid (unsupported) URL!");
4088Reference< XDispatchProviderInterceptor > FormController::createInterceptor(
const Reference< XDispatchProviderInterception > & _xInterception)
4090 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
4093 for (
const auto & it : m_aControlDispatchInterceptors )
4095 if (it->getIntercepted() == _xInterception)
4096 OSL_FAIL(
"FormController::createInterceptor : we already do intercept this objects dispatches !");
4101 m_aControlDispatchInterceptors.push_back( pInterceptor );
4103 return pInterceptor;
4107bool FormController::ensureInteractionHandler()
4111 if ( m_bAttemptedHandlerCreation )
4113 m_bAttemptedHandlerCreation =
true;
4116 getDialogParentWindow(
this));
4121void SAL_CALL FormController::handle(
const Reference< XInteractionRequest >& _rRequest )
4123 if ( !ensureInteractionHandler() )
4129void FormController::deleteInterceptor(
const Reference< XDispatchProviderInterception > & _xInterception)
4131 OSL_ENSURE( !impl_isDisposed_nofail(),
"FormController: already disposed!" );
4133 auto aIter = std::find_if(m_aControlDispatchInterceptors.begin(), m_aControlDispatchInterceptors.end(),
4135 return rpInterceptor->getIntercepted() == _xInterception;
4137 if (aIter != m_aControlDispatchInterceptors.end())
4140 (*aIter)->dispose();
4142 m_aControlDispatchInterceptors.erase(aIter);
4147void FormController::implInvalidateCurrentControlDependentFeatures()
4149 Sequence< sal_Int16 > aCurrentControlDependentFeatures
4151 FormFeature::SortAscending,
4152 FormFeature::SortDescending,
4153 FormFeature::AutoFilter,
4154 FormFeature::RefreshCurrentControl
4157 invalidateFeatures( aCurrentControlDependentFeatures );
4161void SAL_CALL FormController::columnChanged(
const EventObject& )
4163 implInvalidateCurrentControlDependentFeatures();
constexpr OUStringLiteral sServiceName
const LanguageTag & GetUILanguageTag() const
static const AllSettings & GetSettings()
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
const OUString & getNumDecimalSep() const
virtual void ImplSetPeerProperty(const OUString &rPropName, const css::uno::Any &rVal)
void SAL_CALL createPeer(const css::uno::Reference< css::awt::XToolkit > &Toolkit, const css::uno::Reference< css::awt::XWindowPeer > &Parent) override
bool hasMoreElements() const
css::uno::Reference< ListenerT > const & next()
css::uno::Sequence< css::uno::Type > getTypes()
css::uno::Type const & get()
static sal_Int32 getControllerFeatureSlotIdForURL(const OUString &_rMainURL)
retrieves the feature id for a given feature URL
static sal_Int16 getFormFeatureForSlotId(sal_Int32 _nSlotId)
retrieves the css.form.runtime.FormFeature ID for a given slot ID
Reference< XInteractionHandler2 > m_xInteractionHandler
#define DBG_ASSERT(sCon, aError)
#define DBG_UNHANDLED_EXCEPTION(...)
OUString SvxResId(TranslateId aId)
Reference< XComponentContext > const m_xComponentContext
Reference< XSingleServiceFactory > xFactory
constexpr OUStringLiteral FM_PROP_READONLY
#define FM_ATTR_FORM_OPERATIONS
constexpr OUStringLiteral FM_PROP_CYCLE
constexpr OUStringLiteral FM_PROP_DYNAMIC_CONTROL_BORDER
constexpr OUStringLiteral FM_PROP_DEFAULTCONTROL
constexpr OUStringLiteral FM_PROP_ISNULLABLE
constexpr OUStringLiteral FM_PROP_ACTIVE_CONNECTION
constexpr OUStringLiteral FM_PROP_BOUNDFIELD
constexpr OUStringLiteral FM_PROP_ISNEW
constexpr OUStringLiteral FM_PROP_ENABLED
constexpr OUStringLiteral FM_PROP_ACTIVECOMMAND
constexpr OUStringLiteral FM_PROP_INPUT_REQUIRED
constexpr OUStringLiteral FM_PROP_TEXT
constexpr OUStringLiteral FM_PROP_CONTROL_BORDER_COLOR_INVALID
constexpr OUStringLiteral FM_PROP_ISREADONLY
constexpr OUStringLiteral FM_PROP_NAME
constexpr OUStringLiteral FM_PROP_FORM_OPERATIONS
constexpr OUStringLiteral FM_PROP_REALNAME
constexpr OUStringLiteral FM_PROP_FILTER
constexpr OUStringLiteral FM_PROP_AUTOINCREMENT
constexpr OUStringLiteral FM_PROP_SEARCHABLE
constexpr OUStringLiteral FM_PROP_CONTROL_BORDER_COLOR_FOCUS
constexpr OUStringLiteral FM_PROP_VALUE
constexpr OUStringLiteral FM_PROP_ISMODIFIED
constexpr OUStringLiteral FM_PROP_CONTROL_BORDER_COLOR_MOUSE
constexpr OUStringLiteral FMURL_CONFIRM_DELETION
#define LINK(Instance, Class, Member)
void SAL_CALL elementRemoved(const css::container::ContainerEvent &Event) override
DECL_LISTENERMULTIPLEXER_END void SAL_CALL elementInserted(const css::container::ContainerEvent &Event) override
#define SAL_WARN_IF(condition, area, stream)
RttiCompleteObjectLocator col
class SAL_NO_VTABLE XPropertySet
OInteraction< css::task::XInteractionDisapprove > OInteractionDisapprove
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
css::uno::Sequence< T > concatSequences(const css::uno::Sequence< T > &rS1, const Ss &... rSn)
css::uno::Sequence< typename M::key_type > mapKeysToSequence(M const &map)
OInteraction< css::task::XInteractionApprove > OInteractionApprove
OInteraction< css::task::XInteractionAbort > OInteractionAbort
Reference< XComponentContext > getComponentContext(Reference< XMultiServiceFactory > const &factory)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
constexpr OUStringLiteral first
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
Reference< XModel > xModel
::std::pair< MetaAction *, int > Component