1 /* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2004-11-22
7 * Description : showFoto is a stand alone version of image
8 * editor with no support of digiKam database.
9 *
10 * Copyright (C) 2004-2005 by Renchi Raju <renchi dot raju at gmail dot com>
11 * Copyright (C) 2004-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
12 *
13 * This program is free software; you can redistribute it
14 * and/or modify it under the terms of the GNU General
15 * Public License as published by the Free Software Foundation;
16 * either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * ============================================================ */
25
26 #include "digikam_config.h"
27
28 // Qt includes
29
30 #include <QDir>
31 #include <QFile>
32 #include <QSettings>
33 #include <QTranslator>
34 #include <QMessageBox>
35 #include <QApplication>
36 #include <QStandardPaths>
37 #include <QCommandLineParser>
38 #include <QCommandLineOption>
39
40 // KDE includes
41
42 #include <klocalizedstring.h>
43 #include <ksharedconfig.h>
44 #include <kconfiggroup.h>
45 #include <kaboutdata.h>
46
47 // ImageMagick includes
48
49 #if defined(Q_CC_CLANG)
50 # pragma clang diagnostic push
51 # pragma clang diagnostic ignored "-Wkeyword-macro"
52 #endif
53
54 #ifdef HAVE_IMAGE_MAGICK
55 # include <Magick++.h>
56 using namespace Magick;
57 #endif
58
59 #if defined(Q_CC_CLANG)
60 # pragma clang diagnostic pop
61 #endif
62
63 // Local includes
64
65 #include "digikam_debug.h"
66 #include "digikam_globals.h"
67 #include "digikam_version.h"
68 #include "filesdownloader.h"
69 #include "systemsettings.h"
70 #include "metaengine.h"
71 #include "daboutdata.h"
72 #include "showfoto.h"
73
74 #ifdef Q_OS_WIN
75 # include <windows.h>
76 # include <shellapi.h>
77 # include <objbase.h>
78 #endif
79
80 using namespace Digikam;
81
main(int argc,char * argv[])82 int main(int argc, char* argv[])
83 {
84 SystemSettings system(QLatin1String("showfoto"));
85 system.readSettings();
86
87 QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps,
88 system.useHighDpiPixmaps);
89
90 if (system.useHighDpiScaling)
91 {
92 QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
93 }
94 else
95 {
96 QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
97 }
98
99 #ifdef HAVE_QWEBENGINE
100
101 QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
102
103 #endif
104
105 QApplication app(argc, argv);
106
107 digikamSetDebugFilterRules();
108
109 tryInitDrMingw();
110
111 #ifdef HAVE_IMAGE_MAGICK
112
113 InitializeMagick(nullptr);
114
115 #endif
116
117 // if we have some local breeze icon resource, prefer it
118
119 DXmlGuiWindow::setupIconTheme();
120
121 KLocalizedString::setApplicationDomain("digikam");
122
123 KAboutData aboutData(QLatin1String("showfoto"), // component name
124 i18nc("@title", "Showfoto"), // display name
125 digiKamVersion()); // NOTE: showFoto version = digiKam version
126
127 aboutData.setShortDescription(QString::fromUtf8("%1 - %2").arg(DAboutData::digiKamSlogan()).arg(DAboutData::digiKamFamily()));
128 aboutData.setLicense(KAboutLicense::GPL);
129 aboutData.setCopyrightStatement(DAboutData::copyright());
130 aboutData.setOtherText(additionalInformation());
131 aboutData.setHomepage(DAboutData::webProjectUrl().url());
132 aboutData.setProductName(QByteArray("digikam/showfoto")); // For bugzilla
133 aboutData.setTranslator(i18nc("NAME OF TRANSLATORS", "Your names"),
134 i18nc("EMAIL OF TRANSLATORS", "Your emails"));
135
136 DAboutData::authorsRegistration(aboutData);
137
138 QCommandLineParser parser;
139 KAboutData::setApplicationData(aboutData);
140 aboutData.setupCommandLine(&parser);
141 parser.addPositionalArgument(QLatin1String("files"),
142 i18nc("command line option", "File(s) or folder(s) to open"),
143 QLatin1String("[file(s) or folder(s)]"));
144 parser.process(app);
145 aboutData.processCommandLine(&parser);
146
147 KSharedConfig::Ptr config = KSharedConfig::openConfig();
148 KConfigGroup group = config->group(QLatin1String("ImageViewer Settings"));
149 QString iconTheme = group.readEntry(QLatin1String("Icon Theme"), QString());
150 QString colorTheme = group.readEntry(QLatin1String("Theme"), QString::fromLatin1("Standard"));
151
152 #if defined Q_OS_WIN || defined Q_OS_MACOS
153
154 bool loadTranslation = true;
155
156 #else
157
158 bool loadTranslation = isRunningInAppImageBundle();
159
160 #endif
161
162 QString transPath = QStandardPaths::locate(QStandardPaths::DataLocation,
163 QLatin1String("translations"),
164 QStandardPaths::LocateDirectory);
165
166 if (loadTranslation && !transPath.isEmpty())
167 {
168 QString klanguagePath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) +
169 QLatin1Char('/') + QLatin1String("klanguageoverridesrc");
170
171 qCDebug(DIGIKAM_GENERAL_LOG) << "Qt translations path:" << transPath;
172
173 QLocale locale;
174
175 if (!klanguagePath.isEmpty())
176 {
177 QSettings settings(klanguagePath, QSettings::IniFormat);
178 settings.beginGroup(QLatin1String("Language"));
179 QString language = settings.value(qApp->applicationName(), QString()).toString();
180 settings.endGroup();
181
182 if (!language.isEmpty())
183 {
184 locale = QLocale(language.split(QLatin1Char(':')).first());
185 }
186 }
187
188 QStringList qtCatalogs;
189 qtCatalogs << QLatin1String("qt");
190 qtCatalogs << QLatin1String("qtbase");
191 qtCatalogs << QLatin1String("qt_help");
192
193 foreach (const QString& catalog, qtCatalogs)
194 {
195 QTranslator* const translator = new QTranslator(&app);
196
197 if (translator->load(locale, catalog, QLatin1String("_"), transPath))
198 {
199 qCDebug(DIGIKAM_GENERAL_LOG) << "Loaded locale:" << locale.name()
200 << "from catalog:" << catalog;
201
202 app.installTranslator(translator);
203 }
204 else
205 {
206 delete translator;
207 }
208 }
209 }
210
211 MetaEngine::initializeExiv2();
212
213 // Force to use application icon for non plasma desktop as Unity for ex.
214
215 QApplication::setWindowIcon(QIcon::fromTheme(QLatin1String("showfoto"), app.windowIcon()));
216
217 #ifdef Q_OS_WIN
218
219 if (QSysInfo::currentCpuArchitecture().contains(QLatin1String("64")) &&
220 !QSysInfo::buildCpuArchitecture().contains(QLatin1String("64")))
221 {
222 QMessageBox::critical(qApp->activeWindow(),
223 qApp->applicationName(),
224 i18nc("#info", "<p>You are running Showfoto as a 32-bit version on a 64-bit Windows.</p>"
225 "<p>Please install the 64-bit version of Showfoto to get "
226 "a better experience with Showfoto.</p>"));
227 }
228
229 #endif
230
231 QList<QUrl> urlList;
232 QStringList urls = parser.positionalArguments();
233
234 foreach (const QString& url, urls)
235 {
236 urlList.append(QUrl::fromLocalFile(url));
237 }
238
239 parser.clearPositionalArguments();
240
241 if (!iconTheme.isEmpty())
242 {
243 QIcon::setThemeName(iconTheme);
244 }
245
246 // Workaround for the automatic icon theme color
247 // in KF-5.80/KF-5.88, depending on the color scheme.
248 // Note: In a Plasma environment, use the showFoto icon theme setting from the system.
249
250 if (
251 (colorTheme == QLatin1String("White Balance")) ||
252 (colorTheme == QLatin1String("Standard")) ||
253 (colorTheme == QLatin1String("High Key")) ||
254 (colorTheme == QLatin1String("Breeze"))
255 )
256 {
257 qApp->setPalette(QPalette(Qt::white));
258 }
259 else
260 {
261 qApp->setPalette(QPalette(Qt::darkGray));
262 }
263
264 #ifdef Q_OS_WIN
265
266 // Necessary to open native open with dialog on windows
267
268 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
269
270 #endif
271
272 ShowFoto::Showfoto* const w = new ShowFoto::Showfoto(urlList);
273
274 // If application storage place in home directory to save customized XML settings files do not exist, create it,
275 // else QFile will not able to create new files as well.
276
277 if (!QFile::exists(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)))
278 {
279 QDir().mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
280 }
281
282 // If application cache place in home directory to save cached files do not exist, create it.
283
284 if (!QFile::exists(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)))
285 {
286 QDir().mkpath(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
287 }
288
289 w->show();
290
291 QPointer<FilesDownloader> floader = new FilesDownloader(qApp->activeWindow());
292
293 if (!floader->checkDownloadFiles())
294 {
295 floader->startDownload();
296 }
297
298 int ret = app.exec();
299
300 #ifdef Q_OS_WIN
301
302 // Necessary to open native open with dialog on windows
303
304 CoUninitialize();
305
306 #endif
307
308 #ifdef HAVE_IMAGE_MAGICK
309 # if MagickLibVersion >= 0x693
310
311 TerminateMagick();
312
313 # endif
314 #endif
315
316 return ret;
317 }
318