File indexing completed on 2024-04-28 04:21:20

0001 // SPDX-FileCopyrightText: 2021 The KPhotoAlbum Development Team
0002 // SPDX-FileCopyrightText: 2022 Johannes Zarl-Zierl <johannes@zarl-zierl.at>
0003 //
0004 // SPDX-License-Identifier: GPL-2.0-or-later
0005 
0006 #include "VideoPlayerSelectorDialog.h"
0007 #include "Logging.h"
0008 #include <config-kpa-videobackends.h>
0009 
0010 #include <KLocalizedString>
0011 #include <QDialogButtonBox>
0012 #include <QLabel>
0013 #include <QLoggingCategory>
0014 #include <QRadioButton>
0015 #include <QVBoxLayout>
0016 
0017 namespace Settings
0018 {
0019 
0020 VideoPlayerSelectorDialog::VideoPlayerSelectorDialog(QWidget *parent)
0021     : QDialog(parent)
0022 {
0023     QVBoxLayout *layout = new QVBoxLayout(this);
0024 
0025     QLabel *label = new QLabel(i18n("<h1>Choose a Video Player</h1>"));
0026     layout->addWidget(label);
0027 
0028     QString txt = i18n("<html><p>Unfortunately, there is no video player which just works out of the box for everyone.</p>"
0029                        "<p>KPhotoAlbum therefore comes with three different back-ends, choose the one that works the best for you</p>"
0030 
0031                        "<p><b>VLC</b> seems to be the best supported video player back-end, meaning it can play most video formats. "
0032                        "It has one drawback though, it requires X11. "
0033                        "If you use Wayland, then you will find that the videos shows up in a window of their own, and in this case "
0034                        "VLC is likely not a very good fit for you. If on the other hand you do use X11 then VLC is likely your best choice.</p>"
0035 
0036                        "<p>Traditionally KPhotoAlbum has been using <b>Phonon</b> as the video player back-end. We've unfortunately seen it crash "
0037                        "on many different video formats - possibly because our system wasn't correctly configured. "
0038                        "If this is the case for you (and you can't use VLC), then try the <b>QtAV</b> back-end, "
0039                        "which seems to support a lot of formats (everything we threw at it). "
0040                        "<b>QtAV</b> unfortunately also has a drawback - it seems to get slightly out of sync between video and audio.</p>"
0041 
0042                        "<p><b><font color=red>You can at any time change the backend from Settings -> Viewer</font></b></p></html>");
0043     label = new QLabel(txt);
0044     label->setWordWrap(true);
0045     layout->addWidget(label);
0046 
0047     bool somethingNotAvailable = false;
0048     if (availableVideoBackends().testFlag(VideoBackend::VLC)) {
0049         m_vlc = new QRadioButton(QString::fromUtf8("VLC"));
0050     } else {
0051         m_vlc = new QRadioButton(QString::fromUtf8("VLC") + i18n(" (NOT AVAILABLE)"));
0052         m_vlc->setEnabled(false);
0053         somethingNotAvailable = true;
0054     }
0055     layout->addWidget(m_vlc);
0056 
0057     if (availableVideoBackends().testFlag(VideoBackend::QtAV)) {
0058         m_qtav = new QRadioButton(QString::fromUtf8("QtAV"));
0059     } else {
0060         m_qtav = new QRadioButton(QString::fromUtf8("QtAV") + i18n(" (NOT AVAILABLE)"));
0061         m_qtav->setEnabled(false);
0062         somethingNotAvailable = true;
0063     }
0064     layout->addWidget(m_qtav);
0065 
0066     if (availableVideoBackends().testFlag(VideoBackend::Phonon)) {
0067         m_phonon = new QRadioButton(QString::fromUtf8("Phonon"));
0068     } else {
0069         m_phonon = new QRadioButton(QString::fromUtf8("Phonon") + i18n(" (NOT AVAILABLE)"));
0070         m_phonon->setEnabled(false);
0071         somethingNotAvailable = true;
0072     }
0073     layout->addWidget(m_phonon);
0074 
0075     auto backend = preferredVideoBackend(SettingsData::instance()->videoBackend());
0076     QRadioButton *rb = [&] {
0077         QRadioButton *candidate = nullptr;
0078         switch (backend) {
0079         case VideoBackend::Phonon:
0080             candidate = m_phonon;
0081             break;
0082         case VideoBackend::QtAV:
0083             candidate = m_qtav;
0084             break;
0085         case VideoBackend::VLC:
0086             candidate = m_vlc;
0087             break;
0088         default:
0089             Q_UNREACHABLE();
0090         }
0091         return candidate;
0092     }();
0093 
0094     rb->setChecked(true);
0095 
0096     if (somethingNotAvailable) {
0097         auto label = new QLabel(i18n("<html><h1>Missing back-end</h1>"
0098                                      "The back-ends which are not available are due to the system configuration at compile time of KPhotoAlbum. "
0099                                      "If you compiled KPhotoAlbum yourself, then search for the developer packages of the back-ends. "
0100                                      "If you on the other hand got KPhotoAlbum from your system, then please talk to the maintainer of the package.</html>"));
0101         label->setWordWrap(true);
0102         layout->addWidget(label);
0103     }
0104 
0105     // Only offer OK, as it would be way to much work to handle the user not selecting a backend, when we are about to play videos.
0106     auto *box = new QDialogButtonBox(QDialogButtonBox::Ok);
0107     connect(box, &QDialogButtonBox::accepted, this, &QDialog::accept);
0108     layout->addWidget(box);
0109 }
0110 
0111 VideoBackend VideoPlayerSelectorDialog::backend() const
0112 {
0113     if (m_vlc->isChecked())
0114         return VideoBackend::VLC;
0115     else if (m_qtav->isChecked())
0116         return VideoBackend::QtAV;
0117     else
0118         return VideoBackend::Phonon;
0119 }
0120 
0121 constexpr VideoBackends availableVideoBackends()
0122 {
0123     VideoBackends availableBackends;
0124 #if LIBVLC_FOUND
0125     availableBackends |= VideoBackend::VLC;
0126 #endif
0127 #if QtAV_FOUND
0128     availableBackends |= VideoBackend::QtAV;
0129 #endif
0130 #if Phonon4Qt5_FOUND
0131     availableBackends |= VideoBackend::Phonon;
0132 #endif
0133     static_assert(LIBVLC_FOUND || QtAV_FOUND || Phonon4Qt5_FOUND, "A video backend must be provided. The build system should bail out if none is available.");
0134     return availableBackends;
0135 }
0136 
0137 VideoBackend preferredVideoBackend(const VideoBackend configuredBackend, const VideoBackends exclusions)
0138 {
0139     if (availableVideoBackends().testFlag(configuredBackend) && !exclusions.testFlag(configuredBackend)) {
0140         qCDebug(SettingsLog) << "preferredVideoBackend(): configured backend is viable:" << configuredBackend;
0141         return configuredBackend;
0142     }
0143 
0144     // change backend priority here:
0145     for (const VideoBackend candidate : { VideoBackend::Phonon, VideoBackend::VLC, VideoBackend::QtAV }) {
0146         if (availableVideoBackends().testFlag(candidate) && !exclusions.testFlag(candidate)) {
0147             qCDebug(SettingsLog) << "preferredVideoBackend(): backend is viable:" << candidate;
0148             return candidate;
0149         }
0150         qCDebug(SettingsLog) << "preferredVideoBackend(): backend is not viable:" << candidate;
0151     }
0152     qCDebug(SettingsLog) << "preferredVideoBackend(): no backend is viable.";
0153     return VideoBackend::NotConfigured;
0154 }
0155 
0156 QString localizedEnumName(const VideoBackend backend)
0157 {
0158     switch (backend) {
0159     case VideoBackend::NotConfigured:
0160         return i18nc("A friendly name for the video backend", "Unconfigured video backend");
0161     case VideoBackend::Phonon:
0162         return i18nc("A friendly name for the video backend", "Phonon video backend");
0163     case VideoBackend::QtAV:
0164         return i18nc("A friendly name for the video backend", "QtAV video backend");
0165     case VideoBackend::VLC:
0166         return i18nc("A friendly name for the video backend", "VLC video backend");
0167     }
0168     Q_UNREACHABLE();
0169     return {};
0170 }
0171 
0172 } // namespace Settings
0173 
0174 #include "moc_VideoPlayerSelectorDialog.cpp"