QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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"
27
28#include <QUrl>
29#include <QFileInfo>
30#include <QTcpSocket>
31#include <QDesktopServices>
32#include <QRegularExpression>
33#include <QNetworkProxy>
34#include <QNetworkProxyFactory>
35
36#include <memory>
37
38
39void QgsHelp::openHelp( const QString &key )
40{
41 QDesktopServices::openUrl( QgsHelp::helpUrl( key ) );
42}
43
44QUrl QgsHelp::helpUrl( const QString &key )
45{
46 QUrl helpNotFound = QUrl::fromLocalFile( QgsApplication::pkgDataPath() + "/doc/nohelp.html" );
47
48 const QgsSettings settings;
49 const QStringList paths = settings.value( QStringLiteral( "help/helpSearchPath" ) ).toStringList();
50 if ( paths.isEmpty() )
51 {
52 QgsMessageLog::logMessage( QObject::tr( "Help location is not configured!" ), QObject::tr( "QGIS Help" ) );
53 return helpNotFound;
54 }
55
56 std::unique_ptr<QgsExpressionContextScope> scope( QgsExpressionContextUtils::globalScope() );
57
58 QUrl helpUrl;
59 QString helpPath, fullPath;
60 bool helpFound = false;
61
62 const auto constPaths = paths;
63 for ( const QString &path : constPaths )
64 {
65 if ( path.endsWith( QLatin1String( "\\" ) ) || path.endsWith( QLatin1Char( '/' ) ) )
66 {
67 fullPath = path.left( path.size() - 1 );
68 }
69 else
70 {
71 fullPath = path;
72 }
73
74 const auto constVariableNames = scope->variableNames();
75 for ( const QString &var : constVariableNames )
76 {
77 const QRegularExpression rx( QStringLiteral( "(<!\\$\\$)*(\\$%1)" ).arg( var ) );
78 fullPath.replace( rx, scope->variable( var ).toString() );
79 }
80 const thread_local QRegularExpression pathRx( QStringLiteral( "(\\$\\$)" ) );
81 fullPath.replace( pathRx, QStringLiteral( "$" ) );
82
83 helpPath = QStringLiteral( "%1/%2" ).arg( fullPath, key );
84
85 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 );
86
87 if ( helpPath.startsWith( QLatin1String( "http" ) ) )
88 {
89 if ( !QgsHelp::urlExists( helpPath ) )
90 {
91 continue;
92 }
93 helpUrl = QUrl( helpPath );
94 }
95 else
96 {
97 const QString filePath = helpPath.mid( 0, helpPath.lastIndexOf( QLatin1Char( '#' ) ) );
98 if ( !QFileInfo::exists( filePath ) )
99 {
100 continue;
101 }
102 helpUrl = QUrl::fromLocalFile( filePath );
103 const int pos = helpPath.lastIndexOf( QLatin1Char( '#' ) );
104 if ( pos != -1 )
105 {
106 helpUrl.setFragment( helpPath.mid( helpPath.lastIndexOf( QLatin1Char( '#' ) ) + 1, -1 ) );
107 }
108 }
109
110 helpFound = true;
111 break;
112 }
113
114 return helpFound ? helpUrl : helpNotFound;
115}
116
117bool QgsHelp::urlExists( const QString &url )
118{
119 const QUrl helpUrl( url );
120
122 QNetworkRequest req( helpUrl );
123 QgsSetRequestInitiatorClass( req, QStringLiteral( "QgsHelp" ) );
124
125 QgsBlockingNetworkRequest::ErrorCode errCode = request.head( req );
126 return errCode == QgsBlockingNetworkRequest::NoError;
127}
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:44
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:39
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:64
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
#define QgsSetRequestInitiatorClass(request, _class)