Coverage Report

Created: 2026-10-14 09:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/UnoControls/source/base/basecontainercontrol.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 <basecontainercontrol.hxx>
21
22
#include <cppuhelper/queryinterface.hxx>
23
#include <cppuhelper/typeprovider.hxx>
24
25
#include <com/sun/star/container/ContainerEvent.hpp>
26
#include <com/sun/star/container/XContainerListener.hpp>
27
#include <com/sun/star/awt/XControlContainer.hpp>
28
29
//  namespaces
30
31
using namespace ::cppu;
32
using namespace ::osl;
33
using namespace ::com::sun::star::uno;
34
using namespace ::com::sun::star::lang;
35
using namespace ::com::sun::star::awt;
36
using namespace ::com::sun::star::container;
37
38
namespace unocontrols {
39
40
//  construct/destruct
41
42
BaseContainerControl::BaseContainerControl( const Reference< XComponentContext >& rxContext )
43
0
    : BaseContainerControl_BASE(rxContext)
44
0
    , m_aListeners  ( m_aMutex  )
45
0
{
46
0
}
47
48
BaseContainerControl::~BaseContainerControl()
49
0
{
50
0
}
51
52
//  XControl
53
54
void SAL_CALL BaseContainerControl::createPeer( const   Reference< XToolkit >&      xToolkit    ,
55
                                                const   Reference< XWindowPeer >&   xParent     )
56
0
{
57
0
    if ( getPeer().is() )
58
0
        return;
59
60
    // create own peer
61
0
    BaseControl::createPeer( xToolkit, xParent );
62
63
    // create peers at all children
64
0
    Sequence< Reference< XControl > >   seqControlList  = getControls();
65
66
0
    for ( auto& rxControl : asNonConstRange(seqControlList) )
67
0
    {
68
0
        rxControl->createPeer( xToolkit, getPeer() );
69
0
    }
70
0
}
71
72
//  XControl
73
74
sal_Bool SAL_CALL BaseContainerControl::setModel( const Reference< XControlModel >& )
75
0
{
76
    // This object has NO model.
77
0
    return false;
78
0
}
79
80
//  XControl
81
82
Reference< XControlModel > SAL_CALL BaseContainerControl::getModel()
83
0
{
84
    // This object has NO model.
85
    // return (XControlModel*)this;
86
0
    return Reference< XControlModel >();
87
0
}
88
89
//  XComponent
90
91
void SAL_CALL BaseContainerControl::dispose()
92
0
{
93
    // Tell everything that this container is now gone.
94
    // It's faster if you listen to both the control and the container.
95
96
    // Ready for multithreading
97
0
    MutexGuard aGuard( m_aMutex );
98
99
    // remove listeners
100
0
    EventObject aObject;
101
102
0
    aObject.Source.set( static_cast<XControlContainer*>(this), UNO_QUERY );
103
0
    m_aListeners.disposeAndClear( aObject );
104
105
    // remove controls
106
0
    const Sequence< Reference< XControl > >   seqCtrls    =   getControls();
107
108
0
    maControlInfoList.clear();
109
110
0
    for ( Reference< XControl > const & control : seqCtrls )
111
0
    {
112
0
        control->removeEventListener    ( static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) ) );
113
0
        control->dispose                (       );
114
0
    }
115
116
    // call baseclass
117
0
    BaseControl::dispose();
118
0
}
119
120
//  XEventListener
121
122
void SAL_CALL BaseContainerControl::disposing( const EventObject& rEvent )
123
0
{
124
0
    Reference< XControl > xControl( rEvent.Source, UNO_QUERY );
125
126
    // "removeControl" remove only, when control is an active control
127
0
    removeControl( xControl );
128
0
}
129
130
//  XControlContainer
131
132
void SAL_CALL BaseContainerControl::addControl ( const OUString& rName, const Reference< XControl > & rControl )
133
0
{
134
0
    if ( !rControl.is () )
135
0
        return;
136
137
    // take memory for new item
138
0
    IMPL_ControlInfo aNewControl;
139
140
    // Ready for multithreading
141
0
    MutexGuard aGuard (m_aMutex);
142
143
    // set control
144
0
    aNewControl.sName      = rName;
145
0
    aNewControl.xControl   = rControl;
146
147
    // and insert in list
148
0
    maControlInfoList.emplace_back( aNewControl );
149
150
    // initialize new control
151
0
    aNewControl.xControl->setContext       (getXWeak());
152
0
    aNewControl.xControl->addEventListener ( static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) ) );
153
154
    // when container has a peer...
155
0
    if (getPeer().is())
156
0
    {
157
        // ... then create a peer on child
158
0
        aNewControl.xControl->createPeer ( getPeer()->getToolkit(), getPeer() );
159
0
    }
160
161
    // Send message to all listener
162
0
    comphelper::OInterfaceContainerHelper2* pInterfaceContainer = m_aListeners.getContainer( cppu::UnoType<XContainerListener>::get());
163
164
0
    if (!pInterfaceContainer)
165
0
        return;
166
167
    // Build event
168
0
    ContainerEvent  aEvent;
169
170
0
    aEvent.Source   = *this;
171
0
    aEvent.Element <<= rControl;
172
173
    // Get all listener
174
0
    comphelper::OInterfaceIteratorHelper2  aIterator (*pInterfaceContainer);
175
176
    // Send event
177
0
    while ( aIterator.hasMoreElements() )
178
0
    {
179
0
        static_cast<XContainerListener*>(aIterator.next())->elementInserted (aEvent);
180
0
    }
181
0
}
182
183
//  XControlContainer
184
185
void SAL_CALL BaseContainerControl::removeControl ( const Reference< XControl > & rControl )
186
0
{
187
0
    if ( !rControl.is() )
188
0
        return;
189
190
    // Ready for multithreading
191
0
    MutexGuard aGuard (m_aMutex);
192
193
    // Search for right control
194
0
    auto it = std::find_if(maControlInfoList.begin(), maControlInfoList.end(),
195
0
        [&rControl](const IMPL_ControlInfo& control)
196
0
        { return rControl == control.xControl; });
197
198
    // if not found
199
0
    if ( it == maControlInfoList.end() )
200
0
        return;
201
202
    // remove listener from control
203
0
    it->xControl->removeEventListener (static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) ));
204
0
    it->xControl->setContext          ( Reference< XInterface >  ()   );
205
206
    // ... free memory
207
0
    maControlInfoList.erase(it);
208
209
    // Send message to all other listener
210
0
    comphelper::OInterfaceContainerHelper2 * pInterfaceContainer = m_aListeners.getContainer( cppu::UnoType<XContainerListener>::get());
211
212
0
    if (pInterfaceContainer)
213
0
    {
214
0
        ContainerEvent  aEvent;
215
216
0
        aEvent.Source    = *this;
217
0
        aEvent.Element <<= rControl;
218
219
0
        comphelper::OInterfaceIteratorHelper2 aIterator (*pInterfaceContainer);
220
221
0
        while ( aIterator.hasMoreElements() )
222
0
        {
223
0
            static_cast<XContainerListener*>(aIterator.next())->elementRemoved (aEvent);
224
0
        }
225
0
    }
226
0
}
227
228
//  XControlContainer
229
230
void SAL_CALL BaseContainerControl::setStatusText ( const OUString& rStatusText )
231
0
{
232
    // go down to each parent
233
0
    Reference< XControlContainer >  xContainer ( getContext(), UNO_QUERY );
234
235
0
    if ( xContainer.is () )
236
0
    {
237
0
        xContainer->setStatusText ( rStatusText );
238
0
    }
239
0
}
240
241
//  XControlContainer
242
243
Reference< XControl > SAL_CALL BaseContainerControl::getControl ( const OUString& rName )
244
0
{
245
    // Ready for multithreading
246
0
    MutexGuard  aGuard ( Mutex::getGlobalMutex() );
247
248
    // Search for right control
249
0
    for( const IMPL_ControlInfo& rSearchControl : maControlInfoList )
250
0
    {
251
0
        if ( rSearchControl.sName == rName )
252
0
        {
253
            // We have found it ...
254
            // Break operation and return.
255
0
            return rSearchControl.xControl;
256
0
        }
257
0
    }
258
259
    // We have not found it ... return NULL.
260
0
    return Reference< XControl >  ();
261
0
}
262
263
//  XControlContainer
264
265
Sequence< Reference< XControl > > SAL_CALL BaseContainerControl::getControls ()
266
0
{
267
    // Ready for multithreading
268
0
    MutexGuard  aGuard ( Mutex::getGlobalMutex() );
269
270
0
    size_t                              nControls       = maControlInfoList.size();
271
0
    size_t                              nCount          = 0;
272
0
    Sequence< Reference< XControl > >   aDescriptor     ( nControls );
273
0
    Reference< XControl > *             pDestination    = aDescriptor.getArray ();
274
275
    // Copy controls to sequence
276
0
    for( const IMPL_ControlInfo& rCopyControl : maControlInfoList )
277
0
    {
278
0
        pDestination [ nCount++ ] = rCopyControl.xControl;
279
0
    }
280
281
    // Return sequence
282
0
    return aDescriptor;
283
0
}
284
285
//  XWindow
286
287
void SAL_CALL BaseContainerControl::setVisible ( sal_Bool bVisible )
288
0
{
289
    // override baseclass definition
290
0
    BaseControl::setVisible ( bVisible );
291
292
    // is it a top window ?
293
0
    if ( !getContext().is() && bVisible )
294
0
    {
295
        // then show it automatically
296
0
        createPeer ( Reference< XToolkit > (), Reference< XWindowPeer > () );
297
0
    }
298
0
}
299
300
//  protected method
301
302
WindowDescriptor BaseContainerControl::impl_getWindowDescriptor ( const Reference< XWindowPeer > & rParentPeer )
303
0
{
304
0
    WindowDescriptor aDescriptor;
305
306
0
    aDescriptor.Type               = WindowClass_CONTAINER;
307
0
    aDescriptor.WindowServiceName  = "window";
308
0
    aDescriptor.ParentIndex        = -1;
309
0
    aDescriptor.Parent             = rParentPeer;
310
0
    aDescriptor.Bounds             = getPosSize ();
311
0
    aDescriptor.WindowAttributes   = 0;
312
313
0
    return aDescriptor;
314
0
}
315
316
//  protected method
317
318
void BaseContainerControl::impl_paint ( sal_Int32 /*nX*/, sal_Int32 /*nY*/, const Reference< XGraphics > & /*rGraphics*/ )
319
0
{
320
0
}
321
322
} // namespace unocontrols
323
324
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */