bump product version to 7.2.5.1
[LibreOffice.git] / svx / source / form / fmshell.cxx
blob9bbe292ffe90569f6e2757c426c1a6e6a8c038cf
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 <fmvwimp.hxx>
21 #include <svx/fmshell.hxx>
22 #include <svx/fmtools.hxx>
23 #include <fmprop.hxx>
24 #include <fmundo.hxx>
25 #include <com/sun/star/beans/XPropertySet.hpp>
26 #include <com/sun/star/awt/XTabControllerModel.hpp>
27 #include <sfx2/viewfrm.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/weld.hxx>
30 #include <svl/whiter.hxx>
31 #include <sfx2/app.hxx>
32 #include <svl/intitem.hxx>
33 #include <svl/stritem.hxx>
34 #include <svl/visitem.hxx>
35 #include <unotools/moduleoptions.hxx>
36 #include <sfx2/objface.hxx>
37 #include <sfx2/request.hxx>
38 #include <sfx2/dispatch.hxx>
39 #include <svx/svdobj.hxx>
40 #include <svx/fmpage.hxx>
41 #include <svx/svditer.hxx>
43 #include <svx/svxids.hrc>
45 #include <svx/svdobjkind.hxx>
46 #include <svl/eitem.hxx>
47 #include <tools/diagnose_ex.h>
48 #include <svx/svdpage.hxx>
49 #include <svx/fmmodel.hxx>
50 #include <fmshimp.hxx>
51 #include <svx/svdpagv.hxx>
52 #include <sfx2/objitem.hxx>
53 #include <sfx2/viewsh.hxx>
54 #include <fmexpl.hxx>
55 #include <formcontrolling.hxx>
56 #include <comphelper/types.hxx>
57 #include <fmdocumentclassification.hxx>
58 #include <formtoolbars.hxx>
60 #include <svx/svxdlg.hxx>
62 #include <svx/sdrobjectfilter.hxx>
64 #define ShellClass_FmFormShell
65 #include <svxslots.hxx>
67 #include <memory>
69 // is used for Invalidate -> maintain it as well
70 // sort ascending !!!!!!
71 sal_uInt16 const ControllerSlotMap[] = // slots of the controller
73 SID_FM_CONFIG,
74 SID_FM_PUSHBUTTON,
75 SID_FM_RADIOBUTTON,
76 SID_FM_CHECKBOX,
77 SID_FM_FIXEDTEXT,
78 SID_FM_GROUPBOX,
79 SID_FM_EDIT,
80 SID_FM_LISTBOX,
81 SID_FM_COMBOBOX,
82 SID_FM_DBGRID,
83 SID_FM_IMAGEBUTTON,
84 SID_FM_FILECONTROL,
85 SID_FM_NAVIGATIONBAR,
86 SID_FM_CTL_PROPERTIES,
87 SID_FM_PROPERTIES,
88 SID_FM_TAB_DIALOG,
89 SID_FM_ADD_FIELD,
90 SID_FM_DESIGN_MODE,
91 SID_FM_SHOW_FMEXPLORER,
92 SID_FM_SHOW_PROPERTIES,
93 SID_FM_FMEXPLORER_CONTROL,
94 SID_FM_DATEFIELD,
95 SID_FM_TIMEFIELD,
96 SID_FM_NUMERICFIELD,
97 SID_FM_CURRENCYFIELD,
98 SID_FM_PATTERNFIELD,
99 SID_FM_OPEN_READONLY,
100 SID_FM_IMAGECONTROL,
101 SID_FM_USE_WIZARDS,
102 SID_FM_FORMATTEDFIELD,
103 SID_FM_FILTER_NAVIGATOR,
104 SID_FM_AUTOCONTROLFOCUS,
105 SID_FM_SCROLLBAR,
106 SID_FM_SPINBUTTON,
107 SID_FM_SHOW_DATANAVIGATOR,
108 SID_FM_DATANAVIGATOR_CONTROL,
113 using namespace ::com::sun::star::uno;
114 using namespace ::com::sun::star::awt;
115 using namespace ::com::sun::star::sdbc;
116 using namespace ::com::sun::star::sdbcx;
117 using namespace ::com::sun::star::beans;
118 using namespace ::com::sun::star::form;
119 using namespace ::com::sun::star::form::runtime;
120 using namespace ::svxform;
122 FmDesignModeChangedHint::FmDesignModeChangedHint( bool bDesMode )
123 :m_bDesignMode( bDesMode )
128 FmDesignModeChangedHint::~FmDesignModeChangedHint()
132 SFX_IMPL_INTERFACE(FmFormShell, SfxShell)
134 void FmFormShell::InitInterface_Impl()
136 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_NAVIGATION, SfxVisibilityFlags::Standard|SfxVisibilityFlags::ReadonlyDoc,
137 ToolbarId::SvxTbx_Form_Navigation,
138 SfxShellFeature::FormShowDatabaseBar);
140 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_NAVIGATION, SfxVisibilityFlags::Standard|SfxVisibilityFlags::ReadonlyDoc,
141 ToolbarId::SvxTbx_Form_Filter,
142 SfxShellFeature::FormShowFilterBar);
144 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Standard | SfxVisibilityFlags::ReadonlyDoc,
145 ToolbarId::SvxTbx_Text_Control_Attributes,
146 SfxShellFeature::FormShowTextControlBar);
148 GetStaticInterface()->RegisterChildWindow(SID_FM_ADD_FIELD, false, SfxShellFeature::FormShowField);
149 GetStaticInterface()->RegisterChildWindow(SID_FM_SHOW_PROPERTIES, false, SfxShellFeature::FormShowProperties);
150 GetStaticInterface()->RegisterChildWindow(SID_FM_SHOW_FMEXPLORER, false, SfxShellFeature::FormShowExplorer);
151 GetStaticInterface()->RegisterChildWindow(SID_FM_FILTER_NAVIGATOR, false, SfxShellFeature::FormShowFilterNavigator);
152 GetStaticInterface()->RegisterChildWindow(SID_FM_SHOW_DATANAVIGATOR, false, SfxShellFeature::FormShowDataNavigator);
154 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Standard,
155 ToolbarId::SvxTbx_Controls,
156 SfxShellFeature::FormTBControls);
158 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Standard,
159 ToolbarId::SvxTbx_FormDesign,
160 SfxShellFeature::FormTBDesign);
164 FmFormShell::FmFormShell( SfxViewShell* _pParent, FmFormView* pView )
165 :SfxShell(_pParent)
166 ,m_pImpl(new FmXFormShell(*this, _pParent->GetViewFrame()))
167 ,m_pFormView( pView )
168 ,m_pFormModel( nullptr )
169 ,m_nLastSlot( 0 )
170 ,m_bDesignMode( true )
171 ,m_bHasForms(false)
173 SetPool( &SfxGetpApp()->GetPool() );
174 SetName( "Form" );
176 SetView(m_pFormView);
180 FmFormShell::~FmFormShell()
182 if ( m_pFormView )
183 SetView( nullptr );
185 m_pImpl->dispose();
189 void FmFormShell::NotifyMarkListChanged(FmFormView* pWhichView)
191 FmNavViewMarksChanged aChangeNotification(pWhichView);
192 Broadcast(aChangeNotification);
196 bool FmFormShell::PrepareClose(bool bUI)
198 if (GetImpl()->didPrepareClose_Lock())
199 // we already made a PrepareClose for the current modifications of the current form
200 return true;
202 bool bResult = true;
203 // Save the data records, not in DesignMode and FilterMode
204 if (!m_bDesignMode && !GetImpl()->isInFilterMode_Lock() &&
205 m_pFormView && m_pFormView->GetActualOutDev() &&
206 m_pFormView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW)
208 SdrPageView* pCurPageView = m_pFormView->GetSdrPageView();
210 // sal_uInt16 nPos = pCurPageView ? pCurPageView->GetWinList().Find((OutputDevice*)m_pFormView->GetActualOutDev()) : SDRPAGEVIEWWIN_NOTFOUND;
211 SdrPageWindow* pWindow = pCurPageView ? pCurPageView->FindPageWindow(*const_cast<OutputDevice*>(m_pFormView->GetActualOutDev())) : nullptr;
213 if(pWindow)
215 // First, the current contents of the controls are stored.
216 // If everything has gone smoothly, the modified records are stored.
217 if (GetImpl()->getActiveController_Lock().is())
219 const svx::ControllerFeatures& rController = GetImpl()->getActiveControllerFeatures_Lock();
220 if ( rController->commitCurrentControl() )
222 const bool bModified = rController->isModifiedRow();
224 if ( bModified && bUI )
226 SfxViewShell* pShell = GetViewShell();
227 vcl::Window* pShellWnd = pShell ? pShell->GetWindow() : nullptr;
228 weld::Widget* pFrameWeld = pShellWnd ? pShellWnd->GetFrameWeld() : nullptr;
229 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pFrameWeld, "svx/ui/savemodifieddialog.ui"));
230 std::unique_ptr<weld::MessageDialog> xQry(xBuilder->weld_message_dialog("SaveModifiedDialog"));
231 switch (xQry->run())
233 case RET_YES:
234 bResult = rController->commitCurrentRecord( );
235 [[fallthrough]];
236 case RET_NO:
237 GetImpl()->didPrepareClose_Lock(true);
238 break;
240 case RET_CANCEL:
241 return false;
248 return bResult;
252 void FmFormShell::impl_setDesignMode(bool bDesign)
254 if (m_pFormView)
256 if (!bDesign)
257 m_nLastSlot = SID_FM_DESIGN_MODE;
259 GetImpl()->SetDesignMode_Lock(bDesign);
260 // my m_bDesignMode is also set by the Impl ...
262 else
264 m_bHasForms = false;
265 m_bDesignMode = bDesign;
266 UIFeatureChanged();
269 GetViewShell()->GetViewFrame()->GetBindings().Invalidate(ControllerSlotMap);
273 bool FmFormShell::HasUIFeature(SfxShellFeature nFeature) const
275 assert((nFeature & ~SfxShellFeature::FormMask) == SfxShellFeature::NONE);
276 bool bResult = false;
277 if (nFeature & SfxShellFeature::FormShowDatabaseBar)
279 // only if forms are also available
280 bResult = !m_bDesignMode && GetImpl()->hasDatabaseBar_Lock() && !GetImpl()->isInFilterMode_Lock();
282 else if (nFeature & SfxShellFeature::FormShowFilterBar)
284 // only if forms are also available
285 bResult = !m_bDesignMode && GetImpl()->hasDatabaseBar_Lock() && GetImpl()->isInFilterMode_Lock();
287 else if (nFeature & SfxShellFeature::FormShowFilterNavigator)
289 bResult = !m_bDesignMode && GetImpl()->hasDatabaseBar_Lock() && GetImpl()->isInFilterMode_Lock();
291 else if (nFeature & SfxShellFeature::FormShowField)
293 bResult = m_bDesignMode && m_pFormView && m_bHasForms;
295 else if (nFeature & SfxShellFeature::FormShowProperties)
297 bResult = m_bDesignMode && m_pFormView && m_bHasForms;
299 else if (nFeature & SfxShellFeature::FormShowExplorer)
301 bResult = m_bDesignMode; // OJ #101593# && m_pFormView && m_bHasForms;
303 else if (nFeature & SfxShellFeature::FormShowTextControlBar)
305 bResult = !GetImpl()->IsReadonlyDoc_Lock() && m_pImpl->IsActiveControl_Lock(true);
307 else if (nFeature & SfxShellFeature::FormShowDataNavigator)
309 bResult = GetImpl()->isEnhancedForm_Lock();
311 else if ( (nFeature & SfxShellFeature::FormTBControls)
312 || (nFeature & SfxShellFeature::FormTBDesign)
315 bResult = true;
318 return bResult;
322 void FmFormShell::Execute(SfxRequest &rReq)
324 sal_uInt16 nSlot = rReq.GetSlot();
327 // set MasterSlot
328 switch( nSlot )
330 case SID_FM_PUSHBUTTON:
331 case SID_FM_RADIOBUTTON:
332 case SID_FM_CHECKBOX:
333 case SID_FM_FIXEDTEXT:
334 case SID_FM_GROUPBOX:
335 case SID_FM_LISTBOX:
336 case SID_FM_COMBOBOX:
337 case SID_FM_NAVIGATIONBAR:
338 case SID_FM_EDIT:
339 case SID_FM_DBGRID:
340 case SID_FM_IMAGEBUTTON:
341 case SID_FM_IMAGECONTROL:
342 case SID_FM_FILECONTROL:
343 case SID_FM_DATEFIELD:
344 case SID_FM_TIMEFIELD:
345 case SID_FM_NUMERICFIELD:
346 case SID_FM_CURRENCYFIELD:
347 case SID_FM_PATTERNFIELD:
348 case SID_FM_FORMATTEDFIELD:
349 case SID_FM_SCROLLBAR:
350 case SID_FM_SPINBUTTON:
351 m_nLastSlot = nSlot;
352 break;
356 // set the Identifier and Inventor of the Uno control
357 SdrObjKind nIdentifier = OBJ_NONE;
358 switch( nSlot )
360 case SID_FM_CHECKBOX:
361 nIdentifier = OBJ_FM_CHECKBOX;
362 break;
363 case SID_FM_PUSHBUTTON:
364 nIdentifier = OBJ_FM_BUTTON;
365 break;
366 case SID_FM_FIXEDTEXT:
367 nIdentifier = OBJ_FM_FIXEDTEXT;
368 break;
369 case SID_FM_LISTBOX:
370 nIdentifier = OBJ_FM_LISTBOX;
371 break;
372 case SID_FM_EDIT:
373 nIdentifier = OBJ_FM_EDIT;
374 break;
375 case SID_FM_RADIOBUTTON:
376 nIdentifier = OBJ_FM_RADIOBUTTON;
377 break;
378 case SID_FM_GROUPBOX:
379 nIdentifier = OBJ_FM_GROUPBOX;
380 break;
381 case SID_FM_COMBOBOX:
382 nIdentifier = OBJ_FM_COMBOBOX;
383 break;
384 case SID_FM_NAVIGATIONBAR:
385 nIdentifier = OBJ_FM_NAVIGATIONBAR;
386 break;
387 case SID_FM_DBGRID:
388 nIdentifier = OBJ_FM_GRID;
389 break;
390 case SID_FM_IMAGEBUTTON:
391 nIdentifier = OBJ_FM_IMAGEBUTTON;
392 break;
393 case SID_FM_IMAGECONTROL:
394 nIdentifier = OBJ_FM_IMAGECONTROL;
395 break;
396 case SID_FM_FILECONTROL:
397 nIdentifier = OBJ_FM_FILECONTROL;
398 break;
399 case SID_FM_DATEFIELD:
400 nIdentifier = OBJ_FM_DATEFIELD;
401 break;
402 case SID_FM_TIMEFIELD:
403 nIdentifier = OBJ_FM_TIMEFIELD;
404 break;
405 case SID_FM_NUMERICFIELD:
406 nIdentifier = OBJ_FM_NUMERICFIELD;
407 break;
408 case SID_FM_CURRENCYFIELD:
409 nIdentifier = OBJ_FM_CURRENCYFIELD;
410 break;
411 case SID_FM_PATTERNFIELD:
412 nIdentifier = OBJ_FM_PATTERNFIELD;
413 break;
414 case SID_FM_FORMATTEDFIELD:
415 nIdentifier = OBJ_FM_FORMATTEDFIELD;
416 break;
417 case SID_FM_SCROLLBAR:
418 nIdentifier = OBJ_FM_SCROLLBAR;
419 break;
420 case SID_FM_SPINBUTTON:
421 nIdentifier = OBJ_FM_SPINBUTTON;
422 break;
425 switch ( nSlot )
427 case SID_FM_CHECKBOX:
428 case SID_FM_PUSHBUTTON:
429 case SID_FM_FIXEDTEXT:
430 case SID_FM_LISTBOX:
431 case SID_FM_EDIT:
432 case SID_FM_RADIOBUTTON:
433 case SID_FM_COMBOBOX:
434 case SID_FM_NAVIGATIONBAR:
435 case SID_FM_GROUPBOX:
436 case SID_FM_DBGRID:
437 case SID_FM_IMAGEBUTTON:
438 case SID_FM_IMAGECONTROL:
439 case SID_FM_FILECONTROL:
440 case SID_FM_DATEFIELD:
441 case SID_FM_TIMEFIELD:
442 case SID_FM_NUMERICFIELD:
443 case SID_FM_CURRENCYFIELD:
444 case SID_FM_PATTERNFIELD:
445 case SID_FM_FORMATTEDFIELD:
446 case SID_FM_SCROLLBAR:
447 case SID_FM_SPINBUTTON:
449 const SfxBoolItem* pGrabFocusItem = rReq.GetArg<SfxBoolItem>(SID_FM_TOGGLECONTROLFOCUS);
450 if ( pGrabFocusItem && pGrabFocusItem->GetValue() )
451 { // see below
452 SfxViewShell* pShell = GetViewShell();
453 vcl::Window* pShellWnd = pShell ? pShell->GetWindow() : nullptr;
454 if ( pShellWnd )
455 pShellWnd->GrabFocus();
456 break;
459 SfxUInt16Item aIdentifierItem( SID_FM_CONTROL_IDENTIFIER, nIdentifier );
460 SfxUInt32Item aInventorItem( SID_FM_CONTROL_INVENTOR, sal_uInt32(SdrInventor::FmForm) );
461 const SfxPoolItem* pArgs[] =
463 &aIdentifierItem, &aInventorItem, nullptr
465 const SfxPoolItem* pInternalArgs[] =
467 nullptr
470 GetViewShell()->GetViewFrame()->GetDispatcher()->Execute( SID_FM_CREATE_CONTROL, SfxCallMode::ASYNCHRON,
471 pArgs, rReq.GetModifier(), pInternalArgs );
473 if ( rReq.GetModifier() & KEY_MOD1 )
475 // #99013# if selected with control key, return focus to current view
476 // do this asynchron, so that the creation can be finished first
477 // reusing the SID_FM_TOGGLECONTROLFOCUS is somewhat hacky... which it wouldn't if it would have another
478 // name, so I do not really have a big problem with this...
479 SfxBoolItem aGrabFocusIndicatorItem( SID_FM_TOGGLECONTROLFOCUS, true );
480 GetViewShell()->GetViewFrame()->GetDispatcher()->ExecuteList(
481 nSlot, SfxCallMode::ASYNCHRON,
482 { &aGrabFocusIndicatorItem });
485 rReq.Done();
486 } break;
489 // individual actions
490 switch( nSlot )
492 case SID_FM_FORM_DESIGN_TOOLS:
494 FormToolboxes aToolboxAccess(GetImpl()->getHostFrame_Lock());
495 aToolboxAccess.toggleToolbox( nSlot );
496 rReq.Done();
498 break;
500 case SID_FM_TOGGLECONTROLFOCUS:
502 FmFormView* pFormView = GetFormView();
503 if ( !pFormView )
504 break;
506 // if we execute this ourself, then either the application does not implement an own handling for this,
507 // of we're on the top of the dispatcher stack, which means a control has the focus.
508 // In the latter case, we put the focus to the document window, otherwise, we focus the first control
509 const bool bHasControlFocus = GetImpl()->HasControlFocus_Lock();
510 if ( bHasControlFocus )
512 if (m_pFormView)
514 const OutputDevice* pDevice = m_pFormView->GetActualOutDev();
515 vcl::Window* pWindow = pDevice->GetOwnerWindow();
516 if ( pWindow )
517 pWindow->GrabFocus();
520 else
522 pFormView->GrabFirstControlFocus( );
525 break;
527 case SID_FM_VIEW_AS_GRID:
528 GetImpl()->CreateExternalView_Lock();
529 break;
530 case SID_FM_CONVERTTO_EDIT :
531 case SID_FM_CONVERTTO_BUTTON :
532 case SID_FM_CONVERTTO_FIXEDTEXT :
533 case SID_FM_CONVERTTO_LISTBOX :
534 case SID_FM_CONVERTTO_CHECKBOX :
535 case SID_FM_CONVERTTO_RADIOBUTTON :
536 case SID_FM_CONVERTTO_GROUPBOX :
537 case SID_FM_CONVERTTO_COMBOBOX :
538 case SID_FM_CONVERTTO_IMAGEBUTTON :
539 case SID_FM_CONVERTTO_FILECONTROL :
540 case SID_FM_CONVERTTO_DATE :
541 case SID_FM_CONVERTTO_TIME :
542 case SID_FM_CONVERTTO_NUMERIC :
543 case SID_FM_CONVERTTO_CURRENCY :
544 case SID_FM_CONVERTTO_PATTERN :
545 case SID_FM_CONVERTTO_IMAGECONTROL :
546 case SID_FM_CONVERTTO_FORMATTED :
547 case SID_FM_CONVERTTO_SCROLLBAR :
548 case SID_FM_CONVERTTO_SPINBUTTON :
549 case SID_FM_CONVERTTO_NAVIGATIONBAR :
550 GetImpl()->executeControlConversionSlot_Lock(FmXFormShell::SlotToIdent(nSlot));
551 // after the conversion, re-determine the selection, since the
552 // selected object has changed
553 GetImpl()->SetSelection_Lock(GetFormView()->GetMarkedObjectList());
554 break;
555 case SID_FM_LEAVE_CREATE:
556 m_nLastSlot = 0;
557 rReq.Done();
558 break;
559 case SID_FM_SHOW_PROPERTY_BROWSER:
561 const SfxBoolItem* pShowItem = rReq.GetArg<SfxBoolItem>(SID_FM_SHOW_PROPERTIES);
562 bool bShow = true;
563 if ( pShowItem )
564 bShow = pShowItem->GetValue();
565 GetImpl()->ShowSelectionProperties_Lock(bShow);
567 rReq.Done();
568 } break;
570 case SID_FM_PROPERTIES:
572 // display the PropertyBrowser
573 const SfxBoolItem* pShowItem = rReq.GetArg<SfxBoolItem>(nSlot);
574 bool bShow = pShowItem == nullptr || pShowItem->GetValue();
576 InterfaceBag aOnlyTheForm;
577 aOnlyTheForm.insert(Reference<XInterface>(GetImpl()->getCurrentForm_Lock(), UNO_QUERY));
578 GetImpl()->setCurrentSelection_Lock(aOnlyTheForm);
580 GetImpl()->ShowSelectionProperties_Lock(bShow);
582 rReq.Done();
583 } break;
585 case SID_FM_CTL_PROPERTIES:
587 const SfxBoolItem* pShowItem = rReq.GetArg<SfxBoolItem>(nSlot);
588 bool bShow = pShowItem == nullptr || pShowItem->GetValue();
590 OSL_ENSURE( GetImpl()->onlyControlsAreMarked_Lock(), "FmFormShell::Execute: ControlProperties should be disabled!" );
591 if ( bShow )
592 GetImpl()->selectLastMarkedControls_Lock();
593 GetImpl()->ShowSelectionProperties_Lock(bShow);
595 rReq.Done();
596 } break;
597 case SID_FM_SHOW_PROPERTIES:
598 case SID_FM_ADD_FIELD:
599 case SID_FM_FILTER_NAVIGATOR:
600 case SID_FM_SHOW_DATANAVIGATOR :
602 GetViewShell()->GetViewFrame()->ToggleChildWindow(nSlot);
603 rReq.Done();
604 } break;
605 case SID_FM_SHOW_FMEXPLORER:
607 if (!m_pFormView) // force setting the view
608 GetViewShell()->GetViewFrame()->GetDispatcher()->Execute(SID_CREATE_SW_DRAWVIEW);
610 GetViewShell()->GetViewFrame()->ChildWindowExecute(rReq);
611 rReq.Done();
613 break;
615 case SID_FM_TAB_DIALOG:
617 GetImpl()->ExecuteTabOrderDialog_Lock(
618 Reference<XTabControllerModel>(GetImpl()->getCurrentForm_Lock(), UNO_QUERY));
619 rReq.Done();
621 break;
623 case SID_FM_DESIGN_MODE:
625 const SfxBoolItem* pDesignItem = rReq.GetArg<SfxBoolItem>(nSlot);
626 bool bDesignMode = pDesignItem ? pDesignItem->GetValue() : !m_bDesignMode;
627 SetDesignMode( bDesignMode );
628 if ( m_bDesignMode == bDesignMode )
629 rReq.Done();
631 m_nLastSlot = SID_FM_DESIGN_MODE;
633 break;
635 case SID_FM_AUTOCONTROLFOCUS:
637 FmFormModel* pModel = GetFormModel();
638 DBG_ASSERT(pModel, "FmFormShell::Execute : invalid call !");
639 // should have been disabled in GetState if we don't have a FormModel
640 pModel->SetAutoControlFocus( !pModel->GetAutoControlFocus() );
641 GetViewShell()->GetViewFrame()->GetBindings().Invalidate(SID_FM_AUTOCONTROLFOCUS);
643 break;
644 case SID_FM_OPEN_READONLY:
646 FmFormModel* pModel = GetFormModel();
647 DBG_ASSERT(pModel, "FmFormShell::Execute : invalid call !");
648 // should have been disabled in GetState if we don't have a FormModel
649 pModel->SetOpenInDesignMode( !pModel->GetOpenInDesignMode() );
650 GetViewShell()->GetViewFrame()->GetBindings().Invalidate(SID_FM_OPEN_READONLY);
652 break;
653 case SID_FM_USE_WIZARDS:
655 GetImpl()->SetWizardUsing_Lock(!GetImpl()->GetWizardUsing_Lock());
656 GetViewShell()->GetViewFrame()->GetBindings().Invalidate(SID_FM_USE_WIZARDS);
658 break;
659 case SID_FM_SEARCH:
661 const svx::ControllerFeatures& rController = GetImpl()->getActiveControllerFeatures_Lock();
662 if ( rController->commitCurrentControl() && rController->commitCurrentRecord() )
663 GetImpl()->ExecuteSearch_Lock();
664 rReq.Done();
666 break;
668 case SID_FM_RECORD_FIRST:
669 case SID_FM_RECORD_PREV:
670 case SID_FM_RECORD_NEXT:
671 case SID_FM_RECORD_LAST:
672 case SID_FM_RECORD_NEW:
673 case SID_FM_REFRESH:
674 case SID_FM_REFRESH_FORM_CONTROL:
675 case SID_FM_RECORD_DELETE:
676 case SID_FM_RECORD_UNDO:
677 case SID_FM_RECORD_SAVE:
678 case SID_FM_REMOVE_FILTER_SORT:
679 case SID_FM_SORTDOWN:
680 case SID_FM_SORTUP:
681 case SID_FM_AUTOFILTER:
682 case SID_FM_ORDERCRIT:
683 case SID_FM_FORM_FILTERED:
685 GetImpl()->ExecuteFormSlot_Lock(nSlot);
686 rReq.Done();
688 break;
690 case SID_FM_RECORD_ABSOLUTE:
692 const svx::ControllerFeatures& rController = GetImpl()->getNavControllerFeatures_Lock();
693 sal_Int32 nRecord = -1;
695 const SfxItemSet* pArgs = rReq.GetArgs();
696 if ( pArgs )
698 const SfxPoolItem* pItem;
699 if ( ( pArgs->GetItemState( FN_PARAM_1, true, &pItem ) ) == SfxItemState::SET )
701 const SfxInt32Item* pTypedItem = dynamic_cast<const SfxInt32Item* >( pItem );
702 if ( pTypedItem )
703 nRecord = std::max( pTypedItem->GetValue(), sal_Int32(0) );
706 else
708 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
709 ScopedVclPtr<AbstractFmInputRecordNoDialog> dlg(pFact->CreateFmInputRecordNoDialog(rReq.GetFrameWeld()));
710 dlg->SetValue( rController->getCursor()->getRow() );
711 if ( dlg->Execute() == RET_OK )
712 nRecord = dlg->GetValue();
714 rReq.AppendItem( SfxInt32Item( FN_PARAM_1, nRecord ) );
717 if ( nRecord != -1 )
718 rController->execute( nSlot, "Position", makeAny( nRecord ) );
720 rReq.Done();
721 } break;
722 case SID_FM_FILTER_EXECUTE:
723 case SID_FM_FILTER_EXIT:
725 bool bCancelled = ( SID_FM_FILTER_EXIT == nSlot );
726 bool bReopenNavigator = false;
728 if ( !bCancelled )
730 // if the filter navigator is still open, we need to close it, so it can possibly
731 // commit it's most recent changes
732 if ( GetViewShell() && GetViewShell()->GetViewFrame() )
733 if ( GetViewShell()->GetViewFrame()->HasChildWindow( SID_FM_FILTER_NAVIGATOR ) )
735 GetViewShell()->GetViewFrame()->ToggleChildWindow( SID_FM_FILTER_NAVIGATOR );
736 bReopenNavigator = true;
739 Reference<runtime::XFormController> const xController(GetImpl()->getActiveController_Lock());
741 if ( GetViewShell()->GetViewFrame()->HasChildWindow( SID_FM_FILTER_NAVIGATOR )
742 // closing the window was denied, for instance because of an invalid criterion
744 || ( xController.is()
745 && !GetImpl()->getActiveControllerFeatures_Lock()->commitCurrentControl()
747 // committing the controller was denied
750 rReq.Done();
751 break;
755 GetImpl()->stopFiltering_Lock(!bCancelled);
756 rReq.Done();
758 if ( bReopenNavigator )
759 // we closed the navigator only to implicitly commit it (as we do not have another
760 // direct wire to it), but to the user, it should look as it was always open
761 GetViewShell()->GetViewFrame()->ToggleChildWindow( SID_FM_FILTER_NAVIGATOR );
763 break;
765 case SID_FM_FILTER_START:
767 GetImpl()->startFiltering_Lock();
768 rReq.Done();
770 // initially open the filter navigator, the whole form based filter is pretty useless without it
771 SfxBoolItem aIdentifierItem( SID_FM_FILTER_NAVIGATOR, true );
772 GetViewShell()->GetViewFrame()->GetDispatcher()->ExecuteList(
773 SID_FM_FILTER_NAVIGATOR, SfxCallMode::ASYNCHRON,
774 { &aIdentifierItem });
775 } break;
780 void FmFormShell::GetState(SfxItemSet &rSet)
782 SfxWhichIter aIter( rSet );
783 sal_uInt16 nWhich = aIter.FirstWhich();
784 while ( nWhich )
786 switch( nWhich )
788 case SID_FM_FORM_DESIGN_TOOLS:
790 FormToolboxes aToolboxAccess(GetImpl()->getHostFrame_Lock());
791 rSet.Put( SfxBoolItem( nWhich, aToolboxAccess.isToolboxVisible( nWhich ) ) );
793 break;
795 case SID_FM_FILTER_EXECUTE:
796 case SID_FM_FILTER_EXIT:
797 if (!GetImpl()->isInFilterMode_Lock())
798 rSet.DisableItem( nWhich );
799 break;
801 case SID_FM_USE_WIZARDS:
802 if ( !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::EModule::DATABASE ) )
803 rSet.Put( SfxVisibilityItem( nWhich, false ) );
804 else if (!GetFormModel())
805 rSet.DisableItem( nWhich );
806 else
807 rSet.Put(SfxBoolItem(nWhich, GetImpl()->GetWizardUsing_Lock()));
808 break;
809 case SID_FM_AUTOCONTROLFOCUS:
810 if (!GetFormModel())
811 rSet.DisableItem( nWhich );
812 else
813 rSet.Put( SfxBoolItem(nWhich, GetFormModel()->GetAutoControlFocus() ) );
814 break;
815 case SID_FM_OPEN_READONLY:
816 if (!GetFormModel())
817 rSet.DisableItem( nWhich );
818 else
819 rSet.Put( SfxBoolItem(nWhich, GetFormModel()->GetOpenInDesignMode() ) );
820 break;
822 case SID_FM_NAVIGATIONBAR:
823 case SID_FM_DBGRID:
824 if ( !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::EModule::DATABASE ) )
826 rSet.Put( SfxVisibilityItem( nWhich, false ) );
827 break;
829 [[fallthrough]];
831 case SID_FM_SCROLLBAR:
832 case SID_FM_IMAGECONTROL:
833 case SID_FM_FILECONTROL:
834 case SID_FM_CURRENCYFIELD:
835 case SID_FM_PATTERNFIELD:
836 case SID_FM_IMAGEBUTTON:
837 case SID_FM_RADIOBUTTON:
838 case SID_FM_COMBOBOX:
839 case SID_FM_GROUPBOX:
840 case SID_FM_CHECKBOX:
841 case SID_FM_PUSHBUTTON:
842 case SID_FM_FIXEDTEXT:
843 case SID_FM_LISTBOX:
844 case SID_FM_EDIT:
845 case SID_FM_DATEFIELD:
846 case SID_FM_TIMEFIELD:
847 case SID_FM_NUMERICFIELD:
848 case SID_FM_FORMATTEDFIELD:
849 case SID_FM_SPINBUTTON:
850 if (!m_bDesignMode)
851 rSet.DisableItem( nWhich );
852 else
854 bool bLayerLocked = false;
855 if (m_pFormView)
857 // If the css::drawing::Layer is locked, the slots must be disabled. #36897
858 SdrPageView* pPV = m_pFormView->GetSdrPageView();
859 if (pPV != nullptr)
860 bLayerLocked = pPV->IsLayerLocked(m_pFormView->GetActiveLayer());
862 if (bLayerLocked)
863 rSet.DisableItem( nWhich );
864 else
865 rSet.Put( SfxBoolItem(nWhich, (nWhich==m_nLastSlot)) );
867 break;
868 case SID_FM_FILTER_NAVIGATOR_CONTROL:
870 if (GetImpl()->isInFilterMode_Lock())
871 rSet.Put(SfxObjectItem(nWhich, this));
872 else
873 rSet.Put(SfxObjectItem(nWhich));
874 } break;
875 case SID_FM_FIELDS_CONTROL:
876 case SID_FM_PROPERTY_CONTROL:
878 if (!m_bDesignMode || !m_pFormView || !m_bHasForms)
879 rSet.Put(SfxObjectItem(nWhich));
880 else
881 rSet.Put(SfxObjectItem(nWhich, this));
883 } break;
884 case SID_FM_FMEXPLORER_CONTROL:
885 case SID_FM_DATANAVIGATOR_CONTROL :
887 if (!m_bDesignMode || !m_pFormView)
888 rSet.Put(SfxObjectItem(nWhich));
889 else
890 rSet.Put(SfxObjectItem(nWhich, this));
892 } break;
893 case SID_FM_ADD_FIELD:
894 case SID_FM_SHOW_FMEXPLORER:
895 case SID_FM_SHOW_PROPERTIES:
896 case SID_FM_FILTER_NAVIGATOR:
897 case SID_FM_SHOW_DATANAVIGATOR:
899 if ( GetViewShell()->GetViewFrame()->KnowsChildWindow(nWhich) )
900 rSet.Put( SfxBoolItem( nWhich, GetViewShell()->GetViewFrame()->HasChildWindow(nWhich)) );
901 else
902 rSet.DisableItem(nWhich);
903 } break;
905 case SID_FM_SHOW_PROPERTY_BROWSER:
907 rSet.Put(SfxBoolItem(nWhich, GetImpl()->IsPropBrwOpen_Lock()));
909 break;
911 case SID_FM_CTL_PROPERTIES:
913 // potentially, give the Impl the opportunity to update its
914 // current objects which are aligned with the current MarkList
915 if (GetImpl()->IsSelectionUpdatePending_Lock())
916 GetImpl()->ForceUpdateSelection_Lock();
918 if (!m_pFormView || !m_bDesignMode || !GetImpl()->onlyControlsAreMarked_Lock())
919 rSet.DisableItem( nWhich );
920 else
922 bool const bChecked = GetImpl()->IsPropBrwOpen_Lock() && !GetImpl()->isSolelySelected_Lock(GetImpl()->getCurrentForm_Lock());
923 // if the property browser is open, and only controls are marked, and the current selection
924 // does not consist of only the current form, then the current selection is the (composition of)
925 // the currently marked controls
926 rSet.Put( SfxBoolItem( nWhich, bChecked ) );
928 } break;
930 case SID_FM_PROPERTIES:
932 // potentially, give the Impl the opportunity to update its
933 // current objects which are aligned with the current MarkList
934 if (GetImpl()->IsSelectionUpdatePending_Lock())
935 GetImpl()->ForceUpdateSelection_Lock();
937 if (!m_pFormView || !m_bDesignMode || !GetImpl()->getCurrentForm_Lock().is())
938 rSet.DisableItem( nWhich );
939 else
941 bool const bChecked = GetImpl()->IsPropBrwOpen_Lock() && GetImpl()->isSolelySelected_Lock(GetImpl()->getCurrentForm_Lock());
942 rSet.Put(SfxBoolItem(nWhich, bChecked));
944 } break;
945 case SID_FM_TAB_DIALOG:
946 // potentially, give the Impl the opportunity to update its
947 // current objects which are aligned with the current MarkList
948 if (GetImpl()->IsSelectionUpdatePending_Lock())
949 GetImpl()->ForceUpdateSelection_Lock();
951 if (!m_pFormView || !m_bDesignMode || !GetImpl()->getCurrentForm_Lock().is() )
952 rSet.DisableItem( nWhich );
953 break;
954 case SID_FM_DESIGN_MODE:
955 if (!m_pFormView || GetImpl()->IsReadonlyDoc_Lock())
956 rSet.DisableItem( nWhich );
957 else
958 rSet.Put( SfxBoolItem(nWhich, m_bDesignMode) );
959 break;
960 case SID_FM_SEARCH:
961 case SID_FM_RECORD_FIRST:
962 case SID_FM_RECORD_NEXT:
963 case SID_FM_RECORD_PREV:
964 case SID_FM_RECORD_LAST:
965 case SID_FM_RECORD_NEW:
966 case SID_FM_RECORD_DELETE:
967 case SID_FM_RECORD_ABSOLUTE:
968 case SID_FM_RECORD_TOTAL:
969 case SID_FM_RECORD_SAVE:
970 case SID_FM_RECORD_UNDO:
971 case SID_FM_FORM_FILTERED:
972 case SID_FM_REMOVE_FILTER_SORT:
973 case SID_FM_SORTUP:
974 case SID_FM_SORTDOWN:
975 case SID_FM_ORDERCRIT:
976 case SID_FM_FILTER_START:
977 case SID_FM_AUTOFILTER:
978 case SID_FM_REFRESH:
979 case SID_FM_REFRESH_FORM_CONTROL:
980 case SID_FM_VIEW_AS_GRID:
981 GetFormState(rSet,nWhich);
982 break;
984 case SID_FM_CHANGECONTROLTYPE:
986 if ( !m_pFormView || !m_bDesignMode )
987 rSet.DisableItem( nWhich );
988 else
990 if (!GetImpl()->canConvertCurrentSelectionToControl_Lock("ConvertToFixed"))
991 // if it cannot be converted to a fixed text, it is no single control
992 rSet.DisableItem( nWhich );
994 } break;
996 case SID_FM_CONVERTTO_FILECONTROL :
997 case SID_FM_CONVERTTO_CURRENCY :
998 case SID_FM_CONVERTTO_PATTERN :
999 case SID_FM_CONVERTTO_IMAGECONTROL :
1000 case SID_FM_CONVERTTO_SCROLLBAR :
1001 case SID_FM_CONVERTTO_NAVIGATIONBAR :
1002 case SID_FM_CONVERTTO_IMAGEBUTTON :
1003 case SID_FM_CONVERTTO_EDIT :
1004 case SID_FM_CONVERTTO_BUTTON :
1005 case SID_FM_CONVERTTO_FIXEDTEXT :
1006 case SID_FM_CONVERTTO_LISTBOX :
1007 case SID_FM_CONVERTTO_CHECKBOX :
1008 case SID_FM_CONVERTTO_RADIOBUTTON :
1009 case SID_FM_CONVERTTO_GROUPBOX :
1010 case SID_FM_CONVERTTO_COMBOBOX :
1011 case SID_FM_CONVERTTO_DATE :
1012 case SID_FM_CONVERTTO_TIME :
1013 case SID_FM_CONVERTTO_NUMERIC :
1014 case SID_FM_CONVERTTO_FORMATTED :
1015 case SID_FM_CONVERTTO_SPINBUTTON :
1017 if (!m_pFormView || !m_bDesignMode || !GetImpl()->canConvertCurrentSelectionToControl_Lock(FmXFormShell::SlotToIdent(nWhich)))
1018 rSet.DisableItem( nWhich );
1019 else
1021 rSet.Put( SfxBoolItem( nWhich, false ) );
1022 // just to have a defined state (available and not checked)
1025 break;
1027 nWhich = aIter.NextWhich();
1032 void FmFormShell::GetFormState(SfxItemSet &rSet, sal_uInt16 nWhich)
1034 if ( !GetImpl()->getNavController_Lock().is()
1035 || !isRowSetAlive(GetImpl()->getNavController_Lock()->getModel())
1036 || !m_pFormView
1037 || m_bDesignMode
1038 || !GetImpl()->getActiveForm_Lock().is()
1039 || GetImpl()->isInFilterMode_Lock()
1041 rSet.DisableItem(nWhich);
1042 else
1044 bool bEnable = false;
1047 switch (nWhich)
1049 case SID_FM_VIEW_AS_GRID:
1050 if (GetImpl()->getHostFrame_Lock().is() && GetImpl()->getNavController_Lock().is())
1052 bEnable = true;
1053 bool bDisplayingCurrent =
1054 GetImpl()->getInternalForm_Lock(
1055 Reference<XForm>(GetImpl()->getNavController_Lock()->getModel(), UNO_QUERY)
1056 ) == GetImpl()->getExternallyDisplayedForm_Lock();
1057 rSet.Put(SfxBoolItem(nWhich, bDisplayingCurrent));
1059 break;
1061 case SID_FM_SEARCH:
1063 Reference<css::beans::XPropertySet> const xNavSet(GetImpl()->getActiveForm_Lock(), UNO_QUERY);
1064 sal_Int32 nCount = ::comphelper::getINT32(xNavSet->getPropertyValue(FM_PROP_ROWCOUNT));
1065 bEnable = nCount != 0;
1066 } break;
1067 case SID_FM_RECORD_ABSOLUTE:
1068 case SID_FM_RECORD_TOTAL:
1070 FeatureState aState;
1071 GetImpl()->getNavControllerFeatures_Lock()->getState( nWhich, aState );
1072 if ( SID_FM_RECORD_ABSOLUTE == nWhich )
1074 sal_Int32 nPosition = 0;
1075 aState.State >>= nPosition;
1076 rSet.Put( SfxInt32Item( nWhich, nPosition ) );
1078 else if ( SID_FM_RECORD_TOTAL == nWhich )
1080 OUString sTotalCount;
1081 aState.State >>= sTotalCount;
1082 rSet.Put( SfxStringItem( nWhich, sTotalCount ) );
1084 bEnable = aState.Enabled;
1086 break;
1088 // first, prev, next, last, and absolute affect the nav controller, not the
1089 // active controller
1090 case SID_FM_RECORD_FIRST:
1091 case SID_FM_RECORD_PREV:
1092 case SID_FM_RECORD_NEXT:
1093 case SID_FM_RECORD_LAST:
1094 case SID_FM_RECORD_NEW:
1095 case SID_FM_RECORD_SAVE:
1096 case SID_FM_RECORD_UNDO:
1097 case SID_FM_RECORD_DELETE:
1098 case SID_FM_REFRESH:
1099 case SID_FM_REFRESH_FORM_CONTROL:
1100 case SID_FM_REMOVE_FILTER_SORT:
1101 case SID_FM_SORTUP:
1102 case SID_FM_SORTDOWN:
1103 case SID_FM_AUTOFILTER:
1104 case SID_FM_ORDERCRIT:
1105 bEnable = GetImpl()->IsFormSlotEnabled( nWhich, nullptr );
1106 break;
1108 case SID_FM_FORM_FILTERED:
1110 FeatureState aState;
1111 bEnable = GetImpl()->IsFormSlotEnabled( nWhich, &aState );
1113 rSet.Put( SfxBoolItem( nWhich, ::comphelper::getBOOL( aState.State ) ) );
1115 break;
1117 case SID_FM_FILTER_START:
1118 bEnable = GetImpl()->getActiveControllerFeatures_Lock()->canDoFormFilter();
1119 break;
1122 catch( const Exception& )
1124 TOOLS_WARN_EXCEPTION("svx.form", "caught an exception while determining the state!");
1126 if (!bEnable)
1127 rSet.DisableItem(nWhich);
1132 FmFormPage* FmFormShell::GetCurPage() const
1134 FmFormPage* pP = nullptr;
1135 if (m_pFormView && m_pFormView->GetSdrPageView())
1136 pP = dynamic_cast<FmFormPage*>( m_pFormView->GetSdrPageView()->GetPage() );
1137 return pP;
1141 void FmFormShell::SetView( FmFormView* _pView )
1143 if ( m_pFormView )
1145 if ( IsActive() )
1146 GetImpl()->viewDeactivated_Lock(*m_pFormView);
1148 m_pFormView->SetFormShell( nullptr, FmFormView::FormShellAccess() );
1149 m_pFormView = nullptr;
1150 m_pFormModel = nullptr;
1153 if ( !_pView )
1154 return;
1156 m_pFormView = _pView;
1157 m_pFormView->SetFormShell( this, FmFormView::FormShellAccess() );
1158 m_pFormModel = static_cast<FmFormModel*>(m_pFormView->GetModel());
1160 impl_setDesignMode( m_pFormView->IsDesignMode() );
1162 // We activate our view if we are activated ourself, but sometimes the Activate precedes the SetView.
1163 // But here we know both the view and our activation state so we at least are able to pass the latter
1164 // to the former.
1165 // FS - 30.06.99 - 67308
1166 if ( IsActive() )
1167 GetImpl()->viewActivated_Lock(*m_pFormView);
1171 void FmFormShell::DetermineForms(bool bInvalidate)
1173 // are there forms on the current page
1174 bool bForms = GetImpl()->hasForms_Lock();
1175 if (bForms != m_bHasForms)
1177 m_bHasForms = bForms;
1178 if (bInvalidate)
1179 UIFeatureChanged();
1184 bool FmFormShell::GetY2KState(sal_uInt16& nReturn)
1186 return GetImpl()->GetY2KState_Lock(nReturn);
1190 void FmFormShell::SetY2KState(sal_uInt16 n)
1192 GetImpl()->SetY2KState_Lock(n);
1196 void FmFormShell::Activate(bool bMDI)
1198 SfxShell::Activate(bMDI);
1200 if ( m_pFormView )
1201 GetImpl()->viewActivated_Lock(*m_pFormView, true);
1205 void FmFormShell::Deactivate(bool bMDI)
1207 SfxShell::Deactivate(bMDI);
1209 if ( m_pFormView )
1210 GetImpl()->viewDeactivated_Lock(*m_pFormView, false);
1214 void FmFormShell::ExecuteTextAttribute( SfxRequest& _rReq )
1216 m_pImpl->ExecuteTextAttribute_Lock(_rReq);
1220 void FmFormShell::GetTextAttributeState( SfxItemSet& _rSet )
1222 m_pImpl->GetTextAttributeState_Lock(_rSet);
1226 bool FmFormShell::IsActiveControl() const
1228 return m_pImpl->IsActiveControl_Lock(false);
1232 void FmFormShell::ForgetActiveControl()
1234 m_pImpl->ForgetActiveControl_Lock();
1238 void FmFormShell::SetControlActivationHandler( const Link<LinkParamNone*,void>& _rHdl )
1240 m_pImpl->SetControlActivationHandler_Lock(_rHdl);
1244 namespace
1246 SdrUnoObj* lcl_findUnoObject( const SdrObjList& _rObjList, const Reference< XControlModel >& _rxModel )
1248 SdrObjListIter aIter( &_rObjList );
1249 while ( aIter.IsMore() )
1251 SdrObject* pObject = aIter.Next();
1252 SdrUnoObj* pUnoObject = dynamic_cast<SdrUnoObj*>( pObject );
1253 if ( !pUnoObject )
1254 continue;
1256 Reference< XControlModel > xControlModel = pUnoObject->GetUnoControlModel();
1257 if ( !xControlModel.is() )
1258 continue;
1260 if ( _rxModel == xControlModel )
1261 return pUnoObject;
1263 return nullptr;
1268 void FmFormShell::ToggleControlFocus( const SdrUnoObj& i_rUnoObject, const SdrView& i_rView, OutputDevice& i_rDevice ) const
1272 // check if the focus currently is in a control
1273 // Well, okay, do it the other way 'round: Check whether the current control of the active controller
1274 // actually has the focus. This should be equivalent.
1275 const bool bHasControlFocus = GetImpl()->HasControlFocus_Lock();
1277 if ( bHasControlFocus )
1279 vcl::Window* pWindow = i_rDevice.GetOwnerWindow();
1280 OSL_ENSURE( pWindow, "FmFormShell::ToggleControlFocus: I need a Window, really!" );
1281 if ( pWindow )
1282 pWindow->GrabFocus();
1284 else
1286 Reference< XControl > xControl;
1287 GetFormControl( i_rUnoObject.GetUnoControlModel(), i_rView, i_rDevice, xControl );
1288 Reference< XWindow > xControlWindow( xControl, UNO_QUERY );
1289 if ( xControlWindow.is() )
1290 xControlWindow->setFocus();
1293 catch( const Exception& )
1295 DBG_UNHANDLED_EXCEPTION("svx");
1300 namespace
1302 class FocusableControlsFilter : public svx::ISdrObjectFilter
1304 public:
1305 FocusableControlsFilter( const SdrView& i_rView, const OutputDevice& i_rDevice )
1306 :m_rView( i_rView )
1307 ,m_rDevice( i_rDevice )
1311 public:
1312 virtual bool includeObject( const SdrObject& i_rObject ) const override
1314 const SdrUnoObj* pUnoObj = dynamic_cast< const SdrUnoObj* >( &i_rObject );
1315 if ( !pUnoObj )
1316 return false;
1318 Reference< XControl > xControl = pUnoObj->GetUnoControl( m_rView, m_rDevice );
1319 return FmXFormView::isFocusable( xControl );
1322 private:
1323 const SdrView& m_rView;
1324 const OutputDevice& m_rDevice;
1329 ::std::unique_ptr< svx::ISdrObjectFilter > FmFormShell::CreateFocusableControlFilter( const SdrView& i_rView, const OutputDevice& i_rDevice )
1331 ::std::unique_ptr< svx::ISdrObjectFilter > pFilter;
1333 if ( !i_rView.IsDesignMode() )
1334 pFilter.reset( new FocusableControlsFilter( i_rView, i_rDevice ) );
1336 return pFilter;
1340 SdrUnoObj* FmFormShell::GetFormControl( const Reference< XControlModel >& _rxModel, const SdrView& _rView, const OutputDevice& _rDevice, Reference< XControl >& _out_rxControl ) const
1342 if ( !_rxModel.is() )
1343 return nullptr;
1345 // we can only retrieve controls for SdrObjects which belong to page which is actually displayed in the given view
1346 SdrPageView* pPageView = _rView.GetSdrPageView();
1347 SdrPage* pPage = pPageView ? pPageView->GetPage() : nullptr;
1348 OSL_ENSURE( pPage, "FmFormShell::GetFormControl: no page displayed in the given view!" );
1349 if ( !pPage )
1350 return nullptr;
1352 SdrUnoObj* pUnoObject = lcl_findUnoObject( *pPage, _rxModel );
1353 if ( pUnoObject )
1355 _out_rxControl = pUnoObject->GetUnoControl( _rView, _rDevice );
1356 return pUnoObject;
1359 #if OSL_DEBUG_LEVEL > 0
1360 // perhaps we are fed with a control model which lives on a page other than the one displayed
1361 // in the given view. This is worth being reported as error, in non-product builds.
1362 FmFormModel* pModel = GetFormModel();
1363 if ( pModel )
1365 sal_uInt16 pageCount = pModel->GetPageCount();
1366 for ( sal_uInt16 page = 0; page < pageCount; ++page )
1368 pPage = pModel->GetPage( page );
1369 OSL_ENSURE( pPage, "FmFormShell::GetFormControl: NULL page encountered!" );
1370 if ( !pPage )
1371 continue;
1373 pUnoObject = lcl_findUnoObject( *pPage, _rxModel );
1374 OSL_ENSURE( !pUnoObject, "FmFormShell::GetFormControl: the given control model belongs to a wrong page (displayed elsewhere)!" );
1377 #else
1378 (void) this; // avoid loplugin:staticmethods
1379 #endif
1381 return nullptr;
1385 Reference< runtime::XFormController > FmFormShell::GetFormController( const Reference< XForm >& _rxForm, const SdrView& _rView, const OutputDevice& _rDevice )
1387 const FmFormView* pFormView = dynamic_cast< const FmFormView* >( &_rView );
1388 if ( !pFormView )
1389 return nullptr;
1391 return pFormView->GetFormController( _rxForm, _rDevice );
1395 void FmFormShell::SetDesignMode( bool _bDesignMode )
1397 if ( _bDesignMode == m_bDesignMode )
1398 return;
1400 FmFormModel* pModel = GetFormModel();
1401 if (pModel)
1402 // Switch off the undo environment for the time of the transition. This ensures that
1403 // one can also change non-transient properties there. (It should be done with
1404 // caution, however, and it should always be reversed when one switches the mode back.
1405 // An example is the setting of the maximum text length by the OEditModel on its control.)
1406 pModel->GetUndoEnv().Lock();
1408 // then the actual switch
1409 if ( m_bDesignMode || PrepareClose() )
1410 impl_setDesignMode(!m_bDesignMode );
1412 // and my undo environment back on
1413 if ( pModel )
1414 pModel->GetUndoEnv().UnLock();
1417 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */