File: | /home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp |
Warning: | line 412, column 5 Potential leak of memory pointed to by 'audioGroup' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* ============================================================ | |||
2 | * | |||
3 | * This file is a part of digiKam project | |||
4 | * https://www.digikam.org | |||
5 | * | |||
6 | * Date : 2006-20-12 | |||
7 | * Description : a view to embed QtMultimedia media player. | |||
8 | * | |||
9 | * SPDX-FileCopyrightText: 2006-2025 by Gilles Caulier <caulier dot gilles at gmail dot com> | |||
10 | * | |||
11 | * SPDX-License-Identifier: GPL-2.0-or-later | |||
12 | * | |||
13 | * ============================================================ */ | |||
14 | ||||
15 | #include "mediaplayerview.h" | |||
16 | ||||
17 | // Qt includes | |||
18 | ||||
19 | #include <QApplication> | |||
20 | #include <QActionGroup> | |||
21 | #include <QVBoxLayout> | |||
22 | #include <QMouseEvent> | |||
23 | #include <QProxyStyle> | |||
24 | #include <QPushButton> | |||
25 | #include <QToolButton> | |||
26 | #include <QFileInfo> | |||
27 | #include <QToolBar> | |||
28 | #include <QAction> | |||
29 | #include <QSlider> | |||
30 | #include <QLabel> | |||
31 | #include <QFrame> | |||
32 | #include <QStyle> | |||
33 | #include <QMenu> | |||
34 | #include <QTransform> | |||
35 | #include <QGraphicsView> | |||
36 | #include <QGraphicsScene> | |||
37 | #include <QGraphicsVideoItem> | |||
38 | #include <QVideoSink> | |||
39 | #include <QVideoFrame> | |||
40 | #include <QAudioOutput> | |||
41 | #include <QAudioDevice> | |||
42 | #include <QMediaDevices> | |||
43 | #include <QMediaMetaData> | |||
44 | #include <QStandardPaths> | |||
45 | ||||
46 | // KDE includes | |||
47 | ||||
48 | #include <klocalizedstring.h> | |||
49 | #include <ksharedconfig.h> | |||
50 | #include <kconfiggroup.h> | |||
51 | ||||
52 | // Local includes | |||
53 | ||||
54 | #include "digikam_debug.h" | |||
55 | #include "digikam_globals.h" | |||
56 | #include "thememanager.h" | |||
57 | #include "stackedview.h" | |||
58 | #include "dlayoutbox.h" | |||
59 | #include "metaengine.h" | |||
60 | #include "dmetadata.h" | |||
61 | ||||
62 | namespace Digikam | |||
63 | { | |||
64 | ||||
65 | class Q_DECL_HIDDEN__attribute__((visibility("hidden"))) MediaPlayerMouseClickFilter : public QObject | |||
66 | { | |||
67 | Q_OBJECTpublic: clang diagnostic push
clang diagnostic ignored "-Winconsistent-missing-override" clang diagnostic ignored "-Wsuggest-override" static const QMetaObject staticMetaObject; virtual const QMetaObject *metaObject () const; virtual void *qt_metacast(const char *); virtual int qt_metacall(QMetaObject::Call, int, void **); static inline QString tr(const char *s, const char *c = nullptr, int n = -1) { return staticMetaObject.tr(s, c, n); } private: __attribute__((visibility ("hidden"))) static void qt_static_metacall(QObject *, QMetaObject ::Call, int, void **); clang diagnostic pop struct QPrivateSignal { explicit QPrivateSignal () = default; }; | |||
68 | ||||
69 | public: | |||
70 | ||||
71 | explicit MediaPlayerMouseClickFilter(QObject* const parent) | |||
72 | : QObject (parent), | |||
73 | m_parent(parent) | |||
74 | { | |||
75 | } | |||
76 | ||||
77 | protected: | |||
78 | ||||
79 | bool eventFilter(QObject* obj, QEvent* event) override | |||
80 | { | |||
81 | if ((event->type() == QEvent::MouseButtonPress) || (event->type() == QEvent::MouseButtonDblClick)) | |||
82 | { | |||
83 | bool singleClick = qApp(static_cast<QApplication *>(QCoreApplication::instance ()))->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick); | |||
84 | QMouseEvent* const mouseEvent = dynamic_cast<QMouseEvent*>(event); | |||
85 | ||||
86 | if (m_parent && mouseEvent) | |||
87 | { | |||
88 | MediaPlayerView* const mplayer = dynamic_cast<MediaPlayerView*>(m_parent); | |||
89 | ||||
90 | if (mplayer) | |||
91 | { | |||
92 | if ( | |||
93 | (mouseEvent->button() == Qt::LeftButton) && | |||
94 | ( | |||
95 | (singleClick && (event->type() == QEvent::MouseButtonPress)) || | |||
96 | (!singleClick && (event->type() == QEvent::MouseButtonDblClick)) | |||
97 | ) | |||
98 | ) | |||
99 | { | |||
100 | mplayer->slotEscapePressed(); | |||
101 | } | |||
102 | else if ( | |||
103 | (mouseEvent->button() == Qt::RightButton) && | |||
104 | (event->type() == QEvent::MouseButtonPress) | |||
105 | ) | |||
106 | { | |||
107 | mplayer->slotRotateVideo(); | |||
108 | } | |||
109 | ||||
110 | return true; | |||
111 | } | |||
112 | } | |||
113 | } | |||
114 | ||||
115 | return QObject::eventFilter(obj, event); | |||
116 | } | |||
117 | ||||
118 | private: | |||
119 | ||||
120 | QObject* m_parent = nullptr; | |||
121 | }; | |||
122 | ||||
123 | // -------------------------------------------------------- | |||
124 | ||||
125 | class Q_DECL_HIDDEN__attribute__((visibility("hidden"))) PlayerVideoStyle : public QProxyStyle | |||
126 | { | |||
127 | Q_OBJECTpublic: clang diagnostic push
clang diagnostic ignored "-Winconsistent-missing-override" clang diagnostic ignored "-Wsuggest-override" static const QMetaObject staticMetaObject; virtual const QMetaObject *metaObject () const; virtual void *qt_metacast(const char *); virtual int qt_metacall(QMetaObject::Call, int, void **); static inline QString tr(const char *s, const char *c = nullptr, int n = -1) { return staticMetaObject.tr(s, c, n); } private: __attribute__((visibility ("hidden"))) static void qt_static_metacall(QObject *, QMetaObject ::Call, int, void **); clang diagnostic pop struct QPrivateSignal { explicit QPrivateSignal () = default; }; | |||
128 | ||||
129 | public: | |||
130 | ||||
131 | using QProxyStyle::QProxyStyle; | |||
132 | ||||
133 | int styleHint(QStyle::StyleHint hint, | |||
134 | const QStyleOption* option = nullptr, | |||
135 | const QWidget* widget = nullptr, | |||
136 | QStyleHintReturn* returnData = nullptr) const override | |||
137 | { | |||
138 | if (hint == QStyle::SH_Slider_AbsoluteSetButtons) | |||
139 | { | |||
140 | return (Qt::LeftButton | Qt::MiddleButton | Qt::RightButton); | |||
141 | } | |||
142 | ||||
143 | return QProxyStyle::styleHint(hint, option, widget, returnData); | |||
144 | } | |||
145 | }; | |||
146 | ||||
147 | // -------------------------------------------------------- | |||
148 | ||||
149 | class MediaPlayerView::Private | |||
150 | { | |||
151 | ||||
152 | public: | |||
153 | ||||
154 | enum MediaPlayerViewMode | |||
155 | { | |||
156 | ErrorView = 0, | |||
157 | PlayerView | |||
158 | }; | |||
159 | ||||
160 | public: | |||
161 | ||||
162 | Private() = default; | |||
163 | ||||
164 | QFrame* errorView = nullptr; | |||
165 | QFrame* playerView = nullptr; | |||
166 | ||||
167 | QAction* prevAction = nullptr; | |||
168 | QAction* nextAction = nullptr; | |||
169 | QAction* playAction = nullptr; | |||
170 | QAction* grabAction = nullptr; | |||
171 | QAction* backAction = nullptr; | |||
172 | QAction* forwAction = nullptr; | |||
173 | ||||
174 | QToolButton* rateButton = nullptr; | |||
175 | ||||
176 | QPushButton* loopPlay = nullptr; | |||
177 | QPushButton* speaker = nullptr; | |||
178 | ||||
179 | QToolBar* toolBar = nullptr; | |||
180 | ||||
181 | DInfoInterface* iface = nullptr; | |||
182 | ||||
183 | QGraphicsScene* videoScene = nullptr; | |||
184 | QGraphicsView* videoView = nullptr; | |||
185 | QGraphicsVideoItem* videoItem = nullptr; | |||
186 | QMediaPlayer* player = nullptr; | |||
187 | QAudioOutput* audio = nullptr; | |||
188 | ||||
189 | QSlider* slider = nullptr; | |||
190 | QSlider* volume = nullptr; | |||
191 | QLabel* tlabel = nullptr; | |||
192 | ||||
193 | QUrl currentItem; | |||
194 | ||||
195 | int videoOrientation = 0; | |||
196 | qint64 sliderTime = 0; | |||
197 | ||||
198 | const QUrl dummyVideo = QUrl::fromLocalFile( | |||
199 | QStandardPaths::locate( | |||
200 | QStandardPaths::GenericDataLocation, | |||
201 | QLatin1String("digikam/data/video-digikam.mp4"))); | |||
202 | ||||
203 | public: | |||
204 | ||||
205 | void adjustVideoSize() | |||
206 | { | |||
207 | videoItem->resetTransform(); | |||
208 | ||||
209 | QSizeF nativeSize = videoItem->nativeSize(); | |||
210 | int mediaOrientation = videoMediaOrientation(); | |||
211 | ||||
212 | if ( | |||
213 | (nativeSize.width() < 1.0) || | |||
214 | (nativeSize.height() < 1.0) | |||
215 | ) | |||
216 | { | |||
217 | return; | |||
218 | } | |||
219 | ||||
220 | if ( | |||
221 | (mediaOrientation == 90) || | |||
222 | (mediaOrientation == 270) | |||
223 | ) | |||
224 | { | |||
225 | nativeSize.transpose(); | |||
226 | } | |||
227 | ||||
228 | double ratio = (nativeSize.width() / | |||
229 | nativeSize.height()); | |||
230 | ||||
231 | if (videoView->width() > videoView->height()) | |||
232 | { | |||
233 | QSizeF vsize(videoView->height() * ratio, | |||
234 | videoView->height()); | |||
235 | videoItem->setSize(vsize); | |||
236 | } | |||
237 | else | |||
238 | { | |||
239 | QSizeF vsize(videoView->width(), | |||
240 | videoView->width() / ratio); | |||
241 | videoItem->setSize(vsize); | |||
242 | } | |||
243 | ||||
244 | videoView->setSceneRect(0, 0, videoItem->size().width(), | |||
245 | videoItem->size().height()); | |||
246 | ||||
247 | QPointF center = videoItem->boundingRect().center(); | |||
248 | videoItem->setTransformOriginPoint(center); | |||
249 | videoItem->setRotation(videoOrientation); | |||
250 | ||||
251 | videoView->fitInView(videoItem, Qt::KeepAspectRatio); | |||
252 | videoView->centerOn(videoItem); | |||
253 | videoView->raise(); | |||
254 | }; | |||
255 | ||||
256 | int videoMediaOrientation() const | |||
257 | { | |||
258 | int orientation = 0; | |||
259 | QVariant val = player->metaData().value(QMediaMetaData::Orientation); | |||
260 | ||||
261 | if (!val.isNull()) | |||
262 | { | |||
263 | orientation = val.toInt(); | |||
264 | } | |||
265 | ||||
266 | return orientation; | |||
267 | }; | |||
268 | ||||
269 | void setVideoItemOrientation(int orientation) | |||
270 | { | |||
271 | videoOrientation = orientation; | |||
272 | adjustVideoSize(); | |||
273 | }; | |||
274 | }; | |||
275 | ||||
276 | MediaPlayerView::MediaPlayerView(QWidget* const parent) | |||
277 | : QStackedWidget(parent), | |||
278 | d (new Private) | |||
279 | { | |||
280 | setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | |||
281 | ||||
282 | const int spacing = layoutSpacing(); | |||
283 | ||||
284 | ||||
285 | d->prevAction = new QAction(QIcon::fromTheme(QLatin1String("go-previous")), | |||
286 | i18nc("go to previous image", "Back")i18ndc("digikam", "go to previous image", "Back"), this); | |||
287 | d->nextAction = new QAction(QIcon::fromTheme(QLatin1String("go-next")), | |||
288 | i18nc("go to next image", "Forward")i18ndc("digikam", "go to next image", "Forward"), this); | |||
289 | d->backAction = new QAction(QIcon::fromTheme(QLatin1String("media-seek-backward")), | |||
290 | i18nc("video frame backward", "Frame Backward")i18ndc("digikam", "video frame backward", "Frame Backward"), this); | |||
291 | d->playAction = new QAction(QIcon::fromTheme(QLatin1String("media-playback-start")), | |||
292 | i18nc("pause/play video", "Pause/Play")i18ndc("digikam", "pause/play video", "Pause/Play"), this); | |||
293 | d->forwAction = new QAction(QIcon::fromTheme(QLatin1String("media-seek-forward")), | |||
294 | i18nc("video frame forward", "Frame Forward")i18ndc("digikam", "video frame forward", "Frame Forward"), this); | |||
295 | d->grabAction = new QAction(QIcon::fromTheme(QLatin1String("view-preview")), | |||
296 | i18nc("capture video frame", "Capture")i18ndc("digikam", "capture video frame", "Capture"), this); | |||
297 | ||||
298 | d->rateButton = new QToolButton(this); | |||
299 | d->rateButton->setToolTip(i18nc("@info", "Change video playback rate")i18ndc("digikam", "@info", "Change video playback rate")); | |||
300 | d->rateButton->setIcon(QIcon::fromTheme(QLatin1String("player-time"))); | |||
301 | d->rateButton->setPopupMode(QToolButton::InstantPopup); | |||
302 | d->rateButton->setArrowType(Qt::NoArrow); | |||
303 | ||||
304 | QMenu* const rateMenu = new QMenu(this); | |||
305 | QActionGroup* const rateGroup = new QActionGroup(this); | |||
306 | ||||
307 | QAction* const rate05 = rateGroup->addAction(i18nc("video play rate", "0.5x")i18ndc("digikam", "video play rate", "0.5x")); | |||
308 | rate05->setCheckable(true); | |||
309 | rate05->setData(0.5); | |||
310 | QAction* const rate10 = rateGroup->addAction(i18nc("video play rate", "1.0x")i18ndc("digikam", "video play rate", "1.0x")); | |||
311 | rate10->setCheckable(true); | |||
312 | rate10->setData(1.0); | |||
313 | QAction* const rate15 = rateGroup->addAction(i18nc("video play rate", "1.5x")i18ndc("digikam", "video play rate", "1.5x")); | |||
314 | rate15->setCheckable(true); | |||
315 | rate15->setData(1.5); | |||
316 | QAction* const rate20 = rateGroup->addAction(i18nc("video play rate", "2.0x")i18ndc("digikam", "video play rate", "2.0x")); | |||
317 | rate20->setCheckable(true); | |||
318 | rate20->setData(2.0); | |||
319 | QAction* const rate25 = rateGroup->addAction(i18nc("video play rate", "2.5x")i18ndc("digikam", "video play rate", "2.5x")); | |||
320 | rate25->setCheckable(true); | |||
321 | rate25->setData(2.5); | |||
322 | QAction* const rate30 = rateGroup->addAction(i18nc("video play rate", "3.0x")i18ndc("digikam", "video play rate", "3.0x")); | |||
323 | rate30->setCheckable(true); | |||
324 | rate30->setData(3.0); | |||
325 | QAction* const rate40 = rateGroup->addAction(i18nc("video play rate", "4.0x")i18ndc("digikam", "video play rate", "4.0x")); | |||
326 | rate40->setCheckable(true); | |||
327 | rate40->setData(4.0); | |||
328 | QAction* const rate50 = rateGroup->addAction(i18nc("video play rate", "5.0x")i18ndc("digikam", "video play rate", "5.0x")); | |||
329 | rate50->setCheckable(true); | |||
330 | rate50->setData(5.0); | |||
331 | ||||
332 | rate10->setChecked(true); | |||
333 | ||||
334 | rateMenu->addAction(rate05); | |||
335 | rateMenu->addAction(rate10); | |||
336 | rateMenu->addAction(rate15); | |||
337 | rateMenu->addAction(rate20); | |||
338 | rateMenu->addAction(rate25); | |||
339 | rateMenu->addAction(rate30); | |||
340 | rateMenu->addAction(rate40); | |||
341 | rateMenu->addAction(rate50); | |||
342 | d->rateButton->setMenu(rateMenu); | |||
343 | ||||
344 | d->errorView = new QFrame(this); | |||
345 | QLabel* const errorMsg = new QLabel(i18n("An error has occurred with the media player...")i18nd("digikam", "An error has occurred with the media player..." ), this); | |||
346 | ||||
347 | errorMsg->setAlignment(Qt::AlignCenter); | |||
348 | d->errorView->setFrameStyle(QFrame::StyledPanel | QFrame::Plain); | |||
349 | d->errorView->setLineWidth(1); | |||
350 | ||||
351 | QVBoxLayout* const vbox1 = new QVBoxLayout(d->errorView); | |||
352 | vbox1->addWidget(errorMsg, 10); | |||
353 | vbox1->setContentsMargins(QMargins()); | |||
354 | vbox1->setSpacing(spacing); | |||
355 | ||||
356 | insertWidget(Private::ErrorView, d->errorView); | |||
357 | ||||
358 | // -------------------------------------------------------------------------- | |||
359 | ||||
360 | d->playerView = new QFrame(this); | |||
361 | d->videoScene = new QGraphicsScene(this); | |||
362 | d->videoView = new QGraphicsView(d->videoScene); | |||
363 | d->videoView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); | |||
364 | d->videoView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); | |||
365 | d->videoView->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); | |||
366 | d->videoView->setFrameShape(QFrame::NoFrame); | |||
367 | d->videoItem = new QGraphicsVideoItem(); | |||
368 | d->player = new QMediaPlayer(this); | |||
369 | d->audio = new QAudioOutput; | |||
370 | d->player->setAudioOutput(d->audio); | |||
371 | d->player->setVideoOutput(d->videoItem); | |||
372 | d->videoScene->addItem(d->videoItem); | |||
373 | ||||
374 | d->playerView->setFrameStyle(QFrame::StyledPanel | QFrame::Plain); | |||
375 | d->playerView->setLineWidth(1); | |||
376 | ||||
377 | d->videoItem->setAspectRatioMode(Qt::IgnoreAspectRatio); | |||
378 | d->videoView->setMouseTracking(true); | |||
379 | ||||
380 | DHBox* const hbox = new DHBox(this); | |||
381 | d->slider = new QSlider(Qt::Horizontal, hbox); | |||
382 | d->slider->setStyle(new PlayerVideoStyle()); | |||
383 | d->slider->setRange(0, 0); | |||
384 | d->tlabel = new QLabel(hbox); | |||
385 | d->tlabel->setText(QLatin1String("00:00:00 / 00:00:00")); | |||
386 | d->loopPlay = new QPushButton(hbox); | |||
387 | d->loopPlay->setIcon(QIcon::fromTheme(QLatin1String("media-playlist-normal"))); | |||
388 | d->loopPlay->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); | |||
389 | d->loopPlay->setToolTip(i18n("Toggle playing in a loop")i18nd("digikam", "Toggle playing in a loop")); | |||
390 | d->loopPlay->setFocusPolicy(Qt::NoFocus); | |||
391 | d->loopPlay->setMinimumSize(22, 22); | |||
392 | d->loopPlay->setCheckable(true); | |||
393 | ||||
394 | d->speaker = new QPushButton(hbox); | |||
395 | d->speaker->setIcon(QIcon::fromTheme(QLatin1String("audio-volume-high"))); | |||
396 | d->speaker->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); | |||
397 | d->speaker->setFocusPolicy(Qt::NoFocus); | |||
398 | d->speaker->setMinimumSize(22, 22); | |||
399 | ||||
400 | QMenu* const audioMenu = new QMenu(this); | |||
401 | QActionGroup* const audioGroup = new QActionGroup(this); | |||
| ||||
402 | ||||
403 | for (const auto& device : QMediaDevices::audioOutputs()) | |||
404 | { | |||
405 | QAction* const action = audioGroup->addAction(device.description()); | |||
406 | action->setCheckable(true); | |||
407 | action->setData(device.id()); | |||
408 | action->setChecked(device.isDefault()); | |||
409 | audioMenu->addAction(action); | |||
410 | } | |||
411 | ||||
412 | d->speaker->setMenu(audioMenu); | |||
| ||||
413 | ||||
414 | d->volume = new QSlider(Qt::Horizontal, hbox); | |||
415 | d->volume->setRange(0, 100); | |||
416 | d->volume->setValue(50); | |||
417 | ||||
418 | hbox->setStretchFactor(d->slider, 10); | |||
419 | hbox->setContentsMargins(0, 0, 0, spacing); | |||
420 | hbox->setSpacing(spacing); | |||
421 | ||||
422 | QVBoxLayout* const vbox2 = new QVBoxLayout(d->playerView); | |||
423 | vbox2->addWidget(d->videoView, 10); | |||
424 | vbox2->addWidget(hbox, 0); | |||
425 | vbox2->setContentsMargins(QMargins()); | |||
426 | vbox2->setSpacing(spacing); | |||
427 | ||||
428 | insertWidget(Private::PlayerView, d->playerView); | |||
429 | ||||
430 | d->toolBar = new QToolBar(this); | |||
431 | d->toolBar->addAction(d->prevAction); | |||
432 | d->toolBar->addAction(d->nextAction); | |||
433 | d->toolBar->addAction(d->backAction); | |||
434 | d->toolBar->addAction(d->playAction); | |||
435 | d->toolBar->addAction(d->forwAction); | |||
436 | d->toolBar->addWidget(d->rateButton); | |||
437 | d->toolBar->addAction(d->grabAction); | |||
438 | d->toolBar->setStyleSheet(toolButtonStyleSheet()); | |||
439 | ||||
440 | setPreviewMode(Private::PlayerView); | |||
441 | ||||
442 | d->errorView->installEventFilter(new MediaPlayerMouseClickFilter(this)); | |||
443 | d->videoView->installEventFilter(new MediaPlayerMouseClickFilter(this)); | |||
444 | d->playerView->installEventFilter(this); | |||
445 | ||||
446 | KSharedConfig::Ptr config = KSharedConfig::openConfig(); | |||
447 | KConfigGroup group = config->group(QLatin1String("Media Player Settings")); | |||
448 | int volume = group.readEntry("Volume", 50); | |||
449 | ||||
450 | d->volume->setValue(volume); | |||
451 | d->audio->setVolume(volume / 100.0F); | |||
452 | ||||
453 | // -------------------------------------------------------------------------- | |||
454 | ||||
455 | connect(ThemeManager::instance(), SIGNAL(signalThemeChanged())qFlagLocation("2" "signalThemeChanged()" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "455"), | |||
456 | this, SLOT(slotThemeChanged())qFlagLocation("1" "slotThemeChanged()" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "456")); | |||
457 | ||||
458 | connect(d->prevAction, SIGNAL(triggered())qFlagLocation("2" "triggered()" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "458"), | |||
459 | this, SIGNAL(signalPrevItem())qFlagLocation("2" "signalPrevItem()" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "459")); | |||
460 | ||||
461 | connect(d->nextAction, SIGNAL(triggered())qFlagLocation("2" "triggered()" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "461"), | |||
462 | this, SIGNAL(signalNextItem())qFlagLocation("2" "signalNextItem()" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "462")); | |||
463 | ||||
464 | connect(d->backAction, SIGNAL(triggered())qFlagLocation("2" "triggered()" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "464"), | |||
465 | this, SLOT(slotFrameBackward())qFlagLocation("1" "slotFrameBackward()" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "465")); | |||
466 | ||||
467 | connect(d->playAction, SIGNAL(triggered())qFlagLocation("2" "triggered()" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "467"), | |||
468 | this, SLOT(slotPausePlay())qFlagLocation("1" "slotPausePlay()" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "468")); | |||
469 | ||||
470 | connect(d->forwAction, SIGNAL(triggered())qFlagLocation("2" "triggered()" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "470"), | |||
471 | this, SLOT(slotFrameForward())qFlagLocation("1" "slotFrameForward()" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "471")); | |||
472 | ||||
473 | connect(d->grabAction, SIGNAL(triggered())qFlagLocation("2" "triggered()" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "473"), | |||
474 | this, SLOT(slotCapture())qFlagLocation("1" "slotCapture()" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "474")); | |||
475 | ||||
476 | connect(d->slider, SIGNAL(sliderMoved(int))qFlagLocation("2" "sliderMoved(int)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "476"), | |||
477 | this, SLOT(slotPosition(int))qFlagLocation("1" "slotPosition(int)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "477")); | |||
478 | ||||
479 | connect(d->slider, SIGNAL(valueChanged(int))qFlagLocation("2" "valueChanged(int)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "479"), | |||
480 | this, SLOT(slotPosition(int))qFlagLocation("1" "slotPosition(int)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "480")); | |||
481 | ||||
482 | connect(d->volume, SIGNAL(valueChanged(int))qFlagLocation("2" "valueChanged(int)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "482"), | |||
483 | this, SLOT(slotVolumeChanged(int))qFlagLocation("1" "slotVolumeChanged(int)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "483")); | |||
484 | ||||
485 | connect(d->loopPlay, SIGNAL(toggled(bool))qFlagLocation("2" "toggled(bool)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "485"), | |||
486 | this, SLOT(slotLoopToggled(bool))qFlagLocation("1" "slotLoopToggled(bool)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "486")); | |||
487 | ||||
488 | connect(d->player, SIGNAL(playbackStateChanged(QMediaPlayer::PlaybackState))qFlagLocation("2" "playbackStateChanged(QMediaPlayer::PlaybackState)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "488"), | |||
489 | this, SLOT(slotPlayerStateChanged(QMediaPlayer::PlaybackState))qFlagLocation("1" "slotPlayerStateChanged(QMediaPlayer::PlaybackState)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "489")); | |||
490 | ||||
491 | connect(d->player, SIGNAL(positionChanged(qint64))qFlagLocation("2" "positionChanged(qint64)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "491"), | |||
492 | this, SLOT(slotPositionChanged(qint64))qFlagLocation("1" "slotPositionChanged(qint64)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "492")); | |||
493 | ||||
494 | connect(d->player, SIGNAL(durationChanged(qint64))qFlagLocation("2" "durationChanged(qint64)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "494"), | |||
495 | this, SLOT(slotDurationChanged(qint64))qFlagLocation("1" "slotDurationChanged(qint64)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "495")); | |||
496 | ||||
497 | connect(d->player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus))qFlagLocation("2" "mediaStatusChanged(QMediaPlayer::MediaStatus)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "497"), | |||
498 | this, SLOT(slotMediaStatusChanged(QMediaPlayer::MediaStatus))qFlagLocation("1" "slotMediaStatusChanged(QMediaPlayer::MediaStatus)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "498")); | |||
499 | ||||
500 | connect(d->player, SIGNAL(errorOccurred(QMediaPlayer::Error,QString))qFlagLocation("2" "errorOccurred(QMediaPlayer::Error,QString)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "500"), | |||
501 | this, SLOT(slotHandlePlayerError(QMediaPlayer::Error,QString))qFlagLocation("1" "slotHandlePlayerError(QMediaPlayer::Error,QString)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "501")); | |||
502 | ||||
503 | connect(d->videoItem, SIGNAL(nativeSizeChanged(QSizeF))qFlagLocation("2" "nativeSizeChanged(QSizeF)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "503"), | |||
504 | this, SLOT(slotNativeSizeChanged())qFlagLocation("1" "slotNativeSizeChanged()" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "504")); | |||
505 | ||||
506 | connect(rateMenu, SIGNAL(triggered(QAction*))qFlagLocation("2" "triggered(QAction*)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "506"), | |||
507 | this, SLOT(slotPlaybackRate(QAction*))qFlagLocation("1" "slotPlaybackRate(QAction*)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "507")); | |||
508 | ||||
509 | connect(audioMenu, SIGNAL(triggered(QAction*))qFlagLocation("2" "triggered(QAction*)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "509"), | |||
510 | this, SLOT(slotAudioChanged(QAction*))qFlagLocation("1" "slotAudioChanged(QAction*)" "\0" "/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ":" "510")); | |||
511 | } | |||
512 | ||||
513 | MediaPlayerView::~MediaPlayerView() | |||
514 | { | |||
515 | escapePreview(); | |||
516 | ||||
517 | delete d; | |||
518 | } | |||
519 | ||||
520 | void MediaPlayerView::setInfoInterface(DInfoInterface* const iface) | |||
521 | { | |||
522 | d->iface = iface; | |||
523 | } | |||
524 | ||||
525 | void MediaPlayerView::reload() | |||
526 | { | |||
527 | d->player->stop(); | |||
528 | d->player->setSource(d->currentItem); | |||
529 | d->player->play(); | |||
530 | } | |||
531 | ||||
532 | void MediaPlayerView::slotPlayerStateChanged(QMediaPlayer::PlaybackState newState) | |||
533 | { | |||
534 | if (newState == QMediaPlayer::PlayingState) | |||
535 | { | |||
536 | d->playAction->setIcon(QIcon::fromTheme(QLatin1String("media-playback-pause"))); | |||
537 | ||||
538 | d->backAction->setEnabled(true); | |||
539 | d->forwAction->setEnabled(true); | |||
540 | } | |||
541 | else | |||
542 | { | |||
543 | d->playAction->setIcon(QIcon::fromTheme(QLatin1String("media-playback-start"))); | |||
544 | ||||
545 | if ( | |||
546 | (newState == QMediaPlayer::StoppedState) || | |||
547 | (d->player->mediaStatus() == QMediaPlayer::EndOfMedia) | |||
548 | ) | |||
549 | { | |||
550 | qCDebug(DIGIKAM_GENERAL_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_GENERAL_LOG)()); qt_category; qt_category.control = false) QMessageLogger(static_cast<const char *>("/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ), 550, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Play video with QtMultimedia completed:" << d->player->source(); | |||
551 | ||||
552 | if (d->player->error() != QMediaPlayer::NoError) | |||
553 | { | |||
554 | setPreviewMode(Private::ErrorView); | |||
555 | } | |||
556 | ||||
557 | d->backAction->setEnabled(false); | |||
558 | d->forwAction->setEnabled(false); | |||
559 | } | |||
560 | } | |||
561 | } | |||
562 | ||||
563 | void MediaPlayerView::slotMediaStatusChanged(QMediaPlayer::MediaStatus newStatus) | |||
564 | { | |||
565 | if (newStatus == QMediaPlayer::LoadedMedia) | |||
566 | { | |||
567 | int rotate = d->videoMediaOrientation(); | |||
568 | ||||
569 | qCDebug(DIGIKAM_GENERAL_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_GENERAL_LOG)()); qt_category; qt_category.control = false) QMessageLogger(static_cast<const char *>("/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ), 569, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Found video orientation with QtMultimedia:" | |||
570 | << rotate; | |||
571 | ||||
572 | rotate = (-rotate) + d->videoOrientation; | |||
573 | ||||
574 | if ((rotate > 270) || (rotate < 0)) | |||
575 | { | |||
576 | rotate = d->videoOrientation; | |||
577 | } | |||
578 | ||||
579 | d->setVideoItemOrientation(rotate); | |||
580 | } | |||
581 | else if (newStatus == QMediaPlayer::InvalidMedia) | |||
582 | { | |||
583 | setPreviewMode(Private::ErrorView); | |||
584 | } | |||
585 | } | |||
586 | ||||
587 | void MediaPlayerView::escapePreview() | |||
588 | { | |||
589 | d->player->stop(); | |||
590 | d->player->setSource(d->dummyVideo); | |||
591 | } | |||
592 | ||||
593 | void MediaPlayerView::slotThemeChanged() | |||
594 | { | |||
595 | QPalette palette; | |||
596 | palette.setColor(d->errorView->backgroundRole(), qApp(static_cast<QApplication *>(QCoreApplication::instance ()))->palette().color(QPalette::Base)); | |||
597 | d->errorView->setPalette(palette); | |||
598 | ||||
599 | QPalette palette2; | |||
600 | palette2.setColor(d->playerView->backgroundRole(), qApp(static_cast<QApplication *>(QCoreApplication::instance ()))->palette().color(QPalette::Base)); | |||
601 | d->playerView->setPalette(palette2); | |||
602 | } | |||
603 | ||||
604 | void MediaPlayerView::slotEscapePressed() | |||
605 | { | |||
606 | Q_EMIT signalEscapePreview(); | |||
607 | } | |||
608 | ||||
609 | void MediaPlayerView::slotRotateVideo() | |||
610 | { | |||
611 | if (d->player->playbackState() != QMediaPlayer::StoppedState) | |||
612 | { | |||
613 | int orientation = 0; | |||
614 | ||||
615 | switch (d->videoOrientation) | |||
616 | { | |||
617 | case 0: | |||
618 | { | |||
619 | orientation = 90; | |||
620 | break; | |||
621 | } | |||
622 | ||||
623 | case 90: | |||
624 | { | |||
625 | orientation = 180; | |||
626 | break; | |||
627 | } | |||
628 | ||||
629 | case 180: | |||
630 | { | |||
631 | orientation = 270; | |||
632 | break; | |||
633 | } | |||
634 | ||||
635 | default: | |||
636 | { | |||
637 | orientation = 0; | |||
638 | break; | |||
639 | } | |||
640 | } | |||
641 | ||||
642 | d->setVideoItemOrientation(orientation); | |||
643 | } | |||
644 | } | |||
645 | ||||
646 | void MediaPlayerView::slotPausePlay() | |||
647 | { | |||
648 | if (!d->player->isPlaying()) | |||
649 | { | |||
650 | d->player->play(); | |||
651 | ||||
652 | return; | |||
653 | } | |||
654 | ||||
655 | d->player->pause(); | |||
656 | } | |||
657 | ||||
658 | void MediaPlayerView::slotFrameBackward() | |||
659 | { | |||
660 | if (d->player->isPlaying()) | |||
661 | { | |||
662 | d->player->pause(); | |||
663 | ||||
664 | return; | |||
665 | } | |||
666 | ||||
667 | QVariant frameRateVar = d->player->metaData().value(QMediaMetaData::VideoFrameRate); | |||
668 | ||||
669 | if (frameRateVar.isValid()) | |||
670 | { | |||
671 | double frameRate = frameRateVar.toDouble(); | |||
672 | ||||
673 | if (frameRate > 0.0) | |||
674 | { | |||
675 | double frame = 1000.0 / frameRate; | |||
676 | d->player->setPosition(d->player->position() - frame); | |||
677 | } | |||
678 | } | |||
679 | } | |||
680 | ||||
681 | void MediaPlayerView::slotFrameForward() | |||
682 | { | |||
683 | if (d->player->isPlaying()) | |||
684 | { | |||
685 | d->player->pause(); | |||
686 | ||||
687 | return; | |||
688 | } | |||
689 | ||||
690 | QVariant frameRateVar = d->player->metaData().value(QMediaMetaData::VideoFrameRate); | |||
691 | ||||
692 | if (frameRateVar.isValid()) | |||
693 | { | |||
694 | double frameRate = frameRateVar.toDouble(); | |||
695 | ||||
696 | if (frameRate > 0.0) | |||
697 | { | |||
698 | double frame = 1000.0 / frameRate; | |||
699 | d->player->setPosition(d->player->position() + frame); | |||
700 | } | |||
701 | } | |||
702 | } | |||
703 | ||||
704 | void MediaPlayerView::slotCapture() | |||
705 | { | |||
706 | if (d->player->playbackState() != QMediaPlayer::StoppedState) | |||
707 | { | |||
708 | int capturePosition = d->player->position(); | |||
709 | QVideoSink* const sink = d->player->videoSink(); | |||
710 | QVideoFrame frame = sink->videoFrame(); | |||
711 | QImage image = frame.toImage(); | |||
712 | ||||
713 | if (!image.isNull() && d->currentItem.isValid()) | |||
714 | { | |||
715 | QFileInfo info(d->currentItem.toLocalFile()); | |||
716 | QDateTime dateTime; | |||
717 | ||||
718 | if (d->iface) | |||
719 | { | |||
720 | DItemInfo dinfo(d->iface->itemInfo(d->currentItem)); | |||
721 | dateTime = dinfo.dateTime(); | |||
722 | } | |||
723 | else | |||
724 | { | |||
725 | QScopedPointer<DMetadata> meta2(new DMetadata); | |||
726 | ||||
727 | if (meta2->load(d->currentItem.toLocalFile())) | |||
728 | { | |||
729 | dateTime = meta2->getItemDateTime(); | |||
730 | } | |||
731 | } | |||
732 | ||||
733 | if (dateTime.isValid()) | |||
734 | { | |||
735 | dateTime = dateTime.addMSecs(capturePosition); | |||
736 | } | |||
737 | else | |||
738 | { | |||
739 | dateTime = QDateTime::currentDateTime(); | |||
740 | } | |||
741 | ||||
742 | QTransform transform; | |||
743 | transform.rotate(d->videoOrientation); | |||
744 | image = std::move(image.transformed(transform)); | |||
745 | ||||
746 | QString tempPath = QString::fromUtf8("%1/%2-%3.digikamtempfile.jpg") | |||
747 | .arg(info.path()) | |||
748 | .arg(info.baseName()) | |||
749 | .arg(capturePosition); | |||
750 | ||||
751 | if (image.save(tempPath, "JPG", 100)) | |||
752 | { | |||
753 | QScopedPointer<DMetadata> meta(new DMetadata); | |||
754 | ||||
755 | if (meta->load(tempPath)) | |||
756 | { | |||
757 | meta->setItemOrientation(MetaEngine::ORIENTATION_NORMAL); | |||
758 | meta->setImageDateTime(dateTime, true); | |||
759 | meta->setItemDimensions(image.size()); | |||
760 | meta->save(tempPath, true); | |||
761 | } | |||
762 | ||||
763 | QString finalPath = QString::fromUtf8("%1/%2-%3.jpg") | |||
764 | .arg(info.path()) | |||
765 | .arg(info.baseName()) | |||
766 | .arg(capturePosition); | |||
767 | ||||
768 | if (QFile::rename(tempPath, finalPath)) | |||
769 | { | |||
770 | if (d->iface) | |||
771 | { | |||
772 | d->iface->slotMetadataChangedForUrl(QUrl::fromLocalFile(finalPath)); | |||
773 | } | |||
774 | } | |||
775 | else | |||
776 | { | |||
777 | QFile::remove(tempPath); | |||
778 | } | |||
779 | } | |||
780 | } | |||
781 | } | |||
782 | } | |||
783 | ||||
784 | int MediaPlayerView::previewMode() | |||
785 | { | |||
786 | return indexOf(currentWidget()); | |||
787 | } | |||
788 | ||||
789 | void MediaPlayerView::setPreviewMode(int mode) | |||
790 | { | |||
791 | if ((mode != Private::ErrorView) && (mode != Private::PlayerView)) | |||
792 | { | |||
793 | return; | |||
794 | } | |||
795 | ||||
796 | setCurrentIndex(mode); | |||
797 | ||||
798 | d->toolBar->adjustSize(); | |||
799 | d->toolBar->raise(); | |||
800 | } | |||
801 | ||||
802 | void MediaPlayerView::setCurrentItem(const QUrl& url, bool hasPrevious, bool hasNext) | |||
803 | { | |||
804 | d->prevAction->setEnabled(hasPrevious); | |||
805 | d->nextAction->setEnabled(hasNext); | |||
806 | d->adjustVideoSize(); | |||
807 | ||||
808 | if (url.isEmpty()) | |||
809 | { | |||
810 | d->player->stop(); | |||
811 | d->currentItem = url; | |||
812 | ||||
813 | return; | |||
814 | } | |||
815 | ||||
816 | if ( | |||
817 | (d->currentItem == url) && | |||
818 | ( | |||
819 | (d->player->playbackState() == QMediaPlayer::PlayingState) || | |||
820 | (d->player->playbackState() == QMediaPlayer::PausedState) | |||
821 | ) | |||
822 | ) | |||
823 | { | |||
824 | return; | |||
825 | } | |||
826 | ||||
827 | d->player->stop(); | |||
828 | int orientation = 0; | |||
829 | d->currentItem = url; | |||
830 | ||||
831 | if (d->iface) | |||
832 | { | |||
833 | DItemInfo info(d->iface->itemInfo(url)); | |||
834 | ||||
835 | orientation = info.orientation(); | |||
836 | } | |||
837 | ||||
838 | switch (orientation) | |||
839 | { | |||
840 | case MetaEngine::ORIENTATION_ROT_90: | |||
841 | case MetaEngine::ORIENTATION_ROT_90_HFLIP: | |||
842 | case MetaEngine::ORIENTATION_ROT_90_VFLIP: | |||
843 | { | |||
844 | d->videoOrientation = 90; | |||
845 | break; | |||
846 | } | |||
847 | ||||
848 | case MetaEngine::ORIENTATION_ROT_180: | |||
849 | { | |||
850 | d->videoOrientation = 180; | |||
851 | break; | |||
852 | } | |||
853 | ||||
854 | case MetaEngine::ORIENTATION_ROT_270: | |||
855 | { | |||
856 | d->videoOrientation = 270; | |||
857 | break; | |||
858 | } | |||
859 | ||||
860 | default: | |||
861 | { | |||
862 | d->videoOrientation = 0; | |||
863 | break; | |||
864 | } | |||
865 | } | |||
866 | ||||
867 | d->player->setSource(d->currentItem); | |||
868 | setPreviewMode(Private::PlayerView); | |||
869 | d->player->play(); | |||
870 | ||||
871 | qCDebug(DIGIKAM_GENERAL_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_GENERAL_LOG)()); qt_category; qt_category.control = false) QMessageLogger(static_cast<const char *>("/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ), 871, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Play video with QtMultimedia started:" << d->player->source(); | |||
872 | } | |||
873 | ||||
874 | void MediaPlayerView::slotPositionChanged(qint64 position) | |||
875 | { | |||
876 | if ( | |||
877 | (d->sliderTime < position) && | |||
878 | ((d->sliderTime + 100) > position) | |||
879 | ) | |||
880 | { | |||
881 | return; | |||
882 | } | |||
883 | ||||
884 | d->sliderTime = position; | |||
885 | ||||
886 | if (!d->slider->isSliderDown()) | |||
887 | { | |||
888 | d->slider->blockSignals(true); | |||
889 | d->slider->setValue(position); | |||
890 | d->slider->blockSignals(false); | |||
891 | } | |||
892 | ||||
893 | d->tlabel->setText(QString::fromLatin1("%1 / %2") | |||
894 | .arg(QTime(0, 0, 0).addMSecs(position).toString(QLatin1String("HH:mm:ss"))) | |||
895 | .arg(QTime(0, 0, 0).addMSecs(d->slider->maximum()).toString(QLatin1String("HH:mm:ss")))); | |||
896 | } | |||
897 | ||||
898 | void MediaPlayerView::slotVolumeChanged(int volume) | |||
899 | { | |||
900 | d->audio->setVolume(volume / 100.0F); | |||
901 | ||||
902 | if (objectName() != QLatin1String("main_media_player")) | |||
903 | { | |||
904 | return; | |||
905 | } | |||
906 | ||||
907 | KSharedConfig::Ptr config = KSharedConfig::openConfig(); | |||
908 | KConfigGroup group = config->group(QLatin1String("Media Player Settings")); | |||
909 | group.writeEntry("Volume", volume); | |||
910 | } | |||
911 | ||||
912 | void MediaPlayerView::slotLoopToggled(bool loop) | |||
913 | { | |||
914 | if (loop) | |||
915 | { | |||
916 | d->loopPlay->setIcon(QIcon::fromTheme(QLatin1String("media-playlist-repeat"))); | |||
917 | d->player->setLoops(QMediaPlayer::Infinite); | |||
918 | } | |||
919 | else | |||
920 | { | |||
921 | d->loopPlay->setIcon(QIcon::fromTheme(QLatin1String("media-playlist-normal"))); | |||
922 | d->player->setLoops(QMediaPlayer::Once); | |||
923 | } | |||
924 | } | |||
925 | ||||
926 | void MediaPlayerView::slotDurationChanged(qint64 duration) | |||
927 | { | |||
928 | qint64 max = qMax((qint64)1, duration); | |||
929 | d->slider->setRange(0, max); | |||
930 | } | |||
931 | ||||
932 | void MediaPlayerView::slotPlaybackRate(QAction* action) | |||
933 | { | |||
934 | if (action) | |||
935 | { | |||
936 | d->player->setPlaybackRate(action->data().toReal()); | |||
937 | } | |||
938 | } | |||
939 | ||||
940 | void MediaPlayerView::slotAudioChanged(QAction* action) | |||
941 | { | |||
942 | if (action) | |||
943 | { | |||
944 | for (const auto& device : QMediaDevices::audioOutputs()) | |||
945 | { | |||
946 | if (action->data().toByteArray() == device.id()) | |||
947 | { | |||
948 | d->audio->setDevice(device); | |||
949 | break; | |||
950 | } | |||
951 | } | |||
952 | } | |||
953 | } | |||
954 | ||||
955 | void MediaPlayerView::slotPosition(int position) | |||
956 | { | |||
957 | if (d->player->isSeekable()) | |||
958 | { | |||
959 | d->player->setPosition((qint64)position); | |||
960 | } | |||
961 | } | |||
962 | ||||
963 | void MediaPlayerView::slotHandlePlayerError(QMediaPlayer::Error /*error*/, const QString& errStr) | |||
964 | { | |||
965 | setPreviewMode(Private::ErrorView); | |||
966 | ||||
967 | qCDebug(DIGIKAM_GENERAL_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_GENERAL_LOG)()); qt_category; qt_category.control = false) QMessageLogger(static_cast<const char *>("/home/gilles/Devel/8.x/core/libs/video/player/qtmm/mediaplayerview.cpp" ), 967, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "QtMultimedia Error: " << errStr; | |||
968 | } | |||
969 | ||||
970 | void MediaPlayerView::slotNativeSizeChanged() | |||
971 | { | |||
972 | d->adjustVideoSize(); | |||
973 | } | |||
974 | ||||
975 | bool MediaPlayerView::eventFilter(QObject* watched, QEvent* event) | |||
976 | { | |||
977 | if ((watched == d->playerView) && (event->type() == QEvent::Resize)) | |||
978 | { | |||
979 | d->adjustVideoSize(); | |||
980 | } | |||
981 | ||||
982 | return QStackedWidget::eventFilter(watched, event); | |||
983 | } | |||
984 | ||||
985 | } // namespace Digikam | |||
986 | ||||
987 | #include "mediaplayerview.moc" | |||
988 | ||||
989 | #include "moc_mediaplayerview.cpp" |