Coverage Report

Created: 2026-10-14 09:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/avmedia/source/framework/mediacontrol.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 <mediacontrol.hxx>
21
#include <strings.hrc>
22
#include <mediamisc.hxx>
23
#include <avmedia/mediawindow.hxx>
24
#include <helpids.h>
25
#include <vcl/weld/Builder.hxx>
26
#include <avmedia/MediaControlBase.hxx>
27
28
#include <com/sun/star/media/ZoomLevel.hpp>
29
30
namespace avmedia
31
{
32
33
MediaControl::MediaControl( vcl::Window* pParent, MediaControlStyle eControlStyle ) :
34
    // MediaControlStyle::MultiLine is the normal docking windows of tools->media player
35
    // MediaControlStyle::SingleLine is the toolbar of view->toolbar->media playback
36
0
    InterimItemWindow(pParent, eControlStyle == MediaControlStyle::MultiLine ?
37
0
                                   u"svx/ui/mediawindow.ui"_ustr :
38
0
                                   u"svx/ui/medialine.ui"_ustr,
39
0
                               u"MediaWindow"_ustr),
40
0
    maIdle( "avmedia MediaControl Idle" ),
41
0
    maChangeTimeIdle( "avmedia MediaControl Change Time Idle" ),
42
0
    maItem( 0, AVMediaSetMask::ALL ),
43
0
    mbLocked( false ),
44
0
    meControlStyle( eControlStyle )
45
0
{
46
0
    mxPlayToolBox = m_xBuilder->weld_toolbar(u"playtoolbox"_ustr);
47
0
    mxTimeSlider = m_xBuilder->weld_scale(u"timeslider"_ustr);
48
0
    mxMuteToolBox = m_xBuilder->weld_toolbar(u"mutetoolbox"_ustr);
49
0
    mxVolumeSlider = m_xBuilder->weld_scale(u"volumeslider"_ustr);
50
0
    mxZoomListBox = m_xBuilder->weld_combo_box(u"zoombox"_ustr);
51
0
    mxTimeEdit = m_xBuilder->weld_entry(u"timeedit"_ustr);
52
0
    mxMediaPath = m_xBuilder->weld_label(u"url"_ustr);
53
54
0
    InitializeWidgets();
55
56
0
    mxPlayToolBox->connect_clicked( LINK( this, MediaControl, implSelectHdl ) );
57
58
0
    mxTimeSlider->connect_value_changed( LINK( this, MediaControl, implTimeHdl ) );
59
    // when changing the time, use this to do the time change after active scrolling
60
    // has stopped for a little which
61
0
    maChangeTimeIdle.SetPriority( TaskPriority::LOWEST );
62
0
    maChangeTimeIdle.SetInvokeHandler( LINK( this, MediaControl, implTimeEndHdl ) );
63
64
0
    mxTimeEdit->set_text(u" 00:00:00/00:00:00 "_ustr);
65
0
    Size aTextSize = mxTimeEdit->get_preferred_size();
66
0
    mxTimeEdit->set_size_request(aTextSize.Width(), aTextSize.Height());
67
0
    mxTimeEdit->set_text(OUString());
68
69
0
    mxMuteToolBox->connect_clicked( LINK( this, MediaControl, implSelectHdl ) );
70
0
    mxVolumeSlider->connect_value_changed( LINK( this, MediaControl, implVolumeHdl ) );
71
72
0
    mxZoomListBox->connect_changed( LINK( this, MediaControl, implZoomSelectHdl ) );
73
0
    mxZoomListBox->set_help_id(HID_AVMEDIA_ZOOMLISTBOX);
74
75
0
    const OUString aMediaPath( AvmResId( AVMEDIA_MEDIA_PATH_DEFAULT ) );
76
0
    mxMediaPath->set_label(aMediaPath);
77
0
    if (meControlStyle == MediaControlStyle::SingleLine)
78
0
        mxMediaPath->set_size_request(mxMediaPath->get_preferred_size().Width() + 400, -1); // maybe extend the no. 400 to span the screen width
79
80
    // we want time field + progress slider to update as the media plays
81
    // give this task a lower prio than REPAINT so that UI updates are not starved
82
0
    maIdle.SetPriority( TaskPriority::POST_PAINT );
83
0
    maIdle.SetInvokeHandler( LINK( this, MediaControl, implTimeoutHdl ) );
84
0
}
85
86
void MediaControl::InitializeWidgets()
87
0
{
88
0
    if( meControlStyle != MediaControlStyle::SingleLine )
89
0
    {
90
0
        mxPlayToolBox->set_item_help_id(u"open"_ustr, HID_AVMEDIA_TOOLBOXITEM_OPEN);
91
0
        mxPlayToolBox->set_item_help_id(u"apply"_ustr, HID_AVMEDIA_TOOLBOXITEM_INSERT);
92
0
    }
93
0
    avmedia::MediaControlBase::InitializeWidgets();
94
0
}
95
96
MediaControl::~MediaControl()
97
0
{
98
0
    disposeOnce();
99
0
}
100
101
void MediaControl::dispose()
102
0
{
103
0
    disposeWidgets();
104
0
    mxMediaPath.reset();
105
0
    InterimItemWindow::dispose();
106
0
}
107
108
void MediaControl::UpdateURLField(MediaItem const & tempItem)
109
0
{
110
0
    const OUString aURL( AvmResId(AVMEDIA_MEDIA_PATH) + ":  " + tempItem.getURL() ) ;
111
0
    mxMediaPath->set_label(aURL);
112
0
}
113
114
void MediaControl::setState( const MediaItem& rItem )
115
0
{
116
0
    if (mbLocked)
117
0
        return;
118
0
    bool bChanged = maItem.merge(rItem);
119
0
    if (bChanged)
120
0
    {
121
0
        if( rItem.getURL().isEmpty() && meControlStyle == MediaControlStyle::SingleLine )
122
0
            mxPlayToolBox->set_sensitive(false);
123
0
        UpdateToolBoxes( maItem );
124
0
        UpdateTimeSlider( maItem );
125
0
        UpdateVolumeSlider( maItem );
126
0
        UpdateTimeField( maItem, maItem.getTime() );
127
0
        UpdateURLField(maItem);
128
0
    }
129
0
}
130
131
IMPL_LINK( MediaControl, implTimeHdl, weld::Scale&, rSlider, void )
132
0
{
133
0
    mbLocked = true;
134
0
    maIdle.Stop();
135
0
    UpdateTimeField(maItem, rSlider.get_value() * maItem.getDuration() / AVMEDIA_TIME_RANGE);
136
0
    maChangeTimeIdle.Start();
137
0
}
138
139
IMPL_LINK_NOARG(MediaControl, implTimeEndHdl, Timer*, void)
140
0
{
141
0
    MediaItem aExecItem;
142
143
0
    aExecItem.setTime( mxTimeSlider->get_value() * maItem.getDuration() / AVMEDIA_TIME_RANGE );
144
    // keep state (if the media was playing, keep it playing)
145
0
    aExecItem.setState(maItem.getState());
146
0
    execute( aExecItem );
147
0
    update();
148
0
    maIdle.Start();
149
0
    mbLocked = false;
150
0
}
151
152
IMPL_LINK( MediaControl, implVolumeHdl, weld::Scale&, rSlider, void )
153
0
{
154
0
    MediaItem aExecItem;
155
156
0
    aExecItem.setVolumeDB(rSlider.get_value());
157
0
    execute( aExecItem );
158
0
    update();
159
0
}
160
161
IMPL_LINK( MediaControl, implSelectHdl, const OUString&, rIdent, void )
162
0
{
163
0
    MediaItem aExecItem;
164
0
    if (rIdent == "open")
165
0
    {
166
0
        OUString aURL;
167
0
        if (MediaWindow::executeMediaURLDialog(GetFrameWeld(), aURL, nullptr))
168
0
        {
169
0
            if( !MediaWindow::isMediaURL( aURL, u""_ustr/*TODO?*/, true ) )
170
0
                MediaWindow::executeFormatErrorBox(GetFrameWeld());
171
0
            else
172
0
            {
173
0
                aExecItem.setURL( aURL, u""_ustr, u""_ustr/*TODO?*/ );
174
0
                aExecItem.setState( MediaState::Play );
175
0
            }
176
0
        }
177
0
    }
178
0
    else
179
0
        SelectPlayToolBoxItem( aExecItem, maItem, rIdent );
180
181
0
    if (aExecItem.getState() == MediaState::Play)
182
0
        maIdle.Start();
183
0
    else if (aExecItem.getState() == MediaState::Pause ||
184
0
             aExecItem.getState() == MediaState::Stop)
185
0
        maIdle.Stop();
186
187
0
    if( aExecItem.getMaskSet() != AVMediaSetMask::NONE )
188
0
        execute( aExecItem );
189
190
0
    update();
191
0
}
192
193
IMPL_LINK( MediaControl, implZoomSelectHdl, weld::ComboBox&, rBox, void )
194
0
{
195
0
    bool bCurrentlySettingZoom = mbCurrentlySettingZoom;
196
0
    mbCurrentlySettingZoom = true;
197
198
0
    MediaItem aExecItem;
199
0
    css::media::ZoomLevel eLevel;
200
201
0
    switch (rBox.get_active())
202
0
    {
203
0
        case AVMEDIA_ZOOMLEVEL_50: eLevel = css::media::ZoomLevel_ZOOM_1_TO_2; break;
204
0
        case AVMEDIA_ZOOMLEVEL_100: eLevel = css::media::ZoomLevel_ORIGINAL; break;
205
0
        case AVMEDIA_ZOOMLEVEL_200: eLevel = css::media::ZoomLevel_ZOOM_2_TO_1; break;
206
0
        case AVMEDIA_ZOOMLEVEL_FIT: eLevel = css::media::ZoomLevel_FIT_TO_WINDOW_FIXED_ASPECT; break;
207
0
        case AVMEDIA_ZOOMLEVEL_SCALED: eLevel = css::media::ZoomLevel_FIT_TO_WINDOW; break;
208
209
0
        default: eLevel = css::media::ZoomLevel_NOT_AVAILABLE; break;
210
0
    }
211
212
0
    aExecItem.setZoom( eLevel );
213
0
    execute( aExecItem );
214
0
    update();
215
216
0
    mbCurrentlySettingZoom = bCurrentlySettingZoom;
217
0
}
218
219
IMPL_LINK_NOARG(MediaControl, implTimeoutHdl, Timer *, void)
220
0
{
221
0
    update();
222
0
    maIdle.Start();
223
0
}
224
225
} // namespace avmedia
226
227
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */