1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sfx2/docfile.hxx>
24 #include <svtools/ehdl.hxx>
25 #include <unotools/moduleoptions.hxx>
26 #include <com/sun/star/sdb/SQLContext.hpp>
27 #include <com/sun/star/uno/XNamingService.hpp>
28 #include <com/sun/star/sdbc/XConnection.hpp>
29 #include <com/sun/star/sdbc/DataType.hpp>
30 #include <com/sun/star/form/XLoadable.hpp>
31 #include <com/sun/star/form/XReset.hpp>
32 #include "fmvwimp.hxx"
33 #include <sfx2/objsh.hxx>
34 #include <sfx2/viewsh.hxx>
35 #include <sfx2/viewfrm.hxx>
36 #include <sfx2/bindings.hxx>
37 #include <sfx2/dispatch.hxx>
38 #include <basic/sbuno.hxx>
39 #include <basic/sbx.hxx>
40 #include "fmitems.hxx"
42 #include "svx/svditer.hxx"
43 #include <svx/svdpagv.hxx>
44 #include <svx/svdogrp.hxx>
45 #include <svx/fmview.hxx>
46 #include <svx/fmmodel.hxx>
47 #include <svx/fmpage.hxx>
48 #include <svx/fmshell.hxx>
49 #include "fmpgeimp.hxx"
50 #include "svx/fmtools.hxx"
51 #include "fmshimp.hxx"
52 #include "fmservs.hxx"
55 #include <svx/dataaccessdescriptor.hxx>
56 #include <comphelper/processfactory.hxx>
57 #include <comphelper/namedvaluecollection.hxx>
58 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
59 #include <com/sun/star/beans/PropertyValue.hpp>
60 #include <com/sun/star/beans/PropertyState.hpp>
61 #include <com/sun/star/form/FormComponentType.hpp>
62 #include <vcl/svapp.hxx>
63 #include <tools/diagnose_ex.h>
64 #include <vcl/stdtext.hxx>
65 #include <svx/fmglob.hxx>
66 #include <svx/sdrpagewindow.hxx>
67 #include "svx/sdrpaintwindow.hxx"
69 using namespace ::com::sun::star
;
70 using namespace ::com::sun::star::uno
;
71 using namespace ::com::sun::star::lang
;
72 using namespace ::com::sun::star::sdbc
;
73 using namespace ::com::sun::star::sdb
;
74 using namespace ::com::sun::star::beans
;
75 using namespace ::com::sun::star::container
;
76 using namespace ::com::sun::star::form
;
77 using namespace ::com::sun::star::util
;
78 using namespace ::svxform
;
79 using namespace ::svx
;
83 TYPEINIT1(FmFormView
, E3dView
);
86 FmFormView::FmFormView( FmFormModel
* pModel
, OutputDevice
* pOut
)
93 void FmFormView::Init()
96 pImpl
= new FmXFormView(this);
101 SdrModel
* pModel
= GetModel();
103 DBG_ASSERT( pModel
->ISA(FmFormModel
), "Falsches Model" );
104 if( !pModel
->ISA(FmFormModel
) ) return;
105 FmFormModel
* pFormModel
= (FmFormModel
*)pModel
;
108 // DesignMode vom Model holen
109 bool bInitDesignMode
= pFormModel
->GetOpenInDesignMode();
110 if ( pFormModel
->OpenInDesignModeIsDefaulted( ) )
111 { // this means that nobody ever explicitly set this on the model, and the model has never
112 // been loaded from a stream.
113 // This means this is a newly created document. This means, we want to have it in design
114 // mode by default (though a newly created model returns true for GetOpenInDesignMode).
115 // We _want_ to have this because it makes a lot of hacks following the original fix
116 DBG_ASSERT( !bInitDesignMode
, "FmFormView::Init: doesn't the model default to FALSE anymore?" );
117 // if this asserts, either the on-contruction default in the model has changed (then this here
118 // may not be necessary anymore), or we're not dealing with a new document ....
119 bInitDesignMode
= true;
122 SfxObjectShell
* pObjShell
= pFormModel
->GetObjectShell();
123 if ( pObjShell
&& pObjShell
->GetMedium() )
125 const SfxPoolItem
*pItem
=0;
126 if ( pObjShell
->GetMedium()->GetItemSet()->GetItemState( SID_COMPONENTDATA
, false, &pItem
) == SFX_ITEM_SET
)
128 ::comphelper::NamedValueCollection
aComponentData( ((SfxUnoAnyItem
*)pItem
)->GetValue() );
129 bInitDesignMode
= aComponentData
.getOrDefault( "ApplyFormDesignMode", bInitDesignMode
);
133 if( pObjShell
&& pObjShell
->IsReadOnly() )
134 bInitDesignMode
= false;
136 // dieses wird in der Shell vorgenommen
137 // bDesignMode = !bInitDesignMode; // erzwingt, dass SetDesignMode ausgefuehrt wird
138 SetDesignMode( bInitDesignMode
);
142 FmFormView::~FmFormView()
145 pFormShell
->SetView( NULL
);
147 pImpl
->notifyViewDying();
153 FmFormPage
* FmFormView::GetCurPage()
155 SdrPageView
* pPageView
= GetSdrPageView();
156 FmFormPage
* pCurPage
= pPageView
? PTR_CAST( FmFormPage
, pPageView
->GetPage() ) : NULL
;
161 void FmFormView::MarkListHasChanged()
163 E3dView::MarkListHasChanged();
165 if ( pFormShell
&& IsDesignMode() )
167 FmFormObj
* pObj
= getMarkedGrid();
168 if ( pImpl
->m_pMarkedGrid
&& pImpl
->m_pMarkedGrid
!= pObj
)
170 pImpl
->m_pMarkedGrid
= NULL
;
171 if ( pImpl
->m_xWindow
.is() )
173 pImpl
->m_xWindow
->removeFocusListener(pImpl
);
174 pImpl
->m_xWindow
= NULL
;
176 SetMoveOutside(false);
177 //OLMRefreshAllIAOManagers();
180 pFormShell
->GetImpl()->SetSelectionDelayed();
186 const SdrPageWindow
* findPageWindow( const SdrPaintView
* _pView
, OutputDevice
* _pWindow
)
188 SdrPageView
* pPageView
= _pView
->GetSdrPageView();
191 for ( sal_uInt32 window
= 0; window
< pPageView
->PageWindowCount(); ++window
)
193 const SdrPageWindow
* pPageWindow
= pPageView
->GetPageWindow( window
);
194 if ( !pPageWindow
|| &pPageWindow
->GetPaintWindow().GetOutputDevice() != _pWindow
)
205 void FmFormView::AddWindowToPaintView(OutputDevice
* pNewWin
)
207 E3dView::AddWindowToPaintView(pNewWin
);
212 // look up the PageViewWindow for the newly inserted window, and care for it
213 // #i39269# / 2004-12-20 / frank.schoenheit@sun.com
214 const SdrPageWindow
* pPageWindow
= findPageWindow( this, pNewWin
);
216 pImpl
->addWindow( *pPageWindow
);
220 void FmFormView::DeleteWindowFromPaintView(OutputDevice
* pNewWin
)
222 const SdrPageWindow
* pPageWindow
= findPageWindow( this, pNewWin
);
224 pImpl
->removeWindow( pPageWindow
->GetControlContainer() );
226 E3dView::DeleteWindowFromPaintView(pNewWin
);
230 void FmFormView::ChangeDesignMode(bool bDesign
)
232 if (bDesign
== IsDesignMode())
235 FmFormModel
* pModel
= PTR_CAST(FmFormModel
, GetModel());
237 { // fuer die Zeit des Uebergangs das Undo-Environment ausschalten, das sichert, dass man dort auch nicht-transiente
238 // Properties mal eben aendern kann (sollte allerdings mit Vorsicht genossen und beim Rueckschalten des Modes
239 // auch immer wieder rueckgaegig gemacht werden. Ein Beispiel ist das Setzen der maximalen Text-Laenge durch das
240 // FmXEditModel an seinem Control.)
241 pModel
->GetUndoEnv().Lock();
244 // --- 1. deactivate all controls if we are switching to design mode
246 DeactivateControls( GetSdrPageView() );
248 // --- 2. simulate a deactivation (the shell will handle some things there ...?)
249 if ( pFormShell
&& pFormShell
->GetImpl() )
250 pFormShell
->GetImpl()->viewDeactivated( *this, true );
252 pImpl
->Deactivate( true );
254 // --- 3. activate all controls, if we're switching to alive mode
256 ActivateControls( GetSdrPageView() );
258 // --- 4. load resp. unload the forms
259 FmFormPage
* pCurPage
= GetCurPage();
262 if ( pFormShell
&& pFormShell
->GetImpl() )
263 pFormShell
->GetImpl()->loadForms( pCurPage
, ( bDesign
? FORMS_UNLOAD
: FORMS_LOAD
) );
266 // --- 5. base class functionality
267 SetDesignMode( bDesign
);
269 // --- 6. simulate a activation (the shell will handle some things there ...?)
270 OSL_PRECOND( pFormShell
&& pFormShell
->GetImpl(), "FmFormView::ChangeDesignMode: is this really allowed? No shell?" );
271 if ( pFormShell
&& pFormShell
->GetImpl() )
272 pFormShell
->GetImpl()->viewActivated( *this );
280 if ( GetActualOutDev() && GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW
)
282 const Window
* pWindow
= static_cast< const Window
* >( GetActualOutDev() );
283 const_cast< Window
* >( pWindow
)->GrabFocus();
286 // redraw UNO objects
287 if ( GetSdrPageView() )
289 SdrObjListIter
aIter(*pCurPage
);
290 while( aIter
.IsMore() )
292 SdrObject
* pObj
= aIter
.Next();
293 if (pObj
&& pObj
->IsUnoObj())
295 // For redraw just use ActionChanged()
296 // pObj->BroadcastObjectChange();
297 pObj
->ActionChanged();
304 // set the auto focus to the first control (if indicated by the model to do so)
305 bool bForceControlFocus
= pModel
? pModel
->GetAutoControlFocus() : sal_False
;
306 if (bForceControlFocus
)
311 // und mein Undo-Environment wieder an
313 pModel
->GetUndoEnv().UnLock();
317 void FmFormView::GrabFirstControlFocus( bool _bForceSync
)
319 if ( !IsDesignMode() )
320 pImpl
->AutoFocus( _bForceSync
);
324 SdrPageView
* FmFormView::ShowSdrPage(SdrPage
* pPage
)
326 SdrPageView
* pPV
= E3dView::ShowSdrPage(pPage
);
332 // creating the controllers
333 ActivateControls(pPV
);
335 // Alles deselektieren
338 else if ( pFormShell
&& pFormShell
->IsDesignMode() )
340 FmXFormShell
* pFormShellImpl
= pFormShell
->GetImpl();
341 pFormShellImpl
->UpdateForms( true );
343 // damit der Formular-Navigator auf den Seitenwechsel reagieren kann
344 pFormShell
->GetViewShell()->GetViewFrame()->GetBindings().Invalidate(SID_FM_FMEXPLORER_CONTROL
, true, false);
346 pFormShellImpl
->SetSelection(GetMarkedObjectList());
350 // notify our shell that we have been activated
351 if ( pFormShell
&& pFormShell
->GetImpl() )
352 pFormShell
->GetImpl()->viewActivated( *this );
360 void FmFormView::HideSdrPage()
362 // --- 1. deactivate controls
363 if ( !IsDesignMode() )
364 DeactivateControls(GetSdrPageView());
366 // --- 2. tell the shell the view is (going to be) deactivated
367 if ( pFormShell
&& pFormShell
->GetImpl() )
368 pFormShell
->GetImpl()->viewDeactivated( *this, true );
370 pImpl
->Deactivate( true );
372 // --- 3. base class behavior
373 E3dView::HideSdrPage();
377 SdrModel
* FmFormView::GetMarkedObjModel() const
379 return E3dView::GetMarkedObjModel();
383 bool FmFormView::Paste(const SdrModel
& rMod
, const Point
& rPos
, SdrObjList
* pLst
, sal_uInt32 nOptions
)
385 return E3dView::Paste(rMod
, rPos
, pLst
, nOptions
);
389 void FmFormView::ActivateControls(SdrPageView
* pPageView
)
394 for (sal_uInt32 i
= 0L; i
< pPageView
->PageWindowCount(); ++i
)
396 const SdrPageWindow
& rPageWindow
= *pPageView
->GetPageWindow(i
);
397 pImpl
->addWindow(rPageWindow
);
402 void FmFormView::DeactivateControls(SdrPageView
* pPageView
)
407 for (sal_uInt32 i
= 0L; i
< pPageView
->PageWindowCount(); ++i
)
409 const SdrPageWindow
& rPageWindow
= *pPageView
->GetPageWindow(i
);
410 pImpl
->removeWindow(rPageWindow
.GetControlContainer() );
415 SdrObject
* FmFormView::CreateFieldControl( const ODataAccessDescriptor
& _rColumnDescriptor
)
417 return pImpl
->implCreateFieldControl( _rColumnDescriptor
);
421 SdrObject
* FmFormView::CreateXFormsControl( const OXFormsDescriptor
&_rDesc
)
423 return pImpl
->implCreateXFormsControl(_rDesc
);
427 SdrObject
* FmFormView::CreateFieldControl(const OUString
& rFieldDesc
) const
429 OUString sDataSource
= rFieldDesc
.getToken(0,sal_Unicode(11));
430 OUString sObjectName
= rFieldDesc
.getToken(1,sal_Unicode(11));
431 sal_uInt16 nObjectType
= (sal_uInt16
)rFieldDesc
.getToken(2,sal_Unicode(11)).toInt32();
432 OUString sFieldName
= rFieldDesc
.getToken(3,sal_Unicode(11));
434 if (sFieldName
.isEmpty() || sObjectName
.isEmpty() || sDataSource
.isEmpty())
437 ODataAccessDescriptor aColumnDescriptor
;
438 aColumnDescriptor
.setDataSource(sDataSource
);
439 aColumnDescriptor
[ daCommand
] <<= sObjectName
;
440 aColumnDescriptor
[ daCommandType
] <<= nObjectType
;
441 aColumnDescriptor
[ daColumnName
] <<= sFieldName
;
443 return pImpl
->implCreateFieldControl( aColumnDescriptor
);
447 void FmFormView::InsertControlContainer(const Reference
< ::com::sun::star::awt::XControlContainer
> & xCC
)
449 if( !IsDesignMode() )
451 SdrPageView
* pPageView
= GetSdrPageView();
454 for( sal_uInt32 i
= 0L; i
< pPageView
->PageWindowCount(); i
++ )
456 const SdrPageWindow
& rPageWindow
= *pPageView
->GetPageWindow(i
);
458 if( rPageWindow
.GetControlContainer( false ) == xCC
)
460 pImpl
->addWindow(rPageWindow
);
469 void FmFormView::RemoveControlContainer(const Reference
< ::com::sun::star::awt::XControlContainer
> & xCC
)
471 if( !IsDesignMode() )
473 pImpl
->removeWindow( xCC
);
478 SdrPaintWindow
* FmFormView::BeginCompleteRedraw(OutputDevice
* pOut
)
480 SdrPaintWindow
* pPaintWindow
= E3dView::BeginCompleteRedraw( pOut
);
481 pImpl
->suspendTabOrderUpdate();
486 void FmFormView::EndCompleteRedraw( SdrPaintWindow
& rPaintWindow
, bool bPaintFormLayer
)
488 E3dView::EndCompleteRedraw( rPaintWindow
, bPaintFormLayer
);
489 pImpl
->resumeTabOrderUpdate();
493 bool FmFormView::KeyInput(const KeyEvent
& rKEvt
, Window
* pWin
)
496 const KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
498 && rKeyCode
.GetCode() == KEY_RETURN
501 // RETURN alone enters grid controls, for keyboard accessibility
503 && !rKeyCode
.IsShift()
504 && !rKeyCode
.IsMod1()
505 && !rKeyCode
.IsMod2()
508 FmFormObj
* pObj
= getMarkedGrid();
511 Reference
< awt::XWindow
> xWindow( pObj
->GetUnoControl( *this, *pWin
), UNO_QUERY
);
514 pImpl
->m_pMarkedGrid
= pObj
;
515 pImpl
->m_xWindow
= xWindow
;
516 // add as listener to get notified when ESC will be pressed inside the grid
517 pImpl
->m_xWindow
->addFocusListener(pImpl
);
518 SetMoveOutside(true);
519 //OLMRefreshAllIAOManagers();
525 // Alt-RETURN alone shows the properties of the selection
527 && pFormShell
->GetImpl()
528 && !rKeyCode
.IsShift()
529 && !rKeyCode
.IsMod1()
533 pFormShell
->GetImpl()->handleShowPropertiesRequest();
539 bDone
= E3dView::KeyInput(rKEvt
,pWin
);
543 bool FmFormView::checkUnMarkAll(const Reference
< XInterface
>& _xSource
)
545 Reference
< ::com::sun::star::awt::XControl
> xControl(pImpl
->m_xWindow
,UNO_QUERY
);
546 bool bRet
= !xControl
.is() || !_xSource
.is() || _xSource
!= xControl
->getModel();
554 bool FmFormView::MouseButtonDown( const MouseEvent
& _rMEvt
, Window
* _pWin
)
556 bool bReturn
= E3dView::MouseButtonDown( _rMEvt
, _pWin
);
558 if ( pFormShell
&& pFormShell
->GetImpl() )
560 SdrViewEvent aViewEvent
;
561 PickAnything( _rMEvt
, SDRMOUSEBUTTONDOWN
, aViewEvent
);
562 pFormShell
->GetImpl()->handleMouseButtonDown( aViewEvent
);
569 FmFormObj
* FmFormView::getMarkedGrid() const
571 FmFormObj
* pFormObject
= NULL
;
572 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
573 if ( 1 == rMarkList
.GetMarkCount() )
575 SdrMark
* pMark
= rMarkList
.GetMark(0);
578 pFormObject
= FmFormObj::GetFormObject( pMark
->GetMarkedSdrObj() );
581 Reference
< XServiceInfo
> xServInfo( pFormObject
->GetUnoControlModel(), UNO_QUERY
);
582 if ( !xServInfo
.is() || !xServInfo
->supportsService( FM_SUN_COMPONENT_GRIDCONTROL
) )
591 void FmFormView::createControlLabelPair( OutputDevice
* _pOutDev
, sal_Int32 _nXOffsetMM
, sal_Int32 _nYOffsetMM
,
592 const Reference
< XPropertySet
>& _rxField
, const Reference
< XNumberFormats
>& _rxNumberFormats
,
593 sal_uInt16 _nControlObjectID
, const OUString
& _rFieldPostfix
, sal_uInt32 _nInventor
, sal_uInt16 _nLabelObjectID
,
594 SdrPage
* _pLabelPage
, SdrPage
* _pControlPage
, SdrModel
* _pModel
, SdrUnoObj
*& _rpLabel
, SdrUnoObj
*& _rpControl
)
596 FmXFormView::createControlLabelPair(
597 *_pOutDev
, _nXOffsetMM
, _nYOffsetMM
,
598 _rxField
, _rxNumberFormats
,
599 _nControlObjectID
, _rFieldPostfix
, _nInventor
, _nLabelObjectID
,
600 _pLabelPage
, _pControlPage
, _pModel
,
605 Reference
< runtime::XFormController
> FmFormView::GetFormController( const Reference
< XForm
>& _rxForm
, const OutputDevice
& _rDevice
) const
607 return pImpl
->getFormController( _rxForm
, _rDevice
);
610 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */