bump product version to 4.1.6.2
[LibreOffice.git] / svx / source / form / fmvwimp.cxx
blob3dc99ea74da43f1ae985a1b9e9eba1e4e4633334
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "fmdocumentclassification.hxx"
22 #include "fmobj.hxx"
23 #include "fmpgeimp.hxx"
24 #include "fmprop.hrc"
25 #include "svx/fmresids.hrc"
26 #include "fmservs.hxx"
27 #include "fmshimp.hxx"
28 #include "svx/fmtools.hxx"
29 #include "fmundo.hxx"
30 #include "fmvwimp.hxx"
31 #include "formcontrolfactory.hxx"
32 #include "svx/sdrpaintwindow.hxx"
33 #include "svx/svditer.hxx"
34 #include "svx/dataaccessdescriptor.hxx"
35 #include "svx/dialmgr.hxx"
36 #include "svx/fmglob.hxx"
37 #include "svx/fmmodel.hxx"
38 #include "svx/fmpage.hxx"
39 #include "svx/fmshell.hxx"
40 #include "svx/fmview.hxx"
41 #include "svx/sdrpagewindow.hxx"
42 #include "svx/svdogrp.hxx"
43 #include "svx/svdpagv.hxx"
44 #include "svx/xmlexchg.hxx"
46 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
47 #include <com/sun/star/style/VerticalAlignment.hpp>
48 #include <com/sun/star/lang/XInitialization.hpp>
49 #include <com/sun/star/sdbc/XRowSet.hpp>
50 #include <com/sun/star/form/XLoadable.hpp>
51 #include <com/sun/star/awt/VisualEffect.hpp>
52 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
53 #include <com/sun/star/util/XNumberFormats.hpp>
54 #include <com/sun/star/sdb/CommandType.hpp>
55 #include <com/sun/star/sdbc/DataType.hpp>
56 #include <com/sun/star/sdbc/ColumnValue.hpp>
57 #include <com/sun/star/form/FormComponentType.hpp>
58 #include <com/sun/star/form/FormButtonType.hpp>
59 #include <com/sun/star/form/XReset.hpp>
60 #include <com/sun/star/form/binding/XBindableValue.hpp>
61 #include <com/sun/star/form/binding/XValueBinding.hpp>
62 #include <com/sun/star/form/runtime/FormController.hpp>
63 #include <com/sun/star/form/submission/XSubmissionSupplier.hpp>
64 #include <com/sun/star/awt/XTabControllerModel.hpp>
65 #include <com/sun/star/awt/XControlContainer.hpp>
66 #include <com/sun/star/awt/XTabController.hpp>
67 #include <com/sun/star/container/XIndexAccess.hpp>
68 #include <com/sun/star/awt/XControl.hpp>
69 #include <com/sun/star/lang/XUnoTunnel.hpp>
70 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
71 #include <com/sun/star/sdbc/XPreparedStatement.hpp>
72 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
73 #include <com/sun/star/container/XContainer.hpp>
75 #include <comphelper/enumhelper.hxx>
76 #include <comphelper/extract.hxx>
77 #include <comphelper/namedvaluecollection.hxx>
78 #include <comphelper/numbers.hxx>
79 #include <comphelper/property.hxx>
80 #include <cppuhelper/exc_hlp.hxx>
81 #include <unotools/moduleoptions.hxx>
82 #include <tools/diagnose_ex.h>
83 #include <vcl/msgbox.hxx>
84 #include <vcl/stdtext.hxx>
85 #include <osl/mutex.hxx>
86 #include <rtl/logfile.hxx>
88 #include <algorithm>
90 using namespace ::comphelper;
91 using namespace ::svx;
92 using namespace ::svxform;
94 using namespace ::com::sun::star;
95 using ::com::sun::star::uno::Exception;
96 using ::com::sun::star::uno::RuntimeException;
97 using ::com::sun::star::uno::XInterface;
98 using ::com::sun::star::uno::Sequence;
99 using ::com::sun::star::uno::UNO_QUERY;
100 using ::com::sun::star::uno::UNO_QUERY_THROW;
101 using ::com::sun::star::uno::UNO_SET_THROW;
102 using ::com::sun::star::uno::Type;
103 using ::com::sun::star::uno::Reference;
104 using ::com::sun::star::uno::Any;
105 using ::com::sun::star::uno::makeAny;
106 using ::com::sun::star::style::VerticalAlignment_MIDDLE;
107 using ::com::sun::star::form::FormButtonType_SUBMIT;
108 using ::com::sun::star::form::binding::XValueBinding;
109 using ::com::sun::star::form::binding::XBindableValue;
110 using ::com::sun::star::lang::XComponent;
111 using ::com::sun::star::container::XIndexAccess;
112 using ::com::sun::star::form::runtime::FormController;
113 using ::com::sun::star::form::runtime::XFormController;
114 using ::com::sun::star::script::XEventAttacherManager;
115 using ::com::sun::star::awt::XTabControllerModel;
116 using ::com::sun::star::container::XChild;
117 using ::com::sun::star::container::XEnumeration;
118 using ::com::sun::star::task::XInteractionHandler;
119 using ::com::sun::star::lang::XInitialization;
120 using ::com::sun::star::awt::XTabController;
121 using ::com::sun::star::lang::XUnoTunnel;
122 using ::com::sun::star::awt::XControlContainer;
123 using ::com::sun::star::awt::XControl;
124 using ::com::sun::star::form::XFormComponent;
125 using ::com::sun::star::form::XForm;
126 using ::com::sun::star::lang::IndexOutOfBoundsException;
127 using ::com::sun::star::lang::WrappedTargetException;
128 using ::com::sun::star::container::XContainer;
129 using ::com::sun::star::container::ContainerEvent;
130 using ::com::sun::star::lang::EventObject;
131 using ::com::sun::star::beans::NamedValue;
132 using ::com::sun::star::sdb::SQLErrorEvent;
133 using ::com::sun::star::sdbc::XRowSet;
134 using ::com::sun::star::beans::XPropertySet;
135 using ::com::sun::star::container::XElementAccess;
136 using ::com::sun::star::awt::XWindow;
137 using ::com::sun::star::awt::FocusEvent;
138 using ::com::sun::star::ui::dialogs::XExecutableDialog;
139 using ::com::sun::star::sdbc::XDataSource;
140 using ::com::sun::star::container::XIndexContainer;
141 using ::com::sun::star::sdbc::XConnection;
142 using ::com::sun::star::container::XNameAccess;
143 using ::com::sun::star::sdb::SQLContext;
144 using ::com::sun::star::sdbc::SQLWarning;
145 using ::com::sun::star::sdbc::SQLException;
146 using ::com::sun::star::util::XNumberFormatsSupplier;
147 using ::com::sun::star::util::XNumberFormats;
148 using ::com::sun::star::beans::XPropertySetInfo;
150 namespace FormComponentType = ::com::sun::star::form::FormComponentType;
151 namespace CommandType = ::com::sun::star::sdb::CommandType;
152 namespace DataType = ::com::sun::star::sdbc::DataType;
154 //------------------------------------------------------------------------------
155 class FmXFormView::ObjectRemoveListener : public SfxListener
157 FmXFormView* m_pParent;
158 public:
159 ObjectRemoveListener( FmXFormView* pParent );
160 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
163 //========================================================================
164 DBG_NAME(FormViewPageWindowAdapter)
165 //------------------------------------------------------------------------
166 FormViewPageWindowAdapter::FormViewPageWindowAdapter( const ::comphelper::ComponentContext& _rContext, const SdrPageWindow& _rWindow, FmXFormView* _pViewImpl )
167 : m_xControlContainer( _rWindow.GetControlContainer() ),
168 m_aContext( _rContext ),
169 m_pViewImpl( _pViewImpl ),
170 m_pWindow( dynamic_cast< Window* >( &_rWindow.GetPaintWindow().GetOutputDevice() ) )
172 DBG_CTOR(FormViewPageWindowAdapter,NULL);
174 // create an XFormController for every form
175 FmFormPage* pFormPage = dynamic_cast< FmFormPage* >( _rWindow.GetPageView().GetPage() );
176 DBG_ASSERT( pFormPage, "FormViewPageWindowAdapter::FormViewPageWindowAdapter: no FmFormPage found!" );
177 if ( pFormPage )
181 Reference< XIndexAccess > xForms( pFormPage->GetForms(), UNO_QUERY_THROW );
182 sal_uInt32 nLength = xForms->getCount();
183 for (sal_uInt32 i = 0; i < nLength; i++)
185 Reference< XForm > xForm( xForms->getByIndex(i), UNO_QUERY );
186 if ( xForm.is() )
187 setController( xForm, NULL );
190 catch (const Exception&)
192 DBG_UNHANDLED_EXCEPTION();
196 // -----------------------------------------------------------------------------
197 FormViewPageWindowAdapter::~FormViewPageWindowAdapter()
199 DBG_DTOR(FormViewPageWindowAdapter,NULL);
202 //------------------------------------------------------------------
203 void FormViewPageWindowAdapter::dispose()
205 for ( ::std::vector< Reference< XFormController > >::const_iterator i = m_aControllerList.begin();
206 i != m_aControllerList.end();
212 Reference< XFormController > xController( *i, UNO_QUERY_THROW );
214 // detaching the events
215 Reference< XChild > xControllerModel( xController->getModel(), UNO_QUERY );
216 if ( xControllerModel.is() )
218 Reference< XEventAttacherManager > xEventManager( xControllerModel->getParent(), UNO_QUERY_THROW );
219 Reference< XInterface > xControllerNormalized( xController, UNO_QUERY_THROW );
220 xEventManager->detach( i - m_aControllerList.begin(), xControllerNormalized );
223 // dispose the formcontroller
224 Reference< XComponent > xComp( xController, UNO_QUERY_THROW );
225 xComp->dispose();
227 catch (const Exception&)
229 DBG_UNHANDLED_EXCEPTION();
233 m_aControllerList.clear();
237 //------------------------------------------------------------------------------
238 sal_Bool SAL_CALL FormViewPageWindowAdapter::hasElements(void) throw( RuntimeException )
240 return getCount() != 0;
243 //------------------------------------------------------------------------------
244 Type SAL_CALL FormViewPageWindowAdapter::getElementType(void) throw( RuntimeException )
246 return ::getCppuType((const Reference< XFormController>*)0);
249 // XEnumerationAccess
250 //------------------------------------------------------------------------------
251 Reference< XEnumeration > SAL_CALL FormViewPageWindowAdapter::createEnumeration(void) throw( RuntimeException )
253 return new ::comphelper::OEnumerationByIndex(this);
256 // XIndexAccess
257 //------------------------------------------------------------------------------
258 sal_Int32 SAL_CALL FormViewPageWindowAdapter::getCount(void) throw( RuntimeException )
260 return m_aControllerList.size();
263 //------------------------------------------------------------------------------
264 Any SAL_CALL FormViewPageWindowAdapter::getByIndex(sal_Int32 nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
266 if (nIndex < 0 ||
267 nIndex >= getCount())
268 throw IndexOutOfBoundsException();
270 Any aElement;
271 aElement <<= m_aControllerList[nIndex];
272 return aElement;
275 //------------------------------------------------------------------------
276 void SAL_CALL FormViewPageWindowAdapter::makeVisible( const Reference< XControl >& _Control ) throw (RuntimeException)
278 SolarMutexGuard aSolarGuard;
280 Reference< XWindow > xWindow( _Control, UNO_QUERY );
281 if ( xWindow.is() && m_pViewImpl->getView() && m_pWindow )
283 awt::Rectangle aRect = xWindow->getPosSize();
284 ::Rectangle aNewRect( aRect.X, aRect.Y, aRect.X + aRect.Width, aRect.Y + aRect.Height );
285 aNewRect = m_pWindow->PixelToLogic( aNewRect );
286 m_pViewImpl->getView()->MakeVisible( aNewRect, *m_pWindow );
290 //------------------------------------------------------------------------
291 Reference< XFormController > getControllerSearchChildren( const Reference< XIndexAccess > & xIndex, const Reference< XTabControllerModel > & xModel)
293 if (xIndex.is() && xIndex->getCount())
295 Reference< XFormController > xController;
297 for (sal_Int32 n = xIndex->getCount(); n-- && !xController.is(); )
299 xIndex->getByIndex(n) >>= xController;
300 if ((XTabControllerModel*)xModel.get() == (XTabControllerModel*)xController->getModel().get())
301 return xController;
302 else
304 xController = getControllerSearchChildren(Reference< XIndexAccess > (xController, UNO_QUERY), xModel);
305 if ( xController.is() )
306 return xController;
310 return Reference< XFormController > ();
313 // Search the according controller
314 //------------------------------------------------------------------------
315 Reference< XFormController > FormViewPageWindowAdapter::getController( const Reference< XForm > & xForm ) const
317 Reference< XTabControllerModel > xModel(xForm, UNO_QUERY);
318 for (::std::vector< Reference< XFormController > >::const_iterator i = m_aControllerList.begin();
319 i != m_aControllerList.end(); ++i)
321 if ((XTabControllerModel*)(*i)->getModel().get() == (XTabControllerModel*)xModel.get())
322 return *i;
324 // the current-round controller isn't the right one. perhaps one of it's children ?
325 Reference< XFormController > xChildSearch = getControllerSearchChildren(Reference< XIndexAccess > (*i, UNO_QUERY), xModel);
326 if (xChildSearch.is())
327 return xChildSearch;
329 return Reference< XFormController > ();
332 //------------------------------------------------------------------------
333 void FormViewPageWindowAdapter::setController(const Reference< XForm > & xForm, const Reference< XFormController >& _rxParentController )
335 DBG_ASSERT( xForm.is(), "FormViewPageWindowAdapter::setController: there should be a form!" );
336 Reference< XIndexAccess > xFormCps(xForm, UNO_QUERY);
337 if (!xFormCps.is())
338 return;
340 Reference< XTabControllerModel > xTabOrder(xForm, UNO_QUERY);
342 // create a form controller
343 Reference< XFormController > xController( FormController::create(m_aContext.getUNOContext()) );
345 Reference< XInteractionHandler > xHandler;
346 if ( _rxParentController.is() )
347 xHandler = _rxParentController->getInteractionHandler();
348 else
350 // TODO: should we create a default handler? Not really necessary, since the
351 // FormController itself has a default fallback
353 if ( xHandler.is() )
354 xController->setInteractionHandler( xHandler );
356 xController->setContext( this );
358 xController->setModel( xTabOrder );
359 xController->setContainer( m_xControlContainer );
360 xController->activateTabOrder();
361 xController->addActivateListener( m_pViewImpl );
363 if ( _rxParentController.is() )
364 _rxParentController->addChildController( xController );
365 else
367 m_aControllerList.push_back(xController);
369 xController->setParent( *this );
371 // attaching the events
372 Reference< XEventAttacherManager > xEventManager( xForm->getParent(), UNO_QUERY );
373 Reference< XInterface > xIfc(xController, UNO_QUERY);
374 xEventManager->attach(m_aControllerList.size() - 1, xIfc, makeAny(xController) );
377 // jetzt die Subforms durchgehen
378 sal_uInt32 nLength = xFormCps->getCount();
379 Reference< XForm > xSubForm;
380 for (sal_uInt32 i = 0; i < nLength; i++)
382 if ( xFormCps->getByIndex(i) >>= xSubForm )
383 setController( xSubForm, xController );
387 //------------------------------------------------------------------------
388 void FormViewPageWindowAdapter::updateTabOrder( const Reference< XForm >& _rxForm )
390 OSL_PRECOND( _rxForm.is(), "FormViewPageWindowAdapter::updateTabOrder: illegal argument!" );
391 if ( !_rxForm.is() )
392 return;
396 Reference< XTabController > xTabCtrl( getController( _rxForm ).get() );
397 if ( xTabCtrl.is() )
398 { // if there already is a TabController for this form, then delegate the "updateTabOrder" request
399 xTabCtrl->activateTabOrder();
401 else
402 { // otherwise, create a TabController
404 // if it's a sub form, then we must ensure there exist TabControllers
405 // for all its ancestors, too
406 Reference< XForm > xParentForm( _rxForm->getParent(), UNO_QUERY );
407 // there is a parent form -> look for the respective controller
408 Reference< XFormController > xParentController;
409 if ( xParentForm.is() )
410 xParentController.set( getController( xParentForm ), UNO_QUERY );
412 setController( _rxForm, xParentController );
415 catch (const Exception&)
417 DBG_UNHANDLED_EXCEPTION();
421 //------------------------------------------------------------------------
422 FmXFormView::FmXFormView(const ::comphelper::ComponentContext& _rContext, FmFormView* _pView )
423 :m_aContext( _rContext )
424 ,m_pMarkedGrid(NULL)
425 ,m_pView(_pView)
426 ,m_nActivationEvent(0)
427 ,m_nErrorMessageEvent( 0 )
428 ,m_nAutoFocusEvent( 0 )
429 ,m_nControlWizardEvent( 0 )
430 ,m_pWatchStoredList( NULL )
431 ,m_bFirstActivation( true )
432 ,m_isTabOrderUpdateSuspended( false )
436 //------------------------------------------------------------------------
437 void FmXFormView::cancelEvents()
439 if ( m_nActivationEvent )
441 Application::RemoveUserEvent( m_nActivationEvent );
442 m_nActivationEvent = 0;
445 if ( m_nErrorMessageEvent )
447 Application::RemoveUserEvent( m_nErrorMessageEvent );
448 m_nErrorMessageEvent = 0;
451 if ( m_nAutoFocusEvent )
453 Application::RemoveUserEvent( m_nAutoFocusEvent );
454 m_nAutoFocusEvent = 0;
457 if ( m_nControlWizardEvent )
459 Application::RemoveUserEvent( m_nControlWizardEvent );
460 m_nControlWizardEvent = 0;
464 //------------------------------------------------------------------------
465 void FmXFormView::notifyViewDying( )
467 DBG_ASSERT( m_pView, "FmXFormView::notifyViewDying: my view already died!" );
468 m_pView = NULL;
469 cancelEvents();
472 //------------------------------------------------------------------------
473 FmXFormView::~FmXFormView()
475 DBG_ASSERT( m_aPageWindowAdapters.empty(), "FmXFormView::~FmXFormView: Window list not empty!" );
476 if ( !m_aPageWindowAdapters.empty() )
478 for ( PageWindowAdapterList::const_iterator loop = m_aPageWindowAdapters.begin();
479 loop != m_aPageWindowAdapters.end();
480 ++loop
483 (*loop)->dispose();
487 cancelEvents();
489 delete m_pWatchStoredList;
490 m_pWatchStoredList = NULL;
493 // EventListener
494 //------------------------------------------------------------------------------
495 void SAL_CALL FmXFormView::disposing(const EventObject& Source) throw( RuntimeException )
497 if ( m_xWindow.is() && Source.Source == m_xWindow )
498 removeGridWindowListening();
501 // XFormControllerListener
502 //------------------------------------------------------------------------------
503 void SAL_CALL FmXFormView::formActivated(const EventObject& rEvent) throw( RuntimeException )
505 if ( m_pView && m_pView->GetFormShell() && m_pView->GetFormShell()->GetImpl() )
506 m_pView->GetFormShell()->GetImpl()->formActivated( rEvent );
509 //------------------------------------------------------------------------------
510 void SAL_CALL FmXFormView::formDeactivated(const EventObject& rEvent) throw( RuntimeException )
512 if ( m_pView && m_pView->GetFormShell() && m_pView->GetFormShell()->GetImpl() )
513 m_pView->GetFormShell()->GetImpl()->formDeactivated( rEvent );
516 // XContainerListener
517 //------------------------------------------------------------------------------
518 void SAL_CALL FmXFormView::elementInserted(const ContainerEvent& evt) throw( RuntimeException )
522 Reference< XControlContainer > xControlContainer( evt.Source, UNO_QUERY_THROW );
523 Reference< XControl > xControl( evt.Element, UNO_QUERY_THROW );
524 Reference< XFormComponent > xControlModel( xControl->getModel(), UNO_QUERY_THROW );
525 Reference< XForm > xForm( xControlModel->getParent(), UNO_QUERY_THROW );
527 if ( m_isTabOrderUpdateSuspended )
529 // remember the container and the control, so we can update the tab order on resumeTabOrderUpdate
530 m_aNeedTabOrderUpdate[ xControlContainer ].insert( xForm );
532 else
534 PFormViewPageWindowAdapter pAdapter = findWindow( xControlContainer );
535 if ( pAdapter.is() )
536 pAdapter->updateTabOrder( xForm );
539 catch (const Exception&)
541 DBG_UNHANDLED_EXCEPTION();
545 //------------------------------------------------------------------------------
546 void SAL_CALL FmXFormView::elementReplaced(const ContainerEvent& evt) throw( RuntimeException )
548 elementInserted(evt);
551 //------------------------------------------------------------------------------
552 void SAL_CALL FmXFormView::elementRemoved(const ContainerEvent& /*evt*/) throw( RuntimeException )
556 //------------------------------------------------------------------------------
557 PFormViewPageWindowAdapter FmXFormView::findWindow( const Reference< XControlContainer >& _rxCC ) const
559 for ( PageWindowAdapterList::const_iterator i = m_aPageWindowAdapters.begin();
560 i != m_aPageWindowAdapters.end();
564 if ( _rxCC == (*i)->getControlContainer() )
565 return *i;
567 return NULL;
570 //------------------------------------------------------------------------------
571 void FmXFormView::addWindow(const SdrPageWindow& rWindow)
573 FmFormPage* pFormPage = PTR_CAST( FmFormPage, rWindow.GetPageView().GetPage() );
574 if ( !pFormPage )
575 return;
577 Reference< XControlContainer > xCC = rWindow.GetControlContainer();
578 if ( xCC.is()
579 && ( !findWindow( xCC ).is() )
582 PFormViewPageWindowAdapter pAdapter = new FormViewPageWindowAdapter( m_aContext, rWindow, this );
583 m_aPageWindowAdapters.push_back( pAdapter );
585 // Am ControlContainer horchen um Aenderungen mitzbekommen
586 Reference< XContainer > xContainer( xCC, UNO_QUERY );
587 if ( xContainer.is() )
588 xContainer->addContainerListener( this );
592 //------------------------------------------------------------------------------
593 void FmXFormView::removeWindow( const Reference< XControlContainer >& _rxCC )
595 // Wird gerufen, wenn
596 // - in den Design-Modus geschaltet wird
597 // - ein Window geloescht wird, waehrend man im Design-Modus ist
598 // - der Control-Container fuer ein Window entfernt wird, waehrend
599 // der aktive Modus eingeschaltet ist.
601 for ( PageWindowAdapterList::iterator i = m_aPageWindowAdapters.begin();
602 i != m_aPageWindowAdapters.end();
606 if ( _rxCC != (*i)->getControlContainer() )
607 continue;
609 Reference< XContainer > xContainer( _rxCC, UNO_QUERY );
610 if ( xContainer.is() )
611 xContainer->removeContainerListener( this );
613 (*i)->dispose();
614 m_aPageWindowAdapters.erase( i );
615 break;
619 //------------------------------------------------------------------------------
620 void FmXFormView::displayAsyncErrorMessage( const SQLErrorEvent& _rEvent )
622 DBG_ASSERT( 0 == m_nErrorMessageEvent, "FmXFormView::displayAsyncErrorMessage: not too fast, please!" );
623 // This should not happen - usually, the PostUserEvent is faster than any possible user
624 // interaction which could trigger a new error. If it happens, we need a queue for the events.
625 m_aAsyncError = _rEvent;
626 m_nErrorMessageEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnDelayedErrorMessage ) );
629 //------------------------------------------------------------------------------
630 IMPL_LINK(FmXFormView, OnDelayedErrorMessage, void*, /*EMPTYTAG*/)
632 m_nErrorMessageEvent = 0;
633 displayException( m_aAsyncError );
634 return 0L;
637 //------------------------------------------------------------------------------
638 void FmXFormView::onFirstViewActivation( const FmFormModel* _pDocModel )
640 if ( _pDocModel && _pDocModel->GetAutoControlFocus() )
641 m_nAutoFocusEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnAutoFocus ) );
644 //------------------------------------------------------------------------------
645 void FmXFormView::suspendTabOrderUpdate()
647 OSL_ENSURE( !m_isTabOrderUpdateSuspended, "FmXFormView::suspendTabOrderUpdate: nesting not allowed!" );
648 m_isTabOrderUpdateSuspended = true;
651 //------------------------------------------------------------------------------
652 void FmXFormView::resumeTabOrderUpdate()
654 OSL_ENSURE( m_isTabOrderUpdateSuspended, "FmXFormView::resumeTabOrderUpdate: not suspended!" );
655 m_isTabOrderUpdateSuspended = false;
657 // update the tab orders for all components which were collected since the suspendTabOrderUpdate call.
658 for ( MapControlContainerToSetOfForms::const_iterator container = m_aNeedTabOrderUpdate.begin();
659 container != m_aNeedTabOrderUpdate.end();
660 ++container
663 PFormViewPageWindowAdapter pAdapter = findWindow( container->first );
664 if ( !pAdapter.is() )
665 continue;
667 for ( SetOfForms::const_iterator form = container->second.begin();
668 form != container->second.end();
669 ++form
672 pAdapter->updateTabOrder( *form );
675 m_aNeedTabOrderUpdate.clear();
678 //------------------------------------------------------------------------------
679 IMPL_LINK(FmXFormView, OnActivate, void*, /*EMPTYTAG*/)
681 m_nActivationEvent = 0;
683 if ( !m_pView )
685 OSL_FAIL( "FmXFormView::OnActivate: well .... seems we have a timing problem (the view already died)!" );
686 return 0;
689 // setting the controller to activate
690 if (m_pView->GetFormShell() && m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW)
692 Window* pWindow = const_cast<Window*>(static_cast<const Window*>(m_pView->GetActualOutDev()));
693 PFormViewPageWindowAdapter pAdapter = m_aPageWindowAdapters.empty() ? NULL : m_aPageWindowAdapters[0];
694 for ( PageWindowAdapterList::const_iterator i = m_aPageWindowAdapters.begin();
695 i != m_aPageWindowAdapters.end();
699 if ( pWindow == (*i)->getWindow() )
700 pAdapter =*i;
703 if ( pAdapter.get() )
705 for ( ::std::vector< Reference< XFormController > >::const_iterator i = pAdapter->GetList().begin();
706 i != pAdapter->GetList().end();
710 const Reference< XFormController > & xController = *i;
711 if ( !xController.is() )
712 continue;
714 // only database forms are to be activated
715 Reference< XRowSet > xForm(xController->getModel(), UNO_QUERY);
716 if ( !xForm.is() || !OStaticDataAccessTools().getRowSetConnection( xForm ).is() )
717 continue;
719 Reference< XPropertySet > xFormSet( xForm, UNO_QUERY );
720 if ( !xFormSet.is() )
722 SAL_WARN( "svx.form", "FmXFormView::OnActivate: a form which does not have properties?" );
723 continue;
726 const OUString aSource = ::comphelper::getString( xFormSet->getPropertyValue( FM_PROP_COMMAND ) );
727 if ( !aSource.isEmpty() )
729 FmXFormShell* pShImpl = m_pView->GetFormShell()->GetImpl();
730 if ( pShImpl )
731 pShImpl->setActiveController( xController );
732 break;
737 return 0;
740 //------------------------------------------------------------------------------
741 void FmXFormView::Activate(sal_Bool bSync)
743 if (m_nActivationEvent)
745 Application::RemoveUserEvent(m_nActivationEvent);
746 m_nActivationEvent = 0;
749 if (bSync)
751 LINK(this,FmXFormView,OnActivate).Call(NULL);
753 else
754 m_nActivationEvent = Application::PostUserEvent(LINK(this,FmXFormView,OnActivate));
757 //------------------------------------------------------------------------------
758 void FmXFormView::Deactivate(sal_Bool bDeactivateController)
760 if (m_nActivationEvent)
762 Application::RemoveUserEvent(m_nActivationEvent);
763 m_nActivationEvent = 0;
766 FmXFormShell* pShImpl = m_pView->GetFormShell() ? m_pView->GetFormShell()->GetImpl() : NULL;
767 if (pShImpl && bDeactivateController)
768 pShImpl->setActiveController( NULL );
771 //------------------------------------------------------------------------------
772 FmFormShell* FmXFormView::GetFormShell() const
774 return m_pView ? m_pView->GetFormShell() : NULL;
776 // -----------------------------------------------------------------------------
777 void FmXFormView::AutoFocus( sal_Bool _bSync )
779 if (m_nAutoFocusEvent)
780 Application::RemoveUserEvent(m_nAutoFocusEvent);
782 if ( _bSync )
783 OnAutoFocus( NULL );
784 else
785 m_nAutoFocusEvent = Application::PostUserEvent(LINK(this, FmXFormView, OnAutoFocus));
788 // -----------------------------------------------------------------------------
789 bool FmXFormView::isFocusable( const Reference< XControl >& i_rControl )
791 if ( !i_rControl.is() )
792 return false;
796 Reference< XPropertySet > xModelProps( i_rControl->getModel(), UNO_QUERY_THROW );
798 // only enabled controls are allowed to participate
799 sal_Bool bEnabled = sal_False;
800 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_ENABLED ) >>= bEnabled );
801 if ( !bEnabled )
802 return false;
804 // check the class id of the control model
805 sal_Int16 nClassId = FormComponentType::CONTROL;
806 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
808 // controls which are not focussable
809 if ( ( FormComponentType::CONTROL != nClassId )
810 && ( FormComponentType::IMAGEBUTTON != nClassId )
811 && ( FormComponentType::GROUPBOX != nClassId )
812 && ( FormComponentType::FIXEDTEXT != nClassId )
813 && ( FormComponentType::HIDDENCONTROL != nClassId )
814 && ( FormComponentType::IMAGECONTROL != nClassId )
815 && ( FormComponentType::SCROLLBAR != nClassId )
816 && ( FormComponentType::SPINBUTTON!= nClassId )
819 return true;
822 catch (const Exception&)
824 DBG_UNHANDLED_EXCEPTION();
826 return false;
829 // -----------------------------------------------------------------------------
830 static Reference< XControl > lcl_firstFocussableControl( const Sequence< Reference< XControl > >& _rControls )
832 Reference< XControl > xReturn;
834 // loop through all the controls
835 const Reference< XControl >* pControls = _rControls.getConstArray();
836 const Reference< XControl >* pControlsEnd = _rControls.getConstArray() + _rControls.getLength();
837 for ( ; pControls != pControlsEnd; ++pControls )
839 if ( !pControls->is() )
840 continue;
842 if ( FmXFormView::isFocusable( *pControls ) )
844 xReturn = *pControls;
845 break;
849 if ( !xReturn.is() && _rControls.getLength() )
850 xReturn = _rControls[0];
852 return xReturn;
855 // -----------------------------------------------------------------------------
856 namespace
858 // .........................................................................
859 void lcl_ensureControlsOfFormExist_nothrow( const SdrPage& _rPage, const SdrView& _rView, const Window& _rWindow, const Reference< XForm >& _rxForm )
863 Reference< XInterface > xNormalizedForm( _rxForm, UNO_QUERY_THROW );
865 SdrObjListIter aSdrObjectLoop( _rPage, IM_DEEPNOGROUPS );
866 while ( aSdrObjectLoop.IsMore() )
868 FmFormObj* pFormObject = FmFormObj::GetFormObject( aSdrObjectLoop.Next() );
869 if ( !pFormObject )
870 continue;
872 Reference< XChild > xModel( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
873 Reference< XInterface > xModelParent( xModel->getParent(), UNO_QUERY_THROW );
875 if ( xNormalizedForm.get() != xModelParent.get() )
876 continue;
878 pFormObject->GetUnoControl( _rView, _rWindow );
881 catch (const Exception&)
883 DBG_UNHANDLED_EXCEPTION();
888 // -----------------------------------------------------------------------------
889 Reference< XFormController > FmXFormView::getFormController( const Reference< XForm >& _rxForm, const OutputDevice& _rDevice ) const
891 Reference< XFormController > xController;
893 for ( PageWindowAdapterList::const_iterator pos = m_aPageWindowAdapters.begin();
894 pos != m_aPageWindowAdapters.end();
895 ++pos
898 const PFormViewPageWindowAdapter pAdapter( *pos );
899 if ( !pAdapter.get() )
901 SAL_WARN( "svx.form", "FmXFormView::getFormController: invalid page window adapter!" );
902 continue;
905 if ( pAdapter->getWindow() != &_rDevice )
906 // wrong device
907 continue;
909 xController = pAdapter->getController( _rxForm );
910 if ( xController.is() )
911 break;
913 return xController;
916 // -----------------------------------------------------------------------------
917 IMPL_LINK(FmXFormView, OnAutoFocus, void*, /*EMPTYTAG*/)
919 m_nAutoFocusEvent = 0;
921 // go to the first form of our page, examine it's TabController, go to it's first (in terms of the tab order)
922 // control, give it the focus
927 SdrPageView *pPageView = m_pView ? m_pView->GetSdrPageView() : NULL;
928 SdrPage *pSdrPage = pPageView ? pPageView->GetPage() : NULL;
929 // get the forms collection of the page we belong to
930 FmFormPage* pPage = PTR_CAST( FmFormPage, pSdrPage );
931 Reference< XIndexAccess > xForms( pPage ? Reference< XIndexAccess >( pPage->GetForms(), UNO_QUERY ) : Reference< XIndexAccess >() );
933 const PFormViewPageWindowAdapter pAdapter = m_aPageWindowAdapters.empty() ? NULL : m_aPageWindowAdapters[0];
934 const Window* pWindow = pAdapter.get() ? pAdapter->getWindow() : NULL;
936 ENSURE_OR_RETURN( xForms.is() && pWindow, "FmXFormView::OnAutoFocus: could not collect all essentials!", 0L );
940 // go for the tab controller of the first form
941 if ( !xForms->getCount() )
942 break;
943 Reference< XForm > xForm( xForms->getByIndex( 0 ), UNO_QUERY_THROW );
944 Reference< XTabController > xTabController( pAdapter->getController( xForm ), UNO_QUERY_THROW );
946 // go for the first control of the controller
947 Sequence< Reference< XControl > > aControls( xTabController->getControls() );
948 if ( aControls.getLength() == 0 )
950 Reference< XElementAccess > xFormElementAccess( xForm, UNO_QUERY_THROW );
951 if ( xFormElementAccess->hasElements() )
953 // there are control models in the form, but no controls, yet.
954 // Well, since some time controls are created on demand only. In particular,
955 // they're normally created when they're first painted.
956 // Unfortunately, the FormController does not have any way to
957 // trigger the creation itself, so we must hack this ...
958 lcl_ensureControlsOfFormExist_nothrow( *pPage, *m_pView, *pWindow, xForm );
959 aControls = xTabController->getControls();
960 OSL_ENSURE( aControls.getLength(), "FmXFormView::OnAutoFocus: no controls at all!" );
964 // set the focus to this first control
965 Reference< XWindow > xControlWindow( lcl_firstFocussableControl( aControls ), UNO_QUERY );
966 if ( !xControlWindow.is() )
967 break;
969 xControlWindow->setFocus();
971 // ensure that the control is visible
972 // 80210 - 12/07/00 - FS
973 const Window* pCurrentWindow = dynamic_cast< const Window* >( m_pView->GetActualOutDev() );
974 if ( pCurrentWindow )
976 awt::Rectangle aRect = xControlWindow->getPosSize();
977 ::Rectangle aNonUnoRect( aRect.X, aRect.Y, aRect.X + aRect.Width, aRect.Y + aRect.Height );
978 m_pView->MakeVisible( pCurrentWindow->PixelToLogic( aNonUnoRect ), *const_cast< Window* >( pCurrentWindow ) );
981 catch (const Exception&)
983 DBG_UNHANDLED_EXCEPTION();
986 } // do
987 while ( false );
989 return 1L;
992 // -----------------------------------------------------------------------------
993 void FmXFormView::onCreatedFormObject( FmFormObj& _rFormObject )
995 FmFormShell* pShell = m_pView ? m_pView->GetFormShell() : NULL;
996 FmXFormShell* pShellImpl = pShell ? pShell->GetImpl() : NULL;
997 OSL_ENSURE( pShellImpl, "FmXFormView::onCreatedFormObject: no form shell!" );
998 if ( !pShellImpl )
999 return;
1001 // it is valid that the form shell's forms collection is not initialized, yet
1002 pShellImpl->UpdateForms( sal_True );
1004 m_xLastCreatedControlModel.set( _rFormObject.GetUnoControlModel(), UNO_QUERY );
1005 if ( !m_xLastCreatedControlModel.is() )
1006 return;
1008 // some initial property defaults
1009 FormControlFactory aControlFactory( m_aContext );
1010 aControlFactory.initializeControlModel( pShellImpl->getDocumentType(), _rFormObject );
1012 if ( !pShellImpl->GetWizardUsing() )
1013 return;
1015 // #i31958# don't call wizards in XForms mode
1016 if ( pShellImpl->isEnhancedForm() )
1017 return;
1019 // #i46898# no wizards if there is no Base installed - currently, all wizards are
1020 // database related
1021 if ( !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
1022 return;
1024 if ( m_nControlWizardEvent )
1025 Application::RemoveUserEvent( m_nControlWizardEvent );
1026 m_nControlWizardEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnStartControlWizard ) );
1029 // -----------------------------------------------------------------------------
1030 IMPL_LINK( FmXFormView, OnStartControlWizard, void*, /**/ )
1032 m_nControlWizardEvent = 0;
1033 OSL_PRECOND( m_xLastCreatedControlModel.is(), "FmXFormView::OnStartControlWizard: illegal call!" );
1034 if ( !m_xLastCreatedControlModel.is() )
1035 return 0L;
1037 sal_Int16 nClassId = FormComponentType::CONTROL;
1040 OSL_VERIFY( m_xLastCreatedControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
1042 catch (const Exception&)
1044 DBG_UNHANDLED_EXCEPTION();
1047 const sal_Char* pWizardAsciiName = NULL;
1048 switch ( nClassId )
1050 case FormComponentType::GRIDCONTROL:
1051 pWizardAsciiName = "com.sun.star.sdb.GridControlAutoPilot";
1052 break;
1053 case FormComponentType::LISTBOX:
1054 case FormComponentType::COMBOBOX:
1055 pWizardAsciiName = "com.sun.star.sdb.ListComboBoxAutoPilot";
1056 break;
1057 case FormComponentType::GROUPBOX:
1058 pWizardAsciiName = "com.sun.star.sdb.GroupBoxAutoPilot";
1059 break;
1062 if ( pWizardAsciiName )
1064 // build the argument list
1065 ::comphelper::NamedValueCollection aWizardArgs;
1066 aWizardArgs.put( "ObjectModel", m_xLastCreatedControlModel );
1068 // create the wizard object
1069 Reference< XExecutableDialog > xWizard;
1072 m_aContext.createComponentWithArguments( pWizardAsciiName, aWizardArgs.getWrappedPropertyValues(), xWizard );
1074 catch (const Exception&)
1076 DBG_UNHANDLED_EXCEPTION();
1079 if ( !xWizard.is() )
1081 ShowServiceNotAvailableError( NULL, OUString::createFromAscii(pWizardAsciiName), sal_True );
1083 else
1085 // execute the wizard
1088 xWizard->execute();
1090 catch (const Exception&)
1092 DBG_UNHANDLED_EXCEPTION();
1097 m_xLastCreatedControlModel.clear();
1098 return 1L;
1101 // -----------------------------------------------------------------------------
1102 namespace
1104 void lcl_insertIntoFormComponentHierarchy_throw( const FmFormView& _rView, const SdrUnoObj& _rSdrObj,
1105 const Reference< XDataSource >& _rxDataSource = NULL, const OUString& _rDataSourceName = OUString(),
1106 const OUString& _rCommand = OUString(), const sal_Int32 _nCommandType = -1 )
1108 FmFormPage& rPage = static_cast< FmFormPage& >( *_rView.GetSdrPageView()->GetPage() );
1110 Reference< XFormComponent > xFormComponent( _rSdrObj.GetUnoControlModel(), UNO_QUERY_THROW );
1111 Reference< XForm > xTargetForm(
1112 rPage.GetImpl().findPlaceInFormComponentHierarchy( xFormComponent, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType ),
1113 UNO_SET_THROW );
1115 rPage.GetImpl().setUniqueName( xFormComponent, xTargetForm );
1117 Reference< XIndexContainer > xFormAsContainer( xTargetForm, UNO_QUERY_THROW );
1118 xFormAsContainer->insertByIndex( xFormAsContainer->getCount(), makeAny( xFormComponent ) );
1122 // -----------------------------------------------------------------------------
1123 SdrObject* FmXFormView::implCreateFieldControl( const ::svx::ODataAccessDescriptor& _rColumnDescriptor )
1125 // not if we're in design mode
1126 if ( !m_pView->IsDesignMode() )
1127 return NULL;
1129 OUString sCommand, sFieldName;
1130 sal_Int32 nCommandType = CommandType::COMMAND;
1131 SharedConnection xConnection;
1133 OUString sDataSource = _rColumnDescriptor.getDataSource();
1134 _rColumnDescriptor[ daCommand ] >>= sCommand;
1135 _rColumnDescriptor[ daColumnName ] >>= sFieldName;
1136 _rColumnDescriptor[ daCommandType ] >>= nCommandType;
1138 Reference< XConnection > xExternalConnection;
1139 _rColumnDescriptor[ daConnection ] >>= xExternalConnection;
1140 xConnection.reset( xExternalConnection, SharedConnection::NoTakeOwnership );
1143 if ( sCommand.isEmpty()
1144 || sFieldName.isEmpty()
1145 || ( sDataSource.isEmpty()
1146 && !xConnection.is()
1150 OSL_FAIL( "FmXFormView::implCreateFieldControl: nonsense!" );
1153 Reference< XDataSource > xDataSource;
1154 SQLErrorEvent aError;
1157 if ( xConnection.is() && !xDataSource.is() && sDataSource.isEmpty() )
1159 Reference< XChild > xChild( xConnection, UNO_QUERY );
1160 if ( xChild.is() )
1161 xDataSource = xDataSource.query( xChild->getParent() );
1164 // obtain the data source
1165 if ( !xDataSource.is() )
1166 xDataSource = OStaticDataAccessTools().getDataSource( sDataSource, m_aContext.getUNOContext() );
1168 // and the connection, if necessary
1169 if ( !xConnection.is() )
1170 xConnection.reset( OStaticDataAccessTools().getConnection_withFeedback(
1171 sDataSource,
1172 OUString(),
1173 OUString(),
1174 m_aContext.getUNOContext()
1175 ) );
1177 catch (const SQLException&)
1179 aError.Reason = ::cppu::getCaughtException();
1181 catch (const Exception& )
1183 /* will be asserted below */
1185 if (aError.Reason.hasValue())
1187 displayAsyncErrorMessage( aError );
1188 return NULL;
1191 // need a data source and a connection here
1192 if (!xDataSource.is() || !xConnection.is())
1194 OSL_FAIL("FmXFormView::implCreateFieldControl : could not retrieve the data source or the connection!");
1195 return NULL;
1198 OStaticDataAccessTools aDBATools;
1199 Reference< XComponent > xKeepFieldsAlive;
1200 // go
1203 // determine the table/query field which we should create a control for
1204 Reference< XPropertySet > xField;
1206 Reference< XNameAccess > xFields = aDBATools.getFieldsByCommandDescriptor(
1207 xConnection, nCommandType, sCommand, xKeepFieldsAlive );
1209 if (xFields.is() && xFields->hasByName(sFieldName))
1210 xFields->getByName(sFieldName) >>= xField;
1211 if ( !xField.is() )
1212 return NULL;
1214 Reference< XNumberFormatsSupplier > xSupplier( aDBATools.getNumberFormats( xConnection, sal_False ), UNO_SET_THROW );
1215 Reference< XNumberFormats > xNumberFormats( xSupplier->getNumberFormats(), UNO_SET_THROW );
1217 OUString sLabelPostfix;
1219 ////////////////////////////////////////////////////////////////
1220 // nur fuer Textgroesse
1221 OutputDevice* pOutDev = NULL;
1222 if (m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW)
1223 pOutDev = const_cast<OutputDevice*>(m_pView->GetActualOutDev());
1224 else
1225 {// OutDev suchen
1226 SdrPageView* pPageView = m_pView->GetSdrPageView();
1227 if( pPageView && !pOutDev )
1229 // const SdrPageViewWinList& rWinList = pPageView->GetWinList();
1230 // const SdrPageViewWindows& rPageViewWindows = pPageView->GetPageViewWindows();
1232 for( sal_uInt32 i = 0L; i < pPageView->PageWindowCount(); i++ )
1234 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(i);
1236 if( rPageWindow.GetPaintWindow().OutputToWindow())
1238 pOutDev = &rPageWindow.GetPaintWindow().GetOutputDevice();
1239 break;
1245 if ( !pOutDev )
1246 return NULL;
1248 sal_Int32 nDataType = ::comphelper::getINT32(xField->getPropertyValue(FM_PROP_FIELDTYPE));
1249 if ((DataType::BINARY == nDataType) || (DataType::VARBINARY == nDataType))
1250 return NULL;
1252 //////////////////////////////////////////////////////////////////////
1253 // determine the control type by examining the data type of the bound column
1254 sal_uInt16 nOBJID = 0;
1255 sal_Bool bDateNTimeField = sal_False;
1257 sal_Bool bIsCurrency = sal_False;
1258 if (::comphelper::hasProperty(FM_PROP_ISCURRENCY, xField))
1259 bIsCurrency = ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_ISCURRENCY));
1261 if (bIsCurrency)
1262 nOBJID = OBJ_FM_CURRENCYFIELD;
1263 else
1264 switch (nDataType)
1266 case DataType::BLOB:
1267 case DataType::LONGVARBINARY:
1268 nOBJID = OBJ_FM_IMAGECONTROL;
1269 break;
1270 case DataType::LONGVARCHAR:
1271 case DataType::CLOB:
1272 nOBJID = OBJ_FM_EDIT;
1273 break;
1274 case DataType::BINARY:
1275 case DataType::VARBINARY:
1276 return NULL;
1277 case DataType::BIT:
1278 case DataType::BOOLEAN:
1279 nOBJID = OBJ_FM_CHECKBOX;
1280 break;
1281 case DataType::TINYINT:
1282 case DataType::SMALLINT:
1283 case DataType::INTEGER:
1284 nOBJID = OBJ_FM_NUMERICFIELD;
1285 break;
1286 case DataType::REAL:
1287 case DataType::DOUBLE:
1288 case DataType::NUMERIC:
1289 case DataType::DECIMAL:
1290 nOBJID = OBJ_FM_FORMATTEDFIELD;
1291 break;
1292 case DataType::TIMESTAMP:
1293 bDateNTimeField = sal_True;
1294 sLabelPostfix = String( SVX_RES( RID_STR_POSTFIX_DATE ) );
1295 // DON'T break !
1296 case DataType::DATE:
1297 nOBJID = OBJ_FM_DATEFIELD;
1298 break;
1299 case DataType::TIME:
1300 nOBJID = OBJ_FM_TIMEFIELD;
1301 break;
1302 case DataType::CHAR:
1303 case DataType::VARCHAR:
1304 default:
1305 nOBJID = OBJ_FM_EDIT;
1306 break;
1308 if (!nOBJID)
1309 return NULL;
1311 SdrUnoObj* pLabel( NULL );
1312 SdrUnoObj* pControl( NULL );
1313 if ( !createControlLabelPair( *pOutDev, 0, 0, xField, xNumberFormats, nOBJID, sLabelPostfix,
1314 pLabel, pControl, xDataSource, sDataSource, sCommand, nCommandType )
1317 return NULL;
1320 //////////////////////////////////////////////////////////////////////
1321 // group objects
1322 bool bCheckbox = ( OBJ_FM_CHECKBOX == nOBJID );
1323 OSL_ENSURE( !bCheckbox || !pLabel, "FmXFormView::implCreateFieldControl: why was there a label created for a check box?" );
1324 if ( bCheckbox )
1325 return pControl;
1327 SdrObjGroup* pGroup = new SdrObjGroup();
1328 SdrObjList* pObjList = pGroup->GetSubList();
1329 pObjList->InsertObject( pLabel );
1330 pObjList->InsertObject( pControl );
1332 if ( bDateNTimeField )
1333 { // so far we created a date field only, but we also need a time field
1334 pLabel = pControl = NULL;
1335 if ( createControlLabelPair( *pOutDev, 0, 1000, xField, xNumberFormats, OBJ_FM_TIMEFIELD,
1336 String( SVX_RES( RID_STR_POSTFIX_TIME ) ), pLabel, pControl,
1337 xDataSource, sDataSource, sCommand, nCommandType )
1340 pObjList->InsertObject( pLabel );
1341 pObjList->InsertObject( pControl );
1345 return pGroup; // und fertig
1347 catch (const Exception&)
1349 DBG_UNHANDLED_EXCEPTION();
1353 return NULL;
1356 // -----------------------------------------------------------------------------
1357 SdrObject* FmXFormView::implCreateXFormsControl( const ::svx::OXFormsDescriptor &_rDesc )
1359 // not if we're in design mode
1360 if ( !m_pView->IsDesignMode() )
1361 return NULL;
1363 Reference< XComponent > xKeepFieldsAlive;
1365 // go
1368 // determine the table/query field which we should create a control for
1369 Reference< XNumberFormats > xNumberFormats;
1370 OUString sLabelPostfix = _rDesc.szName;
1372 ////////////////////////////////////////////////////////////////
1373 // nur fuer Textgroesse
1374 OutputDevice* pOutDev = NULL;
1375 if (m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW)
1376 pOutDev = const_cast<OutputDevice*>(m_pView->GetActualOutDev());
1377 else
1378 {// OutDev suchen
1379 SdrPageView* pPageView = m_pView->GetSdrPageView();
1380 if( pPageView && !pOutDev )
1382 // const SdrPageViewWinList& rWinList = pPageView->GetWinList();
1383 // const SdrPageViewWindows& rPageViewWindows = pPageView->GetPageViewWindows();
1385 for( sal_uInt32 i = 0L; i < pPageView->PageWindowCount(); i++ )
1387 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(i);
1389 if( rPageWindow.GetPaintWindow().GetOutputDevice().GetOutDevType() == OUTDEV_WINDOW)
1391 pOutDev = &rPageWindow.GetPaintWindow().GetOutputDevice();
1392 break;
1398 if ( !pOutDev )
1399 return NULL;
1401 //////////////////////////////////////////////////////////////////////
1402 // The service name decides which control should be created
1403 sal_uInt16 nOBJID = OBJ_FM_EDIT;
1404 if(OUString(_rDesc.szServiceName).equals((OUString)FM_SUN_COMPONENT_NUMERICFIELD))
1405 nOBJID = OBJ_FM_NUMERICFIELD;
1406 if(OUString(_rDesc.szServiceName).equals((OUString)FM_SUN_COMPONENT_CHECKBOX))
1407 nOBJID = OBJ_FM_CHECKBOX;
1408 if(OUString(_rDesc.szServiceName).equals((OUString)FM_COMPONENT_COMMANDBUTTON))
1409 nOBJID = OBJ_FM_BUTTON;
1411 typedef ::com::sun::star::form::submission::XSubmission XSubmission_t;
1412 Reference< XSubmission_t > xSubmission(_rDesc.xPropSet, UNO_QUERY);
1414 // xform control or submission button?
1415 if ( !xSubmission.is() )
1417 SdrUnoObj* pLabel( NULL );
1418 SdrUnoObj* pControl( NULL );
1419 if ( !createControlLabelPair( *pOutDev, 0, 0, NULL, xNumberFormats, nOBJID, sLabelPostfix,
1420 pLabel, pControl )
1423 return NULL;
1426 //////////////////////////////////////////////////////////////////////
1427 // Now build the connection between the control and the data item.
1428 Reference< XValueBinding > xValueBinding(_rDesc.xPropSet,UNO_QUERY);
1429 Reference< XBindableValue > xBindableValue(pControl->GetUnoControlModel(),UNO_QUERY);
1431 DBG_ASSERT( xBindableValue.is(), "FmXFormView::implCreateXFormsControl: control's not bindable!" );
1432 if ( xBindableValue.is() )
1433 xBindableValue->setValueBinding(xValueBinding);
1435 bool bCheckbox = ( OBJ_FM_CHECKBOX == nOBJID );
1436 OSL_ENSURE( !bCheckbox || !pLabel, "FmXFormView::implCreateXFormsControl: why was there a label created for a check box?" );
1437 if ( bCheckbox )
1438 return pControl;
1440 //////////////////////////////////////////////////////////////////////
1441 // group objects
1442 SdrObjGroup* pGroup = new SdrObjGroup();
1443 SdrObjList* pObjList = pGroup->GetSubList();
1444 pObjList->InsertObject(pLabel);
1445 pObjList->InsertObject(pControl);
1447 return pGroup;
1449 else {
1451 // create a button control
1452 const MapMode eTargetMode( pOutDev->GetMapMode() );
1453 const MapMode eSourceMode(MAP_100TH_MM);
1454 const sal_uInt16 nObjID = OBJ_FM_BUTTON;
1455 ::Size controlSize(4000, 500);
1456 FmFormObj *pControl = static_cast<FmFormObj*>(SdrObjFactory::MakeNewObject( FmFormInventor, nObjID, NULL, NULL ));
1457 controlSize.Width() = Fraction(controlSize.Width(), 1) * eTargetMode.GetScaleX();
1458 controlSize.Height() = Fraction(controlSize.Height(), 1) * eTargetMode.GetScaleY();
1459 ::Point controlPos( pOutDev->LogicToLogic( ::Point( controlSize.Width(), 0 ), eSourceMode, eTargetMode ) );
1460 ::Rectangle controlRect( controlPos, pOutDev->LogicToLogic( controlSize, eSourceMode, eTargetMode ) );
1461 pControl->SetLogicRect(controlRect);
1463 // set the button label
1464 Reference< XPropertySet > xControlSet(pControl->GetUnoControlModel(), UNO_QUERY);
1465 xControlSet->setPropertyValue(FM_PROP_LABEL, makeAny(OUString(_rDesc.szName)));
1467 // connect the submission with the submission supplier (aka the button)
1468 xControlSet->setPropertyValue( FM_PROP_BUTTON_TYPE,
1469 makeAny( FormButtonType_SUBMIT ) );
1470 typedef ::com::sun::star::form::submission::XSubmissionSupplier XSubmissionSupplier_t;
1471 Reference< XSubmissionSupplier_t > xSubmissionSupplier(pControl->GetUnoControlModel(), UNO_QUERY);
1472 xSubmissionSupplier->setSubmission(xSubmission);
1474 return pControl;
1477 catch (const Exception&)
1479 OSL_FAIL("FmXFormView::implCreateXFormsControl: caught an exception while creating the control !");
1483 return NULL;
1486 //------------------------------------------------------------------------
1487 bool FmXFormView::createControlLabelPair( OutputDevice& _rOutDev, sal_Int32 _nXOffsetMM, sal_Int32 _nYOffsetMM,
1488 const Reference< XPropertySet >& _rxField, const Reference< XNumberFormats >& _rxNumberFormats,
1489 sal_uInt16 _nControlObjectID, const OUString& _rFieldPostfix,
1490 SdrUnoObj*& _rpLabel, SdrUnoObj*& _rpControl,
1491 const Reference< XDataSource >& _rxDataSource, const OUString& _rDataSourceName,
1492 const OUString& _rCommand, const sal_Int32 _nCommandType )
1494 if ( !createControlLabelPair( m_aContext, _rOutDev, _nXOffsetMM, _nYOffsetMM,
1495 _rxField, _rxNumberFormats, _nControlObjectID, _rFieldPostfix, FmFormInventor, OBJ_FM_FIXEDTEXT,
1496 NULL, NULL, NULL, _rpLabel, _rpControl )
1498 return false;
1500 // insert the control model(s) into the form component hierachy
1501 if ( _rpLabel )
1502 lcl_insertIntoFormComponentHierarchy_throw( *m_pView, *_rpLabel, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType );
1503 lcl_insertIntoFormComponentHierarchy_throw( *m_pView, *_rpControl, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType );
1505 // some context-dependent initializations
1506 FormControlFactory aControlFactory( m_aContext );
1507 if ( _rpLabel )
1508 aControlFactory.initializeControlModel( impl_getDocumentType(), *_rpLabel );
1509 aControlFactory.initializeControlModel( impl_getDocumentType(), *_rpControl );
1511 return true;
1514 //------------------------------------------------------------------------
1515 bool FmXFormView::createControlLabelPair( const ::comphelper::ComponentContext& _rContext,
1516 OutputDevice& _rOutDev, sal_Int32 _nXOffsetMM, sal_Int32 _nYOffsetMM, const Reference< XPropertySet >& _rxField,
1517 const Reference< XNumberFormats >& _rxNumberFormats, sal_uInt16 _nControlObjectID,
1518 const OUString& _rFieldPostfix, sal_uInt32 _nInventor, sal_uInt16 _nLabelObjectID,
1519 SdrPage* _pLabelPage, SdrPage* _pControlPage, SdrModel* _pModel, SdrUnoObj*& _rpLabel, SdrUnoObj*& _rpControl)
1521 sal_Int32 nDataType = 0;
1522 OUString sFieldName;
1523 Any aFieldName;
1524 if ( _rxField.is() )
1526 nDataType = ::comphelper::getINT32(_rxField->getPropertyValue(FM_PROP_FIELDTYPE));
1527 aFieldName = Any(_rxField->getPropertyValue(FM_PROP_NAME));
1528 aFieldName >>= sFieldName;
1531 // calculate the positions, respecting the settings of the target device
1532 ::Size aTextSize( _rOutDev.GetTextWidth(sFieldName + _rFieldPostfix), _rOutDev.GetTextHeight() );
1534 MapMode eTargetMode( _rOutDev.GetMapMode() ),
1535 eSourceMode( MAP_100TH_MM );
1537 // Textbreite ist mindestens 4cm
1538 // Texthoehe immer halber cm
1539 ::Size aDefTxtSize(4000, 500);
1540 ::Size aDefSize(4000, 500);
1541 ::Size aDefImageSize(4000, 4000);
1543 ::Size aRealSize = _rOutDev.LogicToLogic(aTextSize, eTargetMode, eSourceMode);
1544 aRealSize.Width() = std::max(aRealSize.Width(), aDefTxtSize.Width());
1545 aRealSize.Height()= aDefSize.Height();
1547 // adjust to scaling of the target device (#53523#)
1548 aRealSize.Width() = long(Fraction(aRealSize.Width(), 1) * eTargetMode.GetScaleX());
1549 aRealSize.Height() = long(Fraction(aRealSize.Height(), 1) * eTargetMode.GetScaleY());
1551 // for boolean fields, we do not create a label, but just a checkbox
1552 bool bNeedLabel = ( _nControlObjectID != OBJ_FM_CHECKBOX );
1554 // the label
1555 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1556 ::std::auto_ptr< SdrUnoObj > pLabel;
1557 SAL_WNODEPRECATED_DECLARATIONS_POP
1558 Reference< XPropertySet > xLabelModel;
1559 if ( bNeedLabel )
1561 pLabel.reset( dynamic_cast< SdrUnoObj* >(
1562 SdrObjFactory::MakeNewObject( _nInventor, _nLabelObjectID, _pLabelPage, _pModel ) ) );
1563 OSL_ENSURE( pLabel.get(), "FmXFormView::createControlLabelPair: could not create the label!" );
1564 if ( !pLabel.get() )
1565 return false;
1567 xLabelModel.set( pLabel->GetUnoControlModel(), UNO_QUERY );
1568 if ( xLabelModel.is() )
1570 OUString sLabel;
1571 if ( _rxField.is() && _rxField->getPropertySetInfo()->hasPropertyByName(FM_PROP_LABEL) )
1572 _rxField->getPropertyValue(FM_PROP_LABEL) >>= sLabel;
1573 if ( sLabel.isEmpty() )
1574 sLabel = sFieldName;
1576 xLabelModel->setPropertyValue( FM_PROP_LABEL, makeAny( sLabel + _rFieldPostfix ) );
1577 String sObjectLabel( SVX_RES( RID_STR_OBJECT_LABEL ) );
1578 sObjectLabel.SearchAndReplaceAllAscii( "#object#", sFieldName );
1579 xLabelModel->setPropertyValue( FM_PROP_NAME, makeAny( OUString( sObjectLabel ) ) );
1582 pLabel->SetLogicRect( ::Rectangle(
1583 _rOutDev.LogicToLogic( ::Point( _nXOffsetMM, _nYOffsetMM ), eSourceMode, eTargetMode ),
1584 _rOutDev.LogicToLogic( aRealSize, eSourceMode, eTargetMode )
1585 ) );
1588 // the control
1589 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1590 ::std::auto_ptr< SdrUnoObj > pControl( dynamic_cast< SdrUnoObj* >(
1591 SdrObjFactory::MakeNewObject( _nInventor, _nControlObjectID, _pControlPage, _pModel ) ) );
1592 SAL_WNODEPRECATED_DECLARATIONS_POP
1593 OSL_ENSURE( pControl.get(), "FmXFormView::createControlLabelPair: could not create the control!" );
1594 if ( !pControl.get() )
1595 return false;
1597 Reference< XPropertySet > xControlSet( pControl->GetUnoControlModel(), UNO_QUERY );
1598 if ( !xControlSet.is() )
1599 return false;
1601 // size of the control
1602 ::Size aControlSize( aDefSize );
1603 switch ( nDataType )
1605 case DataType::BIT:
1606 case DataType::BOOLEAN:
1607 aControlSize = aDefSize;
1608 break;
1609 case DataType::LONGVARCHAR:
1610 case DataType::CLOB:
1611 case DataType::LONGVARBINARY:
1612 case DataType::BLOB:
1613 aControlSize = aDefImageSize;
1614 break;
1617 if ( OBJ_FM_IMAGECONTROL == _nControlObjectID )
1618 aControlSize = aDefImageSize;
1620 aControlSize.Width() = long(Fraction(aControlSize.Width(), 1) * eTargetMode.GetScaleX());
1621 aControlSize.Height() = long(Fraction(aControlSize.Height(), 1) * eTargetMode.GetScaleY());
1623 pControl->SetLogicRect( ::Rectangle(
1624 _rOutDev.LogicToLogic( ::Point( aRealSize.Width() + _nXOffsetMM, _nYOffsetMM ), eSourceMode, eTargetMode ),
1625 _rOutDev.LogicToLogic( aControlSize, eSourceMode, eTargetMode )
1626 ) );
1628 // some initializations
1629 Reference< XPropertySetInfo > xControlPropInfo = xControlSet->getPropertySetInfo();
1631 if ( aFieldName.hasValue() )
1633 xControlSet->setPropertyValue( FM_PROP_CONTROLSOURCE, aFieldName );
1634 xControlSet->setPropertyValue( FM_PROP_NAME, aFieldName );
1635 if ( !bNeedLabel )
1637 // no dedicated label control => use the label property
1638 if ( xControlPropInfo->hasPropertyByName( FM_PROP_LABEL ) )
1639 xControlSet->setPropertyValue( FM_PROP_LABEL, makeAny( sFieldName + _rFieldPostfix ) );
1640 else
1641 OSL_FAIL( "FmXFormView::createControlLabelPair: can't set a label for the control!" );
1645 if ( (nDataType == DataType::LONGVARCHAR || nDataType == DataType::CLOB) && xControlPropInfo->hasPropertyByName( FM_PROP_MULTILINE ) )
1647 xControlSet->setPropertyValue( FM_PROP_MULTILINE, makeAny( sal_Bool( sal_True ) ) );
1650 // announce the label to the control
1651 if ( xControlPropInfo->hasPropertyByName( FM_PROP_CONTROLLABEL ) && xLabelModel.is() )
1655 xControlSet->setPropertyValue( FM_PROP_CONTROLLABEL, makeAny( xLabelModel ) );
1657 catch (const Exception&)
1659 DBG_UNHANDLED_EXCEPTION();
1663 if ( _rxField.is() )
1665 FormControlFactory aControlFactory( _rContext );
1666 aControlFactory.initializeFieldDependentProperties( _rxField, xControlSet, _rxNumberFormats );
1669 _rpLabel = pLabel.release();
1670 _rpControl = pControl.release();
1671 return true;
1674 //------------------------------------------------------------------------------
1675 FmXFormView::ObjectRemoveListener::ObjectRemoveListener( FmXFormView* pParent )
1676 :m_pParent( pParent )
1680 //------------------------------------------------------------------------------
1681 void FmXFormView::ObjectRemoveListener::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
1683 if (rHint.ISA(SdrHint) && (((SdrHint&)rHint).GetKind() == HINT_OBJREMOVED))
1684 m_pParent->ObjectRemovedInAliveMode(((SdrHint&)rHint).GetObject());
1687 //------------------------------------------------------------------------------
1688 void FmXFormView::ObjectRemovedInAliveMode( const SdrObject* pObject )
1690 // wenn das entfernte Objekt in meiner MarkList, die ich mir beim Umschalten in den Alive-Mode gemerkt habe, steht,
1691 // muss ich es jetzt da rausnehmen, da ich sonst beim Zurueckschalten versuche, die Markierung wieder zu setzen
1692 // (interesanterweise geht das nur bei gruppierten Objekten schief (beim Zugriff auf deren ObjList GPF), nicht bei einzelnen)
1694 sal_uIntPtr nCount = m_aMark.GetMarkCount();
1695 for (sal_uIntPtr i = 0; i < nCount; ++i)
1697 SdrMark* pMark = m_aMark.GetMark(i);
1698 SdrObject* pCurrent = pMark->GetMarkedSdrObj();
1699 if (pObject == pCurrent)
1701 m_aMark.DeleteMark(i);
1702 return;
1704 // ich brauche nicht in GroupObjects absteigen : wenn dort unten ein Objekt geloescht wird, dann bleibt der
1705 // Zeiger auf das GroupObject, den ich habe, trotzdem weiter gueltig bleibt ...
1709 //------------------------------------------------------------------------------
1710 void FmXFormView::stopMarkListWatching()
1712 if ( m_pWatchStoredList )
1714 m_pWatchStoredList->EndListeningAll();
1715 delete m_pWatchStoredList;
1716 m_pWatchStoredList = NULL;
1720 //------------------------------------------------------------------------------
1721 void FmXFormView::startMarkListWatching()
1723 if ( !m_pWatchStoredList )
1725 m_pWatchStoredList = new ObjectRemoveListener( this );
1726 FmFormModel* pModel = GetFormShell() ? GetFormShell()->GetFormModel() : NULL;
1727 DBG_ASSERT( pModel != NULL, "FmXFormView::startMarkListWatching: shell has no model!" );
1728 m_pWatchStoredList->StartListening( *static_cast< SfxBroadcaster* >( pModel ) );
1730 else
1732 OSL_FAIL( "FmXFormView::startMarkListWatching: already listening!" );
1736 //------------------------------------------------------------------------------
1737 void FmXFormView::saveMarkList( sal_Bool _bSmartUnmark )
1739 if ( m_pView )
1741 m_aMark = m_pView->GetMarkedObjectList();
1742 if ( _bSmartUnmark )
1744 sal_uIntPtr nCount = m_aMark.GetMarkCount( );
1745 for ( sal_uIntPtr i = 0; i < nCount; ++i )
1747 SdrMark* pMark = m_aMark.GetMark(i);
1748 SdrObject* pObj = pMark->GetMarkedSdrObj();
1750 if ( m_pView->IsObjMarked( pObj ) )
1752 if ( pObj->IsGroupObject() )
1754 SdrObjListIter aIter( *pObj->GetSubList() );
1755 sal_Bool bMixed = sal_False;
1756 while ( aIter.IsMore() && !bMixed )
1757 bMixed = ( aIter.Next()->GetObjInventor() != FmFormInventor );
1759 if ( !bMixed )
1761 // all objects in the group are form objects
1762 m_pView->MarkObj( pMark->GetMarkedSdrObj(), pMark->GetPageView(), sal_True /* unmark! */ );
1765 else
1767 if ( pObj->GetObjInventor() == FmFormInventor )
1768 { // this is a form layer object
1769 m_pView->MarkObj( pMark->GetMarkedSdrObj(), pMark->GetPageView(), sal_True /* unmark! */ );
1776 else
1778 OSL_FAIL( "FmXFormView::saveMarkList: invalid view!" );
1779 m_aMark = SdrMarkList();
1783 //--------------------------------------------------------------------------
1784 static sal_Bool lcl_hasObject( SdrObjListIter& rIter, SdrObject* pObj )
1786 sal_Bool bFound = sal_False;
1787 while (rIter.IsMore() && !bFound)
1788 bFound = pObj == rIter.Next();
1790 rIter.Reset();
1791 return bFound;
1794 //------------------------------------------------------------------------------
1795 void FmXFormView::restoreMarkList( SdrMarkList& _rRestoredMarkList )
1797 if ( !m_pView )
1798 return;
1800 _rRestoredMarkList.Clear();
1802 const SdrMarkList& rCurrentList = m_pView->GetMarkedObjectList();
1803 FmFormPage* pPage = GetFormShell() ? GetFormShell()->GetCurPage() : NULL;
1804 if (pPage)
1806 if (rCurrentList.GetMarkCount())
1807 { // there is a current mark ... hmm. Is it a subset of the mark we remembered in saveMarkList?
1808 sal_Bool bMisMatch = sal_False;
1810 // loop through all current marks
1811 sal_uIntPtr nCurrentCount = rCurrentList.GetMarkCount();
1812 for ( sal_uIntPtr i=0; i<nCurrentCount&& !bMisMatch; ++i )
1814 const SdrObject* pCurrentMarked = rCurrentList.GetMark( i )->GetMarkedSdrObj();
1816 // loop through all saved marks, check for equality
1817 sal_Bool bFound = sal_False;
1818 sal_uIntPtr nSavedCount = m_aMark.GetMarkCount();
1819 for ( sal_uIntPtr j=0; j<nSavedCount && !bFound; ++j )
1821 if ( m_aMark.GetMark( j )->GetMarkedSdrObj() == pCurrentMarked )
1822 bFound = sal_True;
1825 // did not find a current mark in the saved marks
1826 if ( !bFound )
1827 bMisMatch = sal_True;
1830 if ( bMisMatch )
1832 m_aMark.Clear();
1833 _rRestoredMarkList = rCurrentList;
1834 return;
1837 // wichtig ist das auf die Objecte der markliste nicht zugegriffen wird
1838 // da diese bereits zerstoert sein koennen
1839 SdrPageView* pCurPageView = m_pView->GetSdrPageView();
1840 SdrObjListIter aPageIter( *pPage );
1841 sal_Bool bFound = sal_True;
1843 // gibt es noch alle Objecte
1844 sal_uIntPtr nCount = m_aMark.GetMarkCount();
1845 for (sal_uIntPtr i = 0; i < nCount && bFound; i++)
1847 SdrMark* pMark = m_aMark.GetMark(i);
1848 SdrObject* pObj = pMark->GetMarkedSdrObj();
1849 if (pObj->IsGroupObject())
1851 SdrObjListIter aIter(*pObj->GetSubList());
1852 while (aIter.IsMore() && bFound)
1853 bFound = lcl_hasObject(aPageIter, aIter.Next());
1855 else
1856 bFound = lcl_hasObject(aPageIter, pObj);
1858 bFound = bFound && pCurPageView == pMark->GetPageView();
1861 if (bFound)
1863 // Das LastObject auswerten
1864 if (nCount) // Objecte jetzt Markieren
1866 for (sal_uIntPtr i = 0; i < nCount; i++)
1868 SdrMark* pMark = m_aMark.GetMark(i);
1869 SdrObject* pObj = pMark->GetMarkedSdrObj();
1870 if ( pObj->GetObjInventor() == FmFormInventor )
1871 if ( !m_pView->IsObjMarked( pObj ) )
1872 m_pView->MarkObj( pObj, pMark->GetPageView() );
1875 _rRestoredMarkList = m_aMark;
1878 m_aMark.Clear();
1881 // -----------------------------------------------------------------------------
1882 void SAL_CALL FmXFormView::focusGained( const FocusEvent& /*e*/ ) throw (RuntimeException)
1884 if ( m_xWindow.is() && m_pView )
1886 m_pView->SetMoveOutside( sal_True, FmFormView::ImplAccess() );
1889 // -----------------------------------------------------------------------------
1890 void SAL_CALL FmXFormView::focusLost( const FocusEvent& /*e*/ ) throw (RuntimeException)
1892 // when switch the focus outside the office the mark didn't change
1893 // so we can not remove us as focus listener
1894 if ( m_xWindow.is() && m_pView )
1896 m_pView->SetMoveOutside( sal_False, FmFormView::ImplAccess() );
1899 // -----------------------------------------------------------------------------
1900 void FmXFormView::removeGridWindowListening()
1902 if ( m_xWindow.is() )
1904 m_xWindow->removeFocusListener(this);
1905 if ( m_pView )
1907 m_pView->SetMoveOutside( sal_False, FmFormView::ImplAccess() );
1909 m_xWindow = NULL;
1913 // -----------------------------------------------------------------------------
1914 DocumentType FmXFormView::impl_getDocumentType() const
1916 if ( GetFormShell() && GetFormShell()->GetImpl() )
1917 return GetFormShell()->GetImpl()->getDocumentType();
1918 return eUnknownDocumentType;
1921 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */