/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: */ |