merge the formfield patch from ooo-build
[ooovba.git] / svx / source / form / fmview.cxx
blob26a5ecd7ddacf10894acc46e75beb0374722f2f5
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fmview.cxx,v $
10 * $Revision: 1.55 $
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>
34 #ifdef REFERENCE
35 #undef REFERENCE
36 #endif
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"
55 #include "fmobj.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"
67 #include "fmprop.hrc"
68 #include "fmundo.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)
104 Init();
107 //------------------------------------------------------------------------
108 void FmFormView::Init()
110 pFormShell = NULL;
111 pImpl = new FmXFormView(::comphelper::getProcessServiceFactory(),this);
112 pImpl->acquire();
114 //////////////////////////////////////////////////////////////////////
115 // Model setzen
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()
163 if( pFormShell )
164 pFormShell->SetView( NULL );
166 pImpl->notifyViewDying();
167 pImpl->release();
168 pImpl = NULL;
171 //------------------------------------------------------------------------
172 FmFormPage* FmFormView::GetCurPage()
174 SdrPageView* pPageView = GetSdrPageView();
175 FmFormPage* pCurPage = pPageView ? PTR_CAST( FmFormPage, pPageView->GetPage() ) : NULL;
176 return pCurPage;
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();
203 namespace
205 const SdrPageWindow* findPageWindow( const SdrPaintView* _pView, OutputDevice* _pWindow )
207 SdrPageView* pPageView = _pView->GetSdrPageView();
208 if(pPageView)
210 for ( sal_uInt32 window = 0; window < pPageView->PageWindowCount(); ++window )
212 const SdrPageWindow* pPageWindow = pPageView->GetPageWindow( window );
213 if ( !pPageWindow || &pPageWindow->GetPaintWindow().GetOutputDevice() != _pWindow )
214 continue;
216 return pPageWindow;
219 return NULL;
223 //------------------------------------------------------------------------
224 void FmFormView::AddWindowToPaintView(OutputDevice* pNewWin)
226 E3dView::AddWindowToPaintView(pNewWin);
228 if ( !pNewWin )
229 return;
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 );
234 if ( pPageWindow )
235 pImpl->addWindow( *pPageWindow );
238 //------------------------------------------------------------------------
239 void FmFormView::DeleteWindowFromPaintView(OutputDevice* pNewWin)
241 const SdrPageWindow* pPageWindow = findPageWindow( this, pNewWin );
242 if ( pPageWindow )
243 pImpl->removeWindow( pPageWindow->GetControlContainer() );
245 E3dView::DeleteWindowFromPaintView(pNewWin);
248 //------------------------------------------------------------------------
249 void FmFormView::ChangeDesignMode(sal_Bool bDesign)
251 if (bDesign == IsDesignMode())
252 return;
254 FmFormModel* pModel = PTR_CAST(FmFormModel, GetModel());
255 if (pModel)
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
264 if ( bDesign )
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 );
270 else
271 pImpl->Deactivate( sal_True );
273 // --- 3. activate all controls, if we're switching to alive mode
274 if ( !bDesign )
275 ActivateControls( GetSdrPageView() );
277 // --- 4. load resp. unload the forms
278 FmFormPage* pCurPage = GetCurPage();
279 if ( pCurPage )
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 );
292 else
293 pImpl->Activate();
295 if ( pCurPage )
297 if ( bDesign )
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();
321 else
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)
326 pImpl->AutoFocus();
330 // und mein Undo-Environment wieder an
331 if (pModel)
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);
349 if (pPage)
351 if (!IsDesignMode())
353 // creating the controllers
354 ActivateControls(pPV);
356 // Alles deselektieren
357 UnmarkAll();
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 );
374 else
375 pImpl->Activate();
377 return pPV;
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 );
392 else
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)
414 if (!pPageView)
415 return;
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)
427 if( !pPageView )
428 return;
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())
458 return NULL;
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();
475 if( pPageView )
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);
484 break;
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();
505 return pPaintWindow;
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)
518 BOOL bDone = FALSE;
519 const KeyCode& rKeyCode = rKEvt.GetKeyCode();
520 if ( IsDesignMode()
521 && rKeyCode.GetCode() == KEY_RETURN
524 // RETURN alone enters grid controls, for keyboard accessibility
525 if ( pWin
526 && !rKeyCode.IsShift()
527 && !rKeyCode.IsMod1()
528 && !rKeyCode.IsMod2()
531 FmFormObj* pObj = getMarkedGrid();
532 if ( pObj )
534 Reference< awt::XWindow > xWindow( pObj->GetUnoControl( *this, *pWin ), UNO_QUERY );
535 if ( xWindow.is() )
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();
543 xWindow->setFocus();
544 bDone = TRUE;
548 // Alt-RETURN alone shows the properties of the selection
549 if ( pFormShell
550 && pFormShell->GetImpl()
551 && !rKeyCode.IsShift()
552 && !rKeyCode.IsMod1()
553 && rKeyCode.IsMod2()
556 pFormShell->GetImpl()->handleShowPropertiesRequest();
561 if ( !bDone )
562 bDone = E3dView::KeyInput(rKEvt,pWin);
563 return bDone;
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();
570 if ( bRet )
571 UnmarkAll();
573 return bRet;
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 );
588 return bReturn;
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);
599 if ( pMark )
601 pFormObject = FmFormObj::GetFormObject( pMark->GetMarkedSdrObj() );
602 if ( pFormObject )
604 Reference< XServiceInfo > xServInfo( pFormObject->GetUnoControlModel(), UNO_QUERY );
605 if ( !xServInfo.is() || !xServInfo->supportsService( FM_SUN_COMPONENT_GRIDCONTROL ) )
606 pFormObject = NULL;
610 return pFormObject;
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,
625 _rpLabel, _rpControl
628 // -----------------------------------------------------------------------------
629 Reference< XFormController > FmFormView::GetFormController( const Reference< XForm >& _rxForm, const OutputDevice& _rDevice ) const
631 return pImpl->getFormController( _rxForm, _rDevice );