Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / svx / source / form / fmshell.cxx
blob423bbb7c25fce63eb1d048f89e8afe417f1a5d19
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 <comphelper/diagnose_ex.hxx>
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);
272 bool FmFormShell::HasUIFeature(SfxShellFeature nFeature) const
274 assert((nFeature & ~SfxShellFeature::FormMask) == SfxShellFeature::NONE);
275 bool bResult = false;
276 if (nFeature & SfxShellFeature::FormShowDatabaseBar)
278 // only if forms are also available
279 bResult = !m_bDesignMode && GetImpl()->hasDatabaseBar_Lock() && !GetImpl()->isInFilterMode_Lock();
281 else if (nFeature & SfxShellFeature::FormShowFilterBar)
283 // only if forms are also available
284 bResult = !m_bDesignMode && GetImpl()->hasDatabaseBar_Lock() && GetImpl()->isInFilterMode_Lock();
286 else if (nFeature & SfxShellFeature::FormShowFilterNavigator)
288 bResult = !m_bDesignMode && GetImpl()->hasDatabaseBar_Lock() && GetImpl()->isInFilterMode_Lock();
290 else if (nFeature & SfxShellFeature::FormShowField)
292 bResult = m_bDesignMode && m_pFormView && m_bHasForms;
294 else if (nFeature & SfxShellFeature::FormShowProperties)
296 bResult = m_bDesignMode && m_pFormView && m_bHasForms;
298 else if (nFeature & SfxShellFeature::FormShowExplorer)
300 bResult = m_bDesignMode; // OJ #101593# && m_pFormView && m_bHasForms;
302 else if (nFeature & SfxShellFeature::FormShowTextControlBar)
304 bResult = !GetImpl()->IsReadonlyDoc_Lock() && m_pImpl->IsActiveControl_Lock(true);
306 else if (nFeature & SfxShellFeature::FormShowDataNavigator)
308 bResult = GetImpl()->isEnhancedForm_Lock();
310 else if ( (nFeature & SfxShellFeature::FormTBControls)
311 || (nFeature & SfxShellFeature::FormTBDesign)
314 bResult = true;
317 return bResult;
321 void FmFormShell::Execute(SfxRequest &rReq)
323 sal_uInt16 nSlot = rReq.GetSlot();
326 // set MasterSlot
327 switch( nSlot )
329 case SID_FM_PUSHBUTTON:
330 case SID_FM_RADIOBUTTON:
331 case SID_FM_CHECKBOX:
332 case SID_FM_FIXEDTEXT:
333 case SID_FM_GROUPBOX:
334 case SID_FM_LISTBOX:
335 case SID_FM_COMBOBOX:
336 case SID_FM_NAVIGATIONBAR:
337 case SID_FM_EDIT:
338 case SID_FM_DBGRID:
339 case SID_FM_IMAGEBUTTON:
340 case SID_FM_IMAGECONTROL:
341 case SID_FM_FILECONTROL:
342 case SID_FM_DATEFIELD:
343 case SID_FM_TIMEFIELD:
344 case SID_FM_NUMERICFIELD:
345 case SID_FM_CURRENCYFIELD:
346 case SID_FM_PATTERNFIELD:
347 case SID_FM_FORMATTEDFIELD:
348 case SID_FM_SCROLLBAR:
349 case SID_FM_SPINBUTTON:
350 m_nLastSlot = nSlot;
351 break;
355 // set the Identifier and Inventor of the Uno control
356 SdrObjKind nIdentifier = SdrObjKind::NONE;
357 switch( nSlot )
359 case SID_FM_CHECKBOX:
360 nIdentifier = SdrObjKind::FormCheckbox;
361 break;
362 case SID_FM_PUSHBUTTON:
363 nIdentifier = SdrObjKind::FormButton;
364 break;
365 case SID_FM_FIXEDTEXT:
366 nIdentifier = SdrObjKind::FormFixedText;
367 break;
368 case SID_FM_LISTBOX:
369 nIdentifier = SdrObjKind::FormListbox;
370 break;
371 case SID_FM_EDIT:
372 nIdentifier = SdrObjKind::FormEdit;
373 break;
374 case SID_FM_RADIOBUTTON:
375 nIdentifier = SdrObjKind::FormRadioButton;
376 break;
377 case SID_FM_GROUPBOX:
378 nIdentifier = SdrObjKind::FormGroupBox;
379 break;
380 case SID_FM_COMBOBOX:
381 nIdentifier = SdrObjKind::FormCombobox;
382 break;
383 case SID_FM_NAVIGATIONBAR:
384 nIdentifier = SdrObjKind::FormNavigationBar;
385 break;
386 case SID_FM_DBGRID:
387 nIdentifier = SdrObjKind::FormGrid;
388 break;
389 case SID_FM_IMAGEBUTTON:
390 nIdentifier = SdrObjKind::FormImageButton;
391 break;
392 case SID_FM_IMAGECONTROL:
393 nIdentifier = SdrObjKind::FormImageControl;
394 break;
395 case SID_FM_FILECONTROL:
396 nIdentifier = SdrObjKind::FormFileControl;
397 break;
398 case SID_FM_DATEFIELD:
399 nIdentifier = SdrObjKind::FormDateField;
400 break;
401 case SID_FM_TIMEFIELD:
402 nIdentifier = SdrObjKind::FormTimeField;
403 break;
404 case SID_FM_NUMERICFIELD:
405 nIdentifier = SdrObjKind::FormNumericField;
406 break;
407 case SID_FM_CURRENCYFIELD:
408 nIdentifier = SdrObjKind::FormCurrencyField;
409 break;
410 case SID_FM_PATTERNFIELD:
411 nIdentifier = SdrObjKind::FormPatternField;
412 break;
413 case SID_FM_FORMATTEDFIELD:
414 nIdentifier = SdrObjKind::FormFormattedField;
415 break;
416 case SID_FM_SCROLLBAR:
417 nIdentifier = SdrObjKind::FormScrollbar;
418 break;
419 case SID_FM_SPINBUTTON:
420 nIdentifier = SdrObjKind::FormSpinButton;
421 break;
424 switch ( nSlot )
426 case SID_FM_CHECKBOX:
427 case SID_FM_PUSHBUTTON:
428 case SID_FM_FIXEDTEXT:
429 case SID_FM_LISTBOX:
430 case SID_FM_EDIT:
431 case SID_FM_RADIOBUTTON:
432 case SID_FM_COMBOBOX:
433 case SID_FM_NAVIGATIONBAR:
434 case SID_FM_GROUPBOX:
435 case SID_FM_DBGRID:
436 case SID_FM_IMAGEBUTTON:
437 case SID_FM_IMAGECONTROL:
438 case SID_FM_FILECONTROL:
439 case SID_FM_DATEFIELD:
440 case SID_FM_TIMEFIELD:
441 case SID_FM_NUMERICFIELD:
442 case SID_FM_CURRENCYFIELD:
443 case SID_FM_PATTERNFIELD:
444 case SID_FM_FORMATTEDFIELD:
445 case SID_FM_SCROLLBAR:
446 case SID_FM_SPINBUTTON:
448 const SfxBoolItem* pGrabFocusItem = rReq.GetArg<SfxBoolItem>(SID_FM_TOGGLECONTROLFOCUS);
449 if ( pGrabFocusItem && pGrabFocusItem->GetValue() )
450 { // see below
451 SfxViewShell* pShell = GetViewShell();
452 vcl::Window* pShellWnd = pShell ? pShell->GetWindow() : nullptr;
453 if ( pShellWnd )
454 pShellWnd->GrabFocus();
455 break;
458 SfxUInt16Item aIdentifierItem( SID_FM_CONTROL_IDENTIFIER, static_cast<sal_uInt16>(nIdentifier) );
459 SfxUInt32Item aInventorItem( SID_FM_CONTROL_INVENTOR, sal_uInt32(SdrInventor::FmForm) );
460 const SfxPoolItem* pArgs[] =
462 &aIdentifierItem, &aInventorItem, nullptr
464 const SfxPoolItem* pInternalArgs[] =
466 nullptr
469 GetViewShell()->GetViewFrame().GetDispatcher()->Execute( SID_FM_CREATE_CONTROL, SfxCallMode::ASYNCHRON,
470 pArgs, rReq.GetModifier(), pInternalArgs );
472 if ( rReq.GetModifier() & KEY_MOD1 )
474 // #99013# if selected with control key, return focus to current view
475 // do this asynchron, so that the creation can be finished first
476 // reusing the SID_FM_TOGGLECONTROLFOCUS is somewhat hacky... which it wouldn't if it would have another
477 // name, so I do not really have a big problem with this...
478 SfxBoolItem aGrabFocusIndicatorItem( SID_FM_TOGGLECONTROLFOCUS, true );
479 GetViewShell()->GetViewFrame().GetDispatcher()->ExecuteList(
480 nSlot, SfxCallMode::ASYNCHRON,
481 { &aGrabFocusIndicatorItem });
484 rReq.Done();
485 } break;
488 // individual actions
489 switch( nSlot )
491 case SID_FM_FORM_DESIGN_TOOLS:
493 FormToolboxes aToolboxAccess(GetImpl()->getHostFrame_Lock());
494 aToolboxAccess.toggleToolbox( nSlot );
495 rReq.Done();
497 break;
499 case SID_FM_TOGGLECONTROLFOCUS:
501 FmFormView* pFormView = GetFormView();
502 if ( !pFormView )
503 break;
505 // if we execute this ourself, then either the application does not implement an own handling for this,
506 // of we're on the top of the dispatcher stack, which means a control has the focus.
507 // In the latter case, we put the focus to the document window, otherwise, we focus the first control
508 const bool bHasControlFocus = GetImpl()->HasControlFocus_Lock();
509 if ( bHasControlFocus )
511 if (m_pFormView)
513 const OutputDevice* pDevice = m_pFormView->GetActualOutDev();
514 vcl::Window* pWindow = pDevice->GetOwnerWindow();
515 if ( pWindow )
516 pWindow->GrabFocus();
519 else
521 pFormView->GrabFirstControlFocus( );
524 break;
526 case SID_FM_VIEW_AS_GRID:
527 GetImpl()->CreateExternalView_Lock();
528 break;
529 case SID_FM_CONVERTTO_EDIT :
530 case SID_FM_CONVERTTO_BUTTON :
531 case SID_FM_CONVERTTO_FIXEDTEXT :
532 case SID_FM_CONVERTTO_LISTBOX :
533 case SID_FM_CONVERTTO_CHECKBOX :
534 case SID_FM_CONVERTTO_RADIOBUTTON :
535 case SID_FM_CONVERTTO_GROUPBOX :
536 case SID_FM_CONVERTTO_COMBOBOX :
537 case SID_FM_CONVERTTO_IMAGEBUTTON :
538 case SID_FM_CONVERTTO_FILECONTROL :
539 case SID_FM_CONVERTTO_DATE :
540 case SID_FM_CONVERTTO_TIME :
541 case SID_FM_CONVERTTO_NUMERIC :
542 case SID_FM_CONVERTTO_CURRENCY :
543 case SID_FM_CONVERTTO_PATTERN :
544 case SID_FM_CONVERTTO_IMAGECONTROL :
545 case SID_FM_CONVERTTO_FORMATTED :
546 case SID_FM_CONVERTTO_SCROLLBAR :
547 case SID_FM_CONVERTTO_SPINBUTTON :
548 case SID_FM_CONVERTTO_NAVIGATIONBAR :
549 GetImpl()->executeControlConversionSlot_Lock(FmXFormShell::SlotToIdent(nSlot));
550 // after the conversion, re-determine the selection, since the
551 // selected object has changed
552 GetImpl()->SetSelection_Lock(GetFormView()->GetMarkedObjectList());
553 break;
554 case SID_FM_LEAVE_CREATE:
555 m_nLastSlot = 0;
556 rReq.Done();
557 break;
558 case SID_FM_SHOW_PROPERTY_BROWSER:
560 const SfxBoolItem* pShowItem = rReq.GetArg<SfxBoolItem>(SID_FM_SHOW_PROPERTIES);
561 bool bShow = true;
562 if ( pShowItem )
563 bShow = pShowItem->GetValue();
564 GetImpl()->ShowSelectionProperties_Lock(bShow);
566 rReq.Done();
567 } break;
569 case SID_FM_PROPERTIES:
571 // display the PropertyBrowser
572 const SfxBoolItem* pShowItem = rReq.GetArg<SfxBoolItem>(nSlot);
573 bool bShow = pShowItem == nullptr || pShowItem->GetValue();
575 InterfaceBag aOnlyTheForm;
576 aOnlyTheForm.insert(Reference<XInterface>(GetImpl()->getCurrentForm_Lock(), UNO_QUERY));
577 GetImpl()->setCurrentSelection_Lock(std::move(aOnlyTheForm));
579 GetImpl()->ShowSelectionProperties_Lock(bShow);
581 rReq.Done();
582 } break;
584 case SID_FM_CTL_PROPERTIES:
586 const SfxBoolItem* pShowItem = rReq.GetArg<SfxBoolItem>(nSlot);
587 bool bShow = pShowItem == nullptr || pShowItem->GetValue();
589 OSL_ENSURE( GetImpl()->onlyControlsAreMarked_Lock(), "FmFormShell::Execute: ControlProperties should be disabled!" );
590 if ( bShow )
591 GetImpl()->selectLastMarkedControls_Lock();
592 GetImpl()->ShowSelectionProperties_Lock(bShow);
594 rReq.Done();
595 } break;
596 case SID_FM_SHOW_PROPERTIES:
597 case SID_FM_ADD_FIELD:
598 case SID_FM_FILTER_NAVIGATOR:
599 case SID_FM_SHOW_DATANAVIGATOR :
601 GetViewShell()->GetViewFrame().ToggleChildWindow(nSlot);
602 rReq.Done();
603 } break;
604 case SID_FM_SHOW_FMEXPLORER:
606 if (!m_pFormView) // force setting the view
607 GetViewShell()->GetViewFrame().GetDispatcher()->Execute(SID_CREATE_SW_DRAWVIEW);
609 GetViewShell()->GetViewFrame().ChildWindowExecute(rReq);
610 rReq.Done();
612 break;
614 case SID_FM_TAB_DIALOG:
616 GetImpl()->ExecuteTabOrderDialog_Lock(
617 Reference<XTabControllerModel>(GetImpl()->getCurrentForm_Lock(), UNO_QUERY));
618 rReq.Done();
620 break;
622 case SID_FM_DESIGN_MODE:
624 const SfxBoolItem* pDesignItem = rReq.GetArg<SfxBoolItem>(nSlot);
625 bool bDesignMode = pDesignItem ? pDesignItem->GetValue() : !m_bDesignMode;
626 SetDesignMode( bDesignMode );
627 if ( m_bDesignMode == bDesignMode )
628 rReq.Done();
630 m_nLastSlot = SID_FM_DESIGN_MODE;
632 break;
634 case SID_FM_AUTOCONTROLFOCUS:
636 FmFormModel* pModel = GetFormModel();
637 DBG_ASSERT(pModel, "FmFormShell::Execute : invalid call !");
638 // should have been disabled in GetState if we don't have a FormModel
639 pModel->SetAutoControlFocus( !pModel->GetAutoControlFocus() );
640 GetViewShell()->GetViewFrame().GetBindings().Invalidate(SID_FM_AUTOCONTROLFOCUS);
642 break;
643 case SID_FM_OPEN_READONLY:
645 FmFormModel* pModel = GetFormModel();
646 DBG_ASSERT(pModel, "FmFormShell::Execute : invalid call !");
647 // should have been disabled in GetState if we don't have a FormModel
648 pModel->SetOpenInDesignMode( !pModel->GetOpenInDesignMode() );
649 GetViewShell()->GetViewFrame().GetBindings().Invalidate(SID_FM_OPEN_READONLY);
651 break;
652 case SID_FM_USE_WIZARDS:
654 GetImpl()->SetWizardUsing_Lock(!GetImpl()->GetWizardUsing_Lock());
655 GetViewShell()->GetViewFrame().GetBindings().Invalidate(SID_FM_USE_WIZARDS);
657 break;
658 case SID_FM_SEARCH:
660 const svx::ControllerFeatures& rController = GetImpl()->getActiveControllerFeatures_Lock();
661 if ( rController->commitCurrentControl() && rController->commitCurrentRecord() )
662 GetImpl()->ExecuteSearch_Lock();
663 rReq.Done();
665 break;
667 case SID_FM_RECORD_FIRST:
668 case SID_FM_RECORD_PREV:
669 case SID_FM_RECORD_NEXT:
670 case SID_FM_RECORD_LAST:
671 case SID_FM_RECORD_NEW:
672 case SID_FM_REFRESH:
673 case SID_FM_REFRESH_FORM_CONTROL:
674 case SID_FM_RECORD_DELETE:
675 case SID_FM_RECORD_UNDO:
676 case SID_FM_RECORD_SAVE:
677 case SID_FM_REMOVE_FILTER_SORT:
678 case SID_FM_SORTDOWN:
679 case SID_FM_SORTUP:
680 case SID_FM_AUTOFILTER:
681 case SID_FM_ORDERCRIT:
682 case SID_FM_FORM_FILTERED:
684 GetImpl()->ExecuteFormSlot_Lock(nSlot);
685 rReq.Done();
687 break;
689 case SID_FM_RECORD_ABSOLUTE:
691 const svx::ControllerFeatures& rController = GetImpl()->getNavControllerFeatures_Lock();
692 sal_Int32 nRecord = -1;
694 const SfxItemSet* pArgs = rReq.GetArgs();
695 if ( pArgs )
697 const SfxPoolItem* pItem;
698 if ( ( pArgs->GetItemState( FN_PARAM_1, true, &pItem ) ) == SfxItemState::SET )
700 const SfxInt32Item* pTypedItem = dynamic_cast<const SfxInt32Item* >( pItem );
701 if ( pTypedItem )
702 nRecord = std::max( pTypedItem->GetValue(), sal_Int32(0) );
705 else
707 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
708 ScopedVclPtr<AbstractFmInputRecordNoDialog> dlg(pFact->CreateFmInputRecordNoDialog(rReq.GetFrameWeld()));
709 dlg->SetValue( rController->getCursor()->getRow() );
710 if ( dlg->Execute() == RET_OK )
711 nRecord = dlg->GetValue();
713 rReq.AppendItem( SfxInt32Item( TypedWhichId<SfxInt32Item>(FN_PARAM_1), nRecord ) );
716 if ( nRecord != -1 )
717 rController->execute( nSlot, "Position", Any( nRecord ) );
719 rReq.Done();
720 } break;
721 case SID_FM_FILTER_EXECUTE:
722 case SID_FM_FILTER_EXIT:
724 bool bCancelled = ( SID_FM_FILTER_EXIT == nSlot );
725 bool bReopenNavigator = false;
727 if ( !bCancelled )
729 // if the filter navigator is still open, we need to close it, so it can possibly
730 // commit it's most recent changes
731 if (GetViewShell())
732 if ( GetViewShell()->GetViewFrame().HasChildWindow( SID_FM_FILTER_NAVIGATOR ) )
734 GetViewShell()->GetViewFrame().ToggleChildWindow( SID_FM_FILTER_NAVIGATOR );
735 bReopenNavigator = true;
738 Reference<runtime::XFormController> const xController(GetImpl()->getActiveController_Lock());
740 if ( GetViewShell()->GetViewFrame().HasChildWindow( SID_FM_FILTER_NAVIGATOR )
741 // closing the window was denied, for instance because of an invalid criterion
743 || ( xController.is()
744 && !GetImpl()->getActiveControllerFeatures_Lock()->commitCurrentControl()
746 // committing the controller was denied
749 rReq.Done();
750 break;
754 GetImpl()->stopFiltering_Lock(!bCancelled);
755 rReq.Done();
757 if ( bReopenNavigator )
758 // we closed the navigator only to implicitly commit it (as we do not have another
759 // direct wire to it), but to the user, it should look as it was always open
760 GetViewShell()->GetViewFrame().ToggleChildWindow( SID_FM_FILTER_NAVIGATOR );
762 break;
764 case SID_FM_FILTER_START:
766 GetImpl()->startFiltering_Lock();
767 rReq.Done();
769 // initially open the filter navigator, the whole form based filter is pretty useless without it
770 SfxBoolItem aIdentifierItem( SID_FM_FILTER_NAVIGATOR, true );
771 GetViewShell()->GetViewFrame().GetDispatcher()->ExecuteList(
772 SID_FM_FILTER_NAVIGATOR, SfxCallMode::ASYNCHRON,
773 { &aIdentifierItem });
774 } break;
779 void FmFormShell::GetState(SfxItemSet &rSet)
781 SfxWhichIter aIter( rSet );
782 sal_uInt16 nWhich = aIter.FirstWhich();
783 while ( nWhich )
785 switch( nWhich )
787 case SID_FM_FORM_DESIGN_TOOLS:
789 FormToolboxes aToolboxAccess(GetImpl()->getHostFrame_Lock());
790 rSet.Put( SfxBoolItem( nWhich, aToolboxAccess.isToolboxVisible( nWhich ) ) );
792 break;
794 case SID_FM_FILTER_EXECUTE:
795 case SID_FM_FILTER_EXIT:
796 if (!GetImpl()->isInFilterMode_Lock())
797 rSet.DisableItem( nWhich );
798 break;
800 case SID_FM_USE_WIZARDS:
801 if ( !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::EModule::DATABASE ) )
802 rSet.Put( SfxVisibilityItem( nWhich, false ) );
803 else if (!GetFormModel())
804 rSet.DisableItem( nWhich );
805 else
806 rSet.Put(SfxBoolItem(nWhich, GetImpl()->GetWizardUsing_Lock()));
807 break;
808 case SID_FM_AUTOCONTROLFOCUS:
809 if (!GetFormModel())
810 rSet.DisableItem( nWhich );
811 else
812 rSet.Put( SfxBoolItem(nWhich, GetFormModel()->GetAutoControlFocus() ) );
813 break;
814 case SID_FM_OPEN_READONLY:
815 if (!GetFormModel())
816 rSet.DisableItem( nWhich );
817 else
818 rSet.Put( SfxBoolItem(nWhich, GetFormModel()->GetOpenInDesignMode() ) );
819 break;
821 case SID_FM_NAVIGATIONBAR:
822 case SID_FM_DBGRID:
823 if ( !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::EModule::DATABASE ) )
825 rSet.Put( SfxVisibilityItem( nWhich, false ) );
826 break;
828 [[fallthrough]];
830 case SID_FM_SCROLLBAR:
831 case SID_FM_IMAGECONTROL:
832 case SID_FM_FILECONTROL:
833 case SID_FM_CURRENCYFIELD:
834 case SID_FM_PATTERNFIELD:
835 case SID_FM_IMAGEBUTTON:
836 case SID_FM_RADIOBUTTON:
837 case SID_FM_COMBOBOX:
838 case SID_FM_GROUPBOX:
839 case SID_FM_CHECKBOX:
840 case SID_FM_PUSHBUTTON:
841 case SID_FM_FIXEDTEXT:
842 case SID_FM_LISTBOX:
843 case SID_FM_EDIT:
844 case SID_FM_DATEFIELD:
845 case SID_FM_TIMEFIELD:
846 case SID_FM_NUMERICFIELD:
847 case SID_FM_FORMATTEDFIELD:
848 case SID_FM_SPINBUTTON:
849 if (!m_bDesignMode)
850 rSet.DisableItem( nWhich );
851 else
853 bool bLayerLocked = false;
854 if (m_pFormView)
856 // If the css::drawing::Layer is locked, the slots must be disabled. #36897
857 SdrPageView* pPV = m_pFormView->GetSdrPageView();
858 if (pPV != nullptr)
859 bLayerLocked = pPV->IsLayerLocked(m_pFormView->GetActiveLayer());
861 if (bLayerLocked)
862 rSet.DisableItem( nWhich );
863 else
864 rSet.Put( SfxBoolItem(nWhich, (nWhich==m_nLastSlot)) );
866 break;
867 case SID_FM_FILTER_NAVIGATOR_CONTROL:
869 if (GetImpl()->isInFilterMode_Lock())
870 rSet.Put(SfxObjectItem(nWhich, this));
871 else
872 rSet.Put(SfxObjectItem(nWhich));
873 } break;
874 case SID_FM_FIELDS_CONTROL:
875 case SID_FM_PROPERTY_CONTROL:
877 if (!m_bDesignMode || !m_pFormView || !m_bHasForms)
878 rSet.Put(SfxObjectItem(nWhich));
879 else
880 rSet.Put(SfxObjectItem(nWhich, this));
882 } break;
883 case SID_FM_FMEXPLORER_CONTROL:
884 case SID_FM_DATANAVIGATOR_CONTROL :
886 if (!m_bDesignMode || !m_pFormView)
887 rSet.Put(SfxObjectItem(nWhich));
888 else
889 rSet.Put(SfxObjectItem(nWhich, this));
891 } break;
892 case SID_FM_ADD_FIELD:
893 case SID_FM_SHOW_FMEXPLORER:
894 case SID_FM_SHOW_PROPERTIES:
895 case SID_FM_FILTER_NAVIGATOR:
896 case SID_FM_SHOW_DATANAVIGATOR:
898 if ( GetViewShell()->GetViewFrame().KnowsChildWindow(nWhich) )
899 rSet.Put( SfxBoolItem( nWhich, GetViewShell()->GetViewFrame().HasChildWindow(nWhich)) );
900 else
901 rSet.DisableItem(nWhich);
902 } break;
904 case SID_FM_SHOW_PROPERTY_BROWSER:
906 rSet.Put(SfxBoolItem(nWhich, GetImpl()->IsPropBrwOpen_Lock()));
908 break;
910 case SID_FM_CTL_PROPERTIES:
912 // potentially, give the Impl the opportunity to update its
913 // current objects which are aligned with the current MarkList
914 if (GetImpl()->IsSelectionUpdatePending_Lock())
915 GetImpl()->ForceUpdateSelection_Lock();
917 if (!m_pFormView || !m_bDesignMode || !GetImpl()->onlyControlsAreMarked_Lock())
918 rSet.DisableItem( nWhich );
919 else
921 bool const bChecked = GetImpl()->IsPropBrwOpen_Lock() && !GetImpl()->isSolelySelected_Lock(GetImpl()->getCurrentForm_Lock());
922 // if the property browser is open, and only controls are marked, and the current selection
923 // does not consist of only the current form, then the current selection is the (composition of)
924 // the currently marked controls
925 rSet.Put( SfxBoolItem( nWhich, bChecked ) );
927 } break;
929 case SID_FM_PROPERTIES:
931 // potentially, give the Impl the opportunity to update its
932 // current objects which are aligned with the current MarkList
933 if (GetImpl()->IsSelectionUpdatePending_Lock())
934 GetImpl()->ForceUpdateSelection_Lock();
936 if (!m_pFormView || !m_bDesignMode || !GetImpl()->getCurrentForm_Lock().is())
937 rSet.DisableItem( nWhich );
938 else
940 bool const bChecked = GetImpl()->IsPropBrwOpen_Lock() && GetImpl()->isSolelySelected_Lock(GetImpl()->getCurrentForm_Lock());
941 rSet.Put(SfxBoolItem(nWhich, bChecked));
943 } break;
944 case SID_FM_TAB_DIALOG:
945 // potentially, give the Impl the opportunity to update its
946 // current objects which are aligned with the current MarkList
947 if (GetImpl()->IsSelectionUpdatePending_Lock())
948 GetImpl()->ForceUpdateSelection_Lock();
950 if (!m_pFormView || !m_bDesignMode || !GetImpl()->getCurrentForm_Lock().is() )
951 rSet.DisableItem( nWhich );
952 break;
953 case SID_FM_DESIGN_MODE:
954 if (!m_pFormView || GetImpl()->IsReadonlyDoc_Lock())
955 rSet.DisableItem( nWhich );
956 else
957 rSet.Put( SfxBoolItem(nWhich, m_bDesignMode) );
958 break;
959 case SID_FM_SEARCH:
960 case SID_FM_RECORD_FIRST:
961 case SID_FM_RECORD_NEXT:
962 case SID_FM_RECORD_PREV:
963 case SID_FM_RECORD_LAST:
964 case SID_FM_RECORD_NEW:
965 case SID_FM_RECORD_DELETE:
966 case SID_FM_RECORD_ABSOLUTE:
967 case SID_FM_RECORD_TOTAL:
968 case SID_FM_RECORD_SAVE:
969 case SID_FM_RECORD_UNDO:
970 case SID_FM_FORM_FILTERED:
971 case SID_FM_REMOVE_FILTER_SORT:
972 case SID_FM_SORTUP:
973 case SID_FM_SORTDOWN:
974 case SID_FM_ORDERCRIT:
975 case SID_FM_FILTER_START:
976 case SID_FM_AUTOFILTER:
977 case SID_FM_REFRESH:
978 case SID_FM_REFRESH_FORM_CONTROL:
979 case SID_FM_VIEW_AS_GRID:
980 GetFormState(rSet,nWhich);
981 break;
983 case SID_FM_CHANGECONTROLTYPE:
985 if ( !m_pFormView || !m_bDesignMode )
986 rSet.DisableItem( nWhich );
987 else
989 if (!GetImpl()->canConvertCurrentSelectionToControl_Lock(u"ConvertToFixed"))
990 // if it cannot be converted to a fixed text, it is no single control
991 rSet.DisableItem( nWhich );
993 } break;
995 case SID_FM_CONVERTTO_FILECONTROL :
996 case SID_FM_CONVERTTO_CURRENCY :
997 case SID_FM_CONVERTTO_PATTERN :
998 case SID_FM_CONVERTTO_IMAGECONTROL :
999 case SID_FM_CONVERTTO_SCROLLBAR :
1000 case SID_FM_CONVERTTO_NAVIGATIONBAR :
1001 case SID_FM_CONVERTTO_IMAGEBUTTON :
1002 case SID_FM_CONVERTTO_EDIT :
1003 case SID_FM_CONVERTTO_BUTTON :
1004 case SID_FM_CONVERTTO_FIXEDTEXT :
1005 case SID_FM_CONVERTTO_LISTBOX :
1006 case SID_FM_CONVERTTO_CHECKBOX :
1007 case SID_FM_CONVERTTO_RADIOBUTTON :
1008 case SID_FM_CONVERTTO_GROUPBOX :
1009 case SID_FM_CONVERTTO_COMBOBOX :
1010 case SID_FM_CONVERTTO_DATE :
1011 case SID_FM_CONVERTTO_TIME :
1012 case SID_FM_CONVERTTO_NUMERIC :
1013 case SID_FM_CONVERTTO_FORMATTED :
1014 case SID_FM_CONVERTTO_SPINBUTTON :
1016 if (!m_pFormView || !m_bDesignMode || !GetImpl()->canConvertCurrentSelectionToControl_Lock(FmXFormShell::SlotToIdent(nWhich)))
1017 rSet.DisableItem( nWhich );
1018 else
1020 rSet.Put( SfxBoolItem( nWhich, false ) );
1021 // just to have a defined state (available and not checked)
1024 break;
1026 nWhich = aIter.NextWhich();
1031 void FmFormShell::GetFormState(SfxItemSet &rSet, sal_uInt16 nWhich)
1033 if ( !GetImpl()->getNavController_Lock().is()
1034 || !isRowSetAlive(GetImpl()->getNavController_Lock()->getModel())
1035 || !m_pFormView
1036 || m_bDesignMode
1037 || !GetImpl()->getActiveForm_Lock().is()
1038 || GetImpl()->isInFilterMode_Lock()
1040 rSet.DisableItem(nWhich);
1041 else
1043 bool bEnable = false;
1046 switch (nWhich)
1048 case SID_FM_VIEW_AS_GRID:
1049 if (GetImpl()->getHostFrame_Lock().is() && GetImpl()->getNavController_Lock().is())
1051 bEnable = true;
1052 bool bDisplayingCurrent =
1053 GetImpl()->getInternalForm_Lock(
1054 Reference<XForm>(GetImpl()->getNavController_Lock()->getModel(), UNO_QUERY)
1055 ) == GetImpl()->getExternallyDisplayedForm_Lock();
1056 rSet.Put(SfxBoolItem(nWhich, bDisplayingCurrent));
1058 break;
1060 case SID_FM_SEARCH:
1062 Reference<css::beans::XPropertySet> const xNavSet(GetImpl()->getActiveForm_Lock(), UNO_QUERY);
1063 sal_Int32 nCount = ::comphelper::getINT32(xNavSet->getPropertyValue(FM_PROP_ROWCOUNT));
1064 bEnable = nCount != 0;
1065 } break;
1066 case SID_FM_RECORD_ABSOLUTE:
1067 case SID_FM_RECORD_TOTAL:
1069 FeatureState aState;
1070 GetImpl()->getNavControllerFeatures_Lock()->getState( nWhich, aState );
1071 if ( SID_FM_RECORD_ABSOLUTE == nWhich )
1073 sal_Int32 nPosition = 0;
1074 aState.State >>= nPosition;
1075 rSet.Put( SfxInt32Item( SID_FM_RECORD_ABSOLUTE, nPosition ) );
1077 else if ( SID_FM_RECORD_TOTAL == nWhich )
1079 OUString sTotalCount;
1080 aState.State >>= sTotalCount;
1081 rSet.Put( SfxStringItem( nWhich, sTotalCount ) );
1083 bEnable = aState.Enabled;
1085 break;
1087 // first, prev, next, last, and absolute affect the nav controller, not the
1088 // active controller
1089 case SID_FM_RECORD_FIRST:
1090 case SID_FM_RECORD_PREV:
1091 case SID_FM_RECORD_NEXT:
1092 case SID_FM_RECORD_LAST:
1093 case SID_FM_RECORD_NEW:
1094 case SID_FM_RECORD_SAVE:
1095 case SID_FM_RECORD_UNDO:
1096 case SID_FM_RECORD_DELETE:
1097 case SID_FM_REFRESH:
1098 case SID_FM_REFRESH_FORM_CONTROL:
1099 case SID_FM_REMOVE_FILTER_SORT:
1100 case SID_FM_SORTUP:
1101 case SID_FM_SORTDOWN:
1102 case SID_FM_AUTOFILTER:
1103 case SID_FM_ORDERCRIT:
1104 bEnable = GetImpl()->IsFormSlotEnabled( nWhich, nullptr );
1105 break;
1107 case SID_FM_FORM_FILTERED:
1109 FeatureState aState;
1110 bEnable = GetImpl()->IsFormSlotEnabled( nWhich, &aState );
1112 rSet.Put( SfxBoolItem( nWhich, ::comphelper::getBOOL( aState.State ) ) );
1114 break;
1116 case SID_FM_FILTER_START:
1117 bEnable = GetImpl()->getActiveControllerFeatures_Lock()->canDoFormFilter();
1118 break;
1121 catch( const Exception& )
1123 TOOLS_WARN_EXCEPTION("svx.form", "caught an exception while determining the state!");
1125 if (!bEnable)
1126 rSet.DisableItem(nWhich);
1131 FmFormPage* FmFormShell::GetCurPage() const
1133 FmFormPage* pP = nullptr;
1134 if (m_pFormView && m_pFormView->GetSdrPageView())
1135 pP = dynamic_cast<FmFormPage*>( m_pFormView->GetSdrPageView()->GetPage() );
1136 return pP;
1140 void FmFormShell::SetView( FmFormView* _pView )
1142 if ( m_pFormView )
1144 if ( IsActive() )
1145 GetImpl()->viewDeactivated_Lock(*m_pFormView);
1147 m_pFormView->SetFormShell( nullptr, FmFormView::FormShellAccess() );
1148 m_pFormView = nullptr;
1149 m_pFormModel = nullptr;
1152 if ( !_pView )
1153 return;
1155 m_pFormView = _pView;
1156 m_pFormView->SetFormShell( this, FmFormView::FormShellAccess() );
1157 m_pFormModel = static_cast<FmFormModel*>(&m_pFormView->GetModel());
1159 impl_setDesignMode( m_pFormView->IsDesignMode() );
1161 // We activate our view if we are activated ourself, but sometimes the Activate precedes the SetView.
1162 // But here we know both the view and our activation state so we at least are able to pass the latter
1163 // to the former.
1164 // FS - 30.06.99 - 67308
1165 if ( IsActive() )
1166 GetImpl()->viewActivated_Lock(*m_pFormView);
1170 void FmFormShell::DetermineForms(bool bInvalidate)
1172 // are there forms on the current page
1173 bool bForms = GetImpl()->hasForms_Lock();
1174 if (bForms != m_bHasForms)
1176 m_bHasForms = bForms;
1177 if (bInvalidate)
1178 UIFeatureChanged();
1183 bool FmFormShell::GetY2KState(sal_uInt16& nReturn)
1185 return GetImpl()->GetY2KState_Lock(nReturn);
1189 void FmFormShell::SetY2KState(sal_uInt16 n)
1191 GetImpl()->SetY2KState_Lock(n);
1195 void FmFormShell::Activate(bool bMDI)
1197 SfxShell::Activate(bMDI);
1199 if ( m_pFormView )
1200 GetImpl()->viewActivated_Lock(*m_pFormView, true);
1204 void FmFormShell::Deactivate(bool bMDI)
1206 SfxShell::Deactivate(bMDI);
1208 if ( m_pFormView )
1209 GetImpl()->viewDeactivated_Lock(*m_pFormView, false);
1213 void FmFormShell::ExecuteTextAttribute( SfxRequest& _rReq )
1215 m_pImpl->ExecuteTextAttribute_Lock(_rReq);
1219 void FmFormShell::GetTextAttributeState( SfxItemSet& _rSet )
1221 m_pImpl->GetTextAttributeState_Lock(_rSet);
1225 bool FmFormShell::IsActiveControl() const
1227 return m_pImpl->IsActiveControl_Lock(false);
1231 void FmFormShell::ForgetActiveControl()
1233 m_pImpl->ForgetActiveControl_Lock();
1237 void FmFormShell::SetControlActivationHandler( const Link<LinkParamNone*,void>& _rHdl )
1239 m_pImpl->SetControlActivationHandler_Lock(_rHdl);
1243 namespace
1245 SdrUnoObj* lcl_findUnoObject( const SdrObjList& _rObjList, const Reference< XControlModel >& _rxModel )
1247 SdrObjListIter aIter( &_rObjList );
1248 while ( aIter.IsMore() )
1250 SdrObject* pObject = aIter.Next();
1251 SdrUnoObj* pUnoObject = dynamic_cast<SdrUnoObj*>( pObject );
1252 if ( !pUnoObject )
1253 continue;
1255 Reference< XControlModel > xControlModel = pUnoObject->GetUnoControlModel();
1256 if ( !xControlModel.is() )
1257 continue;
1259 if ( _rxModel == xControlModel )
1260 return pUnoObject;
1262 return nullptr;
1267 void FmFormShell::ToggleControlFocus( const SdrUnoObj& i_rUnoObject, const SdrView& i_rView, const OutputDevice& i_rDevice ) const
1271 // check if the focus currently is in a control
1272 // Well, okay, do it the other way 'round: Check whether the current control of the active controller
1273 // actually has the focus. This should be equivalent.
1274 const bool bHasControlFocus = GetImpl()->HasControlFocus_Lock();
1276 if ( bHasControlFocus )
1278 vcl::Window* pWindow = i_rDevice.GetOwnerWindow();
1279 OSL_ENSURE( pWindow, "FmFormShell::ToggleControlFocus: I need a Window, really!" );
1280 if ( pWindow )
1281 pWindow->GrabFocus();
1283 else
1285 Reference< XControl > xControl;
1286 GetFormControl( i_rUnoObject.GetUnoControlModel(), i_rView, i_rDevice, xControl );
1287 Reference< XWindow > xControlWindow( xControl, UNO_QUERY );
1288 if ( xControlWindow.is() )
1289 xControlWindow->setFocus();
1292 catch( const Exception& )
1294 DBG_UNHANDLED_EXCEPTION("svx");
1299 namespace
1301 class FocusableControlsFilter : public svx::ISdrObjectFilter
1303 public:
1304 FocusableControlsFilter( const SdrView& i_rView, const OutputDevice& i_rDevice )
1305 :m_rView( i_rView )
1306 ,m_rDevice( i_rDevice )
1310 public:
1311 virtual bool includeObject( const SdrObject& i_rObject ) const override
1313 const SdrUnoObj* pUnoObj = dynamic_cast< const SdrUnoObj* >( &i_rObject );
1314 if ( !pUnoObj )
1315 return false;
1317 Reference< XControl > xControl = pUnoObj->GetUnoControl( m_rView, m_rDevice );
1318 return FmXFormView::isFocusable( xControl );
1321 private:
1322 const SdrView& m_rView;
1323 const OutputDevice& m_rDevice;
1328 ::std::unique_ptr< svx::ISdrObjectFilter > FmFormShell::CreateFocusableControlFilter( const SdrView& i_rView, const OutputDevice& i_rDevice )
1330 ::std::unique_ptr< svx::ISdrObjectFilter > pFilter;
1332 if ( !i_rView.IsDesignMode() )
1333 pFilter.reset( new FocusableControlsFilter( i_rView, i_rDevice ) );
1335 return pFilter;
1339 SdrUnoObj* FmFormShell::GetFormControl( const Reference< XControlModel >& _rxModel, const SdrView& _rView, const OutputDevice& _rDevice, Reference< XControl >& _out_rxControl ) const
1341 if ( !_rxModel.is() )
1342 return nullptr;
1344 // we can only retrieve controls for SdrObjects which belong to page which is actually displayed in the given view
1345 SdrPageView* pPageView = _rView.GetSdrPageView();
1346 SdrPage* pPage = pPageView ? pPageView->GetPage() : nullptr;
1347 OSL_ENSURE( pPage, "FmFormShell::GetFormControl: no page displayed in the given view!" );
1348 if ( !pPage )
1349 return nullptr;
1351 SdrUnoObj* pUnoObject = lcl_findUnoObject( *pPage, _rxModel );
1352 if ( pUnoObject )
1354 _out_rxControl = pUnoObject->GetUnoControl( _rView, _rDevice );
1355 return pUnoObject;
1358 #if OSL_DEBUG_LEVEL > 0
1359 // perhaps we are fed with a control model which lives on a page other than the one displayed
1360 // in the given view. This is worth being reported as error, in non-product builds.
1361 FmFormModel* pModel = GetFormModel();
1362 if ( pModel )
1364 sal_uInt16 pageCount = pModel->GetPageCount();
1365 for ( sal_uInt16 page = 0; page < pageCount; ++page )
1367 pPage = pModel->GetPage( page );
1368 OSL_ENSURE( pPage, "FmFormShell::GetFormControl: NULL page encountered!" );
1369 if ( !pPage )
1370 continue;
1372 pUnoObject = lcl_findUnoObject( *pPage, _rxModel );
1373 OSL_ENSURE( !pUnoObject, "FmFormShell::GetFormControl: the given control model belongs to a wrong page (displayed elsewhere)!" );
1376 #else
1377 (void) this; // avoid loplugin:staticmethods
1378 #endif
1380 return nullptr;
1384 Reference< runtime::XFormController > FmFormShell::GetFormController( const Reference< XForm >& _rxForm, const SdrView& _rView, const OutputDevice& _rDevice )
1386 const FmFormView* pFormView = dynamic_cast< const FmFormView* >( &_rView );
1387 if ( !pFormView )
1388 return nullptr;
1390 return pFormView->GetFormController( _rxForm, _rDevice );
1394 void FmFormShell::SetDesignMode( bool _bDesignMode )
1396 if ( _bDesignMode == m_bDesignMode )
1397 return;
1399 FmFormModel* pModel = GetFormModel();
1400 if (pModel)
1401 // Switch off the undo environment for the time of the transition. This ensures that
1402 // one can also change non-transient properties there. (It should be done with
1403 // caution, however, and it should always be reversed when one switches the mode back.
1404 // An example is the setting of the maximum text length by the OEditModel on its control.)
1405 pModel->GetUndoEnv().Lock();
1407 // then the actual switch
1408 if ( m_bDesignMode || PrepareClose() )
1409 impl_setDesignMode(!m_bDesignMode );
1411 // and my undo environment back on
1412 if ( pModel )
1413 pModel->GetUndoEnv().UnLock();
1416 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */