Coverage Report

Created: 2025-12-08 09:28

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