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: fmview.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 <sfx2/docfile.hxx>
37 #include <svtools/ehdl.hxx>
38 #include <svtools/moduleoptions.hxx>
39 #include <com/sun/star/sdb/SQLContext.hpp>
40 #include <com/sun/star/uno/XNamingService.hpp>
41 #include <com/sun/star/sdbc/XConnection.hpp>
42 #include <com/sun/star/sdbc/DataType.hpp>
43 #include <com/sun/star/form/XLoadable.hpp>
44 #include <com/sun/star/form/XReset.hpp>
45 #include "fmvwimp.hxx"
46 #include <sfx2/objsh.hxx>
47 #include <sfx2/viewsh.hxx>
48 #include <sfx2/viewfrm.hxx>
49 #include <sfx2/bindings.hxx>
50 #include <sfx2/dispatch.hxx>
51 #include <basic/sbuno.hxx>
52 #include <sfx2/macrconf.hxx>
53 #include <basic/sbx.hxx>
54 #include "fmitems.hxx"
56 #include "svditer.hxx"
57 #include <svx/svdpagv.hxx>
58 #include <svx/svdogrp.hxx>
59 #include <svx/fmview.hxx>
60 #include <svx/fmmodel.hxx>
61 #include <svx/fmpage.hxx>
62 #include <svx/fmshell.hxx>
63 #include "fmpgeimp.hxx"
64 #include "fmtools.hxx"
65 #include "fmshimp.hxx"
66 #include "fmservs.hxx"
69 #include <svx/dataaccessdescriptor.hxx>
70 #include <comphelper/processfactory.hxx>
71 #include <comphelper/namedvaluecollection.hxx>
72 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
73 #include <com/sun/star/beans/PropertyValue.hpp>
74 #include <com/sun/star/beans/PropertyState.hpp>
75 #include <com/sun/star/form/FormComponentType.hpp>
76 #include <vcl/svapp.hxx>
77 #include <tools/urlobj.hxx>
78 #include <tools/diagnose_ex.h>
79 #include <vcl/stdtext.hxx>
80 #include <svx/fmglob.hxx>
81 #include <svx/sdrpagewindow.hxx>
82 #include "sdrpaintwindow.hxx"
84 using namespace ::com::sun::star
;
85 using namespace ::com::sun::star::uno
;
86 using namespace ::com::sun::star::lang
;
87 using namespace ::com::sun::star::sdbc
;
88 using namespace ::com::sun::star::sdb
;
89 using namespace ::com::sun::star::beans
;
90 using namespace ::com::sun::star::container
;
91 using namespace ::com::sun::star::form
;
92 using namespace ::com::sun::star::util
;
93 using namespace ::svxform
;
94 using namespace ::svx
;
96 //========================================================================
97 //------------------------------------------------------------------------
98 TYPEINIT1(FmFormView
, E3dView
);
100 //------------------------------------------------------------------------
101 FmFormView::FmFormView( FmFormModel
* pModel
, OutputDevice
* pOut
)
102 :E3dView(pModel
,pOut
)
107 //------------------------------------------------------------------------
108 void FmFormView::Init()
111 pImpl
= new FmXFormView(::comphelper::getProcessServiceFactory(),this);
114 //////////////////////////////////////////////////////////////////////
116 SdrModel
* pModel
= GetModel();
118 DBG_ASSERT( pModel
->ISA(FmFormModel
), "Falsches Model" );
119 if( !pModel
->ISA(FmFormModel
) ) return;
120 FmFormModel
* pFormModel
= (FmFormModel
*)pModel
;
122 //////////////////////////////////////////////////////////////////////
123 // DesignMode vom Model holen
124 sal_Bool bInitDesignMode
= pFormModel
->GetOpenInDesignMode();
125 if ( pFormModel
->OpenInDesignModeIsDefaulted( ) )
126 { // this means that nobody ever explicitly set this on the model, and the model has never
127 // been loaded from a stream.
128 // This means this is a newly created document. This means, we want to have it in design
129 // mode by default (though a newly created model returns true for GetOpenInDesignMode).
130 // We _want_ to have this because it makes a lot of hacks following the original fix
131 // for #94595# unnecessary
132 // #96399# - 2002-10-11 - fs@openoffice.org
133 DBG_ASSERT( !bInitDesignMode
, "FmFormView::Init: doesn't the model default to FALSE anymore?" );
134 // if this asserts, either the on-contruction default in the model has changed (then this here
135 // may not be necessary anymore), or we're not dealing with a new document ....
136 bInitDesignMode
= sal_True
;
139 SfxObjectShell
* pObjShell
= pFormModel
->GetObjectShell();
140 if ( pObjShell
&& pObjShell
->GetMedium() )
142 const SfxPoolItem
*pItem
=0;
143 if ( pObjShell
->GetMedium()->GetItemSet()->GetItemState( SID_COMPONENTDATA
, sal_False
, &pItem
) == SFX_ITEM_SET
)
145 Sequence
< PropertyValue
> aSeq
;
146 ( ((SfxUnoAnyItem
*)pItem
)->GetValue() ) >>= aSeq
;
147 ::comphelper::NamedValueCollection
aComponentData( aSeq
);
148 bInitDesignMode
= aComponentData
.getOrDefault( "ApplyFormDesignMode", bInitDesignMode
);
152 if( pObjShell
&& pObjShell
->IsReadOnly() )
153 bInitDesignMode
= sal_False
;
155 // dieses wird in der Shell vorgenommen
156 // bDesignMode = !bInitDesignMode; // erzwingt, dass SetDesignMode ausgefuehrt wird
157 SetDesignMode( bInitDesignMode
);
160 //------------------------------------------------------------------------
161 FmFormView::~FmFormView()
164 pFormShell
->SetView( NULL
);
166 pImpl
->notifyViewDying();
171 //------------------------------------------------------------------------
172 FmFormPage
* FmFormView::GetCurPage()
174 SdrPageView
* pPageView
= GetSdrPageView();
175 FmFormPage
* pCurPage
= pPageView
? PTR_CAST( FmFormPage
, pPageView
->GetPage() ) : NULL
;
179 //------------------------------------------------------------------------
180 void FmFormView::MarkListHasChanged()
182 E3dView::MarkListHasChanged();
184 if ( pFormShell
&& IsDesignMode() )
186 FmFormObj
* pObj
= getMarkedGrid();
187 if ( pImpl
->m_pMarkedGrid
&& pImpl
->m_pMarkedGrid
!= pObj
)
189 pImpl
->m_pMarkedGrid
= NULL
;
190 if ( pImpl
->m_xWindow
.is() )
192 pImpl
->m_xWindow
->removeFocusListener(pImpl
);
193 pImpl
->m_xWindow
= NULL
;
195 SetMoveOutside(FALSE
);
196 //OLMRefreshAllIAOManagers();
199 pFormShell
->GetImpl()->SetSelectionDelayed();
205 const SdrPageWindow
* findPageWindow( const SdrPaintView
* _pView
, OutputDevice
* _pWindow
)
207 SdrPageView
* pPageView
= _pView
->GetSdrPageView();
210 for ( sal_uInt32 window
= 0; window
< pPageView
->PageWindowCount(); ++window
)
212 const SdrPageWindow
* pPageWindow
= pPageView
->GetPageWindow( window
);
213 if ( !pPageWindow
|| &pPageWindow
->GetPaintWindow().GetOutputDevice() != _pWindow
)
223 //------------------------------------------------------------------------
224 void FmFormView::AddWindowToPaintView(OutputDevice
* pNewWin
)
226 E3dView::AddWindowToPaintView(pNewWin
);
231 // look up the PageViewWindow for the newly inserted window, and care for it
232 // #i39269# / 2004-12-20 / frank.schoenheit@sun.com
233 const SdrPageWindow
* pPageWindow
= findPageWindow( this, pNewWin
);
235 pImpl
->addWindow( *pPageWindow
);
238 //------------------------------------------------------------------------
239 void FmFormView::DeleteWindowFromPaintView(OutputDevice
* pNewWin
)
241 const SdrPageWindow
* pPageWindow
= findPageWindow( this, pNewWin
);
243 pImpl
->removeWindow( pPageWindow
->GetControlContainer() );
245 E3dView::DeleteWindowFromPaintView(pNewWin
);
248 //------------------------------------------------------------------------
249 void FmFormView::ChangeDesignMode(sal_Bool bDesign
)
251 if (bDesign
== IsDesignMode())
254 FmFormModel
* pModel
= PTR_CAST(FmFormModel
, GetModel());
256 { // fuer die Zeit des Uebergangs das Undo-Environment ausschalten, das sichert, dass man dort auch nicht-transiente
257 // Properties mal eben aendern kann (sollte allerdings mit Vorsicht genossen und beim Rueckschalten des Modes
258 // auch immer wieder rueckgaegig gemacht werden. Ein Beispiel ist das Setzen der maximalen Text-Laenge durch das
259 // FmXEditModel an seinem Control.)
260 pModel
->GetUndoEnv().Lock();
263 // --- 1. deactivate all controls if we are switching to design mode
265 DeactivateControls( GetSdrPageView() );
267 // --- 2. simulate a deactivation (the shell will handle some things there ...?)
268 if ( pFormShell
&& pFormShell
->GetImpl() )
269 pFormShell
->GetImpl()->viewDeactivated( *this, sal_True
);
271 pImpl
->Deactivate( sal_True
);
273 // --- 3. activate all controls, if we're switching to alive mode
275 ActivateControls( GetSdrPageView() );
277 // --- 4. load resp. unload the forms
278 FmFormPage
* pCurPage
= GetCurPage();
281 if ( pFormShell
&& pFormShell
->GetImpl() )
282 pFormShell
->GetImpl()->loadForms( pCurPage
, ( bDesign
? FORMS_UNLOAD
: FORMS_LOAD
) );
285 // --- 5. base class functionality
286 SetDesignMode( bDesign
);
288 // --- 6. simulate a activation (the shell will handle some things there ...?)
289 OSL_PRECOND( pFormShell
&& pFormShell
->GetImpl(), "FmFormView::ChangeDesignMode: is this really allowed? No shell?" );
290 if ( pFormShell
&& pFormShell
->GetImpl() )
291 pFormShell
->GetImpl()->viewActivated( *this );
299 if ( GetActualOutDev() && GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW
)
301 const Window
* pWindow
= static_cast< const Window
* >( GetActualOutDev() );
302 const_cast< Window
* >( pWindow
)->GrabFocus();
305 // redraw UNO objects
306 if ( GetSdrPageView() )
308 SdrObjListIter
aIter(*pCurPage
);
309 while( aIter
.IsMore() )
311 SdrObject
* pObj
= aIter
.Next();
312 if (pObj
&& pObj
->IsUnoObj())
314 // For redraw just use ActionChanged()
315 // pObj->BroadcastObjectChange();
316 pObj
->ActionChanged();
323 // set the auto focus to the first control (if indicated by the model to do so)
324 sal_Bool bForceControlFocus
= pModel
? pModel
->GetAutoControlFocus() : sal_False
;
325 if (bForceControlFocus
)
330 // und mein Undo-Environment wieder an
332 pModel
->GetUndoEnv().UnLock();
335 //------------------------------------------------------------------------
336 void FmFormView::GrabFirstControlFocus( sal_Bool _bForceSync
)
338 if ( !IsDesignMode() )
339 pImpl
->AutoFocus( _bForceSync
);
342 //------------------------------------------------------------------------
343 SdrPageView
* FmFormView::ShowSdrPage(SdrPage
* pPage
)
345 OSL_TRACE( "--- FmFormView::ShowSdrPage : ........, %p, %p", this, pPage
);
347 SdrPageView
* pPV
= E3dView::ShowSdrPage(pPage
);
353 // creating the controllers
354 ActivateControls(pPV
);
356 // Alles deselektieren
359 else if ( pFormShell
&& pFormShell
->IsDesignMode() )
361 FmXFormShell
* pFormShellImpl
= pFormShell
->GetImpl();
362 pFormShellImpl
->UpdateForms( sal_True
);
364 // damit der Formular-Navigator auf den Seitenwechsel reagieren kann
365 pFormShell
->GetViewShell()->GetViewFrame()->GetBindings().Invalidate(SID_FM_FMEXPLORER_CONTROL
, sal_True
, sal_False
);
367 pFormShellImpl
->SetSelection(GetMarkedObjectList());
371 // notify our shell that we have been activated
372 if ( pFormShell
&& pFormShell
->GetImpl() )
373 pFormShell
->GetImpl()->viewActivated( *this );
380 //------------------------------------------------------------------------
381 void FmFormView::HideSdrPage()
383 OSL_TRACE( "--- FmFormView::HideSdrPage : ........, %p, %p", this, GetCurPage() );
385 // --- 1. deactivate controls
386 if ( !IsDesignMode() )
387 DeactivateControls(GetSdrPageView());
389 // --- 2. tell the shell the view is (going to be) deactivated
390 if ( pFormShell
&& pFormShell
->GetImpl() )
391 pFormShell
->GetImpl()->viewDeactivated( *this, sal_True
);
393 pImpl
->Deactivate( sal_True
);
395 // --- 3. base class behavior
396 E3dView::HideSdrPage();
399 //------------------------------------------------------------------------
400 SdrModel
* FmFormView::GetMarkedObjModel() const
402 return E3dView::GetMarkedObjModel();
405 //------------------------------------------------------------------------
406 sal_Bool
FmFormView::Paste(const SdrModel
& rMod
, const Point
& rPos
, SdrObjList
* pLst
, sal_uInt32 nOptions
)
408 return E3dView::Paste(rMod
, rPos
, pLst
, nOptions
);
411 //------------------------------------------------------------------------
412 void FmFormView::ActivateControls(SdrPageView
* pPageView
)
417 for (sal_uInt32 i
= 0L; i
< pPageView
->PageWindowCount(); ++i
)
419 const SdrPageWindow
& rPageWindow
= *pPageView
->GetPageWindow(i
);
420 pImpl
->addWindow(rPageWindow
);
424 //------------------------------------------------------------------------
425 void FmFormView::DeactivateControls(SdrPageView
* pPageView
)
430 for (sal_uInt32 i
= 0L; i
< pPageView
->PageWindowCount(); ++i
)
432 const SdrPageWindow
& rPageWindow
= *pPageView
->GetPageWindow(i
);
433 pImpl
->removeWindow(rPageWindow
.GetControlContainer() );
437 //------------------------------------------------------------------------
438 SdrObject
* FmFormView::CreateFieldControl( const ODataAccessDescriptor
& _rColumnDescriptor
)
440 return pImpl
->implCreateFieldControl( _rColumnDescriptor
);
443 //------------------------------------------------------------------------
444 SdrObject
* FmFormView::CreateXFormsControl( const OXFormsDescriptor
&_rDesc
)
446 return pImpl
->implCreateXFormsControl(_rDesc
);
449 //------------------------------------------------------------------------
450 SdrObject
* FmFormView::CreateFieldControl(const UniString
& rFieldDesc
) const
452 ::rtl::OUString sDataSource
= rFieldDesc
.GetToken(0,sal_Unicode(11));
453 ::rtl::OUString sObjectName
= rFieldDesc
.GetToken(1,sal_Unicode(11));
454 sal_uInt16 nObjectType
= (sal_uInt16
)rFieldDesc
.GetToken(2,sal_Unicode(11)).ToInt32();
455 ::rtl::OUString sFieldName
= rFieldDesc
.GetToken(3,sal_Unicode(11));
457 if (!sFieldName
.getLength() || !sObjectName
.getLength() || !sDataSource
.getLength())
460 ODataAccessDescriptor aColumnDescriptor
;
461 aColumnDescriptor
.setDataSource(sDataSource
);
462 aColumnDescriptor
[ daCommand
] <<= sObjectName
;
463 aColumnDescriptor
[ daCommandType
] <<= nObjectType
;
464 aColumnDescriptor
[ daColumnName
] <<= sFieldName
;
466 return pImpl
->implCreateFieldControl( aColumnDescriptor
);
469 //------------------------------------------------------------------------
470 void FmFormView::InsertControlContainer(const Reference
< ::com::sun::star::awt::XControlContainer
> & xCC
)
472 if( !IsDesignMode() )
474 SdrPageView
* pPageView
= GetSdrPageView();
477 for( sal_uInt32 i
= 0L; i
< pPageView
->PageWindowCount(); i
++ )
479 const SdrPageWindow
& rPageWindow
= *pPageView
->GetPageWindow(i
);
481 if( rPageWindow
.GetControlContainer( false ) == xCC
)
483 pImpl
->addWindow(rPageWindow
);
491 //------------------------------------------------------------------------
492 void FmFormView::RemoveControlContainer(const Reference
< ::com::sun::star::awt::XControlContainer
> & xCC
)
494 if( !IsDesignMode() )
496 pImpl
->removeWindow( xCC
);
500 // -----------------------------------------------------------------------------
501 SdrPaintWindow
* FmFormView::BeginCompleteRedraw(OutputDevice
* pOut
)
503 SdrPaintWindow
* pPaintWindow
= E3dView::BeginCompleteRedraw( pOut
);
504 pImpl
->suspendTabOrderUpdate();
508 // -----------------------------------------------------------------------------
509 void FmFormView::EndCompleteRedraw( SdrPaintWindow
& rPaintWindow
, bool bPaintFormLayer
)
511 E3dView::EndCompleteRedraw( rPaintWindow
, bPaintFormLayer
);
512 pImpl
->resumeTabOrderUpdate();
515 // -----------------------------------------------------------------------------
516 BOOL
FmFormView::KeyInput(const KeyEvent
& rKEvt
, Window
* pWin
)
519 const KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
521 && rKeyCode
.GetCode() == KEY_RETURN
524 // RETURN alone enters grid controls, for keyboard accessibility
526 && !rKeyCode
.IsShift()
527 && !rKeyCode
.IsMod1()
528 && !rKeyCode
.IsMod2()
531 FmFormObj
* pObj
= getMarkedGrid();
534 Reference
< awt::XWindow
> xWindow( pObj
->GetUnoControl( *this, *pWin
), UNO_QUERY
);
537 pImpl
->m_pMarkedGrid
= pObj
;
538 pImpl
->m_xWindow
= xWindow
;
539 // add as listener to get notified when ESC will be pressed inside the grid
540 pImpl
->m_xWindow
->addFocusListener(pImpl
);
541 SetMoveOutside(TRUE
);
542 //OLMRefreshAllIAOManagers();
548 // Alt-RETURN alone shows the properties of the selection
550 && pFormShell
->GetImpl()
551 && !rKeyCode
.IsShift()
552 && !rKeyCode
.IsMod1()
556 pFormShell
->GetImpl()->handleShowPropertiesRequest();
562 bDone
= E3dView::KeyInput(rKEvt
,pWin
);
565 // -----------------------------------------------------------------------------
566 sal_Bool
FmFormView::checkUnMarkAll(const Reference
< XInterface
>& _xSource
)
568 Reference
< ::com::sun::star::awt::XControl
> xControl(pImpl
->m_xWindow
,UNO_QUERY
);
569 sal_Bool bRet
= !xControl
.is() || !_xSource
.is() || _xSource
!= xControl
->getModel();
576 // -----------------------------------------------------------------------------
577 BOOL
FmFormView::MouseButtonDown( const MouseEvent
& _rMEvt
, Window
* _pWin
)
579 BOOL bReturn
= E3dView::MouseButtonDown( _rMEvt
, _pWin
);
581 if ( pFormShell
&& pFormShell
->GetImpl() )
583 SdrViewEvent aViewEvent
;
584 PickAnything( _rMEvt
, SDRMOUSEBUTTONDOWN
, aViewEvent
);
585 pFormShell
->GetImpl()->handleMouseButtonDown( aViewEvent
);
591 // -----------------------------------------------------------------------------
592 FmFormObj
* FmFormView::getMarkedGrid() const
594 FmFormObj
* pFormObject
= NULL
;
595 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
596 if ( 1 == rMarkList
.GetMarkCount() )
598 SdrMark
* pMark
= rMarkList
.GetMark(0);
601 pFormObject
= FmFormObj::GetFormObject( pMark
->GetMarkedSdrObj() );
604 Reference
< XServiceInfo
> xServInfo( pFormObject
->GetUnoControlModel(), UNO_QUERY
);
605 if ( !xServInfo
.is() || !xServInfo
->supportsService( FM_SUN_COMPONENT_GRIDCONTROL
) )
613 // -----------------------------------------------------------------------------
614 void FmFormView::createControlLabelPair( OutputDevice
* _pOutDev
, sal_Int32 _nXOffsetMM
, sal_Int32 _nYOffsetMM
,
615 const Reference
< XPropertySet
>& _rxField
, const Reference
< XNumberFormats
>& _rxNumberFormats
,
616 sal_uInt16 _nControlObjectID
, const ::rtl::OUString
& _rFieldPostfix
, UINT32 _nInventor
, UINT16 _nLabelObjectID
,
617 SdrPage
* _pLabelPage
, SdrPage
* _pControlPage
, SdrModel
* _pModel
, SdrUnoObj
*& _rpLabel
, SdrUnoObj
*& _rpControl
)
619 FmXFormView::createControlLabelPair(
620 ::comphelper::getProcessServiceFactory(),
621 *_pOutDev
, _nXOffsetMM
, _nYOffsetMM
,
622 _rxField
, _rxNumberFormats
,
623 _nControlObjectID
, _rFieldPostfix
, _nInventor
, _nLabelObjectID
,
624 _pLabelPage
, _pControlPage
, _pModel
,
628 // -----------------------------------------------------------------------------
629 Reference
< XFormController
> FmFormView::GetFormController( const Reference
< XForm
>& _rxForm
, const OutputDevice
& _rDevice
) const
631 return pImpl
->getFormController( _rxForm
, _rDevice
);