QGIS API Documentation 3.36.0-Maidenhead (09951dc0acf)
Loading...
Searching...
No Matches
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 const thread_local QRegularExpression pathRx( QStringLiteral( "(\\$\\$)" ) );
80 fullPath.replace( pathRx, QStringLiteral( "$" ) );
81
82 helpPath = QStringLiteral( "%1/%2" ).arg( fullPath, key );
83
84 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 );
85
86 if ( helpPath.startsWith( QLatin1String( "http" ) ) )
87 {
88 if ( !QgsHelp::urlExists( helpPath ) )
89 {
90 continue;
91 }
92 helpUrl = QUrl( helpPath );
93 }
94 else
95 {
96 const QString filePath = helpPath.mid( 0, helpPath.lastIndexOf( QLatin1Char( '#' ) ) );
97 if ( !QFileInfo::exists( filePath ) )
98 {
99 continue;
100 }
101 helpUrl = QUrl::fromLocalFile( filePath );
102 const int pos = helpPath.lastIndexOf( QLatin1Char( '#' ) );
103 if ( pos != -1 )
104 {
105 helpUrl.setFragment( helpPath.mid( helpPath.lastIndexOf( QLatin1Char( '#' ) ) + 1, -1 ) );
106 }
107 }
108
109 helpFound = true;
110 break;
111 }
112
113 return helpFound ? helpUrl : helpNotFound;
114}
115
116bool QgsHelp::urlExists( const QString &url )
117{
118 const QUrl helpUrl( url );
119
121 QNetworkRequest req( helpUrl );
122 QgsSetRequestInitiatorClass( req, QStringLiteral( "QgsHelp" ) );
123
124 QgsBlockingNetworkRequest::ErrorCode errCode = request.head( req );
125 return errCode == QgsBlockingNetworkRequest::NoError;
126}
@ Info
Information message.
Definition qgis.h:100
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:64
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
#define QgsSetRequestInitiatorClass(request, _class)