QGIS API Documentation 3.30.0-'s-Hertogenbosch (f186b8efe0)
qgshelp.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgshelp.cpp
3 --------------------------------------
4 Date : December 2016
5 Copyright : (C) 2016 by Alexander Bruy
6 Email : alexander dot bruy at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgshelp.h"
17
18#include "qgis.h"
19#include "qgssettings.h"
20#include "qgsapplication.h"
22#include "qgsmessagelog.h"
26
27#include <QUrl>
28#include <QFileInfo>
29#include <QTcpSocket>
30#include <QDesktopServices>
31#include <QRegularExpression>
32#include <QNetworkProxy>
33#include <QNetworkProxyFactory>
34
35#include <memory>
36
37
38void QgsHelp::openHelp( const QString &key )
39{
40 QDesktopServices::openUrl( QgsHelp::helpUrl( key ) );
41}
42
43QUrl QgsHelp::helpUrl( const QString &key )
44{
45 QUrl helpNotFound = QUrl::fromLocalFile( QgsApplication::pkgDataPath() + "/doc/nohelp.html" );
46
47 const QgsSettings settings;
48 const QStringList paths = settings.value( QStringLiteral( "help/helpSearchPath" ) ).toStringList();
49 if ( paths.isEmpty() )
50 {
51 QgsMessageLog::logMessage( QObject::tr( "Help location is not configured!" ), QObject::tr( "QGIS Help" ) );
52 return helpNotFound;
53 }
54
55 std::unique_ptr<QgsExpressionContextScope> scope( QgsExpressionContextUtils::globalScope() );
56
57 QUrl helpUrl;
58 QString helpPath, fullPath;
59 bool helpFound = false;
60
61 const auto constPaths = paths;
62 for ( const QString &path : constPaths )
63 {
64 if ( path.endsWith( QLatin1String( "\\" ) ) || path.endsWith( QLatin1Char( '/' ) ) )
65 {
66 fullPath = path.left( path.size() - 1 );
67 }
68 else
69 {
70 fullPath = path;
71 }
72
73 const auto constVariableNames = scope->variableNames();
74 for ( const QString &var : constVariableNames )
75 {
76 const QRegularExpression rx( QStringLiteral( "(<!\\$\\$)*(\\$%1)" ).arg( var ) );
77 fullPath.replace( rx, scope->variable( var ).toString() );
78 }
79 fullPath.replace( QRegularExpression( QStringLiteral( "(\\$\\$)" ) ), QStringLiteral( "$" ) );
80
81 helpPath = QStringLiteral( "%1/%2" ).arg( fullPath, key );
82
83 QgsMessageLog::logMessage( QObject::tr( "Trying to open help using key '%1'. Full URI is '%2'…" ).arg( key ).arg( helpPath ), QObject::tr( "QGIS Help" ), Qgis::MessageLevel::Info );
84
85 if ( helpPath.startsWith( QLatin1String( "http" ) ) )
86 {
87 if ( !QgsHelp::urlExists( helpPath ) )
88 {
89 continue;
90 }
91 helpUrl = QUrl( helpPath );
92 }
93 else
94 {
95 const QString filePath = helpPath.mid( 0, helpPath.lastIndexOf( QLatin1Char( '#' ) ) );
96 if ( !QFileInfo::exists( filePath ) )
97 {
98 continue;
99 }
100 helpUrl = QUrl::fromLocalFile( filePath );
101 const int pos = helpPath.lastIndexOf( QLatin1Char( '#' ) );
102 if ( pos != -1 )
103 {
104 helpUrl.setFragment( helpPath.mid( helpPath.lastIndexOf( QLatin1Char( '#' ) ) + 1, -1 ) );
105 }
106 }
107
108 helpFound = true;
109 break;
110 }
111
112 return helpFound ? helpUrl : helpNotFound;
113}
114
115bool QgsHelp::urlExists( const QString &url )
116{
117 const QUrl helpUrl( url );
118
120 QNetworkRequest req( helpUrl );
121 QgsSetRequestInitiatorClass( req, QStringLiteral( "QgsHelp" ) );
122
123 QgsBlockingNetworkRequest::ErrorCode errCode = request.head( req );
124 return errCode == QgsBlockingNetworkRequest::NoError;
125}
static QString pkgDataPath()
Returns the common root path of all application data directories.
A thread safe class for performing blocking (sync) network requests, with full support for QGIS proxy...
ErrorCode head(QNetworkRequest &request, bool forceRefresh=false, QgsFeedback *feedback=nullptr)
Performs a "head" operation on the specified request.
@ NoError
No error was encountered.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
static QUrl helpUrl(const QString &key)
Returns URI of the help topic for the given key.
Definition: qgshelp.cpp:43
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:38
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
This class is a composition of two QSettings instances:
Definition: qgssettings.h:63
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
#define QgsSetRequestInitiatorClass(request, _class)