Coverage Report

Created: 2026-06-30 11:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svx/source/form/fmexpl.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
21
#include <svx/strings.hrc>
22
#include <fmexpl.hxx>
23
24
#include <helpids.h>
25
#include <svx/svdobjkind.hxx>
26
#include <svx/fmtools.hxx>
27
#include <fmexch.hxx>
28
29
#include <svx/svxids.hrc>
30
31
#include <fmprop.hxx>
32
#include <bitmaps.hlst>
33
#include <svx/dialmgr.hxx>
34
#include <com/sun/star/beans/XPropertySet.hpp>
35
#include <com/sun/star/lang/XServiceInfo.hpp>
36
#include <sfx2/chalign.hxx>
37
#include <sfx2/objitem.hxx>
38
#include <vcl/weld/Builder.hxx>
39
40
#include <svx/fmshell.hxx>
41
#include <comphelper/types.hxx>
42
#include <utility>
43
44
using namespace ::svxform;
45
using namespace ::com::sun::star::uno;
46
using namespace ::com::sun::star::form;
47
using namespace ::com::sun::star::beans;
48
using namespace ::com::sun::star::lang;
49
using namespace ::com::sun::star::container;
50
51
FmNavInsertedHint::FmNavInsertedHint( FmEntryData* pInsertedEntryData, sal_uInt32 nRelPos )
52
0
    :SfxHint(SfxHintId::FmNavInserted)
53
0
    ,pEntryData( pInsertedEntryData )
54
0
    ,nPos( nRelPos )
55
56
0
{
57
0
}
58
59
60
FmNavInsertedHint::~FmNavInsertedHint()
61
0
{
62
0
}
63
64
65
66
FmNavModelReplacedHint::FmNavModelReplacedHint( FmEntryData* pAffectedEntryData )
67
0
    :SfxHint(SfxHintId::FmNavModelReplaced), pEntryData( pAffectedEntryData )
68
0
{
69
0
}
70
71
72
FmNavModelReplacedHint::~FmNavModelReplacedHint()
73
0
{
74
0
}
75
76
FmNavRemovedHint::FmNavRemovedHint( FmEntryData* pRemovedEntryData )
77
0
    :SfxHint(SfxHintId::FmNavRemoved), pEntryData( pRemovedEntryData )
78
0
{
79
0
}
80
81
82
FmNavRemovedHint::~FmNavRemovedHint()
83
0
{
84
0
}
85
86
FmNavNameChangedHint::FmNavNameChangedHint( FmEntryData* pData, OUString _aNewName )
87
0
    :SfxHint(SfxHintId::FmNavNameChanged), pEntryData( pData )
88
0
    ,aNewName(std::move( _aNewName ))
89
0
{
90
0
}
91
92
93
FmNavNameChangedHint::~FmNavNameChangedHint()
94
0
{
95
0
}
96
97
0
FmNavClearedHint::FmNavClearedHint() : SfxHint(SfxHintId::FmNavCleared)
98
0
{
99
0
}
100
101
102
FmNavClearedHint::~FmNavClearedHint()
103
0
{
104
0
}
105
106
107
FmEntryDataList::FmEntryDataList()
108
0
{
109
0
}
110
111
112
FmEntryDataList::~FmEntryDataList()
113
0
{
114
0
}
115
116
117
void FmEntryDataList::removeNoDelete( FmEntryData* pItem )
118
0
{
119
0
    auto it = std::find_if(maEntryDataList.begin(), maEntryDataList.end(),
120
0
        [&pItem](const std::unique_ptr<FmEntryData>& rEntryData) { return rEntryData.get() == pItem; });
121
0
    if (it != maEntryDataList.end())
122
0
    {
123
        // coverity[leaked_storage] - deliberately not deleted, ownership transferred
124
0
        it->release();
125
0
        maEntryDataList.erase( it );
126
0
        return;
127
0
    }
128
0
    assert(false);
129
0
}
130
131
132
void FmEntryDataList::insert( std::unique_ptr<FmEntryData> pItem, size_t Index )
133
0
{
134
0
    if ( Index < maEntryDataList.size() )
135
0
    {
136
0
        maEntryDataList.insert( maEntryDataList.begin() + Index, std::move(pItem) );
137
0
    }
138
0
    else
139
0
        maEntryDataList.push_back( std::move(pItem) );
140
0
}
141
142
143
void FmEntryDataList::clear()
144
0
{
145
0
    maEntryDataList.clear();
146
0
}
147
148
149
FmEntryData::FmEntryData( FmEntryData* pParentData, const Reference< XInterface >& _rxIFace )
150
0
    :pParent( pParentData )
