1 /*!
2  * \copyright Copyright (c) 2014-2021 Governikus GmbH & Co. KG, Germany
3  */
4 
5 #include "HelpAction.h"
6 
7 #include "LanguageLoader.h"
8 #include "SingletonHelper.h"
9 #include "VersionNumber.h"
10 
11 #include <QCoreApplication>
12 #include <QDesktopServices>
13 #include <QDir>
14 #include <QFile>
15 #include <QLoggingCategory>
16 #include <QStringBuilder>
17 #include <QUrl>
18 
19 
20 using namespace governikus;
21 
22 defineSingleton(HelpAction) // clazy:exclude=wrong-qglobalstatic
23 
24 Q_DECLARE_LOGGING_CATEGORY(gui)
25 
26 const QMap<QString, QString> HelpAction::mQmlHelpMapping = {
27 	{QStringLiteral("applicationOverview"), QStringLiteral("index.html")},
28 	{QStringLiteral("index"), QStringLiteral("index.html")},
29 	{QStringLiteral("selfauthentication"), QStringLiteral("selfauthentication.html")},
30 	{QStringLiteral("authentication"), QStringLiteral("provider-identify.html")},
31 	{QStringLiteral("provider"), QStringLiteral("provider.html")},
32 	{QStringLiteral("providerDetails"), QStringLiteral("provider-list.html#provider-details")},
33 	{QStringLiteral("history"), QStringLiteral("history.html")},
34 	{QStringLiteral("settings"), QStringLiteral("settings.html")},
35 	{QStringLiteral("settingsRemoteReader"), QStringLiteral("settings-remote-reader.html")},
36 	{QStringLiteral("settingsPcscReader"), QStringLiteral("settings-pcsc-reader.html")},
37 	{QStringLiteral("settingsSecurityPrivacy"), QStringLiteral("settings-security-privacy.html")},
38 	{QStringLiteral("settingsDeveloper"), QStringLiteral("settings-developer.html")},
39 	{QStringLiteral("pinManagement"), QStringLiteral("pin-management.html")},
40 	{QStringLiteral("helpSection"), QStringLiteral("help-section.html")},
41 	{QStringLiteral("diagnosis"), QStringLiteral("help-section-diagnosis.html")},
42 	{QStringLiteral("applicationLog"), QStringLiteral("help-section-application-log.html")},
43 	{QStringLiteral("helpVersioninformation"), QStringLiteral("help-section-versioninformation.html")},
44 	{QStringLiteral("helpLicenseinformation"), QStringLiteral("help-section-software-license.html")},
45 	{QStringLiteral("setupAssistant"), QStringLiteral("setup-assistant.html")},
46 	{QStringLiteral("applicationUpdate"), QStringLiteral("updates.html")}
47 };
48 
49 const QString HelpAction::mBaseUrl = QStringLiteral("https://www.ausweisapp.bund.de/ausweisapp2/");
50 
51 
getHelpPath(QLocale::Language pLang) const52 QString HelpAction::getHelpPath(QLocale::Language pLang) const
53 {
54 	const QString langDir = QCoreApplication::applicationDirPath() % QStringLiteral("/help/") % LanguageLoader::getLocalCode(QLocale(pLang)) % QLatin1Char('/');
55 
56 	if (QDir(langDir).exists())
57 	{
58 		return langDir;
59 	}
60 
61 	return QString();
62 }
63 
64 
getExistingHelpLanguage() const65 QLocale::Language HelpAction::getExistingHelpLanguage() const
66 {
67 	QLocale::Language lang = LanguageLoader::getInstance().getUsedLocale().language();
68 	if (!getHelpPath(lang).isNull())
69 	{
70 		return lang;
71 	}
72 
73 	lang = LanguageLoader::getInstance().getFallbackLanguage();
74 	if (!getHelpPath(lang).isNull())
75 	{
76 		return lang;
77 	}
78 
79 	return QLocale::AnyLanguage;
80 }
81 
82 
getContextMapping(const QString & pObjectName) const83 QString HelpAction::getContextMapping(const QString& pObjectName) const
84 {
85 	if (mQmlHelpMapping.contains(pObjectName))
86 	{
87 		return mQmlHelpMapping.value(pObjectName);
88 	}
89 	else
90 	{
91 		qCWarning(gui) << "Cannot find help mapping:" << pObjectName;
92 	}
93 
94 	return QStringLiteral("index.html");
95 }
96 
97 
getHelpUrl(const QString & pObjectName) const98 QString HelpAction::getHelpUrl(const QString& pObjectName) const
99 {
100 	QLocale::Language lang = getExistingHelpLanguage();
101 	if (lang == QLocale::AnyLanguage)
102 	{
103 		return getOnlineUrl(QString());
104 	}
105 
106 	return QUrl::fromLocalFile(getHelpPath(lang)).toString() + getContextMapping(pObjectName);
107 }
108 
109 
getOnlineUrl(const QString & pObjectName)110 QString HelpAction::getOnlineUrl(const QString& pObjectName)
111 {
112 #ifdef Q_OS_MACOS
113 	const QLatin1String osPath("macOS");
114 #else
115 	const QLatin1String osPath("Windows");
116 #endif
117 
118 	const auto& appVersion = VersionNumber::getApplicationVersion().getVersionNumber();
119 	const QString ver = QString::number(appVersion.majorVersion()) % QLatin1Char('.') % QString::number(appVersion.minorVersion());
120 	const QString locale = LanguageLoader::getLocalCode();
121 	const QString mapping = getInstance().getContextMapping(pObjectName);
122 	return mBaseUrl % QStringLiteral("help") % QLatin1Char('/') % ver % QLatin1Char('/') % locale % QLatin1Char('/') % osPath % QLatin1Char('/') % mapping;
123 }
124 
125 
openContextHelp(const QString & pObjectName)126 void HelpAction::openContextHelp(const QString& pObjectName)
127 {
128 	const auto& url = QUrl(getOnlineUrl(pObjectName));
129 	qCDebug(gui) << "Open online help:" << pObjectName << '|' << url;
130 	QDesktopServices::openUrl(url);
131 }
132