Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / svx / source / form / fmview.cxx
blobe6234e2c942cd73280f9ac5fc879dbff8af1e4c4
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 = (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()
144 if( pFormShell )
145 pFormShell->SetView( NULL );
147 pImpl->notifyViewDying();
148 pImpl->release();
149 pImpl = NULL;
153 FmFormPage* FmFormView::GetCurPage()
155 SdrPageView* pPageView = GetSdrPageView();
156 FmFormPage* pCurPage = pPageView ? PTR_CAST( FmFormPage, pPageView->GetPage() ) : NULL;
157 return pCurPage;
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();
184 namespace
186 const SdrPageWindow* findPageWindow( const SdrPaintView* _pView, OutputDevice* _pWindow )
188 SdrPageView* pPageView = _pView->GetSdrPageView();
189 if(pPageView)
191 for ( sal_uInt32 window = 0; window < pPageView->PageWindowCount(); ++window )
193 const SdrPageWindow* pPageWindow = pPageView->GetPageWindow( window );
194 if ( !pPageWindow || &pPageWindow->GetPaintWindow().GetOutputDevice() != _pWindow )
195 continue;
197 return pPageWindow;
200 return NULL;
205 void FmFormView::AddWindowToPaintView(OutputDevice* pNewWin)
207 E3dView::AddWindowToPaintView(pNewWin);
209 if ( !pNewWin )
210 return;
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 );
215 if ( pPageWindow )
216 pImpl->addWindow( *pPageWindow );
220 void FmFormView::DeleteWindowFromPaintView(OutputDevice* pNewWin)
222 const SdrPageWindow* pPageWindow = findPageWindow( this, pNewWin );
223 if ( pPageWindow )
224 pImpl->removeWindow( pPageWindow->GetControlContainer() );
226 E3dView::DeleteWindowFromPaintView(pNewWin);
230 void FmFormView::ChangeDesignMode(bool bDesign)
232 if (bDesign == IsDesignMode())
233 return;
235 FmFormModel* pModel = PTR_CAST(FmFormModel, GetModel());
236 if (pModel)
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
245 if ( bDesign )
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 );
251 else
252 pImpl->Deactivate( true );
254 // --- 3. activate all controls, if we're switching to alive mode
255 if ( !bDesign )
256 ActivateControls( GetSdrPageView() );
258 // --- 4. load resp. unload the forms
259 FmFormPage* pCurPage = GetCurPage();
260 if ( pCurPage )
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 );
273 else
274 pImpl->Activate();
276 if ( pCurPage )
278 if ( bDesign )
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();
302 else
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)
307 pImpl->AutoFocus();
311 // und mein Undo-Environment wieder an
312 if (pModel)
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);
328 if (pPage)
330 if (!IsDesignMode())
332 // creating the controllers
333 ActivateControls(pPV);
335 // Alles deselektieren
336 UnmarkAll();
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 );
353 else
354 pImpl->Activate();
356 return pPV;
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 );
369 else
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)
391 if (!pPageView)
392 return;
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)
404 if( !pPageView )
405 return;
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())
435 return NULL;
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();
452 if( pPageView )
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);
461 break;
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();
482 return pPaintWindow;
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)
495 bool bDone = false;
496 const KeyCode& rKeyCode = rKEvt.GetKeyCode();
497 if ( IsDesignMode()
498 && rKeyCode.GetCode() == KEY_RETURN
501 // RETURN alone enters grid controls, for keyboard accessibility
502 if ( pWin
503 && !rKeyCode.IsShift()
504 && !rKeyCode.IsMod1()
505 && !rKeyCode.IsMod2()
508 FmFormObj* pObj = getMarkedGrid();
509 if ( pObj )
511 Reference< awt::XWindow > xWindow( pObj->GetUnoControl( *this, *pWin ), UNO_QUERY );
512 if ( xWindow.is() )
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();
520 xWindow->setFocus();
521 bDone = true;
525 // Alt-RETURN alone shows the properties of the selection
526 if ( pFormShell
527 && pFormShell->GetImpl()
528 && !rKeyCode.IsShift()
529 && !rKeyCode.IsMod1()
530 && rKeyCode.IsMod2()
533 pFormShell->GetImpl()->handleShowPropertiesRequest();
538 if ( !bDone )
539 bDone = E3dView::KeyInput(rKEvt,pWin);
540 return bDone;
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();
547 if ( bRet )
548 UnmarkAll();
550 return bRet;
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 );
565 return bReturn;
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);
576 if ( pMark )
578 pFormObject = FmFormObj::GetFormObject( pMark->GetMarkedSdrObj() );
579 if ( pFormObject )
581 Reference< XServiceInfo > xServInfo( pFormObject->GetUnoControlModel(), UNO_QUERY );
582 if ( !xServInfo.is() || !xServInfo->supportsService( FM_SUN_COMPONENT_GRIDCONTROL ) )
583 pFormObject = NULL;
587 return pFormObject;
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,
601 _rpLabel, _rpControl
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: */