bump product version to 5.0.4.1
[LibreOffice.git] / svx / source / form / fmview.cxx
blob26a0c09f841163fdc9869be6715e5e4528e05339
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
21 #ifdef REFERENCE
22 #undef REFERENCE
23 #endif
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"
41 #include "fmobj.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"
53 #include "fmprop.hrc"
54 #include "fmundo.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 )
87 :E3dView(pModel,pOut)
89 Init();
93 void FmFormView::Init()
95 pFormShell = NULL;
96 pImpl = new FmXFormView(this);
97 pImpl->acquire();
100 // Model setzen
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()
141 if( pFormShell )
142 pFormShell->SetView( NULL );
144 pImpl->notifyViewDying();
145 pImpl->release();
146 pImpl = NULL;
150 FmFormPage* FmFormView::GetCurPage()
152 SdrPageView* pPageView = GetSdrPageView();
153 FmFormPage* pCurPage = pPageView ? PTR_CAST( FmFormPage, pPageView->GetPage() ) : NULL;
154 return pCurPage;
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();
181 namespace
183 const SdrPageWindow* findPageWindow( const SdrPaintView* _pView, OutputDevice* _pWindow )
185 SdrPageView* pPageView = _pView->GetSdrPageView();
186 if(pPageView)
188 for ( sal_uInt32 window = 0; window < pPageView->PageWindowCount(); ++window )
190 const SdrPageWindow* pPageWindow = pPageView->GetPageWindow( window );
191 if ( !pPageWindow || &pPageWindow->GetPaintWindow().GetOutputDevice() != _pWindow )
192 continue;
194 return pPageWindow;
197 return NULL;
202 void FmFormView::AddWindowToPaintView(OutputDevice* pNewWin, vcl::Window* pWindow)
204 E3dView::AddWindowToPaintView(pNewWin, pWindow);
206 if ( !pNewWin )
207 return;
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 );
212 if ( pPageWindow )
213 pImpl->addWindow( *pPageWindow );
217 void FmFormView::DeleteWindowFromPaintView(OutputDevice* pNewWin)
219 const SdrPageWindow* pPageWindow = findPageWindow( this, pNewWin );
220 if ( pPageWindow )
221 pImpl->removeWindow( pPageWindow->GetControlContainer() );
223 E3dView::DeleteWindowFromPaintView(pNewWin);
227 void FmFormView::ChangeDesignMode(bool bDesign)
229 if (bDesign == IsDesignMode())
230 return;
232 FmFormModel* pModel = PTR_CAST(FmFormModel, GetModel());
233 if (pModel)
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
242 if ( bDesign )
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 );
248 else
249 pImpl->Deactivate( true );
251 // --- 3. activate all controls, if we're switching to alive mode
252 if ( !bDesign )
253 ActivateControls( GetSdrPageView() );
255 // --- 4. load resp. unload the forms
256 FmFormPage* pCurPage = GetCurPage();
257 if ( pCurPage )
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 );
270 else
271 pImpl->Activate();
273 if ( pCurPage )
275 if ( bDesign )
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();
299 else
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)
304 pImpl->AutoFocus();
308 // und mein Undo-Environment wieder an
309 if (pModel)
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);
325 if (pPage)
327 if (!IsDesignMode())
329 // creating the controllers
330 ActivateControls(pPV);
332 // Alles deselektieren
333 UnmarkAll();
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 );
350 else
351 pImpl->Activate();
353 return pPV;
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 );
366 else
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)
381 if (!pPageView)
382 return;
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)
394 if( !pPageView )
395 return;
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())
425 return NULL;
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();
442 if( pPageView )
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);
451 break;
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();
472 return pPaintWindow;
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)
485 bool bDone = false;
486 const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
487 if ( IsDesignMode()
488 && rKeyCode.GetCode() == KEY_RETURN
491 // RETURN alone enters grid controls, for keyboard accessibility
492 if ( pWin
493 && !rKeyCode.IsShift()
494 && !rKeyCode.IsMod1()
495 && !rKeyCode.IsMod2()
498 FmFormObj* pObj = getMarkedGrid();
499 if ( pObj )
501 Reference< awt::XWindow > xWindow( pObj->GetUnoControl( *this, *pWin ), UNO_QUERY );
502 if ( xWindow.is() )
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();
510 xWindow->setFocus();
511 bDone = true;
515 // Alt-RETURN alone shows the properties of the selection
516 if ( pFormShell
517 && pFormShell->GetImpl()
518 && !rKeyCode.IsShift()
519 && !rKeyCode.IsMod1()
520 && rKeyCode.IsMod2()
523 pFormShell->GetImpl()->handleShowPropertiesRequest();
528 if ( !bDone )
529 bDone = E3dView::KeyInput(rKEvt,pWin);
530 return bDone;
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();
537 if ( bRet )
538 UnmarkAll();
540 return bRet;
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 );
555 return bReturn;
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);
566 if ( pMark )
568 pFormObject = FmFormObj::GetFormObject( pMark->GetMarkedSdrObj() );
569 if ( pFormObject )
571 Reference< XServiceInfo > xServInfo( pFormObject->GetUnoControlModel(), UNO_QUERY );
572 if ( !xServInfo.is() || !xServInfo->supportsService( FM_SUN_COMPONENT_GRIDCONTROL ) )
573 pFormObject = NULL;
577 return pFormObject;
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,
591 _rpLabel, _rpControl
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: */