151
0
{
152
0
    pChildList.reset( new FmEntryDataList() );
153
154
0
    newObject( _rxIFace );
155
0
}
156
157
158
FmEntryData::~FmEntryData()
159
0
{
160
0
    pChildList->clear();
161
0
}
162
163
164
void FmEntryData::newObject( const css::uno::Reference< css::uno::XInterface >& _rxIFace )
165
0
{
166
    // do not just copy, normalize it
167
0
    m_xNormalizedIFace.set( _rxIFace, UNO_QUERY );
168
0
    m_xProperties.set(m_xNormalizedIFace, css::uno::UNO_QUERY);
169
0
    m_xChild.set(m_xNormalizedIFace, css::uno::UNO_QUERY);
170
0
}
171
172
173
174
175
176
bool FmEntryData::IsEqualWithoutChildren( FmEntryData* pEntryData )
177
0
{
178
0
    if(this == pEntryData)
179
0
        return true;
180
181
0
    if( !pEntryData )
182
0
        return false;
183
184
0
    if( aText != pEntryData->GetText() )
185
0
        return false;
186
187
0
    if( !pEntryData->GetParent() && pParent )
188
0
        return false;
189
190
0
    if( pEntryData->GetParent() && !pParent )
191
0
        return false;
192
193
0
    if( !pEntryData->GetParent() && !pParent )
194
0
        return true;
195
196
0
    if( !pParent->IsEqualWithoutChildren(pEntryData->GetParent()) )
197
0
        return false;
198
199
0
    return true;
200
0
}
201
202
FmFormData::FmFormData(const Reference< XForm >& _rxForm, FmFormData* _pParent)
203
0
    : FmEntryData(_pParent, _rxForm)
204
0
    , m_xForm(_rxForm)
205
0
{
206
    // set images
207
0
    m_aNormalImage = RID_SVXBMP_FORM;
208
209
    // set title
210
0
    if (m_xForm.is())
211
0
    {
212
0
        Reference< XPropertySet >  xSet(m_xForm, UNO_QUERY);
213
0
        if (xSet.is())
214
0
        {
215
0
            OUString aEntryName(::comphelper::getString(xSet->getPropertyValue( FM_PROP_NAME )));
216
0
            SetText(aEntryName);
217
0
        }
218
0
    }
219
0
    else
220
0
        SetText( OUString() );
221
0
}
222
223
FmFormData::~FmFormData()
224
0
{
225
0
}
226
227
bool FmFormData::IsEqualWithoutChildren( FmEntryData* pEntryData )
228
0
{
229
0
    if(this == pEntryData)
230
0
        return true;
231
0
    FmFormData* pFormData = dynamic_cast<FmFormData*>(pEntryData);
232
0
    if( !pFormData )
233
0
        return false;
234
0
    if( m_xForm.get() != pFormData->GetFormIface().get() )
235
0
        return false;
236
237
0
    return FmEntryData::IsEqualWithoutChildren( pFormData );
238
0
}
239
240
FmControlData::FmControlData(const Reference< XFormComponent >& _rxComponent, FmFormData* _pParent)
241
0
:   FmEntryData( _pParent, _rxComponent ),
242
0
    m_xFormComponent( _rxComponent )
243
0
{
244
245
    // set images
246
0
    m_aNormalImage = GetImage();
247
248
249
    // set title
250
0
    Reference< XPropertySet >  xSet(m_xFormComponent, UNO_QUERY);
251
0
    if( xSet.is() )
252
0
    {
253
0
        SetText( ::comphelper::getString(xSet->getPropertyValue( FM_PROP_NAME )));
254
0
    }
255
0
}
256
257
258
FmControlData::~FmControlData()
259
0
{
260
0
}
261
262
263
OUString FmControlData::GetImage() const
264
0
{
265
    // Default-Image
266
0
    OUString aImage(RID_SVXBMP_CONTROL);
267
268
0
    Reference< XServiceInfo > xInfo( m_xFormComponent, UNO_QUERY );
269
0
    if (!m_xFormComponent.is())
270
0
        return aImage;
271
272
273
    // Spezielle Control-Images
274
0
    SdrObjKind nObjectType = getControlTypeByObject(xInfo);
275
0
    switch (nObjectType)
276
0
    {
277
0
    case SdrObjKind::FormButton:
278
0
        aImage = RID_SVXBMP_BUTTON;
279
0
        break;
280
281
0
    case SdrObjKind::FormFixedText:
282
0
        aImage = RID_SVXBMP_FIXEDTEXT;
283
0
        break;
284
285
0
    case SdrObjKind::FormEdit:
286
0
        aImage = RID_SVXBMP_EDITBOX;
287
0
        break;
288
289
0
    case SdrObjKind::FormRadioButton:
290
0
        aImage = RID_SVXBMP_RADIOBUTTON;
291
0
        break;
292
293
0
    case SdrObjKind::FormCheckbox:
294
0
        aImage = RID_SVXBMP_CHECKBOX;
295
0
        break;
296
297
0
    case SdrObjKind::FormListbox:
298
0
        aImage = RID_SVXBMP_LISTBOX;
299
0
        break;
300
301
0
    case SdrObjKind::FormCombobox:
302
0
        aImage = RID_SVXBMP_COMBOBOX;
303
0
        break;
304
305
0
    case SdrObjKind::FormNavigationBar:
306
0
        aImage = RID_SVXBMP_NAVIGATIONBAR;
307
0
        break;
308
309
0
    case SdrObjKind::FormGroupBox:
310
0
        aImage = RID_SVXBMP_GROUPBOX;
311
0
        break;
312
313
0
    case SdrObjKind::FormImageButton:
314
0
        aImage = RID_SVXBMP_IMAGEBUTTON;
315
0
        break;
316
317
0
    case SdrObjKind::FormFileControl:
318
0
        aImage = RID_SVXBMP_FILECONTROL;
319
0
        break;
320
321
0
    case SdrObjKind::FormHidden:
322
0
        aImage = RID_SVXBMP_HIDDEN;
323
0
        break;
324
325
0
    case SdrObjKind::FormDateField:
326
0
        aImage = RID_SVXBMP_DATEFIELD;
327
0
        break;
328
329
0
    case SdrObjKind::FormTimeField:
330
0
        aImage = RID_SVXBMP_TIMEFIELD;
331
0
        break;
332
333
0
    case SdrObjKind::FormNumericField:
334
0
        aImage = RID_SVXBMP_NUMERICFIELD;
335
0
        break;
336
337
0
    case SdrObjKind::FormCurrencyField:
338
0
        aImage = RID_SVXBMP_CURRENCYFIELD;
339
0
        break;
340
341
0
    case SdrObjKind::FormPatternField:
342
0
        aImage = RID_SVXBMP_PATTERNFIELD;
343
0
        break;
344
345
0
    case SdrObjKind::FormImageControl:
346
0
        aImage = RID_SVXBMP_IMAGECONTROL;
347
0
        break;
348
349
0
    case SdrObjKind::FormFormattedField:
350
0
        aImage = RID_SVXBMP_FORMATTEDFIELD;
351
0
        break;
352
353
0
    case SdrObjKind::FormGrid:
354
0
        aImage = RID_SVXBMP_GRID;
355
0
        break;
356
357
0
    case SdrObjKind::FormScrollbar:
358
0
        aImage = RID_SVXBMP_SCROLLBAR;
359
0
        break;
360
361
0
    case SdrObjKind::FormSpinButton:
362
0
        aImage = RID_SVXBMP_SPINBUTTON;
363
0
        break;
364
365
0
    default:;
366
0
    }
367
368
0
    return aImage;
369
0
}
370
371
bool FmControlData::IsEqualWithoutChildren( FmEntryData* pEntryData )
372
0
{
373
0
    if(this == pEntryData)
374
0
        return true;
375
376
0
    FmControlData* pControlData = dynamic_cast<FmControlData*>(pEntryData);
377
0
    if( !pControlData )
378
0
        return false;
379
380
0
    if( m_xFormComponent.get() != pControlData->GetFormComponent().get() )
381
0
        return false;
382
383
0
    return FmEntryData::IsEqualWithoutChildren( pControlData );
384
0
}
385
386
void FmControlData::ModelReplaced(const Reference< XFormComponent >& _rxNew)
387
0
{
388
0
    m_xFormComponent = _rxNew;
389
0
    newObject( m_xFormComponent );
390
    // set images anew
391
0
    m_aNormalImage = GetImage();
392
0
}
393
394
namespace svxform
395
{
396
397
    NavigatorFrame::NavigatorFrame( SfxBindings* _pBindings, SfxChildWindow* _pMgr,
398
                                  vcl::Window* _pParent )
399
0
      : SfxDockingWindow(_pBindings, _pMgr, _pParent, u"FormNavigator"_ustr, u"svx/ui/formnavigator.ui"_ustr)
400
0
      , SfxControllerItem( SID_FM_FMEXPLORER_CONTROL, *_pBindings )
401
0
      , m_xNavigatorTree(new NavigatorTree(m_xBuilder->weld_tree_view(u"treeview"_ustr)))
402
0
    {
403
0
        SetHelpId( HID_FORM_NAVIGATOR_WIN );
404
405
0
        SetText( SvxResId(RID_STR_FMEXPLORER) );
406
0
        SfxDockingWindow::SetFloatingSize( Size(200,200) );
407
0
    }
Unexecuted instantiation: svxform::NavigatorFrame::NavigatorFrame(SfxBindings*, SfxChildWindow*, vcl::Window*)
Unexecuted instantiation: svxform::NavigatorFrame::NavigatorFrame(SfxBindings*, SfxChildWindow*, vcl::Window*)
408
409
    NavigatorFrame::~NavigatorFrame()
410
0
    {
411
0
        disposeOnce();
412
0
    }
413
414
    void NavigatorFrame::dispose()
415
0
    {
416
0
        m_xNavigatorTree.reset();
417
0
        ::SfxControllerItem::dispose();
418
0
        SfxDockingWindow::dispose();
419
0
    }
420
421
    void NavigatorFrame::UpdateContent( FmFormShell* pFormShell )
422
0
    {
423
0
        m_xNavigatorTree->UpdateContent(pFormShell);
424
0
    }
425
426
    void NavigatorFrame::StateChangedAtToolBoxControl( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState )
427
0
    {
428
0
        if( !pState  || SID_FM_FMEXPLORER_CONTROL != nSID )
429
0
            return;
430
431
0
        if( eState >= SfxItemState::DEFAULT )
432
0
        {
433
0
            FmFormShell* pShell = dynamic_cast<FmFormShell*>( static_cast<const SfxObjectItem*>(pState)->GetShell()  );
434
0
            UpdateContent( pShell );
435
0
        }
436
0
        else
437
0
            UpdateContent( nullptr );
438
0
    }
439
440
    void NavigatorFrame::GetFocus()
441
0
    {
442
0
        if (m_xNavigatorTree )
443
0
            m_xNavigatorTree->GrabFocus();
444
0
        else
445
0
            SfxDockingWindow::GetFocus();
446
0
    }
447
448
    bool NavigatorFrame::Close()
449
0
    {
450
0
        UpdateContent( nullptr );
451
0
        return SfxDockingWindow::Close();
452
0
    }
453
454
    void NavigatorFrame::FillInfo( SfxChildWinInfo& rInfo ) const
455
0
    {
456
0
        SfxDockingWindow::FillInfo( rInfo );
457
0
        rInfo.bVisible = false;
458
0
    }
459
460
    Size NavigatorFrame::CalcDockingSize( SfxChildAlignment eAlign )
461
0
    {
462
0
        if ( ( eAlign == SfxChildAlignment::TOP ) || ( eAlign == SfxChildAlignment::BOTTOM ) )
463
0
            return Size();
464
465
0
        return SfxDockingWindow::CalcDockingSize( eAlign );
466
0
    }
467
468
    SfxChildAlignment NavigatorFrame::CheckAlignment( SfxChildAlignment _eActAlign, SfxChildAlignment _eAlign )
469
0
    {
470
0
        if ( ( _eAlign == SfxChildAlignment::LEFT ) || ( _eAlign == SfxChildAlignment::RIGHT ) || ( _eAlign == SfxChildAlignment::NOALIGNMENT ) )
471
0
            return _eAlign;
472
0
        return _eActAlign;
473
0
    }
474
475
    SFX_IMPL_DOCKINGWINDOW( NavigatorFrameManager, SID_FM_SHOW_FMEXPLORER )
476
477
    NavigatorFrameManager::NavigatorFrameManager( vcl::Window* _pParent, sal_uInt16 _nId,
478
                                        SfxBindings* _pBindings, SfxChildWinInfo* _pInfo )
479
0
                     :SfxChildWindow( _pParent, _nId )
480
0
    {
481
0
        SetWindow( VclPtr<NavigatorFrame>::Create( _pBindings, this, _pParent ) );
482
0
        static_cast<SfxDockingWindow*>(GetWindow())->Initialize( _pInfo );
483
0
    }
484
}
485
486
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */