1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fmshimp.cxx,v $
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"
33 #include "gridcols.hxx"
34 #include <svx/obj3d.hxx>
35 #include "fmvwimp.hxx"
36 #include "fmshimp.hxx"
37 #include "fmtextcontrolshell.hxx"
38 #include <svx/svdpagv.hxx>
39 #include <svx/fmpage.hxx>
40 #include <svx/dialmgr.hxx>
41 #ifndef _SVX_FMRESIDS_HRC
42 #include "fmresids.hrc"
44 #include "fmitems.hxx"
46 #include "formtoolbars.hxx"
47 #include <svx/fmglob.hxx>
48 #include "svditer.hxx"
49 #include "fmservs.hxx"
50 #include "fmpgeimp.hxx"
51 #include "fmtools.hxx"
52 #ifndef _SVX_FMPROP_HRC
55 #include <svx/fmshell.hxx>
56 #ifndef _SVX_SVXIDS_HRC
57 #include <svx/svxids.hrc>
59 #include <svx/fmmodel.hxx>
62 #include "formcontrolling.hxx"
63 #include <svx/svxdlg.hxx>
64 #include <svx/dialogs.hrc>
65 #include <com/sun/star/frame/FrameSearchFlag.hpp>
66 #include <com/sun/star/form/XLoadable.hpp>
67 #include <com/sun/star/container/XNamed.hpp>
68 #include <com/sun/star/container/XContainer.hpp>
69 #include <com/sun/star/container/XEnumeration.hpp>
70 #include <com/sun/star/container/XIndexAccess.hpp>
71 #include <com/sun/star/container/XEnumerationAccess.hpp>
72 #include <com/sun/star/frame/FrameSearchFlag.hpp>
73 #include <com/sun/star/awt/XTextComponent.hpp>
74 #include <com/sun/star/awt/XListBox.hpp>
75 #include <com/sun/star/awt/XCheckBox.hpp>
76 #include <com/sun/star/form/XBoundComponent.hpp>
77 #include <com/sun/star/form/ListSourceType.hpp>
78 #include <com/sun/star/view/XSelectionSupplier.hpp>
79 #include <com/sun/star/script/XEventAttacherManager.hpp>
80 #include <com/sun/star/form/XBoundControl.hpp>
81 #include <com/sun/star/form/XReset.hpp>
82 #include <com/sun/star/form/XGrid.hpp>
83 #include <com/sun/star/form/XGridPeer.hpp>
84 #include <com/sun/star/util/XNumberFormatter.hpp>
85 #include <com/sun/star/util/XModeSelector.hpp>
86 #include <com/sun/star/util/XModifyBroadcaster.hpp>
87 #include <com/sun/star/util/XCancellable.hpp>
88 #include <com/sun/star/beans/PropertyAttribute.hpp>
89 #include <com/sun/star/beans/XPropertyState.hpp>
90 #include <com/sun/star/form/binding/XBindableValue.hpp>
91 #include <com/sun/star/beans/NamedValue.hpp>
92 #include <com/sun/star/form/binding/XListEntrySink.hpp>
93 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
94 #include <osl/mutex.hxx>
95 #include <sfx2/viewsh.hxx>
96 #include <sfx2/viewfrm.hxx>
97 #include <sfx2/frame.hxx>
98 #include <vcl/waitobj.hxx>
99 #include <tools/shl.hxx>
100 #include <tools/diagnose_ex.h>
101 #include <vcl/msgbox.hxx>
102 #include <sfx2/dispatch.hxx>
103 #include <sfx2/objsh.hxx>
104 #include <sfx2/docfile.hxx>
105 #include <tools/color.hxx>
106 #include <tools/urlobj.hxx>
107 #include <comphelper/property.hxx>
108 #include <connectivity/dbtools.hxx>
109 #include <comphelper/stl_types.hxx>
110 #include <comphelper/processfactory.hxx>
111 #include <cppuhelper/servicefactory.hxx>
112 #include <comphelper/extract.hxx>
113 #include <toolkit/helper/vclunohelper.hxx>
114 #include <svx/sdrpagewindow.hxx>
115 #include <rtl/logfile.hxx>
118 #include <functional>
120 // wird fuer Invalidate verwendet -> mitpflegen
121 sal_uInt16 DatabaseSlotMap
[] =
128 SID_FM_RECORD_DELETE
,
129 SID_FM_RECORD_ABSOLUTE
,
133 SID_FM_REMOVE_FILTER_SORT
,
138 SID_FM_FORM_FILTERED
,
140 SID_FM_REFRESH_FORM_CONTROL
,
147 // wird fuer Invalidate verwendet -> mitpflegen
148 // aufsteigend sortieren !!!!!!
149 sal_Int16 DlgSlotMap
[] = // slots des Controllers
151 SID_FM_CTL_PROPERTIES
,
155 SID_FM_SHOW_FMEXPLORER
,
156 SID_FM_FIELDS_CONTROL
,
157 SID_FM_SHOW_PROPERTIES
,
158 SID_FM_PROPERTY_CONTROL
,
159 SID_FM_FMEXPLORER_CONTROL
,
160 SID_FM_SHOW_DATANAVIGATOR
,
161 SID_FM_DATANAVIGATOR_CONTROL
,
165 sal_Int16 SelObjectSlotMap
[] = // vom SelObject abhaengige Slots
167 SID_FM_CONVERTTO_EDIT
,
168 SID_FM_CONVERTTO_BUTTON
,
169 SID_FM_CONVERTTO_FIXEDTEXT
,
170 SID_FM_CONVERTTO_LISTBOX
,
171 SID_FM_CONVERTTO_CHECKBOX
,
172 SID_FM_CONVERTTO_RADIOBUTTON
,
173 SID_FM_CONVERTTO_GROUPBOX
,
174 SID_FM_CONVERTTO_COMBOBOX
,
175 SID_FM_CONVERTTO_IMAGEBUTTON
,
176 SID_FM_CONVERTTO_FILECONTROL
,
177 SID_FM_CONVERTTO_DATE
,
178 SID_FM_CONVERTTO_TIME
,
179 SID_FM_CONVERTTO_NUMERIC
,
180 SID_FM_CONVERTTO_CURRENCY
,
181 SID_FM_CONVERTTO_PATTERN
,
182 SID_FM_CONVERTTO_IMAGECONTROL
,
183 SID_FM_CONVERTTO_FORMATTED
,
184 SID_FM_CONVERTTO_SCROLLBAR
,
185 SID_FM_CONVERTTO_SPINBUTTON
,
186 SID_FM_CONVERTTO_NAVIGATIONBAR
,
188 SID_FM_FMEXPLORER_CONTROL
,
189 SID_FM_DATANAVIGATOR_CONTROL
,
194 // die folgenden Arrays muessen kosistent sein, also einander entsprechende Eintraege an der selben relativen Position
195 // innerhalb ihres jeweiligen Arrays stehen
196 sal_Int16 nConvertSlots
[] =
198 SID_FM_CONVERTTO_EDIT
,
199 SID_FM_CONVERTTO_BUTTON
,
200 SID_FM_CONVERTTO_FIXEDTEXT
,
201 SID_FM_CONVERTTO_LISTBOX
,
202 SID_FM_CONVERTTO_CHECKBOX
,
203 SID_FM_CONVERTTO_RADIOBUTTON
,
204 SID_FM_CONVERTTO_GROUPBOX
,
205 SID_FM_CONVERTTO_COMBOBOX
,
206 SID_FM_CONVERTTO_IMAGEBUTTON
,
207 SID_FM_CONVERTTO_FILECONTROL
,
208 SID_FM_CONVERTTO_DATE
,
209 SID_FM_CONVERTTO_TIME
,
210 SID_FM_CONVERTTO_NUMERIC
,
211 SID_FM_CONVERTTO_CURRENCY
,
212 SID_FM_CONVERTTO_PATTERN
,
213 SID_FM_CONVERTTO_IMAGECONTROL
,
214 SID_FM_CONVERTTO_FORMATTED
,
215 SID_FM_CONVERTTO_SCROLLBAR
,
216 SID_FM_CONVERTTO_SPINBUTTON
,
217 SID_FM_CONVERTTO_NAVIGATIONBAR
220 sal_Int16 nCreateSlots
[] =
235 SID_FM_CURRENCYFIELD
,
238 SID_FM_FORMATTEDFIELD
,
244 sal_Int16 nObjectTypes
[] =
259 OBJ_FM_CURRENCYFIELD
,
262 OBJ_FM_FORMATTEDFIELD
,
268 using namespace ::com::sun::star
;
269 using namespace ::com::sun::star::ui
;
270 using namespace ::com::sun::star::uno
;
271 using namespace ::com::sun::star::sdb
;
272 using namespace ::com::sun::star::sdbc
;
273 using namespace ::com::sun::star::sdbcx
;
274 using namespace ::com::sun::star::beans
;
275 using namespace ::com::sun::star::container
;
276 using namespace ::com::sun::star::form
;
277 using namespace ::com::sun::star::form::binding
;
278 using namespace ::com::sun::star::form::runtime
;
279 using namespace ::com::sun::star::awt
;
280 using namespace ::com::sun::star::view
;
281 using namespace ::com::sun::star::lang
;
282 using namespace ::com::sun::star::util
;
283 using namespace ::com::sun::star::frame
;
284 using namespace ::svxform
;
285 using namespace ::svx
;
287 //==============================================================================
289 //==============================================================================
292 //....................................................................
293 void collectInterfacesFromMarkList( const SdrMarkList
& _rMarkList
, InterfaceBag
& /* [out] */ _rInterfaces
)
295 _rInterfaces
.clear();
297 sal_uInt32 nMarkCount
= _rMarkList
.GetMarkCount();
298 for ( sal_uInt32 i
= 0; i
< nMarkCount
; ++i
)
300 SdrObject
* pCurrent
= _rMarkList
.GetMark( i
)->GetMarkedSdrObj();
302 SdrObjListIter
* pGroupIterator
= NULL
;
303 if ( pCurrent
->IsGroupObject() )
305 pGroupIterator
= new SdrObjListIter( *pCurrent
->GetSubList() );
306 pCurrent
= pGroupIterator
->IsMore() ? pGroupIterator
->Next() : NULL
;
311 FmFormObj
* pAsFormObject
= FmFormObj::GetFormObject( pCurrent
);
312 // note this will de-reference virtual objects, if necessary/possible
315 Reference
< XInterface
> xControlModel( pAsFormObject
->GetUnoControlModel(), UNO_QUERY
);
316 // the UNO_QUERY is important for normalization
317 if ( xControlModel
.is() )
318 _rInterfaces
.insert( xControlModel
);
322 pCurrent
= pGroupIterator
&& pGroupIterator
->IsMore() ? pGroupIterator
->Next() : NULL
;
325 if ( pGroupIterator
)
326 delete pGroupIterator
;
332 //------------------------------------------------------------------------------
333 // check if the control has one of the interfaces we can use for searching
334 // *_pCurrentText will be filled with the current text of the control (as used when searching this control)
335 sal_Bool
IsSearchableControl( const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>& _rxControl
,
336 ::rtl::OUString
* _pCurrentText
)
338 if ( !_rxControl
.is() )
341 Reference
< XTextComponent
> xAsText( _rxControl
, UNO_QUERY
);
345 *_pCurrentText
= xAsText
->getText();
349 Reference
< XListBox
> xListBox( _rxControl
, UNO_QUERY
);
353 *_pCurrentText
= xListBox
->getSelectedItem();
357 Reference
< XCheckBox
> xCheckBox( _rxControl
, UNO_QUERY
);
358 if ( xCheckBox
.is() )
362 switch ( (TriState
)xCheckBox
->getState() )
364 case STATE_NOCHECK
: *_pCurrentText
= ::rtl::OUString::createFromAscii( "0" ); break;
365 case STATE_CHECK
: *_pCurrentText
= ::rtl::OUString::createFromAscii( "1" ); break;
366 default: *_pCurrentText
= ::rtl::OUString(); break;
375 //------------------------------------------------------------------------------
376 sal_Bool
FmXBoundFormFieldIterator::ShouldStepInto(const Reference
< XInterface
>& _rContainer
) const
378 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXBoundFormFieldIterator::ShouldStepInto" );
379 if (_rContainer
== m_xStartingPoint
)
380 // would be quite stupid to step over the root ....
383 return Reference
< XControlModel
>(_rContainer
, UNO_QUERY
).is();
386 //------------------------------------------------------------------------------
387 sal_Bool
FmXBoundFormFieldIterator::ShouldHandleElement(const Reference
< XInterface
>& _rElement
)
389 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXBoundFormFieldIterator::ShouldHandleElement" );
394 if (Reference
< XForm
>(_rElement
, UNO_QUERY
).is() || Reference
< XGrid
>(_rElement
, UNO_QUERY
).is())
398 Reference
< XPropertySet
> xSet(_rElement
, UNO_QUERY
);
399 if (!xSet
.is() || !::comphelper::hasProperty(FM_PROP_BOUNDFIELD
, xSet
))
400 // no "BoundField" property
403 Any
aVal( xSet
->getPropertyValue(FM_PROP_BOUNDFIELD
) );
404 if (aVal
.getValueTypeClass() != TypeClass_INTERFACE
)
405 // void or invalid property value
408 return aVal
.hasValue();
411 //==============================================================================
413 DECL_CURSOR_ACTION_THREAD(FmMoveToLastThread
)
414 IMPL_CURSOR_ACTION_THREAD(FmMoveToLastThread
, SVX_RES(RID_STR_MOVING_CURSOR
), last());
416 //------------------------------------------------------------------------------
417 sal_Bool
isControlList(const SdrMarkList
& rMarkList
)
419 // enthaelt die liste nur Controls und mindestens ein control
420 sal_uInt32 nMarkCount
= rMarkList
.GetMarkCount();
421 sal_Bool bControlList
= nMarkCount
!= 0;
423 sal_Bool bHadAnyLeafs
= sal_False
;
425 for (sal_uInt32 i
= 0; i
< nMarkCount
&& bControlList
; i
++)
427 SdrObject
*pObj
= rMarkList
.GetMark(i
)->GetMarkedSdrObj();
428 E3dObject
* pAs3DObject
= PTR_CAST(E3dObject
, pObj
);
429 // E3dObject's do not contain any 2D-objects (by definition)
430 // we need this extra check here : an E3dObject->IsGroupObject says "YES", but an SdrObjListIter working
431 // with an E3dObject doesn't give me any Nodes (E3dObject has a sub list, but no members in that list,
432 // cause there implementation differs from the one of "normal" SdrObject's. Unfortunally SdrObject::IsGroupObject
433 // doesn't check the element count of the sub list, which is simply a bug in IsGroupObject we can't fix at the moment).
434 // So at the end of this function bControlList would have the same value it was initialized with above : sal_True
435 // And this would be wrong :)
436 // 03.02.00 - 72529 - FS
439 if (pObj
->IsGroupObject())
441 SdrObjListIter
aIter(*pObj
->GetSubList());
442 while (aIter
.IsMore() && bControlList
)
444 bControlList
= FmFormInventor
== aIter
.Next()->GetObjInventor();
445 bHadAnyLeafs
= sal_True
;
450 bHadAnyLeafs
= sal_True
;
451 bControlList
= FmFormInventor
== pObj
->GetObjInventor();
456 return bControlList
&& bHadAnyLeafs
;
459 //------------------------------------------------------------------------
460 Reference
< XForm
> GetForm(const Reference
< XInterface
>& _rxElement
)
462 Reference
< XForm
> xForm( _rxElement
, UNO_QUERY
);
466 Reference
< XChild
> xChild( _rxElement
, UNO_QUERY
);
468 return GetForm( xChild
->getParent() );
470 return Reference
< XForm
>();
473 //========================================================================
474 // class FmXFormShell_Base_Disambiguation
475 //========================================================================
476 FmXFormShell_Base_Disambiguation::FmXFormShell_Base_Disambiguation( ::osl::Mutex
& _rMutex
)
477 :FmXFormShell_BD_BASE( _rMutex
)
481 void SAL_CALL
FmXFormShell_Base_Disambiguation::disposing()
483 WeakComponentImplHelperBase::disposing();
486 // Normally it should be sufficient to call the "disposing" of our direct
487 // base class, but SUN PRO 5 does not like this and claims there is a conflict
488 // with the XEventListener::disposing(EventObject) of our various listener
492 //========================================================================
493 // class FmXFormShell
494 //========================================================================
495 DBG_NAME(FmXFormShell
);
496 //------------------------------------------------------------------------
497 FmXFormShell::FmXFormShell( FmFormShell
& _rShell
, SfxViewFrame
* _pViewFrame
)
498 :FmXFormShell_BASE(m_aMutex
)
499 ,FmXFormShell_CFGBASE(::rtl::OUString::createFromAscii("Office.Common/Misc"), CONFIG_MODE_DELAYED_UPDATE
)
500 ,m_eNavigate( NavigationBarMode_NONE
)
501 ,m_nInvalidationEvent( 0 )
502 ,m_nActivationEvent( 0 )
503 ,m_pShell( &_rShell
)
504 ,m_pTextShell( new ::svx::FmTextControlShell( _pViewFrame
) )
505 ,m_aActiveControllerFeatures( ::comphelper::getProcessServiceFactory(), this )
506 ,m_aNavControllerFeatures( ::comphelper::getProcessServiceFactory(), this )
507 ,m_pExternalViewInterceptor( NULL
)
508 ,m_eDocumentType( eUnknownDocumentType
)
509 ,m_nLockSlotInvalidation( 0 )
510 ,m_bHadPropertyBrowserInDesignMode( sal_False
)
511 ,m_bTrackProperties( sal_True
)
512 ,m_bUseWizards( sal_True
)
513 ,m_bDatabaseBar( sal_False
)
514 ,m_bInActivate( sal_False
)
515 ,m_bSetFocus( sal_False
)
516 ,m_bFilterMode( sal_False
)
517 ,m_bChangingDesignMode( sal_False
)
518 ,m_bPreparedClose( sal_False
)
519 ,m_bFirstActivation( sal_True
)
521 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::FmXFormShell" );
522 DBG_CTOR(FmXFormShell
,NULL
);
523 m_aMarkTimer
.SetTimeout(100);
524 m_aMarkTimer
.SetTimeoutHdl(LINK(this,FmXFormShell
,OnTimeOut
));
526 SfxFrame
* pFrame
= _pViewFrame
? _pViewFrame
->GetFrame() : NULL
;
528 m_xAttachedFrame
= pFrame
->GetFrameInterface();
530 // to prevent deletion of this we acquire our refcounter once
531 ::comphelper::increment(FmXFormShell_BASE::m_refCount
);
533 // correct the refcounter
534 ::comphelper::decrement(FmXFormShell_BASE::m_refCount
);
536 // cache the current configuration settings we're interested in
537 implAdjustConfigCache();
538 // and register for changes on this settings
539 Sequence
< ::rtl::OUString
> aNames(1);
540 aNames
[0] = ::rtl::OUString::createFromAscii("FormControlPilotsEnabled");
541 EnableNotification(aNames
);
544 //------------------------------------------------------------------------
545 FmXFormShell::~FmXFormShell()
548 DBG_DTOR(FmXFormShell
,NULL
);
551 //------------------------------------------------------------------
552 Reference
< XModel
> FmXFormShell::getContextDocument() const
554 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::getContextDocument" );
555 Reference
< XModel
> xModel
;
557 // determine the type of document we live in
560 Reference
< XController
> xController
;
561 if ( m_xAttachedFrame
.is() )
562 xController
= m_xAttachedFrame
->getController();
563 if ( xController
.is() )
564 xModel
= xController
->getModel();
566 catch( const Exception
& )
568 DBG_UNHANDLED_EXCEPTION();
573 //------------------------------------------------------------------
574 bool FmXFormShell::isEnhancedForm() const
576 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::isEnhancedForm" );
577 return getDocumentType() == eEnhancedForm
;
580 //------------------------------------------------------------------
581 bool FmXFormShell::impl_checkDisposed() const
583 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::impl_checkDisposed" );
586 OSL_ENSURE( false, "FmXFormShell::impl_checkDisposed: already disposed!" );
592 //------------------------------------------------------------------
593 ::svxform::DocumentType
FmXFormShell::getDocumentType() const
595 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::getDocumentType" );
596 if ( m_eDocumentType
!= eUnknownDocumentType
)
597 return m_eDocumentType
;
599 // determine the type of document we live in
600 Reference
< XModel
> xModel
= getContextDocument();
602 m_eDocumentType
= DocumentClassification::classifyDocument( xModel
);
605 OSL_ENSURE( sal_False
, "FmXFormShell::getDocumentType: can't determine the document type!" );
606 m_eDocumentType
= eTextDocument
;
607 // fallback, just to have a defined state
610 return m_eDocumentType
;
613 //------------------------------------------------------------------
614 bool FmXFormShell::IsReadonlyDoc() const
616 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::IsReadonlyDoc" );
617 if ( impl_checkDisposed() )
620 FmFormModel
* pModel
= m_pShell
->GetFormModel();
621 if ( pModel
&& pModel
->GetObjectShell() )
622 return pModel
->GetObjectShell()->IsReadOnly() || pModel
->GetObjectShell()->IsReadOnlyUI();
626 //------------------------------------------------------------------
627 Any SAL_CALL
FmXFormShell::queryInterface( const Type
& type
) throw ( RuntimeException
)
629 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::queryInterface" );
630 return FmXFormShell_BASE::queryInterface(type
);
632 //------------------------------------------------------------------------------
633 Sequence
< Type
> SAL_CALL
FmXFormShell::getTypes( ) throw(RuntimeException
)
635 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::getTypes" );
636 return FmXFormShell_BASE::getTypes();
638 //------------------------------------------------------------------------------
639 Sequence
< sal_Int8
> SAL_CALL
FmXFormShell::getImplementationId() throw(RuntimeException
)
641 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::getImplementationId" );
642 static ::cppu::OImplementationId
* pId
= 0;
645 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
648 static ::cppu::OImplementationId aId
;
652 return pId
->getImplementationId();
655 //------------------------------------------------------------------------------
656 void SAL_CALL
FmXFormShell::disposing(const EventObject
& e
) throw( RuntimeException
)
658 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::disposing" );
659 impl_checkDisposed();
661 if (m_xActiveController
== e
.Source
)
663 // wird der Controller freigeben dann alles loslassen
665 m_xActiveForm
= NULL
;
666 m_xActiveController
= NULL
;
667 m_xNavigationController
= NULL
;
669 m_aActiveControllerFeatures
.dispose();
670 m_aNavControllerFeatures
.dispose();
673 m_pShell
->GetViewShell()->GetViewFrame()->GetBindings().InvalidateShell(*m_pShell
);
676 if (e
.Source
== m_xExternalViewController
)
678 Reference
< XFormController
> xFormController(m_xExternalViewController
, UNO_QUERY
);
679 if (xFormController
.is())
680 xFormController
->removeActivateListener((XFormControllerListener
*)this);
682 Reference
< ::com::sun::star::lang::XComponent
> xComp(m_xExternalViewController
, UNO_QUERY
);
684 xComp
->removeEventListener((XEventListener
*)(XPropertyChangeListener
*)this);
686 m_xExternalViewController
= NULL
;
687 m_xExternalDisplayedForm
= NULL
;
688 m_xExtViewTriggerController
= NULL
;
690 InvalidateSlot( SID_FM_VIEW_AS_GRID
, sal_False
);
694 //------------------------------------------------------------------------------
695 void SAL_CALL
FmXFormShell::propertyChange(const PropertyChangeEvent
& evt
) throw(::com::sun::star::uno::RuntimeException
)
697 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::propertyChange" );
698 if ( impl_checkDisposed() )
701 if (evt
.PropertyName
== FM_PROP_ROWCOUNT
)
703 // Das gleich folgenden Update erzwingt ein Neu-Painten der entsprechenden Slots. Wenn ich mich aber hier nicht
704 // in dem HauptThread der Applikation befinde (weil zum Beispiel ein Cursor gerade Datensaetze zaehlt und mir dabei
705 // immer diese PropertyChanges beschert), kann sich das mit en normalen Paints im HauptThread der Applikation beissen.
706 // (Solche Paints passieren zum Beispiel, wenn man einfach nur eine andere Applikation ueber das Office legt und wieder
708 // Deshalb die Benutzung des SolarMutex, der sichert das ab.
709 ::vos::IMutex
& rSolarSafety
= Application::GetSolarMutex();
710 if (rSolarSafety
.tryToAcquire())
712 m_pShell
->GetViewShell()->GetViewFrame()->GetBindings().Invalidate(SID_FM_RECORD_TOTAL
, sal_True
, sal_False
);
713 m_pShell
->GetViewShell()->GetViewFrame()->GetBindings().Update(SID_FM_RECORD_TOTAL
);
714 rSolarSafety
.release();
718 // with the following the slot is invalidated asynchron
719 LockSlotInvalidation(sal_True
);
720 InvalidateSlot(SID_FM_RECORD_TOTAL
, sal_False
);
721 LockSlotInvalidation(sal_False
);
725 // this may be called from a non-main-thread so invalidate the shell asynchronously
726 LockSlotInvalidation(sal_True
);
727 InvalidateSlot(0, 0); // special meaning : invalidate m_pShell
728 LockSlotInvalidation(sal_False
);
731 //------------------------------------------------------------------------------
732 void FmXFormShell::invalidateFeatures( const ::std::vector
< sal_Int32
>& _rFeatures
)
734 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::invalidateFeatures" );
735 if ( impl_checkDisposed() )
738 OSL_ENSURE( _rFeatures
.size() > 0, "FmXFormShell::invalidateFeatures: invalid arguments!" );
740 if ( m_pShell
->GetViewShell() && m_pShell
->GetViewShell()->GetViewFrame() )
742 // unfortunately, SFX requires sal_uInt16
743 ::std::vector
< sal_uInt16
> aSlotIds
;
744 aSlotIds
.reserve( _rFeatures
.size() );
745 ::std::copy( _rFeatures
.begin(),
747 ::std::insert_iterator
< ::std::vector
< sal_uInt16
> >( aSlotIds
, aSlotIds
.begin() )
750 // furthermore, SFX wants a terminating 0
751 aSlotIds
.push_back( 0 );
753 // and, last but not least, SFX wants the ids to be sorted
754 ::std::sort( aSlotIds
.begin(), aSlotIds
.end() - 1 );
756 sal_uInt16
*pSlotIds
= aSlotIds
.empty() ? 0 : &(aSlotIds
[0]);
757 m_pShell
->GetViewShell()->GetViewFrame()->GetBindings().Invalidate( pSlotIds
);
761 //------------------------------------------------------------------------------
762 void SAL_CALL
FmXFormShell::formActivated(const EventObject
& rEvent
) throw( RuntimeException
)
764 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::formActivated" );
765 if ( impl_checkDisposed() )
768 Reference
< XFormController
> xController( rEvent
.Source
, UNO_QUERY_THROW
);
769 m_pTextShell
->formActivated( xController
);
770 setActiveController( xController
);
773 //------------------------------------------------------------------------------
774 void SAL_CALL
FmXFormShell::formDeactivated(const EventObject
& rEvent
) throw( RuntimeException
)
776 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::formDeactivated" );
777 if ( impl_checkDisposed() )
780 Reference
< XFormController
> xController( rEvent
.Source
, UNO_QUERY_THROW
);
781 m_pTextShell
->formDeactivated( xController
);
784 //------------------------------------------------------------------------------
785 void FmXFormShell::disposing()
787 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::disposing" );
788 OSL_TRACE( "--- FmXFormShell::disposing : %p, ........, ........\n", this );
789 impl_checkDisposed();
791 FmXFormShell_BASE::disposing();
793 if ( m_pShell
&& !m_pShell
->IsDesignMode() )
794 setActiveController( NULL
, sal_True
);
795 // do NOT save the content of the old form (the second parameter tells this)
796 // if we're here, then we expect that PrepareClose has been called, and thus the user
797 // got a chance to commit or reject any changes. So in case we're here and there
798 // are still uncommitted changes, the user explicitly wanted this.
799 // 2002-11-11 - 104702 - fs@openoffice.org
801 // dispose our interceptor helpers
802 if (m_pExternalViewInterceptor
)
804 m_pExternalViewInterceptor
->dispose();
805 m_pExternalViewInterceptor
->release();
806 m_pExternalViewInterceptor
= NULL
;
809 m_pTextShell
->dispose();
811 m_xAttachedFrame
= NULL
;
813 CloseExternalFormViewer();
815 while ( m_aLoadingPages
.size() )
817 Application::RemoveUserEvent( m_aLoadingPages
.front().nEventId
);
818 m_aLoadingPages
.pop();
822 ::osl::MutexGuard
aGuard(m_aInvalidationSafety
);
823 if (m_nInvalidationEvent
)
825 Application::RemoveUserEvent(m_nInvalidationEvent
);
826 m_nInvalidationEvent
= 0;
828 if ( m_nActivationEvent
)
830 Application::RemoveUserEvent( m_nActivationEvent
);
831 m_nActivationEvent
= 0;
836 ::osl::ClearableMutexGuard
aGuard(m_aAsyncSafety
);
837 if (HasAnyPendingCursorAction())
838 CancelAnyPendingCursorAction();
841 DBG_ASSERT(!m_nInvalidationEvent
, "FmXFormShell::~FmXFormShell : still have an invalidation event !");
842 // should habe been deleted while beeing disposed
847 DisableNotification();
849 RemoveElement( m_xForms
);
852 impl_switchActiveControllerListening( false );
853 m_xActiveController
= NULL
;
854 m_xActiveForm
= NULL
;
857 m_xNavigationController
= NULL
;
858 m_xCurrentForm
= NULL
;
859 m_xLastGridFound
= NULL
;
860 m_xAttachedFrame
= NULL
;
861 m_xExternalViewController
= NULL
;
862 m_xExtViewTriggerController
= NULL
;
863 m_xExternalDisplayedForm
= NULL
;
864 m_xLastGridFound
= NULL
;
867 m_aCurrentSelection
.swap( aEmpty
);
869 m_aActiveControllerFeatures
.dispose();
870 m_aNavControllerFeatures
.dispose();
873 //------------------------------------------------------------------------------
874 void FmXFormShell::UpdateSlot( sal_Int16 _nId
)
876 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::UpdateSlot" );
877 if ( impl_checkDisposed() )
880 ::osl::MutexGuard
aGuard(m_aInvalidationSafety
);
882 if ( m_nLockSlotInvalidation
)
884 OSL_ENSURE( sal_False
, "FmXFormShell::UpdateSlot: cannot update if invalidation is currently locked!" );
885 InvalidateSlot( _nId
, sal_False
);
889 OSL_ENSURE( _nId
, "FmXFormShell::UpdateSlot: can't update the complete shell!" );
890 m_pShell
->GetViewShell()->GetViewFrame()->GetBindings().Invalidate( _nId
, sal_True
, sal_True
);
891 m_pShell
->GetViewShell()->GetViewFrame()->GetBindings().Update( _nId
);
895 //------------------------------------------------------------------------------
896 void FmXFormShell::InvalidateSlot( sal_Int16 nId
, sal_Bool bWithId
)
898 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::InvalidateSlot" );
899 if ( impl_checkDisposed() )
902 ::osl::MutexGuard
aGuard(m_aInvalidationSafety
);
903 if (m_nLockSlotInvalidation
)
905 m_arrInvalidSlots
.Insert(nId
, m_arrInvalidSlots
.Count());
906 BYTE nFlags
= ( bWithId
? 0x01 : 0 );
907 m_arrInvalidSlots_Flags
.Insert(nFlags
, m_arrInvalidSlots_Flags
.Count());
911 m_pShell
->GetViewShell()->GetViewFrame()->GetBindings().Invalidate(nId
, sal_True
, bWithId
);
913 m_pShell
->GetViewShell()->GetViewFrame()->GetBindings().InvalidateShell(*m_pShell
);
916 //------------------------------------------------------------------------------
917 void FmXFormShell::LockSlotInvalidation(sal_Bool bLock
)
919 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::LockSlotInvalidation" );
920 if ( impl_checkDisposed() )
923 ::osl::MutexGuard
aGuard(m_aInvalidationSafety
);
924 DBG_ASSERT(bLock
|| m_nLockSlotInvalidation
>0, "FmXFormShell::LockSlotInvalidation : invalid call !");
927 ++m_nLockSlotInvalidation
;
928 else if (!--m_nLockSlotInvalidation
)
930 // alles, was sich waehrend der gelockten Phase angesammelt hat, (asynchron) invalidieren
931 if (!m_nInvalidationEvent
)
932 m_nInvalidationEvent
= Application::PostUserEvent(LINK(this, FmXFormShell
, OnInvalidateSlots
));
936 //------------------------------------------------------------------------------
937 IMPL_LINK(FmXFormShell
, OnInvalidateSlots
, void*, EMPTYARG
)
939 if ( impl_checkDisposed() )
942 ::osl::MutexGuard
aGuard(m_aInvalidationSafety
);
943 m_nInvalidationEvent
= 0;
945 DBG_ASSERT(m_arrInvalidSlots
.Count() == m_arrInvalidSlots_Flags
.Count(),
946 "FmXFormShell::OnInvalidateSlots : inconsistent slot arrays !");
948 for (sal_Int16 i
=0; i
<m_arrInvalidSlots
.Count(); ++i
)
950 nFlags
= m_arrInvalidSlots_Flags
[i
];
952 if (m_arrInvalidSlots
[i
])
953 m_pShell
->GetViewShell()->GetViewFrame()->GetBindings().Invalidate(m_arrInvalidSlots
[i
], sal_True
, (nFlags
& 0x01));
955 m_pShell
->GetViewShell()->GetViewFrame()->GetBindings().InvalidateShell(*m_pShell
);
958 m_arrInvalidSlots
.Remove(0, m_arrInvalidSlots
.Count());
959 m_arrInvalidSlots_Flags
.Remove(0, m_arrInvalidSlots_Flags
.Count());
963 //------------------------------------------------------------------------------
964 void FmXFormShell::ForceUpdateSelection(sal_Bool bAllowInvalidation
)
966 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::ForceUpdateSelection" );
967 if ( impl_checkDisposed() )
970 if (IsSelectionUpdatePending())
974 // die Invalidierung der Slots, die implizit von SetSelection besorgt wird, eventuell abschalten
975 if (!bAllowInvalidation
)
976 LockSlotInvalidation(sal_True
);
978 SetSelection(m_pShell
->GetFormView()->GetMarkedObjectList());
980 if (!bAllowInvalidation
)
981 LockSlotInvalidation(sal_False
);
985 //------------------------------------------------------------------------------
986 PopupMenu
* FmXFormShell::GetConversionMenu()
988 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::GetConversionMenu" );
989 const StyleSettings
& rSettings
= Application::GetSettings().GetStyleSettings();
990 BOOL bIsHiContrastMode
= rSettings
.GetMenuColor().IsDark();
992 PopupMenu
* pNewMenu
= new PopupMenu(SVX_RES( RID_FMSHELL_CONVERSIONMENU
));
994 ImageList
aImageList( SVX_RES( bIsHiContrastMode
? RID_SVXIMGLIST_FMEXPL_HC
: RID_SVXIMGLIST_FMEXPL
) );
995 for ( size_t i
= 0; i
< sizeof( nConvertSlots
) / sizeof( nConvertSlots
[0] ); ++i
)
997 // das entsprechende Image dran
998 pNewMenu
->SetItemImage(nConvertSlots
[i
], aImageList
.GetImage(nCreateSlots
[i
]));
1004 //------------------------------------------------------------------------------
1005 bool FmXFormShell::isControlConversionSlot( sal_uInt16 nSlotId
)
1007 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::isControlConversionSlot" );
1008 for ( size_t i
= 0; i
< sizeof( nConvertSlots
) / sizeof( nConvertSlots
[0] ); ++i
)
1009 if (nConvertSlots
[i
] == nSlotId
)
1014 //------------------------------------------------------------------------------
1015 bool FmXFormShell::executeControlConversionSlot( sal_uInt16 _nSlotId
)
1017 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::executeControlConversionSlot" );
1018 OSL_PRECOND( canConvertCurrentSelectionToControl( _nSlotId
), "FmXFormShell::executeControlConversionSlot: illegal call!" );
1019 InterfaceBag::const_iterator aSelectedElement
= m_aCurrentSelection
.begin();
1020 if ( aSelectedElement
== m_aCurrentSelection
.end() )
1023 return executeControlConversionSlot( Reference
< XFormComponent
>( *aSelectedElement
, UNO_QUERY
), _nSlotId
);
1026 //------------------------------------------------------------------------------
1027 bool FmXFormShell::executeControlConversionSlot( const Reference
< XFormComponent
>& _rxObject
, sal_uInt16 _nSlotId
)
1029 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::executeControlConversionSlot" );
1030 if ( impl_checkDisposed() )
1033 OSL_ENSURE( _rxObject
.is(), "FmXFormShell::executeControlConversionSlot: invalid object!" );
1034 if ( !_rxObject
.is() )
1037 SdrPage
* pPage
= m_pShell
->GetCurPage();
1038 FmFormPage
* pFormPage
= pPage
? dynamic_cast< FmFormPage
* >( pPage
) : NULL
;
1039 OSL_ENSURE( pFormPage
, "FmXFormShell::executeControlConversionSlot: no current (form) page!" );
1043 OSL_ENSURE( isSolelySelected( _rxObject
),
1044 "FmXFormShell::executeControlConversionSlot: hmm ... shouldn't this parameter be redundant?" );
1046 for ( size_t lookupSlot
= 0; lookupSlot
< sizeof( nConvertSlots
) / sizeof( nConvertSlots
[0] ); ++lookupSlot
)
1048 if (nConvertSlots
[lookupSlot
] == _nSlotId
)
1050 Reference
< XInterface
> xNormalizedObject( _rxObject
, UNO_QUERY
);
1052 FmFormObj
* pFormObject
= NULL
;
1053 SdrObjListIter
aPageIter( *pFormPage
);
1054 while ( aPageIter
.IsMore() )
1056 SdrObject
* pCurrent
= aPageIter
.Next();
1057 pFormObject
= FmFormObj::GetFormObject( pCurrent
);
1061 Reference
< XInterface
> xCurrentNormalized( pFormObject
->GetUnoControlModel(), UNO_QUERY
);
1062 if ( xCurrentNormalized
.get() == xNormalizedObject
.get() )
1071 ::rtl::OUString
sNewName( getServiceNameByControlType( nObjectTypes
[ lookupSlot
] ) );
1072 Reference
< XControlModel
> xNewModel( ::comphelper::getProcessServiceFactory()->createInstance( sNewName
), UNO_QUERY
);
1073 if (!xNewModel
.is())
1076 Reference
< XControlModel
> xOldModel( pFormObject
->GetUnoControlModel() );
1077 Reference
< XServiceInfo
> xModelInfo(xOldModel
, UNO_QUERY
);
1079 // Properties uebertragen
1080 Reference
< XPropertySet
> xOldSet(xOldModel
, UNO_QUERY
);
1081 Reference
< XPropertySet
> xNewSet(xNewModel
, UNO_QUERY
);
1084 Locale aNewLanguage
= Application::GetSettings().GetUILocale();
1085 TransferFormComponentProperties(xOldSet
, xNewSet
, aNewLanguage
);
1087 Sequence
< ::com::sun::star::script::ScriptEventDescriptor
> aOldScripts
;
1088 Reference
< XChild
> xChild(xOldModel
, UNO_QUERY
);
1091 Reference
< XIndexAccess
> xParent(xChild
->getParent(), UNO_QUERY
);
1093 // remember old script events
1094 Reference
< ::com::sun::star::script::XEventAttacherManager
> xEvManager(xChild
->getParent(), UNO_QUERY
);
1095 if (xParent
.is() && xEvManager
.is())
1097 sal_Int32 nIndex
= getElementPos(xParent
, xOldModel
);
1098 if (nIndex
>=0 && nIndex
<xParent
->getCount())
1099 aOldScripts
= xEvManager
->getScriptEvents(nIndex
);
1102 // replace the mdoel within the parent container
1103 Reference
< XIndexContainer
> xIndexParent(xChild
->getParent(), UNO_QUERY
); //Modified by BerryJia for fixing Bug102516 Time(China):2002-9-5 16:00
1104 if (xIndexParent
.is())
1106 // the form container works with FormComponents
1107 Reference
< XFormComponent
> xComponent(xNewModel
, UNO_QUERY
);
1108 DBG_ASSERT(xComponent
.is(), "FmXFormShell::executeControlConversionSlot: the new model is no form component !");
1109 Any
aNewModel(makeAny(xComponent
));
1112 //Modified by BerryJia for fixing Bug102516 Time(China):2002-9-5 16:00
1113 sal_Int32 nIndex
= getElementPos(xParent
, xOldModel
);
1114 if (nIndex
>=0 && nIndex
<xParent
->getCount())
1115 xIndexParent
->replaceByIndex(nIndex
, aNewModel
);
1118 DBG_ERROR("FmXFormShell::executeControlConversionSlot: could not replace the model !");
1119 Reference
< ::com::sun::star::lang::XComponent
> xNewComponent(xNewModel
, UNO_QUERY
);
1120 if (xNewComponent
.is())
1121 xNewComponent
->dispose();
1127 DBG_ERROR("FmXFormShell::executeControlConversionSlot: could not replace the model !");
1128 Reference
< ::com::sun::star::lang::XComponent
> xNewComponent(xNewModel
, UNO_QUERY
);
1129 if (xNewComponent
.is())
1130 xNewComponent
->dispose();
1137 // special handling for the LabelControl-property : can only be set when the model is placed
1138 // within the forms hierarchy
1139 if (::comphelper::hasProperty(FM_PROP_CONTROLLABEL
, xOldSet
) && ::comphelper::hasProperty(FM_PROP_CONTROLLABEL
, xNewSet
))
1143 xNewSet
->setPropertyValue(FM_PROP_CONTROLLABEL
, xOldSet
->getPropertyValue(FM_PROP_CONTROLLABEL
));
1151 // neues Model setzen
1152 pFormObject
->SetChanged();
1153 pFormObject
->SetUnoControlModel(xNewModel
);
1155 // transfer script events
1156 // (do this _after_ SetUnoControlModel as we need the new (implicitly created) control)
1157 if (aOldScripts
.getLength())
1159 // das Control zum Model suchen
1160 Reference
< XControlContainer
> xControlContainer( getControlContainerForView() );
1162 Sequence
< Reference
< XControl
> > aControls( xControlContainer
->getControls() );
1163 const Reference
< XControl
>* pControls
= aControls
.getConstArray();
1165 sal_uInt32 nLen
= aControls
.getLength();
1166 Reference
< XControl
> xControl
;
1167 for (sal_uInt32 i
=0 ; i
<nLen
; ++i
)
1169 if (pControls
[i
]->getModel() == xNewModel
)
1171 xControl
= pControls
[i
];
1175 TransferEventScripts(xNewModel
, xControl
, aOldScripts
);
1178 // transfer value bindings, if possible
1180 Reference
< XBindableValue
> xOldBindable( xOldModel
, UNO_QUERY
);
1181 Reference
< XBindableValue
> xNewBindable( xNewModel
, UNO_QUERY
);
1182 if ( xOldBindable
.is() )
1186 if ( xNewBindable
.is() )
1187 xNewBindable
->setValueBinding( xOldBindable
->getValueBinding() );
1188 xOldBindable
->setValueBinding( NULL
);
1190 catch(const Exception
&)
1192 DBG_UNHANDLED_EXCEPTION();
1196 // same for list entry sources
1198 Reference
< XListEntrySink
> xOldSink( xOldModel
, UNO_QUERY
);
1199 Reference
< XListEntrySink
> xNewSink( xNewModel
, UNO_QUERY
);
1200 if ( xOldSink
.is() )
1204 if ( xNewSink
.is() )
1205 xNewSink
->setListEntrySource( xOldSink
->getListEntrySource() );
1206 xOldSink
->setListEntrySource( NULL
);
1208 catch(const Exception
&)
1210 DBG_UNHANDLED_EXCEPTION();
1215 // create an undo action
1216 FmFormModel
* pModel
= m_pShell
->GetFormModel();
1217 DBG_ASSERT(pModel
!= NULL
, "FmXFormShell::executeControlConversionSlot: my shell has no model !");
1218 if (pModel
&& pModel
->IsUndoEnabled() )
1220 pModel
->AddUndo(new FmUndoModelReplaceAction(*pModel
, pFormObject
, xOldModel
));
1224 FmUndoModelReplaceAction::DisposeElement( xOldModel
);
1233 //------------------------------------------------------------------------------
1234 bool FmXFormShell::canConvertCurrentSelectionToControl( sal_Int16 nConversionSlot
)
1236 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::canConvertCurrentSelectionToControl" );
1237 if ( m_aCurrentSelection
.empty() )
1240 InterfaceBag::const_iterator aCheck
= m_aCurrentSelection
.begin();
1241 Reference
< XServiceInfo
> xElementInfo( *aCheck
, UNO_QUERY
);
1242 if ( !xElementInfo
.is() )
1243 // no service info -> cannot determine this
1246 if ( ++aCheck
!= m_aCurrentSelection
.end() )
1247 // more than one element
1250 if ( Reference
< XForm
>::query( xElementInfo
).is() )
1254 sal_Int16 nObjectType
= getControlTypeByObject( xElementInfo
);
1256 if ( ( OBJ_FM_HIDDEN
== nObjectType
)
1257 || ( OBJ_FM_CONTROL
== nObjectType
)
1258 || ( OBJ_FM_GRID
== nObjectType
)
1260 return false; // those types cannot be converted
1262 DBG_ASSERT(sizeof(nConvertSlots
)/sizeof(nConvertSlots
[0]) == sizeof(nObjectTypes
)/sizeof(nObjectTypes
[0]),
1263 "FmXFormShell::canConvertCurrentSelectionToControl: nConvertSlots & nObjectTypes must have the same size !");
1265 for ( size_t i
= 0; i
< sizeof( nConvertSlots
) / sizeof( nConvertSlots
[0] ); ++i
)
1266 if (nConvertSlots
[i
] == nConversionSlot
)
1267 return nObjectTypes
[i
] != nObjectType
;
1269 return sal_True
; // all other slots: assume "yes"
1272 //------------------------------------------------------------------------------
1273 void FmXFormShell::checkControlConversionSlotsForCurrentSelection( Menu
& rMenu
)
1275 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::checkControlConversionSlotsForCurrentSelection" );
1276 for (sal_Int16 i
=0; i
<rMenu
.GetItemCount(); ++i
)
1277 // der Context ist schon von einem Typ, der dem Eitnrag entspricht -> disable
1278 rMenu
.EnableItem( rMenu
.GetItemId(i
), canConvertCurrentSelectionToControl( rMenu
.GetItemId( i
) ) );
1281 //------------------------------------------------------------------------------
1282 void FmXFormShell::LoopGrids(sal_Int16 nWhat
)
1284 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::LoopGrids" );
1285 if ( impl_checkDisposed() )
1288 Reference
< XIndexContainer
> xControlModels(m_xActiveForm
, UNO_QUERY
);
1289 if (xControlModels
.is())
1291 for (sal_Int16 i
=0; i
<xControlModels
->getCount(); ++i
)
1293 Reference
< XPropertySet
> xModelSet
;
1294 xControlModels
->getByIndex(i
) >>= xModelSet
;
1295 if (!xModelSet
.is())
1298 if (!::comphelper::hasProperty(FM_PROP_CLASSID
, xModelSet
))
1300 sal_Int16 nClassId
= ::comphelper::getINT16(xModelSet
->getPropertyValue(FM_PROP_CLASSID
));
1301 if (FormComponentType::GRIDCONTROL
!= nClassId
)
1304 if (!::comphelper::hasProperty(FM_PROP_CURSORCOLOR
, xModelSet
) || !::comphelper::hasProperty(FM_PROP_ALWAYSSHOWCURSOR
, xModelSet
) || !::comphelper::hasProperty(FM_PROP_DISPLAYSYNCHRON
, xModelSet
))
1307 switch (nWhat
& GA_SYNC_MASK
)
1309 case GA_DISABLE_SYNC
:
1311 sal_Bool
bB(sal_False
);
1312 xModelSet
->setPropertyValue(FM_PROP_DISPLAYSYNCHRON
, Any(&bB
,getBooleanCppuType()));
1317 Any
aOldVal( xModelSet
->getPropertyValue(FM_PROP_DISPLAYSYNCHRON
) );
1318 sal_Bool
bB(sal_True
);
1319 xModelSet
->setPropertyValue(FM_PROP_DISPLAYSYNCHRON
, Any(&bB
,getBooleanCppuType()));
1320 xModelSet
->setPropertyValue(FM_PROP_DISPLAYSYNCHRON
, aOldVal
);
1323 case GA_ENABLE_SYNC
:
1325 sal_Bool
bB(sal_True
);
1326 xModelSet
->setPropertyValue(FM_PROP_DISPLAYSYNCHRON
, Any(&bB
,getBooleanCppuType()));
1331 if (nWhat
& GA_DISABLE_ROCTRLR
)
1333 sal_Bool
bB(sal_False
);
1334 xModelSet
->setPropertyValue(FM_PROP_ALWAYSSHOWCURSOR
, Any(&bB
,getBooleanCppuType()));
1335 Reference
< XPropertyState
> xModelPropState(xModelSet
, UNO_QUERY
);
1336 if (xModelPropState
.is())
1337 xModelPropState
->setPropertyToDefault(FM_PROP_CURSORCOLOR
);
1339 xModelSet
->setPropertyValue(FM_PROP_CURSORCOLOR
, Any()); // this should be the default
1341 else if (nWhat
& GA_ENABLE_ROCTRLR
)
1343 sal_Bool
bB(sal_True
);
1344 xModelSet
->setPropertyValue(FM_PROP_ALWAYSSHOWCURSOR
, Any(&bB
,getBooleanCppuType()));
1345 xModelSet
->setPropertyValue(FM_PROP_CURSORCOLOR
, makeAny(sal_Int32(COL_LIGHTRED
)));
1351 //------------------------------------------------------------------------------
1352 Reference
< XControlContainer
> FmXFormShell::getControlContainerForView()
1354 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::getControlContainerForView" );
1355 if ( impl_checkDisposed() )
1358 SdrPageView
* pPageView
= NULL
;
1359 if ( m_pShell
&& m_pShell
->GetFormView() )
1360 pPageView
= m_pShell
->GetFormView()->GetSdrPageView();
1362 Reference
< XControlContainer
> xControlContainer
;
1364 xControlContainer
= pPageView
->GetPageWindow(0)->GetControlContainer();
1366 return xControlContainer
;
1369 //------------------------------------------------------------------------------
1370 void FmXFormShell::ExecuteTabOrderDialog( const Reference
< XTabControllerModel
>& _rxForForm
)
1372 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::ExecuteTabOrderDialog" );
1373 if ( impl_checkDisposed() )
1376 OSL_PRECOND( _rxForForm
.is(), "FmXFormShell::ExecuteTabOrderDialog: invalid tabbing model!" );
1377 if ( !_rxForForm
.is() )
1382 Sequence
< Any
> aDialogArgs( 3 );
1383 aDialogArgs
[0] <<= NamedValue(
1384 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TabbingModel" ) ),
1385 makeAny( _rxForForm
)
1387 aDialogArgs
[1] <<= NamedValue(
1388 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ControlContext" ) ),
1389 makeAny( getControlContainerForView() )
1392 Reference
< XWindow
> xParentWindow
;
1393 if ( m_pShell
->GetViewShell() && m_pShell
->GetViewShell()->GetViewFrame() )
1394 xParentWindow
= VCLUnoHelper::GetInterface ( &m_pShell
->GetViewShell()->GetViewFrame()->GetWindow() );
1395 aDialogArgs
[2] <<= NamedValue(
1396 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ) ),
1397 makeAny( xParentWindow
)
1400 Reference
< dialogs::XExecutableDialog
> xDialog(
1401 ::comphelper::getProcessServiceFactory()->createInstanceWithArguments(
1402 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.ui.TabOrderDialog" ) ),
1407 OSL_ENSURE( xDialog
.is(), "FmXFormShell::ExecuteTabOrderDialog: could not create the dialog!" );
1412 catch( const Exception
& )
1414 OSL_ENSURE( sal_False
, "FmXFormShell::ExecuteTabOrderDialog: caught an exception!" );
1418 //------------------------------------------------------------------------------
1419 void FmXFormShell::ExecuteSearch()
1421 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::ExecuteSearch" );
1422 if ( impl_checkDisposed() )
1425 // eine Sammlung aller (logischen) Formulare
1427 m_aSearchForms
.swap( aEmpty
);
1428 ::std::vector
< String
> aContextNames
;
1429 impl_collectFormSearchContexts_nothrow( m_pShell
->GetCurPage()->GetForms(), ::rtl::OUString(), m_aSearchForms
, aContextNames
);
1430 OSL_POSTCOND( m_aSearchForms
.size() == aContextNames
.size(),
1431 "FmXFormShell::ExecuteSearch: nonsense!" );
1432 if ( m_aSearchForms
.size() != aContextNames
.size() )
1435 // filter out the forms which do not contain valid controls at all
1436 FmFormArray::reverse_iterator form
= m_aSearchForms
.rbegin();
1437 ::std::vector
< String
>::reverse_iterator contextName
= aContextNames
.rbegin();
1438 sal_Int32 i
= m_aSearchForms
.size();
1440 form
!= m_aSearchForms
.rend();
1441 ++form
, ++contextName
, --i
1444 FmSearchContext aTestContext
;
1445 aTestContext
.nContext
= static_cast< sal_Int16
>( i
-1 );
1446 sal_uInt32 nValidControls
= OnSearchContextRequest( &aTestContext
);
1447 if ( nValidControls
== 0 )
1449 m_aSearchForms
.erase( form
.base() - 1 );
1450 aContextNames
.erase( contextName
.base() - 1 );
1454 if (m_aSearchForms
.size() == 0)
1455 { // es gibt keine Controls, die alle Bedingungen fuer eine Suche erfuellen
1456 ErrorBox(NULL
, WB_OK
, SVX_RESSTR(RID_STR_NODATACONTROLS
)).Execute();
1460 // jetzt brauche ich noch einen 'initial context'
1461 sal_Int16 nInitialContext
= 0;
1462 Reference
< XForm
> xActiveForm( getActiveForm());
1463 for (i
=0; i
<(sal_Int32
)m_aSearchForms
.size(); ++i
)
1465 if (m_aSearchForms
.at(i
) == xActiveForm
)
1467 nInitialContext
= (sal_Int16
)i
;
1472 // wenn der Dialog initial den Text des aktiven Controls anbieten soll, muss dieses ein XTextComponent-Interface habe,
1473 // ausserdem macht das nur Sinn, wenn das aktuelle Feld auch an ein Tabellen- (oder was-auch-immer-)Feld gebunden ist
1474 UniString strActiveField
;
1475 UniString strInitialText
;
1476 // ... das bekomme ich von meinem FormController
1477 DBG_ASSERT(m_xActiveController
.is(), "FmXFormShell::ExecuteSearch : no active controller !");
1478 Reference
< XControl
> xActiveControl( m_xActiveController
->getCurrentControl());
1479 if (xActiveControl
.is())
1481 // das Control kann mir sein Model sagen ...
1482 Reference
< XControlModel
> xActiveModel( xActiveControl
->getModel());
1483 DBG_ASSERT(xActiveModel
.is(), "FmXFormShell::ExecuteSearch : active control has no model !");
1485 // das Model frage ich nach der ControlSource-Eigenschaft ...
1486 Reference
< XPropertySet
> xProperties(xActiveControl
->getModel(), UNO_QUERY
);
1487 if (::comphelper::hasProperty(FM_PROP_CONTROLSOURCE
, xProperties
) && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD
, xProperties
))
1489 Reference
< XPropertySet
> xField
;
1490 xProperties
->getPropertyValue(FM_PROP_BOUNDFIELD
) >>= xField
;
1491 if (xField
.is()) // (nur wenn das Ding wirklich gebunden ist)
1493 // und das Control selber nach einem TextComponent-Interface (damit ich mir dort den Text abholen kann)
1494 Reference
< XTextComponent
> xText(xActiveControl
, UNO_QUERY
);
1497 strActiveField
= getLabelName(xProperties
).getStr();
1498 strInitialText
= xText
->getText().getStr();
1504 // das Control selber hat keine ControlSource, aber vielleicht ist es ein GridControl
1505 Reference
< XGrid
> xGrid(xActiveControl
, UNO_QUERY
);
1508 // fuer strActiveField brauche ich die die ControlSource der Column, dafuer den Columns-Container, dafuer die
1510 Reference
< XGridPeer
> xGridPeer(xActiveControl
->getPeer(), UNO_QUERY
);
1511 Reference
< XIndexAccess
> xColumns
;
1513 xColumns
= Reference
< XIndexAccess
>(xGridPeer
->getColumns(),UNO_QUERY
);
1515 sal_Int16 nViewCol
= xGrid
->getCurrentColumnPosition();
1516 sal_Int16 nModelCol
= GridView2ModelPos(xColumns
, nViewCol
);
1517 Reference
< XPropertySet
> xCurrentCol
;
1519 xColumns
->getByIndex(nModelCol
) >>= xCurrentCol
;
1520 if (xCurrentCol
.is())
1521 strActiveField
= ::comphelper::getString(xCurrentCol
->getPropertyValue(FM_PROP_LABEL
)).getStr();
1523 // the text fo the current column
1524 Reference
< XIndexAccess
> xColControls(xGridPeer
, UNO_QUERY
);
1525 Reference
< XInterface
> xCurControl
;
1526 xColControls
->getByIndex(nViewCol
) >>= xCurControl
;
1527 ::rtl::OUString sInitialText
;
1528 if (IsSearchableControl(xCurControl
, &sInitialText
))
1529 strInitialText
= sInitialText
.getStr();
1534 // um eventuelle GridControls, die ich kenne, kuemmern
1535 LoopGrids(GA_DISABLE_SYNC
/*| GA_ENABLE_ROCTRLR*/);
1537 // jetzt bin ich reif fuer den Dialog
1538 // wenn die potentiellen Deadlocks, die durch die Benutzung des Solar-Mutex in MTs VCLX...-Klasen entstehen, irgendwann mal
1539 // ausgeraeumt sind, sollte hier ein SM_USETHREAD rein, denn die Suche in einem eigenen Thread ist doch etwas fluessiger
1540 // sollte allerdings irgendwie von dem unterliegenden Cursor abhaengig gemacht werden, DAO zum Beispiel ist nicht thread-sicher
1541 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
1542 AbstractFmSearchDialog
* pDialog
= NULL
;
1544 pDialog
= pFact
->CreateFmSearchDialog( &m_pShell
->GetViewShell()->GetViewFrame()->GetWindow(), strInitialText
, aContextNames
, nInitialContext
, LINK( this, FmXFormShell
, OnSearchContextRequest
) );
1545 DBG_ASSERT( pDialog
, "FmXFormShell::ExecuteSearch: could not create the search dialog!" );
1548 pDialog
->SetActiveField( strActiveField
);
1549 pDialog
->SetFoundHandler( LINK( this, FmXFormShell
, OnFoundData
) );
1550 pDialog
->SetCanceledNotFoundHdl( LINK( this, FmXFormShell
, OnCanceledNotFound
) );
1555 // GridControls wieder restaurieren
1556 LoopGrids(GA_ENABLE_SYNC
| GA_DISABLE_ROCTRLR
);
1558 m_pShell
->GetFormView()->UnMarkAll(m_pShell
->GetFormView()->GetSdrPageView());
1559 // da ich in OnFoundData (fals ich dort war) Controls markiert habe
1562 //------------------------------------------------------------------------------
1563 sal_Bool
FmXFormShell::GetY2KState(sal_uInt16
& n
)
1565 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::GetY2KState" );
1566 if ( impl_checkDisposed() )
1569 if (m_pShell
->IsDesignMode())
1570 // im Design-Modus (ohne aktive Controls) soll sich das Haupt-Dokument darum kuemmern
1573 Reference
< XForm
> xForm( getActiveForm());
1575 // kein aktuelles Formular (also insbesondere kein aktuelles Control) -> das Haupt-Dokument soll sich kuemmern
1578 Reference
< XRowSet
> xDB(xForm
, UNO_QUERY
);
1579 DBG_ASSERT(xDB
.is(), "FmXFormShell::GetY2KState : current form has no dbform-interface !");
1581 Reference
< XNumberFormatsSupplier
> xSupplier( getNumberFormats(OStaticDataAccessTools().getRowSetConnection(xDB
), sal_False
));
1584 Reference
< XPropertySet
> xSet(xSupplier
->getNumberFormatSettings());
1589 Any
aVal( xSet
->getPropertyValue(::rtl::OUString::createFromAscii("TwoDigitDateStart")) );
1602 //------------------------------------------------------------------------------
1603 void FmXFormShell::SetY2KState(sal_uInt16 n
)
1605 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::SetY2KState" );
1606 if ( impl_checkDisposed() )
1609 Reference
< XForm
> xActiveForm( getActiveForm());
1610 Reference
< XRowSet
> xActiveRowSet( xActiveForm
, UNO_QUERY
);
1611 if ( xActiveRowSet
.is() )
1613 Reference
< XNumberFormatsSupplier
> xSupplier( getNumberFormats( getRowSetConnection( xActiveRowSet
), sal_False
) );
1616 Reference
< XPropertySet
> xSet(xSupplier
->getNumberFormatSettings());
1623 xSet
->setPropertyValue(::rtl::OUString::createFromAscii("TwoDigitDateStart"), aVal
);
1627 DBG_ERROR("FmXFormShell::SetY2KState: Exception occured!");
1635 // kein aktives Formular gefunden -> alle aktuell vorhandenen Formulare durchiterieren
1636 Reference
< XIndexAccess
> xCurrentForms( m_xForms
);
1637 if (!xCurrentForms
.is())
1638 { // im alive-Modus sind meine Forms nicht gesetzt, wohl aber die an der Page
1639 if (m_pShell
->GetCurPage())
1640 xCurrentForms
= Reference
< XIndexAccess
>( m_pShell
->GetCurPage()->GetForms( false ), UNO_QUERY
);
1642 if (!xCurrentForms
.is())
1645 ::comphelper::IndexAccessIterator
aIter(xCurrentForms
);
1646 Reference
< XInterface
> xCurrentElement( aIter
.Next());
1647 while (xCurrentElement
.is())
1649 // ist das aktuelle Element eine DatabaseForm ?
1650 Reference
< XRowSet
> xElementAsRowSet( xCurrentElement
, UNO_QUERY
);
1651 if ( xElementAsRowSet
.is() )
1653 Reference
< XNumberFormatsSupplier
> xSupplier( getNumberFormats( getRowSetConnection( xElementAsRowSet
), sal_False
) );
1654 if (!xSupplier
.is())
1657 Reference
< XPropertySet
> xSet(xSupplier
->getNumberFormatSettings());
1664 xSet
->setPropertyValue(::rtl::OUString::createFromAscii("TwoDigitDateStart"), aVal
);
1668 DBG_ERROR("FmXFormShell::SetY2KState: Exception occured!");
1673 xCurrentElement
= aIter
.Next();
1677 //------------------------------------------------------------------------------
1678 void FmXFormShell::CloseExternalFormViewer()
1680 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::CloseExternalFormViewer" );
1681 if ( impl_checkDisposed() )
1684 if (!m_xExternalViewController
.is())
1687 Reference
< ::com::sun::star::frame::XFrame
> xExternalViewFrame( m_xExternalViewController
->getFrame());
1688 Reference
< ::com::sun::star::frame::XDispatchProvider
> xCommLink(xExternalViewFrame
, UNO_QUERY
);
1689 if (!xCommLink
.is())
1692 xExternalViewFrame
->setComponent(NULL
,NULL
);
1693 ::comphelper::disposeComponent(xExternalViewFrame
);
1694 m_xExternalViewController
= NULL
;
1695 m_xExtViewTriggerController
= NULL
;
1696 m_xExternalDisplayedForm
= NULL
;
1699 //------------------------------------------------------------------------------
1700 Reference
< XResultSet
> FmXFormShell::getInternalForm(const Reference
< XResultSet
>& _xForm
) const
1702 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::getInternalForm" );
1703 if ( impl_checkDisposed() )
1706 Reference
< XFormController
> xExternalCtrlr(m_xExternalViewController
, UNO_QUERY
);
1707 if (xExternalCtrlr
.is() && (_xForm
== xExternalCtrlr
->getModel()))
1709 DBG_ASSERT(m_xExternalDisplayedForm
.is(), "FmXFormShell::getInternalForm : invalid external form !");
1710 return m_xExternalDisplayedForm
;
1715 //------------------------------------------------------------------------------
1716 Reference
< XForm
> FmXFormShell::getInternalForm(const Reference
< XForm
>& _xForm
) const
1718 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::getInternalForm" );
1719 if ( impl_checkDisposed() )
1722 Reference
< XFormController
> xExternalCtrlr(m_xExternalViewController
, UNO_QUERY
);
1723 if (xExternalCtrlr
.is() && (_xForm
== xExternalCtrlr
->getModel()))
1725 DBG_ASSERT(m_xExternalDisplayedForm
.is(), "FmXFormShell::getInternalForm : invalid external form !");
1726 return Reference
< XForm
>(m_xExternalDisplayedForm
, UNO_QUERY
);
1731 //------------------------------------------------------------------------
1734 static bool lcl_isNavigationRelevant( sal_Int32 _nWhich
)
1736 return ( _nWhich
== SID_FM_RECORD_FIRST
)
1737 || ( _nWhich
== SID_FM_RECORD_PREV
)
1738 || ( _nWhich
== SID_FM_RECORD_NEXT
)
1739 || ( _nWhich
== SID_FM_RECORD_LAST
)
1740 || ( _nWhich
== SID_FM_RECORD_NEW
);
1744 //------------------------------------------------------------------------------
1745 bool FmXFormShell::IsFormSlotEnabled( sal_Int32 _nSlot
, FeatureState
* _pCompleteState
)
1747 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::IsFormSlotEnabled" );
1748 const ::svx::ControllerFeatures
& rController
=
1749 lcl_isNavigationRelevant( _nSlot
)
1750 ? getNavControllerFeatures()
1751 : getActiveControllerFeatures();
1753 if ( !_pCompleteState
)
1754 return rController
->isEnabled( _nSlot
);
1756 rController
->getState( _nSlot
, *_pCompleteState
);
1757 return _pCompleteState
->Enabled
;
1760 //------------------------------------------------------------------------------
1761 void FmXFormShell::ExecuteFormSlot( sal_Int32 _nSlot
)
1763 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::ExecuteFormSlot" );
1764 const ::svx::ControllerFeatures
& rController
=
1765 lcl_isNavigationRelevant( _nSlot
)
1766 ? getNavControllerFeatures()
1767 : getActiveControllerFeatures();
1769 rController
->execute( _nSlot
);
1771 if ( _nSlot
== SID_FM_RECORD_UNDO
)
1773 // if we're doing an UNDO, *and* if the affected form is the form which we also display
1774 // as external view, then we need to reset the controls of the external form, too
1775 if ( getInternalForm( getActiveForm() ) == m_xExternalDisplayedForm
)
1777 Reference
< XIndexAccess
> xContainer( m_xExternalDisplayedForm
, UNO_QUERY
);
1778 if ( xContainer
.is() )
1780 Reference
< XReset
> xReset
;
1781 for ( sal_Int32 i
= 0; i
< xContainer
->getCount(); ++i
)
1783 if ( ( xContainer
->getByIndex( i
) >>= xReset
) && xReset
.is() )
1785 // no resets on sub forms
1786 Reference
< XForm
> xAsForm( xReset
, UNO_QUERY
);
1787 if ( !xAsForm
.is() )
1796 //------------------------------------------------------------------------------
1797 void FmXFormShell::impl_switchActiveControllerListening( const bool _bListen
)
1799 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::impl_switchActiveControllerListening" );
1800 Reference
< XComponent
> xComp( m_xActiveController
, UNO_QUERY
);
1805 xComp
->addEventListener( (XFormControllerListener
*)this );
1807 xComp
->removeEventListener( (XFormControllerListener
*)this );
1810 //------------------------------------------------------------------------------
1811 void FmXFormShell::setActiveController( const Reference
< XFormController
>& xController
, sal_Bool _bNoSaveOldContent
)
1813 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::setActiveController" );
1814 if ( impl_checkDisposed() )
1817 if (m_bChangingDesignMode
)
1819 DBG_ASSERT(!m_pShell
->IsDesignMode(), "nur im alive mode verwenden");
1821 // Ist die Routine ein zweites Mal gerufen worden,
1822 // dann sollte der Focus nicht mehr umgesetzt werden
1825 m_bSetFocus
= xController
!= m_xActiveController
;
1829 if (xController
!= m_xActiveController
)
1831 // if there is a async cursor action running we have to restore the locking state of the controls of the old controller
1832 if (HasPendingCursorAction(Reference
< XResultSet
>(m_xActiveForm
, UNO_QUERY
)))
1833 restoreControlLocks();
1835 ::osl::ClearableMutexGuard
aGuard(m_aAsyncSafety
);
1836 // switch all nav dispatchers belonging to the form of the current nav controller to 'non active'
1837 Reference
< XResultSet
> xNavigationForm
;
1838 if (m_xNavigationController
.is())
1839 xNavigationForm
= Reference
< XResultSet
>(m_xNavigationController
->getModel(), UNO_QUERY
);
1842 m_bInActivate
= sal_True
;
1844 // check if the 2 controllers serve different forms
1845 Reference
< XResultSet
> xOldForm
;
1846 if (m_xActiveController
.is())
1847 xOldForm
= Reference
< XResultSet
>(m_xActiveController
->getModel(), UNO_QUERY
);
1848 Reference
< XResultSet
> xNewForm
;
1849 if (xController
.is())
1850 xNewForm
= Reference
< XResultSet
>(xController
->getModel(), UNO_QUERY
);
1851 xOldForm
= getInternalForm(xOldForm
);
1852 xNewForm
= getInternalForm(xNewForm
);
1854 sal_Bool bDifferentForm
= ( xOldForm
.get() != xNewForm
.get() );
1855 sal_Bool bNeedSave
= bDifferentForm
&& !_bNoSaveOldContent
;
1856 // we save the content of the old form if we move to a new form, and saving old content is allowed
1858 if ( m_xActiveController
.is() && bNeedSave
)
1860 // beim Wechsel des Controllers den Inhalt speichern, ein Commit
1861 // wurde bereits ausgefuehrt
1862 if ( m_aActiveControllerFeatures
->commitCurrentControl() )
1864 m_bSetFocus
= sal_True
;
1865 if ( m_aActiveControllerFeatures
->isModifiedRow() )
1867 sal_Bool bIsNew
= m_aActiveControllerFeatures
->isInsertionRow();
1868 sal_Bool bResult
= m_aActiveControllerFeatures
->commitCurrentRecord();
1869 if ( !bResult
&& m_bSetFocus
)
1871 // if we couldn't save the current record, set the focus back to the
1873 Reference
< XWindow
> xWindow( m_xActiveController
->getCurrentControl(), UNO_QUERY
);
1875 xWindow
->setFocus();
1876 m_bInActivate
= sal_False
;
1879 else if ( bResult
&& bIsNew
)
1881 Reference
< XResultSet
> xCursor( m_aActiveControllerFeatures
->getCursor().get() );
1884 DO_SAFE( xCursor
->last(); );
1893 impl_switchActiveControllerListening( false );
1895 m_aActiveControllerFeatures
.dispose();
1896 m_xActiveController
= xController
;
1897 if ( m_xActiveController
.is() )
1898 m_aActiveControllerFeatures
.assign( m_xActiveController
);
1900 impl_switchActiveControllerListening( true );
1902 if ( m_xActiveController
.is() )
1903 m_xActiveForm
= getInternalForm( Reference
< XForm
>( m_xActiveController
->getModel(), UNO_QUERY
) );
1905 m_xActiveForm
= NULL
;
1909 // activate all dispatchers belonging to form of the new navigation controller
1910 xNavigationForm
= NULL
;
1911 if (m_xNavigationController
.is())
1912 xNavigationForm
= Reference
< XResultSet
>(m_xNavigationController
->getModel(), UNO_QUERY
);
1914 // if there is a async cursor action running we have to lock the controls of the new controller
1915 if (HasPendingCursorAction(Reference
< XResultSet
>(m_xActiveForm
, UNO_QUERY
)))
1918 m_bInActivate
= sal_False
;
1920 m_pShell
->UIFeatureChanged();
1921 m_pShell
->GetViewShell()->GetViewFrame()->GetBindings().InvalidateShell(*m_pShell
);
1923 InvalidateSlot(SID_FM_FILTER_NAVIGATOR_CONTROL
, sal_True
);
1927 //------------------------------------------------------------------------------
1928 void FmXFormShell::getCurrentSelection( InterfaceBag
& /* [out] */ _rSelection
) const
1930 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::getCurrentSelection" );
1931 _rSelection
= m_aCurrentSelection
;
1934 //------------------------------------------------------------------------------
1935 bool FmXFormShell::setCurrentSelectionFromMark( const SdrMarkList
& _rMarkList
)
1937 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::setCurrentSelectionFromMark" );
1938 m_aLastKnownMarkedControls
.clear();
1940 if ( ( _rMarkList
.GetMarkCount() > 0 ) && isControlList( _rMarkList
) )
1941 collectInterfacesFromMarkList( _rMarkList
, m_aLastKnownMarkedControls
);
1943 return setCurrentSelection( m_aLastKnownMarkedControls
);
1946 //------------------------------------------------------------------------------
1947 bool FmXFormShell::selectLastMarkedControls()
1949 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::selectLastMarkedControls" );
1950 return setCurrentSelection( m_aLastKnownMarkedControls
);
1953 //------------------------------------------------------------------------------
1954 bool FmXFormShell::setCurrentSelection( const InterfaceBag
& _rSelection
)
1956 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::setCurrentSelection" );
1957 if ( impl_checkDisposed() )
1960 DBG_ASSERT( m_pShell
->IsDesignMode(), "FmXFormShell::setCurrentSelection: only to be used in design mode!" );
1962 if ( _rSelection
.empty() && m_aCurrentSelection
.empty() )
1966 if ( _rSelection
.size() == m_aCurrentSelection
.size() )
1968 InterfaceBag::const_iterator aNew
= _rSelection
.begin();
1969 InterfaceBag::const_iterator aOld
= m_aCurrentSelection
.begin();
1970 for ( ; aNew
!= _rSelection
.end(); ++aNew
, ++aOld
)
1972 OSL_ENSURE( Reference
< XInterface
>( *aNew
, UNO_QUERY
).get() == aNew
->get(), "FmXFormShell::setCurrentSelection: new interface not normalized!" );
1973 OSL_ENSURE( Reference
< XInterface
>( *aOld
, UNO_QUERY
).get() == aOld
->get(), "FmXFormShell::setCurrentSelection: old interface not normalized!" );
1975 if ( aNew
->get() != aOld
->get() )
1979 if ( aNew
== _rSelection
.end() )
1984 // the following is some strange code to ensure that when you have two grid controls in a document,
1985 // only one of them can have a selected column.
1986 // TODO: this should happen elsewhere, but not here - shouldn't it?
1987 if ( !m_aCurrentSelection
.empty() )
1989 Reference
< XChild
> xCur
; if ( m_aCurrentSelection
.size() == 1 ) xCur
= xCur
.query( *m_aCurrentSelection
.begin() );
1990 Reference
< XChild
> xNew
; if ( _rSelection
.size() == 1 ) xNew
= xNew
.query( *_rSelection
.begin() );
1992 // is there nothing to be selected, or the parents differ, and the parent of the current object
1993 // is a selection supplier, then deselect
1994 if ( xCur
.is() && ( !xNew
.is() || ( xCur
->getParent() != xNew
->getParent() ) ) )
1996 Reference
< XSelectionSupplier
> xSel( xCur
->getParent(), UNO_QUERY
);
1998 xSel
->select( Any() );
2002 m_aCurrentSelection
= _rSelection
;
2004 // determine the form which all the selected objécts belong to, if any
2005 Reference
< XForm
> xNewCurrentForm
;
2006 for ( InterfaceBag::const_iterator loop
= m_aCurrentSelection
.begin();
2007 loop
!= m_aCurrentSelection
.end();
2011 Reference
< XForm
> xThisRoundsForm( GetForm( *loop
) );
2012 OSL_ENSURE( xThisRoundsForm
.is(), "FmXFormShell::setCurrentSelection: *everything* should belong to a form!" );
2014 if ( !xNewCurrentForm
.is() )
2015 { // the first form we encounterd
2016 xNewCurrentForm
= xThisRoundsForm
;
2018 else if ( xNewCurrentForm
!= xThisRoundsForm
)
2019 { // different forms -> no "current form" at all
2020 xNewCurrentForm
.clear();
2025 if ( !m_aCurrentSelection
.empty() )
2026 impl_updateCurrentForm( xNewCurrentForm
);
2028 // ensure some slots are updated
2029 for ( size_t i
= 0; i
< sizeof( SelObjectSlotMap
) / sizeof( SelObjectSlotMap
[0] ); ++i
)
2030 InvalidateSlot( SelObjectSlotMap
[i
], sal_False
);
2035 //------------------------------------------------------------------------------
2036 bool FmXFormShell::isSolelySelected( const Reference
< XInterface
>& _rxObject
)
2038 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::isSolelySelected" );
2039 return ( m_aCurrentSelection
.size() == 1 ) && ( *m_aCurrentSelection
.begin() == _rxObject
);
2042 //------------------------------------------------------------------------------
2043 void FmXFormShell::forgetCurrentForm()
2045 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::forgetCurrentForm" );
2046 if ( !m_xCurrentForm
.is() )
2050 impl_updateCurrentForm( NULL
);
2052 // ... and try finding a new current form
2053 // #i88186# / 2008-04-12 / frank.schoenheit@sun.com
2054 impl_defaultCurrentForm_nothrow();
2057 //------------------------------------------------------------------------------
2058 void FmXFormShell::impl_updateCurrentForm( const Reference
< XForm
>& _rxNewCurForm
)
2060 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::impl_updateCurrentForm" );
2061 if ( impl_checkDisposed() )
2064 m_xCurrentForm
= _rxNewCurForm
;
2066 // propagate to the FormPage(Impl)
2067 FmFormPage
* pPage
= m_pShell
->GetCurPage();
2069 pPage
->GetImpl().setCurForm( m_xCurrentForm
);
2071 // ensure the UI which depends on the current form is up-to-date
2072 for ( size_t i
= 0; i
< sizeof( DlgSlotMap
) / sizeof( DlgSlotMap
[0] ); ++i
)
2073 InvalidateSlot( DlgSlotMap
[i
], sal_False
);
2076 //------------------------------------------------------------------------------
2077 void FmXFormShell::startListening()
2079 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::startListening" );
2080 if ( impl_checkDisposed() )
2083 Reference
< XRowSet
> xDatabaseForm(m_xActiveForm
, UNO_QUERY
);
2084 if (xDatabaseForm
.is() && getRowSetConnection(xDatabaseForm
).is())
2086 Reference
< XPropertySet
> xActiveFormSet(m_xActiveForm
, UNO_QUERY
);
2087 if (xActiveFormSet
.is())
2089 // wenn es eine Datenquelle gibt, dann den Listener aufbauen
2090 // TODO: this is strange - shouldn't this depend on a isLoaded instead of
2091 // a "has command value"? Finally, the command value only means that it was
2092 // intended to be loaded, not that it actually *is* loaded
2093 ::rtl::OUString aSource
= ::comphelper::getString(xActiveFormSet
->getPropertyValue(FM_PROP_COMMAND
));
2094 if (aSource
.getLength())
2096 m_bDatabaseBar
= sal_True
;
2098 xActiveFormSet
->getPropertyValue(FM_PROP_NAVIGATION
) >>= m_eNavigate
;
2100 switch (m_eNavigate
)
2102 case NavigationBarMode_PARENT
:
2104 // suchen des Controllers, ueber den eine Navigation moeglich ist
2105 Reference
< XChild
> xChild(m_xActiveController
, UNO_QUERY
);
2106 Reference
< XFormController
> xParent
;
2109 xChild
= Reference
< XChild
>(xChild
->getParent(), UNO_QUERY
);
2110 xParent
= Reference
< XFormController
>(xChild
, UNO_QUERY
);
2111 Reference
< XPropertySet
> xParentSet
;
2113 xParentSet
= Reference
< XPropertySet
>(xParent
->getModel(), UNO_QUERY
);
2114 if (xParentSet
.is())
2116 xParentSet
->getPropertyValue(FM_PROP_NAVIGATION
) >>= m_eNavigate
;
2117 if (m_eNavigate
== NavigationBarMode_CURRENT
)
2121 m_xNavigationController
= xParent
;
2125 case NavigationBarMode_CURRENT
:
2126 m_xNavigationController
= m_xActiveController
;
2130 m_xNavigationController
= NULL
;
2131 m_bDatabaseBar
= sal_False
;
2134 m_aNavControllerFeatures
.dispose();
2135 if ( m_xNavigationController
.is() && ( m_xNavigationController
!= m_xActiveController
) )
2136 m_aNavControllerFeatures
.assign( m_xNavigationController
);
2138 // an dem Controller, der die Navigation regelt, wg. RecordCount lauschen
2139 Reference
< XPropertySet
> xNavigationSet
;
2140 if (m_xNavigationController
.is())
2142 xNavigationSet
= Reference
< XPropertySet
>(m_xNavigationController
->getModel(), UNO_QUERY
);
2143 if (xNavigationSet
.is())
2144 xNavigationSet
->addPropertyChangeListener(FM_PROP_ROWCOUNT
,this);
2151 m_eNavigate
= NavigationBarMode_NONE
;
2152 m_bDatabaseBar
= sal_False
;
2153 m_xNavigationController
= NULL
;
2156 //------------------------------------------------------------------------------
2157 void FmXFormShell::stopListening()
2159 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::stopListening" );
2160 if ( impl_checkDisposed() )
2163 Reference
< XRowSet
> xDatabaseForm(m_xActiveForm
, UNO_QUERY
);
2164 if ( xDatabaseForm
.is() )
2166 if (m_xNavigationController
.is())
2168 Reference
< XPropertySet
> xSet(m_xNavigationController
->getModel(), UNO_QUERY
);
2170 xSet
->removePropertyChangeListener(FM_PROP_ROWCOUNT
, this);
2175 m_bDatabaseBar
= sal_False
;
2176 m_eNavigate
= NavigationBarMode_NONE
;
2177 m_xNavigationController
= NULL
;
2180 //------------------------------------------------------------------------------
2181 void FmXFormShell::ShowSelectionProperties( sal_Bool bShow
)
2183 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::ShowSelectionProperties" );
2184 if ( impl_checkDisposed() )
2187 // if the window is already visible, only update the state
2188 sal_Bool bHasChild
= m_pShell
->GetViewShell()->GetViewFrame()->HasChildWindow( SID_FM_SHOW_PROPERTIES
);
2189 if ( bHasChild
&& bShow
)
2190 UpdateSlot( SID_FM_PROPERTY_CONTROL
);
2192 // else toggle state
2194 m_pShell
->GetViewShell()->GetViewFrame()->ToggleChildWindow(SID_FM_SHOW_PROPERTIES
);
2196 InvalidateSlot( SID_FM_PROPERTIES
, sal_False
);
2197 InvalidateSlot( SID_FM_CTL_PROPERTIES
, sal_False
);
2200 //------------------------------------------------------------------------------
2201 IMPL_LINK(FmXFormShell
, OnFoundData
, FmFoundRecordInformation
*, pfriWhere
)
2203 if ( impl_checkDisposed() )
2206 DBG_ASSERT((pfriWhere
->nContext
>= 0) && (pfriWhere
->nContext
< (sal_Int16
)m_aSearchForms
.size()),
2207 "FmXFormShell::OnFoundData : ungueltiger Kontext !");
2208 Reference
< XForm
> xForm( m_aSearchForms
.at(pfriWhere
->nContext
));
2209 DBG_ASSERT(xForm
.is(), "FmXFormShell::OnFoundData : ungueltige Form !");
2211 Reference
< XRowLocate
> xCursor(xForm
, UNO_QUERY
);
2213 return 0; // was soll ich da machen ?
2218 xCursor
->moveToBookmark(pfriWhere
->aPosition
);
2220 catch(const SQLException
&)
2222 OSL_ENSURE(0,"Can position on bookmark!");
2225 LoopGrids(GA_FORCE_SYNC
);
2227 // und zum Feld (dazu habe ich vor dem Start des Suchens die XVclComponent-Interfaces eingesammelt)
2228 DBG_ASSERT(pfriWhere
->nFieldPos
< m_arrSearchedControls
.Count(), "FmXFormShell::OnFoundData : ungueltige Daten uebergeben !");
2229 SdrObject
* pObject
= m_arrSearchedControls
.GetObject(pfriWhere
->nFieldPos
);
2230 DBG_ASSERT(pObject
!= NULL
, "FmXFormShell::OnFoundData : unerwartet : ungueltiges VclControl-Interface");
2232 m_pShell
->GetFormView()->UnMarkAll(m_pShell
->GetFormView()->GetSdrPageView());
2233 m_pShell
->GetFormView()->MarkObj(pObject
, m_pShell
->GetFormView()->GetSdrPageView());
2235 FmFormObj
* pFormObject
= FmFormObj::GetFormObject( pObject
);
2236 Reference
< XControlModel
> xControlModel( pFormObject
? pFormObject
->GetUnoControlModel() : Reference
< XControlModel
>() );
2237 DBG_ASSERT( xControlModel
.is(), "FmXFormShell::OnFoundData: invalid control!" );
2239 // disable the permanent cursor for the last grid we found a record
2240 if (m_xLastGridFound
.is() && (m_xLastGridFound
!= xControlModel
))
2242 Reference
< XPropertySet
> xOldSet(m_xLastGridFound
, UNO_QUERY
);
2243 xOldSet
->setPropertyValue(FM_PROP_ALWAYSSHOWCURSOR
, makeAny( (sal_Bool
)sal_False
) );
2244 Reference
< XPropertyState
> xOldSetState(xOldSet
, UNO_QUERY
);
2245 if (xOldSetState
.is())
2246 xOldSetState
->setPropertyToDefault(FM_PROP_CURSORCOLOR
);
2248 xOldSet
->setPropertyValue(FM_PROP_CURSORCOLOR
, Any());
2251 // wenn das Feld sich in einem GridControl befindet, muss ich dort noch in die entsprechende Spalte gehen
2252 sal_Int32 nGridColumn
= m_arrRelativeGridColumn
.GetObject(pfriWhere
->nFieldPos
);
2253 if (nGridColumn
!= -1)
2254 { // dummer weise muss ich mir das Control erst wieder besorgen
2255 Reference
< XControl
> xControl( GetControlFromModel(xControlModel
));
2256 Reference
< XGrid
> xGrid(xControl
, UNO_QUERY
);
2257 DBG_ASSERT(xGrid
.is(), "FmXFormShell::OnFoundData : ungueltiges Control !");
2258 // wenn eine der Asserts anschlaegt, habe ich beim Aufbauen von m_arrSearchedControls wohl was falsch gemacht
2260 // enable a permanent cursor for the grid so we can see the found text
2261 Reference
< XPropertySet
> xModelSet(xControlModel
, UNO_QUERY
);
2262 DBG_ASSERT(xModelSet
.is(), "FmXFormShell::OnFoundData : invalid control model (no property set) !");
2263 xModelSet
->setPropertyValue( FM_PROP_ALWAYSSHOWCURSOR
, makeAny( (sal_Bool
)sal_True
) );
2264 xModelSet
->setPropertyValue( FM_PROP_CURSORCOLOR
, makeAny( sal_Int32( COL_LIGHTRED
) ) );
2265 m_xLastGridFound
= xControlModel
;
2267 xGrid
->setCurrentColumnPosition((sal_Int16
)nGridColumn
);
2270 // als der Cursor neu positioniert wurde, habe ich (in positioned) meine Formularleisten-Slots invalidiert, aber das greift
2271 // hier dummerweise nicht, da i.A. ja der (modale) Suchdialog oben ist ... also Gewalt ...
2272 sal_uInt16 nPos
= 0;
2273 while (DatabaseSlotMap
[nPos
])
2274 m_pShell
->GetViewShell()->GetViewFrame()->GetBindings().Update(DatabaseSlotMap
[nPos
++]);
2275 // leider geht das Update im Gegensatz zum Invalidate nur mit einzelnen Slots)
2280 //------------------------------------------------------------------------------
2281 IMPL_LINK(FmXFormShell
, OnCanceledNotFound
, FmFoundRecordInformation
*, pfriWhere
)
2283 if ( impl_checkDisposed() )
2286 DBG_ASSERT((pfriWhere
->nContext
>= 0) && (pfriWhere
->nContext
< (sal_Int16
)m_aSearchForms
.size()),
2287 "FmXFormShell::OnCanceledNotFound : ungueltiger Kontext !");
2288 Reference
< XForm
> xForm( m_aSearchForms
.at(pfriWhere
->nContext
));
2289 DBG_ASSERT(xForm
.is(), "FmXFormShell::OnCanceledNotFound : ungueltige Form !");
2291 Reference
< XRowLocate
> xCursor(xForm
, UNO_QUERY
);
2293 return 0; // was soll ich da machen ?
2298 xCursor
->moveToBookmark(pfriWhere
->aPosition
);
2300 catch(const SQLException
&)
2302 OSL_ENSURE(0,"Can position on bookmark!");
2306 m_pShell
->GetFormView()->UnMarkAll(m_pShell
->GetFormView()->GetSdrPageView());
2310 //------------------------------------------------------------------------------
2311 IMPL_LINK(FmXFormShell
, OnSearchContextRequest
, FmSearchContext
*, pfmscContextInfo
)
2313 if ( impl_checkDisposed() )
2316 DBG_ASSERT(pfmscContextInfo
->nContext
< (sal_Int16
)m_aSearchForms
.size(), "FmXFormShell::OnSearchContextRequest : invalid parameter !");
2317 Reference
< XForm
> xForm( m_aSearchForms
.at(pfmscContextInfo
->nContext
));
2318 DBG_ASSERT(xForm
.is(), "FmXFormShell::OnSearchContextRequest : unexpected : invalid context !");
2320 Reference
< XResultSet
> xIter(xForm
, UNO_QUERY
);
2321 DBG_ASSERT(xIter
.is(), "FmXFormShell::OnSearchContextRequest : unexpected : context has no iterator !");
2323 // --------------------------------------------------------------------------------------------
2324 // die Liste der zu involvierenden Felder zusammenstellen (sind die ControlSources aller Felder, die eine solche Eigenschaft habe)
2325 UniString strFieldList
, sFieldDisplayNames
;
2326 m_arrSearchedControls
.Remove(0, m_arrSearchedControls
.Count());
2327 m_arrRelativeGridColumn
.Remove(0, m_arrRelativeGridColumn
.Count());
2329 // folgendes kleines Problem : Ich brauche, um gefundene Felder zu markieren, SdrObjekte. Um hier festzustellen, welche Controls
2330 // ich in die Suche einbeziehen soll, brauche ich Controls (also XControl-Interfaces). Ich muss also ueber eines von beiden
2331 // iterieren und mir das jeweils andere besorgen. Dummerweise gibt es keine direkte Verbindung zwischen beiden Welten (abgesehen
2332 // von einem GetUnoControl an SdrUnoObject, das aber ein OutputDevice verlangt, womit ich nichts anfangen kann).
2333 // Allerdings komme ich sowohl von einem Control als auch von einem SdrObject zum Model, und damit ist mir mit einer doppelten
2334 // Schleife die Zuordnung SdrObject<->Control moeglich.
2335 // Die Alternative zu dieser (unschoenen und sicher auch nicht ganz fixen) Loesung waere, auf das Cachen der SdrObjects zu
2336 // verzichten, was dann aber in OnFoundData zu wesentlicher Mehrarbeit fuehren wuerde (da ich mir dort jedesmal das SdrObject
2337 // erst besorgen muesste). Da aber OnFoundData i.d.R. oefter aufgerufen wird als ExecuteSearch, erledige ich das hier.
2339 Reference
< XNameAccess
> xValidFormFields
;
2340 Reference
< XColumnsSupplier
> xSupplyCols(xIter
, UNO_QUERY
);
2341 DBG_ASSERT(xSupplyCols
.is(), "FmXFormShell::OnSearchContextRequest : invalid cursor : no columns supplier !");
2342 if (xSupplyCols
.is())
2343 xValidFormFields
= xSupplyCols
->getColumns();
2344 DBG_ASSERT(xValidFormFields
.is(), "FmXFormShell::OnSearchContextRequest : form has no fields !");
2346 // aktuelle(r) Page/Controller
2347 FmFormPage
* pCurrentPage
= m_pShell
->GetCurPage();
2348 DBG_ASSERT(pCurrentPage
!=NULL
, "FmXFormShell::OnSearchContextRequest : no page !");
2349 // alle Sdr-Controls dieser Seite durchsuchen ...
2350 ::rtl::OUString sControlSource
, aName
;
2352 SdrObjListIter
aPageIter( *pCurrentPage
);
2353 while ( aPageIter
.IsMore() )
2355 SdrObject
* pCurrent
= aPageIter
.Next();
2356 FmFormObj
* pFormObject
= FmFormObj::GetFormObject( pCurrent
);
2357 // note that in case pCurrent is a virtual object, pFormObject points to the referenced object
2362 // the current object's model, in different tastes
2363 Reference
< XControlModel
> xControlModel( pFormObject
->GetUnoControlModel() );
2364 Reference
< XFormComponent
> xCurrentFormComponent( xControlModel
, UNO_QUERY
);
2365 DBG_ASSERT( xCurrentFormComponent
.is(), "FmXFormShell::OnSearchContextRequest: invalid objects!" );
2366 if ( !xCurrentFormComponent
.is() )
2369 // does the component belong to the form which we're interested in?
2370 if ( xCurrentFormComponent
->getParent() != xForm
)
2373 // ... nach der ControlSource-Eigenschaft fragen
2374 SearchableControlIterator
iter( xCurrentFormComponent
);
2375 Reference
< XControl
> xControlBehindModel
;
2376 // das Control, das als Model xControlModel hat
2377 // (das folgende while kann mehrmals durchlaufen werden, ohne dass das Control sich aendert, dann muss
2378 // ich nicht jedesmal neu suchen)
2380 Reference
< XInterface
> xSearchable( iter
.Next() );
2381 while ( xSearchable
.is() )
2383 sControlSource
= iter
.getCurrentValue();
2384 if ( sControlSource
.getLength() == 0 )
2385 { // das aktuelle Element hat keine ControlSource, also ist es ein GridControl (das ist das einzige, was
2386 // der SearchableControlIterator noch zulaesst)
2387 xControlBehindModel
= GetControlFromModel(xControlModel
);
2388 DBG_ASSERT(xControlBehindModel
.is(), "FmXFormShell::OnSearchContextRequest : didn't ::std::find a control with requested model !");
2390 Reference
< XGridPeer
> xGridPeer(xControlBehindModel
->getPeer(), UNO_QUERY
);
2393 if (!xGridPeer
.is())
2396 Reference
< XIndexAccess
> xPeerContainer(xGridPeer
, UNO_QUERY
);
2397 if (!xPeerContainer
.is())
2400 Reference
< XIndexAccess
> xModelColumns(xGridPeer
->getColumns(), UNO_QUERY
);
2401 DBG_ASSERT(xModelColumns
.is(), "FmXFormShell::OnSearchContextRequest : there is a grid control without columns !");
2402 // the case 'no columns' should be indicated with an empty container, I think ...
2403 DBG_ASSERT(xModelColumns
->getCount() >= xPeerContainer
->getCount(), "FmXFormShell::OnSearchContextRequest : impossible : have more view than model columns !");
2405 Reference
< XInterface
> xCurrentColumn
;
2406 for (sal_Int16 nViewPos
=0; nViewPos
<xPeerContainer
->getCount(); ++nViewPos
)
2408 xPeerContainer
->getByIndex(nViewPos
) >>= xCurrentColumn
;
2409 if (!xCurrentColumn
.is())
2412 // can we use this column control fo searching ?
2413 if (!IsSearchableControl(xCurrentColumn
))
2416 sal_Int16 nModelPos
= GridView2ModelPos(xModelColumns
, nViewPos
);
2417 Reference
< XPropertySet
> xCurrentColModel
;
2418 xModelColumns
->getByIndex(nModelPos
) >>= xCurrentColModel
;
2419 aName
= ::comphelper::getString(xCurrentColModel
->getPropertyValue(FM_PROP_CONTROLSOURCE
));
2420 // the cursor has a field matching the control source ?
2421 if (xValidFormFields
->hasByName(aName
))
2423 strFieldList
+= aName
.getStr();
2424 strFieldList
+= ';';
2426 sFieldDisplayNames
+= ::comphelper::getString(xCurrentColModel
->getPropertyValue(FM_PROP_LABEL
)).getStr();
2427 sFieldDisplayNames
+= ';';
2429 pfmscContextInfo
->arrFields
.push_back(xCurrentColumn
);
2431 // und das SdrObjekt zum Feld
2432 m_arrSearchedControls
.C40_INSERT(SdrObject
, pCurrent
, m_arrSearchedControls
.Count());
2433 // die Nummer der Spalte
2434 m_arrRelativeGridColumn
.Insert(nViewPos
, m_arrRelativeGridColumn
.Count());
2437 } while (sal_False
);
2441 if (sControlSource
.getLength() && xValidFormFields
->hasByName(sControlSource
))
2443 // jetzt brauche ich das Control zum SdrObject
2444 if (!xControlBehindModel
.is())
2446 xControlBehindModel
= GetControlFromModel(xControlModel
);
2447 DBG_ASSERT(xControlBehindModel
.is(), "FmXFormShell::OnSearchContextRequest : didn't ::std::find a control with requested model !");
2450 if (IsSearchableControl(xControlBehindModel
))
2451 { // alle Tests ueberstanden -> in die Liste mit aufnehmen
2452 strFieldList
+= sControlSource
.getStr();
2453 strFieldList
+= ';';
2455 // the label which should appear for the control :
2456 sFieldDisplayNames
+= getLabelName(Reference
< XPropertySet
>(xControlModel
, UNO_QUERY
)).getStr();
2457 sFieldDisplayNames
+= ';';
2459 // das SdrObjekt merken (beschleunigt die Behandlung in OnFoundData)
2460 m_arrSearchedControls
.C40_INSERT(SdrObject
, pCurrent
, m_arrSearchedControls
.Count());
2462 // die Nummer der Spalte (hier ein Dummy, nur fuer GridControls interesant)
2463 m_arrRelativeGridColumn
.Insert(-1, m_arrRelativeGridColumn
.Count());
2465 // und fuer die formatierte Suche ...
2466 pfmscContextInfo
->arrFields
.push_back(Reference
< XInterface
>(xControlBehindModel
, UNO_QUERY
));
2471 xSearchable
= iter
.Next();
2475 strFieldList
.EraseTrailingChars(';');
2476 sFieldDisplayNames
.EraseTrailingChars(';');
2478 if (!pfmscContextInfo
->arrFields
.size())
2480 pfmscContextInfo
->arrFields
.clear();
2481 pfmscContextInfo
->xCursor
= NULL
;
2482 pfmscContextInfo
->strUsedFields
.Erase();
2486 pfmscContextInfo
->xCursor
= xIter
;
2487 pfmscContextInfo
->strUsedFields
= strFieldList
;
2488 pfmscContextInfo
->sFieldDisplayNames
= sFieldDisplayNames
;
2490 // 66463 - 31.05.99 - FS
2491 // wenn der Cursor sich in einem anderen RecordMode als STANDARD befindet, ruecksetzen
2492 Reference
< XPropertySet
> xCursorSet(pfmscContextInfo
->xCursor
, UNO_QUERY
);
2493 Reference
< XResultSetUpdate
> xUpdateCursor(pfmscContextInfo
->xCursor
, UNO_QUERY
);
2494 if (xUpdateCursor
.is() && xCursorSet
.is() && xCursorSet
.is())
2496 if (::comphelper::getBOOL(xCursorSet
->getPropertyValue(FM_PROP_ISNEW
)))
2497 xUpdateCursor
->moveToCurrentRow();
2498 else if (::comphelper::getBOOL(xCursorSet
->getPropertyValue(FM_PROP_ISMODIFIED
)))
2499 xUpdateCursor
->cancelRowUpdates();
2502 return pfmscContextInfo
->arrFields
.size();
2505 // XContainerListener
2506 //------------------------------------------------------------------------------
2507 void FmXFormShell::elementInserted(const ContainerEvent
& evt
) throw(::com::sun::star::uno::RuntimeException
)
2509 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::elementInserted" );
2510 if ( impl_checkDisposed() )
2513 // neues Object zum lauschen
2514 Reference
< XInterface
> xTemp
;
2515 evt
.Element
>>= xTemp
;
2517 m_pShell
->DetermineForms(sal_True
);
2520 //------------------------------------------------------------------------------
2521 void FmXFormShell::elementReplaced(const ContainerEvent
& evt
) throw(::com::sun::star::uno::RuntimeException
)
2523 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::elementReplaced" );
2524 if ( impl_checkDisposed() )
2527 Reference
< XInterface
> xTemp
;
2528 evt
.ReplacedElement
>>= xTemp
;
2529 RemoveElement(xTemp
);
2530 evt
.Element
>>= xTemp
;
2534 //------------------------------------------------------------------------------
2535 void FmXFormShell::elementRemoved(const ContainerEvent
& evt
) throw(::com::sun::star::uno::RuntimeException
)
2537 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::elementRemoved" );
2538 if ( impl_checkDisposed() )
2541 Reference
< XInterface
> xTemp
;
2542 evt
.Element
>>= xTemp
;
2543 RemoveElement(xTemp
);
2544 m_pShell
->DetermineForms(sal_True
);
2547 //------------------------------------------------------------------------------
2548 void FmXFormShell::UpdateForms( sal_Bool _bInvalidate
)
2550 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::UpdateForms" );
2551 if ( impl_checkDisposed() )
2554 Reference
< XIndexAccess
> xForms
;
2556 FmFormPage
* pPage
= m_pShell
->GetCurPage();
2559 if ( m_pShell
->m_bDesignMode
)
2560 xForms
= xForms
.query( pPage
->GetForms( false ) );
2563 if ( m_xForms
!= xForms
)
2565 RemoveElement( m_xForms
);
2567 AddElement( m_xForms
);
2570 m_pShell
->DetermineForms( _bInvalidate
);
2573 //------------------------------------------------------------------------------
2574 void FmXFormShell::AddElement(const Reference
< XInterface
>& _xElement
)
2576 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::AddElement" );
2577 if ( impl_checkDisposed() )
2579 impl_AddElement_nothrow(_xElement
);
2581 // -----------------------------------------------------------------------------
2582 void FmXFormShell::impl_AddElement_nothrow(const Reference
< XInterface
>& Element
)
2584 // am Container horchen
2585 const Reference
< XIndexContainer
> xContainer(Element
, UNO_QUERY
);
2586 if (xContainer
.is())
2588 const sal_uInt32 nCount
= xContainer
->getCount();
2589 Reference
< XInterface
> xElement
;
2590 for (sal_uInt32 i
= 0; i
< nCount
; ++i
)
2592 xElement
.set(xContainer
->getByIndex(i
),UNO_QUERY
);
2593 impl_AddElement_nothrow(xElement
);
2596 const Reference
< XContainer
> xCont(Element
, UNO_QUERY
);
2598 xCont
->addContainerListener(this);
2601 const Reference
< ::com::sun::star::view::XSelectionSupplier
> xSelSupplier(Element
, UNO_QUERY
);
2602 if (xSelSupplier
.is())
2603 xSelSupplier
->addSelectionChangeListener(this);
2606 //------------------------------------------------------------------------------
2607 void FmXFormShell::RemoveElement(const Reference
< XInterface
>& Element
)
2609 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::RemoveElement" );
2610 if ( impl_checkDisposed() )
2612 impl_RemoveElement_nothrow(Element
);
2614 //------------------------------------------------------------------------------
2615 void FmXFormShell::impl_RemoveElement_nothrow(const Reference
< XInterface
>& Element
)
2617 const Reference
< ::com::sun::star::view::XSelectionSupplier
> xSelSupplier(Element
, UNO_QUERY
);
2618 if (xSelSupplier
.is())
2619 xSelSupplier
->removeSelectionChangeListener(this);
2621 // Verbindung zu Kindern aufheben
2622 const Reference
< XIndexContainer
> xContainer(Element
, UNO_QUERY
);
2623 if (xContainer
.is())
2625 const Reference
< XContainer
> xCont(Element
, UNO_QUERY
);
2627 xCont
->removeContainerListener(this);
2629 const sal_uInt32 nCount
= xContainer
->getCount();
2630 Reference
< XInterface
> xElement
;
2631 for (sal_uInt32 i
= 0; i
< nCount
; i
++)
2633 xElement
.set(xContainer
->getByIndex(i
),UNO_QUERY
);
2634 impl_RemoveElement_nothrow(xElement
);
2638 InterfaceBag::iterator wasSelectedPos
= m_aCurrentSelection
.find( Element
);
2639 if ( wasSelectedPos
!= m_aCurrentSelection
.end() )
2640 m_aCurrentSelection
.erase( wasSelectedPos
);
2643 //------------------------------------------------------------------------------
2644 void FmXFormShell::selectionChanged(const EventObject
& rEvent
) throw(::com::sun::star::uno::RuntimeException
)
2646 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::selectionChanged" );
2647 if ( impl_checkDisposed() )
2650 Reference
< XSelectionSupplier
> xSupplier( rEvent
.Source
, UNO_QUERY
);
2651 Reference
< XInterface
> xSelObj( xSupplier
->getSelection(), UNO_QUERY
);
2652 // es wurde eine Selektion weggenommen, dieses kann nur durch die Shell vorgenommen werden
2653 if ( !xSelObj
.is() )
2656 EnableTrackProperties(sal_False
);
2658 sal_Bool bMarkChanged
= m_pShell
->GetFormView()->checkUnMarkAll(rEvent
.Source
);
2659 Reference
< XForm
> xNewForm( GetForm( rEvent
.Source
) );
2661 InterfaceBag aNewSelection
;
2662 aNewSelection
.insert( Reference
< XInterface
>( xSelObj
, UNO_QUERY
) );
2664 if ( setCurrentSelection( aNewSelection
) && IsPropBrwOpen() )
2665 ShowSelectionProperties( sal_True
);
2667 EnableTrackProperties(sal_True
);
2670 m_pShell
->NotifyMarkListChanged( m_pShell
->GetFormView() );
2673 //------------------------------------------------------------------------------
2674 IMPL_LINK(FmXFormShell
, OnTimeOut
, void*, /*EMPTYTAG*/)
2676 if ( impl_checkDisposed() )
2679 if (m_pShell
->IsDesignMode() && m_pShell
->GetFormView())
2680 SetSelection(m_pShell
->GetFormView()->GetMarkedObjectList());
2685 //------------------------------------------------------------------------
2686 void FmXFormShell::SetSelectionDelayed()
2688 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::SetSelectionDelayed" );
2689 if ( impl_checkDisposed() )
2692 if (m_pShell
->IsDesignMode() && IsTrackPropertiesEnabled() && !m_aMarkTimer
.IsActive())
2693 m_aMarkTimer
.Start();
2696 //------------------------------------------------------------------------
2697 void FmXFormShell::SetSelection(const SdrMarkList
& rMarkList
)
2699 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::SetSelection" );
2700 if ( impl_checkDisposed() )
2703 DetermineSelection(rMarkList
);
2704 m_pShell
->NotifyMarkListChanged(m_pShell
->GetFormView());
2707 //------------------------------------------------------------------------
2708 void FmXFormShell::DetermineSelection(const SdrMarkList
& rMarkList
)
2710 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::DetermineSelection" );
2711 if ( setCurrentSelectionFromMark( rMarkList
) && IsPropBrwOpen() )
2712 ShowSelectionProperties( sal_True
);
2715 //------------------------------------------------------------------------------
2716 sal_Bool
FmXFormShell::IsPropBrwOpen() const
2718 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::IsPropBrwOpen" );
2719 if ( impl_checkDisposed() )
2722 return( ( m_pShell
->GetViewShell() && m_pShell
->GetViewShell()->GetViewFrame() ) ?
2723 m_pShell
->GetViewShell()->GetViewFrame()->HasChildWindow(SID_FM_SHOW_PROPERTIES
) : sal_False
);
2726 //------------------------------------------------------------------------------
2727 class FmXFormShell::SuspendPropertyTracking
2730 FmXFormShell
& m_rShell
;
2731 sal_Bool m_bEnabled
;
2734 SuspendPropertyTracking( FmXFormShell
& _rShell
)
2735 :m_rShell( _rShell
)
2736 ,m_bEnabled( sal_False
)
2738 if ( m_rShell
.IsTrackPropertiesEnabled() )
2740 m_rShell
.EnableTrackProperties( sal_False
);
2741 m_bEnabled
= sal_True
;
2745 ~SuspendPropertyTracking( )
2747 if ( m_bEnabled
) // note that ( sal_False != m_bEnabled ) implies ( NULL != m_pShell )
2748 m_rShell
.EnableTrackProperties( sal_True
);
2752 //------------------------------------------------------------------------------
2753 void FmXFormShell::SetDesignMode(sal_Bool bDesign
)
2755 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::SetDesignMode" );
2756 if ( impl_checkDisposed() )
2759 DBG_ASSERT(m_pShell
->GetFormView(), "FmXFormShell::SetDesignMode : invalid call (have no shell or no view) !");
2760 m_bChangingDesignMode
= sal_True
;
2762 // 67506 - 15.07.99 - FS
2763 // if we're switching off the design mode we have to force the property browser to be closed
2764 // so it can commit it's changes _before_ we load the forms
2767 m_bHadPropertyBrowserInDesignMode
= m_pShell
->GetViewShell()->GetViewFrame()->HasChildWindow(SID_FM_SHOW_PROPERTIES
);
2768 if (m_bHadPropertyBrowserInDesignMode
)
2769 m_pShell
->GetViewShell()->GetViewFrame()->ToggleChildWindow(SID_FM_SHOW_PROPERTIES
);
2772 FmFormView
* pFormView
= m_pShell
->GetFormView();
2775 // we are currently filtering, so stop filtering
2777 stopFiltering(sal_False
);
2779 // an den Objekten meiner MarkList als Listener abmelden
2780 pFormView
->GetImpl()->stopMarkListWatching();
2784 m_aMarkTimer
.Stop();
2786 SuspendPropertyTracking
aSuspend( *this );
2787 pFormView
->GetImpl()->saveMarkList( sal_True
);
2790 if (bDesign
&& m_xExternalViewController
.is())
2791 CloseExternalFormViewer();
2793 pFormView
->ChangeDesignMode(bDesign
);
2795 // Listener benachrichtigen
2796 FmDesignModeChangedHint
aChangedHint( bDesign
);
2797 m_pShell
->Broadcast(aChangedHint
);
2799 m_pShell
->m_bDesignMode
= bDesign
;
2800 UpdateForms( sal_False
);
2802 m_pTextShell
->designModeChanged( m_pShell
->m_bDesignMode
);
2808 // during changing the mark list, don't track the selected objects in the property browser
2809 SuspendPropertyTracking
aSuspend( *this );
2810 // restore the marks
2811 pFormView
->GetImpl()->restoreMarkList( aList
);
2814 // synchronize with the restored mark list
2815 if ( aList
.GetMarkCount() )
2816 SetSelection( aList
);
2820 // am Model der View als Listener anmelden (damit ich mitbekomme, wenn jemand waehrend des Alive-Modus
2821 // Controls loescht, die ich eigentlich mit saveMarkList gespeichert habe) (60343)
2822 pFormView
->GetImpl()->startMarkListWatching();
2825 m_pShell
->UIFeatureChanged();
2827 // 67506 - 15.07.99 - FS
2828 if (bDesign
&& m_bHadPropertyBrowserInDesignMode
)
2830 // The UIFeatureChanged performes an update (a check of the available features) asynchronously.
2831 // So we can't call ShowSelectionProperties directly as the according feature isn't enabled yet.
2832 // That's why we use an asynchron execution on the dispatcher.
2833 // (And that's why this has to be done AFTER the UIFeatureChanged.)
2834 m_pShell
->GetViewShell()->GetViewFrame()->GetDispatcher()->Execute( SID_FM_SHOW_PROPERTY_BROWSER
, SFX_CALLMODE_ASYNCHRON
);
2836 m_bChangingDesignMode
= sal_False
;
2839 //------------------------------------------------------------------------------
2840 Reference
< XControl
> FmXFormShell::GetControlFromModel(const Reference
< XControlModel
>& xModel
)
2842 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::GetControlFromModel" );
2843 if ( impl_checkDisposed() )
2846 Reference
< XControlContainer
> xControlContainer( getControlContainerForView() );
2848 Sequence
< Reference
< XControl
> > seqControls( xControlContainer
->getControls() );
2849 Reference
< XControl
>* pControls
= seqControls
.getArray();
2850 // ... die ich dann durchsuchen kann
2851 for (int i
=0; i
<seqControls
.getLength(); ++i
)
2853 Reference
< XControlModel
> xSearchLoopModel( pControls
[i
]->getModel());
2854 if ((XControlModel
*)xSearchLoopModel
.get() == (XControlModel
*)xModel
.get())
2855 return pControls
[i
];
2857 return Reference
< XControl
>(NULL
);
2860 //------------------------------------------------------------------------------
2861 void FmXFormShell::impl_collectFormSearchContexts_nothrow( const Reference
< XInterface
>& _rxStartingPoint
,
2862 const ::rtl::OUString
& _rCurrentLevelPrefix
, FmFormArray
& _out_rForms
, ::std::vector
< String
>& _out_rNames
)
2864 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::impl_collectFormSearchContexts_nothrow" );
2867 Reference
< XIndexAccess
> xContainer( _rxStartingPoint
, UNO_QUERY
);
2868 if ( !xContainer
.is() )
2871 sal_Int32
nCount( xContainer
->getCount() );
2875 ::rtl::OUString sCurrentFormName
;
2876 ::rtl::OUStringBuffer aNextLevelPrefix
;
2877 for ( sal_Int32 i
=0; i
<nCount
; ++i
)
2879 // is the current child a form?
2880 Reference
< XForm
> xCurrentAsForm( xContainer
->getByIndex(i
), UNO_QUERY
);
2881 if ( !xCurrentAsForm
.is() )
2884 Reference
< XNamed
> xNamed( xCurrentAsForm
, UNO_QUERY_THROW
);
2885 sCurrentFormName
= xNamed
->getName();
2887 // the name of the current form
2888 ::rtl::OUStringBuffer
sCompleteCurrentName( sCurrentFormName
);
2889 if ( _rCurrentLevelPrefix
.getLength() )
2891 sCompleteCurrentName
.appendAscii( " (" );
2892 sCompleteCurrentName
.append ( _rCurrentLevelPrefix
);
2893 sCompleteCurrentName
.appendAscii( ")" );
2896 // the prefix for the next level
2897 aNextLevelPrefix
= _rCurrentLevelPrefix
;
2898 if ( _rCurrentLevelPrefix
.getLength() )
2899 aNextLevelPrefix
.append( (sal_Unicode
)'/' );
2900 aNextLevelPrefix
.append( sCurrentFormName
);
2902 // remember both the form and it's "display name"
2903 _out_rForms
.push_back( xCurrentAsForm
);
2904 _out_rNames
.push_back( sCompleteCurrentName
.makeStringAndClear() );
2907 impl_collectFormSearchContexts_nothrow( xCurrentAsForm
, aNextLevelPrefix
.makeStringAndClear(), _out_rForms
, _out_rNames
);
2910 catch( const Exception
& )
2912 DBG_UNHANDLED_EXCEPTION();
2916 //------------------------------------------------------------------------------
2917 void FmXFormShell::startFiltering()
2919 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::startFiltering" );
2920 if ( impl_checkDisposed() )
2923 // setting all forms in filter mode
2924 FmXFormView
* pXView
= m_pShell
->GetFormView()->GetImpl();
2926 // if the active controller is our external one we have to use the trigger controller
2927 Reference
< XControlContainer
> xContainer
;
2928 if (getActiveController() == m_xExternalViewController
)
2930 DBG_ASSERT(m_xExtViewTriggerController
.is(), "FmXFormShell::startFiltering : inconsistent : active external controller, but noone triggered this !");
2931 xContainer
= m_xExtViewTriggerController
->getContainer();
2934 xContainer
= getActiveController()->getContainer();
2936 FmWinRecList::iterator i
= pXView
->findWindow(xContainer
);
2937 if (i
!= pXView
->getWindowList().end())
2939 const ::std::vector
< Reference
< XFormController
> >& rControllerList
= (*i
)->GetList();
2940 for (::std::vector
< Reference
< XFormController
> >::const_iterator j
= rControllerList
.begin();
2941 j
!= rControllerList
.end(); ++j
)
2943 Reference
< XModeSelector
> xModeSelector(*j
, UNO_QUERY
);
2944 if (xModeSelector
.is())
2945 xModeSelector
->setMode(FILTER_MODE
);
2949 m_bFilterMode
= sal_True
;
2951 m_pShell
->UIFeatureChanged();
2952 m_pShell
->GetViewShell()->GetViewFrame()->GetBindings().InvalidateShell(*m_pShell
);
2955 //------------------------------------------------------------------------------
2956 void saveFilter(const Reference
< XFormController
>& _rxController
)
2958 Reference
< XPropertySet
> xFormAsSet(_rxController
->getModel(), UNO_QUERY
);
2959 Reference
< XPropertySet
> xControllerAsSet(_rxController
, UNO_QUERY
);
2960 Reference
< XIndexAccess
> xControllerAsIndex(_rxController
, UNO_QUERY
);
2962 // call the subcontroller
2963 Reference
< XFormController
> xController
;
2964 for (sal_Int32 i
= 0, nCount
= xControllerAsIndex
->getCount(); i
< nCount
; ++i
)
2966 xControllerAsIndex
->getByIndex(i
) >>= xController
;
2967 saveFilter(xController
);
2973 xFormAsSet
->setPropertyValue(FM_PROP_FILTER
, xControllerAsSet
->getPropertyValue(FM_PROP_FILTER
));
2974 xFormAsSet
->setPropertyValue(FM_PROP_APPLYFILTER
, makeAny( (sal_Bool
)sal_True
) );
2976 catch (const Exception
& )
2978 DBG_UNHANDLED_EXCEPTION();
2983 //------------------------------------------------------------------------------
2984 void FmXFormShell::stopFiltering(sal_Bool bSave
)
2986 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::stopFiltering" );
2987 if ( impl_checkDisposed() )
2990 m_bFilterMode
= sal_False
;
2992 FmXFormView
* pXView
= m_pShell
->GetFormView()->GetImpl();
2994 // if the active controller is our external one we have to use the trigger controller
2995 Reference
< XControlContainer
> xContainer
;
2996 if (getActiveController() == m_xExternalViewController
)
2998 DBG_ASSERT(m_xExtViewTriggerController
.is(), "FmXFormShell::startFiltering : inconsistent : active external controller, but noone triggered this !");
2999 xContainer
= m_xExtViewTriggerController
->getContainer();
3002 xContainer
= getActiveController()->getContainer();
3004 FmWinRecList::iterator i
= pXView
->findWindow(xContainer
);
3005 if (i
!= pXView
->getWindowList().end())
3007 const ::std::vector
< Reference
< XFormController
> >& rControllerList
= (*i
)->GetList();
3008 ::std::vector
< ::rtl::OUString
> aOriginalFilters
;
3009 ::std::vector
< sal_Bool
> aOriginalApplyFlags
;
3013 for (::std::vector
< Reference
< XFormController
> > ::const_iterator j
= rControllerList
.begin();
3014 j
!= rControllerList
.end(); ++j
)
3017 { // remember the current filter settings in case we're goin to reload the forms below (which may fail)
3020 Reference
< XPropertySet
> xFormAsSet((*j
)->getModel(), UNO_QUERY
);
3021 aOriginalFilters
.push_back(::comphelper::getString(xFormAsSet
->getPropertyValue(FM_PROP_FILTER
)));
3022 aOriginalApplyFlags
.push_back(::comphelper::getBOOL(xFormAsSet
->getPropertyValue(FM_PROP_APPLYFILTER
)));
3026 DBG_ERROR("FmXFormShell::stopFiltering : could not get the original filter !");
3027 // put dummies into the arrays so the they have the right size
3029 if (aOriginalFilters
.size() == aOriginalApplyFlags
.size())
3030 // the first getPropertyValue failed -> use two dummies
3031 aOriginalFilters
.push_back( ::rtl::OUString() );
3032 aOriginalApplyFlags
.push_back( sal_False
);
3038 for (::std::vector
< Reference
< XFormController
> > ::const_iterator j
= rControllerList
.begin();
3039 j
!= rControllerList
.end(); ++j
)
3042 Reference
< XModeSelector
> xModeSelector(*j
, UNO_QUERY
);
3043 if (xModeSelector
.is())
3044 xModeSelector
->setMode(DATA_MODE
);
3046 if (bSave
) // execute the filter
3048 const ::std::vector
< Reference
< XFormController
> > & rControllers
= (*i
)->GetList();
3049 for (::std::vector
< Reference
< XFormController
> > ::const_iterator j
= rControllers
.begin();
3050 j
!= rControllers
.end(); ++j
)
3052 Reference
< XLoadable
> xReload((*j
)->getModel(), UNO_QUERY
);
3055 Reference
< XPropertySet
> xFormSet(xReload
, UNO_QUERY
);
3063 DBG_ERROR("FmXFormShell::stopFiltering: Exception occured!");
3066 if (!isRowSetAlive(xFormSet
))
3067 { // something went wrong -> restore the original state
3068 ::rtl::OUString sOriginalFilter
= aOriginalFilters
[ j
- rControllers
.begin() ];
3069 sal_Bool bOriginalApplyFlag
= aOriginalApplyFlags
[ j
- rControllers
.begin() ];
3072 xFormSet
->setPropertyValue(FM_PROP_FILTER
, makeAny(sOriginalFilter
));
3073 xFormSet
->setPropertyValue(FM_PROP_APPLYFILTER
, makeAny(bOriginalApplyFlag
));
3076 catch(const Exception
&)
3078 DBG_UNHANDLED_EXCEPTION();
3085 m_pShell
->UIFeatureChanged();
3086 m_pShell
->GetViewShell()->GetViewFrame()->GetBindings().InvalidateShell(*m_pShell
);
3089 //------------------------------------------------------------------------------
3090 void clearFilter(const Reference
< XFormController
>& _rxController
)
3092 Reference
< XPropertySet
> xControllerAsSet(_rxController
, UNO_QUERY
);
3093 Reference
< XIndexAccess
> xControllerAsIndex(_rxController
, UNO_QUERY
);
3095 // call the subcontroller
3096 Reference
< XFormController
> xController
;
3097 for (sal_Int32 i
= 0, nCount
= xControllerAsIndex
->getCount();
3100 xControllerAsIndex
->getByIndex(i
) >>= xController
;
3101 clearFilter(xController
);
3105 Reference
< XIndexContainer
> xContainer
;
3106 xControllerAsSet
->getPropertyValue(FM_PROP_FILTERSUPPLIER
) >>= xContainer
;
3107 if (xContainer
.is())
3109 // clear the current filter
3110 Sequence
< PropertyValue
> aCondition
;
3112 // as there is always an empty row, if we have a filter:
3113 if (xContainer
->getCount())
3115 xControllerAsSet
->setPropertyValue(FM_PROP_CURRENTFILTER
, makeAny(sal_Int32(xContainer
->getCount() - 1)));
3116 while (xContainer
->getCount() > 1)
3117 xContainer
->removeByIndex(0);
3122 //------------------------------------------------------------------------------
3123 void FmXFormShell::clearFilter()
3125 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::clearFilter" );
3126 if ( impl_checkDisposed() )
3129 FmXFormView
* pXView
= m_pShell
->GetFormView()->GetImpl();
3131 // if the active controller is our external one we have to use the trigger controller
3132 Reference
< XControlContainer
> xContainer
;
3133 if (getActiveController() == m_xExternalViewController
)
3135 DBG_ASSERT(m_xExtViewTriggerController
.is(), "FmXFormShell::startFiltering : inconsistent : active external controller, but noone triggered this !");
3136 xContainer
= m_xExtViewTriggerController
->getContainer();
3139 xContainer
= getActiveController()->getContainer();
3141 FmWinRecList::iterator i
= pXView
->findWindow(xContainer
);
3142 if (i
!= pXView
->getWindowList().end())
3144 const ::std::vector
< Reference
< XFormController
> > & rControllerList
= (*i
)->GetList();
3145 for (::std::vector
< Reference
< XFormController
> > ::const_iterator j
= rControllerList
.begin();
3146 j
!= rControllerList
.end(); ++j
)
3153 //------------------------------------------------------------------------------
3154 void FmXFormShell::setControlLocks()
3156 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::setControlLocks" );
3157 if ( impl_checkDisposed() )
3160 Reference
< XTabController
> xCtrler(getActiveController(), UNO_QUERY
);
3164 Reference
< XControlContainer
> xControls(xCtrler
->getContainer(), UNO_QUERY
);
3165 if (!xControls
.is())
3168 DBG_ASSERT( m_aControlLocks
.empty(), "FmXFormShell::setControlLocks: locking state array isn't empty (called me twice ?)!" );
3170 Sequence
< Reference
< XControl
> > aControls
= xControls
->getControls();
3171 const Reference
< XControl
>* pControls
= aControls
.getConstArray();
3173 // iterate through all bound controls, remember the old locking state, set the lock
3174 for (sal_Int32 i
=0; i
<aControls
.getLength(); ++i
)
3176 Reference
< XBoundControl
> xCtrl(pControls
[i
], UNO_QUERY
);
3179 // it may be a container of controls
3180 Reference
< XIndexAccess
> xContainer(pControls
[i
], UNO_QUERY
);
3181 if (xContainer
.is())
3182 { // no recursion. we only know top level control containers (e.g. grid controls)
3183 for (sal_Int16 j
=0; j
<xContainer
->getCount(); ++j
)
3185 xContainer
->getByIndex(j
) >>= xCtrl
;
3189 m_aControlLocks
.push_back( xCtrl
->getLock() );
3190 xCtrl
->setLock(sal_True
);
3196 m_aControlLocks
.push_back( xCtrl
->getLock() );
3197 xCtrl
->setLock(sal_True
);
3201 //------------------------------------------------------------------------------
3202 void FmXFormShell::restoreControlLocks()
3204 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::restoreControlLocks" );
3205 if ( impl_checkDisposed() )
3208 Reference
< XTabController
> xCtrler(getActiveController(), UNO_QUERY
);
3212 Reference
< XControlContainer
> xControls(xCtrler
->getContainer(), UNO_QUERY
);
3213 if (!xControls
.is())
3216 Sequence
< Reference
< XControl
> > aControls(xControls
->getControls());
3217 const Reference
< XControl
>* pControls
= aControls
.getConstArray();
3219 // iterate through all bound controls, restore the old locking state
3220 size_t nBoundControl
= 0;
3221 for (sal_Int32 i
=0; i
<aControls
.getLength(); ++i
)
3223 Reference
< XBoundControl
> xCtrl(pControls
[i
], UNO_QUERY
);
3226 // it may be a container of controls
3227 Reference
< XIndexAccess
> xContainer(pControls
[i
], UNO_QUERY
);
3228 if (xContainer
.is())
3229 { // no recursion. we only know top level control containers (e.g. grid controls)
3230 for (sal_Int16 j
=0; j
<xContainer
->getCount(); ++j
)
3232 xContainer
->getByIndex(j
) >>= xCtrl
;
3236 DBG_ASSERT( nBoundControl
< m_aControlLocks
.size(), "FmXFormShell::restoreControlLocks: m_aControlLocks is invalid!" );
3237 xCtrl
->setLock( m_aControlLocks
[ nBoundControl
] );
3244 DBG_ASSERT( nBoundControl
< m_aControlLocks
.size(), "FmXFormShell::restoreControlLocks: m_aControlLocks is invalid!" );
3245 // a violation of this condition would mean a) setControlLocks hasn't been called or b) the ControlContainer
3246 // has changed since the last call to setControlLocks.
3247 // a) clearly is a fault of the programmer and b) shouldn't be possible (as we are in alive mode)
3248 xCtrl
->setLock( m_aControlLocks
[ nBoundControl
] );
3251 ::std::vector
< sal_Bool
> aEmpty
;
3252 m_aControlLocks
.swap( aEmpty
);
3255 //------------------------------------------------------------------------------
3256 void FmXFormShell::DoAsyncCursorAction(const Reference
< XFormController
>& _xController
, CURSOR_ACTION _eWhat
)
3258 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::DoAsyncCursorAction" );
3259 if ( impl_checkDisposed() )
3262 DBG_ASSERT(_xController
.is(), "FmXFormShell::DoAsyncCursorAction : invalid argument !");
3263 DoAsyncCursorAction(Reference
< XResultSet
>(_xController
->getModel(), UNO_QUERY
), _eWhat
);
3266 //------------------------------------------------------------------------------
3267 void FmXFormShell::DoAsyncCursorAction(const Reference
< XResultSet
>& _xForm
, CURSOR_ACTION _eWhat
)
3269 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::DoAsyncCursorAction" );
3270 if ( impl_checkDisposed() )
3273 ::osl::MutexGuard
aGuard(m_aAsyncSafety
);
3274 DBG_ASSERT(_xForm
.is(), "FmXFormShell::DoAsyncCursorAction : invalid argument !");
3276 // build the access path for the form
3277 if (HasPendingCursorAction(_xForm
))
3279 DBG_ERROR("FmXFormShell::DoAsyncCursorAction : invalid call !");
3283 CursorActionDescription
& rDesc
= m_aCursorActions
[ _xForm
];
3284 // [] will create a new one if non-existent
3285 DBG_ASSERT(rDesc
.pThread
== NULL
, "FmXFormShell::DoAsyncCursorAction : the cursor action thread for this form is still alive !");
3287 Reference
< XResultSet
> xCursor( getInternalForm( _xForm
), UNO_QUERY
);
3290 case CA_MOVE_TO_LAST
:
3291 rDesc
.pThread
= new FmMoveToLastThread( xCursor
);
3293 case CA_MOVE_ABSOLUTE
:
3294 DBG_ERROR("FmXFormShell::DoAsyncCursorAction : CA_MOVE_ABSOLUTE not supported yet !");
3297 rDesc
.pThread
->SetTerminationHdl(LINK(this, FmXFormShell
, OnCursorActionDone
));
3298 rDesc
.pThread
->EnableSelfDelete(sal_False
);
3300 rDesc
.bCanceling
= sal_False
;
3302 // set the control locks before starting the thread
3303 DBG_ASSERT(getInternalForm(m_xActiveForm
) == m_xActiveForm
, "FmXFormShell::DoAsyncCursorAction : the active form should always be a internal one !");
3304 if (getInternalForm(_xForm
) == m_xActiveForm
)
3308 rDesc
.pThread
->create();
3310 // set a priority slightly below normal
3311 rDesc
.pThread
->setPriority(::vos::OThread::TPriority_BelowNormal
);
3314 //------------------------------------------------------------------------------
3315 sal_Bool
FmXFormShell::HasPendingCursorAction(const Reference
< XResultSet
>& _xForm
) const
3317 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::HasPendingCursorAction" );
3318 if ( impl_checkDisposed() )
3324 // TODO: if we ever re-implement the asynchronous cursor actions, then this will happen
3325 // in the controller, and not in the form. In such a case, we here probably need to check
3326 // whether the controller for the form has this "pending cursor action"
3331 //------------------------------------------------------------------------------
3332 sal_Bool
FmXFormShell::HasPendingCursorAction(const Reference
< XFormController
>& xController
) const
3334 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::HasPendingCursorAction" );
3335 if ( impl_checkDisposed() )
3338 if (!xController
.is())
3341 return HasPendingCursorAction(Reference
< XResultSet
>(xController
->getModel(), UNO_QUERY
));
3344 //------------------------------------------------------------------------------
3345 sal_Bool
FmXFormShell::HasAnyPendingCursorAction() const
3347 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::HasAnyPendingCursorAction" );
3348 ::osl::MutexGuard
aGuard( const_cast< FmXFormShell
* >( this )->m_aAsyncSafety
);
3350 for ( CursorActions::const_iterator aIter
= m_aCursorActions
.begin(); aIter
!= m_aCursorActions
.end(); ++aIter
)
3352 if (((*aIter
).second
.pThread
!= NULL
) || ((*aIter
).second
.nFinishedEvent
!= 0))
3358 //------------------------------------------------------------------------------
3359 void FmXFormShell::CancelAnyPendingCursorAction()
3361 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::CancelAnyPendingCursorAction" );
3362 if ( impl_checkDisposed() )
3365 ::osl::ResettableMutexGuard
aGuard( m_aAsyncSafety
);
3367 CursorActions::iterator aIter
;
3368 for (aIter
= m_aCursorActions
.begin(); aIter
!= m_aCursorActions
.end(); ++aIter
)
3370 if (!(*aIter
).second
.nFinishedEvent
&& (*aIter
).second
.pThread
)
3371 { // the thread is really running
3372 (*aIter
).second
.bCanceling
= sal_True
;
3375 (*aIter
).second
.pThread
->StopItWait();
3376 // StopItWait returns after the termination handler (our OnCursorActionDone) has been called
3381 // all threads are finished (means canceled), now do the cleanup
3382 for (aIter
= m_aCursorActions
.begin(); aIter
!= m_aCursorActions
.end(); ++aIter
)
3384 if ((*aIter
).second
.pThread
)
3386 LINK(this, FmXFormShell
, OnCursorActionDoneMainThread
).Call((*aIter
).second
.pThread
);
3387 DBG_ASSERT((*aIter
).second
.pThread
== NULL
, "FmXFormShell::CancelAnyPendingCursorAction : strange behaviour of OnCursorActionDoneMainThread !");
3392 //------------------------------------------------------------------------------
3393 IMPL_LINK(FmXFormShell
, OnCursorActionDone
, FmCursorActionThread
*, pThread
)
3395 if ( impl_checkDisposed() )
3398 ::osl::MutexGuard
aGuard(m_aAsyncSafety
);
3400 // search the pos of the thread within m_aCursorActions
3401 CursorActions::iterator aIter
;
3402 for (aIter
= m_aCursorActions
.begin(); aIter
!= m_aCursorActions
.end(); ++aIter
)
3404 if ((*aIter
).second
.pThread
== pThread
)
3408 DBG_ASSERT(aIter
!= m_aCursorActions
.end(), "FmXFormShell::OnCursorActionDone : could not ::std::find the thread !");
3409 DBG_ASSERT((*aIter
).second
.nFinishedEvent
== 0, "FmXFormShell::OnCursorActionDone : another 'ActionDone' for this thread is pending !");
3410 // as we allow only one async action at a time (per form) this shouldn't happen
3412 if (!(*aIter
).second
.bCanceling
)
3413 (*aIter
).second
.nFinishedEvent
= Application::PostUserEvent(LINK(this, FmXFormShell
, OnCursorActionDoneMainThread
), pThread
);
3414 // if bCanceling is sal_True an other thread's execution is in CancelAnyPendingCursorAction
3418 //------------------------------------------------------------------------------
3419 IMPL_LINK(FmXFormShell
, OnCursorActionDoneMainThread
, FmCursorActionThread
*, pThread
)
3421 if ( impl_checkDisposed() )
3424 ::osl::MutexGuard
aGuard(m_aAsyncSafety
);
3426 // search the pos of the thread within m_aCursorActions
3427 CursorActions::iterator aIter
= m_aCursorActions
.find( pThread
->getDataSource() );
3428 DBG_ASSERT(aIter
!= m_aCursorActions
.end(), "FmXFormShell::OnCursorActionDoneMainThread : could not ::std::find the thread data !");
3429 DBG_ASSERT((*aIter
).second
.pThread
== pThread
, "FmXFormShell::OnCursorActionDoneMainThread : invalid thread data !");
3431 // remember some thread parameters
3432 Reference
< XResultSet
> xForm(pThread
->getDataSource(), UNO_QUERY
);
3434 // throw away the thread
3435 delete (*aIter
).second
.pThread
;
3436 (*aIter
).second
.pThread
= NULL
;
3437 (*aIter
).second
.nFinishedEvent
= 0;
3438 (*aIter
).second
.bCanceling
= sal_False
;
3439 // as we allow exactly one thread per form we may remove this ones data from m_aCursorActions
3440 m_aCursorActions
.erase(aIter
);
3442 DBG_ASSERT(getInternalForm(m_xActiveForm
) == m_xActiveForm
, "FmXFormShell::DoAsyncCursorAction : the active form should always be a internal one !");
3443 DBG_ASSERT(getInternalForm(xForm
) == xForm
, "FmXFormShell::DoAsyncCursorAction : the thread's form should always be a internal one !");
3444 // if one of the two asserts above fails the upcoming comparison is senseless
3445 if (xForm
== m_xActiveForm
)
3447 // the active controller belongs to the form where the action is finished
3448 // -> re-enable the controls if they are not locked because of another running thread
3449 if (!HasPendingCursorAction(xForm
))
3450 restoreControlLocks();
3453 m_pShell
->GetViewShell()->GetViewFrame()->GetBindings().Invalidate(DatabaseSlotMap
);
3454 // it may not be neccessary but me thinks it's faster without the check if we really have to do this
3459 //------------------------------------------------------------------------------
3460 void FmXFormShell::CreateExternalView()
3462 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::CreateExternalView" );
3463 if ( impl_checkDisposed() )
3466 DBG_ASSERT(m_xAttachedFrame
.is(), "FmXFormShell::CreateExternalView : no frame !");
3468 // the frame the external view is displayed in
3469 sal_Bool bAlreadyExistent
= m_xExternalViewController
.is();
3470 Reference
< ::com::sun::star::frame::XFrame
> xExternalViewFrame
;
3471 ::rtl::OUString sFrameName
= ::rtl::OUString::createFromAscii("_beamer");
3472 sal_Int32 nSearchFlags
= ::com::sun::star::frame::FrameSearchFlag::CHILDREN
| ::com::sun::star::frame::FrameSearchFlag::CREATE
;
3474 Reference
< XFormController
> xCurrentNavController( getNavController());
3475 // the creation of the "partwindow" may cause a deactivate of the document which will result in our nav controller to be set to NULL
3477 // _first_ check if we have any valid fields we can use for the grid view
3478 // FS - 21.10.99 - 69219
3480 FmXBoundFormFieldIterator
aModelIterator(xCurrentNavController
->getModel());
3481 Reference
< XPropertySet
> xCurrentModelSet
;
3482 sal_Bool bHaveUsableControls
= sal_False
;
3483 while ((xCurrentModelSet
= Reference
< XPropertySet
>(aModelIterator
.Next(), UNO_QUERY
)).is())
3485 // the FmXBoundFormFieldIterator only supplies controls with a valid control source
3486 // so we just have to check the field type
3487 sal_Int16 nClassId
= ::comphelper::getINT16(xCurrentModelSet
->getPropertyValue(FM_PROP_CLASSID
));
3490 case FormComponentType::IMAGECONTROL
:
3491 case FormComponentType::CONTROL
:
3494 bHaveUsableControls
= sal_True
;
3498 if (!bHaveUsableControls
)
3500 ErrorBox(NULL
, WB_OK
, SVX_RESSTR(RID_STR_NOCONTROLS_FOR_EXTERNALDISPLAY
)).Execute();
3505 // load the component for external form views
3506 if (!bAlreadyExistent
)
3508 URL aWantToDispatch
;
3509 aWantToDispatch
.Complete
= FMURL_COMPONENT_FORMGRIDVIEW
;
3511 Reference
< ::com::sun::star::frame::XDispatchProvider
> xProv(m_xAttachedFrame
, UNO_QUERY
);
3512 Reference
< ::com::sun::star::frame::XDispatch
> xDisp
;
3514 xDisp
= xProv
->queryDispatch(aWantToDispatch
, sFrameName
, nSearchFlags
);
3517 xDisp
->dispatch(aWantToDispatch
, Sequence
< PropertyValue
>());
3520 // with this the component should be loaded, now search the frame where it resides in
3521 xExternalViewFrame
= m_xAttachedFrame
->findFrame(sFrameName
, ::com::sun::star::frame::FrameSearchFlag::CHILDREN
);
3522 if (xExternalViewFrame
.is())
3524 m_xExternalViewController
= xExternalViewFrame
->getController();
3525 Reference
< ::com::sun::star::lang::XComponent
> xComp(m_xExternalViewController
, UNO_QUERY
);
3527 xComp
->addEventListener((XEventListener
*)(XPropertyChangeListener
*)this);
3532 xExternalViewFrame
= m_xExternalViewController
->getFrame();
3533 Reference
< ::com::sun::star::frame::XDispatchProvider
> xCommLink(xExternalViewFrame
, UNO_QUERY
);
3535 // if we display the active form we interpret the slot as "remove it"
3536 Reference
< XForm
> xCurrentModel(xCurrentNavController
->getModel(), UNO_QUERY
);
3537 if ((xCurrentModel
== m_xExternalDisplayedForm
) || (getInternalForm(xCurrentModel
) == m_xExternalDisplayedForm
))
3539 if ( m_xExternalViewController
== getActiveController() )
3541 Reference
< XFormController
> xAsFormController( m_xExternalViewController
, UNO_QUERY
);
3542 ControllerFeatures
aHelper( ::comphelper::getProcessServiceFactory(), xAsFormController
, NULL
);
3543 aHelper
->commitCurrentControl();
3546 Reference
< XFormController
> xNewController(m_xExtViewTriggerController
);
3547 CloseExternalFormViewer();
3548 setActiveController(xNewController
);
3553 aClearURL
.Complete
= FMURL_GRIDVIEW_CLEARVIEW
;
3555 Reference
< ::com::sun::star::frame::XDispatch
> xClear( xCommLink
->queryDispatch(aClearURL
, ::rtl::OUString::createFromAscii(""), 0));
3557 xClear
->dispatch(aClearURL
, Sequence
< PropertyValue
>());
3560 // interception of slots of the external view
3561 if (m_pExternalViewInterceptor
)
3562 { // already intercepting ...
3563 if (m_pExternalViewInterceptor
->getIntercepted() != xExternalViewFrame
)
3564 { // ... but another frame -> create a new interceptor
3565 m_pExternalViewInterceptor
->dispose();
3566 m_pExternalViewInterceptor
->release();
3567 m_pExternalViewInterceptor
= NULL
;
3571 if (!m_pExternalViewInterceptor
)
3573 Reference
< ::com::sun::star::frame::XDispatchProviderInterception
> xSupplier(xExternalViewFrame
, UNO_QUERY
);
3574 ::rtl::OUString sInterceptorScheme
= FMURL_FORMSLOTS_PREFIX
;
3575 sInterceptorScheme
+= ::rtl::OUString::createFromAscii("*");
3576 // m_pExternalViewInterceptor = new FmXDispatchInterceptorImpl(xSupplier, this, 1, Sequence< ::rtl::OUString >(&sInterceptorScheme, 1));
3577 // m_pExternalViewInterceptor->acquire();
3578 // TODO: re-implement this in a easier way than before: We need an interceptor at the xSupplier, which
3579 // forwards all queryDispatch requests to the FormController instance for which this "external view"
3583 // get the dispatch interface of the frame so we can communicate (interceptable) with the controller
3584 Reference
< ::com::sun::star::frame::XDispatchProvider
> xCommLink(xExternalViewFrame
, UNO_QUERY
);
3586 if (m_xExternalViewController
.is())
3588 DBG_ASSERT(xCommLink
.is(), "FmXFormShell::CreateExternalView : the component doesn't have the necessary interfaces !");
3589 // collect the dispatchers we will need
3591 aAddColumnURL
.Complete
= FMURL_GRIDVIEW_ADDCOLUMN
;
3592 Reference
< ::com::sun::star::frame::XDispatch
> xAddColumnDispatch( xCommLink
->queryDispatch(aAddColumnURL
, ::rtl::OUString::createFromAscii(""), 0));
3594 aAttachURL
.Complete
= FMURL_GRIDVIEW_ATTACHTOFORM
;
3595 Reference
< ::com::sun::star::frame::XDispatch
> xAttachDispatch( xCommLink
->queryDispatch(aAttachURL
, ::rtl::OUString::createFromAscii(""), 0));
3597 if (xAddColumnDispatch
.is() && xAttachDispatch
.is())
3599 DBG_ASSERT(xCurrentNavController
.is(), "FmXFormShell::CreateExternalView : invalid call : have no nav controller !");
3600 // first : dispatch the descriptions for the columns to add
3601 Sequence
< Reference
< XControl
> > aCurrentControls(xCurrentNavController
->getControls());
3603 sal_Int16 nAddedColumns
= 0;
3605 // for radio buttons we need some special structures
3606 DECLARE_STL_USTRINGACCESS_MAP(Sequence
< ::rtl::OUString
>, MapUString2UstringSeq
);
3607 DECLARE_STL_ITERATORS(MapUString2UstringSeq
);
3608 DECLARE_STL_USTRINGACCESS_MAP(::rtl::OUString
, FmMapUString2UString
);
3609 DECLARE_STL_USTRINGACCESS_MAP(sal_Int16
, FmMapUString2Int16
);
3610 DECLARE_STL_ITERATORS(FmMapUString2Int16
);
3612 MapUString2UstringSeq aRadioValueLists
;
3613 MapUString2UstringSeq aRadioListSources
;
3614 FmMapUString2UString aRadioControlSources
;
3615 FmMapUString2Int16 aRadioPositions
;
3617 FmXBoundFormFieldIterator
aModelIterator(xCurrentNavController
->getModel());
3618 Reference
< XPropertySet
> xCurrentModelSet
;
3619 Any aCurrentBoundField
;
3620 ::rtl::OUString sColumnType
,aGroupName
,sControlSource
;
3621 Sequence
< Property
> aProps
;
3622 Reference
< XPropertySet
> xCurrentBoundField
;
3623 while ((xCurrentModelSet
= Reference
< XPropertySet
>(aModelIterator
.Next(), UNO_QUERY
)).is())
3625 xCurrentModelSet
->getPropertyValue(FM_PROP_BOUNDFIELD
) >>= xCurrentBoundField
;
3626 OSL_ENSURE(xCurrentModelSet
.is(),"xCurrentModelSet is null!");
3627 // create a description of the column to be created
3628 // first : determine it's type
3630 sal_Int16 nClassId
= ::comphelper::getINT16(xCurrentModelSet
->getPropertyValue(FM_PROP_CLASSID
));
3633 case FormComponentType::RADIOBUTTON
:
3635 // get the label of the button (this is the access key for our structures)
3636 aGroupName
= getLabelName(xCurrentModelSet
);
3638 // add the reference value of the radio button to the list source sequence
3639 Sequence
< ::rtl::OUString
>& aThisGroupLabels
= aRadioListSources
[aGroupName
];
3640 sal_Int32 nNewSizeL
= aThisGroupLabels
.getLength() + 1;
3641 aThisGroupLabels
.realloc(nNewSizeL
);
3642 aThisGroupLabels
.getArray()[nNewSizeL
- 1] = ::comphelper::getString(xCurrentModelSet
->getPropertyValue(FM_PROP_REFVALUE
));
3644 // add the label to the value list sequence
3645 Sequence
< ::rtl::OUString
>& aThisGroupControlSources
= aRadioValueLists
[aGroupName
];
3646 sal_Int32 nNewSizeC
= aThisGroupControlSources
.getLength() + 1;
3647 aThisGroupControlSources
.realloc(nNewSizeC
);
3648 aThisGroupControlSources
.getArray()[nNewSizeC
- 1] = ::comphelper::getString(xCurrentModelSet
->getPropertyValue(FM_PROP_LABEL
));
3650 // remember the controls source of the radio group
3651 sControlSource
= ::comphelper::getString(xCurrentModelSet
->getPropertyValue(FM_PROP_CONTROLSOURCE
));
3652 if (aRadioControlSources
.find(aGroupName
) == aRadioControlSources
.end())
3653 aRadioControlSources
[aGroupName
] = sControlSource
;
3656 DBG_ASSERT(aRadioControlSources
[aGroupName
] == sControlSource
,
3657 "FmXFormShell::CreateExternalView : inconsistent radio buttons detected !");
3658 // (radio buttons with the same name should have the same control source)
3660 // remember the position within the columns
3661 if (aRadioPositions
.find(aGroupName
) == aRadioPositions
.end())
3662 aRadioPositions
[aGroupName
] = (sal_Int16
)nAddedColumns
;
3664 // any further handling is done below
3668 case FormComponentType::IMAGECONTROL
:
3669 case FormComponentType::CONTROL
:
3670 // no grid columns for these types (though they have a control source)
3672 case FormComponentType::CHECKBOX
:
3673 sColumnType
= FM_COL_CHECKBOX
; break;
3674 case FormComponentType::LISTBOX
:
3675 sColumnType
= FM_COL_LISTBOX
; break;
3676 case FormComponentType::COMBOBOX
:
3677 sColumnType
= FM_COL_COMBOBOX
; break;
3678 case FormComponentType::DATEFIELD
:
3679 sColumnType
= FM_COL_DATEFIELD
; break;
3680 case FormComponentType::TIMEFIELD
:
3681 sColumnType
= FM_COL_TIMEFIELD
; break;
3682 case FormComponentType::NUMERICFIELD
:
3683 sColumnType
= FM_COL_NUMERICFIELD
; break;
3684 case FormComponentType::CURRENCYFIELD
:
3685 sColumnType
= FM_COL_CURRENCYFIELD
; break;
3686 case FormComponentType::PATTERNFIELD
:
3687 sColumnType
= FM_COL_PATTERNFIELD
; break;
3689 case FormComponentType::TEXTFIELD
:
3691 sColumnType
= FM_COL_TEXTFIELD
;
3692 // we know at least two different controls which are TextFields : the basic edit field and the formatted
3693 // field. we distinguish them by their service name
3694 Reference
< XServiceInfo
> xInfo(xCurrentModelSet
, UNO_QUERY
);
3697 sal_Int16 nObjectType
= getControlTypeByObject(xInfo
);
3698 if (OBJ_FM_FORMATTEDFIELD
== nObjectType
)
3699 sColumnType
= FM_COL_FORMATTEDFIELD
;
3704 sColumnType
= FM_COL_TEXTFIELD
; break;
3707 const sal_Int16 nDispatchArgs
= 3;
3708 Sequence
< PropertyValue
> aDispatchArgs(nDispatchArgs
);
3709 PropertyValue
* pDispatchArgs
= aDispatchArgs
.getArray();
3711 // properties describing "meta data" about the column
3713 pDispatchArgs
->Name
= FMARG_ADDCOL_COLUMNTYPE
;
3714 pDispatchArgs
->Value
<<= sColumnType
;
3717 // the pos : append the col
3718 pDispatchArgs
->Name
= FMARG_ADDCOL_COLUMNPOS
;
3719 pDispatchArgs
->Value
<<= nAddedColumns
;
3722 // the properties to forward to the new column
3723 Sequence
< PropertyValue
> aColumnProps(1);
3724 PropertyValue
* pColumnProps
= aColumnProps
.getArray();
3727 pColumnProps
->Name
= FM_PROP_LABEL
;
3728 pColumnProps
->Value
<<= getLabelName(xCurrentModelSet
);
3731 // for all other props : transfer them
3732 Reference
< XPropertySetInfo
> xControlModelInfo( xCurrentModelSet
->getPropertySetInfo());
3733 DBG_ASSERT(xControlModelInfo
.is(), "FmXFormShell::CreateExternalView : the control model has no property info ! This will crash !");
3734 aProps
= xControlModelInfo
->getProperties();
3735 const Property
* pProps
= aProps
.getConstArray();
3737 // realloc the control description sequence
3738 sal_Int32 nExistentDescs
= pColumnProps
- aColumnProps
.getArray();
3739 aColumnProps
.realloc(nExistentDescs
+ aProps
.getLength());
3740 pColumnProps
= aColumnProps
.getArray() + nExistentDescs
;
3742 for (sal_Int32 i
=0; i
<aProps
.getLength(); ++i
, ++pProps
)
3744 if (pProps
->Name
.equals(FM_PROP_LABEL
))
3747 if (pProps
->Name
.equals(FM_PROP_DEFAULTCONTROL
))
3748 // allow the column's own "default control"
3750 if (pProps
->Attributes
& PropertyAttribute::READONLY
)
3751 // assume that properties which are readonly for the control are ro for the column to be created, too
3754 pColumnProps
->Name
= pProps
->Name
;
3755 pColumnProps
->Value
= xCurrentModelSet
->getPropertyValue(pProps
->Name
);
3758 aColumnProps
.realloc(pColumnProps
- aColumnProps
.getArray());
3760 // columns props are a dispatch argument
3761 pDispatchArgs
->Name
= ::rtl::OUString::createFromAscii("ColumnProperties"); // TODO : fmurl.*
3762 pDispatchArgs
->Value
= makeAny(aColumnProps
);
3764 DBG_ASSERT(nDispatchArgs
== (pDispatchArgs
- aDispatchArgs
.getConstArray()),
3765 "FmXFormShell::CreateExternalView : forgot to adjust nDispatchArgs ?");
3767 // dispatch the "add column"
3768 xAddColumnDispatch
->dispatch(aAddColumnURL
, aDispatchArgs
);
3772 // now for the radio button handling
3773 sal_Int16
nOffset(0);
3774 // properties describing the "direct" column properties
3775 const sal_Int16 nListBoxDescription
= 6;
3776 Sequence
< PropertyValue
> aListBoxDescription(nListBoxDescription
);
3777 for ( ConstFmMapUString2UStringIterator aCtrlSource
= aRadioControlSources
.begin();
3778 aCtrlSource
!= aRadioControlSources
.end();
3779 ++aCtrlSource
, ++nOffset
3783 PropertyValue
* pListBoxDescription
= aListBoxDescription
.getArray();
3785 pListBoxDescription
->Name
= FM_PROP_LABEL
;
3786 pListBoxDescription
->Value
<<= (*aCtrlSource
).first
;
3787 ++pListBoxDescription
;
3790 pListBoxDescription
->Name
= FM_PROP_CONTROLSOURCE
;
3791 pListBoxDescription
->Value
<<= (*aCtrlSource
).second
;
3792 ++pListBoxDescription
;
3795 pListBoxDescription
->Name
= FM_PROP_BOUNDCOLUMN
;
3796 pListBoxDescription
->Value
<<= (sal_Int16
)1;
3797 ++pListBoxDescription
;
3800 pListBoxDescription
->Name
= FM_PROP_LISTSOURCETYPE
;
3801 ListSourceType eType
= ListSourceType_VALUELIST
;
3802 pListBoxDescription
->Value
= makeAny(eType
);
3803 ++pListBoxDescription
;
3806 MapUString2UstringSeq::const_iterator aCurrentListSource
= aRadioListSources
.find((*aCtrlSource
).first
);
3807 DBG_ASSERT(aCurrentListSource
!= aRadioListSources
.end(),
3808 "FmXFormShell::CreateExternalView : inconsistent radio descriptions !");
3809 pListBoxDescription
->Name
= FM_PROP_LISTSOURCE
;
3810 pListBoxDescription
->Value
= makeAny((*aCurrentListSource
).second
);
3811 ++pListBoxDescription
;
3814 MapUString2UstringSeq::const_iterator aCurrentValueList
= aRadioValueLists
.find((*aCtrlSource
).first
);
3815 DBG_ASSERT(aCurrentValueList
!= aRadioValueLists
.end(),
3816 "FmXFormShell::CreateExternalView : inconsistent radio descriptions !");
3817 pListBoxDescription
->Name
= FM_PROP_STRINGITEMLIST
;
3818 pListBoxDescription
->Value
= makeAny(((*aCurrentValueList
).second
));
3819 ++pListBoxDescription
;
3821 DBG_ASSERT(nListBoxDescription
== (pListBoxDescription
- aListBoxDescription
.getConstArray()),
3822 "FmXFormShell::CreateExternalView : forgot to adjust nListBoxDescription ?");
3824 // properties describing the column "meta data"
3825 const sal_Int16 nDispatchArgs
= 3;
3826 Sequence
< PropertyValue
> aDispatchArgs(nDispatchArgs
);
3827 PropertyValue
* pDispatchArgs
= aDispatchArgs
.getArray();
3829 // column type : listbox
3830 pDispatchArgs
->Name
= FMARG_ADDCOL_COLUMNTYPE
;
3831 ::rtl::OUString fColName
= FM_COL_LISTBOX
;
3832 pDispatchArgs
->Value
<<= fColName
;
3833 // pDispatchArgs->Value <<= (::rtl::OUString)FM_COL_LISTBOX;
3837 pDispatchArgs
->Name
= FMARG_ADDCOL_COLUMNPOS
;
3838 FmMapUString2Int16::const_iterator aOffset
= aRadioPositions
.find((*aCtrlSource
).first
);
3839 DBG_ASSERT(aOffset
!= aRadioPositions
.end(),
3840 "FmXFormShell::CreateExternalView : inconsistent radio descriptions !");
3841 sal_Int16 nPosition
= (*aOffset
).second
;
3842 nPosition
= nPosition
+ nOffset
;
3843 // we alread inserted nOffset additinal columns ....
3844 pDispatchArgs
->Value
<<= nPosition
;
3848 pDispatchArgs
->Name
= ::rtl::OUString::createFromAscii("ColumnProperties"); // TODO : fmurl.*
3849 pDispatchArgs
->Value
= makeAny(aListBoxDescription
);
3851 DBG_ASSERT(nDispatchArgs
== (pDispatchArgs
- aDispatchArgs
.getConstArray()),
3852 "FmXFormShell::CreateExternalView : forgot to adjust nDispatchArgs ?");
3854 // dispatch the "add column"
3855 xAddColumnDispatch
->dispatch(aAddColumnURL
, aDispatchArgs
);
3860 DBG_ASSERT(nAddedColumns
> 0, "FmXFormShell::CreateExternalView : no controls (inconsistent) !");
3861 // we should have checked if we have any usable controls (see above).
3863 // "load" the "form" of the external view
3865 aArg
.Name
= FMARG_ATTACHTO_MASTERFORM
;
3866 Reference
< XResultSet
> xForm(xCurrentNavController
->getModel(), UNO_QUERY
);
3867 aArg
.Value
<<= xForm
;
3869 m_xExternalDisplayedForm
= Reference
< XResultSet
>(xForm
, UNO_QUERY
);
3870 // do this before dispatching the "attach" command, as the atach may result in a call to our queryDispatch (for the FormSlots)
3871 // whichs needs the m_xExternalDisplayedForm
3873 xAttachDispatch
->dispatch(aAttachURL
, Sequence
< PropertyValue
>(&aArg
, 1));
3875 m_xExtViewTriggerController
= xCurrentNavController
;
3877 // we want to know modifications done in the external view
3878 // if the external controller is a XFormController we can use all our default handlings for it
3879 Reference
< XFormController
> xFormController(m_xExternalViewController
, UNO_QUERY
);
3880 if (xFormController
.is())
3881 xFormController
->addActivateListener((XFormControllerListener
*)this);
3887 DBG_ERROR("FmXFormShell::CreateExternalView : could not create the external form view !");
3890 InvalidateSlot( SID_FM_VIEW_AS_GRID
, sal_False
);
3893 //------------------------------------------------------------------------
3894 void FmXFormShell::implAdjustConfigCache()
3896 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::implAdjustConfigCache" );
3897 // get (cache) the wizard usage flag
3898 Sequence
< ::rtl::OUString
> aNames(1);
3899 aNames
[0] = ::rtl::OUString::createFromAscii("FormControlPilotsEnabled");
3900 Sequence
< Any
> aFlags
= GetProperties(aNames
);
3901 if (1 == aFlags
.getLength())
3902 m_bUseWizards
= ::cppu::any2bool(aFlags
[0]);
3905 //------------------------------------------------------------------------
3906 void FmXFormShell::Notify( const com::sun::star::uno::Sequence
< rtl::OUString
>& _rPropertyNames
)
3908 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::Notify" );
3909 if ( impl_checkDisposed() )
3912 const ::rtl::OUString
* pSearch
= _rPropertyNames
.getConstArray();
3913 const ::rtl::OUString
* pSearchTil
= pSearch
+ _rPropertyNames
.getLength();
3914 for (;pSearch
< pSearchTil
; ++pSearch
)
3915 if (0 == pSearch
->compareToAscii("FormControlPilotsEnabled"))
3917 implAdjustConfigCache();
3918 InvalidateSlot( SID_FM_USE_WIZARDS
, sal_True
);
3922 //------------------------------------------------------------------------
3923 void FmXFormShell::SetWizardUsing(sal_Bool _bUseThem
)
3925 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::SetWizardUsing" );
3926 m_bUseWizards
= _bUseThem
;
3928 Sequence
< ::rtl::OUString
> aNames(1);
3929 aNames
[0] = ::rtl::OUString::createFromAscii("FormControlPilotsEnabled");
3930 Sequence
< Any
> aValues(1);
3931 aValues
[0] = ::cppu::bool2any(m_bUseWizards
);
3932 PutProperties(aNames
, aValues
);
3935 //------------------------------------------------------------------------
3936 void FmXFormShell::viewDeactivated( FmFormView
& _rCurrentView
, sal_Bool _bDeactivateController
/* = sal_True */ )
3938 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::viewDeactivated" );
3939 OSL_TRACE( "--- FmXFormShell::viewDeactivated: %p, %p, ........\n", this, &_rCurrentView
);
3941 if ( _rCurrentView
.GetImpl() && !_rCurrentView
.IsDesignMode() )
3943 _rCurrentView
.GetImpl()->Deactivate( _bDeactivateController
);
3946 // if we have an async load operation pending for the 0-th page for this view,
3947 // we need to cancel this
3948 // 103727 - 2002-09-26 - fs@openoffice.org
3949 FmFormPage
* pPage
= _rCurrentView
.GetCurPage();
3952 // move all events from our queue to a new one, omit the events for the deactivated
3954 ::std::queue
< FmLoadAction
> aNewEvents
;
3955 while ( m_aLoadingPages
.size() )
3957 FmLoadAction aAction
= m_aLoadingPages
.front();
3958 m_aLoadingPages
.pop();
3959 if ( pPage
!= aAction
.pPage
)
3961 aNewEvents
.push( aAction
);
3965 Application::RemoveUserEvent( aAction
.nEventId
);
3968 m_aLoadingPages
= aNewEvents
;
3971 // remove callbacks at the page
3974 OSL_TRACE( "--- FmXFormShell::resetHandler : %p, ........, %p\n", this, pPage
);
3975 pPage
->GetImpl().SetFormsCreationHdl( Link() );
3977 UpdateForms( sal_True
);
3980 //------------------------------------------------------------------------
3981 IMPL_LINK( FmXFormShell
, OnFirstTimeActivation
, void*, /*NOTINTERESTEDIN*/ )
3983 if ( impl_checkDisposed() )
3986 m_nActivationEvent
= 0;
3987 SfxObjectShell
* pDocument
= m_pShell
->GetObjectShell();
3989 if ( pDocument
&& !pDocument
->HasName() )
3991 if ( isEnhancedForm() )
3993 // show the data navigator
3994 if ( !m_pShell
->GetViewShell()->GetViewFrame()->HasChildWindow( SID_FM_SHOW_DATANAVIGATOR
) )
3995 m_pShell
->GetViewShell()->GetViewFrame()->ToggleChildWindow( SID_FM_SHOW_DATANAVIGATOR
);
4002 //------------------------------------------------------------------------
4003 IMPL_LINK( FmXFormShell
, OnFormsCreated
, FmFormPage
*, /*_pPage*/ )
4005 UpdateForms( sal_True
);
4009 //------------------------------------------------------------------------
4010 void FmXFormShell::viewActivated( FmFormView
& _rCurrentView
, sal_Bool _bSyncAction
/* = sal_False */ )
4012 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::viewActivated" );
4013 OSL_TRACE( "--- FmXFormShell::viewActivated : %p, %p, ........\n", this, &_rCurrentView
);
4015 FmFormPage
* pPage
= _rCurrentView
.GetCurPage();
4017 // activate our view if we are activated ourself
4018 // FS - 30.06.99 - 67308
4019 if ( _rCurrentView
.GetImpl() && !_rCurrentView
.IsDesignMode() )
4021 // load forms for the page the current view belongs to
4024 if ( !pPage
->GetImpl().hasEverBeenActivated() )
4025 loadForms( pPage
, FORMS_LOAD
| ( _bSyncAction
? FORMS_SYNC
: FORMS_ASYNC
) );
4026 pPage
->GetImpl().setHasBeenActivated( );
4029 // first-time initializations for the views
4030 if ( !_rCurrentView
.GetImpl()->hasEverBeenActivated( ) )
4032 _rCurrentView
.GetImpl()->onFirstViewActivation( PTR_CAST( FmFormModel
, _rCurrentView
.GetModel() ) );
4033 _rCurrentView
.GetImpl()->setHasBeenActivated( );
4036 // activate the current view
4037 _rCurrentView
.GetImpl()->Activate( _bSyncAction
);
4040 // set callbacks at the page
4043 OSL_TRACE( "--- FmXFormShell::setHandler : %p, ........, %p\n", this, pPage
);
4044 pPage
->GetImpl().SetFormsCreationHdl( LINK( this, FmXFormShell
, OnFormsCreated
) );
4047 UpdateForms( sal_True
);
4049 if ( !hasEverBeenActivated() )
4051 m_nActivationEvent
= Application::PostUserEvent( LINK( this, FmXFormShell
, OnFirstTimeActivation
) );
4052 setHasBeenActivated();
4055 // find a default "current form", if there is none, yet
4056 // #i88186# / 2008-04-12 / frank.schoenheit@sun.com
4057 impl_defaultCurrentForm_nothrow();
4060 //------------------------------------------------------------------------------
4061 void FmXFormShell::impl_defaultCurrentForm_nothrow()
4063 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::impl_defaultCurrentForm_nothrow" );
4064 if ( impl_checkDisposed() )
4067 if ( m_xCurrentForm
.is() )
4068 // no action required
4071 FmFormView
* pFormView
= m_pShell
->GetFormView();
4072 FmFormPage
* pPage
= pFormView
? pFormView
->GetCurPage() : NULL
;
4078 Reference
< XIndexAccess
> xForms( pPage
->GetForms( false ), UNO_QUERY
);
4079 if ( !xForms
.is() || !xForms
->hasElements() )
4082 Reference
< XForm
> xNewCurrentForm( xForms
->getByIndex(0), UNO_QUERY_THROW
);
4083 impl_updateCurrentForm( xNewCurrentForm
);
4085 catch( const Exception
& )
4087 DBG_UNHANDLED_EXCEPTION();
4091 //------------------------------------------------------------------------------
4092 void FmXFormShell::smartControlReset( const Reference
< XIndexAccess
>& _rxModels
)
4094 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::smartControlReset" );
4095 if (!_rxModels
.is())
4097 DBG_ERROR("FmXFormShell::smartControlReset: invalid container!");
4101 static const ::rtl::OUString sClassIdPropertyName
= FM_PROP_CLASSID
;
4102 static const ::rtl::OUString sBoundFieldPropertyName
= FM_PROP_BOUNDFIELD
;
4103 sal_Int32 nCount
= _rxModels
->getCount();
4104 Reference
< XPropertySet
> xCurrent
;
4105 Reference
< XPropertySetInfo
> xCurrentInfo
;
4106 Reference
< XPropertySet
> xBoundField
;
4108 for (sal_Int32 i
=0; i
<nCount
; ++i
)
4110 _rxModels
->getByIndex(i
) >>= xCurrent
;
4112 xCurrentInfo
= xCurrent
->getPropertySetInfo();
4114 xCurrentInfo
.clear();
4115 if (!xCurrentInfo
.is())
4118 if (xCurrentInfo
->hasPropertyByName(sClassIdPropertyName
))
4119 { // it's a control model
4121 // check if this control is bound to a living database field
4122 if (xCurrentInfo
->hasPropertyByName(sBoundFieldPropertyName
))
4123 xCurrent
->getPropertyValue(sBoundFieldPropertyName
) >>= xBoundField
;
4125 xBoundField
.clear();
4127 // reset only if it's *not* bound
4128 bool bReset
= !xBoundField
.is();
4130 // and additionally, check if it has an external value binding
4131 Reference
< XBindableValue
> xBindable( xCurrent
, UNO_QUERY
);
4132 if ( xBindable
.is() && xBindable
->getValueBinding().is() )
4137 Reference
< XReset
> xControlReset( xCurrent
, UNO_QUERY
);
4138 if ( xControlReset
.is() )
4139 xControlReset
->reset();
4144 Reference
< XIndexAccess
> xContainer(xCurrent
, UNO_QUERY
);
4145 if (xContainer
.is())
4146 smartControlReset(xContainer
);
4151 //------------------------------------------------------------------------
4152 IMPL_LINK( FmXFormShell
, OnLoadForms
, FmFormPage
*, /*_pPage*/ )
4154 FmLoadAction aAction
= m_aLoadingPages
.front();
4155 m_aLoadingPages
.pop();
4157 loadForms( aAction
.pPage
, aAction
.nFlags
& ~FORMS_ASYNC
);
4161 //------------------------------------------------------------------------
4162 void FmXFormShell::loadForms( FmFormPage
* _pPage
, const sal_uInt16 _nBehaviour
/* FORMS_LOAD | FORMS_SYNC */ )
4164 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::loadForms" );
4165 DBG_ASSERT( ( _nBehaviour
& ( FORMS_ASYNC
| FORMS_UNLOAD
) ) != ( FORMS_ASYNC
| FORMS_UNLOAD
),
4166 "FmXFormShell::loadForms: async loading not supported - this will heavily fail!" );
4168 if ( _nBehaviour
& FORMS_ASYNC
)
4170 m_aLoadingPages
.push( FmLoadAction(
4173 Application::PostUserEvent( LINK( this, FmXFormShell
, OnLoadForms
), _pPage
)
4178 DBG_ASSERT( _pPage
, "FmXFormShell::loadForms: invalid page!" );
4181 // lock the undo env so the forms can change non-transient properties while loading
4182 // (without this my doc's modified flag would be set)
4183 FmFormModel
* pModel
= PTR_CAST( FmFormModel
, _pPage
->GetModel() );
4184 DBG_ASSERT( pModel
, "FmXFormShell::loadForms: invalid model!" );
4186 pModel
->GetUndoEnv().Lock();
4189 Reference
< XIndexAccess
> xForms
;
4190 xForms
= xForms
.query( _pPage
->GetForms( false ) );
4194 Reference
< XLoadable
> xForm
;
4195 sal_Bool bFormWasLoaded
= sal_False
;
4196 for ( sal_Int32 j
= 0, nCount
= xForms
->getCount(); j
< nCount
; ++j
)
4198 xForms
->getByIndex( j
) >>= xForm
;
4199 bFormWasLoaded
= sal_False
;
4200 // a database form must be loaded for
4203 if ( 0 == ( _nBehaviour
& FORMS_UNLOAD
) )
4205 if ( ::isLoadable( xForm
) && !xForm
->isLoaded() )
4210 if ( xForm
->isLoaded() )
4212 bFormWasLoaded
= sal_True
;
4217 catch( const Exception
& )
4219 DBG_UNHANDLED_EXCEPTION();
4222 // reset the form if it was loaded
4223 if ( bFormWasLoaded
)
4225 Reference
< XIndexAccess
> xContainer( xForm
, UNO_QUERY
);
4226 DBG_ASSERT( xContainer
.is(), "FmXFormShell::loadForms: the form is no container!" );
4227 if ( xContainer
.is() )
4228 smartControlReset( xContainer
);
4234 // unlock the environment
4235 pModel
->GetUndoEnv().UnLock();
4239 //------------------------------------------------------------------------
4240 void FmXFormShell::ExecuteTextAttribute( SfxRequest
& _rReq
)
4242 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::ExecuteTextAttribute" );
4243 m_pTextShell
->ExecuteTextAttribute( _rReq
);
4246 //------------------------------------------------------------------------
4247 void FmXFormShell::GetTextAttributeState( SfxItemSet
& _rSet
)
4249 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::GetTextAttributeState" );
4250 m_pTextShell
->GetTextAttributeState( _rSet
);
4253 //------------------------------------------------------------------------
4254 bool FmXFormShell::IsActiveControl( bool _bCountRichTextOnly
) const
4256 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::IsActiveControl" );
4257 return m_pTextShell
->IsActiveControl( _bCountRichTextOnly
);
4260 //------------------------------------------------------------------------
4261 void FmXFormShell::ForgetActiveControl()
4263 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::ForgetActiveControl" );
4264 m_pTextShell
->ForgetActiveControl();
4267 //------------------------------------------------------------------------
4268 void FmXFormShell::SetControlActivationHandler( const Link
& _rHdl
)
4270 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::SetControlActivationHandler" );
4271 m_pTextShell
->SetControlActivationHandler( _rHdl
);
4273 //------------------------------------------------------------------------
4274 void FmXFormShell::handleShowPropertiesRequest()
4276 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::handleShowPropertiesRequest" );
4277 if ( onlyControlsAreMarked() )
4278 ShowSelectionProperties( sal_True
);
4281 //------------------------------------------------------------------------
4282 void FmXFormShell::handleMouseButtonDown( const SdrViewEvent
& _rViewEvent
)
4284 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmXFormShell::handleMouseButtonDown" );
4285 // catch simple double clicks
4286 if ( ( _rViewEvent
.nMouseClicks
== 2 ) && ( _rViewEvent
.nMouseCode
== MOUSE_LEFT
) )
4288 if ( _rViewEvent
.eHit
== SDRHIT_MARKEDOBJECT
)
4290 if ( onlyControlsAreMarked() )
4291 ShowSelectionProperties( sal_True
);
4296 //==============================================================================
4297 //==============================================================================
4298 SearchableControlIterator::SearchableControlIterator(Reference
< XInterface
> xStartingPoint
)
4299 :IndexAccessIterator(xStartingPoint
)
4303 //------------------------------------------------------------------------------
4304 sal_Bool
SearchableControlIterator::ShouldHandleElement(const Reference
< XInterface
>& xElement
)
4306 // wenn das Ding eine ControlSource und einen BoundField-Property hat
4307 Reference
< XPropertySet
> xProperties(xElement
, UNO_QUERY
);
4308 if (::comphelper::hasProperty(FM_PROP_CONTROLSOURCE
, xProperties
) && ::comphelper::hasProperty(FM_PROP_BOUNDFIELD
, xProperties
))
4310 // und das BoundField gueltig ist
4311 Reference
< XPropertySet
> xField
;
4312 xProperties
->getPropertyValue(FM_PROP_BOUNDFIELD
) >>= xField
;
4316 m_sCurrentValue
= ::comphelper::getString(xProperties
->getPropertyValue(FM_PROP_CONTROLSOURCE
));
4321 // wenn es ein Grid-Control ist
4322 if (::comphelper::hasProperty(FM_PROP_CLASSID
, xProperties
))
4324 Any
aClassId( xProperties
->getPropertyValue(FM_PROP_CLASSID
) );
4325 if (::comphelper::getINT16(aClassId
) == FormComponentType::GRIDCONTROL
)
4327 m_sCurrentValue
= ::rtl::OUString();
4335 //------------------------------------------------------------------------------
4336 sal_Bool
SearchableControlIterator::ShouldStepInto(const Reference
< XInterface
>& /*xContainer*/) const
4341 //==============================================================================
4342 //==============================================================================
4344 SV_IMPL_PTRARR(StatusForwarderArray
, SfxStatusForwarder
*)
4346 SFX_IMPL_MENU_CONTROL(ControlConversionMenuController
, SfxBoolItem
);
4348 //------------------------------------------------------------------------------
4349 ControlConversionMenuController::ControlConversionMenuController( sal_uInt16 _nId
, Menu
& _rMenu
, SfxBindings
& _rBindings
)
4350 :SfxMenuControl( _nId
, _rBindings
)
4351 ,m_pMainMenu( &_rMenu
)
4352 ,m_pConversionMenu( NULL
)
4354 if ( _nId
== SID_FM_CHANGECONTROLTYPE
)
4356 m_pConversionMenu
= FmXFormShell::GetConversionMenu();
4357 _rMenu
.SetPopupMenu( _nId
, m_pConversionMenu
);
4359 for (sal_Int16 i
=0; i
<m_pConversionMenu
->GetItemCount(); ++i
)
4361 _rBindings
.Invalidate(m_pConversionMenu
->GetItemId(i
));
4362 SfxStatusForwarder
* pForwarder
= new SfxStatusForwarder(m_pConversionMenu
->GetItemId(i
), *this);
4363 m_aStatusForwarders
.C40_INSERT(SfxStatusForwarder
, pForwarder
, m_aStatusForwarders
.Count());
4368 //------------------------------------------------------------------------------
4369 ControlConversionMenuController::~ControlConversionMenuController()
4371 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "ControlConversionMenuController::~ControlConversionMenuController" );
4372 m_pMainMenu
->SetPopupMenu(SID_FM_CHANGECONTROLTYPE
, NULL
);
4373 delete m_pConversionMenu
;
4376 //------------------------------------------------------------------------------
4377 void ControlConversionMenuController::StateChanged(sal_uInt16 nSID
, SfxItemState eState
, const SfxPoolItem
* pState
)
4379 if (nSID
== GetId())
4380 SfxMenuControl::StateChanged(nSID
, eState
, pState
);
4381 else if (FmXFormShell::isControlConversionSlot(nSID
))
4383 if ((m_pConversionMenu
->GetItemPos(nSID
) != MENU_ITEM_NOTFOUND
) && (eState
== SFX_ITEM_DISABLED
))
4385 m_pConversionMenu
->RemoveItem(m_pConversionMenu
->GetItemPos(nSID
));
4387 else if ((m_pConversionMenu
->GetItemPos(nSID
) == MENU_ITEM_NOTFOUND
) && (eState
!= SFX_ITEM_DISABLED
))
4389 // We can't simply re-insert the item because we have a clear order for all the our items.
4390 // So first we have to determine the position of the item to insert.
4391 PopupMenu
* pSource
= FmXFormShell::GetConversionMenu();
4392 USHORT nSourcePos
= pSource
->GetItemPos(nSID
);
4393 DBG_ASSERT(nSourcePos
!= MENU_ITEM_NOTFOUND
, "ControlConversionMenuController::StateChanged : FmXFormShell supplied an invalid menu !");
4394 USHORT nPrevInSource
= nSourcePos
;
4395 USHORT nPrevInConversion
= MENU_ITEM_NOTFOUND
;
4396 while (nPrevInSource
>0)
4398 sal_Int16 nPrevId
= pSource
->GetItemId(--nPrevInSource
);
4400 // do we have the source's predecessor in our conversion menu, too ?
4401 nPrevInConversion
= m_pConversionMenu
->GetItemPos(nPrevId
);
4402 if (nPrevInConversion
!= MENU_ITEM_NOTFOUND
)
4405 if (MENU_ITEM_NOTFOUND
== nPrevInConversion
)
4406 // none of the items which precede the nSID-slot in the source menu are present in our conversion menu
4407 nPrevInConversion
= sal::static_int_cast
< USHORT
>(-1); // put the item at the first position
4408 m_pConversionMenu
->InsertItem(nSID
, pSource
->GetItemText(nSID
), pSource
->GetItemBits(nSID
), ++nPrevInConversion
);
4409 m_pConversionMenu
->SetItemImage(nSID
, pSource
->GetItemImage(nSID
));
4410 m_pConversionMenu
->SetHelpId(nSID
, pSource
->GetHelpId(nSID
));
4414 m_pMainMenu
->EnableItem(SID_FM_CHANGECONTROLTYPE
, m_pConversionMenu
->GetItemCount() > 0);
4418 DBG_ERROR("ControlConversionMenuController::StateChanged : unknown id !");
4422 //==================================================================
4424 FmCursorActionThread::FmCursorActionThread(const Reference
< XResultSet
>& _xDataSource
, const UniString
& _rStopperCaption
)
4425 :m_xDataSource(_xDataSource
)
4426 ,m_sStopperCaption(_rStopperCaption
)
4427 ,m_bCanceled(sal_False
)
4428 ,m_bDeleteMyself(sal_False
)
4429 ,m_bDisposeCursor(sal_False
)
4430 ,m_bTerminated(sal_False
)
4431 ,m_bRunFailed(sal_False
)
4433 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "svx", "Ocke.Janssen@sun.com", "FmCursorActionThread::FmCursorActionThread" );
4434 DBG_ASSERT(m_xDataSource
.is() && Reference
< XCancellable
>(m_xDataSource
, UNO_QUERY
).is(),
4435 "FmCursorActionThread::FmCursorActionThread : invalid cursor !");
4438 //------------------------------------------------------------------------------
4439 void FmCursorActionThread::run()
4441 // On instantiation of a SfxCancellable the application is notified and 'switches on' the red stop button.
4442 // Unfortunally this is conditioned with the acquirement of the solar mutex, and the application tries
4443 // only once and ignores the notification if it fails.
4444 // To prevent that we get the solar mutex and _block_ 'til we got it.
4445 // As we are in the 'top level execution' of this thread (with a rather small stack and no other mutexes locked)
4446 // we shouldn't experience problems with deadlocks ...
4447 ::vos::OClearableGuard
aSolarGuard(Application::GetSolarMutex());
4448 ThreadStopper
* pStopper
= new ThreadStopper(this, m_sStopperCaption
);
4449 aSolarGuard
.clear();
4451 // we're not canceled yet
4452 ::osl::ClearableMutexGuard
aInitGuard(m_aAccessSafety
);
4453 m_bCanceled
= sal_False
;
4454 m_bRunFailed
= sal_False
;
4462 catch(SQLException e
)
4464 ::osl::MutexGuard
aErrorGuard(m_aAccessSafety
);
4465 m_bRunFailed
= sal_True
;
4466 m_aRunException
= e
;
4470 DBG_ERROR("FmCursorActionThread::run : catched a non-database exception !");
4474 sal_Bool bReallyCanceled
;
4475 ::osl::ClearableMutexGuard
aEvalGuard(m_aAccessSafety
);
4476 bReallyCanceled
= m_bCanceled
;
4479 pStopper
->OwnerTerminated();
4480 // this will cause the stopper to delete itself (in the main thread) so we don't have to care of the
4484 //------------------------------------------------------------------------------
4485 void FmCursorActionThread::onTerminated()
4487 ::osl::ClearableMutexGuard
aResetGuard(m_aAccessSafety
);
4488 if (m_aTerminationHandler
.IsSet())
4489 m_aTerminationHandler
.Call(this);
4491 if (IsCursorDisposeEnabled())
4493 Reference
< ::com::sun::star::lang::XComponent
> xDataSourceComponent(m_xDataSource
, UNO_QUERY
);
4494 if (xDataSourceComponent
.is())
4495 xDataSourceComponent
->dispose();
4498 aResetGuard
.clear();
4499 // with this StopItWait has a chance to do it's Terminated()
4501 ::osl::MutexGuard
aGuard(m_aFinalExitControl
);
4502 // Terminated() in StopItWait still returns sal_False
4503 m_bTerminated
= sal_True
;
4504 // Terminated() now returns sal_True, but StopItWait can't exit until this method exits (because of the guarded m_aFinalExitControl)
4506 if (IsSelfDeleteEnabled())
4510 //------------------------------------------------------------------------------
4511 void FmCursorActionThread::StopIt()
4513 ::osl::MutexGuard
aGuard(m_aAccessSafety
);
4514 m_bCanceled
= sal_True
;
4516 Reference
< XCancellable
> xCancel(m_xDataSource
, UNO_QUERY
);
4517 DBG_ASSERT(xCancel
.is(), "FmCursorActionThread::StopIt : invalid cursor !");
4521 //------------------------------------------------------------------------------
4522 void FmCursorActionThread::StopItWait()
4526 while (!Terminated())
4529 // OnTerminated has been called, but we can't simply exit : Suppose the caller want's to delete the thread object
4530 // immediately after returning from StopItWait. With the following guard we ensure that we exit this method
4531 // only after onTerminated has exited.
4532 ::osl::ClearableMutexGuard
aGuard(m_aFinalExitControl
);
4534 // now onTerminated has exited, so we can leave, too
4537 //------------------------------------------------------------------------------
4538 FmCursorActionThread::ThreadStopper::ThreadStopper(FmCursorActionThread
* pOwner
, const UniString
& rTitle
)
4539 :SfxCancellable(SFX_APP()->GetCancelManager(), rTitle
)
4544 //------------------------------------------------------------------------------
4545 void FmCursorActionThread::ThreadStopper::Cancel()
4547 if (!m_pOwner
) // the owner is already terminated and we're waiting for the OnDeleteInMainThread event
4550 ::osl::MutexGuard
aGuard(m_pOwner
->m_aAccessSafety
);
4552 // we already did pass this to our owner
4555 SfxCancellable::Cancel();
4559 //------------------------------------------------------------------------------
4560 void FmCursorActionThread::ThreadStopper::OwnerTerminated()
4563 Application::PostUserEvent(LINK(this, FmCursorActionThread::ThreadStopper
, OnDeleteInMainThread
), this);
4566 //------------------------------------------------------------------------------
4567 IMPL_LINK(FmCursorActionThread::ThreadStopper
, OnDeleteInMainThread
, FmCursorActionThread::ThreadStopper
*, pThis
)
4573 //==============================================================================