Coverage Report

Created: 2026-10-14 09:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svx/source/form/fmshell.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
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/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
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 .
18
 */
19
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/Builder.hxx>
30
#include <vcl/weld/MessageDialog.hxx>
31
#include <svl/whiter.hxx>
32
#include <sfx2/app.hxx>
33
#include <svl/intitem.hxx>
34
#include <svl/stritem.hxx>
35
#include <svl/visitem.hxx>
36
#include <unotools/moduleoptions.hxx>
37
#include <sfx2/objface.hxx>
38
#include <sfx2/toolbarids.hxx>
39
#include <sfx2/request.hxx>
40
#include <sfx2/dispatch.hxx>
41
#include <svx/svdobj.hxx>
42
#include <svx/fmpage.hxx>
43
#include <svx/svditer.hxx>
44
45
#include <svx/svxids.hrc>
46
47
#include <svx/svdobjkind.hxx>
48
#include <svl/eitem.hxx>
49
#include <comphelper/diagnose_ex.hxx>
50
#include <svx/svdpage.hxx>
51
#include <svx/fmmodel.hxx>
52
#include <fmshimp.hxx>
53
#include <svx/svdpagv.hxx>
54
#include <sfx2/objitem.hxx>
55
#include <sfx2/viewsh.hxx>
56
#include <fmexpl.hxx>
57
#include <formcontrolling.hxx>
58
#include <comphelper/types.hxx>
59
#include <fmdocumentclassification.hxx>
60
#include <formtoolbars.hxx>
61
62
#include <svx/svxdlg.hxx>
63
64
#include <svx/sdrobjectfilter.hxx>
65
66
#define ShellClass_FmFormShell
67
#include <svxslots.hxx>
68
69
#include <memory>
70
71
// is used for Invalidate -> maintain it as well
72
// sort ascending !!!!!!
73
sal_uInt16 const ControllerSlotMap[] =    // slots of the controller
74
{
75
    SID_FM_CONFIG,
76
    SID_FM_PUSHBUTTON,
77
    SID_FM_RADIOBUTTON,
78
    SID_FM_CHECKBOX,
79
    SID_FM_FIXEDTEXT,
80
    SID_FM_GROUPBOX,
81
    SID_FM_EDIT,
82
    SID_FM_LISTBOX,
83
    SID_FM_COMBOBOX,
84
    SID_FM_DBGRID,
85
    SID_FM_IMAGEBUTTON,
86
    SID_FM_FILECONTROL,
87
    SID_FM_NAVIGATIONBAR,
88
    SID_FM_CTL_PROPERTIES,
89
    SID_FM_PROPERTIES,
90
    SID_FM_TAB_DIALOG,
91
    SID_FM_ADD_FIELD,
92
    SID_FM_DESIGN_MODE,
93
    SID_FM_SHOW_FMEXPLORER,
94
    SID_FM_SHOW_PROPERTIES,
95
    SID_FM_FMEXPLORER_CONTROL,
96
    SID_FM_DATEFIELD,
97
    SID_FM_TIMEFIELD,
98
    SID_FM_NUMERICFIELD,
99
    SID_FM_CURRENCYFIELD,
100
    SID_FM_PATTERNFIELD,
101
    SID_FM_OPEN_READONLY,
102
    SID_FM_IMAGECONTROL,
103
    SID_FM_USE_WIZARDS,
104
    SID_FM_FORMATTEDFIELD,
105
    SID_FM_FILTER_NAVIGATOR,
106
    SID_FM_AUTOCONTROLFOCUS,
107
    SID_FM_SCROLLBAR,
108
    SID_FM_SPINBUTTON,
109
    SID_FM_SHOW_DATANAVIGATOR,
110
    SID_FM_DATANAVIGATOR_CONTROL,
111
112
    0
113
};
114
115
using namespace ::com::sun::star::uno;
116
using namespace ::com::sun::star::awt;
117
using namespace ::com::sun::star::sdbc;
118
using namespace ::com::sun::star::beans;
119
using namespace ::com::sun::star::form;
120
using namespace ::com::sun::star::form::runtime;
121
using namespace ::svxform;
122
123
FmDesignModeChangedHint::FmDesignModeChangedHint( bool bDesMode )
124
8.87k
    :SfxHint(SfxHintId::FmDesignModeChanged), m_bDesignMode( bDesMode )
125
8.87k
{
126
8.87k
}
127
128
129
FmDesignModeChangedHint::~FmDesignModeChangedHint()
130
8.87k
{
131
8.87k
}
132
133
SFX_IMPL_INTERFACE(FmFormShell, SfxShell)
134
135
void FmFormShell::InitInterface_Impl()
136
23
{
137
23
    GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_NAVIGATION, SfxVisibilityFlags::Standard|SfxVisibilityFlags::ReadonlyDoc,
138
23
                                            ToolbarId::SvxTbx_Form_Navigation,
139
23
                                            SfxShellFeature::FormShowDatabaseBar);
140
141
23
    GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_NAVIGATION, SfxVisibilityFlags::Standard|SfxVisibilityFlags::ReadonlyDoc,
142
23
                                            ToolbarId::SvxTbx_Form_Filter,
143
23
                                            SfxShellFeature::FormShowFilterBar);
144
145
23
    GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Standard | SfxVisibilityFlags::ReadonlyDoc,
146
23
                                            ToolbarId::SvxTbx_Text_Control_Attributes,
147
23
                                            SfxShellFeature::FormShowTextControlBar);
148
149
23
    GetStaticInterface()->RegisterChildWindow(SID_FM_ADD_FIELD, false, SfxShellFeature::FormShowField);
150
23
    GetStaticInterface()->RegisterChildWindow(SID_FM_SHOW_PROPERTIES, false, SfxShellFeature::FormShowProperties);
151
23
    GetStaticInterface()->RegisterChildWindow(SID_FM_SHOW_FMEXPLORER, false, SfxShellFeature::FormShowExplorer);
152
23
    GetStaticInterface()->RegisterChildWindow(SID_FM_FILTER_NAVIGATOR, false, SfxShellFeature::FormShowFilterNavigator);
153
23
    GetStaticInterface()->RegisterChildWindow(SID_FM_SHOW_DATANAVIGATOR, false, SfxShellFeature::FormShowDataNavigator);
154
155
23
    GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Standard,
156
23
                                            ToolbarId::SvxTbx_Controls,
157
23
                                            SfxShellFeature::FormTBControls);
158
159
23
    GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Standard,
160
23
                                            ToolbarId::SvxTbx_FormDesign,
161
23
                                            SfxShellFeature::FormTBDesign);
162
23
}
163
164
165
FmFormShell::FmFormShell( SfxViewShell* _pParent, FmFormView* pView )
166
8.87k
            :SfxShell(_pParent)
167
8.87k
            ,m_pImpl(new FmXFormShell(*this, &_pParent->GetViewFrame()))
168
8.87k
            ,m_pFormView( pView )
169
8.87k
            ,m_pFormModel( nullptr )
170
8.87k
            ,m_nLastSlot( 0 )
171
8.87k
            ,m_bDesignMode( true )
172
8.87k
            ,m_bHasForms(false)
173
8.87k
{
174
8.87k
    SetPool( &SfxGetpApp()->GetPool() );
175
8.87k
    SetName( u"Form"_ustr );
176
177
8.87k
    SetView(m_pFormView);
178
8.87k
}
179
180
181
FmFormShell::~FmFormShell()
182
8.87k
{
183
8.87k
    if ( m_pFormView )
184
8.87k
        SetView( nullptr );
185
186
8.87k
    m_pImpl->dispose();
187
8.87k
}
188
189
190
void FmFormShell::NotifyMarkListChanged(FmFormView* pWhichView)
191
0
{
192
0
    FmNavViewMarksChanged aChangeNotification(pWhichView);
193
0
    Broadcast(aChangeNotification);
194
0
}
195
196
197
bool FmFormShell::PrepareClose(bool bUI)
198
17.7k
{
199
17.7k
    if (GetImpl()->didPrepareClose_Lock())
200
        // we already made a PrepareClose for the current modifications of the current form
201
0
        return true;
202
203
17.7k
    bool bResult = true;
204
    // Save the data records, not in DesignMode and FilterMode
205
17.7k
    if (!m_bDesignMode && !GetImpl()->isInFilterMode_Lock() &&
206
64
        m_pFormView && m_pFormView->GetActualOutDev() &&
207
0
        m_pFormView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW)
208
0
    {
209
0
        SdrPageView* pCurPageView = m_pFormView->GetSdrPageView();
210
211
        // sal_uInt16 nPos = pCurPageView ? pCurPageView->GetWinList().Find((OutputDevice*)m_pFormView->GetActualOutDev()) : SDRPAGEVIEWWIN_NOTFOUND;
212
0
        SdrPageWindow* pWindow = pCurPageView ? pCurPageView->FindPageWindow(*const_cast<OutputDevice*>(m_pFormView->GetActualOutDev())) : nullptr;
213
214
0
        if(pWindow)
215
0
        {
216
            // First, the current contents of the controls are stored.
217
            // If everything has gone smoothly, the modified records are stored.
218
0
            if (GetImpl()->getActiveController_Lock().is())
219
0
            {
220
0
                const svx::ControllerFeatures& rController = GetImpl()->getActiveControllerFeatures_Lock();
221
0
                if ( rController->commitCurrentControl() )
222
0
                {
223
0
                    const bool bModified = rController->isModifiedRow();
224
225
0
                    if ( bModified && bUI )
226
0
                    {
227
0
                        SfxViewShell* pShell = GetViewShell();
228
0
                        vcl::Window* pShellWnd = pShell ? pShell->GetWindow() : nullptr;
229
0
                        weld::Widget* pFrameWeld = pShellWnd ? pShellWnd->GetFrameWeld() : nullptr;
230
0
                        std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pFrameWeld, u"svx/ui/savemodifieddialog.ui"_ustr));
231
0
                        std::unique_ptr<weld::MessageDialog> xQry(xBuilder->weld_message_dialog(u"SaveModifiedDialog"_ustr));
232
0
                        switch (xQry->run())
233
0
                        {
234
0
                            case RET_YES:
235
0
                                bResult = rController->commitCurrentRecord( );
236
0
                                [[fallthrough]];
237
0
                            case RET_NO:
238
0
                                GetImpl()->didPrepareClose_Lock(true);
239
0
                                break;
240
241
0
                            case RET_CANCEL:
242
0
                                return false;
243
0
                        }
244
0
                    }
245
0
                }
246
0
            }
247
0
        }
248
0
    }
249
17.7k
    return bResult;
250
17.7k
}
251
252
253
void FmFormShell::impl_setDesignMode(bool bDesign)
254
8.87k
{
255
8.87k
    if (m_pFormView)
256
8.87k
    {
257
8.87k
        if (!bDesign)
258
32
            m_nLastSlot = SID_FM_DESIGN_MODE;
259
260
8.87k
        GetImpl()->SetDesignMode_Lock(bDesign);
261
        // my m_bDesignMode is also set by the Impl ...
262
8.87k
    }
263
0
    else
264
0
    {
265
0
        m_bHasForms = false;
266
0
        m_bDesignMode = bDesign;
267
0
        UIFeatureChanged();
268
0
    }
269
270
8.87k
    GetViewShell()->GetViewFrame().GetBindings().Invalidate(ControllerSlotMap);
271
8.87k
}
272
273
bool FmFormShell::HasUIFeature(SfxShellFeature nFeature) const
274
88.7k
{
275
88.7k
    assert((nFeature & ~SfxShellFeature::FormMask) == SfxShellFeature::NONE);
276
88.7k
    bool bResult = false;
277
88.7k
    if (nFeature & SfxShellFeature::FormShowDatabaseBar)
278
8.87k
    {
279
        // only if forms are also available
280
8.87k
        bResult = !m_bDesignMode && GetImpl()->hasDatabaseBar_Lock() && !GetImpl()->isInFilterMode_Lock();
281
8.87k
    }
282
79.9k
    else if (nFeature & SfxShellFeature::FormShowFilterBar)
283
8.87k
    {
284
        // only if forms are also available
285
8.87k
        bResult = !m_bDesignMode && GetImpl()->hasDatabaseBar_Lock() && GetImpl()->isInFilterMode_Lock();
286
8.87k
    }
287
71.0k
    else if (nFeature & SfxShellFeature::FormShowFilterNavigator)
288
8.87k
    {
289
8.87k
        bResult = !m_bDesignMode && GetImpl()->hasDatabaseBar_Lock() && GetImpl()->isInFilterMode_Lock();
290
8.87k
    }
291
62.1k
    else if (nFeature & SfxShellFeature::FormShowField)
292
8.87k
    {
293
8.87k
        bResult = m_bDesignMode && m_pFormView && m_bHasForms;
294
8.87k
    }
295
53.2k
    else if (nFeature & SfxShellFeature::FormShowProperties)
296
8.87k
    {
297
8.87k
        bResult = m_bDesignMode && m_pFormView && m_bHasForms;
298
8.87k
    }
299
44.3k
    else if (nFeature & SfxShellFeature::FormShowExplorer)
300
8.87k
    {
301
8.87k
        bResult = m_bDesignMode; // OJ #101593# && m_pFormView && m_bHasForms;
302
8.87k
    }
303
35.5k
    else if (nFeature & SfxShellFeature::FormShowTextControlBar)
304
8.87k
    {
305
8.87k
        bResult = !GetImpl()->IsReadonlyDoc_Lock() && m_pImpl->IsActiveControl_Lock(true);
306
8.87k
    }
307
26.6k
    else if (nFeature & SfxShellFeature::FormShowDataNavigator)
308
8.87k
    {
309
8.87k
        bResult = GetImpl()->isEnhancedForm_Lock();
310
8.87k
    }
311
17.7k
    else if (  (nFeature & SfxShellFeature::FormTBControls)
312
8.87k
            || (nFeature & SfxShellFeature::FormTBDesign)
313
17.7k
            )
314
17.7k
    {
315
17.7k
        bResult = true;
316
17.7k
    }
317
318
88.7k
    return bResult;
319
88.7k
}
320
321
322
void FmFormShell::Execute(SfxRequest &rReq)
323
0
{
324
0
    sal_uInt16 nSlot = rReq.GetSlot();
325
326
327
    // set MasterSlot
328
0
    switch( nSlot )
329
0
    {
330
0
        case SID_FM_PUSHBUTTON:
331
0
        case SID_FM_RADIOBUTTON:
332
0
        case SID_FM_CHECKBOX:
333
0
        case SID_FM_FIXEDTEXT:
334
0
        case SID_FM_GROUPBOX:
335
0
        case SID_FM_LISTBOX:
336
0
        case SID_FM_COMBOBOX:
337
0
        case SID_FM_NAVIGATIONBAR:
338
0
        case SID_FM_EDIT:
339
0
        case SID_FM_DBGRID:
340
0
        case SID_FM_IMAGEBUTTON:
341
0
        case SID_FM_IMAGECONTROL:
342
0
        case SID_FM_FILECONTROL:
343
0
        case SID_FM_DATEFIELD:
344
0
        case SID_FM_TIMEFIELD:
345
0
        case SID_FM_NUMERICFIELD:
346
0
        case SID_FM_CURRENCYFIELD:
347
0
        case SID_FM_PATTERNFIELD:
348
0
        case SID_FM_FORMATTEDFIELD:
349
0
        case SID_FM_SCROLLBAR:
350
0
        case SID_FM_SPINBUTTON:
351
0
            m_nLastSlot = nSlot;
352
0
            break;
353
0
    }
354
355
356
    // set the Identifier and Inventor of the Uno control
357
0
    SdrObjKind nIdentifier = SdrObjKind::NONE;
358
0
    switch( nSlot )
359
0
    {
360
0
        case SID_FM_CHECKBOX:
361
0
            nIdentifier = SdrObjKind::FormCheckbox;
362
0
            break;
363
0
        case SID_FM_PUSHBUTTON:
364
0
            nIdentifier = SdrObjKind::FormButton;
365
0
            break;
366
0
        case SID_FM_FIXEDTEXT:
367
0
            nIdentifier = SdrObjKind::FormFixedText;
368
0
            break;
369
0
        case SID_FM_LISTBOX:
370
0
            nIdentifier = SdrObjKind::FormListbox;
371
0
            break;
372
0
        case SID_FM_EDIT:
373
0
            nIdentifier = SdrObjKind::FormEdit;
374
0
            break;
375
0
        case SID_FM_RADIOBUTTON:
376
0
            nIdentifier = SdrObjKind::FormRadioButton;
377
0
            break;
378
0
        case SID_FM_GROUPBOX:
379
0
            nIdentifier = SdrObjKind::FormGroupBox;
380
0
            break;
381
0
        case SID_FM_COMBOBOX:
382
0
            nIdentifier = SdrObjKind::FormCombobox;
383
0
            break;
384
0
        case SID_FM_NAVIGATIONBAR:
385
0
            nIdentifier = SdrObjKind::FormNavigationBar;
386
0
            break;
387
0
        case SID_FM_DBGRID:
388
0
            nIdentifier = SdrObjKind::FormGrid;
389
0
            break;
390
0
        case SID_FM_IMAGEBUTTON:
391
0
            nIdentifier = SdrObjKind::FormImageButton;
392
0
            break;
393
0
        case SID_FM_IMAGECONTROL:
394
0
            nIdentifier = SdrObjKind::FormImageControl;
395
0
            break;
396
0
        case SID_FM_FILECONTROL:
397
0
            nIdentifier = SdrObjKind::FormFileControl;
398
0
            break;
399
0
        case SID_FM_DATEFIELD:
400
0
            nIdentifier = SdrObjKind::FormDateField;
401
0
            break;
402
0
        case SID_FM_TIMEFIELD:
403
0
            nIdentifier = SdrObjKind::FormTimeField;
404
0
            break;
405
0
        case SID_FM_NUMERICFIELD:
406
0
            nIdentifier = SdrObjKind::FormNumericField;
407
0
            break;
408
0
        case SID_FM_CURRENCYFIELD:
409
0
            nIdentifier = SdrObjKind::FormCurrencyField;
410
0
            break;
411
0
        case SID_FM_PATTERNFIELD:
412
0
            nIdentifier = SdrObjKind::FormPatternField;
413
0
            break;
414
0
        case SID_FM_FORMATTEDFIELD:
415
0
            nIdentifier = SdrObjKind::FormFormattedField;
416
0
            break;
417
0
        case SID_FM_SCROLLBAR:
418
0
            nIdentifier = SdrObjKind::FormScrollbar;
419
0
            break;
420
0
        case SID_FM_SPINBUTTON:
421
0
            nIdentifier = SdrObjKind::FormSpinButton;
422
0
            break;
423
0
    }
424
425
0
    switch ( nSlot )
426
0
    {
427
0
        case SID_FM_CHECKBOX:
428
0
        case SID_FM_PUSHBUTTON:
429
0
        case SID_FM_FIXEDTEXT:
430
0
        case SID_FM_LISTBOX:
431
0
        case SID_FM_EDIT:
432
0
        case SID_FM_RADIOBUTTON:
433
0
        case SID_FM_COMBOBOX:
434
0
        case SID_FM_NAVIGATIONBAR:
435
0
        case SID_FM_GROUPBOX:
436
0
        case SID_FM_DBGRID:
437
0
        case SID_FM_IMAGEBUTTON:
438
0
        case SID_FM_IMAGECONTROL:
439
0
        case SID_FM_FILECONTROL:
440
0
        case SID_FM_DATEFIELD:
441
0
        case SID_FM_TIMEFIELD:
442
0
        case SID_FM_NUMERICFIELD:
443
0
        case SID_FM_CURRENCYFIELD:
444
0
        case SID_FM_PATTERNFIELD:
445
0
        case SID_FM_FORMATTEDFIELD:
446
0
        case SID_FM_SCROLLBAR:
447
0
        case SID_FM_SPINBUTTON:
448
0
        {
449
0
            const SfxBoolItem* pGrabFocusItem = rReq.GetArg(SID_FM_TOGGLECONTROLFOCUS);
450
0
            if ( pGrabFocusItem && pGrabFocusItem->GetValue() )
451
0
            {   // see below
452
0
                SfxViewShell* pShell = GetViewShell();
453
0
                vcl::Window* pShellWnd = pShell ? pShell->GetWindow() : nullptr;
454
0
                if ( pShellWnd )
455
0
                    pShellWnd->GrabFocus();
456
0
                break;
457
0
            }
458
459
0
            SfxUInt16Item aIdentifierItem( SID_FM_CONTROL_IDENTIFIER, static_cast<sal_uInt16>(nIdentifier) );
460
0
            SfxUInt32Item aInventorItem( SID_FM_CONTROL_INVENTOR, sal_uInt32(SdrInventor::FmForm) );
461
0
            const SfxPoolItem* pArgs[] =
462
0
            {
463
0
                &aIdentifierItem, &aInventorItem, nullptr
464
0
            };
465
0
            const SfxPoolItem* pInternalArgs[] =
466
0
            {
467
0
                nullptr
468
0
            };
469
470
0
            GetViewShell()->GetViewFrame().GetDispatcher()->Execute( SID_FM_CREATE_CONTROL, SfxCallMode::ASYNCHRON,
471
0
                                      pArgs, rReq.GetModifier(), pInternalArgs );
472
473
0
            if ( rReq.GetModifier() & KEY_MOD1 )
474
0
            {
475
                //  #99013# if selected with control key, return focus to current view
476
                // do this asynchronously, 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
0
                SfxBoolItem aGrabFocusIndicatorItem( SID_FM_TOGGLECONTROLFOCUS, true );
480
0
                GetViewShell()->GetViewFrame().GetDispatcher()->ExecuteList(
481
0
                        nSlot, SfxCallMode::ASYNCHRON,
482
0
                        { &aGrabFocusIndicatorItem });
483
0
            }
484
485
0
            rReq.Done();
486
0
        }   break;
487
0
    }
488
489
    // individual actions
490
0
    switch( nSlot )
491
0
    {
492
0
        case SID_FM_FORM_DESIGN_TOOLS:
493
0
        {
494
0
            FormToolboxes aToolboxAccess(GetImpl()->getHostFrame_Lock());
495
0
            aToolboxAccess.toggleToolbox( nSlot );
496
0
            rReq.Done();
497
0
        }
498
0
        break;
499
500
0
        case SID_FM_TOGGLECONTROLFOCUS:
501
0
        {
502
0
            FmFormView* pFormView = GetFormView();
503
0
            if ( !pFormView )
504
0
                break;
505
506
            // if we execute this ourself, then either the application does not implement an own handling for this,
507
            // or 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
0
            const bool bHasControlFocus = GetImpl()->HasControlFocus_Lock();
510
0
            if ( bHasControlFocus )
511
0
            {
512
0
                if (m_pFormView)
513
0
                {
514
0
                    const OutputDevice* pDevice = m_pFormView->GetActualOutDev();
515
0
                    vcl::Window* pWindow = pDevice->GetOwnerWindow();
516
0
                    if ( pWindow )
517
0
                        pWindow->GrabFocus();
518
0
                }
519
0
            }
520
0
            else
521
0
            {
522
0
                pFormView->GrabFirstControlFocus( );
523
0
            }
524
0
        }
525
0
        break;
526
527
0
        case SID_FM_VIEW_AS_GRID:
528
0
            GetImpl()->CreateExternalView_Lock();
529
0
            break;
530
0
        case SID_FM_CONVERTTO_EDIT          :
531
0
        case SID_FM_CONVERTTO_BUTTON            :
532
0
        case SID_FM_CONVERTTO_FIXEDTEXT     :
533
0
        case SID_FM_CONVERTTO_LISTBOX       :
534
0
        case SID_FM_CONVERTTO_CHECKBOX      :
535
0
        case SID_FM_CONVERTTO_RADIOBUTTON   :
536
0
        case SID_FM_CONVERTTO_GROUPBOX      :
537
0
        case SID_FM_CONVERTTO_COMBOBOX      :
538
0
        case SID_FM_CONVERTTO_IMAGEBUTTON   :
539
0
        case SID_FM_CONVERTTO_FILECONTROL   :
540
0
        case SID_FM_CONVERTTO_DATE          :
541
0
        case SID_FM_CONVERTTO_TIME          :
542
0
        case SID_FM_CONVERTTO_NUMERIC       :
543
0
        case SID_FM_CONVERTTO_CURRENCY      :
544
0
        case SID_FM_CONVERTTO_PATTERN       :
545
0
        case SID_FM_CONVERTTO_IMAGECONTROL  :
546
0
        case SID_FM_CONVERTTO_FORMATTED     :
547
0
        case SID_FM_CONVERTTO_SCROLLBAR     :
548
0
        case SID_FM_CONVERTTO_SPINBUTTON    :
549
0
        case SID_FM_CONVERTTO_NAVIGATIONBAR :
550
0
            GetImpl()->executeControlConversionSlot_Lock(FmXFormShell::SlotToIdent(nSlot));
551
            // after the conversion, re-determine the selection, since the
552
            // selected object has changed
553
0
            GetImpl()->SetSelection_Lock(GetFormView()->GetMarkedObjectList());
554
0
            break;
555
0
        case SID_FM_LEAVE_CREATE:
556
0
            m_nLastSlot = 0;
557
0
            rReq.Done();
558
0
            break;
559
0
        case SID_FM_SHOW_PROPERTY_BROWSER:
560
0
        {
561
0
            const SfxBoolItem* pShowItem = rReq.GetArg(SID_FM_SHOW_PROPERTIES);
562
0
            bool bShow = true;
563
0
            if ( pShowItem )
564
0
                bShow = pShowItem->GetValue();
565
0
            GetImpl()->ShowSelectionProperties_Lock(bShow);
566
567
0
            rReq.Done();
568
0
        } break;
569
570
0
        case SID_FM_PROPERTIES:
571
0
        {
572
            // display the PropertyBrowser
573
0
            const SfxBoolItem* pShowItem = rReq.GetArg<SfxBoolItem>(nSlot);
574
0
            bool bShow = pShowItem == nullptr || pShowItem->GetValue();
575
576
0
            InterfaceBag aOnlyTheForm;
577
0
            aOnlyTheForm.insert(Reference<XInterface>(GetImpl()->getCurrentForm_Lock(), UNO_QUERY));
578
0
            GetImpl()->setCurrentSelection_Lock(std::move(aOnlyTheForm));
579
580
0
            GetImpl()->ShowSelectionProperties_Lock(bShow);
581
582
0
            rReq.Done();
583
0
        }   break;
584
585
0
        case SID_FM_CTL_PROPERTIES:
586
0
        {
587
0
            const SfxBoolItem* pShowItem = rReq.GetArg<SfxBoolItem>(nSlot);
588
0
            bool bShow = pShowItem == nullptr || pShowItem->GetValue();
589
590
0
            OSL_ENSURE( GetImpl()->onlyControlsAreMarked_Lock(), "FmFormShell::Execute: ControlProperties should be disabled!" );
591
0
            if ( bShow )
592
0
                GetImpl()->selectLastMarkedControls_Lock();
593
0
            GetImpl()->ShowSelectionProperties_Lock(bShow);
594
595
0
            rReq.Done();
596
0
        }   break;
597
0
        case SID_FM_SHOW_PROPERTIES:
598
0
        case SID_FM_ADD_FIELD:
599
0
        case SID_FM_FILTER_NAVIGATOR:
600
0
        case SID_FM_SHOW_DATANAVIGATOR :
601
0
        {
602
            // request may explicitly request to show/hide these
603
            // so may or may not result in a ToggleChildWindow
604
0
            GetViewShell()->GetViewFrame().ChildWindowExecute(rReq);
605
0
            rReq.Done();
606
0
        }   break;
607
0
        case SID_FM_SHOW_FMEXPLORER:
608
0
        {
609
0
            if (!m_pFormView)   // force setting the view
610
0
                GetViewShell()->GetViewFrame().GetDispatcher()->Execute(SID_CREATE_SW_DRAWVIEW);
611
612
0
            GetViewShell()->GetViewFrame().ChildWindowExecute(rReq);
613
0
            rReq.Done();
614
0
        }
615
0
        break;
616
617
0
        case SID_FM_TAB_DIALOG:
618
0
        {
619
0
            GetImpl()->ExecuteTabOrderDialog_Lock(
620
0
                Reference<XTabControllerModel>(GetImpl()->getCurrentForm_Lock(), UNO_QUERY));
621
0
            rReq.Done();
622
0
        }
623
0
        break;
624
625
0
        case SID_FM_DESIGN_MODE:
626
0
        {
627
0
            const SfxBoolItem* pDesignItem = rReq.GetArg<SfxBoolItem>(nSlot);
628
0
            bool bDesignMode = pDesignItem ? pDesignItem->GetValue() : !m_bDesignMode;
629
0
            SetDesignMode( bDesignMode );
630
0
            if ( m_bDesignMode == bDesignMode )
631
0
                rReq.Done();
632
633
0
            m_nLastSlot = SID_FM_DESIGN_MODE;
634
0
        }
635
0
        break;
636
637
0
        case SID_FM_AUTOCONTROLFOCUS:
638
0
        {
639
0
            FmFormModel* pModel = GetFormModel();
640
0
            DBG_ASSERT(pModel, "FmFormShell::Execute : invalid call !");
641
                // should have been disabled in GetState if we don't have a FormModel
642
0
            pModel->SetAutoControlFocus( !pModel->GetAutoControlFocus() );
643
0
            GetViewShell()->GetViewFrame().GetBindings().Invalidate(SID_FM_AUTOCONTROLFOCUS);
644
0
        }
645
0
        break;
646
0
        case SID_FM_OPEN_READONLY:
647
0
        {
648
0
            FmFormModel* pModel = GetFormModel();
649
0
            DBG_ASSERT(pModel, "FmFormShell::Execute : invalid call !");
650
                // should have been disabled in GetState if we don't have a FormModel
651
0
            pModel->SetOpenInDesignMode( !pModel->GetOpenInDesignMode() );
652
0
            GetViewShell()->GetViewFrame().GetBindings().Invalidate(SID_FM_OPEN_READONLY);
653
0
        }
654
0
        break;
655
0
        case SID_FM_USE_WIZARDS:
656
0
        {
657
0
            GetImpl()->SetWizardUsing_Lock(!GetImpl()->GetWizardUsing_Lock());
658
0
            GetViewShell()->GetViewFrame().GetBindings().Invalidate(SID_FM_USE_WIZARDS);
659
0
        }
660
0
        break;
661
0
        case SID_FM_SEARCH:
662
0
        {
663
0
            const svx::ControllerFeatures& rController = GetImpl()->getActiveControllerFeatures_Lock();
664
0
            if ( rController->commitCurrentControl() && rController->commitCurrentRecord() )
665
0
                GetImpl()->ExecuteSearch_Lock();
666
0
            rReq.Done();
667
0
        }
668
0
        break;
669
670
0
        case SID_FM_RECORD_FIRST:
671
0
        case SID_FM_RECORD_PREV:
672
0
        case SID_FM_RECORD_NEXT:
673
0
        case SID_FM_RECORD_LAST:
674
0
        case SID_FM_RECORD_NEW:
675
0
        case SID_FM_REFRESH:
676
0
        case SID_FM_REFRESH_FORM_CONTROL:
677
0
        case SID_FM_RECORD_DELETE:
678
0
        case SID_FM_RECORD_UNDO:
679
0
        case SID_FM_RECORD_SAVE:
680
0
        case SID_FM_REMOVE_FILTER_SORT:
681
0
        case SID_FM_SORTDOWN:
682
0
        case SID_FM_SORTUP:
683
0
        case SID_FM_AUTOFILTER:
684
0
        case SID_FM_ORDERCRIT:
685
0
        case SID_FM_FORM_FILTERED:
686
0
        {
687
0
            GetImpl()->ExecuteFormSlot_Lock(nSlot);
688
0
            rReq.Done();
689
0
        }
690
0
        break;
691
692
0
        case SID_FM_RECORD_ABSOLUTE:
693
0
        {
694
0
            const svx::ControllerFeatures& rController = GetImpl()->getNavControllerFeatures_Lock();
695
0
            sal_Int32 nRecord = -1;
696
697
0
            const SfxItemSet* pArgs = rReq.GetArgs();
698
0
            if ( pArgs )
699
0
            {
700
0
                const SfxPoolItem* pItem;
701
0
                if ( ( pArgs->GetItemState( FN_PARAM_1, true, &pItem ) ) == SfxItemState::SET )
702
0
                {
703
0
                    const SfxInt32Item* pTypedItem = dynamic_cast<const SfxInt32Item* >( pItem );
704
0
                    if ( pTypedItem )
705
0
                        nRecord = std::max( pTypedItem->GetValue(), sal_Int32(0) );
706
0
                }
707
0
            }
708
0
            else
709
0
            {
710
0
                SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
711
0
                ScopedVclPtr<AbstractFmInputRecordNoDialog> dlg(pFact->CreateFmInputRecordNoDialog(rReq.GetFrameWeld()));
712
0
                dlg->SetValue( rController->getCursor()->getRow() );
713
0
                if ( dlg->Execute() == RET_OK )
714
0
                    nRecord = dlg->GetValue();
715
716
0
                rReq.AppendItem( SfxInt32Item( TypedWhichId<SfxInt32Item>(FN_PARAM_1), nRecord ) );
717
0
            }
718
719
0
            if ( nRecord != -1 )
720
0
                rController->execute( nSlot, u"Position"_ustr, Any( nRecord ) );
721
722
0
            rReq.Done();
723
0
        }   break;
724
0
        case SID_FM_FILTER_EXECUTE:
725
0
        case SID_FM_FILTER_EXIT:
726
0
        {
727
0
            bool bCancelled = ( SID_FM_FILTER_EXIT == nSlot );
728
0
            bool bReopenNavigator = false;
729
730
0
            if ( !bCancelled )
731
0
            {
732
                // if the filter navigator is still open, we need to close it, so it can possibly
733
                // commit its most recent changes
734
0
                if (GetViewShell())
735
0
                    if ( GetViewShell()->GetViewFrame().HasChildWindow( SID_FM_FILTER_NAVIGATOR ) )
736
0
                    {
737
0
                        GetViewShell()->GetViewFrame().ToggleChildWindow( SID_FM_FILTER_NAVIGATOR );
738
0
                        bReopenNavigator = true;
739
0
                    }
740
741
0
                Reference<runtime::XFormController> const xController(GetImpl()->getActiveController_Lock());
742
743
0
                if  (   GetViewShell()->GetViewFrame().HasChildWindow( SID_FM_FILTER_NAVIGATOR )
744
                        // closing the window was denied, for instance because of an invalid criterion
745
746
0
                    ||  (   xController.is()
747
0
                        &&  !GetImpl()->getActiveControllerFeatures_Lock()->commitCurrentControl()
748
0
                        )
749
                        // committing the controller was denied
750
0
                    )
751
0
                {
752
0
                    rReq.Done();
753
0
                    break;
754
0
                }
755
0
            }
756
757
0
            GetImpl()->stopFiltering_Lock(!bCancelled);
758
0
            rReq.Done();
759
760
0
            if ( bReopenNavigator )
761
                // we closed the navigator only to implicitly commit it (as we do not have another
762
                // direct wire to it), but to the user, it should look as it was always open
763
0
                GetViewShell()->GetViewFrame().ToggleChildWindow( SID_FM_FILTER_NAVIGATOR );
764
0
        }
765
0
        break;
766
767
0
        case SID_FM_FILTER_START:
768
0
        {
769
0
            GetImpl()->startFiltering_Lock();
770
0
            rReq.Done();
771
772
            // initially open the filter navigator, the whole form based filter is pretty useless without it
773
0
            SfxBoolItem aIdentifierItem( SID_FM_FILTER_NAVIGATOR, true );
774
0
            GetViewShell()->GetViewFrame().GetDispatcher()->ExecuteList(
775
0
                    SID_FM_FILTER_NAVIGATOR, SfxCallMode::ASYNCHRON,
776
0
                    { &aIdentifierItem });
777
0
        }   break;
778
0
    }
779
0
}
780
781
782
void FmFormShell::GetState(SfxItemSet &rSet)
783
0
{
784
0
    SfxWhichIter aIter( rSet );
785
0
    sal_uInt16 nWhich = aIter.FirstWhich();
786
0
    while ( nWhich )
787
0
    {
788
0
        switch( nWhich )
789
0
        {
790
0
            case SID_FM_FORM_DESIGN_TOOLS:
791
0
            {
792
0
                FormToolboxes aToolboxAccess(GetImpl()->getHostFrame_Lock());
793
0
                rSet.Put( SfxBoolItem( nWhich, aToolboxAccess.isToolboxVisible( nWhich ) ) );
794
0
            }
795
0
            break;
796
797
0
            case SID_FM_FILTER_EXECUTE:
798
0
            case SID_FM_FILTER_EXIT:
799
0
                if (!GetImpl()->isInFilterMode_Lock())
800
0
                    rSet.DisableItem( nWhich );
801
0
                break;
802
803
0
            case SID_FM_USE_WIZARDS:
804
0
                if (!SvtModuleOptions().IsDataBaseInstalled())
805
0
                    rSet.Put( SfxVisibilityItem( nWhich, false ) );
806
0
                else if (!GetFormModel())
807
0
                    rSet.DisableItem( nWhich );
808
0
                else
809
0
                    rSet.Put(SfxBoolItem(nWhich, GetImpl()->GetWizardUsing_Lock()));
810
0
                break;
811
0
            case SID_FM_AUTOCONTROLFOCUS:
812
0
                if (!GetFormModel())
813
0
                    rSet.DisableItem( nWhich );
814
0
                else
815
0
                    rSet.Put( SfxBoolItem(nWhich, GetFormModel()->GetAutoControlFocus() ) );
816
0
                break;
817
0
            case SID_FM_OPEN_READONLY:
818
0
                if (!GetFormModel())
819
0
                    rSet.DisableItem( nWhich );
820
0
                else
821
0
                    rSet.Put( SfxBoolItem(nWhich, GetFormModel()->GetOpenInDesignMode() ) );
822
0
                break;
823
824
0
            case SID_FM_NAVIGATIONBAR:
825
0
            case SID_FM_DBGRID:
826
0
                if (!SvtModuleOptions().IsDataBaseInstalled())
827
0
                {
828
0
                    rSet.Put( SfxVisibilityItem( nWhich, false ) );
829
0
                    break;
830
0
                }
831
0
                [[fallthrough]];
832
833
0
            case SID_FM_SCROLLBAR:
834
0
            case SID_FM_IMAGECONTROL:
835
0
            case SID_FM_FILECONTROL:
836
0
            case SID_FM_CURRENCYFIELD:
837
0
            case SID_FM_PATTERNFIELD:
838
0
            case SID_FM_IMAGEBUTTON:
839
0
            case SID_FM_RADIOBUTTON:
840
0
            case SID_FM_COMBOBOX:
841
0
            case SID_FM_GROUPBOX:
842
0
            case SID_FM_CHECKBOX:
843
0
            case SID_FM_PUSHBUTTON:
844
0
            case SID_FM_FIXEDTEXT:
845
0
            case SID_FM_LISTBOX:
846
0
            case SID_FM_EDIT:
847
0
            case SID_FM_DATEFIELD:
848
0
            case SID_FM_TIMEFIELD:
849
0
            case SID_FM_NUMERICFIELD:
850
0
            case SID_FM_FORMATTEDFIELD:
851
0
            case SID_FM_SPINBUTTON:
852
0
                if (!m_bDesignMode)
853
0
                    rSet.DisableItem( nWhich );
854
0
                else
855
0
                {
856
0
                    bool bLayerLocked = false;
857
0
                    if (m_pFormView)
858
0
                    {
859
                        // If the css::drawing::Layer is locked, the slots must be disabled. #36897
860
0
                        SdrPageView* pPV = m_pFormView->GetSdrPageView();
861
0
                        if (pPV != nullptr)
862
0
                            bLayerLocked = pPV->IsLayerLocked(m_pFormView->GetActiveLayer());
863
0
                    }
864
0
                    if (bLayerLocked)
865
0
                        rSet.DisableItem( nWhich );
866
0
                    else
867
0
                        rSet.Put( SfxBoolItem(nWhich, (nWhich==m_nLastSlot)) );
868
0
                }
869
0
                break;
870
0
            case SID_FM_FILTER_NAVIGATOR_CONTROL:
871
0
            {
872
0
                if (GetImpl()->isInFilterMode_Lock())
873
0
                    rSet.Put(SfxObjectItem(nWhich, this));
874
0
                else
875
0
                    rSet.Put(SfxObjectItem(nWhich));
876
0
            }   break;
877
0
            case SID_FM_FIELDS_CONTROL:
878
0
            case SID_FM_PROPERTY_CONTROL:
879
0
            {
880
0
                if (!m_bDesignMode || !m_pFormView || !m_bHasForms)
881
0
                    rSet.Put(SfxObjectItem(nWhich));
882
0
                else
883
0
                    rSet.Put(SfxObjectItem(nWhich, this));
884
885
0
            }   break;
886
0
            case SID_FM_FMEXPLORER_CONTROL:
887
0
            case SID_FM_DATANAVIGATOR_CONTROL :
888
0
            {
889
0
                if (!m_bDesignMode || !m_pFormView)
890
0
                    rSet.Put(SfxObjectItem(nWhich));
891
0
                else
892
0
                    rSet.Put(SfxObjectItem(nWhich, this));
893
894
0
            }   break;
895
0
            case SID_FM_ADD_FIELD:
896
0
            case SID_FM_SHOW_FMEXPLORER:
897
0
            case SID_FM_SHOW_PROPERTIES:
898
0
            case SID_FM_FILTER_NAVIGATOR:
899
0
            case SID_FM_SHOW_DATANAVIGATOR:
900
0
            {
901
0
                if ( GetViewShell()->GetViewFrame().KnowsChildWindow(nWhich) )
902
0
                    rSet.Put( SfxBoolItem( nWhich, GetViewShell()->GetViewFrame().HasChildWindow(nWhich)) );
903
0
                else
904
0
                    rSet.DisableItem(nWhich);
905
0
            }   break;
906
907
0
            case SID_FM_SHOW_PROPERTY_BROWSER:
908
0
            {
909
0
                rSet.Put(SfxBoolItem(nWhich, GetImpl()->IsPropBrwOpen_Lock()));
910
0
            }
911
0
            break;
912
913
0
            case SID_FM_CTL_PROPERTIES:
914
0
            {
915
                // potentially, give the Impl the opportunity to update its
916
                // current objects which are aligned with the current MarkList
917
0
                if (GetImpl()->IsSelectionUpdatePending_Lock())
918
0
                    GetImpl()->ForceUpdateSelection_Lock();
919
920
0
                if (!m_pFormView || !m_bDesignMode || !GetImpl()->onlyControlsAreMarked_Lock())
921
0
                    rSet.DisableItem( nWhich );
922
0
                else
923
0
                {
924
0
                    bool const bChecked = GetImpl()->IsPropBrwOpen_Lock() && !GetImpl()->isSolelySelected_Lock(GetImpl()->getCurrentForm_Lock());
925
                        // if the property browser is open, and only controls are marked, and the current selection
926
                        // does not consist of only the current form, then the current selection is the (composition of)
927
                        // the currently marked controls
928
0
                    rSet.Put( SfxBoolItem( nWhich, bChecked ) );
929
0
                }
930
0
            }   break;
931
932
0
            case SID_FM_PROPERTIES:
933
0
            {
934
                // potentially, give the Impl the opportunity to update its
935
                // current objects which are aligned with the current MarkList
936
0
                if (GetImpl()->IsSelectionUpdatePending_Lock())
937
0
                    GetImpl()->ForceUpdateSelection_Lock();
938
939
0
                if (!m_pFormView || !m_bDesignMode || !GetImpl()->getCurrentForm_Lock().is())
940
0
                    rSet.DisableItem( nWhich );
941
0
                else
942
0
                {
943
0
                    bool const bChecked = GetImpl()->IsPropBrwOpen_Lock() && GetImpl()->isSolelySelected_Lock(GetImpl()->getCurrentForm_Lock());
944
0
                    rSet.Put(SfxBoolItem(nWhich, bChecked));
945
0
                }
946
0
            }   break;
947
0
            case SID_FM_TAB_DIALOG:
948
                // potentially, give the Impl the opportunity to update its
949
                // current objects which are aligned with the current MarkList
950
0
                if (GetImpl()->IsSelectionUpdatePending_Lock())
951
0
                    GetImpl()->ForceUpdateSelection_Lock();
952
953
0
                if (!m_pFormView || !m_bDesignMode || !GetImpl()->getCurrentForm_Lock().is() )
954
0
                    rSet.DisableItem( nWhich );
955
0
                break;
956
0
            case SID_FM_DESIGN_MODE:
957
0
                if (!m_pFormView || GetImpl()->IsReadonlyDoc_Lock())
958
0
                    rSet.DisableItem( nWhich );
959
0
                else
960
0
                    rSet.Put( SfxBoolItem(nWhich, m_bDesignMode) );
961
0
                break;
962
0
            case SID_FM_SEARCH:
963
0
            case SID_FM_RECORD_FIRST:
964
0
            case SID_FM_RECORD_NEXT:
965
0
            case SID_FM_RECORD_PREV:
966
0
            case SID_FM_RECORD_LAST:
967
0
            case SID_FM_RECORD_NEW:
968
0
            case SID_FM_RECORD_DELETE:
969
0
            case SID_FM_RECORD_ABSOLUTE:
970
0
            case SID_FM_RECORD_TOTAL:
971
0
            case SID_FM_RECORD_SAVE:
972
0
            case SID_FM_RECORD_UNDO:
973
0
            case SID_FM_FORM_FILTERED:
974
0
            case SID_FM_REMOVE_FILTER_SORT:
975
0
            case SID_FM_SORTUP:
976
0
            case SID_FM_SORTDOWN:
977
0
            case SID_FM_ORDERCRIT:
978
0
            case SID_FM_FILTER_START:
979
0
            case SID_FM_AUTOFILTER:
980
0
            case SID_FM_REFRESH:
981
0
            case SID_FM_REFRESH_FORM_CONTROL:
982
0
            case SID_FM_VIEW_AS_GRID:
983
0
                GetFormState(rSet,nWhich);
984
0
                break;
985
986
0
            case SID_FM_CHANGECONTROLTYPE:
987
0
            {
988
0
                if ( !m_pFormView || !m_bDesignMode )
989
0
                    rSet.DisableItem( nWhich );
990
0
                else
991
0
                {
992
0
                    if (!GetImpl()->canConvertCurrentSelectionToControl_Lock(u"ConvertToFixed"))
993
                        // if it cannot be converted to a fixed text, it is no single control
994
0
                        rSet.DisableItem( nWhich );
995
0
                }
996
0
            } break;
997
998
0
            case SID_FM_CONVERTTO_FILECONTROL   :
999
0
            case SID_FM_CONVERTTO_CURRENCY      :
1000
0
            case SID_FM_CONVERTTO_PATTERN       :
1001
0
            case SID_FM_CONVERTTO_IMAGECONTROL  :
1002
0
            case SID_FM_CONVERTTO_SCROLLBAR     :
1003
0
            case SID_FM_CONVERTTO_NAVIGATIONBAR :
1004
0
            case SID_FM_CONVERTTO_IMAGEBUTTON   :
1005
0
            case SID_FM_CONVERTTO_EDIT          :
1006
0
            case SID_FM_CONVERTTO_BUTTON        :
1007
0
            case SID_FM_CONVERTTO_FIXEDTEXT     :
1008
0
            case SID_FM_CONVERTTO_LISTBOX       :
1009
0
            case SID_FM_CONVERTTO_CHECKBOX      :
1010
0
            case SID_FM_CONVERTTO_RADIOBUTTON   :
1011
0
            case SID_FM_CONVERTTO_GROUPBOX      :
1012
0
            case SID_FM_CONVERTTO_COMBOBOX      :
1013
0
            case SID_FM_CONVERTTO_DATE          :
1014
0
            case SID_FM_CONVERTTO_TIME          :
1015
0
            case SID_FM_CONVERTTO_NUMERIC       :
1016
0
            case SID_FM_CONVERTTO_FORMATTED     :
1017
0
            case SID_FM_CONVERTTO_SPINBUTTON    :
1018
0
            {
1019
0
                if (!m_pFormView || !m_bDesignMode || !GetImpl()->canConvertCurrentSelectionToControl_Lock(FmXFormShell::SlotToIdent(nWhich)))
1020
0
                    rSet.DisableItem( nWhich );
1021
0
                else
1022
0
                {
1023
0
                    rSet.Put( SfxBoolItem( nWhich, false ) );
1024
                    // just to have a defined state (available and not checked)
1025
0
                }
1026
0
            }
1027
0
            break;
1028
0
        }
1029
0
        nWhich = aIter.NextWhich();
1030
0
    }
1031
0
}
1032
1033
1034
void FmFormShell::GetFormState(SfxItemSet &rSet, sal_uInt16 nWhich)
1035
0
{
1036
0
    if  (   !GetImpl()->getNavController_Lock().is()
1037
0
        ||  !isRowSetAlive(GetImpl()->getNavController_Lock()->getModel())
1038
0
        ||  !m_pFormView
1039
0
        ||  m_bDesignMode
1040
0
        ||  !GetImpl()->getActiveForm_Lock().is()
1041
0
        ||  GetImpl()->isInFilterMode_Lock()
1042
0
        )
1043
0
        rSet.DisableItem(nWhich);
1044
0
    else
1045
0
    {
1046
0
        bool bEnable = false;
1047
0
        try
1048
0
        {
1049
0
            switch (nWhich)
1050
0
            {
1051
0
            case SID_FM_VIEW_AS_GRID:
1052
0
                if (GetImpl()->getHostFrame_Lock().is() && GetImpl()->getNavController_Lock().is())
1053
0
                {
1054
0
                    bEnable = true;
1055
0
                    bool bDisplayingCurrent =
1056
0
                        GetImpl()->getInternalForm_Lock(
1057
0
                            Reference<XForm>(GetImpl()->getNavController_Lock()->getModel(), UNO_QUERY)
1058
0
                        ) == GetImpl()->getExternallyDisplayedForm_Lock();
1059
0
                    rSet.Put(SfxBoolItem(nWhich, bDisplayingCurrent));
1060
0
                }
1061
0
                break;
1062
1063
0
            case SID_FM_SEARCH:
1064
0
            {
1065
0
                Reference<css::beans::XPropertySet> const xNavSet(GetImpl()->getActiveForm_Lock(), UNO_QUERY);
1066
0
                sal_Int32 nCount = ::comphelper::getINT32(xNavSet->getPropertyValue(FM_PROP_ROWCOUNT));
1067
0
                bEnable = nCount != 0;
1068
0
            }   break;
1069
0
            case SID_FM_RECORD_ABSOLUTE:
1070
0
            case SID_FM_RECORD_TOTAL:
1071
0
            {
1072
0
                FeatureState aState;
1073
0
                GetImpl()->getNavControllerFeatures_Lock()->getState( nWhich, aState );
1074
0
                if ( SID_FM_RECORD_ABSOLUTE == nWhich )
1075
0
                {
1076
0
                    sal_Int32 nPosition = 0;
1077
0
                    aState.State >>= nPosition;
1078
0
                    rSet.Put( SfxInt32Item( SID_FM_RECORD_ABSOLUTE, nPosition ) );
1079
0
                }
1080
0
                else if ( SID_FM_RECORD_TOTAL == nWhich )
1081
0
                {
1082
0
                    OUString sTotalCount;
1083
0
                    aState.State >>= sTotalCount;
1084
0
                    rSet.Put( SfxStringItem( nWhich, sTotalCount ) );
1085
0
                }
1086
0
                bEnable = aState.Enabled;
1087
0
            }
1088
0
            break;
1089
1090
            // first, prev, next, last, and absolute affect the nav controller, not the
1091
            // active controller
1092
0
            case SID_FM_RECORD_FIRST:
1093
0
            case SID_FM_RECORD_PREV:
1094
0
            case SID_FM_RECORD_NEXT:
1095
0
            case SID_FM_RECORD_LAST:
1096
0
            case SID_FM_RECORD_NEW:
1097
0
            case SID_FM_RECORD_SAVE:
1098
0
            case SID_FM_RECORD_UNDO:
1099
0
            case SID_FM_RECORD_DELETE:
1100
0
            case SID_FM_REFRESH:
1101
0
            case SID_FM_REFRESH_FORM_CONTROL:
1102
0
            case SID_FM_REMOVE_FILTER_SORT:
1103
0
            case SID_FM_SORTUP:
1104
0
            case SID_FM_SORTDOWN:
1105
0
            case SID_FM_AUTOFILTER:
1106
0
            case SID_FM_ORDERCRIT:
1107
0
                bEnable = GetImpl()->IsFormSlotEnabled( nWhich, nullptr );
1108
0
                break;
1109
1110
0
            case SID_FM_FORM_FILTERED:
1111
0
            {
1112
0
                FeatureState aState;
1113
0
                bEnable = GetImpl()->IsFormSlotEnabled( nWhich, &aState );
1114
1115
0
                rSet.Put( SfxBoolItem( nWhich, ::comphelper::getBOOL( aState.State ) ) );
1116
0
            }
1117
0
            break;
1118
1119
0
            case SID_FM_FILTER_START:
1120
0
                bEnable = GetImpl()->getActiveControllerFeatures_Lock()->canDoFormFilter();
1121
0
                break;
1122
0
            }
1123
0
        }
1124
0
        catch( const Exception& )
1125
0
        {
1126
0
            TOOLS_WARN_EXCEPTION("svx.form", "caught an exception while determining the state!");
1127
0
        }
1128
0
        if (!bEnable)
1129
0
            rSet.DisableItem(nWhich);
1130
0
    }
1131
0
}
1132
1133
1134
FmFormPage* FmFormShell::GetCurPage() const
1135
35.4k
{
1136
35.4k
    FmFormPage* pP = nullptr;
1137
35.4k
    if (m_pFormView && m_pFormView->GetSdrPageView())
1138
35.4k
        pP = dynamic_cast<FmFormPage*>( m_pFormView->GetSdrPageView()->GetPage() );
1139
35.4k
    return pP;
1140
35.4k
}
1141
1142
1143
void FmFormShell::SetView( FmFormView* _pView )
1144
26.6k
{
1145
26.6k
    if ( m_pFormView )
1146
8.87k
    {
1147
8.87k
        if ( IsActive() )
1148
0
            GetImpl()->viewDeactivated_Lock(*m_pFormView);
1149
1150
8.87k
        m_pFormView->SetFormShell( nullptr, FmFormView::FormShellAccess() );
1151
8.87k
        m_pFormView = nullptr;
1152
8.87k
        m_pFormModel = nullptr;
1153
8.87k
    }
1154
1155
26.6k
    if ( !_pView )
1156
17.7k
        return;
1157
1158
8.87k
    m_pFormView = _pView;
1159
8.87k
    m_pFormView->SetFormShell( this, FmFormView::FormShellAccess() );
1160
8.87k
    m_pFormModel = static_cast<FmFormModel*>(&m_pFormView->GetModel());
1161
1162
8.87k
    impl_setDesignMode( m_pFormView->IsDesignMode() );
1163
1164
    // We activate our view if we are activated ourself, but sometimes the Activate precedes the SetView.
1165
    // But here we know both the view and our activation state so we at least are able to pass the latter
1166
    // to the former.
1167
    // FS - 30.06.99 - 67308
1168
8.87k
    if ( IsActive() )
1169
8.87k
        GetImpl()->viewActivated_Lock(*m_pFormView);
1170
8.87k
}
1171
1172
1173
void FmFormShell::DetermineForms(bool bInvalidate)
1174
26.6k
{
1175
    // are there forms on the current page
1176
26.6k
    bool bForms = GetImpl()->hasForms_Lock();
1177
26.6k
    if (bForms != m_bHasForms)
1178
0
    {
1179
0
        m_bHasForms = bForms;
1180
0
        if (bInvalidate)
1181
0
            UIFeatureChanged();
1182
0
    }
1183
26.6k
}
1184
1185
1186
bool FmFormShell::GetY2KState(sal_uInt16& nReturn)
1187
0
{
1188
0
    return GetImpl()->GetY2KState_Lock(nReturn);
1189
0
}
1190
1191
1192
void FmFormShell::SetY2KState(sal_uInt16 n)
1193
0
{
1194
0
    GetImpl()->SetY2KState_Lock(n);
1195
0
}
1196
1197
1198
void FmFormShell::Activate(bool bMDI)
1199
8.87k
{
1200
8.87k
    SfxShell::Activate(bMDI);
1201
1202
8.87k
    if ( m_pFormView )
1203
2
        GetImpl()->viewActivated_Lock(*m_pFormView, true);
1204
8.87k
}
1205
1206
1207
void FmFormShell::Deactivate(bool bMDI)
1208
8.87k
{
1209
8.87k
    SfxShell::Deactivate(bMDI);
1210
1211
8.87k
    if ( m_pFormView )
1212
8.87k
        GetImpl()->viewDeactivated_Lock(*m_pFormView, false);
1213
8.87k
}
1214
1215
1216
void FmFormShell::ExecuteTextAttribute( SfxRequest& _rReq )
1217
0
{
1218
0
    m_pImpl->ExecuteTextAttribute_Lock(_rReq);
1219
0
}
1220
1221
1222
void FmFormShell::GetTextAttributeState( SfxItemSet& _rSet )
1223
0
{
1224
0
    m_pImpl->GetTextAttributeState_Lock(_rSet);
1225
0
}
1226
1227
1228
bool FmFormShell::IsActiveControl() const
1229
25.3k
{
1230
25.3k
    return m_pImpl->IsActiveControl_Lock(false);
1231
25.3k
}
1232
1233
1234
void FmFormShell::ForgetActiveControl()
1235
0
{
1236
0
    m_pImpl->ForgetActiveControl_Lock();
1237
0
}
1238
1239
1240
void FmFormShell::SetControlActivationHandler( const Link<LinkParamNone*,void>& _rHdl )
1241
8.87k
{
1242
8.87k
    m_pImpl->SetControlActivationHandler_Lock(_rHdl);
1243
8.87k
}
1244
1245
1246
namespace
1247
{
1248
    SdrUnoObj* lcl_findUnoObject( const SdrObjList& _rObjList, const Reference< XControlModel >& _rxModel )
1249
0
    {
1250
0
        SdrObjListIter aIter( &_rObjList );
1251
0
        while ( aIter.IsMore() )
1252
0
        {
1253
0
            SdrObject* pObject = aIter.Next();
1254
0
            SdrUnoObj* pUnoObject = dynamic_cast<SdrUnoObj*>( pObject  );
1255
0
            if ( !pUnoObject )
1256
0
                continue;
1257
1258
0
            Reference< XControlModel > xControlModel = pUnoObject->GetUnoControlModel();
1259
0
            if ( !xControlModel.is() )
1260
0
                continue;
1261
1262
0
            if ( _rxModel == xControlModel )
1263
0
                return pUnoObject;
1264
0
        }
1265
0
        return nullptr;
1266
0
    }
1267
}
1268
1269
1270
void FmFormShell::ToggleControlFocus( const SdrUnoObj& i_rUnoObject, const SdrView& i_rView, const OutputDevice& i_rDevice ) const
1271
0
{
1272
0
    try
1273
0
    {
1274
        // check if the focus currently is in a control
1275
        // Well, okay, do it the other way 'round: Check whether the current control of the active controller
1276
        // actually has the focus. This should be equivalent.
1277
0
        const bool bHasControlFocus = GetImpl()->HasControlFocus_Lock();
1278
1279
0
        if ( bHasControlFocus )
1280
0
        {
1281
0
            vcl::Window* pWindow = i_rDevice.GetOwnerWindow();
1282
0
            OSL_ENSURE( pWindow, "FmFormShell::ToggleControlFocus: I need a Window, really!" );
1283
0
            if ( pWindow )
1284
0
                pWindow->GrabFocus();
1285
0
        }
1286
0
        else
1287
0
        {
1288
0
            Reference< XControl > xControl;
1289
0
            GetFormControl( i_rUnoObject.GetUnoControlModel(), i_rView, i_rDevice, xControl );
1290
0
            Reference< XWindow > xControlWindow( xControl, UNO_QUERY );
1291
0
            if ( xControlWindow.is() )
1292
0
                xControlWindow->setFocus();
1293
0
        }
1294
0
    }
1295
0
    catch( const Exception& )
1296
0
    {
1297
0
        DBG_UNHANDLED_EXCEPTION("svx");
1298
0
    }
1299
0
}
1300
1301
1302
namespace
1303
{
1304
    class FocusableControlsFilter : public svx::ISdrObjectFilter
1305
    {
1306
    public:
1307
        FocusableControlsFilter( const SdrView& i_rView, const OutputDevice& i_rDevice )
1308
0
            :m_rView( i_rView )
1309
0
            ,m_rDevice( i_rDevice )
1310
0
        {
1311
0
        }
1312
1313
    public:
1314
        virtual bool    includeObject( const SdrObject& i_rObject ) const override
1315
0
        {
1316
0
            const SdrUnoObj* pUnoObj = dynamic_cast< const SdrUnoObj* >( &i_rObject );
1317
0
            if ( !pUnoObj )
1318
0
                return false;
1319
1320
0
            Reference< XControl > xControl = pUnoObj->GetUnoControl( m_rView, m_rDevice );
1321
0
            return FmXFormView::isFocusable( xControl );
1322
0
        }
1323
1324
    private:
1325
        const SdrView&      m_rView;
1326
        const OutputDevice& m_rDevice;
1327
    };
1328
}
1329
1330
1331
::std::unique_ptr< svx::ISdrObjectFilter > FmFormShell::CreateFocusableControlFilter( const SdrView& i_rView, const OutputDevice& i_rDevice )
1332
0
{
1333
0
    ::std::unique_ptr< svx::ISdrObjectFilter > pFilter;
1334
1335
0
    if ( !i_rView.IsDesignMode() )
1336
0
        pFilter.reset( new FocusableControlsFilter( i_rView, i_rDevice ) );
1337
1338
0
    return pFilter;
1339
0
}
1340
1341
1342
SdrUnoObj* FmFormShell::GetFormControl( const Reference< XControlModel >& _rxModel, const SdrView& _rView, const OutputDevice& _rDevice, Reference< XControl >& _out_rxControl ) const
1343
0
{
1344
0
    if ( !_rxModel.is() )
1345
0
        return nullptr;
1346
1347
    // we can only retrieve controls for SdrObjects which belong to a page which is actually displayed in the given view
1348
0
    SdrPageView* pPageView = _rView.GetSdrPageView();
1349
0
    SdrPage* pPage = pPageView ? pPageView->GetPage() : nullptr;
1350
0
    OSL_ENSURE( pPage, "FmFormShell::GetFormControl: no page displayed in the given view!" );
1351
0
    if ( !pPage )
1352
0
        return nullptr;
1353
1354
0
    SdrUnoObj* pUnoObject = lcl_findUnoObject( *pPage, _rxModel );
1355
0
    if ( pUnoObject )
1356
0
    {
1357
0
        _out_rxControl = pUnoObject->GetUnoControl( _rView, _rDevice );
1358
0
        return pUnoObject;
1359
0
    }
1360
1361
#if OSL_DEBUG_LEVEL > 0
1362
    // perhaps we are fed with a control model which lives on a page other than the one displayed
1363
    // in the given view. This is worth being reported as error, in non-product builds.
1364
    FmFormModel* pModel = GetFormModel();
1365
    if ( pModel )
1366
    {
1367
        sal_uInt16 pageCount = pModel->GetPageCount();
1368
        for ( sal_uInt16 page = 0; page < pageCount; ++page )
1369
        {
1370
            pPage = pModel->GetPage( page );
1371
            OSL_ENSURE( pPage, "FmFormShell::GetFormControl: NULL page encountered!" );
1372
            if  ( !pPage )
1373
                continue;
1374
1375
            pUnoObject = lcl_findUnoObject( *pPage, _rxModel );
1376
            OSL_ENSURE( !pUnoObject, "FmFormShell::GetFormControl: the given control model belongs to a wrong page (displayed elsewhere)!" );
1377
        }
1378
    }
1379
#else
1380
0
    (void) this; // avoid loplugin:staticmethods
1381
0
#endif
1382
1383
0
    return nullptr;
1384
0
}
1385
1386
1387
Reference< runtime::XFormController > FmFormShell::GetFormController( const Reference< XForm >& _rxForm, const SdrView& _rView, const OutputDevice& _rDevice )
1388
0
{
1389
0
    const FmFormView* pFormView = dynamic_cast< const FmFormView* >( &_rView );
1390
0
    if ( !pFormView )
1391
0
        return nullptr;
1392
1393
0
    return pFormView->GetFormController( _rxForm, _rDevice );
1394
0
}
1395
1396
1397
void FmFormShell::SetDesignMode( bool _bDesignMode )
1398
0
{
1399
0
    if ( _bDesignMode == m_bDesignMode )
1400
0
        return;
1401
1402
0
    FmFormModel* pModel = GetFormModel();
1403
0
    if (pModel)
1404
        // Switch off the undo environment for the time of the transition. This ensures that
1405
        // one can also change non-transient properties there. (It should be done with
1406
        // caution, however, and it should always be reversed when one switches the mode back.
1407
        // An example is the setting of the maximum text length by the OEditModel on its control.)
1408
0
        pModel->GetUndoEnv().Lock();
1409
1410
    // then the actual switch
1411
0
    if ( m_bDesignMode || PrepareClose() )
1412
0
        impl_setDesignMode(!m_bDesignMode );
1413
1414
    // and my undo environment back on
1415
0
    if ( pModel )
1416
0
        pModel->GetUndoEnv().UnLock();
1417
0
}
1418
1419
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */