update dev300-m58
[ooovba.git] / svx / source / form / fmvwimp.cxx
blob4f088e426307b49f1fef63a235a0856830ef0589
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fmvwimp.cxx,v $
10 * $Revision: 1.72 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include "fmctrler.hxx"
35 #include "fmdocumentclassification.hxx"
36 #include "fmobj.hxx"
37 #include "fmpgeimp.hxx"
38 #include "fmprop.hrc"
39 #include "fmresids.hrc"
40 #include "fmservs.hxx"
41 #include "fmshimp.hxx"
42 #include "fmtools.hxx"
43 #include "fmundo.hxx"
44 #include "fmvwimp.hxx"
45 #include "formcontrolfactory.hxx"
46 #include "sdrpaintwindow.hxx"
47 #include "svditer.hxx"
48 #include "svx/dataaccessdescriptor.hxx"
49 #include "svx/dialmgr.hxx"
50 #include "svx/fmglob.hxx"
51 #include "svx/fmmodel.hxx"
52 #include "svx/fmpage.hxx"
53 #include "svx/fmshell.hxx"
54 #include "svx/fmview.hxx"
55 #include "svx/sdrpagewindow.hxx"
56 #include "svx/svdogrp.hxx"
57 #include "svx/svdpagv.hxx"
58 #include "xmlexchg.hxx"
60 /** === begin UNO includes === **/
61 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
62 #include <com/sun/star/style/VerticalAlignment.hpp>
63 #include <com/sun/star/lang/XInitialization.hpp>
64 #include <com/sun/star/sdbc/XRowSet.hpp>
65 #include <com/sun/star/form/XLoadable.hpp>
66 #include <com/sun/star/awt/VisualEffect.hpp>
67 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
68 #include <com/sun/star/util/XNumberFormats.hpp>
69 #include <com/sun/star/sdb/CommandType.hpp>
70 #include <com/sun/star/sdbc/DataType.hpp>
71 #include <com/sun/star/sdbc/ColumnValue.hpp>
72 #include <com/sun/star/form/FormComponentType.hpp>
73 #include <com/sun/star/form/FormButtonType.hpp>
74 #include <com/sun/star/form/XReset.hpp>
75 #include <com/sun/star/form/binding/XBindableValue.hpp>
76 #include <com/sun/star/form/binding/XValueBinding.hpp>
77 #include <com/sun/star/form/submission/XSubmissionSupplier.hpp>
78 #include <com/sun/star/awt/XTabControllerModel.hpp>
79 #include <com/sun/star/awt/XControlContainer.hpp>
80 #include <com/sun/star/awt/XTabController.hpp>
81 #include <com/sun/star/container/XIndexAccess.hpp>
82 #include <com/sun/star/awt/XControl.hpp>
83 #include <com/sun/star/lang/XUnoTunnel.hpp>
84 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
85 #include <com/sun/star/sdbc/XPreparedStatement.hpp>
86 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
87 /** === end UNO includes === **/
89 #include <comphelper/enumhelper.hxx>
90 #include <comphelper/extract.hxx>
91 #include <comphelper/numbers.hxx>
92 #include <comphelper/property.hxx>
93 #include <svtools/moduleoptions.hxx>
94 #include <tools/diagnose_ex.h>
95 #include <vcl/msgbox.hxx>
96 #include <vcl/stdtext.hxx>
97 #include <rtl/logfile.hxx>
99 #include <algorithm>
101 using namespace ::com::sun::star;
102 using namespace ::com::sun::star::uno;
103 using namespace ::com::sun::star::beans;
104 using namespace ::com::sun::star::sdbcx;
105 using namespace ::com::sun::star::sdbc;
106 using namespace ::com::sun::star::sdb;
107 using namespace ::com::sun::star::container;
108 using namespace ::com::sun::star::form;
109 using namespace ::com::sun::star::awt;
110 using namespace ::com::sun::star::lang;
111 using namespace ::com::sun::star::util;
112 using namespace ::com::sun::star::script;
113 using namespace ::com::sun::star::style;
114 using namespace ::com::sun::star::task;
115 using namespace ::com::sun::star::ui::dialogs;
116 using namespace ::comphelper;
117 using namespace ::svxform;
118 using namespace ::svx;
119 using com::sun::star::style::VerticalAlignment_MIDDLE;
120 using ::com::sun::star::form::binding::XValueBinding;
121 using ::com::sun::star::form::binding::XBindableValue;
123 namespace svxform
125 //========================================================================
126 class OAutoDispose
128 protected:
129 Reference< XComponent > m_xComp;
131 public:
132 OAutoDispose( const Reference< XInterface > _rxObject );
133 ~OAutoDispose();
136 //------------------------------------------------------------------------
137 OAutoDispose::OAutoDispose( const Reference< XInterface > _rxObject )
138 :m_xComp(_rxObject, UNO_QUERY)
142 //------------------------------------------------------------------------
143 OAutoDispose::~OAutoDispose()
145 if (m_xComp.is())
146 m_xComp->dispose();
150 //------------------------------------------------------------------------------
151 class FmXFormView::ObjectRemoveListener : public SfxListener
153 FmXFormView* m_pParent;
154 public:
155 ObjectRemoveListener( FmXFormView* pParent );
156 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
159 //========================================================================
160 DBG_NAME(FmXPageViewWinRec)
161 //------------------------------------------------------------------------
162 FmXPageViewWinRec::FmXPageViewWinRec( const ::comphelper::ComponentContext& _rContext, const SdrPageWindow& _rWindow, FmXFormView* _pViewImpl )
163 : m_xControlContainer( _rWindow.GetControlContainer() ),
164 m_aContext( _rContext ),
165 m_pViewImpl( _pViewImpl ),
166 m_pWindow( dynamic_cast< Window* >( &_rWindow.GetPaintWindow().GetOutputDevice() ) )
168 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXPageViewWinRec::FmXPageViewWinRec" );
169 DBG_CTOR(FmXPageViewWinRec,NULL);
171 // create an XFormController for every form
172 FmFormPage* pFormPage = dynamic_cast< FmFormPage* >( _rWindow.GetPageView().GetPage() );
173 DBG_ASSERT( pFormPage, "FmXPageViewWinRec::FmXPageViewWinRec: no FmFormPage found!" );
174 if ( pFormPage )
178 Reference< XIndexAccess > xForms( pFormPage->GetForms(), UNO_QUERY_THROW );
179 sal_uInt32 nLength = xForms->getCount();
180 for (sal_uInt32 i = 0; i < nLength; i++)
182 Reference< XForm > xForm( xForms->getByIndex(i), UNO_QUERY );
183 if ( xForm.is() )
184 setController( xForm );
187 catch( const Exception& )
189 DBG_UNHANDLED_EXCEPTION();
193 // -----------------------------------------------------------------------------
194 FmXPageViewWinRec::~FmXPageViewWinRec()
196 DBG_DTOR(FmXPageViewWinRec,NULL);
199 //------------------------------------------------------------------
200 void FmXPageViewWinRec::dispose()
202 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXPageViewWinRec::dispose" );
203 for ( ::std::vector< Reference< XFormController > >::const_iterator i = m_aControllerList.begin();
204 i != m_aControllerList.end();
210 Reference< XFormController > xController( *i, UNO_SET_THROW );
212 // detaching the events
213 Reference< XChild > xControllerModel( xController->getModel(), UNO_QUERY );
214 if ( xControllerModel.is() )
216 Reference< XEventAttacherManager > xEventManager( xControllerModel->getParent(), UNO_QUERY_THROW );
217 Reference< XInterface > xControllerNormalized( xController, UNO_QUERY_THROW );
218 xEventManager->detach( i - m_aControllerList.begin(), xControllerNormalized );
221 // dispose the formcontroller
222 Reference< XComponent > xComp( xController, UNO_QUERY_THROW );
223 xComp->dispose();
225 catch( const Exception& )
227 DBG_UNHANDLED_EXCEPTION();
231 m_aControllerList.clear();
235 //------------------------------------------------------------------------------
236 sal_Bool SAL_CALL FmXPageViewWinRec::hasElements(void) throw( RuntimeException )
238 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXPageViewWinRec::hasElements" );
239 return getCount() != 0;
242 //------------------------------------------------------------------------------
243 Type SAL_CALL FmXPageViewWinRec::getElementType(void) throw( RuntimeException )
245 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXPageViewWinRec::getElementType" );
246 return ::getCppuType((const Reference< XFormController>*)0);
249 // XEnumerationAccess
250 //------------------------------------------------------------------------------
251 Reference< XEnumeration > SAL_CALL FmXPageViewWinRec::createEnumeration(void) throw( RuntimeException )
253 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXPageViewWinRec::createEnumeration" );
254 return new ::comphelper::OEnumerationByIndex(this);
257 // XIndexAccess
258 //------------------------------------------------------------------------------
259 sal_Int32 SAL_CALL FmXPageViewWinRec::getCount(void) throw( RuntimeException )
261 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXPageViewWinRec::getCount" );
262 return m_aControllerList.size();
265 //------------------------------------------------------------------------------
266 Any SAL_CALL FmXPageViewWinRec::getByIndex(sal_Int32 nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
268 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXPageViewWinRec::getByIndex" );
269 if (nIndex < 0 ||
270 nIndex >= getCount())
271 throw IndexOutOfBoundsException();
273 Any aElement;
274 aElement <<= m_aControllerList[nIndex];
275 return aElement;
278 //------------------------------------------------------------------------
279 Reference< XFormController > getControllerSearchChilds( const Reference< XIndexAccess > & xIndex, const Reference< XTabControllerModel > & xModel)
281 if (xIndex.is() && xIndex->getCount())
283 Reference< XFormController > xController;
285 for (sal_Int32 n = xIndex->getCount(); n-- && !xController.is(); )
287 xIndex->getByIndex(n) >>= xController;
288 if ((XTabControllerModel*)xModel.get() == (XTabControllerModel*)xController->getModel().get())
289 return xController;
290 else
292 xController = getControllerSearchChilds(Reference< XIndexAccess > (xController, UNO_QUERY), xModel);
293 if ( xController.is() )
294 return xController;
298 return Reference< XFormController > ();
301 // Search the according controller
302 //------------------------------------------------------------------------
303 Reference< XFormController > FmXPageViewWinRec::getController( const Reference< XForm > & xForm ) const
305 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXPageViewWinRec::getController" );
306 Reference< XTabControllerModel > xModel(xForm, UNO_QUERY);
307 for (::std::vector< Reference< XFormController > >::const_iterator i = m_aControllerList.begin();
308 i != m_aControllerList.end(); i++)
310 if ((XTabControllerModel*)(*i)->getModel().get() == (XTabControllerModel*)xModel.get())
311 return *i;
313 // the current-round controller isn't the right one. perhaps one of it's children ?
314 Reference< XFormController > xChildSearch = getControllerSearchChilds(Reference< XIndexAccess > (*i, UNO_QUERY), xModel);
315 if (xChildSearch.is())
316 return xChildSearch;
318 return Reference< XFormController > ();
321 //------------------------------------------------------------------------
322 void FmXPageViewWinRec::setController(const Reference< XForm > & xForm, FmXFormController* _pParent )
324 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXPageViewWinRec::setController" );
325 DBG_ASSERT( xForm.is(), "FmXPageViewWinRec::setController: there should be a form!" );
326 Reference< XIndexAccess > xFormCps(xForm, UNO_QUERY);
327 if (!xFormCps.is())
328 return;
330 Reference< XTabControllerModel > xTabOrder(xForm, UNO_QUERY);
332 // create a form controller
333 FmXFormController* pController = new FmXFormController( m_aContext.getLegacyServiceFactory(), m_pViewImpl->getView(), m_pWindow );
334 Reference< XFormController > xController( pController );
336 Reference< XInteractionHandler > xHandler;
337 if ( _pParent )
338 xHandler = _pParent->getInteractionHandler();
339 else
341 // TODO: should we create a default handler? Not really necessary, since the
342 // FormController itself has a default fallback
344 if ( xHandler.is() )
346 Reference< XInitialization > xInitController( xController, UNO_QUERY );
347 DBG_ASSERT( xInitController.is(), "FmXPageViewWinRec::setController: can't initialize the controller!" );
348 if ( xInitController.is() )
350 Sequence< Any > aInitArgs( 1 );
351 aInitArgs[ 0 ] <<= NamedValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InteractionHandler" ) ), makeAny( xHandler ) );
352 xInitController->initialize( aInitArgs );
356 pController->setModel(xTabOrder);
357 pController->setContainer( m_xControlContainer );
358 pController->activateTabOrder();
359 pController->addActivateListener(m_pViewImpl);
361 if ( _pParent )
362 _pParent->addChild(pController);
363 else
365 // Reference< XFormController > xController(pController);
366 m_aControllerList.push_back(xController);
368 pController->setParent(*this);
370 // attaching the events
371 Reference< XEventAttacherManager > xEventManager(xForm->getParent(), UNO_QUERY);
372 Reference< XInterface > xIfc(xController, UNO_QUERY);
373 xEventManager->attach(m_aControllerList.size() - 1, xIfc, makeAny(xController) );
378 // jetzt die Subforms durchgehen
379 sal_uInt32 nLength = xFormCps->getCount();
380 Reference< XForm > xSubForm;
381 for (sal_uInt32 i = 0; i < nLength; i++)
383 if ( xFormCps->getByIndex(i) >>= xSubForm )
384 setController(xSubForm, pController);
388 //------------------------------------------------------------------------
389 void FmXPageViewWinRec::updateTabOrder( const Reference< XForm >& _rxForm )
391 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXPageViewWinRec::updateTabOrder" );
392 OSL_PRECOND( _rxForm.is(), "FmXPageViewWinRec::updateTabOrder: illegal argument!" );
393 if ( !_rxForm.is() )
394 return;
398 Reference< XTabController > xTabCtrl( getController( _rxForm ).get() );
399 if ( xTabCtrl.is() )
400 { // if there already is a TabController for this form, then delegate the "updateTabOrder" request
401 xTabCtrl->activateTabOrder();
403 else
404 { // otherwise, create a TabController
406 // if it's a sub form, then we must ensure there exist TabControllers
407 // for all its ancestors, too
408 Reference< XForm > xParentForm( _rxForm->getParent(), UNO_QUERY );
409 FmXFormController* pFormController = NULL;
410 // there is a parent form -> look for the respective controller
411 if ( xParentForm.is() )
412 xTabCtrl = Reference< XTabController >( getController( xParentForm ), UNO_QUERY );
414 if ( xTabCtrl.is() )
416 Reference< XUnoTunnel > xTunnel( xTabCtrl, UNO_QUERY_THROW );
417 pFormController = reinterpret_cast< FmXFormController* >( xTunnel->getSomething( FmXFormController::getUnoTunnelImplementationId() ) );
420 setController( _rxForm, pFormController );
423 catch( const Exception& )
425 DBG_UNHANDLED_EXCEPTION();
429 //------------------------------------------------------------------------
430 FmXFormView::FmXFormView(const ::comphelper::ComponentContext& _rContext, FmFormView* _pView )
431 :m_aContext( _rContext )
432 ,m_pMarkedGrid(NULL)
433 ,m_pView(_pView)
434 ,m_nActivationEvent(0)
435 ,m_nErrorMessageEvent( 0 )
436 ,m_nAutoFocusEvent( 0 )
437 ,m_nControlWizardEvent( 0 )
438 ,m_pWatchStoredList( NULL )
439 ,m_bFirstActivation( true )
440 ,m_isTabOrderUpdateSuspended( false )
442 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::FmXFormView" );
445 //------------------------------------------------------------------------
446 void FmXFormView::cancelEvents()
448 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::cancelEvents" );
449 if ( m_nActivationEvent )
451 Application::RemoveUserEvent( m_nActivationEvent );
452 m_nActivationEvent = 0;
455 if ( m_nErrorMessageEvent )
457 Application::RemoveUserEvent( m_nErrorMessageEvent );
458 m_nErrorMessageEvent = 0;
461 if ( m_nAutoFocusEvent )
463 Application::RemoveUserEvent( m_nAutoFocusEvent );
464 m_nAutoFocusEvent = 0;
467 if ( m_nControlWizardEvent )
469 Application::RemoveUserEvent( m_nControlWizardEvent );
470 m_nControlWizardEvent = 0;
474 //------------------------------------------------------------------------
475 void FmXFormView::notifyViewDying( )
477 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::notifyViewDying" );
478 DBG_ASSERT( m_pView, "FmXFormView::notifyViewDying: my view already died!" );
479 m_pView = NULL;
480 cancelEvents();
483 //------------------------------------------------------------------------
484 FmXFormView::~FmXFormView()
486 DBG_ASSERT(m_aWinList.size() == 0, "FmXFormView::~FmXFormView: Window list not empty!");
488 cancelEvents();
490 delete m_pWatchStoredList;
491 m_pWatchStoredList = NULL;
494 // EventListener
495 //------------------------------------------------------------------------------
496 void SAL_CALL FmXFormView::disposing(const EventObject& Source) throw( RuntimeException )
498 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::disposing" );
499 if ( m_xWindow.is() && Source.Source == m_xWindow )
500 removeGridWindowListening();
503 // XFormControllerListener
504 //------------------------------------------------------------------------------
505 void SAL_CALL FmXFormView::formActivated(const EventObject& rEvent) throw( RuntimeException )
507 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::formActivated" );
508 if ( m_pView && m_pView->GetFormShell() && m_pView->GetFormShell()->GetImpl() )
509 m_pView->GetFormShell()->GetImpl()->formActivated( rEvent );
512 //------------------------------------------------------------------------------
513 void SAL_CALL FmXFormView::formDeactivated(const EventObject& rEvent) throw( RuntimeException )
515 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::formDeactivated" );
516 if ( m_pView && m_pView->GetFormShell() && m_pView->GetFormShell()->GetImpl() )
517 m_pView->GetFormShell()->GetImpl()->formDeactivated( rEvent );
520 // XContainerListener
521 //------------------------------------------------------------------------------
522 void SAL_CALL FmXFormView::elementInserted(const ContainerEvent& evt) throw( RuntimeException )
524 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::elementInserted" );
527 Reference< XControlContainer > xControlContainer( evt.Source, UNO_QUERY_THROW );
528 Reference< XControl > xControl( evt.Element, UNO_QUERY_THROW );
529 Reference< XFormComponent > xControlModel( xControl->getModel(), UNO_QUERY_THROW );
530 Reference< XForm > xForm( xControlModel->getParent(), UNO_QUERY_THROW );
532 if ( m_isTabOrderUpdateSuspended )
534 // remember the container and the control, so we can update the tab order on resumeTabOrderUpdate
535 m_aNeedTabOrderUpdate[ xControlContainer ].insert( xForm );
537 else
539 FmWinRecList::iterator pos = findWindow( xControlContainer );
540 if ( pos != m_aWinList.end() )
542 (*pos)->updateTabOrder( xForm );
546 catch( const Exception& )
548 DBG_UNHANDLED_EXCEPTION();
552 //------------------------------------------------------------------------------
553 void SAL_CALL FmXFormView::elementReplaced(const ContainerEvent& evt) throw( RuntimeException )
555 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::elementReplaced" );
556 elementInserted(evt);
559 //------------------------------------------------------------------------------
560 void SAL_CALL FmXFormView::elementRemoved(const ContainerEvent& /*evt*/) throw( RuntimeException )
562 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::elementRemoved" );
565 //------------------------------------------------------------------------------
566 FmWinRecList::const_iterator FmXFormView::findWindow( const Reference< XControlContainer >& _rxCC ) const
568 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::findWindow" );
569 for (FmWinRecList::const_iterator i = m_aWinList.begin();
570 i != m_aWinList.end(); i++)
572 if ( _rxCC == (*i)->getControlContainer() )
573 return i;
575 return m_aWinList.end();
578 //------------------------------------------------------------------------------
579 FmWinRecList::iterator FmXFormView::findWindow( const Reference< XControlContainer >& _rxCC )
581 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::findWindow" );
582 for (FmWinRecList::iterator i = m_aWinList.begin();
583 i != m_aWinList.end(); i++)
585 if ( _rxCC == (*i)->getControlContainer() )
586 return i;
588 return m_aWinList.end();
591 //------------------------------------------------------------------------------
592 void FmXFormView::addWindow(const SdrPageWindow& rWindow)
594 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::addWindow" );
595 FmFormPage* pFormPage = PTR_CAST( FmFormPage, rWindow.GetPageView().GetPage() );
596 if ( !pFormPage )
597 return;
599 Reference< XControlContainer > xCC = rWindow.GetControlContainer();
600 if ( xCC.is() && findWindow( xCC ) == m_aWinList.end())
602 FmXPageViewWinRec *pFmRec = new FmXPageViewWinRec( m_aContext, rWindow, this );
603 pFmRec->acquire();
605 m_aWinList.push_back(pFmRec);
607 // Am ControlContainer horchen um Aenderungen mitzbekommen
608 Reference< XContainer > xContainer( xCC, UNO_QUERY );
609 if (xContainer.is())
610 xContainer->addContainerListener(this);
614 //------------------------------------------------------------------------------
615 void FmXFormView::removeWindow( const Reference< XControlContainer >& _rxCC )
617 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::removeWindow" );
618 // Wird gerufen, wenn
619 // - in den Design-Modus geschaltet wird
620 // - ein Window geloescht wird, waehrend man im Design-Modus ist
621 // - der Control-Container fuer ein Window entfernt wird, waehrend
622 // der aktive Modus eingeschaltet ist.
623 FmWinRecList::iterator i = findWindow( _rxCC );
624 if (i != m_aWinList.end())
626 // Am ControlContainer horchen um Aenderungen mitzbekommen
627 Reference< XContainer > xContainer( _rxCC, UNO_QUERY );
628 if (xContainer.is())
629 xContainer->removeContainerListener(this);
631 (*i)->dispose();
632 (*i)->release();
633 m_aWinList.erase(i);
637 //------------------------------------------------------------------------------
638 void FmXFormView::displayAsyncErrorMessage( const SQLErrorEvent& _rEvent )
640 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::displayAsyncErrorMessage" );
641 DBG_ASSERT( 0 == m_nErrorMessageEvent, "FmXFormView::displayAsyncErrorMessage: not too fast, please!" );
642 // This should not happen - usually, the PostUserEvent is faster than any possible user
643 // interaction which could trigger a new error. If it happens, we need a queue for the events.
644 m_aAsyncError = _rEvent;
645 m_nErrorMessageEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnDelayedErrorMessage ) );
648 //------------------------------------------------------------------------------
649 IMPL_LINK(FmXFormView, OnDelayedErrorMessage, void*, /*EMPTYTAG*/)
651 m_nErrorMessageEvent = 0;
652 displayException( m_aAsyncError );
653 return 0L;
656 //------------------------------------------------------------------------------
657 void FmXFormView::onFirstViewActivation( const FmFormModel* _pDocModel )
659 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::onFirstViewActivation" );
660 if ( _pDocModel && _pDocModel->GetAutoControlFocus() )
661 m_nAutoFocusEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnAutoFocus ) );
664 //------------------------------------------------------------------------------
665 void FmXFormView::suspendTabOrderUpdate()
667 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::suspendTabOrderUpdate" );
668 OSL_ENSURE( !m_isTabOrderUpdateSuspended, "FmXFormView::suspendTabOrderUpdate: nesting not allowed!" );
669 m_isTabOrderUpdateSuspended = true;
672 //------------------------------------------------------------------------------
673 void FmXFormView::resumeTabOrderUpdate()
675 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::resumeTabOrderUpdate" );
676 OSL_ENSURE( m_isTabOrderUpdateSuspended, "FmXFormView::resumeTabOrderUpdate: not suspended!" );
677 m_isTabOrderUpdateSuspended = false;
679 // update the tab orders for all components which were collected since the suspendTabOrderUpdate call.
680 for ( MapControlContainerToSetOfForms::const_iterator container = m_aNeedTabOrderUpdate.begin();
681 container != m_aNeedTabOrderUpdate.end();
682 ++container
685 FmWinRecList::iterator pos = findWindow( container->first );
686 if ( pos == m_aWinList.end() )
687 continue;
689 for ( SetOfForms::const_iterator form = container->second.begin();
690 form != container->second.end();
691 ++form
694 (*pos)->updateTabOrder( *form );
697 m_aNeedTabOrderUpdate.clear();
700 //------------------------------------------------------------------------------
701 IMPL_LINK(FmXFormView, OnActivate, void*, /*EMPTYTAG*/)
703 m_nActivationEvent = 0;
705 if ( !m_pView )
707 DBG_ERROR( "FmXFormView::OnActivate: well .... seems we have a timing problem (the view already died)!" );
708 return 0;
711 // setting the controller to activate
712 if (m_pView->GetFormShell() && m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW)
714 Window* pWindow = const_cast<Window*>(static_cast<const Window*>(m_pView->GetActualOutDev()));
715 FmXPageViewWinRec* pFmRec = m_aWinList.size() ? m_aWinList[0] : NULL;
716 for (FmWinRecList::const_iterator i = m_aWinList.begin();
717 i != m_aWinList.end(); i++)
719 if (pWindow == (*i)->getWindow())
720 pFmRec =*i;
723 if (pFmRec)
725 for (::std::vector< Reference< XFormController > >::const_iterator i = pFmRec->GetList().begin();
726 i != pFmRec->GetList().end(); i++)
728 const Reference< XFormController > & xController = *i;
729 if (xController.is())
731 // Nur bei Datenbankformularen erfolgt eine aktivierung
732 Reference< XRowSet > xForm(xController->getModel(), UNO_QUERY);
733 if (xForm.is() && OStaticDataAccessTools().getRowSetConnection(xForm).is())
735 Reference< XPropertySet > xFormSet(xForm, UNO_QUERY);
736 if (xFormSet.is())
738 // wenn es eine Datenquelle gibt, dann als aktive ::com::sun::star::form setzen
739 ::rtl::OUString aSource = ::comphelper::getString(xFormSet->getPropertyValue(FM_PROP_COMMAND));
740 if (aSource.getLength())
742 // benachrichtigung der Shell
743 FmXFormShell* pShImpl = m_pView->GetFormShell()->GetImpl();
744 if (pShImpl)
745 pShImpl->setActiveController(xController);
746 break;
754 return 0;
757 //------------------------------------------------------------------------------
758 void FmXFormView::Activate(sal_Bool bSync)
760 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::Activate" );
761 if (m_nActivationEvent)
763 Application::RemoveUserEvent(m_nActivationEvent);
764 m_nActivationEvent = 0;
767 if (bSync)
769 LINK(this,FmXFormView,OnActivate).Call(NULL);
771 else
772 m_nActivationEvent = Application::PostUserEvent(LINK(this,FmXFormView,OnActivate));
775 //------------------------------------------------------------------------------
776 void FmXFormView::Deactivate(BOOL bDeactivateController)
778 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::Deactivate" );
779 if (m_nActivationEvent)
781 Application::RemoveUserEvent(m_nActivationEvent);
782 m_nActivationEvent = 0;
785 FmXFormShell* pShImpl = m_pView->GetFormShell() ? m_pView->GetFormShell()->GetImpl() : NULL;
786 if (pShImpl && bDeactivateController)
787 pShImpl->setActiveController( NULL );
790 //------------------------------------------------------------------------------
791 FmFormShell* FmXFormView::GetFormShell() const
793 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::GetFormShell" );
794 return m_pView ? m_pView->GetFormShell() : NULL;
796 // -----------------------------------------------------------------------------
797 void FmXFormView::AutoFocus( sal_Bool _bSync )
799 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::AutoFocus" );
800 if (m_nAutoFocusEvent)
801 Application::RemoveUserEvent(m_nAutoFocusEvent);
803 if ( _bSync )
804 OnAutoFocus( NULL );
805 else
806 m_nAutoFocusEvent = Application::PostUserEvent(LINK(this, FmXFormView, OnAutoFocus));
808 // -----------------------------------------------------------------------------
809 static Reference< XControl > lcl_firstFocussableControl( const Sequence< Reference< XControl > >& _rControls )
811 Reference< XControl > xReturn;
813 // loop through all the controls
814 const Reference< XControl >* pControls = _rControls.getConstArray();
815 const Reference< XControl >* pControlsEnd = _rControls.getConstArray() + _rControls.getLength();
816 for ( ; pControls != pControlsEnd; ++pControls )
820 if ( !pControls->is() )
821 continue;
823 Reference< XPropertySet > xModelProps( (*pControls)->getModel(), UNO_QUERY_THROW );
825 // only enabled controls are allowed to participate
826 sal_Bool bEnabled = sal_False;
827 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_ENABLED ) >>= bEnabled );
828 if ( !bEnabled )
829 continue;
831 // check the class id of the control model
832 sal_Int16 nClassId = FormComponentType::CONTROL;
833 OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
835 // controls which are not focussable
836 if ( ( FormComponentType::CONTROL != nClassId )
837 && ( FormComponentType::IMAGEBUTTON != nClassId )
838 && ( FormComponentType::GROUPBOX != nClassId )
839 && ( FormComponentType::FIXEDTEXT != nClassId )
840 && ( FormComponentType::HIDDENCONTROL != nClassId )
841 && ( FormComponentType::IMAGECONTROL != nClassId )
842 && ( FormComponentType::SCROLLBAR != nClassId )
843 && ( FormComponentType::SPINBUTTON!= nClassId )
846 xReturn = *pControls;
847 break;
850 catch( const Exception& e )
852 (void)e; // make compiler happy
855 if ( !xReturn.is() && _rControls.getLength() )
856 xReturn = _rControls[0];
859 return xReturn;
862 // -----------------------------------------------------------------------------
863 namespace
865 // .........................................................................
866 void lcl_ensureControlsOfFormExist_nothrow( const SdrPage& _rPage, const SdrView& _rView, const Window& _rWindow, const Reference< XForm >& _rxForm )
870 Reference< XInterface > xNormalizedForm( _rxForm, UNO_QUERY_THROW );
872 SdrObjListIter aSdrObjectLoop( _rPage, IM_DEEPNOGROUPS );
873 while ( aSdrObjectLoop.IsMore() )
875 FmFormObj* pFormObject = FmFormObj::GetFormObject( aSdrObjectLoop.Next() );
876 if ( !pFormObject )
877 continue;
879 Reference< XChild > xModel( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW );
880 Reference< XInterface > xModelParent( xModel->getParent(), UNO_QUERY_THROW );
882 if ( xNormalizedForm.get() != xModelParent.get() )
883 continue;
885 pFormObject->GetUnoControl( _rView, _rWindow );
888 catch( const Exception& )
890 DBG_UNHANDLED_EXCEPTION();
895 // -----------------------------------------------------------------------------
896 Reference< XFormController > FmXFormView::getFormController( const Reference< XForm >& _rxForm, const OutputDevice& _rDevice ) const
898 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::getFormController" );
899 Reference< XFormController > xController;
901 for ( FmWinRecList::const_iterator rec = m_aWinList.begin(); rec != m_aWinList.end(); ++rec )
903 const FmXPageViewWinRec* pViewWinRec( *rec );
904 OSL_ENSURE( pViewWinRec, "FmXFormView::getFormController: invalid PageViewWinRec!" );
905 if ( !pViewWinRec || ( pViewWinRec->getWindow() != &_rDevice ) )
906 // wrong device
907 continue;
909 xController = pViewWinRec->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 // get the forms collection of the page we belong to
928 FmFormPage* pPage = m_pView ? PTR_CAST( FmFormPage, m_pView->GetSdrPageView()->GetPage() ) : NULL;
929 Reference< XIndexAccess > xForms( pPage ? Reference< XIndexAccess >( pPage->GetForms(), UNO_QUERY ) : Reference< XIndexAccess >() );
931 const FmXPageViewWinRec* pViewWinRec = m_aWinList.size() ? m_aWinList[0] : NULL;
932 const Window* pWindow = pViewWinRec ? pViewWinRec->getWindow() : NULL;
934 OSL_ENSURE( xForms.is() && pWindow, "FmXFormView::OnAutoFocus: could not collect all essentials!" );
935 if ( !xForms.is() || !pWindow )
936 return 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( pViewWinRec->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 namespace
997 // -----------------------------------------------------------------------------
998 void FmXFormView::onCreatedFormObject( FmFormObj& _rFormObject )
1000 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::onCreatedFormObject" );
1001 FmFormShell* pShell = m_pView ? m_pView->GetFormShell() : NULL;
1002 FmXFormShell* pShellImpl = pShell ? pShell->GetImpl() : NULL;
1003 OSL_ENSURE( pShellImpl, "FmXFormView::onCreatedFormObject: no form shell!" );
1004 if ( !pShellImpl )
1005 return;
1007 // it is valid that the form shell's forms collection is not initialized, yet
1008 pShellImpl->UpdateForms( sal_True );
1010 m_xLastCreatedControlModel.set( _rFormObject.GetUnoControlModel(), UNO_QUERY );
1011 if ( !m_xLastCreatedControlModel.is() )
1012 return;
1014 // some initial property defaults
1015 FormControlFactory aControlFactory( m_aContext );
1016 aControlFactory.initializeControlModel( pShellImpl->getDocumentType(), _rFormObject );
1018 if ( !pShellImpl->GetWizardUsing() )
1019 return;
1021 // #i31958# don't call wizards in XForms mode
1022 if ( pShellImpl->isEnhancedForm() )
1023 return;
1025 // #i46898# no wizards if there is no Base installed - currently, all wizards are
1026 // database related
1027 if ( !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
1028 return;
1030 if ( m_nControlWizardEvent )
1031 Application::RemoveUserEvent( m_nControlWizardEvent );
1032 m_nControlWizardEvent = Application::PostUserEvent( LINK( this, FmXFormView, OnStartControlWizard ) );
1035 // -----------------------------------------------------------------------------
1036 IMPL_LINK( FmXFormView, OnStartControlWizard, void*, /**/ )
1038 m_nControlWizardEvent = 0;
1039 OSL_PRECOND( m_xLastCreatedControlModel.is(), "FmXFormView::OnStartControlWizard: illegal call!" );
1040 if ( !m_xLastCreatedControlModel.is() )
1041 return 0L;
1043 sal_Int16 nClassId = FormComponentType::CONTROL;
1046 OSL_VERIFY( m_xLastCreatedControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
1048 catch( const Exception& )
1050 DBG_UNHANDLED_EXCEPTION();
1053 const sal_Char* pWizardAsciiName = NULL;
1054 switch ( nClassId )
1056 case FormComponentType::GRIDCONTROL:
1057 pWizardAsciiName = "com.sun.star.sdb.GridControlAutoPilot";
1058 break;
1059 case FormComponentType::LISTBOX:
1060 case FormComponentType::COMBOBOX:
1061 pWizardAsciiName = "com.sun.star.sdb.ListComboBoxAutoPilot";
1062 break;
1063 case FormComponentType::GROUPBOX:
1064 pWizardAsciiName = "com.sun.star.sdb.GroupBoxAutoPilot";
1065 break;
1068 if ( pWizardAsciiName )
1070 // build the argument list
1071 Sequence< Any > aWizardArgs(1);
1072 // the object affected
1073 aWizardArgs[0] = makeAny( PropertyValue(
1074 ::rtl::OUString::createFromAscii("ObjectModel"),
1076 makeAny( m_xLastCreatedControlModel ),
1077 PropertyState_DIRECT_VALUE
1078 ) );
1080 // create the wizard object
1081 Reference< XExecutableDialog > xWizard;
1084 m_aContext.createComponentWithArguments( pWizardAsciiName, aWizardArgs, xWizard );
1086 catch( const Exception& )
1088 DBG_UNHANDLED_EXCEPTION();
1091 if ( !xWizard.is() )
1093 ShowServiceNotAvailableError( NULL, String::CreateFromAscii( pWizardAsciiName ), sal_True );
1095 else
1097 // execute the wizard
1100 xWizard->execute();
1102 catch( const Exception& )
1104 DBG_UNHANDLED_EXCEPTION();
1109 m_xLastCreatedControlModel.clear();
1110 return 1L;
1113 // -----------------------------------------------------------------------------
1114 namespace
1116 void lcl_insertIntoFormComponentHierarchy_throw( const FmFormView& _rView, const SdrUnoObj& _rSdrObj,
1117 const Reference< XDataSource >& _rxDataSource = NULL, const ::rtl::OUString& _rDataSourceName = ::rtl::OUString(),
1118 const ::rtl::OUString& _rCommand = ::rtl::OUString(), const sal_Int32 _nCommandType = -1 )
1120 FmFormPage& rPage = static_cast< FmFormPage& >( *_rView.GetSdrPageView()->GetPage() );
1122 Reference< XFormComponent > xFormComponent( _rSdrObj.GetUnoControlModel(), UNO_QUERY_THROW );
1123 Reference< XForm > xTargetForm(
1124 rPage.GetImpl().findPlaceInFormComponentHierarchy( xFormComponent, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType ),
1125 UNO_SET_THROW );
1127 rPage.GetImpl().setUniqueName( xFormComponent, xTargetForm );
1129 Reference< XIndexContainer > xFormAsContainer( xTargetForm, UNO_QUERY_THROW );
1130 xFormAsContainer->insertByIndex( xFormAsContainer->getCount(), makeAny( xFormComponent ) );
1134 // -----------------------------------------------------------------------------
1135 SdrObject* FmXFormView::implCreateFieldControl( const ::svx::ODataAccessDescriptor& _rColumnDescriptor )
1137 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::implCreateFieldControl" );
1138 // not if we're in design mode
1139 if ( !m_pView->IsDesignMode() )
1140 return NULL;
1142 ::rtl::OUString sCommand, sFieldName;
1143 sal_Int32 nCommandType = CommandType::COMMAND;
1144 SharedConnection xConnection;
1146 ::rtl::OUString sDataSource = _rColumnDescriptor.getDataSource();
1147 _rColumnDescriptor[ daCommand ] >>= sCommand;
1148 _rColumnDescriptor[ daColumnName ] >>= sFieldName;
1149 _rColumnDescriptor[ daCommandType ] >>= nCommandType;
1151 Reference< XConnection > xExternalConnection;
1152 _rColumnDescriptor[ daConnection ] >>= xExternalConnection;
1153 xConnection.reset( xExternalConnection, SharedConnection::NoTakeOwnership );
1156 if ( !sCommand.getLength()
1157 || !sFieldName.getLength()
1158 || ( !sDataSource.getLength()
1159 && !xConnection.is()
1163 DBG_ERROR( "FmXFormView::implCreateFieldControl: nonsense!" );
1166 Reference< XDataSource > xDataSource;
1167 SQLErrorEvent aError;
1170 if ( xConnection.is() && !xDataSource.is() && !sDataSource.getLength() )
1172 Reference< XChild > xChild( xConnection, UNO_QUERY );
1173 if ( xChild.is() )
1174 xDataSource = xDataSource.query( xChild->getParent() );
1177 // obtain the data source
1178 if ( !xDataSource.is() )
1179 xDataSource = OStaticDataAccessTools().getDataSource( sDataSource, m_aContext.getLegacyServiceFactory() );
1181 // and the connection, if necessary
1182 if ( !xConnection.is() )
1183 xConnection.reset( OStaticDataAccessTools().getConnection_withFeedback(
1184 sDataSource,
1185 ::rtl::OUString(),
1186 ::rtl::OUString(),
1187 m_aContext.getLegacyServiceFactory()
1188 ) );
1190 catch(const SQLContext& e) { aError.Reason <<= e; }
1191 catch(const SQLWarning& e) { aError.Reason <<= e; }
1192 catch(const SQLException& e) { aError.Reason <<= e; }
1193 catch( const Exception& ) { /* will be asserted below */ }
1194 if (aError.Reason.hasValue())
1196 displayAsyncErrorMessage( aError );
1197 return NULL;
1200 // need a data source and a connection here
1201 if (!xDataSource.is() || !xConnection.is())
1203 DBG_ERROR("FmXFormView::implCreateFieldControl : could not retrieve the data source or the connection!");
1204 return NULL;
1207 OStaticDataAccessTools aDBATools;
1208 Reference< XComponent > xKeepFieldsAlive;
1209 // go
1212 // determine the table/query field which we should create a control for
1213 Reference< XPropertySet > xField;
1215 Reference< XNameAccess > xFields = aDBATools.getFieldsByCommandDescriptor(
1216 xConnection, nCommandType, sCommand, xKeepFieldsAlive );
1218 if (xFields.is() && xFields->hasByName(sFieldName))
1219 xFields->getByName(sFieldName) >>= xField;
1221 Reference< XNumberFormatsSupplier > xSupplier = aDBATools.getNumberFormats(xConnection, sal_False);
1222 if (!xSupplier.is() || !xField.is())
1223 return NULL;
1225 Reference< XNumberFormats > xNumberFormats(xSupplier->getNumberFormats());
1226 if (!xNumberFormats.is())
1227 return NULL;
1229 ::rtl::OUString sLabelPostfix;
1231 ////////////////////////////////////////////////////////////////
1232 // nur fuer Textgroesse
1233 OutputDevice* pOutDev = NULL;
1234 if (m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW)
1235 pOutDev = const_cast<OutputDevice*>(m_pView->GetActualOutDev());
1236 else
1237 {// OutDev suchen
1238 SdrPageView* pPageView = m_pView->GetSdrPageView();
1239 if( pPageView && !pOutDev )
1241 // const SdrPageViewWinList& rWinList = pPageView->GetWinList();
1242 // const SdrPageViewWindows& rPageViewWindows = pPageView->GetPageViewWindows();
1244 for( sal_uInt32 i = 0L; i < pPageView->PageWindowCount(); i++ )
1246 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(i);
1248 if( rPageWindow.GetPaintWindow().OutputToWindow())
1250 pOutDev = &rPageWindow.GetPaintWindow().GetOutputDevice();
1251 break;
1257 if ( !pOutDev )
1258 return NULL;
1260 sal_Int32 nDataType = ::comphelper::getINT32(xField->getPropertyValue(FM_PROP_FIELDTYPE));
1261 if ((DataType::BINARY == nDataType) || (DataType::VARBINARY == nDataType))
1262 return NULL;
1264 //////////////////////////////////////////////////////////////////////
1265 // determine the control type by examining the data type of the bound column
1266 sal_uInt16 nOBJID = 0;
1267 sal_Bool bDateNTimeField = sal_False;
1269 sal_Bool bIsCurrency = sal_False;
1270 if (::comphelper::hasProperty(FM_PROP_ISCURRENCY, xField))
1271 bIsCurrency = ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_ISCURRENCY));
1273 if (bIsCurrency)
1274 nOBJID = OBJ_FM_CURRENCYFIELD;
1275 else
1276 switch (nDataType)
1278 case DataType::LONGVARBINARY:
1279 nOBJID = OBJ_FM_IMAGECONTROL;
1280 break;
1281 case DataType::LONGVARCHAR:
1282 nOBJID = OBJ_FM_EDIT;
1283 break;
1284 case DataType::BINARY:
1285 case DataType::VARBINARY:
1286 return NULL;
1287 case DataType::BIT:
1288 case DataType::BOOLEAN:
1289 nOBJID = OBJ_FM_CHECKBOX;
1290 break;
1291 case DataType::TINYINT:
1292 case DataType::SMALLINT:
1293 case DataType::INTEGER:
1294 nOBJID = OBJ_FM_NUMERICFIELD;
1295 break;
1296 case DataType::REAL:
1297 case DataType::DOUBLE:
1298 case DataType::NUMERIC:
1299 case DataType::DECIMAL:
1300 nOBJID = OBJ_FM_FORMATTEDFIELD;
1301 break;
1302 case DataType::TIMESTAMP:
1303 bDateNTimeField = sal_True;
1304 sLabelPostfix = String( SVX_RES( RID_STR_POSTFIX_DATE ) );
1305 // DON'T break !
1306 case DataType::DATE:
1307 nOBJID = OBJ_FM_DATEFIELD;
1308 break;
1309 case DataType::TIME:
1310 nOBJID = OBJ_FM_TIMEFIELD;
1311 break;
1312 case DataType::CHAR:
1313 case DataType::VARCHAR:
1314 default:
1315 nOBJID = OBJ_FM_EDIT;
1316 break;
1318 if (!nOBJID)
1319 return NULL;
1321 SdrUnoObj* pLabel( NULL );
1322 SdrUnoObj* pControl( NULL );
1323 if ( !createControlLabelPair( *pOutDev, 0, 0, xField, xNumberFormats, nOBJID, sLabelPostfix,
1324 pLabel, pControl, xDataSource, sDataSource, sCommand, nCommandType )
1327 return NULL;
1330 //////////////////////////////////////////////////////////////////////
1331 // group objects
1332 bool bCheckbox = ( OBJ_FM_CHECKBOX == nOBJID );
1333 OSL_ENSURE( !bCheckbox || !pLabel, "FmXFormView::implCreateFieldControl: why was there a label created for a check box?" );
1334 if ( bCheckbox )
1335 return pControl;
1337 SdrObjGroup* pGroup = new SdrObjGroup();
1338 SdrObjList* pObjList = pGroup->GetSubList();
1339 pObjList->InsertObject( pLabel );
1340 pObjList->InsertObject( pControl );
1342 if ( bDateNTimeField )
1343 { // so far we created a date field only, but we also need a time field
1344 pLabel = pControl = NULL;
1345 if ( createControlLabelPair( *pOutDev, 0, 1000, xField, xNumberFormats, OBJ_FM_TIMEFIELD,
1346 String( SVX_RES( RID_STR_POSTFIX_TIME ) ), pLabel, pControl,
1347 xDataSource, sDataSource, sCommand, nCommandType )
1350 pObjList->InsertObject( pLabel );
1351 pObjList->InsertObject( pControl );
1355 return pGroup; // und fertig
1357 catch(const Exception&)
1359 DBG_UNHANDLED_EXCEPTION();
1363 return NULL;
1366 // -----------------------------------------------------------------------------
1367 SdrObject* FmXFormView::implCreateXFormsControl( const ::svx::OXFormsDescriptor &_rDesc )
1369 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::implCreateXFormsControl" );
1370 // not if we're in design mode
1371 if ( !m_pView->IsDesignMode() )
1372 return NULL;
1374 Reference< XComponent > xKeepFieldsAlive;
1376 // go
1379 // determine the table/query field which we should create a control for
1380 Reference< XNumberFormats > xNumberFormats;
1381 ::rtl::OUString sLabelPostfix = _rDesc.szName;
1383 ////////////////////////////////////////////////////////////////
1384 // nur fuer Textgroesse
1385 OutputDevice* pOutDev = NULL;
1386 if (m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW)
1387 pOutDev = const_cast<OutputDevice*>(m_pView->GetActualOutDev());
1388 else
1389 {// OutDev suchen
1390 SdrPageView* pPageView = m_pView->GetSdrPageView();
1391 if( pPageView && !pOutDev )
1393 // const SdrPageViewWinList& rWinList = pPageView->GetWinList();
1394 // const SdrPageViewWindows& rPageViewWindows = pPageView->GetPageViewWindows();
1396 for( sal_uInt32 i = 0L; i < pPageView->PageWindowCount(); i++ )
1398 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(i);
1400 if( rPageWindow.GetPaintWindow().GetOutputDevice().GetOutDevType() == OUTDEV_WINDOW)
1402 pOutDev = &rPageWindow.GetPaintWindow().GetOutputDevice();
1403 break;
1409 if ( !pOutDev )
1410 return NULL;
1412 //////////////////////////////////////////////////////////////////////
1413 // The service name decides which control should be created
1414 sal_uInt16 nOBJID = OBJ_FM_EDIT;
1415 if(::rtl::OUString(_rDesc.szServiceName).equals((::rtl::OUString)FM_SUN_COMPONENT_NUMERICFIELD))
1416 nOBJID = OBJ_FM_NUMERICFIELD;
1417 if(::rtl::OUString(_rDesc.szServiceName).equals((::rtl::OUString)FM_SUN_COMPONENT_CHECKBOX))
1418 nOBJID = OBJ_FM_CHECKBOX;
1419 if(::rtl::OUString(_rDesc.szServiceName).equals((::rtl::OUString)FM_COMPONENT_COMMANDBUTTON))
1420 nOBJID = OBJ_FM_BUTTON;
1422 typedef ::com::sun::star::form::submission::XSubmission XSubmission_t;
1423 Reference< XSubmission_t > xSubmission(_rDesc.xPropSet, UNO_QUERY);
1425 // xform control or submission button?
1426 if ( !xSubmission.is() )
1428 SdrUnoObj* pLabel( NULL );
1429 SdrUnoObj* pControl( NULL );
1430 if ( !createControlLabelPair( *pOutDev, 0, 0, NULL, xNumberFormats, nOBJID, sLabelPostfix,
1431 pLabel, pControl )
1434 return NULL;
1437 //////////////////////////////////////////////////////////////////////
1438 // Now build the connection between the control and the data item.
1439 Reference< XValueBinding > xValueBinding(_rDesc.xPropSet,UNO_QUERY);
1440 Reference< XBindableValue > xBindableValue(pControl->GetUnoControlModel(),UNO_QUERY);
1442 DBG_ASSERT( xBindableValue.is(), "FmXFormView::implCreateXFormsControl: control's not bindable!" );
1443 if ( xBindableValue.is() )
1444 xBindableValue->setValueBinding(xValueBinding);
1446 bool bCheckbox = ( OBJ_FM_CHECKBOX == nOBJID );
1447 OSL_ENSURE( !bCheckbox || !pLabel, "FmXFormView::implCreateXFormsControl: why was there a label created for a check box?" );
1448 if ( bCheckbox )
1449 return pControl;
1451 //////////////////////////////////////////////////////////////////////
1452 // group objects
1453 SdrObjGroup* pGroup = new SdrObjGroup();
1454 SdrObjList* pObjList = pGroup->GetSubList();
1455 pObjList->InsertObject(pLabel);
1456 pObjList->InsertObject(pControl);
1458 return pGroup;
1460 else {
1462 // create a button control
1463 const MapMode eTargetMode( pOutDev->GetMapMode() );
1464 const MapMode eSourceMode(MAP_100TH_MM);
1465 const sal_uInt16 nObjID = OBJ_FM_BUTTON;
1466 ::Size controlSize(4000, 500);
1467 FmFormObj *pControl = static_cast<FmFormObj*>(SdrObjFactory::MakeNewObject( FmFormInventor, nObjID, NULL, NULL ));
1468 controlSize.Width() = Fraction(controlSize.Width(), 1) * eTargetMode.GetScaleX();
1469 controlSize.Height() = Fraction(controlSize.Height(), 1) * eTargetMode.GetScaleY();
1470 ::Point controlPos( pOutDev->LogicToLogic( ::Point( controlSize.Width(), 0 ), eSourceMode, eTargetMode ) );
1471 ::Rectangle controlRect( controlPos, pOutDev->LogicToLogic( controlSize, eSourceMode, eTargetMode ) );
1472 pControl->SetLogicRect(controlRect);
1474 // set the button label
1475 Reference< XPropertySet > xControlSet(pControl->GetUnoControlModel(), UNO_QUERY);
1476 xControlSet->setPropertyValue(FM_PROP_LABEL, makeAny(::rtl::OUString(_rDesc.szName)));
1478 // connect the submission with the submission supplier (aka the button)
1479 xControlSet->setPropertyValue( FM_PROP_BUTTON_TYPE,
1480 makeAny( FormButtonType_SUBMIT ) );
1481 typedef ::com::sun::star::form::submission::XSubmissionSupplier XSubmissionSupplier_t;
1482 Reference< XSubmissionSupplier_t > xSubmissionSupplier(pControl->GetUnoControlModel(), UNO_QUERY);
1483 xSubmissionSupplier->setSubmission(xSubmission);
1485 return pControl;
1488 catch(const Exception&)
1490 DBG_ERROR("FmXFormView::implCreateXFormsControl: caught an exception while creating the control !");
1494 return NULL;
1497 //------------------------------------------------------------------------
1498 bool FmXFormView::createControlLabelPair( OutputDevice& _rOutDev, sal_Int32 _nXOffsetMM, sal_Int32 _nYOffsetMM,
1499 const Reference< XPropertySet >& _rxField, const Reference< XNumberFormats >& _rxNumberFormats,
1500 sal_uInt16 _nControlObjectID, const ::rtl::OUString& _rFieldPostfix,
1501 SdrUnoObj*& _rpLabel, SdrUnoObj*& _rpControl,
1502 const Reference< XDataSource >& _rxDataSource, const ::rtl::OUString& _rDataSourceName,
1503 const ::rtl::OUString& _rCommand, const sal_Int32 _nCommandType )
1505 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::createControlLabelPair" );
1506 if ( !createControlLabelPair( m_aContext, _rOutDev, _nXOffsetMM, _nYOffsetMM,
1507 _rxField, _rxNumberFormats, _nControlObjectID, _rFieldPostfix, FmFormInventor, OBJ_FM_FIXEDTEXT,
1508 NULL, NULL, NULL, _rpLabel, _rpControl )
1510 return false;
1512 // insert the control model(s) into the form component hierachy
1513 if ( _rpLabel )
1514 lcl_insertIntoFormComponentHierarchy_throw( *m_pView, *_rpLabel, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType );
1515 lcl_insertIntoFormComponentHierarchy_throw( *m_pView, *_rpControl, _rxDataSource, _rDataSourceName, _rCommand, _nCommandType );
1517 // some context-dependent initializations
1518 FormControlFactory aControlFactory( m_aContext );
1519 if ( _rpLabel )
1520 aControlFactory.initializeControlModel( impl_getDocumentType(), *_rpLabel );
1521 aControlFactory.initializeControlModel( impl_getDocumentType(), *_rpControl );
1523 return true;
1526 //------------------------------------------------------------------------
1527 bool FmXFormView::createControlLabelPair( const ::comphelper::ComponentContext& _rContext,
1528 OutputDevice& _rOutDev, sal_Int32 _nXOffsetMM, sal_Int32 _nYOffsetMM, const Reference< XPropertySet >& _rxField,
1529 const Reference< XNumberFormats >& _rxNumberFormats, sal_uInt16 _nControlObjectID,
1530 const ::rtl::OUString& _rFieldPostfix, UINT32 _nInventor, UINT16 _nLabelObjectID,
1531 SdrPage* _pLabelPage, SdrPage* _pControlPage, SdrModel* _pModel, SdrUnoObj*& _rpLabel, SdrUnoObj*& _rpControl)
1533 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::createControlLabelPair" );
1534 sal_Int32 nDataType = 0;
1535 ::rtl::OUString sFieldName;
1536 Any aFieldName;
1537 if ( _rxField.is() )
1539 nDataType = ::comphelper::getINT32(_rxField->getPropertyValue(FM_PROP_FIELDTYPE));
1540 aFieldName = Any(_rxField->getPropertyValue(FM_PROP_NAME));
1541 aFieldName >>= sFieldName;
1544 // calculate the positions, respecting the settings of the target device
1545 ::Size aTextSize( _rOutDev.GetTextWidth(sFieldName + _rFieldPostfix), _rOutDev.GetTextHeight() );
1547 MapMode eTargetMode( _rOutDev.GetMapMode() ),
1548 eSourceMode( MAP_100TH_MM );
1550 // Textbreite ist mindestens 4cm
1551 // Texthoehe immer halber cm
1552 ::Size aDefTxtSize(4000, 500);
1553 ::Size aDefSize(4000, 500);
1554 ::Size aDefImageSize(4000, 4000);
1556 ::Size aRealSize = _rOutDev.LogicToLogic(aTextSize, eTargetMode, eSourceMode);
1557 aRealSize.Width() = std::max(aRealSize.Width(), aDefTxtSize.Width());
1558 aRealSize.Height()= aDefSize.Height();
1560 // adjust to scaling of the target device (#53523#)
1561 aRealSize.Width() = long(Fraction(aRealSize.Width(), 1) * eTargetMode.GetScaleX());
1562 aRealSize.Height() = long(Fraction(aRealSize.Height(), 1) * eTargetMode.GetScaleY());
1564 // for boolean fields, we do not create a label, but just a checkbox
1565 bool bNeedLabel = ( _nControlObjectID != OBJ_FM_CHECKBOX );
1567 // the label
1568 ::std::auto_ptr< SdrUnoObj > pLabel;
1569 Reference< XPropertySet > xLabelModel;
1570 if ( bNeedLabel )
1572 pLabel.reset( dynamic_cast< SdrUnoObj* >(
1573 SdrObjFactory::MakeNewObject( _nInventor, _nLabelObjectID, _pLabelPage, _pModel ) ) );
1574 OSL_ENSURE( pLabel.get(), "FmXFormView::createControlLabelPair: could not create the label!" );
1575 if ( !pLabel.get() )
1576 return false;
1578 xLabelModel.set( pLabel->GetUnoControlModel(), UNO_QUERY );
1579 if ( xLabelModel.is() )
1581 xLabelModel->setPropertyValue( FM_PROP_LABEL, makeAny( sFieldName + _rFieldPostfix ) );
1582 String sObjectLabel( SVX_RES( RID_STR_OBJECT_LABEL ) );
1583 sObjectLabel.SearchAndReplaceAllAscii( "#object#", sFieldName );
1584 xLabelModel->setPropertyValue( FM_PROP_NAME, makeAny( ::rtl::OUString( sObjectLabel ) ) );
1587 pLabel->SetLogicRect( ::Rectangle(
1588 _rOutDev.LogicToLogic( ::Point( _nXOffsetMM, _nYOffsetMM ), eSourceMode, eTargetMode ),
1589 _rOutDev.LogicToLogic( aRealSize, eSourceMode, eTargetMode )
1590 ) );
1593 // the control
1594 ::std::auto_ptr< SdrUnoObj > pControl( dynamic_cast< SdrUnoObj* >(
1595 SdrObjFactory::MakeNewObject( _nInventor, _nControlObjectID, _pControlPage, _pModel ) ) );
1596 OSL_ENSURE( pControl.get(), "FmXFormView::createControlLabelPair: could not create the control!" );
1597 if ( !pControl.get() )
1598 return false;
1600 Reference< XPropertySet > xControlSet( pControl->GetUnoControlModel(), UNO_QUERY );
1601 if ( !xControlSet.is() )
1602 return false;
1604 // size of the control
1605 ::Size aControlSize( aDefSize );
1606 switch ( nDataType )
1608 case DataType::BIT:
1609 case DataType::BOOLEAN:
1610 aControlSize = aDefSize;
1611 break;
1612 case DataType::LONGVARCHAR:
1613 case DataType::LONGVARBINARY:
1614 aControlSize = aDefImageSize;
1615 break;
1618 if ( OBJ_FM_IMAGECONTROL == _nControlObjectID )
1619 aControlSize = aDefImageSize;
1621 aControlSize.Width() = long(Fraction(aControlSize.Width(), 1) * eTargetMode.GetScaleX());
1622 aControlSize.Height() = long(Fraction(aControlSize.Height(), 1) * eTargetMode.GetScaleY());
1624 pControl->SetLogicRect( ::Rectangle(
1625 _rOutDev.LogicToLogic( ::Point( aRealSize.Width() + _nXOffsetMM, _nYOffsetMM ), eSourceMode, eTargetMode ),
1626 _rOutDev.LogicToLogic( aControlSize, eSourceMode, eTargetMode )
1627 ) );
1629 // some initializations
1630 Reference< XPropertySetInfo > xControlPropInfo = xControlSet->getPropertySetInfo();
1632 if ( aFieldName.hasValue() )
1634 xControlSet->setPropertyValue( FM_PROP_CONTROLSOURCE, aFieldName );
1635 xControlSet->setPropertyValue( FM_PROP_NAME, aFieldName );
1636 if ( !bNeedLabel )
1638 // no dedicated label control => use the label property
1639 if ( xControlPropInfo->hasPropertyByName( FM_PROP_LABEL ) )
1640 xControlSet->setPropertyValue( FM_PROP_LABEL, makeAny( sFieldName + _rFieldPostfix ) );
1641 else
1642 OSL_ENSURE( false, "FmXFormView::createControlLabelPair: can't set a label for the control!" );
1646 if ( nDataType == DataType::LONGVARCHAR && xControlPropInfo->hasPropertyByName( FM_PROP_MULTILINE ) )
1648 xControlSet->setPropertyValue( FM_PROP_MULTILINE, makeAny( sal_Bool( sal_True ) ) );
1651 // announce the label to the control
1652 if ( xControlPropInfo->hasPropertyByName( FM_PROP_CONTROLLABEL ) && xLabelModel.is() )
1656 xControlSet->setPropertyValue( FM_PROP_CONTROLLABEL, makeAny( xLabelModel ) );
1658 catch( const Exception& )
1660 DBG_UNHANDLED_EXCEPTION();
1664 if ( _rxField.is() )
1666 FormControlFactory aControlFactory( _rContext );
1667 aControlFactory.initializeFieldDependentProperties( _rxField, xControlSet, _rxNumberFormats );
1670 _rpLabel = pLabel.release();
1671 _rpControl = pControl.release();
1672 return true;
1675 //------------------------------------------------------------------------------
1676 FmXFormView::ObjectRemoveListener::ObjectRemoveListener( FmXFormView* pParent )
1677 :m_pParent( pParent )
1681 //------------------------------------------------------------------------------
1682 void FmXFormView::ObjectRemoveListener::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
1684 if (rHint.ISA(SdrHint) && (((SdrHint&)rHint).GetKind() == HINT_OBJREMOVED))
1685 m_pParent->ObjectRemovedInAliveMode(((SdrHint&)rHint).GetObject());
1688 //------------------------------------------------------------------------------
1689 void FmXFormView::ObjectRemovedInAliveMode( const SdrObject* pObject )
1691 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::ObjectRemovedInAliveMode" );
1692 // wenn das entfernte Objekt in meiner MarkList, die ich mir beim Umschalten in den Alive-Mode gemerkt habe, steht,
1693 // muss ich es jetzt da rausnehmen, da ich sonst beim Zurueckschalten versuche, die Markierung wieder zu setzen
1694 // (interesanterweise geht das nur bei gruppierten Objekten schief (beim Zugriff auf deren ObjList GPF), nicht bei einzelnen)
1696 ULONG nCount = m_aMark.GetMarkCount();
1697 for (ULONG i = 0; i < nCount; ++i)
1699 SdrMark* pMark = m_aMark.GetMark(i);
1700 SdrObject* pCurrent = pMark->GetMarkedSdrObj();
1701 if (pObject == pCurrent)
1703 m_aMark.DeleteMark(i);
1704 return;
1706 // ich brauche nicht in GroupObjects absteigen : wenn dort unten ein Objekt geloescht wird, dann bleibt der
1707 // Zeiger auf das GroupObject, den ich habe, trotzdem weiter gueltig bleibt ...
1711 //------------------------------------------------------------------------------
1712 void FmXFormView::stopMarkListWatching()
1714 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::stopMarkListWatching" );
1715 if ( m_pWatchStoredList )
1717 m_pWatchStoredList->EndListeningAll();
1718 delete m_pWatchStoredList;
1719 m_pWatchStoredList = NULL;
1723 //------------------------------------------------------------------------------
1724 void FmXFormView::startMarkListWatching()
1726 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::startMarkListWatching" );
1727 if ( !m_pWatchStoredList )
1729 m_pWatchStoredList = new ObjectRemoveListener( this );
1730 FmFormModel* pModel = GetFormShell() ? GetFormShell()->GetFormModel() : NULL;
1731 DBG_ASSERT( pModel != NULL, "FmXFormView::startMarkListWatching: shell has no model!" );
1732 m_pWatchStoredList->StartListening( *static_cast< SfxBroadcaster* >( pModel ) );
1734 else
1736 DBG_ERROR( "FmXFormView::startMarkListWatching: already listening!" );
1740 //------------------------------------------------------------------------------
1741 void FmXFormView::saveMarkList( sal_Bool _bSmartUnmark )
1743 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::saveMarkList" );
1744 if ( m_pView )
1746 m_aMark = m_pView->GetMarkedObjectList();
1747 if ( _bSmartUnmark )
1749 ULONG nCount = m_aMark.GetMarkCount( );
1750 for ( ULONG i = 0; i < nCount; ++i )
1752 SdrMark* pMark = m_aMark.GetMark(i);
1753 SdrObject* pObj = pMark->GetMarkedSdrObj();
1755 if ( m_pView->IsObjMarked( pObj ) )
1757 if ( pObj->IsGroupObject() )
1759 SdrObjListIter aIter( *pObj->GetSubList() );
1760 sal_Bool bMixed = sal_False;
1761 while ( aIter.IsMore() && !bMixed )
1762 bMixed = ( aIter.Next()->GetObjInventor() != FmFormInventor );
1764 if ( !bMixed )
1766 // all objects in the group are form objects
1767 m_pView->MarkObj( pMark->GetMarkedSdrObj(), pMark->GetPageView(), sal_True /* unmark! */ );
1770 else
1772 if ( pObj->GetObjInventor() == FmFormInventor )
1773 { // this is a form layer object
1774 m_pView->MarkObj( pMark->GetMarkedSdrObj(), pMark->GetPageView(), sal_True /* unmark! */ );
1781 else
1783 DBG_ERROR( "FmXFormView::saveMarkList: invalid view!" );
1784 m_aMark = SdrMarkList();
1788 //--------------------------------------------------------------------------
1789 static sal_Bool lcl_hasObject( SdrObjListIter& rIter, SdrObject* pObj )
1791 sal_Bool bFound = sal_False;
1792 while (rIter.IsMore() && !bFound)
1793 bFound = pObj == rIter.Next();
1795 rIter.Reset();
1796 return bFound;
1799 //------------------------------------------------------------------------------
1800 void FmXFormView::restoreMarkList( SdrMarkList& _rRestoredMarkList )
1802 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::restoreMarkList" );
1803 if ( !m_pView )
1804 return;
1806 _rRestoredMarkList.Clear();
1808 const SdrMarkList& rCurrentList = m_pView->GetMarkedObjectList();
1809 FmFormPage* pPage = GetFormShell() ? GetFormShell()->GetCurPage() : NULL;
1810 if (pPage)
1812 if (rCurrentList.GetMarkCount())
1813 { // there is a current mark ... hmm. Is it a subset of the mark we remembered in saveMarkList?
1814 sal_Bool bMisMatch = sal_False;
1816 // loop through all current marks
1817 ULONG nCurrentCount = rCurrentList.GetMarkCount();
1818 for ( ULONG i=0; i<nCurrentCount&& !bMisMatch; ++i )
1820 const SdrObject* pCurrentMarked = rCurrentList.GetMark( i )->GetMarkedSdrObj();
1822 // loop through all saved marks, check for equality
1823 sal_Bool bFound = sal_False;
1824 ULONG nSavedCount = m_aMark.GetMarkCount();
1825 for ( ULONG j=0; j<nSavedCount && !bFound; ++j )
1827 if ( m_aMark.GetMark( j )->GetMarkedSdrObj() == pCurrentMarked )
1828 bFound = sal_True;
1831 // did not find a current mark in the saved marks
1832 if ( !bFound )
1833 bMisMatch = sal_True;
1836 if ( bMisMatch )
1838 m_aMark.Clear();
1839 _rRestoredMarkList = rCurrentList;
1840 return;
1843 // wichtig ist das auf die Objecte der markliste nicht zugegriffen wird
1844 // da diese bereits zerstoert sein koennen
1845 SdrPageView* pCurPageView = m_pView->GetSdrPageView();
1846 SdrObjListIter aPageIter( *pPage );
1847 sal_Bool bFound = sal_True;
1849 // gibt es noch alle Objecte
1850 ULONG nCount = m_aMark.GetMarkCount();
1851 for (ULONG i = 0; i < nCount && bFound; i++)
1853 SdrMark* pMark = m_aMark.GetMark(i);
1854 SdrObject* pObj = pMark->GetMarkedSdrObj();
1855 if (pObj->IsGroupObject())
1857 SdrObjListIter aIter(*pObj->GetSubList());
1858 while (aIter.IsMore() && bFound)
1859 bFound = lcl_hasObject(aPageIter, aIter.Next());
1861 else
1862 bFound = lcl_hasObject(aPageIter, pObj);
1864 bFound = bFound && pCurPageView == pMark->GetPageView();
1867 if (bFound)
1869 // Das LastObject auswerten
1870 if (nCount) // Objecte jetzt Markieren
1872 for (ULONG i = 0; i < nCount; i++)
1874 SdrMark* pMark = m_aMark.GetMark(i);
1875 SdrObject* pObj = pMark->GetMarkedSdrObj();
1876 if ( pObj->GetObjInventor() == FmFormInventor )
1877 if ( !m_pView->IsObjMarked( pObj ) )
1878 m_pView->MarkObj( pObj, pMark->GetPageView() );
1881 _rRestoredMarkList = m_aMark;
1884 m_aMark.Clear();
1887 // -----------------------------------------------------------------------------
1888 void SAL_CALL FmXFormView::focusGained( const FocusEvent& /*e*/ ) throw (RuntimeException)
1890 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::focusGained" );
1891 if ( m_xWindow.is() && m_pView )
1893 m_pView->SetMoveOutside( TRUE, FmFormView::ImplAccess() );
1896 // -----------------------------------------------------------------------------
1897 void SAL_CALL FmXFormView::focusLost( const FocusEvent& /*e*/ ) throw (RuntimeException)
1899 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::focusLost" );
1900 // when switch the focus outside the office the mark didn't change
1901 // so we can not remove us as focus listener
1902 if ( m_xWindow.is() && m_pView )
1904 m_pView->SetMoveOutside( FALSE, FmFormView::ImplAccess() );
1907 // -----------------------------------------------------------------------------
1908 void FmXFormView::removeGridWindowListening()
1910 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::removeGridWindowListening" );
1911 if ( m_xWindow.is() )
1913 m_xWindow->removeFocusListener(this);
1914 if ( m_pView )
1916 m_pView->SetMoveOutside( FALSE, FmFormView::ImplAccess() );
1918 m_xWindow = NULL;
1922 // -----------------------------------------------------------------------------
1923 DocumentType FmXFormView::impl_getDocumentType() const
1925 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmXFormView::impl_getDocumentType" );
1926 if ( GetFormShell() && GetFormShell()->GetImpl() )
1927 return GetFormShell()->GetImpl()->getDocumentType();
1928 return eUnknownDocumentType;