Coverage Report

Created: 2026-06-30 11:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/avmedia/source/viewer/mediawindow_impl.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 <iostream>
21
#include "mediawindow_impl.hxx"
22
#include "mediaevent_impl.hxx"
23
#include <mediamisc.hxx>
24
#include <bitmaps.hlst>
25
#include <helpids.h>
26
27
#include <algorithm>
28
29
#include <sal/log.hxx>
30
#include <comphelper/processfactory.hxx>
31
#include <comphelper/diagnose_ex.hxx>
32
#include <comphelper/DirectoryHelper.hxx>
33
#include <comphelper/scopeguard.hxx>
34
#include <tools/urlobj.hxx>
35
#include <unotools/securityoptions.hxx>
36
#include <vcl/bitmap.hxx>
37
#include <vcl/sysdata.hxx>
38
#include <vcl/commandevent.hxx>
39
#include <vcl/event.hxx>
40
#include <vcl/ptrstyle.hxx>
41
#include <vcl/svapp.hxx>
42
43
#include <com/sun/star/awt/SystemPointer.hpp>
44
#include <com/sun/star/lang/XComponent.hpp>
45
#include <com/sun/star/media/XManager.hpp>
46
#include <com/sun/star/uno/XComponentContext.hpp>
47
using namespace ::com::sun::star;
48
49
namespace avmedia::priv {
50
51
MediaWindowControl::MediaWindowControl(vcl::Window* pParent)
52
0
    : MediaControl(pParent, MediaControlStyle::MultiLine)
53
0
{
54
0
}
Unexecuted instantiation: avmedia::priv::MediaWindowControl::MediaWindowControl(vcl::Window*)
Unexecuted instantiation: avmedia::priv::MediaWindowControl::MediaWindowControl(vcl::Window*)
55
56
void MediaWindowControl::update()
57
0
{
58
0
    MediaItem aItem;
59
60
0
    static_cast< MediaWindowImpl* >( GetParent() )->updateMediaItem( aItem );
61
0
    setState(aItem);
62
0
}
63
64
void MediaWindowControl::execute(const MediaItem& rItem)
65
0
{
66
0
    static_cast<MediaWindowImpl*>(GetParent())->executeMediaItem(rItem);
67
0
}
68
69
MediaChildWindow::MediaChildWindow(vcl::Window* pParent)
70
0
    : SystemChildWindow(pParent, WB_CLIPCHILDREN)
71
0
{
72
0
}
Unexecuted instantiation: avmedia::priv::MediaChildWindow::MediaChildWindow(vcl::Window*)
Unexecuted instantiation: avmedia::priv::MediaChildWindow::MediaChildWindow(vcl::Window*)
73
74
void MediaChildWindow::MouseMove( const MouseEvent& rMEvt )
75
0
{
76
0
    const MouseEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ),
77
0
                                          rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() );
78
79
0
    SystemChildWindow::MouseMove( rMEvt );
80
0
    GetParent()->MouseMove( aTransformedEvent );
81
0
}
82
83
void MediaChildWindow::MouseButtonDown( const MouseEvent& rMEvt )
84
0
{
85
0
    const MouseEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ),
86
0
                                          rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() );
87
88
0
    SystemChildWindow::MouseButtonDown( rMEvt );
89
0
    GetParent()->MouseButtonDown( aTransformedEvent );
90
0
}
91
92
void MediaChildWindow::MouseButtonUp( const MouseEvent& rMEvt )
93
0
{
94
0
    const MouseEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ),
95
0
                                          rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() );
96
97
0
    SystemChildWindow::MouseButtonUp( rMEvt );
98
0
    GetParent()->MouseButtonUp( aTransformedEvent );
99
0
}
100
101
void MediaChildWindow::KeyInput( const KeyEvent& rKEvt )
102
0
{
103
0
    SystemChildWindow::KeyInput( rKEvt );
104
0
    GetParent()->KeyInput( rKEvt );
105
0
}
106
107
void MediaChildWindow::KeyUp( const KeyEvent& rKEvt )
108
0
{
109
0
    SystemChildWindow::KeyUp( rKEvt );
110
0
    GetParent()->KeyUp( rKEvt );
111
0
}
112
113
void MediaChildWindow::Command( const CommandEvent& rCEvt )
114
0
{
115
0
    const CommandEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rCEvt.GetMousePosPixel() ) ),
116
0
                                          rCEvt.GetCommand(), rCEvt.IsMouseEvent(), rCEvt.GetEventData() );
117
118
0
    SystemChildWindow::Command( rCEvt );
119
0
    GetParent()->Command( aTransformedEvent );
120
0
}
121
122
MediaWindowImpl::MediaWindowImpl(vcl::Window* pParent, MediaWindow* pMediaWindow, bool bInternalMediaControl)
123
0
    : Control(pParent)
124
0
    , DropTargetHelper(this)
125
0
    , DragSourceHelper(this)
126
0
    , mpMediaWindow(pMediaWindow)
127
0
    , mpMediaWindowControl(bInternalMediaControl ? VclPtr<MediaWindowControl>::Create(this) : nullptr)
128
0
{
129
0
    if (mpMediaWindowControl)
130
0
    {
131
0
        mpMediaWindowControl->SetSizePixel(mpMediaWindowControl->GetOptimalSize());
132
0
        mpMediaWindowControl->Show();
133
0
    }
134
0
}
Unexecuted instantiation: avmedia::priv::MediaWindowImpl::MediaWindowImpl(vcl::Window*, avmedia::MediaWindow*, bool)
Unexecuted instantiation: avmedia::priv::MediaWindowImpl::MediaWindowImpl(vcl::Window*, avmedia::MediaWindow*, bool)
135
136
MediaWindowImpl::~MediaWindowImpl()
137
0
{
138
0
    disposeOnce();
139
0
}
140
141
void MediaWindowImpl::dispose()
142
0
{
143
0
    if (mxEvents.is())
144
0
        mxEvents->cleanUp();
145
146
0
    if (mxPlayerWindow.is())
147
0
    {
148
0
        mxPlayerWindow->removeKeyListener( uno::Reference< awt::XKeyListener >( mxEvents ) );
149
0
        mxPlayerWindow->removeMouseListener( uno::Reference< awt::XMouseListener >( mxEvents ) );
150
0
        mxPlayerWindow->removeMouseMotionListener( uno::Reference< awt::XMouseMotionListener >( mxEvents ) );
151
0
        mxPlayerWindow->dispose();
152
0
        mxPlayerWindow.clear();
153
0
    }
154
155
0
    uno::Reference< lang::XComponent > xComponent( mxPlayer, uno::UNO_QUERY );
156
0
    if (xComponent.is()) // this stops the player
157
0
        xComponent->dispose();
158
159
0
    mxPlayer.clear();
160
161
0
    mpMediaWindow = nullptr;
162
163
0
    maEmptyBmp.SetEmpty();
164
0
    maAudioBmp.SetEmpty();
165
0
    mpMediaWindowControl.disposeAndClear();
166
0
    mpChildWindow.disposeAndClear();
167
168
0
    Control::dispose();
169
0
}
170
171
uno::Reference<media::XPlayer> MediaWindowImpl::createPlayer(const OUString& rURL, const OUString& rReferer, const OUString*)
172
0
{
173
0
    if( rURL.isEmpty() )
174
0
        return nullptr;
175
176
0
    if (SvtSecurityOptions::isUntrustedReferer(rReferer))
177
0
        return nullptr;
178
179
0
    if (INetURLObject(rURL).IsExoticProtocol())
180
0
        return nullptr;
181
182
0
    uno::Reference<media::XPlayer> xPlayer;
183
184
    // currently there isn't anything else, throw any mime type to the media players
185
    //if (!pMimeType || *pMimeType == AVMEDIA_MIMETYPE_COMMON)
186
0
    {
187
0
        const OUString sToolkitName = Application::GetToolkitName();
188
0
        if (sToolkitName == "gtk4")
189
0
            xPlayer = createPlayer(rURL, u"com.sun.star.comp.avmedia.Manager_Gtk"_ustr);
190
0
        else if (sToolkitName.startsWith(u"kf6") || sToolkitName.startsWith(u"qt6"))
191
0
            xPlayer = createPlayer(rURL, u"com.sun.star.comp.avmedia.Manager_Qt"_ustr);
192
0
        else
193
0
            xPlayer = createPlayer(rURL, AVMEDIA_MANAGER_SERVICE_NAME);
194
0
    }
195
196
0
    return xPlayer;
197
0
}
198
199
uno::Reference< media::XPlayer > MediaWindowImpl::createPlayer(
200
    const OUString& rURL, const OUString& rManagerServName)
201
0
{
202
0
    uno::Reference< media::XPlayer > xPlayer;
203
0
    const uno::Reference<uno::XComponentContext>& xContext = ::comphelper::getProcessComponentContext();
204
0
    try
205
0
    {
206
0
        uno::Reference< media::XManager > xManager (
207
0
            xContext->getServiceManager()->createInstanceWithContext(rManagerServName, xContext),
208
0
            uno::UNO_QUERY );
209
0
        if( xManager.is() )
210
0
            xPlayer = xManager->createPlayer( rURL );
211
0
        else
212
0
            SAL_INFO( "avmedia", "failed to create media player service " << rManagerServName );
213
0
    } catch ( const uno::Exception & )
214
0
    {
215
0
        TOOLS_WARN_EXCEPTION( "avmedia", "couldn't create media player " << rManagerServName);
216
0
    }
217
0
    return xPlayer;
218
0
}
219
220
void MediaWindowImpl::setURL( const OUString& rURL,
221
        OUString const& rTempURL, OUString const& rReferer)
222
0
{
223
0
    maReferer = rReferer;
224
0
    if( rURL == getURL() )
225
0
        return;
226
227
0
    if( mxPlayer.is() )
228
0
        mxPlayer->stop();
229
230
0
    if( mxPlayerWindow.is() )
231
0
    {
232
0
        mxPlayerWindow->setVisible( false );
233
0
        mxPlayerWindow.clear();
234
0
    }
235
236
0
    mxPlayer.clear();
237
0
    mTempFileURL.clear();
238
239
0
    if (!rTempURL.isEmpty())
240
0
    {
241
0
        maFileURL = rURL;
242
0
        mTempFileURL = rTempURL;
243
0
    }
244
0
    else
245
0
    {
246
0
        INetURLObject aURL( rURL );
247
248
0
        if (aURL.GetProtocol() != INetProtocol::NotValid)
249
0
            maFileURL = aURL.GetMainURL(INetURLObject::DecodeMechanism::Unambiguous);
250
0
        else
251
0
            maFileURL = rURL;
252
0
    }
253
254
0
    OUString mediaURL;
255
    // If the file with the given URL does not exist and a fallback is specified, then use it
256
0
    if ( rURL.startsWith("file:///")
257
0
         && !comphelper::DirectoryHelper::fileExists(maFileURL)
258
0
         && maFallbackFileURL.getLength() > 0 )
259
0
    {
260
0
        mediaURL = maFallbackFileURL;
261
0
    }
262
0
    else
263
0
        mediaURL = (!mTempFileURL.isEmpty()) ? mTempFileURL : maFileURL;
264
265
0
    mxPlayer = createPlayer(mediaURL, rReferer, &m_sMimeType );
266
267
0
    onURLChanged();
268
0
}
269
270
const OUString& MediaWindowImpl::getURL() const
271
0
{
272
0
    return maFileURL;
273
0
}
274
275
void MediaWindowImpl::setFallbackURL( const OUString& rURL )
276
0
{
277
0
    maFallbackFileURL = rURL;
278
0
}
279
280
const OUString& MediaWindowImpl::getFallbackURL() const
281
0
{
282
0
    return maFallbackFileURL;
283
0
}
284
285
bool MediaWindowImpl::isValid() const
286
0
{
287
0
    return mxPlayer.is();
288
0
}
289
290
Size MediaWindowImpl::getPreferredSize() const
291
0
{
292
0
    Size aRet(480, 360);
293
294
0
    if( mxPlayer.is() )
295
0
    {
296
0
        awt::Size aPrefSize( mxPlayer->getPreferredPlayerWindowSize() );
297
298
0
        aRet.setWidth( aPrefSize.Width );
299
0
        aRet.setHeight( aPrefSize.Height );
300
0
    }
301
302
0
    return aRet;
303
0
}
304
305
bool MediaWindowImpl::start()
306
0
{
307
0
    return mxPlayer.is() && ( mxPlayer->start(), true );
308
0
}
309
310
void MediaWindowImpl::updateMediaItem( MediaItem& rItem ) const
311
0
{
312
0
    if( isPlaying() )
313
0
        rItem.setState( MediaState::Play );
314
0
    else
315
0
        rItem.setState( ( getMediaTime() == 0.0 ) ? MediaState::Stop : MediaState::Pause );
316
317
0
    rItem.setDuration( getDuration() );
318
0
    rItem.setTime( getMediaTime() );
319
0
    rItem.setLoop( mxPlayer.is() && mxPlayer->isPlaybackLoop() );
320
0
    rItem.setMute( mxPlayer.is() && mxPlayer->isMute() );
321
0
    rItem.setVolumeDB( mxPlayer.is() ? mxPlayer->getVolumeDB() : 0 );
322
0
    rItem.setZoom( mxPlayerWindow.is() ? mxPlayerWindow->getZoomLevel() : media::ZoomLevel_NOT_AVAILABLE );
323
0
    rItem.setFallbackURL( getFallbackURL() );
324
0
    rItem.setURL( getURL(), mTempFileURL, maReferer );
325
0
}
326
327
void MediaWindowImpl::executeMediaItem( const MediaItem& rItem )
328
0
{
329
0
    mpItem = &rItem;
330
0
    comphelper::ScopeGuard g([this] { this->mpItem = nullptr; });
331
332
0
    const AVMediaSetMask nMaskSet = rItem.getMaskSet();
333
334
    // set URL first
335
0
    if (nMaskSet & AVMediaSetMask::URL)
336
0
    {
337
0
        m_sMimeType = rItem.getMimeType();
338
0
        setFallbackURL(rItem.getFallbackURL());
339
0
        setURL(rItem.getURL(), rItem.getTempURL(), rItem.getReferer());
340
0
    }
341
342
    // set different states next
343
0
    if (nMaskSet & AVMediaSetMask::TIME)
344
0
        setMediaTime(std::min(rItem.getTime(), getDuration()));
345
346
0
    if (nMaskSet & AVMediaSetMask::LOOP && mxPlayer.is() )
347
0
        mxPlayer->setPlaybackLoop( rItem.isLoop() );
348
349
0
    if (nMaskSet & AVMediaSetMask::MUTE && mxPlayer.is() )
350
0
        mxPlayer->setMute( rItem.isMute() );
351
352
0
    if (nMaskSet & AVMediaSetMask::VOLUMEDB && mxPlayer.is() )
353
0
        mxPlayer->setVolumeDB( rItem.getVolumeDB() );
354
355
0
    if (nMaskSet & AVMediaSetMask::ZOOM && mxPlayerWindow.is() )
356
0
        mxPlayerWindow->setZoomLevel( rItem.getZoom() );
357
358
    // set play state at last
359
0
    if (!(nMaskSet & AVMediaSetMask::STATE))
360
0
        return;
361
362
0
    switch (rItem.getState())
363
0
    {
364
0
        case MediaState::Play:
365
0
        {
366
0
            if (!isPlaying())
367
0
                start();
368
0
        }
369
0
        break;
370
371
0
        case MediaState::Pause:
372
0
        {
373
0
            if (isPlaying())
374
0
                stop();
375
0
        }
376
0
        break;
377
378
0
        case MediaState::Stop:
379
0
        {
380
0
            if (isPlaying())
381
0
            {
382
0
                setMediaTime( 0.0 );
383
0
                stop();
384
0
                setMediaTime( 0.0 );
385
0
            }
386
0
        }
387
0
        break;
388
0
    }
389
0
}
390
391
void MediaWindowImpl::stop()
392
0
{
393
0
    if( mxPlayer.is() )
394
0
        mxPlayer->stop();
395
0
}
396
397
bool MediaWindowImpl::isPlaying() const
398
0
{
399
0
    return( mxPlayer.is() && mxPlayer->isPlaying() );
400
0
}
401
402
double MediaWindowImpl::getDuration() const
403
0
{
404
0
    return( mxPlayer.is() ? mxPlayer->getDuration() : 0.0 );
405
0
}
406
407
void MediaWindowImpl::setMediaTime( double fTime )
408
0
{
409
0
    if( mxPlayer.is() )
410
0
        mxPlayer->setMediaTime( fTime );
411
0
}
412
413
double MediaWindowImpl::getMediaTime() const
414
0
{
415
0
    return( mxPlayer.is() ? mxPlayer->getMediaTime() : 0.0 );
416
0
}
417
418
void MediaWindowImpl::stopPlayingInternal(bool bStop)
419
0
{
420
0
    if (isPlaying())
421
0
    {
422
0
        bStop ? mxPlayer->stop() : mxPlayer->start();
423
0
    }
424
0
}
425
426
void MediaWindowImpl::onURLChanged()
427
0
{
428
    //if (m_sMimeType == AVMEDIA_MIMETYPE_COMMON)
429
0
    {
430
0
        mpChildWindow.disposeAndClear();
431
0
        mpChildWindow.reset(VclPtr<MediaChildWindow>::Create(this));
432
0
    }
433
0
    if (!mpChildWindow)
434
0
        return;
435
0
    mpChildWindow->SetHelpId(HID_AVMEDIA_PLAYERWINDOW);
436
0
    mxEvents = new MediaEventListenersImpl(*mpChildWindow);
437
438
0
    if (mxPlayer.is())
439
0
    {
440
0
        Resize();
441
0
        uno::Reference<media::XPlayerWindow> xPlayerWindow;
442
0
        const Point aPoint;
443
0
        const Size aSize(mpChildWindow->GetSizePixel());
444
445
0
        sal_IntPtr nParentWindowHandle(0);
446
        // tdf#139609 gtk doesn't need the handle, and fetching it is undesirable
447
0
        if (Application::GetToolkit() != Toolkit::Gtk)
448
0
            nParentWindowHandle = mpChildWindow->GetParentWindowHandle();
449
0
        uno::Sequence<uno::Any> aArgs{
450
0
            uno::Any(nParentWindowHandle),
451
0
            uno::Any(awt::Rectangle(aPoint.X(), aPoint.Y(), aSize.Width(), aSize.Height())),
452
0
            uno::Any(reinterpret_cast<sal_IntPtr>(mpChildWindow.get())),
453
            // Media item contains media properties, e.g. cropping.
454
0
            uno::Any(reinterpret_cast<sal_IntPtr>(mpItem))
455
0
        };
456
457
0
        try
458
0
        {
459
0
            xPlayerWindow = mxPlayer->createPlayerWindow( aArgs );
460
0
        }
461
0
        catch( const uno::RuntimeException& )
462
0
        {
463
            // happens eg, on MacOSX where Java frames cannot be created from X11 window handles
464
0
        }
465
466
0
        mxPlayerWindow = xPlayerWindow;
467
468
0
        if( xPlayerWindow.is() )
469
0
        {
470
0
            xPlayerWindow->addKeyListener( uno::Reference< awt::XKeyListener >( mxEvents ) );
471
0
            xPlayerWindow->addMouseListener( uno::Reference< awt::XMouseListener >( mxEvents ) );
472
0
            xPlayerWindow->addMouseMotionListener( uno::Reference< awt::XMouseMotionListener >( mxEvents ) );
473
0
            xPlayerWindow->addFocusListener( uno::Reference< awt::XFocusListener >( mxEvents ) );
474
0
        }
475
0
    }
476
0
    else
477
0
        mxPlayerWindow.clear();
478
479
0
    if( mxPlayerWindow.is() )
480
0
        mpChildWindow->Show();
481
0
    else
482
0
        mpChildWindow->Hide();
483
484
0
    if( mpMediaWindowControl )
485
0
    {
486
0
        MediaItem aItem;
487
488
0
        updateMediaItem( aItem );
489
0
        mpMediaWindowControl->setState( aItem );
490
0
    }
491
0
}
492
493
void MediaWindowImpl::setPosSize(const tools::Rectangle& rRect)
494
0
{
495
0
    SetPosSizePixel(rRect.TopLeft(), rRect.GetSize());
496
0
}
497
498
void MediaWindowImpl::setPointer(PointerStyle aPointer)
499
0
{
500
0
    SetPointer(aPointer);
501
502
0
    if (mpChildWindow)
503
0
        mpChildWindow->SetPointer(aPointer);
504
505
0
    if (!mxPlayerWindow.is())
506
0
        return;
507
508
0
    sal_Int32 nPointer;
509
510
0
    switch (aPointer)
511
0
    {
512
0
        case PointerStyle::Cross:
513
0
            nPointer = awt::SystemPointer::CROSS;
514
0
            break;
515
0
        case PointerStyle::Hand:
516
0
            nPointer = awt::SystemPointer::HAND;
517
0
            break;
518
0
        case PointerStyle::Move:
519
0
            nPointer = awt::SystemPointer::MOVE;
520
0
            break;
521
0
        case PointerStyle::Wait:
522
0
            nPointer = awt::SystemPointer::WAIT;
523
0
            break;
524
0
        default:
525
0
            nPointer = awt::SystemPointer::ARROW;
526
0
            break;
527
0
    }
528
529
0
    mxPlayerWindow->setPointerType(nPointer);
530
0
}
531
532
void MediaWindowImpl::Resize()
533
0
{
534
0
    const Size aCurSize(GetOutputSizePixel());
535
0
    const sal_Int32 nOffset(mpMediaWindowControl ? AVMEDIA_CONTROLOFFSET : 0);
536
537
0
    Size aPlayerWindowSize(aCurSize.Width() - (nOffset << 1),
538
0
                           aCurSize.Height() - (nOffset << 1));
539
540
0
    if (mpMediaWindowControl)
541
0
    {
542
0
        const sal_Int32 nControlHeight = mpMediaWindowControl->GetSizePixel().Height();
543
0
        const sal_Int32 nControlY = std::max(aCurSize.Height() - nControlHeight - nOffset, tools::Long(0));
544
545
0
        aPlayerWindowSize.setHeight( nControlY - (nOffset << 1) );
546
0
        mpMediaWindowControl->SetPosSizePixel(Point(nOffset, nControlY ), Size(aCurSize.Width() - (nOffset << 1), nControlHeight));
547
0
    }
548
0
    if (mpChildWindow)
549
0
        mpChildWindow->SetPosSizePixel(Point(0, 0), aPlayerWindowSize);
550
551
0
    if (mxPlayerWindow.is())
552
0
        mxPlayerWindow->setPosSize(0, 0, aPlayerWindowSize.Width(), aPlayerWindowSize.Height(), 0);
553
0
}
554
555
void MediaWindowImpl::StateChanged(StateChangedType eType)
556
0
{
557
0
    if (!mxPlayerWindow.is())
558
0
        return;
559
560
    // stop playing when going disabled or hidden
561
0
    switch (eType)
562
0
    {
563
0
        case StateChangedType::Visible:
564
0
        {
565
0
            stopPlayingInternal(!IsVisible());
566
0
            mxPlayerWindow->setVisible(IsVisible());
567
0
        }
568
0
        break;
569
570
0
        case StateChangedType::Enable:
571
0
        {
572
0
            stopPlayingInternal(!IsEnabled());
573
0
            mxPlayerWindow->setEnable(IsEnabled());
574
0
        }
575
0
        break;
576
577
0
        default:
578
0
        break;
579
0
    }
580
0
}
581
582
void MediaWindowImpl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
583
0
{
584
0
    if (mxPlayerWindow.is())
585
0
        mxPlayerWindow->update();
586
587
0
    Bitmap* pLogo = nullptr;
588
589
0
    if (!mxPlayer.is())
590
0
    {
591
0
        if (maEmptyBmp.IsEmpty())
592
0
            maEmptyBmp = Bitmap(AVMEDIA_BMP_EMPTYLOGO);
593
594
0
        pLogo = &maEmptyBmp;
595
0
    }
596
0
    else if (!mxPlayerWindow.is())
597
0
    {
598
0
        if (maAudioBmp.IsEmpty())
599
0
            maAudioBmp = Bitmap(AVMEDIA_BMP_AUDIOLOGO);
600
601
0
        pLogo = &maAudioBmp;
602
0
    }
603
604
0
    if (!mpChildWindow)
605
0
        return;
606
607
0
    const Point aBasePos(mpChildWindow->GetPosPixel());
608
0
    const tools::Rectangle aVideoRect(aBasePos, mpChildWindow->GetSizePixel());
609
610
0
    if (!pLogo || pLogo->IsEmpty() || aVideoRect.IsEmpty())
611
0
        return;
612
613
0
    Size aLogoSize(pLogo->GetSizePixel());
614
0
    const Color aBackgroundColor(67, 67, 67);
615
616
0
    rRenderContext.SetLineColor(aBackgroundColor);
617
0
    rRenderContext.SetFillColor(aBackgroundColor);
618
0
    rRenderContext.DrawRect(aVideoRect);
619
620
0
    if ((aLogoSize.Width() > aVideoRect.GetWidth() || aLogoSize.Height() > aVideoRect.GetHeight() ) &&
621
0
        (aLogoSize.Height() > 0))
622
0
    {
623
0
        const double fLogoWH = double(aLogoSize.Width()) / aLogoSize.Height();
624
625
0
        if (fLogoWH < (double(aVideoRect.GetWidth()) / aVideoRect.GetHeight()))
626
0
        {
627
0
            aLogoSize.setWidth( tools::Long(aVideoRect.GetHeight() * fLogoWH) );
628
0
            aLogoSize.setHeight( aVideoRect.GetHeight() );
629
0
        }
630
0
        else
631
0
        {
632
0
            aLogoSize.setWidth( aVideoRect.GetWidth() );
633
0
            aLogoSize.setHeight( tools::Long(aVideoRect.GetWidth() / fLogoWH) );
634
0
        }
635
0
    }
636
637
0
    Point aPoint(aBasePos.X() + ((aVideoRect.GetWidth() - aLogoSize.Width()) >> 1),
638
0
                 aBasePos.Y() + ((aVideoRect.GetHeight() - aLogoSize.Height()) >> 1));
639
640
0
    rRenderContext.DrawBitmap(aPoint, aLogoSize, *pLogo);
641
0
}
642
643
void MediaWindowImpl::GetFocus()
644
0
{
645
0
}
646
647
void MediaWindowImpl::MouseMove(const MouseEvent& rMEvt)
648
0
{
649
0
    if (mpMediaWindow)
650
0
        mpMediaWindow->MouseMove(rMEvt);
651
0
}
652
653
void MediaWindowImpl::MouseButtonDown(const MouseEvent& rMEvt)
654
0
{
655
0
    if (mpMediaWindow)
656
0
        mpMediaWindow->MouseButtonDown(rMEvt);
657
0
}
658
659
void MediaWindowImpl::MouseButtonUp(const MouseEvent& rMEvt)
660
0
{
661
0
    if (mpMediaWindow)
662
0
        mpMediaWindow->MouseButtonUp(rMEvt);
663
0
}
664
665
void MediaWindowImpl::KeyInput(const KeyEvent& rKEvt)
666
0
{
667
0
    if (mpMediaWindow)
668
0
        mpMediaWindow->KeyInput(rKEvt);
669
0
}
670
671
void MediaWindowImpl::KeyUp(const KeyEvent& rKEvt)
672
0
{
673
0
    if (mpMediaWindow)
674
0
        mpMediaWindow->KeyUp(rKEvt);
675
0
}
676
677
void MediaWindowImpl::Command(const CommandEvent& rCEvt)
678
0
{
679
0
    if (mpMediaWindow)
680
0
        mpMediaWindow->Command(rCEvt);
681
0
}
682
683
sal_Int8 MediaWindowImpl::AcceptDrop(const AcceptDropEvent& rEvt)
684
0
{
685
0
    return (mpMediaWindow ? mpMediaWindow->AcceptDrop(rEvt) : 0);
686
0
}
687
688
sal_Int8 MediaWindowImpl::ExecuteDrop(const ExecuteDropEvent& rEvt)
689
0
{
690
0
    return (mpMediaWindow ? mpMediaWindow->ExecuteDrop(rEvt) : 0);
691
0
}
692
693
void MediaWindowImpl::StartDrag(sal_Int8 nAction, const Point& rPosPixel)
694
0
{
695
0
    if (mpMediaWindow)
696
0
        mpMediaWindow->StartDrag(nAction, rPosPixel);
697
0
}
698
699
} // namespace
700
701
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */