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
= static_cast<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-construction 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
) == SfxItemState::SET
)
128 ::comphelper::NamedValueCollection
aComponentData( static_cast<const SfxUnoAnyItem
*>(pItem
)->GetValue() );
129 bInitDesignMode
= aComponentData
.getOrDefault( "ApplyFormDesignMode", bInitDesignMode
);
133 // dieses wird in der Shell vorgenommen
134 // bDesignMode = !bInitDesignMode; // erzwingt, dass SetDesignMode ausgefuehrt wird
135 SetDesignMode( bInitDesignMode
);
139 FmFormView::~FmFormView()
142 pFormShell
->SetView( NULL
);
144 pImpl
->notifyViewDying();
150 FmFormPage
* FmFormView::GetCurPage()
152 SdrPageView
* pPageView
= GetSdrPageView();
153 FmFormPage
* pCurPage
= pPageView
? PTR_CAST( FmFormPage
, pPageView
->GetPage() ) : NULL
;
158 void FmFormView::MarkListHasChanged()
160 E3dView::MarkListHasChanged();
162 if ( pFormShell
&& IsDesignMode() )
164 FmFormObj
* pObj
= getMarkedGrid();
165 if ( pImpl
->m_pMarkedGrid
&& pImpl
->m_pMarkedGrid
!= pObj
)
167 pImpl
->m_pMarkedGrid
= NULL
;
168 if ( pImpl
->m_xWindow
.is() )
170 pImpl
->m_xWindow
->removeFocusListener(pImpl
);
171 pImpl
->m_xWindow
= NULL
;
173 SetMoveOutside(false);
174 //OLMRefreshAllIAOManagers();
177 pFormShell
->GetImpl()->SetSelectionDelayed();
183 const SdrPageWindow
* findPageWindow( const SdrPaintView
* _pView
, OutputDevice
* _pWindow
)
185 SdrPageView
* pPageView
= _pView
->GetSdrPageView();
188 for ( sal_uInt32 window
= 0; window
< pPageView
->PageWindowCount(); ++window
)
190 const SdrPageWindow
* pPageWindow
= pPageView
->GetPageWindow( window
);
191 if ( !pPageWindow
|| &pPageWindow
->GetPaintWindow().GetOutputDevice() != _pWindow
)
202 void FmFormView::AddWindowToPaintView(OutputDevice
* pNewWin
, vcl::Window
* pWindow
)
204 E3dView::AddWindowToPaintView(pNewWin
, pWindow
);
209 // look up the PageViewWindow for the newly inserted window, and care for it
210 // #i39269# / 2004-12-20 / frank.schoenheit@sun.com
211 const SdrPageWindow
* pPageWindow
= findPageWindow( this, pNewWin
);
213 pImpl
->addWindow( *pPageWindow
);
217 void FmFormView::DeleteWindowFromPaintView(OutputDevice
* pNewWin
)
219 const SdrPageWindow
* pPageWindow
= findPageWindow( this, pNewWin
);
221 pImpl
->removeWindow( pPageWindow
->GetControlContainer() );
223 E3dView::DeleteWindowFromPaintView(pNewWin
);
227 void FmFormView::ChangeDesignMode(bool bDesign
)
229 if (bDesign
== IsDesignMode())
232 FmFormModel
* pModel
= PTR_CAST(FmFormModel
, GetModel());
234 { // fuer die Zeit des Uebergangs das Undo-Environment ausschalten, das sichert, dass man dort auch nicht-transiente
235 // Properties mal eben aendern kann (sollte allerdings mit Vorsicht genossen und beim Rueckschalten des Modes
236 // auch immer wieder rueckgaegig gemacht werden. Ein Beispiel ist das Setzen der maximalen Text-Laenge durch das
237 // FmXEditModel an seinem Control.)
238 pModel
->GetUndoEnv().Lock();
241 // --- 1. deactivate all controls if we are switching to design mode
243 DeactivateControls( GetSdrPageView() );
245 // --- 2. simulate a deactivation (the shell will handle some things there ...?)
246 if ( pFormShell
&& pFormShell
->GetImpl() )
247 pFormShell
->GetImpl()->viewDeactivated( *this, true );
249 pImpl
->Deactivate( true );
251 // --- 3. activate all controls, if we're switching to alive mode
253 ActivateControls( GetSdrPageView() );
255 // --- 4. load resp. unload the forms
256 FmFormPage
* pCurPage
= GetCurPage();
259 if ( pFormShell
&& pFormShell
->GetImpl() )
260 pFormShell
->GetImpl()->loadForms( pCurPage
, ( bDesign
? FORMS_UNLOAD
: FORMS_LOAD
) );
263 // --- 5. base class functionality
264 SetDesignMode( bDesign
);
266 // --- 6. simulate a activation (the shell will handle some things there ...?)
267 OSL_PRECOND( pFormShell
&& pFormShell
->GetImpl(), "FmFormView::ChangeDesignMode: is this really allowed? No shell?" );
268 if ( pFormShell
&& pFormShell
->GetImpl() )
269 pFormShell
->GetImpl()->viewActivated( *this );
277 if ( GetActualOutDev() && GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW
)
279 const vcl::Window
* pWindow
= static_cast< const vcl::Window
* >( GetActualOutDev() );
280 const_cast< vcl::Window
* >( pWindow
)->GrabFocus();
283 // redraw UNO objects
284 if ( GetSdrPageView() )
286 SdrObjListIter
aIter(*pCurPage
);
287 while( aIter
.IsMore() )
289 SdrObject
* pObj
= aIter
.Next();
290 if (pObj
&& pObj
->IsUnoObj())
292 // For redraw just use ActionChanged()
293 // pObj->BroadcastObjectChange();
294 pObj
->ActionChanged();
301 // set the auto focus to the first control (if indicated by the model to do so)
302 bool bForceControlFocus
= pModel
&& pModel
->GetAutoControlFocus();
303 if (bForceControlFocus
)
308 // und mein Undo-Environment wieder an
310 pModel
->GetUndoEnv().UnLock();
314 void FmFormView::GrabFirstControlFocus( bool _bForceSync
)
316 if ( !IsDesignMode() )
317 pImpl
->AutoFocus( _bForceSync
);
321 SdrPageView
* FmFormView::ShowSdrPage(SdrPage
* pPage
)
323 SdrPageView
* pPV
= E3dView::ShowSdrPage(pPage
);
329 // creating the controllers
330 ActivateControls(pPV
);
332 // Alles deselektieren
335 else if ( pFormShell
&& pFormShell
->IsDesignMode() )
337 FmXFormShell
* pFormShellImpl
= pFormShell
->GetImpl();
338 pFormShellImpl
->UpdateForms( true );
340 // damit der Formular-Navigator auf den Seitenwechsel reagieren kann
341 pFormShell
->GetViewShell()->GetViewFrame()->GetBindings().Invalidate(SID_FM_FMEXPLORER_CONTROL
, true, false);
343 pFormShellImpl
->SetSelection(GetMarkedObjectList());
347 // notify our shell that we have been activated
348 if ( pFormShell
&& pFormShell
->GetImpl() )
349 pFormShell
->GetImpl()->viewActivated( *this );
357 void FmFormView::HideSdrPage()
359 // --- 1. deactivate controls
360 if ( !IsDesignMode() )
361 DeactivateControls(GetSdrPageView());
363 // --- 2. tell the shell the view is (going to be) deactivated
364 if ( pFormShell
&& pFormShell
->GetImpl() )
365 pFormShell
->GetImpl()->viewDeactivated( *this, true );
367 pImpl
->Deactivate( true );
369 // --- 3. base class behavior
370 E3dView::HideSdrPage();
374 SdrModel
* FmFormView::GetMarkedObjModel() const
376 return E3dView::GetMarkedObjModel();
379 void FmFormView::ActivateControls(SdrPageView
* pPageView
)
384 for (sal_uInt32 i
= 0L; i
< pPageView
->PageWindowCount(); ++i
)
386 const SdrPageWindow
& rPageWindow
= *pPageView
->GetPageWindow(i
);
387 pImpl
->addWindow(rPageWindow
);
392 void FmFormView::DeactivateControls(SdrPageView
* pPageView
)
397 for (sal_uInt32 i
= 0L; i
< pPageView
->PageWindowCount(); ++i
)
399 const SdrPageWindow
& rPageWindow
= *pPageView
->GetPageWindow(i
);
400 pImpl
->removeWindow(rPageWindow
.GetControlContainer() );
405 SdrObject
* FmFormView::CreateFieldControl( const ODataAccessDescriptor
& _rColumnDescriptor
)
407 return pImpl
->implCreateFieldControl( _rColumnDescriptor
);
411 SdrObject
* FmFormView::CreateXFormsControl( const OXFormsDescriptor
&_rDesc
)
413 return pImpl
->implCreateXFormsControl(_rDesc
);
417 SdrObject
* FmFormView::CreateFieldControl(const OUString
& rFieldDesc
) const
419 OUString sDataSource
= rFieldDesc
.getToken(0,sal_Unicode(11));
420 OUString sObjectName
= rFieldDesc
.getToken(1,sal_Unicode(11));
421 sal_uInt16 nObjectType
= (sal_uInt16
)rFieldDesc
.getToken(2,sal_Unicode(11)).toInt32();
422 OUString sFieldName
= rFieldDesc
.getToken(3,sal_Unicode(11));
424 if (sFieldName
.isEmpty() || sObjectName
.isEmpty() || sDataSource
.isEmpty())
427 ODataAccessDescriptor aColumnDescriptor
;
428 aColumnDescriptor
.setDataSource(sDataSource
);
429 aColumnDescriptor
[ daCommand
] <<= sObjectName
;
430 aColumnDescriptor
[ daCommandType
] <<= nObjectType
;
431 aColumnDescriptor
[ daColumnName
] <<= sFieldName
;
433 return pImpl
->implCreateFieldControl( aColumnDescriptor
);
437 void FmFormView::InsertControlContainer(const Reference
< ::com::sun::star::awt::XControlContainer
> & xCC
)
439 if( !IsDesignMode() )
441 SdrPageView
* pPageView
= GetSdrPageView();
444 for( sal_uInt32 i
= 0L; i
< pPageView
->PageWindowCount(); i
++ )
446 const SdrPageWindow
& rPageWindow
= *pPageView
->GetPageWindow(i
);
448 if( rPageWindow
.GetControlContainer( false ) == xCC
)
450 pImpl
->addWindow(rPageWindow
);
459 void FmFormView::RemoveControlContainer(const Reference
< ::com::sun::star::awt::XControlContainer
> & xCC
)
461 if( !IsDesignMode() )
463 pImpl
->removeWindow( xCC
);
468 SdrPaintWindow
* FmFormView::BeginCompleteRedraw(OutputDevice
* pOut
)
470 SdrPaintWindow
* pPaintWindow
= E3dView::BeginCompleteRedraw( pOut
);
471 pImpl
->suspendTabOrderUpdate();
476 void FmFormView::EndCompleteRedraw( SdrPaintWindow
& rPaintWindow
, bool bPaintFormLayer
)
478 E3dView::EndCompleteRedraw( rPaintWindow
, bPaintFormLayer
);
479 pImpl
->resumeTabOrderUpdate();
483 bool FmFormView::KeyInput(const KeyEvent
& rKEvt
, vcl::Window
* pWin
)
486 const vcl::KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
488 && rKeyCode
.GetCode() == KEY_RETURN
491 // RETURN alone enters grid controls, for keyboard accessibility
493 && !rKeyCode
.IsShift()
494 && !rKeyCode
.IsMod1()
495 && !rKeyCode
.IsMod2()
498 FmFormObj
* pObj
= getMarkedGrid();
501 Reference
< awt::XWindow
> xWindow( pObj
->GetUnoControl( *this, *pWin
), UNO_QUERY
);
504 pImpl
->m_pMarkedGrid
= pObj
;
505 pImpl
->m_xWindow
= xWindow
;
506 // add as listener to get notified when ESC will be pressed inside the grid
507 pImpl
->m_xWindow
->addFocusListener(pImpl
);
508 SetMoveOutside(true);
509 //OLMRefreshAllIAOManagers();
515 // Alt-RETURN alone shows the properties of the selection
517 && pFormShell
->GetImpl()
518 && !rKeyCode
.IsShift()
519 && !rKeyCode
.IsMod1()
523 pFormShell
->GetImpl()->handleShowPropertiesRequest();
529 bDone
= E3dView::KeyInput(rKEvt
,pWin
);
533 bool FmFormView::checkUnMarkAll(const Reference
< XInterface
>& _xSource
)
535 Reference
< ::com::sun::star::awt::XControl
> xControl(pImpl
->m_xWindow
,UNO_QUERY
);
536 bool bRet
= !xControl
.is() || !_xSource
.is() || _xSource
!= xControl
->getModel();
544 bool FmFormView::MouseButtonDown( const MouseEvent
& _rMEvt
, vcl::Window
* _pWin
)
546 bool bReturn
= E3dView::MouseButtonDown( _rMEvt
, _pWin
);
548 if ( pFormShell
&& pFormShell
->GetImpl() )
550 SdrViewEvent aViewEvent
;
551 PickAnything( _rMEvt
, SdrMouseEventKind::BUTTONDOWN
, aViewEvent
);
552 pFormShell
->GetImpl()->handleMouseButtonDown( aViewEvent
);
559 FmFormObj
* FmFormView::getMarkedGrid() const
561 FmFormObj
* pFormObject
= NULL
;
562 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
563 if ( 1 == rMarkList
.GetMarkCount() )
565 SdrMark
* pMark
= rMarkList
.GetMark(0);
568 pFormObject
= FmFormObj::GetFormObject( pMark
->GetMarkedSdrObj() );
571 Reference
< XServiceInfo
> xServInfo( pFormObject
->GetUnoControlModel(), UNO_QUERY
);
572 if ( !xServInfo
.is() || !xServInfo
->supportsService( FM_SUN_COMPONENT_GRIDCONTROL
) )
581 void FmFormView::createControlLabelPair( OutputDevice
* _pOutDev
, sal_Int32 _nXOffsetMM
, sal_Int32 _nYOffsetMM
,
582 const Reference
< XPropertySet
>& _rxField
, const Reference
< XNumberFormats
>& _rxNumberFormats
,
583 sal_uInt16 _nControlObjectID
, const OUString
& _rFieldPostfix
, sal_uInt32 _nInventor
, sal_uInt16 _nLabelObjectID
,
584 SdrPage
* _pLabelPage
, SdrPage
* _pControlPage
, SdrModel
* _pModel
, SdrUnoObj
*& _rpLabel
, SdrUnoObj
*& _rpControl
)
586 FmXFormView::createControlLabelPair(
587 *_pOutDev
, _nXOffsetMM
, _nYOffsetMM
,
588 _rxField
, _rxNumberFormats
,
589 _nControlObjectID
, _rFieldPostfix
, _nInventor
, _nLabelObjectID
,
590 _pLabelPage
, _pControlPage
, _pModel
,
595 Reference
< runtime::XFormController
> FmFormView::GetFormController( const Reference
< XForm
>& _rxForm
, const OutputDevice
& _rDevice
) const
597 return pImpl
->getFormController( _rxForm
, _rDevice
);
600 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */