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>
41 #include <svx/svditer.hxx>
42 #include <svx/svdpagv.hxx>
43 #include <svx/svdogrp.hxx>
44 #include <svx/fmview.hxx>
45 #include <svx/fmmodel.hxx>
46 #include <svx/fmpage.hxx>
47 #include <svx/fmshell.hxx>
48 #include <fmpgeimp.hxx>
49 #include <svx/fmtools.hxx>
50 #include <fmshimp.hxx>
51 #include <fmservs.hxx>
54 #include <svx/dataaccessdescriptor.hxx>
55 #include <comphelper/namedvaluecollection.hxx>
56 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
57 #include <com/sun/star/beans/PropertyValue.hpp>
58 #include <com/sun/star/beans/PropertyState.hpp>
59 #include <com/sun/star/form/FormComponentType.hpp>
60 #include <vcl/svapp.hxx>
61 #include <tools/debug.hxx>
62 #include <tools/diagnose_ex.h>
63 #include <vcl/stdtext.hxx>
64 #include <svx/fmglob.hxx>
65 #include <svx/sdrpagewindow.hxx>
66 #include <svx/sdrpaintwindow.hxx>
68 using namespace ::com::sun::star
;
69 using namespace ::com::sun::star::uno
;
70 using namespace ::com::sun::star::lang
;
71 using namespace ::com::sun::star::sdbc
;
72 using namespace ::com::sun::star::sdb
;
73 using namespace ::com::sun::star::beans
;
74 using namespace ::com::sun::star::container
;
75 using namespace ::com::sun::star::form
;
76 using namespace ::com::sun::star::util
;
77 using namespace ::svxform
;
78 using namespace ::svx
;
80 FmFormView::FmFormView(
83 : E3dView(rSdrModel
, pOut
)
88 void FmFormView::Init()
91 pImpl
= new FmXFormView(this);
94 SdrModel
* pModel
= GetModel();
96 DBG_ASSERT( dynamic_cast<const FmFormModel
*>( pModel
) != nullptr, "Wrong model" );
97 if( dynamic_cast<const FmFormModel
*>( pModel
) == nullptr ) return;
98 FmFormModel
* pFormModel
= static_cast<FmFormModel
*>(pModel
);
101 // get DesignMode from model
102 bool bInitDesignMode
= pFormModel
->GetOpenInDesignMode();
103 if ( pFormModel
->OpenInDesignModeIsDefaulted( ) )
104 { // this means that nobody ever explicitly set this on the model, and the model has never
105 // been loaded from a stream.
106 // This means this is a newly created document. This means, we want to have it in design
107 // mode by default (though a newly created model returns true for GetOpenInDesignMode).
108 // We _want_ to have this because it makes a lot of hacks following the original fix
109 DBG_ASSERT( !bInitDesignMode
, "FmFormView::Init: doesn't the model default to FALSE anymore?" );
110 // if this asserts, either the on-construction default in the model has changed (then this here
111 // may not be necessary anymore), or we're not dealing with a new document...
112 bInitDesignMode
= true;
115 SfxObjectShell
* pObjShell
= pFormModel
->GetObjectShell();
116 if ( pObjShell
&& pObjShell
->GetMedium() )
118 const SfxPoolItem
*pItem
=nullptr;
119 if ( pObjShell
->GetMedium()->GetItemSet()->GetItemState( SID_COMPONENTDATA
, false, &pItem
) == SfxItemState::SET
)
121 ::comphelper::NamedValueCollection
aComponentData( static_cast<const SfxUnoAnyItem
*>(pItem
)->GetValue() );
122 bInitDesignMode
= aComponentData
.getOrDefault( "ApplyFormDesignMode", bInitDesignMode
);
126 // this will be done in the shell
127 // bDesignMode = !bInitDesignMode; // forces execution of SetDesignMode
128 SetDesignMode( bInitDesignMode
);
132 FmFormView::~FmFormView()
135 pFormShell
->SetView( nullptr );
137 pImpl
->notifyViewDying();
141 FmFormPage
* FmFormView::GetCurPage()
143 SdrPageView
* pPageView
= GetSdrPageView();
144 FmFormPage
* pCurPage
= pPageView
? dynamic_cast<FmFormPage
*>( pPageView
->GetPage() ) : nullptr;
149 void FmFormView::MarkListHasChanged()
151 E3dView::MarkListHasChanged();
153 if ( pFormShell
&& IsDesignMode() )
155 FmFormObj
* pObj
= getMarkedGrid();
156 if ( pImpl
->m_pMarkedGrid
&& pImpl
->m_pMarkedGrid
!= pObj
)
158 pImpl
->m_pMarkedGrid
= nullptr;
159 if ( pImpl
->m_xWindow
.is() )
161 pImpl
->m_xWindow
->removeFocusListener(pImpl
.get());
162 pImpl
->m_xWindow
= nullptr;
164 SetMoveOutside(false);
165 //OLMRefreshAllIAOManagers();
168 pFormShell
->GetImpl()->SetSelectionDelayed_Lock();
174 const SdrPageWindow
* findPageWindow( const SdrPaintView
* _pView
, OutputDevice
const * _pWindow
)
176 SdrPageView
* pPageView
= _pView
->GetSdrPageView();
179 for ( sal_uInt32 window
= 0; window
< pPageView
->PageWindowCount(); ++window
)
181 const SdrPageWindow
* pPageWindow
= pPageView
->GetPageWindow( window
);
182 if ( !pPageWindow
|| &pPageWindow
->GetPaintWindow().GetOutputDevice() != _pWindow
)
193 void FmFormView::AddWindowToPaintView(OutputDevice
* pNewWin
, vcl::Window
* pWindow
)
195 E3dView::AddWindowToPaintView(pNewWin
, pWindow
);
200 // look up the PageViewWindow for the newly inserted window, and care for it
201 // #i39269# / 2004-12-20 / frank.schoenheit@sun.com
202 const SdrPageWindow
* pPageWindow
= findPageWindow( this, pNewWin
);
204 pImpl
->addWindow( *pPageWindow
);
208 void FmFormView::DeleteWindowFromPaintView(OutputDevice
* pNewWin
)
210 const SdrPageWindow
* pPageWindow
= findPageWindow( this, pNewWin
);
212 pImpl
->removeWindow( pPageWindow
->GetControlContainer() );
214 E3dView::DeleteWindowFromPaintView(pNewWin
);
218 void FmFormView::ChangeDesignMode(bool bDesign
)
220 if (bDesign
== IsDesignMode())
223 FmFormModel
* pModel
= dynamic_cast<FmFormModel
*>( GetModel() );
225 { // For the duration of the transition the Undo-Environment is disabled. This ensures that non-transient Properties can
226 // also be changed (this should be done with care and also reversed before switching the mode back. An example is the
227 // setting of the maximal length of the text by FmXEditModel on its control.)
228 pModel
->GetUndoEnv().Lock();
231 // --- 1. deactivate all controls if we are switching to design mode
233 DeactivateControls( GetSdrPageView() );
235 // --- 2. simulate a deactivation (the shell will handle some things there ...?)
236 if ( pFormShell
&& pFormShell
->GetImpl() )
237 pFormShell
->GetImpl()->viewDeactivated_Lock(*this);
241 // --- 3. activate all controls, if we're switching to alive mode
243 ActivateControls( GetSdrPageView() );
245 // --- 4. load resp. unload the forms
246 FmFormPage
* pCurPage
= GetCurPage();
249 if ( pFormShell
&& pFormShell
->GetImpl() )
250 pFormShell
->GetImpl()->loadForms_Lock(pCurPage
, (bDesign
? LoadFormsFlags::Unload
: LoadFormsFlags::Load
));
253 // --- 5. base class functionality
254 SetDesignMode( bDesign
);
256 // --- 6. simulate an activation (the shell will handle some things there ...?)
257 OSL_PRECOND( pFormShell
&& pFormShell
->GetImpl(), "FmFormView::ChangeDesignMode: is this really allowed? No shell?" );
258 if ( pFormShell
&& pFormShell
->GetImpl() )
259 pFormShell
->GetImpl()->viewActivated_Lock(*this);
267 if ( GetActualOutDev() && GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW
)
269 const vcl::Window
* pWindow
= static_cast< const vcl::Window
* >( GetActualOutDev() );
270 const_cast< vcl::Window
* >( pWindow
)->GrabFocus();
273 // redraw UNO objects
274 if ( GetSdrPageView() )
276 SdrObjListIter
aIter(pCurPage
);
277 while( aIter
.IsMore() )
279 SdrObject
* pObj
= aIter
.Next();
280 if (pObj
&& pObj
->IsUnoObj())
282 // For redraw just use ActionChanged()
283 // pObj->BroadcastObjectChange();
284 pObj
->ActionChanged();
291 // set the auto focus to the first control (if indicated by the model to do so)
292 bool bForceControlFocus
= pModel
&& pModel
->GetAutoControlFocus();
293 if (bForceControlFocus
)
298 // Unlock Undo-Environment
300 pModel
->GetUndoEnv().UnLock();
304 void FmFormView::GrabFirstControlFocus()
306 if ( !IsDesignMode() )
311 SdrPageView
* FmFormView::ShowSdrPage(SdrPage
* pPage
)
313 SdrPageView
* pPV
= E3dView::ShowSdrPage(pPage
);
319 // creating the controllers
320 ActivateControls(pPV
);
325 else if ( pFormShell
&& pFormShell
->IsDesignMode() )
327 FmXFormShell
* pFormShellImpl
= pFormShell
->GetImpl();
328 pFormShellImpl
->UpdateForms_Lock(true);
330 // so that the form navigator can react to the pagechange
331 pFormShell
->GetViewShell()->GetViewFrame()->GetBindings().Invalidate(SID_FM_FMEXPLORER_CONTROL
, true);
333 pFormShellImpl
->SetSelection_Lock(GetMarkedObjectList());
337 // notify our shell that we have been activated
338 if ( pFormShell
&& pFormShell
->GetImpl() )
339 pFormShell
->GetImpl()->viewActivated_Lock(*this);
347 void FmFormView::HideSdrPage()
349 // --- 1. deactivate controls
350 if ( !IsDesignMode() )
351 DeactivateControls(GetSdrPageView());
353 // --- 2. tell the shell the view is (going to be) deactivated
354 if ( pFormShell
&& pFormShell
->GetImpl() )
355 pFormShell
->GetImpl()->viewDeactivated_Lock(*this);
359 // --- 3. base class behavior
360 E3dView::HideSdrPage();
364 void FmFormView::ActivateControls(SdrPageView
const * pPageView
)
369 for (sal_uInt32 i
= 0; i
< pPageView
->PageWindowCount(); ++i
)
371 const SdrPageWindow
& rPageWindow
= *pPageView
->GetPageWindow(i
);
372 pImpl
->addWindow(rPageWindow
);
377 void FmFormView::DeactivateControls(SdrPageView
const * pPageView
)
382 for (sal_uInt32 i
= 0; i
< pPageView
->PageWindowCount(); ++i
)
384 const SdrPageWindow
& rPageWindow
= *pPageView
->GetPageWindow(i
);
385 pImpl
->removeWindow(rPageWindow
.GetControlContainer() );
390 SdrObjectUniquePtr
FmFormView::CreateFieldControl( const ODataAccessDescriptor
& _rColumnDescriptor
)
392 return pImpl
->implCreateFieldControl( _rColumnDescriptor
);
396 SdrObjectUniquePtr
FmFormView::CreateXFormsControl( const OXFormsDescriptor
&_rDesc
)
398 return pImpl
->implCreateXFormsControl(_rDesc
);
402 SdrObjectUniquePtr
FmFormView::CreateFieldControl(const OUString
& rFieldDesc
) const
405 OUString sDataSource
= rFieldDesc
.getToken(0, u
'\x000B', nIdx
);
406 OUString sObjectName
= rFieldDesc
.getToken(0, u
'\x000B', nIdx
);
407 sal_uInt16 nObjectType
= static_cast<sal_uInt16
>(rFieldDesc
.getToken(0, u
'\x000B', nIdx
).toInt32());
408 OUString sFieldName
= rFieldDesc
.getToken(0, u
'\x000B', nIdx
);
410 if (sFieldName
.isEmpty() || sObjectName
.isEmpty() || sDataSource
.isEmpty())
413 ODataAccessDescriptor aColumnDescriptor
;
414 aColumnDescriptor
.setDataSource(sDataSource
);
415 aColumnDescriptor
[ DataAccessDescriptorProperty::Command
] <<= sObjectName
;
416 aColumnDescriptor
[ DataAccessDescriptorProperty::CommandType
] <<= nObjectType
;
417 aColumnDescriptor
[ DataAccessDescriptorProperty::ColumnName
] <<= sFieldName
;
419 return pImpl
->implCreateFieldControl( aColumnDescriptor
);
423 void FmFormView::InsertControlContainer(const Reference
< css::awt::XControlContainer
> & xCC
)
425 if( !IsDesignMode() )
427 SdrPageView
* pPageView
= GetSdrPageView();
430 for( sal_uInt32 i
= 0; i
< pPageView
->PageWindowCount(); i
++ )
432 const SdrPageWindow
& rPageWindow
= *pPageView
->GetPageWindow(i
);
434 if( rPageWindow
.GetControlContainer( false ) == xCC
)
436 pImpl
->addWindow(rPageWindow
);
445 void FmFormView::RemoveControlContainer(const Reference
< css::awt::XControlContainer
> & xCC
)
447 if( !IsDesignMode() )
449 pImpl
->removeWindow( xCC
);
454 SdrPaintWindow
* FmFormView::BeginCompleteRedraw(OutputDevice
* pOut
)
456 SdrPaintWindow
* pPaintWindow
= E3dView::BeginCompleteRedraw( pOut
);
457 pImpl
->suspendTabOrderUpdate();
462 void FmFormView::EndCompleteRedraw( SdrPaintWindow
& rPaintWindow
, bool bPaintFormLayer
)
464 E3dView::EndCompleteRedraw( rPaintWindow
, bPaintFormLayer
);
465 pImpl
->resumeTabOrderUpdate();
469 bool FmFormView::KeyInput(const KeyEvent
& rKEvt
, vcl::Window
* pWin
)
472 const vcl::KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
474 && rKeyCode
.GetCode() == KEY_RETURN
477 // RETURN alone enters grid controls, for keyboard accessibility
479 && !rKeyCode
.IsShift()
480 && !rKeyCode
.IsMod1()
481 && !rKeyCode
.IsMod2()
484 FmFormObj
* pObj
= getMarkedGrid();
487 Reference
< awt::XWindow
> xWindow( pObj
->GetUnoControl( *this, *pWin
), UNO_QUERY
);
490 pImpl
->m_pMarkedGrid
= pObj
;
491 pImpl
->m_xWindow
= xWindow
;
492 // add as listener to get notified when ESC will be pressed inside the grid
493 pImpl
->m_xWindow
->addFocusListener(pImpl
.get());
494 SetMoveOutside(true);
495 //OLMRefreshAllIAOManagers();
501 // Alt-RETURN alone shows the properties of the selection
503 && pFormShell
->GetImpl()
504 && !rKeyCode
.IsShift()
505 && !rKeyCode
.IsMod1()
509 pFormShell
->GetImpl()->handleShowPropertiesRequest_Lock();
515 bDone
= E3dView::KeyInput(rKEvt
,pWin
);
519 bool FmFormView::checkUnMarkAll(const Reference
< XInterface
>& _xSource
)
521 Reference
< css::awt::XControl
> xControl(pImpl
->m_xWindow
,UNO_QUERY
);
522 bool bRet
= !xControl
.is() || !_xSource
.is() || _xSource
!= xControl
->getModel();
530 bool FmFormView::MouseButtonDown( const MouseEvent
& _rMEvt
, OutputDevice
* _pWin
)
532 bool bReturn
= E3dView::MouseButtonDown( _rMEvt
, _pWin
);
534 if ( pFormShell
&& pFormShell
->GetImpl() )
536 SdrViewEvent aViewEvent
;
537 PickAnything( _rMEvt
, SdrMouseEventKind::BUTTONDOWN
, aViewEvent
);
538 pFormShell
->GetImpl()->handleMouseButtonDown_Lock(aViewEvent
);
545 FmFormObj
* FmFormView::getMarkedGrid() const
547 FmFormObj
* pFormObject
= nullptr;
548 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
549 if ( 1 == rMarkList
.GetMarkCount() )
551 SdrMark
* pMark
= rMarkList
.GetMark(0);
554 pFormObject
= FmFormObj::GetFormObject( pMark
->GetMarkedSdrObj() );
557 Reference
< XServiceInfo
> xServInfo( pFormObject
->GetUnoControlModel(), UNO_QUERY
);
558 if ( !xServInfo
.is() || !xServInfo
->supportsService( FM_SUN_COMPONENT_GRIDCONTROL
) )
559 pFormObject
= nullptr;
567 void FmFormView::createControlLabelPair( OutputDevice
const * _pOutDev
, sal_Int32 _nXOffsetMM
, sal_Int32 _nYOffsetMM
,
568 const Reference
< XPropertySet
>& _rxField
, const Reference
< XNumberFormats
>& _rxNumberFormats
,
569 sal_uInt16 _nControlObjectID
, SdrInventor _nInventor
, sal_uInt16 _nLabelObjectID
,
571 std::unique_ptr
<SdrUnoObj
, SdrObjectFreeOp
>& _rpLabel
,
572 std::unique_ptr
<SdrUnoObj
, SdrObjectFreeOp
>& _rpControl
)
574 FmXFormView::createControlLabelPair(
575 *_pOutDev
, _nXOffsetMM
, _nYOffsetMM
,
576 _rxField
, _rxNumberFormats
,
577 _nControlObjectID
, "", _nInventor
, _nLabelObjectID
,
583 Reference
< runtime::XFormController
> FmFormView::GetFormController( const Reference
< XForm
>& _rxForm
, const OutputDevice
& _rDevice
) const
585 return pImpl
->getFormController( _rxForm
, _rDevice
);
588 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */