1 /* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2006-12-20
7 * Description : a widget to display a welcome page
8 * on root album.
9 *
10 * Copyright (C) 2006-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
11 * Copyright (C) 2009-2011 by Andi Clemens <andi dot clemens at gmail dot com>
12 * Copyright (C) 2015 by Mohamed_Anwer <m_dot_anwer at gmx dot com>
13 *
14 * This program is free software; you can redistribute it
15 * and/or modify it under the terms of the GNU General
16 * Public License as published by the Free Software Foundation;
17 * either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * ============================================================ */
26
27 #include "welcomepageview.h"
28
29 // Qt includes
30
31 #include <QFile>
32 #include <QFileInfo>
33 #include <QTimer>
34 #include <QWidget>
35 #include <QApplication>
36 #include <QStandardPaths>
37
38 #ifdef HAVE_QWEBENGINE
39 # include <QtWebEngineWidgetsVersion>
40 #endif
41
42 // KDE includes
43
44 #include <klocalizedstring.h>
45
46 // Local includes
47
48 #include "digikam_debug.h"
49 #include "digikam_version.h"
50 #include "daboutdata.h"
51 #include "thememanager.h"
52 #include "webbrowserdlg.h"
53
54 namespace Digikam
55 {
56
57 #ifdef HAVE_QWEBENGINE
58
WelcomePageViewPage(QObject * const parent)59 WelcomePageViewPage::WelcomePageViewPage(QObject* const parent)
60 : QWebEnginePage(parent)
61 {
62 }
63
~WelcomePageViewPage()64 WelcomePageViewPage::~WelcomePageViewPage()
65 {
66 }
67
acceptNavigationRequest(const QUrl & url,QWebEnginePage::NavigationType type,bool)68 bool WelcomePageViewPage::acceptNavigationRequest(const QUrl& url, QWebEnginePage::NavigationType type, bool)
69 {
70 if (type == QWebEnginePage::NavigationTypeLinkClicked)
71 {
72 emit linkClicked(url);
73
74 return false;
75 }
76
77 return true;
78 }
79
80 // ----------------------------------------------------------------------------
81
WelcomePageView(QWidget * const parent)82 WelcomePageView::WelcomePageView(QWidget* const parent)
83 : QWebEngineView(parent)
84
85 #else
86
87 WelcomePageView::WelcomePageView(QWidget* const parent)
88 : QWebView(parent)
89
90 #endif
91
92 {
93 setFocusPolicy(Qt::WheelFocus);
94
95 #ifndef HAVE_QWEBENGINE
96
97 page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
98 setRenderHint(QPainter::TextAntialiasing);
99
100 #endif
101
102 setContextMenuPolicy(Qt::NoContextMenu);
103 setContentsMargins(QMargins());
104
105 #ifdef HAVE_QWEBENGINE
106
107 WelcomePageViewPage* const wpage = new WelcomePageViewPage(this);
108 setPage(wpage);
109
110 # if QTWEBENGINEWIDGETS_VERSION >= QT_VERSION_CHECK(5, 7, 0)
111
112 settings()->setAttribute(QWebEngineSettings::WebGLEnabled, false);
113 settings()->setAttribute(QWebEngineSettings::Accelerated2dCanvasEnabled, false);
114
115 # endif
116
117 #endif
118
119 // ------------------------------------------------------------
120
121 #ifdef HAVE_QWEBENGINE
122
123 connect(wpage, SIGNAL(linkClicked(QUrl)),
124 this, SLOT(slotUrlOpen(QUrl)));
125
126 #else
127
128 connect(this, SIGNAL(linkClicked(QUrl)),
129 this, SLOT(slotUrlOpen(QUrl)));
130
131 #endif
132
133 connect(ThemeManager::instance(), SIGNAL(signalThemeChanged()),
134 this, SLOT(slotThemeChanged()));
135
136 QTimer::singleShot(0, this, SLOT(slotThemeChanged()));
137 }
138
~WelcomePageView()139 WelcomePageView::~WelcomePageView()
140 {
141 }
142
slotUrlOpen(const QUrl & url)143 void WelcomePageView::slotUrlOpen(const QUrl& url)
144 {
145 WebBrowserDlg* const browser = new WebBrowserDlg(url, qApp->activeWindow());
146 browser->show();
147 }
148
featuresTabContent() const149 QStringList WelcomePageView::featuresTabContent() const
150 {
151 QStringList newFeatures;
152 newFeatures << i18n("More than 1300 user-reports closed on bugzilla.");
153 newFeatures << i18n("New Neural Network engine based on OpenCV Deep Learning module to detect and recognize faces.");
154 newFeatures << i18n("Update Slideshow to plugin with new shuffle mode.");
155 newFeatures << i18n("Add new theme Html5Responsive for HtmlGallery plugin.");
156 newFeatures << i18n("New plugin ImageMosaicWall to create an image based on a bunch of other photos.");
157 newFeatures << i18n("add new batch queue manager tool to fix hot pixels from images.");
158 newFeatures << i18n("add new batch queue manager tool to apply texture over images.");
159 newFeatures << i18n("Face Scan dialog contents is now simplified and embedded into left sidebar.");
160 newFeatures << i18n("Add support for Gimp XCF files >= 2.10.");
161 newFeatures << i18n("Add Flatpak bundle support for Linux platforms.");
162 newFeatures << i18n("Table-view is now able to show digiKam Tag-Paths properties.");
163 newFeatures << i18n("Add option to write geolocation information in file metadata.");
164 newFeatures << i18n("Add color label support for advanced metadata settings.");
165 newFeatures << i18n("Add Exif, Iptc, and Xmp read support for HEIF images.");
166 newFeatures << i18n("Improved support for UNC network paths under Windows.");
167 newFeatures << i18n("Improved support for Unicode paths under Windows.");
168 newFeatures << i18n("Apple bundle is now relocatable and compatible with macOS BigSur.");
169 newFeatures << i18n("New online version checker and downloader to automatize upgrade under Windows and macOS.");
170 newFeatures << i18n("Better support of astro FITS image format including metadata extraction support to populate the database.");
171 newFeatures << i18n("Use last Exiv2 0.27.4 in all bundles with Base Media File metadata read and write support (HEIF, AVIF).");
172 newFeatures << i18n("Find duplicates items is now process in parallel using multi-cores.");
173 newFeatures << i18n("New tool to export items to iNaturatist web service.");
174 newFeatures << i18n("New metadata viewer based on ExifTool.");
175 newFeatures << i18n("Integration of Google Summer of Code project 2021 "
176 "<a href=\"https://community.kde.org/GSoC/2021/StatusReports/PhuocKhanhLE\">Image Quality Sorter</a>.");
177 newFeatures << i18n("New tool to share items on the network with a Motion JPEG stream server.");
178 newFeatures << i18n("Showfoto has a new left sidebar hosting a folder-view to quickly explore images from local file system.");
179 newFeatures << i18n("Update internal RAW engine to last Libraw 0.20.2 (snapshot 20210827) including Canon CR3 and Sony A7R4 support.");
180 newFeatures << i18n("New camera supported: "
181 "Canon CR3, PowerShot G5 X Mark II, G7 X Mark III, SX70 HS, EOS R, EOS RP, EOS 90D, EOS 250D, EOS M6 Mark II, EOS M50, EOS M200, EOS 1DX Mark III (lossless files only) "
182 "DJI Mavic Air, Air2, Osmo Action, "
183 "FujiFilm Fujifilm compressed/16bit, GFX 100, X-A7, X-Pro3, X100V, X-T4, X-T200, "
184 "GoPro Fusion, HERO5, HERO6, HERO7, HERO8, "
185 "Hasselblad L1D-20c, X1D II 50C, "
186 "Leica D-LUX7, Q-P, Q2, V-LUX5, C-Lux / CAM-DC25, SL2, M10 Monochrom, "
187 "Nikon D780, Z50, P950, "
188 "Olympus TG-6, E-M5 Mark III, E-PL10, E-M1 Mark III, "
189 "Panasonic Panasonic 14-bit, DC-FZ1000 II, DC-G90, DC-S1, DC-S1R, DC-S1H, DC-TZ95, "
190 "PhaseOne IQ4 150MP, "
191 "Rapsberry Pi RAW+JPEG format, "
192 "Ricoh GR III, "
193 "Sony A7R IV, A9 II, ILCE-6100, ILCE-6600, RX0 II, RX100 VII, "
194 "Zenit M, "
195 "also multiple modern smartphones.");
196
197 // Add new features here...
198
199 newFeatures << i18n("...and much more.");
200
201 QString featureItems;
202
203 for (int i = 0 ; i < newFeatures.count() ; ++i)
204 {
205 featureItems += i18n("<li>%1</li>\n", newFeatures.at(i));
206 }
207
208 QString tabHeader = i18n("New Features");
209 QString tabContent =
210 i18n("<h3>%1</h3><ul>%2</ul>",
211 i18n("Some of the new features in this release of digiKam include (compared to digiKam 6.x):"),
212 featureItems);
213
214 return QStringList() << tabHeader << tabContent;
215 }
216
aboutTabContent() const217 QStringList WelcomePageView::aboutTabContent() const
218 {
219 QString tabHeader = i18n("About");
220 QString tabContent =
221 i18n("<h3>%1</h3><h3>%2</h3><ul>%3</ul>",
222 i18n("digiKam is an open source photo management program designed to import, organize, enhance, search and export your digital images to and from your computer."),
223 i18n("Currently, you are in the Album view mode of digiKam. Albums are the places where your files are stored, and are identical to the folders on your hard disk."),
224 i18n("<li>%1</li><li>%2</li>",
225 i18n("digiKam has many powerful features which are described in the <a href=\"https://docs.kde.org/?application=digikam&branch=trunk5\">documentation</a>"),
226 i18n("The <a href=\"https://www.digikam.org\">digiKam homepage</a> provides information about new versions of digiKam.")));
227
228 return QStringList() << tabHeader << tabContent;
229 }
230
fileToString(const QString & aFileName) const231 QByteArray WelcomePageView::fileToString(const QString& aFileName) const
232 {
233 QByteArray result;
234 QFileInfo info(aFileName);
235 unsigned int readLen;
236 unsigned int len = info.size();
237 QFile file(aFileName);
238
239 if (aFileName.isEmpty() || (len == 0) ||
240 !info.exists() || info.isDir() || !info.isReadable() ||
241 !file.open(QIODevice::Unbuffered|QIODevice::ReadOnly))
242 {
243 return QByteArray();
244 }
245
246 result.resize(len + 2);
247 readLen = file.read(result.data(), len);
248 file.close();
249
250 if (result[len-1] != '\n')
251 {
252 result[len++] = '\n';
253 ++readLen;
254 }
255
256 result[len] = '\0';
257
258 if (readLen < len)
259 {
260 return QByteArray();
261 }
262
263 return result;
264 }
265
slotThemeChanged()266 void WelcomePageView::slotThemeChanged()
267 {
268 QString appTitle = i18n("digiKam");
269 QString slogan = DAboutData::digiKamSlogan();
270 QString locationHtml = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("digikam/about/main.html"));
271 QString content = QString::fromUtf8(fileToString(locationHtml));
272 content = content.arg(appTitle)
273 .arg(slogan)
274 .arg(i18n("Welcome to digiKam %1", QLatin1String(digikam_version)))
275 .arg(featuresTabContent().value(0))
276 .arg(aboutTabContent().value(0))
277 .arg(i18n("Background Image Credits"))
278 .arg(featuresTabContent().value(1))
279 .arg(aboutTabContent().value(1));
280
281 //qCDebug(DIGIKAM_GENERAL_LOG) << content;
282
283 setHtml(content, QUrl::fromLocalFile(locationHtml));
284 }
285
286 } // namespace Digikam
287