Coverage Report

Created: 2025-12-08 09:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/UnoControls/source/base/basecontrol.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 <basecontrol.hxx>
21
#include <multiplexer.hxx>
22
23
#include <com/sun/star/awt/XDevice.hpp>
24
#include <com/sun/star/awt/WindowAttribute.hpp>
25
#include <com/sun/star/awt/PosSize.hpp>
26
#include <com/sun/star/awt/Toolkit.hpp>
27
#include <cppuhelper/supportsservice.hxx>
28
#include <cppuhelper/queryinterface.hxx>
29
#include <cppuhelper/typeprovider.hxx>
30
31
//  namespaces
32
33
using namespace ::cppu;
34
using namespace ::osl;
35
using namespace ::com::sun::star::uno;
36
using namespace ::com::sun::star::lang;
37
using namespace ::com::sun::star::awt;
38
39
namespace unocontrols {
40
41
constexpr sal_Int32 DEFAULT_X = 0;
42
constexpr sal_Int32 DEFAULT_Y = 0;
43
constexpr sal_Int32 DEFAULT_WIDTH = 100;
44
constexpr sal_Int32 DEFAULT_HEIGHT = 100;
45
constexpr bool DEFAULT_VISIBLE = false;
46
constexpr bool DEFAULT_INDESIGNMODE = false;
47
constexpr bool DEFAULT_ENABLE = true;
48
49
//  construct/destruct
50
51
BaseControl::BaseControl( const Reference< XComponentContext >& rxContext )
52
0
    : WeakComponentImplHelper   ( m_aMutex              )
53
0
    , m_xComponentContext       ( rxContext              )
54
0
    , m_nX                      ( DEFAULT_X             )
55
0
    , m_nY                      ( DEFAULT_Y             )
56
0
    , m_nWidth                  ( DEFAULT_WIDTH         )
57
0
    , m_nHeight                 ( DEFAULT_HEIGHT        )
58
0
    , m_bVisible                ( DEFAULT_VISIBLE       )
59
0
    , m_bInDesignMode           ( DEFAULT_INDESIGNMODE  )
60
0
    , m_bEnable                 ( DEFAULT_ENABLE        )
61
0
{
62
0
}
63
64
BaseControl::~BaseControl()
65
0
{
66
0
}
67
68
//  XServiceInfo
69
70
OUString SAL_CALL BaseControl::getImplementationName()
71
0
{
72
0
    return OUString();
73
0
}
74
75
//  XServiceInfo
76
77
sal_Bool SAL_CALL BaseControl::supportsService( const OUString& sServiceName )
78
0
{
79
0
    return cppu::supportsService(this, sServiceName);
80
0
}
81
82
//  XServiceInfo
83
84
Sequence< OUString > SAL_CALL BaseControl::getSupportedServiceNames()
85
0
{
86
0
    return Sequence< OUString >();
87
0
}
88
89
//  XComponent
90
91
void SAL_CALL BaseControl::dispose()
92
0
{
93
    // Ready for multithreading
94
0
    MutexGuard aGuard( m_aMutex );
95
96
0
    if ( m_xMultiplexer.is() )
97
0
    {
98
        // to all other paint, focus, etc.
99
0
        m_xMultiplexer->disposeAndClear();
100
0
        m_xMultiplexer.clear();
101
0
    }
102
103
    // set the service manager to disposed
104
0
    WeakComponentImplHelper::dispose();
105
106
    // release context and peer
107
0
    m_xContext.clear();
108
0
    if ( m_xPeer.is() )
109
0
    {
110
0
        if ( m_xGraphicsPeer.is() )
111
0
        {
112
0
            removePaintListener( this );
113
0
            removeWindowListener( this );
114
0
            m_xGraphicsPeer.clear();
115
0
        }
116
117
0
        m_xPeer->dispose();
118
0
        m_xPeerWindow.clear();
119
0
        m_xPeer.clear();
120
0
    }
121
122
    // release view
123
0
    if ( m_xGraphicsView.is() )
124
0
    {
125
0
        m_xGraphicsView.clear();
126
0
    }
127
0
}
128
129
//  XComponent
130
131
void SAL_CALL BaseControl::addEventListener( const Reference< XEventListener >& xListener )
132
0
{
133
    // Ready for multithreading
134
0
    MutexGuard aGuard( m_aMutex );
135
0
    WeakComponentImplHelper::addEventListener( xListener );
136
0
}
137
138
//  XComponent
139
140
void SAL_CALL BaseControl::removeEventListener( const Reference< XEventListener >& xListener )
141
0
{
142
    // Ready for multithreading
143
0
    MutexGuard aGuard( m_aMutex );
144
0
    WeakComponentImplHelper::removeEventListener( xListener );
145
0
}
146
147
//  XControl
148
149
void SAL_CALL BaseControl::createPeer(  const   Reference< XToolkit >&      xToolkit    ,
150
                                        const   Reference< XWindowPeer >&   xParentPeer )
151
0
{
152
    // Ready for multithreading
153
0
    MutexGuard aGuard( m_aMutex );
154
155
0
    if ( m_xPeer.is() )
156
0
        return;
157
158
    // use method "BaseControl::getWindowDescriptor()" to change window attributes!
159
0
    WindowDescriptor aDescriptor = impl_getWindowDescriptor( xParentPeer );
160
161
0
    if ( m_bVisible )
162
0
    {
163
0
        aDescriptor.WindowAttributes |= WindowAttribute::SHOW;
164
0
    }
165
166
    // very slow under remote conditions!
167
    // create the window on the server
168
0
    Reference< XToolkit > xLocalToolkit = xToolkit;
169
0
    if ( !xLocalToolkit.is() )
170
0
    {
171
        // but first create well known toolkit, if it not exist
172
0
        xLocalToolkit.set( Toolkit::create(m_xComponentContext), UNO_QUERY_THROW );
173
0
    }
174
0
    m_xPeer         = xLocalToolkit->createWindow( aDescriptor );
175
0
    m_xPeerWindow.set( m_xPeer, UNO_QUERY );
176
177
0
    if ( !m_xPeerWindow.is() )
178
0
        return;
179
180
0
    if ( m_xMultiplexer.is() )
181
0
    {
182
0
        m_xMultiplexer->setPeer( m_xPeerWindow );
183
0
    }
184
185
    // create new reference to xgraphics for painting on a peer
186
    // and add a paint listener
187
0
    Reference< XDevice > xDevice( m_xPeerWindow, UNO_QUERY );
188
189
0
    if ( xDevice.is() )
190
0
    {
191
0
        m_xGraphicsPeer = xDevice->createGraphics();
192
0
    }
193
194
0
    if ( m_xGraphicsPeer.is() )
195
0
    {
196
0
        addPaintListener( this );
197
0
        addWindowListener( this );
198
0
    }
199
200
0
    m_xPeerWindow->setPosSize(  m_nX, m_nY, m_nWidth, m_nHeight, PosSize::POSSIZE   );
201
0
    m_xPeerWindow->setEnable(   m_bEnable                                           );
202
0
    m_xPeerWindow->setVisible(  m_bVisible && !m_bInDesignMode                      );
203
0
}
204
205
//  XControl
206
207
void SAL_CALL BaseControl::setContext( const Reference< XInterface >& xContext )
208
0
{
209
    // Ready for multithreading
210
0
    MutexGuard aGuard( m_aMutex );
211
0
    m_xContext = xContext;
212
0
}
213
214
//  XControl
215
216
void SAL_CALL BaseControl::setDesignMode( sal_Bool bOn )
217
0
{
218
    // Ready for multithreading
219
0
    MutexGuard aGuard( m_aMutex );
220
0
    m_bInDesignMode = bOn;
221
0
}
222
223
//  XControl
224
225
Reference< XInterface > SAL_CALL BaseControl::getContext()
226
0
{
227
    // Ready for multithreading
228
0
    MutexGuard aGuard( m_aMutex );
229
0
    return m_xContext;
230
0
}
231
232
//  XControl
233
234
Reference< XWindowPeer > SAL_CALL BaseControl::getPeer()
235
0
{
236
    // Ready for multithreading
237
0
    MutexGuard aGuard( m_aMutex );
238
0
    return m_xPeer;
239
0
}
240
241
//  XControl
242
243
Reference< XView > SAL_CALL BaseControl::getView()
244
0
{
245
    // Ready for multithreading
246
0
    MutexGuard aGuard( m_aMutex );
247
0
    return this;
248
0
}
249
250
//  XControl
251
252
sal_Bool SAL_CALL BaseControl::isDesignMode()
253
0
{
254
    // Ready for multithreading
255
0
    MutexGuard aGuard( m_aMutex );
256
0
    return m_bInDesignMode;
257
0
}
258
259
//  XControl
260
261
sal_Bool SAL_CALL BaseControl::isTransparent()
262
0
{
263
0
    return false;
264
0
}
265
266
//  XWindow
267
268
void SAL_CALL BaseControl::setPosSize(  sal_Int32   nX      ,
269
                                        sal_Int32   nY      ,
270
                                        sal_Int32   nWidth  ,
271
                                        sal_Int32   nHeight ,
272
                                        sal_Int16   nFlags  )
273
0
{
274
    // - change size and position of window and save the values
275
276
    // Ready for multithreading
277
0
    MutexGuard aGuard( m_aMutex );
278
279
0
    bool bChanged = false;
280
281
0
    if ( nFlags & PosSize::X )
282
0
    {
283
0
        bChanged |= m_nX != nX;
284
0
        m_nX = nX;
285
0
    }
286
287
0
    if ( nFlags & PosSize::Y )
288
0
    {
289
0
        bChanged |= m_nY != nY;
290
0
        m_nY = nY;
291
0
    }
292
293
0
    if ( nFlags & PosSize::WIDTH )
294
0
    {
295
0
        bChanged |= m_nWidth != nWidth;
296
0
        m_nWidth  = nWidth;
297
0
    }
298
299
0
    if ( nFlags & PosSize::HEIGHT )
300
0
    {
301
0
        bChanged |= m_nHeight != nHeight;
302
0
        m_nHeight = nHeight;
303
0
    }
304
305
0
    if ( bChanged && m_xPeerWindow.is() )
306
0
    {
307
0
        m_xPeerWindow->setPosSize( m_nX, m_nY, m_nWidth, m_nHeight, nFlags );
308
0
    }
309
0
}
310
311
//  XWindow
312
313
void SAL_CALL BaseControl::setVisible( sal_Bool bVisible )
314
0
{
315
    // Ready for multithreading
316
0
    MutexGuard aGuard( m_aMutex );
317
318
    // Set new state of flag
319
0
    m_bVisible = bVisible;
320
321
0
    if ( m_xPeerWindow.is() )
322
0
    {
323
        // Set it also on peerwindow
324
0
        m_xPeerWindow->setVisible( m_bVisible );
325
0
    }
326
0
}
327
328
//  XWindow
329
330
void SAL_CALL BaseControl::setEnable( sal_Bool bEnable )
331
0
{
332
    // Ready for multithreading
333
0
    MutexGuard aGuard( m_aMutex );
334
335
    // Set new state of flag
336
0
    m_bEnable = bEnable;
337
338
0
    if ( m_xPeerWindow.is() )
339
0
    {
340
        // Set it also on peerwindow
341
0
        m_xPeerWindow->setEnable( m_bEnable );
342
0
    }
343
0
}
344
345
//  XWindow
346
347
void SAL_CALL BaseControl::setFocus()
348
0
{
349
    // Ready for multithreading
350
0
    MutexGuard aGuard( m_aMutex );
351
352
0
    if ( m_xPeerWindow.is() )
353
0
    {
354
0
        m_xPeerWindow->setFocus();
355
0
    }
356
0
}
357
358
//  XWindow
359
360
Rectangle SAL_CALL BaseControl::getPosSize()
361
0
{
362
    // Ready for multithreading
363
0
    MutexGuard aGuard( m_aMutex );
364
0
    return Rectangle( m_nX, m_nY , m_nWidth, m_nHeight );
365
0
}
366
367
//  XWindow
368
369
void SAL_CALL BaseControl::addWindowListener( const Reference< XWindowListener >& xListener )
370
0
{
371
0
    impl_getMultiplexer()->advise(xListener);
372
0
}
373
374
//  XWindow
375
376
void SAL_CALL BaseControl::addFocusListener( const Reference< XFocusListener >& xListener )
377
0
{
378
0
    impl_getMultiplexer()->advise(xListener);
379
0
}
380
381
//  XWindow
382
383
void SAL_CALL BaseControl::addKeyListener( const Reference< XKeyListener >& xListener )
384
0
{
385
0
    impl_getMultiplexer()->advise(xListener);
386
0
}
387
388
//  XWindow
389
390
void SAL_CALL BaseControl::addMouseListener( const Reference< XMouseListener >& xListener )
391
0
{
392
0
    impl_getMultiplexer()->advise(xListener);
393
0
}
394
395
//  XWindow
396
397
void SAL_CALL BaseControl::addMouseMotionListener( const Reference< XMouseMotionListener >& xListener )
398
0
{
399
0
    impl_getMultiplexer()->advise(xListener);
400
0
}
401
402
//  XWindow
403
404
void SAL_CALL BaseControl::addPaintListener( const Reference< XPaintListener >& xListener )
405
0
{
406
0
    impl_getMultiplexer()->advise(xListener);
407
0
}
408
409
//  XWindow
410
411
void SAL_CALL BaseControl::removeWindowListener( const Reference< XWindowListener >& xListener )
412
0
{
413
0
    impl_getMultiplexer()->unadvise(xListener);
414
0
}
415
416
//  XWindow
417
418
void SAL_CALL BaseControl::removeFocusListener( const Reference< XFocusListener >& xListener )
419
0
{
420
0
    impl_getMultiplexer()->unadvise(xListener);
421
0
}
422
423
//  XWindow
424
425
void SAL_CALL BaseControl::removeKeyListener( const Reference< XKeyListener >& xListener )
426
0
{
427
0
    impl_getMultiplexer()->unadvise(xListener);
428
0
}
429
430
//  XWindow
431
432
void SAL_CALL BaseControl::removeMouseListener( const Reference< XMouseListener >& xListener )
433
0
{
434
0
    impl_getMultiplexer()->unadvise(xListener);
435
0
}
436
437
//  XWindow
438
439
void  SAL_CALL BaseControl::removeMouseMotionListener( const Reference< XMouseMotionListener >& xListener )
440
0
{
441
0
    impl_getMultiplexer()->unadvise(xListener);
442
0
}
443
444
//  XWindow
445
446
void SAL_CALL BaseControl::removePaintListener( const Reference< XPaintListener >& xListener )
447
0
{
448
0
    impl_getMultiplexer()->unadvise(xListener);
449
0
}
450
451
//  XView
452
453
void SAL_CALL BaseControl::draw(    sal_Int32   nX  ,
454
                                    sal_Int32   nY  )
455
0
{
456
    // Ready for multithreading
457
0
    MutexGuard aGuard( m_aMutex );
458
459
    // - paint to a view
460
    // - use the method "paint()"
461
    // - see also "windowPaint()"
462
0
    impl_paint( nX, nY, m_xGraphicsView );
463
0
}
464
465
//  XView
466
467
sal_Bool SAL_CALL BaseControl::setGraphics( const Reference< XGraphics >& xDevice )
468
0
{
469
    // - set the graphics for a view
470
    // - in this class exist 2 graphics-member ... one for peer[_xGraphicsPeer] and one for view[_xGraphicsView]
471
    // - they are used by "windowPaint() and draw()", forwarded to "paint ()"
472
0
    bool bReturn = false;
473
0
    if ( xDevice.is() )
474
0
    {
475
        // Ready for multithreading
476
0
        MutexGuard aGuard( m_aMutex );
477
478
0
        m_xGraphicsView = xDevice;
479
0
        bReturn         = true;
480
0
    }
481
482
0
    return bReturn;
483
0
}
484
485
//  XView
486
487
void SAL_CALL BaseControl::setZoom( float   /*fZoomX*/  ,
488
                                    float   /*fZoomY*/  )
489
0
{
490
    // Not implemented yet
491
0
}
492
493
//  XView
494
495
Reference< XGraphics > SAL_CALL BaseControl::getGraphics()
496
0
{
497
    // Ready for multithreading
498
0
    MutexGuard aGuard( m_aMutex );
499
0
    return m_xGraphicsView;
500
0
}
501
502
//  XView
503
504
Size SAL_CALL BaseControl::getSize()
505
0
{
506
    // Ready for multithreading
507
0
    MutexGuard aGuard( m_aMutex );
508
0
    return Size( m_nWidth, m_nHeight );
509
0
}
510
511
//  XEventListener
512
513
void SAL_CALL BaseControl::disposing( const EventObject& /*aSource*/ )
514
0
{
515
    // Ready for multithreading
516
0
    MutexGuard aGuard( m_aMutex );
517
518
    // - release ALL references
519
    // - it must be !!!
520
0
    if ( m_xGraphicsPeer.is() )
521
0
    {
522
0
        removePaintListener( this );
523
0
        removeWindowListener( this );
524
0
        m_xGraphicsPeer.clear();
525
0
    }
526
527
0
    if ( m_xGraphicsView.is() )
528
0
    {
529
0
        m_xGraphicsView.clear();
530
0
    }
531
0
}
532
533
//  XPaintListener
534
535
void SAL_CALL BaseControl::windowPaint( const PaintEvent& /*aEvent*/ )
536
0
{
537
    // Ready for multithreading
538
0
    MutexGuard aGuard( m_aMutex );
539
540
    // - repaint the peer
541
    // - use the method "paint ()" for painting on a peer and a print device !!!
542
    // - see also "draw ()"
543
0
    impl_paint( 0, 0, m_xGraphicsPeer );
544
0
}
545
546
//  XWindowListener
547
548
void SAL_CALL BaseControl::windowResized( const WindowEvent& aEvent )
549
0
{
550
    // Ready for multithreading
551
0
    MutexGuard aGuard( m_aMutex );
552
553
0
    m_nWidth    =   aEvent.Width;
554
0
    m_nHeight   =   aEvent.Height;
555
0
    WindowEvent aMappedEvent = aEvent;
556
0
    aMappedEvent.X = 0;
557
0
    aMappedEvent.Y = 0;
558
0
    impl_recalcLayout( aMappedEvent );
559
0
}
560
561
//  XWindowListener
562
563
void SAL_CALL BaseControl::windowMoved( const WindowEvent& aEvent )
564
0
{
565
    // Ready for multithreading
566
0
    MutexGuard aGuard( m_aMutex );
567
568
0
    m_nWidth    =   aEvent.Width;
569
0
    m_nHeight   =   aEvent.Height;
570
0
    WindowEvent aMappedEvent = aEvent;
571
0
    aMappedEvent.X = 0;
572
0
    aMappedEvent.Y = 0;
573
0
    impl_recalcLayout( aMappedEvent );
574
0
}
575
576
//  XWindowListener
577
578
void SAL_CALL BaseControl::windowShown( const EventObject& /*aEvent*/ )
579
0
{
580
0
}
581
582
//  XWindowListener
583
584
void SAL_CALL BaseControl::windowHidden( const EventObject& /*aEvent*/ )
585
0
{
586
0
}
587
588
//  protected method
589
590
WindowDescriptor BaseControl::impl_getWindowDescriptor( const Reference< XWindowPeer >& xParentPeer )
591
0
{
592
    // - used from "createPeer()" to set the values of a css::awt::WindowDescriptor !!!
593
    // - if you will change the descriptor-values, you must override this virtual function
594
    // - the caller must release the memory for this dynamical descriptor !!!
595
596
0
    WindowDescriptor aDescriptor;
597
598
0
    aDescriptor.Type               = WindowClass_SIMPLE;
599
0
    aDescriptor.WindowServiceName  = "window";
600
0
    aDescriptor.ParentIndex        = -1;
601
0
    aDescriptor.Parent             = xParentPeer;
602
0
    aDescriptor.Bounds             = getPosSize ();
603
0
    aDescriptor.WindowAttributes   = 0;
604
605
0
    return aDescriptor;
606
0
}
607
608
//  protected method
609
610
void BaseControl::impl_paint(           sal_Int32               /*nX*/          ,
611
                                        sal_Int32               /*nY*/          ,
612
                                const   Reference< XGraphics >& /*xGraphics*/   )
613
0
{
614
    // - one paint method for peer AND view !!!
615
    //   (see also => "windowPaint()" and "draw()")
616
    // - not used in this implementation, but it's not necessary to make it pure virtual !!!
617
0
}
618
619
//  protected method
620
621
void BaseControl::impl_recalcLayout( const WindowEvent& /*aEvent*/ )
622
0
{
623
    // We need as virtual function to support automatically resizing of derived controls!
624
    // But we make it not pure virtual because it's not necessary for all derived classes!
625
0
}
626
627
//  private method
628
629
OMRCListenerMultiplexerHelper* BaseControl::impl_getMultiplexer()
630
0
{
631
0
    if ( !m_xMultiplexer.is() )
632
0
    {
633
0
        m_xMultiplexer = new OMRCListenerMultiplexerHelper( static_cast<XWindow*>(this), m_xPeerWindow );
634
0
    }
635
636
0
    return m_xMultiplexer.get();
637
0
}
638
639
} // namespace unocontrols
640
641
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */