1 // SPDX-FileCopyrightText: 2003-2020 The KPhotoAlbum Development Team
2 // SPDX-FileCopyrightText: 2021 Johannes Zarl-Zierl <johannes@zarl-zierl.at>
3 //
4 // SPDX-License-Identifier: GPL-2.0-or-later
5 
6 #include "FeatureDialog.h"
7 
8 #include <kpabase/config-kpa-marble.h>
9 #include <kpabase/config-kpa-plugins.h>
10 #include <kpaexif/Database.h>
11 
12 #include <KLocalizedString>
13 #include <QDialogButtonBox>
14 #include <QLayout>
15 #include <QList>
16 #include <QProcess>
17 #include <QPushButton>
18 #include <QStandardPaths>
19 #include <QTextBrowser>
20 #include <QVBoxLayout>
21 #include <phonon/backendcapabilities.h>
22 
23 using namespace MainWindow;
24 
FeatureDialog(QWidget * parent)25 FeatureDialog::FeatureDialog(QWidget *parent)
26     : QDialog(parent)
27 {
28     setWindowTitle(i18nc("@title:window", "Feature Status"));
29 
30     QTextBrowser *browser = new QTextBrowser(this);
31 
32     QString text = i18n("<h1>Overview</h1>"
33                         "<p>Below you may see the list of compile- and runtime features KPhotoAlbum has, and their status:</p>"
34                         "%1",
35                         featureString());
36     text += i18n("<h1>What can I do if I miss a feature?</h1>"
37 
38                  "<p>If you compiled KPhotoAlbum yourself, then please review the sections below to learn what to install "
39                  "to get the feature in question. If on the other hand you installed KPhotoAlbum from a binary package, please tell "
40                  "whoever made the package about this defect, eventually including the information from the section below.</p>"
41 
42                  "<p>In case you are missing a feature and you did not compile KPhotoAlbum yourself, please do consider doing so. "
43                  "It really is not that hard. If you need help compiling KPhotoAlbum, feel free to ask on the "
44                  "<a href=\"https://mail.kdab.com/mailman/listinfo/kphotoalbum\">KPhotoAlbum mailing list</a></p>"
45 
46                  "<p>The steps to compile KPhotoAlbum can be seen on <a href=\"https://community.kde.org/KPhotoAlbum/build_instructions\">"
47                  "the KPhotoAlbum home page</a>. If you have never compiled a KDE application, then please ensure that "
48                  "you have the developer packages installed, in most distributions they go under names like kdelibs<i>-devel</i></p>");
49 
50     text += i18n("<h1><a name=\"purpose\">Plugin support</a></h1>"
51                  "<p>KPhotoAlbum supports the <em>Purpose</em> plugin system.</p>");
52 
53     text += i18n("<h1><a name=\"database\">SQLite database support</a></h1>"
54                  "<p>KPhotoAlbum allows you to search using a certain number of Exif tags. For this KPhotoAlbum "
55                  "needs an SQLite database. "
56                  "In addition the Qt package for SQLite (e.g. qt-sql-sqlite) must be installed.</p>");
57 
58     text += i18n("<h1><a name=\"geomap\">Map view for geotagged images</a></h1>"
59                  "<p>If KPhotoAlbum has been built with support for Marble, "
60                  "KPhotoAlbum can show images with GPS information on a map."
61                  "</p>");
62 
63     text += i18n("<h1><a name=\"video\">Video support</a></h1>"
64                  "<p>KPhotoAlbum relies on Qt's Phonon architecture for displaying videos; this in turn relies on GStreamer.</p>");
65 
66     QStringList mimeTypes = supportedVideoMimeTypes();
67     mimeTypes.sort();
68     if (mimeTypes.isEmpty())
69         text += i18n("<p>No video mime types found, which indicates that either Qt was compiled without phonon support, or there were missing codecs</p>");
70     else
71         text += i18n("<p>Phonon is capable of playing movies of these mime types:<ul><li>%1</li></ul></p>", mimeTypes.join(QString::fromLatin1("</li><li>")));
72 
73     text += i18n("<h1><a name=\"videoPreview\">Video thumbnail support</a></h1>"
74                  "<p>KPhotoAlbum can use <tt>ffmpeg</tt> to extract thumbnails from videos. These thumbnails are used to preview "
75                  "videos in the thumbnail viewer.</p>");
76 
77     text += i18n("<h1><a name=\"videoInfo\">Video metadata support</a></h1>"
78                  "<p>KPhotoAlbum can use <tt>ffprobe</tt> to extract length information from videos."
79                  "</p>"
80                  "<p>Correct length information is necessary for correct rendering of video thumbnails.</p>");
81 
82     browser->setText(text);
83 
84     QVBoxLayout *layout = new QVBoxLayout;
85     layout->addWidget(browser);
86     this->setLayout(layout);
87 
88     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
89     buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return);
90     layout->addWidget(buttonBox);
91 
92     connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
93 }
94 
sizeHint() const95 QSize FeatureDialog::sizeHint() const
96 {
97     return QSize(800, 600);
98 }
99 
hasPurposeSupport()100 bool MainWindow::FeatureDialog::hasPurposeSupport()
101 {
102 #ifdef KF5Purpose_FOUND
103     return true;
104 #else
105     return false;
106 #endif
107 }
108 
hasEXIV2DBSupport()109 bool MainWindow::FeatureDialog::hasEXIV2DBSupport()
110 {
111     return Exif::Database::isAvailable();
112 }
113 
hasGeoMapSupport()114 bool MainWindow::FeatureDialog::hasGeoMapSupport()
115 {
116 #ifdef HAVE_MARBLE
117     return true;
118 #else
119     return false;
120 #endif
121 }
122 
ffmpegBinary()123 QString FeatureDialog::ffmpegBinary()
124 {
125     QString ffmpeg = QStandardPaths::findExecutable(QString::fromLatin1("ffmpeg"));
126     return ffmpeg;
127 }
128 
ffprobeBinary()129 QString FeatureDialog::ffprobeBinary()
130 {
131     QString ffprobe = QStandardPaths::findExecutable(QString::fromLatin1("ffprobe"));
132     return ffprobe;
133 }
134 
hasVideoThumbnailer()135 bool FeatureDialog::hasVideoThumbnailer()
136 {
137     return !ffmpegBinary().isEmpty();
138 }
139 
hasVideoProber()140 bool FeatureDialog::hasVideoProber()
141 {
142     return !ffprobeBinary().isEmpty();
143 }
144 
hasAllFeaturesAvailable()145 bool MainWindow::FeatureDialog::hasAllFeaturesAvailable()
146 {
147     // Only answer those that are compile time tests, otherwise we will pay a penalty each time we start up.
148     return hasPurposeSupport() && hasEXIV2DBSupport() && hasGeoMapSupport() && hasVideoThumbnailer() && hasVideoProber();
149 }
150 
151 struct Data {
DataData152     Data() { }
DataData153     Data(const QString &title, const QString tag, bool featureFound)
154         : title(title)
155         , tag(tag)
156         , featureFound(featureFound)
157     {
158     }
159     QString title;
160     QString tag;
161     bool featureFound;
162 };
163 
featureString()164 QString MainWindow::FeatureDialog::featureString()
165 {
166     QList<Data> features;
167     features << Data(i18n("Plug-ins available"), QString::fromLatin1("#purpose"), hasPurposeSupport());
168     features << Data(i18n("SQLite database support (used for Exif searches)"), QString::fromLatin1("#database"), hasEXIV2DBSupport());
169     features << Data(i18n("Map view for geotagged images."), QString::fromLatin1("#geomap"), hasGeoMapSupport());
170     features << Data(i18n("Video support"), QString::fromLatin1("#video"), !supportedVideoMimeTypes().isEmpty());
171     features << Data(i18n("Video thumbnail support"), QString::fromLatin1("#videoPreview"), hasVideoThumbnailer());
172     features << Data(i18n("Video metadata support"), QString::fromLatin1("#videoInfo"), hasVideoProber());
173 
174     QString result = QString::fromLatin1("<p><table>");
175     const QString red = QString::fromLatin1("<font color=\"red\">%1</font>");
176     const QString yes = i18nc("Feature available", "Yes");
177     const QString no = red.arg(i18nc("Feature not available", "No"));
178     const QString formatString = QString::fromLatin1("<tr><td><a href=\"%1\">%2</a></td><td><b>%3</b></td></tr>");
179     for (QList<Data>::ConstIterator featureIt = features.constBegin(); featureIt != features.constEnd(); ++featureIt) {
180         result += formatString
181                       .arg((*featureIt).tag)
182                       .arg((*featureIt).title)
183                       .arg((*featureIt).featureFound ? yes : no);
184     }
185     result += QString::fromLatin1("</table></p>");
186 
187     return result;
188 }
189 
supportedVideoMimeTypes()190 QStringList MainWindow::FeatureDialog::supportedVideoMimeTypes()
191 {
192     return Phonon::BackendCapabilities::availableMimeTypes();
193 }
194 
195 // vi:expandtab:tabstop=4 shiftwidth=4:
196