Coverage Report

Created: 2026-04-09 11:41

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