| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_svx.hxx" |
| |
| #include "fmdocumentclassification.hxx" |
| #include "fmobj.hxx" |
| #include "fmpgeimp.hxx" |
| #include "fmprop.hrc" |
| #include "svx/fmresids.hrc" |
| #include "fmservs.hxx" |
| #include "fmshimp.hxx" |
| #include "svx/fmtools.hxx" |
| #include "fmundo.hxx" |
| #include "fmvwimp.hxx" |
| #include "formcontrolfactory.hxx" |
| #include "svx/sdrpaintwindow.hxx" |
| #include "svx/svditer.hxx" |
| #include "svx/dataaccessdescriptor.hxx" |
| #include "svx/dialmgr.hxx" |
| #include "svx/fmglob.hxx" |
| #include "svx/fmmodel.hxx" |
| #include "svx/fmpage.hxx" |
| #include "svx/fmshell.hxx" |
| #include "svx/fmview.hxx" |
| #include "svx/sdrpagewindow.hxx" |
| #include "svx/svdogrp.hxx" |
| #include "svx/svdpagv.hxx" |
| #include "svx/xmlexchg.hxx" |
| |
| /** === begin UNO includes === **/ |
| #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> |
| #include <com/sun/star/style/VerticalAlignment.hpp> |
| #include <com/sun/star/lang/XInitialization.hpp> |
| #include <com/sun/star/sdbc/XRowSet.hpp> |
| #include <com/sun/star/form/XLoadable.hpp> |
| #include <com/sun/star/awt/VisualEffect.hpp> |
| #include <com/sun/star/util/XNumberFormatsSupplier.hpp> |
| #include <com/sun/star/util/XNumberFormats.hpp> |
| #include <com/sun/star/sdb/CommandType.hpp> |
| #include <com/sun/star/sdbc/DataType.hpp> |
| #include <com/sun/star/sdbc/ColumnValue.hpp> |
| #include <com/sun/star/form/FormComponentType.hpp> |
| #include <com/sun/star/form/FormButtonType.hpp> |
| #include <com/sun/star/form/XReset.hpp> |
| #include <com/sun/star/form/binding/XBindableValue.hpp> |
| #include <com/sun/star/form/binding/XValueBinding.hpp> |
| #include <com/sun/star/form/submission/XSubmissionSupplier.hpp> |
| #include <com/sun/star/awt/XTabControllerModel.hpp> |
| #include <com/sun/star/awt/XControlContainer.hpp> |
| #include <com/sun/star/awt/XTabController.hpp> |
| #include <com/sun/star/container/XIndexAccess.hpp> |
| #include <com/sun/star/awt/XControl.hpp> |
| #include <com/sun/star/lang/XUnoTunnel.hpp> |
| #include <com/sun/star/sdbcx/XTablesSupplier.hpp> |
| #include <com/sun/star/sdbc/XPreparedStatement.hpp> |
| #include <com/sun/star/sdb/XQueriesSupplier.hpp> |
| #include <com/sun/star/container/XContainer.hpp> |
| /** === end UNO includes === **/ |
| |
| #include <comphelper/enumhelper.hxx> |
| #include <comphelper/extract.hxx> |
| #include <comphelper/namedvaluecollection.hxx> |
| #include <comphelper/numbers.hxx> |
| #include <comphelper/property.hxx> |
| #include <cppuhelper/exc_hlp.hxx> |
| #include <unotools/moduleoptions.hxx> |
| #include <tools/diagnose_ex.h> |
| #include <vcl/msgbox.hxx> |
| #include <vcl/stdtext.hxx> |
| #include <vos/mutex.hxx> |
| #include <rtl/logfile.hxx> |
| |
| #include <algorithm> |
| |
| using namespace ::comphelper; |
| using namespace ::svx; |
| using namespace ::svxform; |
| |
| using namespace ::com::sun::star; |
| /** === begin UNO using === **/ |
| using ::com::sun::star::uno::Exception; |
| using ::com::sun::star::uno::RuntimeException; |
| using ::com::sun::star::uno::XInterface; |
| using ::com::sun::star::uno::Sequence; |
| using ::com::sun::star::uno::UNO_QUERY; |
| using ::com::sun::star::uno::UNO_QUERY_THROW; |
| using ::com::sun::star::uno::UNO_SET_THROW; |
| using ::com::sun::star::uno::Type; |
| using ::com::sun::star::uno::Reference; |
| using ::com::sun::star::uno::Any; |
| using ::com::sun::star::uno::makeAny; |
| using ::com::sun::star::style::VerticalAlignment_MIDDLE; |
| using ::com::sun::star::form::FormButtonType_SUBMIT; |
| using ::com::sun::star::form::binding::XValueBinding; |
| using ::com::sun::star::form::binding::XBindableValue; |
| using ::com::sun::star::lang::XComponent; |
| using ::com::sun::star::container::XIndexAccess; |
| using ::com::sun::star::form::XForm; |
| using ::com::sun::star::form::runtime::XFormController; |
| using ::com::sun::star::script::XEventAttacherManager; |
| using ::com::sun::star::awt::XTabControllerModel; |
| using ::com::sun::star::container::XChild; |
| using ::com::sun::star::container::XEnumeration; |
| using ::com::sun::star::task::XInteractionHandler; |
| using ::com::sun::star::lang::XInitialization; |
| using ::com::sun::star::awt::XTabController; |
| using ::com::sun::star::lang::XUnoTunnel; |
| using ::com::sun::star::awt::XControlContainer; |
| using ::com::sun::star::awt::XControl; |
| using ::com::sun::star::form::XFormComponent; |
| using ::com::sun::star::form::XForm; |
| using ::com::sun::star::lang::IndexOutOfBoundsException; |
| using ::com::sun::star::lang::WrappedTargetException; |
| using ::com::sun::star::container::XContainer; |
| using ::com::sun::star::container::ContainerEvent; |
| using ::com::sun::star::lang::EventObject; |
| using ::com::sun::star::beans::NamedValue; |
| using ::com::sun::star::sdb::SQLErrorEvent; |
| using ::com::sun::star::sdbc::XRowSet; |
| using ::com::sun::star::beans::XPropertySet; |
| using ::com::sun::star::container::XElementAccess; |
| using ::com::sun::star::awt::XWindow; |
| using ::com::sun::star::awt::FocusEvent; |
| using ::com::sun::star::ui::dialogs::XExecutableDialog; |
| using ::com::sun::star::sdbc::XDataSource; |
| using ::com::sun::star::container::XIndexContainer; |
| using ::com::sun::star::sdbc::XConnection; |
| using ::com::sun::star::container::XNameAccess; |
| using ::com::sun::star::sdb::SQLContext; |
| using ::com::sun::star::sdbc::SQLWarning; |
| using ::com::sun::star::sdbc::SQLException; |
| using ::com::sun::star::util::XNumberFormatsSupplier; |
| using ::com::sun::star::util::XNumberFormats; |
| using ::com::sun::star::beans::XPropertySetInfo; |
| /** === end UNO using === **/ |
| namespace FormComponentType = ::com::sun::star::form::FormComponentType; |
| namespace CommandType = ::com::sun::star::sdb::CommandType; |
| namespace DataType = ::com::sun::star::sdbc::DataType; |
| |
| //------------------------------------------------------------------------------ |
| class FmXFormView::ObjectRemoveListener : public SfxListener |
| { |
| FmXFormView* m_pParent; |
| public: |
| ObjectRemoveListener( FmXFormView* pParent ); |
| virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); |
| }; |
| |
| //======================================================================== |
| DBG_NAME(FormViewPageWindowAdapter) |
| //------------------------------------------------------------------------ |
| FormViewPageWindowAdapter::FormViewPageWindowAdapter( const ::comphelper::ComponentContext& _rContext, const SdrPageWindow& _rWindow, FmXFormView* _pViewImpl ) |
| : m_xControlContainer( _rWindow.GetControlContainer() ), |
| m_aContext( _rContext ), |
| m_pViewImpl( _pViewImpl ), |
| m_pWindow( dynamic_cast< Window* >( &_rWindow.GetPaintWindow().GetOutputDevice() ) ) |
| { |
| DBG_CTOR(FormViewPageWindowAdapter,NULL); |
| |
| // create an XFormController for every form |
| FmFormPage* pFormPage = dynamic_cast< FmFormPage* >( _rWindow.GetPageView().GetPage() ); |
| DBG_ASSERT( pFormPage, "FormViewPageWindowAdapter::FormViewPageWindowAdapter: no FmFormPage found!" ); |
| if ( pFormPage ) |
| { |
| try |
| { |
| Reference< XIndexAccess > xForms( pFormPage->GetForms(), UNO_QUERY_THROW ); |
| sal_uInt32 nLength = xForms->getCount(); |
| for (sal_uInt32 i = 0; i < nLength; i++) |
| { |
| Reference< XForm > xForm( xForms->getByIndex(i), UNO_QUERY ); |
| if ( xForm.is() ) |
| setController( xForm, NULL ); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| } |
| // ----------------------------------------------------------------------------- |
| FormViewPageWindowAdapter::~FormViewPageWindowAdapter() |
| { |
| DBG_DTOR(FormViewPageWindowAdapter,NULL); |
| } |
| |
| //------------------------------------------------------------------ |
| void FormViewPageWindowAdapter::dispose() |
| { |
| for ( ::std::vector< Reference< XFormController > >::const_iterator i = m_aControllerList.begin(); |
| i != m_aControllerList.end(); |
| ++i |
| ) |
| { |
| try |
| { |
| Reference< XFormController > xController( *i, UNO_QUERY_THROW ); |
| |
| // detaching the events |
| Reference< XChild > xControllerModel( xController->getModel(), UNO_QUERY ); |
| if ( xControllerModel.is() ) |
| { |
| Reference< XEventAttacherManager > xEventManager( xControllerModel->getParent(), UNO_QUERY_THROW ); |
| Reference< XInterface > xControllerNormalized( xController, UNO_QUERY_THROW ); |
| xEventManager->detach( i - m_aControllerList.begin(), xControllerNormalized ); |
| } |
| |
| // dispose the formcontroller |
| Reference< XComponent > xComp( xController, UNO_QUERY_THROW ); |
| xComp->dispose(); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| m_aControllerList.clear(); |
| } |
| |
| |
| //------------------------------------------------------------------------------ |
| sal_Bool SAL_CALL FormViewPageWindowAdapter::hasElements(void) throw( RuntimeException ) |
| { |
| return getCount() != 0; |
| } |
| |
| //------------------------------------------------------------------------------ |
| Type SAL_CALL FormViewPageWindowAdapter::getElementType(void) throw( RuntimeException ) |
| { |
| return ::getCppuType((const Reference< XFormController>*)0); |
| } |
| |
| // XEnumerationAccess |
| //------------------------------------------------------------------------------ |
| Reference< XEnumeration > SAL_CALL FormViewPageWindowAdapter::createEnumeration(void) throw( RuntimeException ) |
| { |
| return new ::comphelper::OEnumerationByIndex(this); |
| } |
| |
| // XIndexAccess |
| //------------------------------------------------------------------------------ |
| sal_Int32 SAL_CALL FormViewPageWindowAdapter::getCount(void) throw( RuntimeException ) |
| { |
| return m_aControllerList.size(); |
| } |
| |
| //------------------------------------------------------------------------------ |
| Any SAL_CALL FormViewPageWindowAdapter::getByIndex(sal_Int32 nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) |
| { |
| if (nIndex < 0 || |
| nIndex >= getCount()) |
| throw IndexOutOfBoundsException(); |
| |
| Any aElement; |
| aElement <<= m_aControllerList[nIndex]; |
| return aElement; |
| } |
| |
| //------------------------------------------------------------------------ |
| void SAL_CALL FormViewPageWindowAdapter::makeVisible( const Reference< XControl >& _Control ) throw (RuntimeException) |
| { |
| ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); |
| |
| Reference< XWindow > xWindow( _Control, UNO_QUERY ); |
| if ( xWindow.is() && m_pViewImpl->getView() && m_pWindow ) |
| { |
| awt::Rectangle aRect = xWindow->getPosSize(); |
| ::Rectangle aNewRect( aRect.X, aRect.Y, aRect.X + aRect.Width, aRect.Y + aRect.Height ); |
| aNewRect = m_pWindow->PixelToLogic( aNewRect ); |
| m_pViewImpl->getView()->MakeVisible( aNewRect, *m_pWindow ); |
| } |
| } |
| |
| //------------------------------------------------------------------------ |
| Reference< XFormController > getControllerSearchChilds( const Reference< XIndexAccess > & xIndex, const Reference< XTabControllerModel > & xModel) |
| { |
| if (xIndex.is() && xIndex->getCount()) |
| { |
| Reference< XFormController > xController; |
| |
| for (sal_Int32 n = xIndex->getCount(); n-- && !xController.is(); ) |
| { |
| xIndex->getByIndex(n) >>= xController; |
| if ((XTabControllerModel*)xModel.get() == (XTabControllerModel*)xController->getModel().get()) |
| return xController; |
| else |
| { |
| xController = getControllerSearchChilds(Reference< XIndexAccess > (xController, UNO_QUERY), xModel); |
| if ( xController.is() ) |
| return xController; |
| } |
| } |
| } |
| return Reference< XFormController > (); |
| } |
| |
| // Search the according controller |
| //------------------------------------------------------------------------ |
| Reference< XFormController > FormViewPageWindowAdapter::getController( const Reference< XForm > & xForm ) const |
| { |
| Reference< XTabControllerModel > xModel(xForm, UNO_QUERY); |
| for (::std::vector< Reference< XFormController > >::const_iterator i = m_aControllerList.begin(); |
| i != m_aControllerList.end(); i++) |
| { |
| if ((XTabControllerModel*)(*i)->getModel().get() == (XTabControllerModel*)xModel.get()) |
| return *i; |
| |
| // the current-round controller isn't the right one. perhaps one of it's children ? |
| Reference< XFormController > xChildSearch = getControllerSearchChilds(Reference< XIndexAccess > (*i, UNO_QUERY), xModel); |
| if (xChildSearch.is()) |
| return xChildSearch; |
| } |
| return Reference< XFormController > (); |
| } |
| |
| //------------------------------------------------------------------------ |
| void FormViewPageWindowAdapter::setController(const Reference< XForm > & xForm, const Reference< XFormController >& _rxParentController ) |
| { |
| DBG_ASSERT( xForm.is(), "FormViewPageWindowAdapter::setController: there should be a form!" ); |
| Reference< XIndexAccess > xFormCps(xForm, UNO_QUERY); |
| if (!xFormCps.is()) |
| return; |
| |
| Reference< XTabControllerModel > xTabOrder(xForm, UNO_QUERY); |
| |
| // create a form controller |
| Reference< XFormController > xController( m_aContext.createComponent( FM_FORM_CONTROLLER ), UNO_QUERY ); |
| if ( !xController.is() ) |
| { |
| ShowServiceNotAvailableError( m_pWindow, FM_FORM_CONTROLLER, sal_True ); |
| return; |
| } |
| |
| Reference< XInteractionHandler > xHandler; |
| if ( _rxParentController.is() ) |
| xHandler = _rxParentController->getInteractionHandler(); |
| else |
| { |
| // TODO: should we create a default handler? Not really necessary, since the |
| // FormController itself has a default fallback |
| } |
| if ( xHandler.is() ) |
| xController->setInteractionHandler( xHandler ); |
| |
| xController->setContext( this ); |
| |
| xController->setModel( xTabOrder ); |
| xController->setContainer( m_xControlContainer ); |
| xController->activateTabOrder(); |
| xController->addActivateListener( m_pViewImpl ); |
| |
| if ( _rxParentController.is() ) |
| _rxParentController->addChildController( xController ); |
| else |
| { |
| m_aControllerList.push_back(xController); |
| |
| xController->setParent( *this ); |
| |
| // attaching the events |
| Reference< XEventAttacherManager > xEventManager( xForm->getParent(), UNO_QUERY ); |
| Reference< XInterface > xIfc(xController, UNO_QUERY); |
| xEventManager->attach(m_aControllerList.size() - 1, xIfc, makeAny(xController) ); |
| } |
| |
| // jetzt die Subforms durchgehen |
| sal_uInt32 nLength = xFormCps->getCount(); |
| Reference< XForm > xSubForm; |
| for (sal_uInt32 i = 0; i < nLength; i++) |
| { |
| if ( xFormCps->getByIndex(i) >>= xSubForm ) |
| setController( xSubForm, xController ); |
| } |
| } |
| |
| //------------------------------------------------------------------------ |
| void FormViewPageWindowAdapter::updateTabOrder( const Reference< XForm >& _rxForm ) |
| { |
| OSL_PRECOND( _rxForm.is(), "FormViewPageWindowAdapter::updateTabOrder: illegal argument!" ); |
| if ( !_rxForm.is() ) |
| return; |
| |
| try |
| { |
| Reference< XTabController > xTabCtrl( getController( _rxForm ).get() ); |
| if ( xTabCtrl.is() ) |
| { // if there already is a TabController for this form, then delegate the "updateTabOrder" request |
| xTabCtrl->activateTabOrder(); |
| } |
| else |
| { // otherwise, create a TabController |
| |
| // if it's a sub form, then we must ensure there exist TabControllers |
| // for all its ancestors, too |
| Reference< XForm > xParentForm( _rxForm->getParent(), UNO_QUERY ); |
| // there is a parent form -> look for the respective controller |
| Reference< XFormController > xParentController; |
| if ( xParentForm.is() ) |
| xParentController.set( getController( xParentForm ), UNO_QUERY ); |
| |
| setController( _rxForm, xParentController ); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| //------------------------------------------------------------------------ |
| FmXFormView::FmXFormView(const ::comphelper::ComponentContext& _rContext, FmFormView* _pView ) |
| :m_aContext( _rContext ) |
| ,m_pMarkedGrid(NULL) |
| ,m_pView(_pView) |
| ,m_nActivationEvent(0) |
| ,m_nErrorMessageEvent( 0 ) |
| ,m_nAutoFocusEvent( 0 ) |
| ,m_nControlWizardEvent( 0 ) |
| ,m_pWatchStoredList( NULL ) |
| ,m_bFirstActivation( true ) |
| ,m_isTabOrderUpdateSuspended( false ) |
| { |
| } |
| |
| //------------------------------------------------------------------------ |
| void FmXFormView::cancelEvents() |
| { |
| if ( m_nActivationEvent ) |
| { |
| Application::RemoveUserEvent( m_nActivationEvent ); |
| m_nActivationEvent = 0; |
| } |
| |
| if ( m_nErrorMessageEvent ) |
| { |
| Application::RemoveUserEvent( m_nErrorMessageEvent ); |
| m_nErrorMessageEvent = 0; |
| } |
| |
| if ( m_nAutoFocusEvent ) |
| { |
| Application::RemoveUserEvent( m_nAutoFocusEvent ); |
| m_nAutoFocusEvent = 0; |
| } |
| |
| if ( m_nControlWizardEvent ) |
| { |
| Application::RemoveUserEvent( m_nControlWizardEvent ); |
| m_nControlWizardEvent = 0; |
| } |
| } |
| |
| //------------------------------------------------------------------------ |
| void FmXFormView::notifyViewDying( ) |
| { |
| DBG_ASSERT( m_pView, "FmXFormView::notifyViewDying: my view already died!" ); |
| m_pView = NULL; |
| cancelEvents(); |
| } |
| |
| //------------------------------------------------------------------------ |
| FmXFormView::~FmXFormView() |
| { |
| DBG_ASSERT( m_aPageWindowAdapters.empty(), "FmXFormView::~FmXFormView: Window list not empty!" ); |
| if ( !m_aPageWindowAdapters.empty() ) |
| { |
| for ( PageWindowAdapterList::const_iterator loop = m_aPageWindowAdapters.begin(); |
| loop != m_aPageWindowAdapters.end(); |
| ++loop |
| ) |
| { |
| (*loop)->dispose(); |
| } |
| } |
| |
| cancelEvents(); |
| |
| delete m_pWatchStoredList; |
| m_pWatchStoredList = NULL; |
| } |
| |
| // EventListener |
| //------------------------------------------------------------------------------ |
| void SAL_CALL FmXFormView::disposing(const EventObject& Source) throw( RuntimeException ) |
| { |
| if ( m_xWindow.is() && Source.Source == m_xWindow ) |
| removeGridWindowListening(); |
| } |
| |
| // XFormControllerListener |
| //------------------------------------------------------------------------------ |
| void SAL_CALL FmXFormView::formActivated(const EventObject& rEvent) throw( RuntimeException ) |
| { |
| if ( m_pView && m_pView->GetFormShell() && m_pView->GetFormShell()->GetImpl() ) |
| m_pView->GetFormShell()->GetImpl()->formActivated( rEvent ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| void SAL_CALL FmXFormView::formDeactivated(const EventObject& rEvent) throw( RuntimeException ) |
| { |
| if ( m_pView && m_pView->GetFormShell() && m_pView->GetFormShell()->GetImpl() ) |
| m_pView->GetFormShell()->GetImpl()->formDeactivated( rEvent ); |
| } |
| |
| // XContainerListener |
| //------------------------------------------------------------------------------ |
| void SAL_CALL FmXFormView::elementInserted(const ContainerEvent& evt) throw( RuntimeException ) |
| { |
| try |
| { |
| Reference< XControlContainer > xControlContainer( evt.Source, UNO_QUERY_THROW ); |
| Reference< XControl > xControl( evt.Element, UNO_QUERY_THROW ); |
| Reference< XFormComponent > xControlModel( xControl->getModel(), UNO_QUERY_THROW ); |
| Reference< XForm > xForm( xControlModel->getParent(), UNO_QUERY_THROW ); |
| |
| if ( m_isTabOrderUpdateSuspended ) |
| { |
| // remember the container and the control, so we can update the tab order on resumeTabOrderUpdate |
| m_aNeedTabOrderUpdate[ xControlContainer ].insert( xForm ); |
| } |
| else |
| { |
| PFormViewPageWindowAdapter pAdapter = findWindow( xControlContainer ); |
| if ( pAdapter.is() ) |
| pAdapter->updateTabOrder( xForm ); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| //------------------------------------------------------------------------------ |
| void SAL_CALL FmXFormView::elementReplaced(const ContainerEvent& evt) throw( RuntimeException ) |
| { |
| elementInserted(evt); |
| } |
| |
| //------------------------------------------------------------------------------ |
| void SAL_CALL FmXFormView::elementRemoved(const ContainerEvent& /*evt*/) throw( RuntimeException ) |
| { |
| } |
| |
| //------------------------------------------------------------------------------ |
| PFormViewPageWindowAdapter FmXFormView::findWindow( const Reference< XControlContainer >& _rxCC ) const |
| { |
| for ( PageWindowAdapterList::const_iterator i = m_aPageWindowAdapters.begin(); |
| i != m_aPageWindowAdapters.end(); |
| ++i |
| ) |
| { |
| if ( _rxCC == (*i)->getControlContainer() ) |
| return *i; |
| } |
| return NULL; |
| } |
| |
| //------------------------------------------------------------------------------ |
| void FmXFormView::addWindow(const SdrPageWindow& rWindow) |
| { |
| FmFormPage* pFormPage = PTR_CAST( FmFormPage, rWindow.GetPageView().GetPage() ); |
| if ( !pFormPage ) |
| return; |
| |
| Reference< XControlContainer > xCC = rWindow.GetControlContainer(); |
| if ( xCC.is() |
| && ( !findWindow( xCC ).is() ) |
| ) |
| { |
| PFormViewPageWindowAdapter pAdapter = new FormViewPageWindowAdapter( m_aContext, rWindow, this ); |
| m_aPageWindowAdapters.push_back( pAdapter ); |
| |
| // Am ControlContainer horchen um Aenderungen mitzbekommen |
| Reference< XContainer > xContainer( xCC, UNO_QUERY ); |
| if ( xContainer.is() ) |
| xContainer->addContainerListener( this ); |
| } |
| } |
| |
| //------------------------------------------------------------------------------ |
| void FmXFormView::removeWindow( const Reference< XControlContainer >& _rxCC ) |
| { |
| // Wird gerufen, wenn |
| // - in den Design-Modus geschaltet wird |
| // - ein Window geloescht wird, waehrend man im Design-Modus ist |
| // - der Control-Container fuer ein Window entfernt wird, waehrend |
| // der aktive Modus eingeschaltet ist. |
| |
| for ( PageWindowAdapterList::iterator i = m_aPageWindowAdapters.begin(); |
| i != m_aPageWindowAdapters.end(); |
| ++i |
| ) |
| { |
| if ( _rxCC != (*i)->getControlContainer() ) |
| continue; |
| |
| Reference< XContainer > xContainer( _rxCC, UNO_QUERY ); |
| if ( xContainer.is() ) |
| xContainer->removeContainerListener( this ); |
| |
| (*i)->dispose(); |
| m_aPageWindowAdapters.erase( i ); |
| break; |
| } |
| } |
| |
| //------------------------------------------------------------------------------ |
| void FmXFormView::displayAsyncErrorMessage( const SQLErrorEvent& _rEvent ) |
| { |
| DBG_ASSERT( 0 == m_nErrorMessageEvent, "FmXFormView::displayAsyncErrorMessage: not too fast, please!" ); |
| // This should not happen - usually, the PostUserEvent is faster than any possible user |
| // interaction which could trigger a new error. If it happens, we need a queue for the events. |
| m_aAsyncError = _rEvent; |
| m_nErrorMessageEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnDelayedErrorMessage ) ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| IMPL_LINK(FmXFormView, OnDelayedErrorMessage, void*, /*EMPTYTAG*/) |
| { |
| m_nErrorMessageEvent = 0; |
| displayException( m_aAsyncError ); |
| return 0L; |
| } |
| |
| //------------------------------------------------------------------------------ |
| void FmXFormView::onFirstViewActivation( const FmFormModel* _pDocModel ) |
| { |
| if ( _pDocModel && _pDocModel->GetAutoControlFocus() ) |
| m_nAutoFocusEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnAutoFocus ) ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| void FmXFormView::suspendTabOrderUpdate() |
| { |
| OSL_ENSURE( !m_isTabOrderUpdateSuspended, "FmXFormView::suspendTabOrderUpdate: nesting not allowed!" ); |
| m_isTabOrderUpdateSuspended = true; |
| } |
| |
| //------------------------------------------------------------------------------ |
| void FmXFormView::resumeTabOrderUpdate() |
| { |
| OSL_ENSURE( m_isTabOrderUpdateSuspended, "FmXFormView::resumeTabOrderUpdate: not suspended!" ); |
| m_isTabOrderUpdateSuspended = false; |
| |
| // update the tab orders for all components which were collected since the suspendTabOrderUpdate call. |
| for ( MapControlContainerToSetOfForms::const_iterator container = m_aNeedTabOrderUpdate.begin(); |
| container != m_aNeedTabOrderUpdate.end(); |
| ++container |
| ) |
| { |
| PFormViewPageWindowAdapter pAdapter = findWindow( container->first ); |
| if ( !pAdapter.is() ) |
| continue; |
| |
| for ( SetOfForms::const_iterator form = container->second.begin(); |
| form != container->second.end(); |
| ++form |
| ) |
| { |
| pAdapter->updateTabOrder( *form ); |
| } |
| } |
| m_aNeedTabOrderUpdate.clear(); |
| } |
| |
| //------------------------------------------------------------------------------ |
| IMPL_LINK(FmXFormView, OnActivate, void*, /*EMPTYTAG*/) |
| { |
| m_nActivationEvent = 0; |
| |
| if ( !m_pView ) |
| { |
| DBG_ERROR( "FmXFormView::OnActivate: well .... seems we have a timing problem (the view already died)!" ); |
| return 0; |
| } |
| |
| // setting the controller to activate |
| if (m_pView->GetFormShell() && m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW) |
| { |
| Window* pWindow = const_cast<Window*>(static_cast<const Window*>(m_pView->GetActualOutDev())); |
| PFormViewPageWindowAdapter pAdapter = m_aPageWindowAdapters.empty() ? NULL : m_aPageWindowAdapters[0]; |
| for ( PageWindowAdapterList::const_iterator i = m_aPageWindowAdapters.begin(); |
| i != m_aPageWindowAdapters.end(); |
| ++i |
| ) |
| { |
| if ( pWindow == (*i)->getWindow() ) |
| pAdapter =*i; |
| } |
| |
| if ( pAdapter.get() ) |
| { |
| for ( ::std::vector< Reference< XFormController > >::const_iterator i = pAdapter->GetList().begin(); |
| i != pAdapter->GetList().end(); |
| ++i |
| ) |
| { |
| const Reference< XFormController > & xController = *i; |
| if ( !xController.is() ) |
| continue; |
| |
| // only database forms are to be activated |
| Reference< XRowSet > xForm(xController->getModel(), UNO_QUERY); |
| if ( !xForm.is() || !OStaticDataAccessTools().getRowSetConnection( xForm ).is() ) |
| continue; |
| |
| Reference< XPropertySet > xFormSet( xForm, UNO_QUERY ); |
| ENSURE_OR_CONTINUE( xFormSet.is(), "FmXFormView::OnActivate: a form which does not have properties?" ); |
| |
| const ::rtl::OUString aSource = ::comphelper::getString( xFormSet->getPropertyValue( FM_PROP_COMMAND ) ); |
| if ( aSource.getLength() ) |
| { |
| FmXFormShell* pShImpl = m_pView->GetFormShell()->GetImpl(); |
| if ( pShImpl ) |
| pShImpl->setActiveController( xController ); |
| break; |
| } |
| } |
| } |
| } |
| return 0; |
| } |
| |
| //------------------------------------------------------------------------------ |
| void FmXFormView::Activate(sal_Bool bSync) |
| { |
| if (m_nActivationEvent) |
| { |
| Application::RemoveUserEvent(m_nActivationEvent); |
| m_nActivationEvent = 0; |
| } |
| |
| if (bSync) |
| { |
| LINK(this,FmXFormView,OnActivate).Call(NULL); |
| } |
| else |
| m_nActivationEvent = Application::PostUserEvent(LINK(this,FmXFormView,OnActivate)); |
| } |
| |
| //------------------------------------------------------------------------------ |
| void FmXFormView::Deactivate(sal_Bool bDeactivateController) |
| { |
| if (m_nActivationEvent) |
| { |
| Application::RemoveUserEvent(m_nActivationEvent); |
| m_nActivationEvent = 0; |
| } |
| |
| FmXFormShell* pShImpl = m_pView->GetFormShell() ? m_pView->GetFormShell()->GetImpl() : NULL; |
| if (pShImpl && bDeactivateController) |
| pShImpl->setActiveController( NULL ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| FmFormShell* FmXFormView::GetFormShell() const |
| { |
| return m_pView ? m_pView->GetFormShell() : NULL; |
| } |
| // ----------------------------------------------------------------------------- |
| void FmXFormView::AutoFocus( sal_Bool _bSync ) |
| { |
| if (m_nAutoFocusEvent) |
| Application::RemoveUserEvent(m_nAutoFocusEvent); |
| |
| if ( _bSync ) |
| OnAutoFocus( NULL ); |
| else |
| m_nAutoFocusEvent = Application::PostUserEvent(LINK(this, FmXFormView, OnAutoFocus)); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| bool FmXFormView::isFocusable( const Reference< XControl >& i_rControl ) |
| { |
| if ( !i_rControl.is() ) |
| return false; |
| |
| try |
| { |
| Reference< XPropertySet > xModelProps( i_rControl->getModel(), UNO_QUERY_THROW ); |
| |
| // only enabled controls are allowed to participate |
| sal_Bool bEnabled = sal_False; |
| OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_ENABLED ) >>= bEnabled ); |
| if ( !bEnabled ) |
| return false; |
| |
| // check the class id of the control model |
| sal_Int16 nClassId = FormComponentType::CONTROL; |
| OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId ); |
| |
| // controls which are not focussable |
| if ( ( FormComponentType::CONTROL != nClassId ) |
| && ( FormComponentType::IMAGEBUTTON != nClassId ) |
| && ( FormComponentType::GROUPBOX != nClassId ) |
| && ( FormComponentType::FIXEDTEXT != nClassId ) |
| && ( FormComponentType::HIDDENCONTROL != nClassId ) |
| && ( FormComponentType::IMAGECONTROL != nClassId ) |
| && ( FormComponentType::SCROLLBAR != nClassId ) |
| && ( FormComponentType::SPINBUTTON!= nClassId ) |
| ) |
| { |
| return true; |
| } |
| } |
| catch( const Exception& e ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| return false; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| static Reference< XControl > lcl_firstFocussableControl( const Sequence< Reference< XControl > >& _rControls ) |
| { |
| Reference< XControl > xReturn; |
| |
| // loop through all the controls |
| const Reference< XControl >* pControls = _rControls.getConstArray(); |
| const Reference< XControl >* pControlsEnd = _rControls.getConstArray() + _rControls.getLength(); |
| for ( ; pControls != pControlsEnd; ++pControls ) |
| { |
| if ( !pControls->is() ) |
| continue; |
| |
| if ( FmXFormView::isFocusable( *pControls ) ) |
| { |
| xReturn = *pControls; |
| break; |
| } |
| } |
| |
| if ( !xReturn.is() && _rControls.getLength() ) |
| xReturn = _rControls[0]; |
| |
| return xReturn; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| namespace |
| { |
| // ......................................................................... |
| void lcl_ensureControlsOfFormExist_nothrow( const SdrPage& _rPage, const SdrView& _rView, const Window& _rWindow, const Reference< XForm >& _rxForm ) |
| { |
| try |
| { |
| Reference< XInterface > xNormalizedForm( _rxForm, UNO_QUERY_THROW ); |
| |
| SdrObjListIter aSdrObjectLoop( _rPage, IM_DEEPNOGROUPS ); |
| while ( aSdrObjectLoop.IsMore() ) |
| { |
| FmFormObj* pFormObject = FmFormObj::GetFormObject( aSdrObjectLoop.Next() ); |
| if ( !pFormObject ) |
| continue; |
| |
| Reference< XChild > xModel( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW ); |
| Reference< XInterface > xModelParent( xModel->getParent(), UNO_QUERY_THROW ); |
| |
| if ( xNormalizedForm.get() != xModelParent.get() ) |
| continue; |
| |
| pFormObject->GetUnoControl( _rView, _rWindow ); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------------- |
| Reference< XFormController > FmXFormView::getFormController( const Reference< XForm >& _rxForm, const OutputDevice& _rDevice ) const |
| { |
| Reference< XFormController > xController; |
| |
| for ( PageWindowAdapterList::const_iterator pos = m_aPageWindowAdapters.begin(); |
| pos != m_aPageWindowAdapters.end(); |
| ++pos |
| ) |
| { |
| const PFormViewPageWindowAdapter pAdapter( *pos ); |
| ENSURE_OR_CONTINUE( pAdapter.get(), "FmXFormView::getFormController: invalid page window adapter!" ); |
| if ( pAdapter->getWindow() != &_rDevice ) |
| // wrong device |
| continue; |
| |
| xController = pAdapter->getController( _rxForm ); |
| if ( xController.is() ) |
| break; |
| } |
| return xController; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| IMPL_LINK(FmXFormView, OnAutoFocus, void*, /*EMPTYTAG*/) |
| { |
| m_nAutoFocusEvent = 0; |
| |
| // go to the first form of our page, examine it's TabController, go to it's first (in terms of the tab order) |
| // control, give it the focus |
| |
| do |
| { |
| |
| // get the forms collection of the page we belong to |
| FmFormPage* pPage = m_pView ? PTR_CAST( FmFormPage, m_pView->GetSdrPageView()->GetPage() ) : NULL; |
| Reference< XIndexAccess > xForms( pPage ? Reference< XIndexAccess >( pPage->GetForms(), UNO_QUERY ) : Reference< XIndexAccess >() ); |
| |
| const PFormViewPageWindowAdapter pAdapter = m_aPageWindowAdapters.empty() ? NULL : m_aPageWindowAdapters[0]; |
| const Window* pWindow = pAdapter.get() ? pAdapter->getWindow() : NULL; |
| |
| ENSURE_OR_RETURN( xForms.is() && pWindow, "FmXFormView::OnAutoFocus: could not collect all essentials!", 0L ); |
| |
| try |
| { |
| // go for the tab controller of the first form |
| if ( !xForms->getCount() ) |
| break; |
| Reference< XForm > xForm( xForms->getByIndex( 0 ), UNO_QUERY_THROW ); |
| Reference< XTabController > xTabController( pAdapter->getController( xForm ), UNO_QUERY_THROW ); |
| |
| // go for the first control of the controller |
| Sequence< Reference< XControl > > aControls( xTabController->getControls() ); |
| if ( aControls.getLength() == 0 ) |
| { |
| Reference< XElementAccess > xFormElementAccess( xForm, UNO_QUERY_THROW ); |
| if ( xFormElementAccess->hasElements() ) |
| { |
| // there are control models in the form, but no controls, yet. |
| // Well, since some time controls are created on demand only. In particular, |
| // they're normally created when they're first painted. |
| // Unfortunately, the FormController does not have any way to |
| // trigger the creation itself, so we must hack this ... |
| lcl_ensureControlsOfFormExist_nothrow( *pPage, *m_pView, *pWindow, xForm ); |
| aControls = xTabController->getControls(); |
| OSL_ENSURE( aControls.getLength(), "FmXFormView::OnAutoFocus: no controls at all!" ); |
| } |
| } |
| |
| // set the focus to this first control |
| Reference< XWindow > xControlWindow( lcl_firstFocussableControl( aControls ), UNO_QUERY ); |
| if ( !xControlWindow.is() ) |
| break; |
| |
| xControlWindow->setFocus(); |
| |
| // ensure that the control is visible |
| // 80210 - 12/07/00 - FS |
| const Window* pCurrentWindow = dynamic_cast< const Window* >( m_pView->GetActualOutDev() ); |
| if ( pCurrentWindow ) |
| { |
| awt::Rectangle aRect = xControlWindow->getPosSize(); |
| ::Rectangle aNonUnoRect( aRect.X, aRect.Y, aRect.X + aRect.Width, aRect.Y + aRect.Height ); |
| m_pView->MakeVisible( pCurrentWindow->PixelToLogic( aNonUnoRect ), *const_cast< Window* >( pCurrentWindow ) ); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| |
| } // do |
| while ( false ); |
| |
| return 1L; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| void FmXFormView::onCreatedFormObject( FmFormObj& _rFormObject ) |
| { |
| FmFormShell* pShell = m_pView ? m_pView->GetFormShell() : NULL; |
| FmXFormShell* pShellImpl = pShell ? pShell->GetImpl() : NULL; |
| OSL_ENSURE( pShellImpl, "FmXFormView::onCreatedFormObject: no form shell!" ); |
| if ( !pShellImpl ) |
| return; |
| |
| // it is valid that the form shell's forms collection is not initialized, yet |
| pShellImpl->UpdateForms( sal_True ); |
| |
| m_xLastCreatedControlModel.set( _rFormObject.GetUnoControlModel(), UNO_QUERY ); |
| if ( !m_xLastCreatedControlModel.is() ) |
| return; |
| |
| // some initial property defaults |
| FormControlFactory aControlFactory( m_aContext ); |
| aControlFactory.initializeControlModel( pShellImpl->getDocumentType(), _rFormObject ); |
| |
| if ( !pShellImpl->GetWizardUsing() ) |
| return; |
| |
| // #i31958# don't call wizards in XForms mode |
| if ( pShellImpl->isEnhancedForm() ) |
| return; |
| |
| // #i46898# no wizards if there is no Base installed - currently, all wizards are |
| // database related |
| if ( !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) ) |
| return; |
| |
| if ( m_nControlWizardEvent ) |
| Application::RemoveUserEvent( m_nControlWizardEvent ); |
| m_nControlWizardEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnStartControlWizard ) ); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| IMPL_LINK( FmXFormView, OnStartControlWizard, void*, /**/ ) |
| { |
| m_nControlWizardEvent = 0; |
| OSL_PRECOND( m_xLastCreatedControlModel.is(), "FmXFormView::OnStartControlWizard: illegal call!" ); |
| if ( !m_xLastCreatedControlModel.is() ) |
| return 0L; |
| |
| sal_Int16 nClassId = FormComponentType::CONTROL; |
| try |
| { |
| OSL_VERIFY( m_xLastCreatedControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| |
| const sal_Char* pWizardAsciiName = NULL; |
| switch ( nClassId ) |
| { |
| case FormComponentType::GRIDCONTROL: |
| pWizardAsciiName = "com.sun.star.sdb.GridControlAutoPilot"; |
| break; |
| case FormComponentType::LISTBOX: |
| case FormComponentType::COMBOBOX: |
| pWizardAsciiName = "com.sun.star.sdb.ListComboBoxAutoPilot"; |
| break; |
| case FormComponentType::GROUPBOX: |
| pWizardAsciiName = "com.sun.star.sdb.GroupBoxAutoPilot"; |
| break; |
| } |
| |
| if ( pWizardAsciiName ) |
| { |
| // build the argument list |
| ::comphelper::NamedValueCollection aWizardArgs; |
| aWizardArgs.put( "ObjectModel", m_xLastCreatedControlModel ); |
| |
| // create the wizard object |
| Reference< XExecutableDialog > xWizard; |
| try |
| { |
| m_aContext.createComponentWithArguments( pWizardAsciiName, aWizardArgs.getWrappedPropertyValues(), xWizard ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| |
| if ( !xWizard.is() ) |
| { |
| ShowServiceNotAvailableError( NULL, String::CreateFromAscii( pWizardAsciiName ), sal_True ); |
| } |
| else |
| { |
| // execute the wizard |
| try |
| { |
| xWizard->execute(); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| } |
| |
| m_xLastCreatedControlModel.clear(); |
| return 1L; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| namespace |
| { |
| void lcl_insertIntoFormComponentHierarchy_throw( const FmFormView& _rView, const SdrUnoObj& _rSdrObj, |
| const Reference< XDataSource >& _rxDataSource = NULL, const ::rtl::OUString& _rDataSourceName = ::rtl::OUString(), |
| const ::rtl::OUString& _rCommand = ::rtl::OUString(), const sal_Int32 _nCommandType = -1 ) |
| { |
| FmFormPage& rPage = static_cast< FmFormPage& >( *_rView.GetSdrPageView()->GetPage() ); |
| |
| Reference< XFormComponent > xFormComponent( _rSdrObj.GetUnoControlModel(), UNO_QUERY_THROW ); |
| Reference< XForm > xTargetForm( |
| rPage.GetImpl().findPlaceInFormComponentHierarchy( xFormComponent, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType ), |
| UNO_SET_THROW ); |
| |
| rPage.GetImpl().setUniqueName( xFormComponent, xTargetForm ); |
| |
| Reference< XIndexContainer > xFormAsContainer( xTargetForm, UNO_QUERY_THROW ); |
| xFormAsContainer->insertByIndex( xFormAsContainer->getCount(), makeAny( xFormComponent ) ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------------- |
| SdrObject* FmXFormView::implCreateFieldControl( const ::svx::ODataAccessDescriptor& _rColumnDescriptor ) |
| { |
| // not if we're in design mode |
| if ( !m_pView->IsDesignMode() ) |
| return NULL; |
| |
| ::rtl::OUString sCommand, sFieldName; |
| sal_Int32 nCommandType = CommandType::COMMAND; |
| SharedConnection xConnection; |
| |
| ::rtl::OUString sDataSource = _rColumnDescriptor.getDataSource(); |
| _rColumnDescriptor[ daCommand ] >>= sCommand; |
| _rColumnDescriptor[ daColumnName ] >>= sFieldName; |
| _rColumnDescriptor[ daCommandType ] >>= nCommandType; |
| { |
| Reference< XConnection > xExternalConnection; |
| _rColumnDescriptor[ daConnection ] >>= xExternalConnection; |
| xConnection.reset( xExternalConnection, SharedConnection::NoTakeOwnership ); |
| } |
| |
| if ( !sCommand.getLength() |
| || !sFieldName.getLength() |
| || ( !sDataSource.getLength() |
| && !xConnection.is() |
| ) |
| ) |
| { |
| DBG_ERROR( "FmXFormView::implCreateFieldControl: nonsense!" ); |
| } |
| |
| Reference< XDataSource > xDataSource; |
| SQLErrorEvent aError; |
| try |
| { |
| if ( xConnection.is() && !xDataSource.is() && !sDataSource.getLength() ) |
| { |
| Reference< XChild > xChild( xConnection, UNO_QUERY ); |
| if ( xChild.is() ) |
| xDataSource = xDataSource.query( xChild->getParent() ); |
| } |
| |
| // obtain the data source |
| if ( !xDataSource.is() ) |
| xDataSource = OStaticDataAccessTools().getDataSource( sDataSource, m_aContext.getLegacyServiceFactory() ); |
| |
| // and the connection, if necessary |
| if ( !xConnection.is() ) |
| xConnection.reset( OStaticDataAccessTools().getConnection_withFeedback( |
| sDataSource, |
| ::rtl::OUString(), |
| ::rtl::OUString(), |
| m_aContext.getLegacyServiceFactory() |
| ) ); |
| } |
| catch ( const SQLException& ) |
| { |
| aError.Reason = ::cppu::getCaughtException(); |
| } |
| catch( const Exception& ) { /* will be asserted below */ } |
| if (aError.Reason.hasValue()) |
| { |
| displayAsyncErrorMessage( aError ); |
| return NULL; |
| } |
| |
| // need a data source and a connection here |
| if (!xDataSource.is() || !xConnection.is()) |
| { |
| DBG_ERROR("FmXFormView::implCreateFieldControl : could not retrieve the data source or the connection!"); |
| return NULL; |
| } |
| |
| OStaticDataAccessTools aDBATools; |
| Reference< XComponent > xKeepFieldsAlive; |
| // go |
| try |
| { |
| // determine the table/query field which we should create a control for |
| Reference< XPropertySet > xField; |
| |
| Reference< XNameAccess > xFields = aDBATools.getFieldsByCommandDescriptor( |
| xConnection, nCommandType, sCommand, xKeepFieldsAlive ); |
| |
| if (xFields.is() && xFields->hasByName(sFieldName)) |
| xFields->getByName(sFieldName) >>= xField; |
| if ( !xField.is() ) |
| return NULL; |
| |
| Reference< XNumberFormatsSupplier > xSupplier( aDBATools.getNumberFormats( xConnection, sal_False ), UNO_SET_THROW ); |
| Reference< XNumberFormats > xNumberFormats( xSupplier->getNumberFormats(), UNO_SET_THROW ); |
| |
| ::rtl::OUString sLabelPostfix; |
| |
| //////////////////////////////////////////////////////////////// |
| // nur fuer Textgroesse |
| OutputDevice* pOutDev = NULL; |
| if (m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW) |
| pOutDev = const_cast<OutputDevice*>(m_pView->GetActualOutDev()); |
| else |
| {// OutDev suchen |
| SdrPageView* pPageView = m_pView->GetSdrPageView(); |
| if( pPageView && !pOutDev ) |
| { |
| // const SdrPageViewWinList& rWinList = pPageView->GetWinList(); |
| // const SdrPageViewWindows& rPageViewWindows = pPageView->GetPageViewWindows(); |
| |
| for( sal_uInt32 i = 0L; i < pPageView->PageWindowCount(); i++ ) |
| { |
| const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(i); |
| |
| if( rPageWindow.GetPaintWindow().OutputToWindow()) |
| { |
| pOutDev = &rPageWindow.GetPaintWindow().GetOutputDevice(); |
| break; |
| } |
| } |
| } |
| } |
| |
| if ( !pOutDev ) |
| return NULL; |
| |
| sal_Int32 nDataType = ::comphelper::getINT32(xField->getPropertyValue(FM_PROP_FIELDTYPE)); |
| if ((DataType::BINARY == nDataType) || (DataType::VARBINARY == nDataType)) |
| return NULL; |
| |
| ////////////////////////////////////////////////////////////////////// |
| // determine the control type by examining the data type of the bound column |
| sal_uInt16 nOBJID = 0; |
| sal_Bool bDateNTimeField = sal_False; |
| |
| sal_Bool bIsCurrency = sal_False; |
| if (::comphelper::hasProperty(FM_PROP_ISCURRENCY, xField)) |
| bIsCurrency = ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_ISCURRENCY)); |
| |
| if (bIsCurrency) |
| nOBJID = OBJ_FM_CURRENCYFIELD; |
| else |
| switch (nDataType) |
| { |
| case DataType::BLOB: |
| case DataType::LONGVARBINARY: |
| nOBJID = OBJ_FM_IMAGECONTROL; |
| break; |
| case DataType::LONGVARCHAR: |
| case DataType::CLOB: |
| nOBJID = OBJ_FM_EDIT; |
| break; |
| case DataType::BINARY: |
| case DataType::VARBINARY: |
| return NULL; |
| case DataType::BIT: |
| case DataType::BOOLEAN: |
| nOBJID = OBJ_FM_CHECKBOX; |
| break; |
| case DataType::TINYINT: |
| case DataType::SMALLINT: |
| case DataType::INTEGER: |
| nOBJID = OBJ_FM_NUMERICFIELD; |
| break; |
| case DataType::REAL: |
| case DataType::DOUBLE: |
| case DataType::NUMERIC: |
| case DataType::DECIMAL: |
| nOBJID = OBJ_FM_FORMATTEDFIELD; |
| break; |
| case DataType::TIMESTAMP: |
| bDateNTimeField = sal_True; |
| sLabelPostfix = String( SVX_RES( RID_STR_POSTFIX_DATE ) ); |
| // DON'T break ! |
| case DataType::DATE: |
| nOBJID = OBJ_FM_DATEFIELD; |
| break; |
| case DataType::TIME: |
| nOBJID = OBJ_FM_TIMEFIELD; |
| break; |
| case DataType::CHAR: |
| case DataType::VARCHAR: |
| default: |
| nOBJID = OBJ_FM_EDIT; |
| break; |
| } |
| if (!nOBJID) |
| return NULL; |
| |
| SdrUnoObj* pLabel( NULL ); |
| SdrUnoObj* pControl( NULL ); |
| if ( !createControlLabelPair( *pOutDev, 0, 0, xField, xNumberFormats, nOBJID, sLabelPostfix, |
| pLabel, pControl, xDataSource, sDataSource, sCommand, nCommandType ) |
| ) |
| { |
| return NULL; |
| } |
| |
| ////////////////////////////////////////////////////////////////////// |
| // group objects |
| bool bCheckbox = ( OBJ_FM_CHECKBOX == nOBJID ); |
| OSL_ENSURE( !bCheckbox || !pLabel, "FmXFormView::implCreateFieldControl: why was there a label created for a check box?" ); |
| if ( bCheckbox ) |
| return pControl; |
| |
| SdrObjGroup* pGroup = new SdrObjGroup(); |
| SdrObjList* pObjList = pGroup->GetSubList(); |
| pObjList->InsertObject( pLabel ); |
| pObjList->InsertObject( pControl ); |
| |
| if ( bDateNTimeField ) |
| { // so far we created a date field only, but we also need a time field |
| pLabel = pControl = NULL; |
| if ( createControlLabelPair( *pOutDev, 0, 1000, xField, xNumberFormats, OBJ_FM_TIMEFIELD, |
| String( SVX_RES( RID_STR_POSTFIX_TIME ) ), pLabel, pControl, |
| xDataSource, sDataSource, sCommand, nCommandType ) |
| ) |
| { |
| pObjList->InsertObject( pLabel ); |
| pObjList->InsertObject( pControl ); |
| } |
| } |
| |
| return pGroup; // und fertig |
| } |
| catch(const Exception&) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| |
| |
| return NULL; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| SdrObject* FmXFormView::implCreateXFormsControl( const ::svx::OXFormsDescriptor &_rDesc ) |
| { |
| // not if we're in design mode |
| if ( !m_pView->IsDesignMode() ) |
| return NULL; |
| |
| Reference< XComponent > xKeepFieldsAlive; |
| |
| // go |
| try |
| { |
| // determine the table/query field which we should create a control for |
| Reference< XNumberFormats > xNumberFormats; |
| ::rtl::OUString sLabelPostfix = _rDesc.szName; |
| |
| //////////////////////////////////////////////////////////////// |
| // nur fuer Textgroesse |
| OutputDevice* pOutDev = NULL; |
| if (m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW) |
| pOutDev = const_cast<OutputDevice*>(m_pView->GetActualOutDev()); |
| else |
| {// OutDev suchen |
| SdrPageView* pPageView = m_pView->GetSdrPageView(); |
| if( pPageView && !pOutDev ) |
| { |
| // const SdrPageViewWinList& rWinList = pPageView->GetWinList(); |
| // const SdrPageViewWindows& rPageViewWindows = pPageView->GetPageViewWindows(); |
| |
| for( sal_uInt32 i = 0L; i < pPageView->PageWindowCount(); i++ ) |
| { |
| const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(i); |
| |
| if( rPageWindow.GetPaintWindow().GetOutputDevice().GetOutDevType() == OUTDEV_WINDOW) |
| { |
| pOutDev = &rPageWindow.GetPaintWindow().GetOutputDevice(); |
| break; |
| } |
| } |
| } |
| } |
| |
| if ( !pOutDev ) |
| return NULL; |
| |
| ////////////////////////////////////////////////////////////////////// |
| // The service name decides which control should be created |
| sal_uInt16 nOBJID = OBJ_FM_EDIT; |
| if(::rtl::OUString(_rDesc.szServiceName).equals((::rtl::OUString)FM_SUN_COMPONENT_NUMERICFIELD)) |
| nOBJID = OBJ_FM_NUMERICFIELD; |
| if(::rtl::OUString(_rDesc.szServiceName).equals((::rtl::OUString)FM_SUN_COMPONENT_CHECKBOX)) |
| nOBJID = OBJ_FM_CHECKBOX; |
| if(::rtl::OUString(_rDesc.szServiceName).equals((::rtl::OUString)FM_COMPONENT_COMMANDBUTTON)) |
| nOBJID = OBJ_FM_BUTTON; |
| |
| typedef ::com::sun::star::form::submission::XSubmission XSubmission_t; |
| Reference< XSubmission_t > xSubmission(_rDesc.xPropSet, UNO_QUERY); |
| |
| // xform control or submission button? |
| if ( !xSubmission.is() ) |
| { |
| SdrUnoObj* pLabel( NULL ); |
| SdrUnoObj* pControl( NULL ); |
| if ( !createControlLabelPair( *pOutDev, 0, 0, NULL, xNumberFormats, nOBJID, sLabelPostfix, |
| pLabel, pControl ) |
| ) |
| { |
| return NULL; |
| } |
| |
| ////////////////////////////////////////////////////////////////////// |
| // Now build the connection between the control and the data item. |
| Reference< XValueBinding > xValueBinding(_rDesc.xPropSet,UNO_QUERY); |
| Reference< XBindableValue > xBindableValue(pControl->GetUnoControlModel(),UNO_QUERY); |
| |
| DBG_ASSERT( xBindableValue.is(), "FmXFormView::implCreateXFormsControl: control's not bindable!" ); |
| if ( xBindableValue.is() ) |
| xBindableValue->setValueBinding(xValueBinding); |
| |
| bool bCheckbox = ( OBJ_FM_CHECKBOX == nOBJID ); |
| OSL_ENSURE( !bCheckbox || !pLabel, "FmXFormView::implCreateXFormsControl: why was there a label created for a check box?" ); |
| if ( bCheckbox ) |
| return pControl; |
| |
| ////////////////////////////////////////////////////////////////////// |
| // group objects |
| SdrObjGroup* pGroup = new SdrObjGroup(); |
| SdrObjList* pObjList = pGroup->GetSubList(); |
| pObjList->InsertObject(pLabel); |
| pObjList->InsertObject(pControl); |
| |
| return pGroup; |
| } |
| else { |
| |
| // create a button control |
| const MapMode eTargetMode( pOutDev->GetMapMode() ); |
| const MapMode eSourceMode(MAP_100TH_MM); |
| const sal_uInt16 nObjID = OBJ_FM_BUTTON; |
| ::Size controlSize(4000, 500); |
| FmFormObj *pControl = static_cast<FmFormObj*>(SdrObjFactory::MakeNewObject( FmFormInventor, nObjID, NULL, NULL )); |
| controlSize.Width() = Fraction(controlSize.Width(), 1) * eTargetMode.GetScaleX(); |
| controlSize.Height() = Fraction(controlSize.Height(), 1) * eTargetMode.GetScaleY(); |
| ::Point controlPos( pOutDev->LogicToLogic( ::Point( controlSize.Width(), 0 ), eSourceMode, eTargetMode ) ); |
| ::Rectangle controlRect( controlPos, pOutDev->LogicToLogic( controlSize, eSourceMode, eTargetMode ) ); |
| pControl->SetLogicRect(controlRect); |
| |
| // set the button label |
| Reference< XPropertySet > xControlSet(pControl->GetUnoControlModel(), UNO_QUERY); |
| xControlSet->setPropertyValue(FM_PROP_LABEL, makeAny(::rtl::OUString(_rDesc.szName))); |
| |
| // connect the submission with the submission supplier (aka the button) |
| xControlSet->setPropertyValue( FM_PROP_BUTTON_TYPE, |
| makeAny( FormButtonType_SUBMIT ) ); |
| typedef ::com::sun::star::form::submission::XSubmissionSupplier XSubmissionSupplier_t; |
| Reference< XSubmissionSupplier_t > xSubmissionSupplier(pControl->GetUnoControlModel(), UNO_QUERY); |
| xSubmissionSupplier->setSubmission(xSubmission); |
| |
| return pControl; |
| } |
| } |
| catch(const Exception&) |
| { |
| DBG_ERROR("FmXFormView::implCreateXFormsControl: caught an exception while creating the control !"); |
| } |
| |
| |
| return NULL; |
| } |
| |
| //------------------------------------------------------------------------ |
| bool FmXFormView::createControlLabelPair( OutputDevice& _rOutDev, sal_Int32 _nXOffsetMM, sal_Int32 _nYOffsetMM, |
| const Reference< XPropertySet >& _rxField, const Reference< XNumberFormats >& _rxNumberFormats, |
| sal_uInt16 _nControlObjectID, const ::rtl::OUString& _rFieldPostfix, |
| SdrUnoObj*& _rpLabel, SdrUnoObj*& _rpControl, |
| const Reference< XDataSource >& _rxDataSource, const ::rtl::OUString& _rDataSourceName, |
| const ::rtl::OUString& _rCommand, const sal_Int32 _nCommandType ) |
| { |
| if ( !createControlLabelPair( m_aContext, _rOutDev, _nXOffsetMM, _nYOffsetMM, |
| _rxField, _rxNumberFormats, _nControlObjectID, _rFieldPostfix, FmFormInventor, OBJ_FM_FIXEDTEXT, |
| NULL, NULL, NULL, _rpLabel, _rpControl ) |
| ) |
| return false; |
| |
| // insert the control model(s) into the form component hierarchy |
| if ( _rpLabel ) |
| lcl_insertIntoFormComponentHierarchy_throw( *m_pView, *_rpLabel, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType ); |
| lcl_insertIntoFormComponentHierarchy_throw( *m_pView, *_rpControl, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType ); |
| |
| // some context-dependent initializations |
| FormControlFactory aControlFactory( m_aContext ); |
| if ( _rpLabel ) |
| aControlFactory.initializeControlModel( impl_getDocumentType(), *_rpLabel ); |
| aControlFactory.initializeControlModel( impl_getDocumentType(), *_rpControl ); |
| |
| return true; |
| } |
| |
| //------------------------------------------------------------------------ |
| bool FmXFormView::createControlLabelPair( const ::comphelper::ComponentContext& _rContext, |
| OutputDevice& _rOutDev, sal_Int32 _nXOffsetMM, sal_Int32 _nYOffsetMM, const Reference< XPropertySet >& _rxField, |
| const Reference< XNumberFormats >& _rxNumberFormats, sal_uInt16 _nControlObjectID, |
| const ::rtl::OUString& _rFieldPostfix, sal_uInt32 _nInventor, sal_uInt16 _nLabelObjectID, |
| SdrPage* _pLabelPage, SdrPage* _pControlPage, SdrModel* _pModel, SdrUnoObj*& _rpLabel, SdrUnoObj*& _rpControl) |
| { |
| sal_Int32 nDataType = 0; |
| ::rtl::OUString sFieldName; |
| Any aFieldName; |
| if ( _rxField.is() ) |
| { |
| nDataType = ::comphelper::getINT32(_rxField->getPropertyValue(FM_PROP_FIELDTYPE)); |
| aFieldName = Any(_rxField->getPropertyValue(FM_PROP_NAME)); |
| aFieldName >>= sFieldName; |
| } |
| |
| // calculate the positions, respecting the settings of the target device |
| ::Size aTextSize( _rOutDev.GetTextWidth(sFieldName + _rFieldPostfix), _rOutDev.GetTextHeight() ); |
| |
| MapMode eTargetMode( _rOutDev.GetMapMode() ), |
| eSourceMode( MAP_100TH_MM ); |
| |
| // Textbreite ist mindestens 4cm |
| // Texthoehe immer halber cm |
| ::Size aDefTxtSize(4000, 500); |
| ::Size aDefSize(4000, 500); |
| ::Size aDefImageSize(4000, 4000); |
| |
| ::Size aRealSize = _rOutDev.LogicToLogic(aTextSize, eTargetMode, eSourceMode); |
| aRealSize.Width() = std::max(aRealSize.Width(), aDefTxtSize.Width()); |
| aRealSize.Height()= aDefSize.Height(); |
| |
| // adjust to scaling of the target device (#53523#) |
| aRealSize.Width() = long(Fraction(aRealSize.Width(), 1) * eTargetMode.GetScaleX()); |
| aRealSize.Height() = long(Fraction(aRealSize.Height(), 1) * eTargetMode.GetScaleY()); |
| |
| // for boolean fields, we do not create a label, but just a checkbox |
| bool bNeedLabel = ( _nControlObjectID != OBJ_FM_CHECKBOX ); |
| |
| // the label |
| ::std::auto_ptr< SdrUnoObj > pLabel; |
| Reference< XPropertySet > xLabelModel; |
| if ( bNeedLabel ) |
| { |
| pLabel.reset( dynamic_cast< SdrUnoObj* >( |
| SdrObjFactory::MakeNewObject( _nInventor, _nLabelObjectID, _pLabelPage, _pModel ) ) ); |
| OSL_ENSURE( pLabel.get(), "FmXFormView::createControlLabelPair: could not create the label!" ); |
| if ( !pLabel.get() ) |
| return false; |
| |
| xLabelModel.set( pLabel->GetUnoControlModel(), UNO_QUERY ); |
| if ( xLabelModel.is() ) |
| { |
| ::rtl::OUString sLabel; |
| if ( _rxField.is() && _rxField->getPropertySetInfo()->hasPropertyByName(FM_PROP_LABEL) ) |
| _rxField->getPropertyValue(FM_PROP_LABEL) >>= sLabel; |
| if ( !sLabel.getLength() ) |
| sLabel = sFieldName; |
| |
| xLabelModel->setPropertyValue( FM_PROP_LABEL, makeAny( sLabel + _rFieldPostfix ) ); |
| String sObjectLabel( SVX_RES( RID_STR_OBJECT_LABEL ) ); |
| sObjectLabel.SearchAndReplaceAllAscii( "#object#", sFieldName ); |
| xLabelModel->setPropertyValue( FM_PROP_NAME, makeAny( ::rtl::OUString( sObjectLabel ) ) ); |
| } |
| |
| pLabel->SetLogicRect( ::Rectangle( |
| _rOutDev.LogicToLogic( ::Point( _nXOffsetMM, _nYOffsetMM ), eSourceMode, eTargetMode ), |
| _rOutDev.LogicToLogic( aRealSize, eSourceMode, eTargetMode ) |
| ) ); |
| } |
| |
| // the control |
| ::std::auto_ptr< SdrUnoObj > pControl( dynamic_cast< SdrUnoObj* >( |
| SdrObjFactory::MakeNewObject( _nInventor, _nControlObjectID, _pControlPage, _pModel ) ) ); |
| OSL_ENSURE( pControl.get(), "FmXFormView::createControlLabelPair: could not create the control!" ); |
| if ( !pControl.get() ) |
| return false; |
| |
| Reference< XPropertySet > xControlSet( pControl->GetUnoControlModel(), UNO_QUERY ); |
| if ( !xControlSet.is() ) |
| return false; |
| |
| // size of the control |
| ::Size aControlSize( aDefSize ); |
| switch ( nDataType ) |
| { |
| case DataType::BIT: |
| case DataType::BOOLEAN: |
| aControlSize = aDefSize; |
| break; |
| case DataType::LONGVARCHAR: |
| case DataType::CLOB: |
| case DataType::LONGVARBINARY: |
| case DataType::BLOB: |
| aControlSize = aDefImageSize; |
| break; |
| } |
| |
| if ( OBJ_FM_IMAGECONTROL == _nControlObjectID ) |
| aControlSize = aDefImageSize; |
| |
| aControlSize.Width() = long(Fraction(aControlSize.Width(), 1) * eTargetMode.GetScaleX()); |
| aControlSize.Height() = long(Fraction(aControlSize.Height(), 1) * eTargetMode.GetScaleY()); |
| |
| pControl->SetLogicRect( ::Rectangle( |
| _rOutDev.LogicToLogic( ::Point( aRealSize.Width() + _nXOffsetMM, _nYOffsetMM ), eSourceMode, eTargetMode ), |
| _rOutDev.LogicToLogic( aControlSize, eSourceMode, eTargetMode ) |
| ) ); |
| |
| // some initializations |
| Reference< XPropertySetInfo > xControlPropInfo = xControlSet->getPropertySetInfo(); |
| |
| if ( aFieldName.hasValue() ) |
| { |
| xControlSet->setPropertyValue( FM_PROP_CONTROLSOURCE, aFieldName ); |
| xControlSet->setPropertyValue( FM_PROP_NAME, aFieldName ); |
| if ( !bNeedLabel ) |
| { |
| // no dedicated label control => use the label property |
| if ( xControlPropInfo->hasPropertyByName( FM_PROP_LABEL ) ) |
| xControlSet->setPropertyValue( FM_PROP_LABEL, makeAny( sFieldName + _rFieldPostfix ) ); |
| else |
| OSL_ENSURE( false, "FmXFormView::createControlLabelPair: can't set a label for the control!" ); |
| } |
| } |
| |
| if ( (nDataType == DataType::LONGVARCHAR || nDataType == DataType::CLOB) && xControlPropInfo->hasPropertyByName( FM_PROP_MULTILINE ) ) |
| { |
| xControlSet->setPropertyValue( FM_PROP_MULTILINE, makeAny( sal_Bool( sal_True ) ) ); |
| } |
| |
| // announce the label to the control |
| if ( xControlPropInfo->hasPropertyByName( FM_PROP_CONTROLLABEL ) && xLabelModel.is() ) |
| { |
| try |
| { |
| xControlSet->setPropertyValue( FM_PROP_CONTROLLABEL, makeAny( xLabelModel ) ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| if ( _rxField.is() ) |
| { |
| FormControlFactory aControlFactory( _rContext ); |
| aControlFactory.initializeFieldDependentProperties( _rxField, xControlSet, _rxNumberFormats ); |
| } |
| |
| _rpLabel = pLabel.release(); |
| _rpControl = pControl.release(); |
| return true; |
| } |
| |
| //------------------------------------------------------------------------------ |
| FmXFormView::ObjectRemoveListener::ObjectRemoveListener( FmXFormView* pParent ) |
| :m_pParent( pParent ) |
| { |
| } |
| |
| //------------------------------------------------------------------------------ |
| void FmXFormView::ObjectRemoveListener::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) |
| { |
| if (rHint.ISA(SdrHint) && (((SdrHint&)rHint).GetKind() == HINT_OBJREMOVED)) |
| m_pParent->ObjectRemovedInAliveMode(((SdrHint&)rHint).GetObject()); |
| } |
| |
| //------------------------------------------------------------------------------ |
| void FmXFormView::ObjectRemovedInAliveMode( const SdrObject* pObject ) |
| { |
| // wenn das entfernte Objekt in meiner MarkList, die ich mir beim Umschalten in den Alive-Mode gemerkt habe, steht, |
| // muss ich es jetzt da rausnehmen, da ich sonst beim Zurueckschalten versuche, die Markierung wieder zu setzen |
| // (interesanterweise geht das nur bei gruppierten Objekten schief (beim Zugriff auf deren ObjList GPF), nicht bei einzelnen) |
| |
| sal_uIntPtr nCount = m_aMark.GetMarkCount(); |
| for (sal_uIntPtr i = 0; i < nCount; ++i) |
| { |
| SdrMark* pMark = m_aMark.GetMark(i); |
| SdrObject* pCurrent = pMark->GetMarkedSdrObj(); |
| if (pObject == pCurrent) |
| { |
| m_aMark.DeleteMark(i); |
| return; |
| } |
| // ich brauche nicht in GroupObjects absteigen : wenn dort unten ein Objekt geloescht wird, dann bleibt der |
| // Zeiger auf das GroupObject, den ich habe, trotzdem weiter gueltig bleibt ... |
| } |
| } |
| |
| //------------------------------------------------------------------------------ |
| void FmXFormView::stopMarkListWatching() |
| { |
| if ( m_pWatchStoredList ) |
| { |
| m_pWatchStoredList->EndListeningAll(); |
| delete m_pWatchStoredList; |
| m_pWatchStoredList = NULL; |
| } |
| } |
| |
| //------------------------------------------------------------------------------ |
| void FmXFormView::startMarkListWatching() |
| { |
| if ( !m_pWatchStoredList ) |
| { |
| m_pWatchStoredList = new ObjectRemoveListener( this ); |
| FmFormModel* pModel = GetFormShell() ? GetFormShell()->GetFormModel() : NULL; |
| DBG_ASSERT( pModel != NULL, "FmXFormView::startMarkListWatching: shell has no model!" ); |
| m_pWatchStoredList->StartListening( *static_cast< SfxBroadcaster* >( pModel ) ); |
| } |
| else |
| { |
| DBG_ERROR( "FmXFormView::startMarkListWatching: already listening!" ); |
| } |
| } |
| |
| //------------------------------------------------------------------------------ |
| void FmXFormView::saveMarkList( sal_Bool _bSmartUnmark ) |
| { |
| if ( m_pView ) |
| { |
| m_aMark = m_pView->GetMarkedObjectList(); |
| if ( _bSmartUnmark ) |
| { |
| sal_uIntPtr nCount = m_aMark.GetMarkCount( ); |
| for ( sal_uIntPtr i = 0; i < nCount; ++i ) |
| { |
| SdrMark* pMark = m_aMark.GetMark(i); |
| SdrObject* pObj = pMark->GetMarkedSdrObj(); |
| |
| if ( m_pView->IsObjMarked( pObj ) ) |
| { |
| if ( pObj->IsGroupObject() ) |
| { |
| SdrObjListIter aIter( *pObj->GetSubList() ); |
| sal_Bool bMixed = sal_False; |
| while ( aIter.IsMore() && !bMixed ) |
| bMixed = ( aIter.Next()->GetObjInventor() != FmFormInventor ); |
| |
| if ( !bMixed ) |
| { |
| // all objects in the group are form objects |
| m_pView->MarkObj( pMark->GetMarkedSdrObj(), pMark->GetPageView(), sal_True /* unmark! */ ); |
| } |
| } |
| else |
| { |
| if ( pObj->GetObjInventor() == FmFormInventor ) |
| { // this is a form layer object |
| m_pView->MarkObj( pMark->GetMarkedSdrObj(), pMark->GetPageView(), sal_True /* unmark! */ ); |
| } |
| } |
| } |
| } |
| } |
| } |
| else |
| { |
| DBG_ERROR( "FmXFormView::saveMarkList: invalid view!" ); |
| m_aMark = SdrMarkList(); |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| static sal_Bool lcl_hasObject( SdrObjListIter& rIter, SdrObject* pObj ) |
| { |
| sal_Bool bFound = sal_False; |
| while (rIter.IsMore() && !bFound) |
| bFound = pObj == rIter.Next(); |
| |
| rIter.Reset(); |
| return bFound; |
| } |
| |
| //------------------------------------------------------------------------------ |
| void FmXFormView::restoreMarkList( SdrMarkList& _rRestoredMarkList ) |
| { |
| if ( !m_pView ) |
| return; |
| |
| _rRestoredMarkList.Clear(); |
| |
| const SdrMarkList& rCurrentList = m_pView->GetMarkedObjectList(); |
| FmFormPage* pPage = GetFormShell() ? GetFormShell()->GetCurPage() : NULL; |
| if (pPage) |
| { |
| if (rCurrentList.GetMarkCount()) |
| { // there is a current mark ... hmm. Is it a subset of the mark we remembered in saveMarkList? |
| sal_Bool bMisMatch = sal_False; |
| |
| // loop through all current marks |
| sal_uIntPtr nCurrentCount = rCurrentList.GetMarkCount(); |
| for ( sal_uIntPtr i=0; i<nCurrentCount&& !bMisMatch; ++i ) |
| { |
| const SdrObject* pCurrentMarked = rCurrentList.GetMark( i )->GetMarkedSdrObj(); |
| |
| // loop through all saved marks, check for equality |
| sal_Bool bFound = sal_False; |
| sal_uIntPtr nSavedCount = m_aMark.GetMarkCount(); |
| for ( sal_uIntPtr j=0; j<nSavedCount && !bFound; ++j ) |
| { |
| if ( m_aMark.GetMark( j )->GetMarkedSdrObj() == pCurrentMarked ) |
| bFound = sal_True; |
| } |
| |
| // did not find a current mark in the saved marks |
| if ( !bFound ) |
| bMisMatch = sal_True; |
| } |
| |
| if ( bMisMatch ) |
| { |
| m_aMark.Clear(); |
| _rRestoredMarkList = rCurrentList; |
| return; |
| } |
| } |
| // wichtig ist das auf die Objecte der markliste nicht zugegriffen wird |
| // da diese bereits zerstoert sein koennen |
| SdrPageView* pCurPageView = m_pView->GetSdrPageView(); |
| SdrObjListIter aPageIter( *pPage ); |
| sal_Bool bFound = sal_True; |
| |
| // gibt es noch alle Objecte |
| sal_uIntPtr nCount = m_aMark.GetMarkCount(); |
| for (sal_uIntPtr i = 0; i < nCount && bFound; i++) |
| { |
| SdrMark* pMark = m_aMark.GetMark(i); |
| SdrObject* pObj = pMark->GetMarkedSdrObj(); |
| if (pObj->IsGroupObject()) |
| { |
| SdrObjListIter aIter(*pObj->GetSubList()); |
| while (aIter.IsMore() && bFound) |
| bFound = lcl_hasObject(aPageIter, aIter.Next()); |
| } |
| else |
| bFound = lcl_hasObject(aPageIter, pObj); |
| |
| bFound = bFound && pCurPageView == pMark->GetPageView(); |
| } |
| |
| if (bFound) |
| { |
| // Das LastObject auswerten |
| if (nCount) // Objecte jetzt Markieren |
| { |
| for (sal_uIntPtr i = 0; i < nCount; i++) |
| { |
| SdrMark* pMark = m_aMark.GetMark(i); |
| SdrObject* pObj = pMark->GetMarkedSdrObj(); |
| if ( pObj->GetObjInventor() == FmFormInventor ) |
| if ( !m_pView->IsObjMarked( pObj ) ) |
| m_pView->MarkObj( pObj, pMark->GetPageView() ); |
| } |
| |
| _rRestoredMarkList = m_aMark; |
| } |
| } |
| m_aMark.Clear(); |
| } |
| } |
| // ----------------------------------------------------------------------------- |
| void SAL_CALL FmXFormView::focusGained( const FocusEvent& /*e*/ ) throw (RuntimeException) |
| { |
| if ( m_xWindow.is() && m_pView ) |
| { |
| m_pView->SetMoveOutside( sal_True, FmFormView::ImplAccess() ); |
| } |
| } |
| // ----------------------------------------------------------------------------- |
| void SAL_CALL FmXFormView::focusLost( const FocusEvent& /*e*/ ) throw (RuntimeException) |
| { |
| // when switch the focus outside the office the mark didn't change |
| // so we can not remove us as focus listener |
| if ( m_xWindow.is() && m_pView ) |
| { |
| m_pView->SetMoveOutside( sal_False, FmFormView::ImplAccess() ); |
| } |
| } |
| // ----------------------------------------------------------------------------- |
| void FmXFormView::removeGridWindowListening() |
| { |
| if ( m_xWindow.is() ) |
| { |
| m_xWindow->removeFocusListener(this); |
| if ( m_pView ) |
| { |
| m_pView->SetMoveOutside( sal_False, FmFormView::ImplAccess() ); |
| } |
| m_xWindow = NULL; |
| } |
| } |
| |
| // ----------------------------------------------------------------------------- |
| DocumentType FmXFormView::impl_getDocumentType() const |
| { |
| if ( GetFormShell() && GetFormShell()->GetImpl() ) |
| return GetFormShell()->GetImpl()->getDocumentType(); |
| return eUnknownDocumentType; |
| } |