Skip to content

Commit

Permalink
new QgsHelp class that uses QGIS User Guide as help source
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbruy committed Jan 10, 2017
1 parent 981810b commit 9a94da8
Show file tree
Hide file tree
Showing 5 changed files with 240 additions and 1 deletion.
2 changes: 1 addition & 1 deletion doc/CMakeLists.txt
Expand Up @@ -22,7 +22,7 @@ ELSE(TXT2TAGS_EXECUTABLE)
)
ENDIF(TXT2TAGS_EXECUTABLE)

SET(QGIS_DOC_FILES ${QGIS_DOC_FILES} index.html news.html developersmap.html contributors.json favicon.ico style.css release-sponsors.html AUTHORS CONTRIBUTORS SPONSORS DONORS TRANSLATORS LICENSE)
SET(QGIS_DOC_FILES ${QGIS_DOC_FILES} index.html news.html developersmap.html nohelp.html contributors.json favicon.ico style.css release-sponsors.html AUTHORS CONTRIBUTORS SPONSORS DONORS TRANSLATORS LICENSE)

INSTALL(FILES ${QGIS_DOC_FILES} DESTINATION ${QGIS_DATA_DIR}/doc)
INSTALL(FILES ../images/icons/qgis-icon-60x60.png DESTINATION ${QGIS_DATA_DIR}/doc/images)
Expand Down
19 changes: 19 additions & 0 deletions doc/nohelp.html
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<title>No help found</title>
<meta charset="UTF-8">
</head>

<body>
<center><a href="http://qgis.org"><img src="qgis-icon-60x60.png" border=0></a></center>
<h1><center>Oops!</center></h1>
<p>Sorry, help is not available. Probably you have no Internet connection,
location of the help files is not configured or there is no help content
for requested topic.</p>
<p>Please make sure that correct location of the help files specified
in the QGIS options dialog (Settings&nbsp;&rarr; Options&nbsp;&rarr;
System).</p>
</body>

</html>
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -135,6 +135,7 @@ SET(QGIS_CORE_SRCS
qgsgeometryvalidator.cpp
qgsgml.cpp
qgsgmlschema.cpp
qgshelp.cpp
qgshistogram.cpp
qgsinterval.cpp
qgsjsonutils.cpp
Expand Down Expand Up @@ -481,6 +482,7 @@ SET(QGIS_CORE_MOC_HDRS
qgsgeometryvalidator.h
qgsgml.h
qgsgmlschema.h
qgshelp.h
qgsmaplayer.h
qgsmaplayerlegend.h
qgsmaplayermodel.h
Expand Down
145 changes: 145 additions & 0 deletions src/core/qgshelp.cpp
@@ -0,0 +1,145 @@
/***************************************************************************
qgshelp.cpp
--------------------------------------
Date : December 2016
Copyright : (C) 2016 by Alexander Bruy
Email : alexander dot bruy at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgshelp.h"

#include <QSettings>
#include <QLocale>
#include <QUrl>
#include <QFileInfo>
#include <QTcpSocket>
#include <QDesktopServices>

#include "qgis.h"
#include "qgsapplication.h"

QgsHelp *QgsHelp::sHelp = nullptr; // Singleton instance

void QgsHelp::openHelp( const QString& key )
{
if ( !sHelp )
{
sHelp = new QgsHelp();
}

QDesktopServices::openUrl( sHelp->helpUrl( key ) );
}

QUrl QgsHelp::helpUrl( const QString& key )
{
if ( !sHelp )
{
sHelp = new QgsHelp();
}

QSettings settings;
QUrl helpNotFound = QUrl::fromLocalFile( QgsApplication::pkgDataPath() + "/doc/nohelp.html" );

QString paths = settings.value( QStringLiteral( "help/helpSearchPath" ), "" ).toString();
if ( paths.isEmpty() )
{
return helpNotFound;
}

QString qgisLocale;
bool overrideLocale = settings.value( QStringLiteral( "locale/overrideFlag" ), false ).toBool();
if ( overrideLocale )
{
qgisLocale = settings.value( QStringLiteral( "locale/userLocale" ), "" ).toString();
}
else
{
qgisLocale = QLocale::system().name().left( 2 );
}

QString qgisVersion;
if ( Qgis::QGIS_VERSION_INT / 100 % 100 == 99 )
{
qgisVersion = QStringLiteral( "testing" );
qgisLocale = QStringLiteral( "en" );
}
else
{
qgisVersion = QStringLiteral( "%1.%2" ).arg( Qgis::QGIS_VERSION_INT / 10000 ).arg( Qgis::QGIS_VERSION_INT / 100 % 100 );
}

QString suffix = QStringLiteral( "%1/%2/docs/user_manual/%3" ).arg( qgisVersion ).arg( qgisLocale ).arg( key );

QUrl myUrl;
QString helpPath;
bool helpFound = false;

QStringList pathList = paths.split( '|' );
QStringList::const_iterator pathIt = pathList.constBegin();
for ( ; pathIt != pathList.constEnd(); ++pathIt )
{
helpPath = QStringLiteral( "%1/%2" ).arg( *pathIt ).arg( suffix );

if (( *pathIt ).startsWith( QStringLiteral( "http://" ) ) )
{
if ( !sHelp->urlExists( helpPath ) )
{
continue;
}
myUrl = QUrl( helpPath );
}
else
{
if ( !QFileInfo( helpPath.mid( 0, helpPath.lastIndexOf( "#" ) ) ).exists() )
{
continue;
}
myUrl = QUrl::fromLocalFile( helpPath );
myUrl.setFragment( helpPath.mid( helpPath.lastIndexOf( "#" ), -1 ) );
}

helpFound = true;
break;
}

return helpFound ? myUrl : helpNotFound;
}


QgsHelp::QgsHelp()
{
}

QgsHelp::~QgsHelp()
{
}

bool QgsHelp::urlExists( const QString& url ) const
{
QUrl myUrl( url );
QTcpSocket socket;

socket.connectToHost( myUrl.host(), 80 );
if ( socket.waitForConnected() )
{
socket.write( "HEAD " + myUrl.path().toUtf8() + " HTTP/1.1\r\n"
"Host: " + myUrl.host().toUtf8() + "\r\n\r\n" );
if ( socket.waitForReadyRead() )
{
QByteArray bytes = socket.readAll();
if ( bytes.contains( "200 OK" ) || bytes.contains( "302 Found" ) )
{
return true;
}
}
}

return false;
}
73 changes: 73 additions & 0 deletions src/core/qgshelp.h
@@ -0,0 +1,73 @@
/***************************************************************************
qgshelp.h
--------------------------------------
Date : December 2016
Copyright : (C) 2016 by Alexander Bruy
Email : alexander dot bruy at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSHELP_H
#define QGSHELP_H

#include <QObject>

/** \ingroup core
* @brief The class provides help URI for the given key.
*
* Help can be stored online, on the local directory or on the intranet
* server. Location of the QGIS help can be configured in QGIS options.
* Multiple locations are supported, they will be used in order of
* preference, from top to bottom.
*
* URI construction takes in account following information:
* - QGIS version
* - language of the QGIS UI
*
* If no help found, default error page with information how to setup
* help system will be shown.
*
* @note added in QGIS 3.0
*/
class CORE_EXPORT QgsHelp : public QObject
{
Q_OBJECT
public:
/** Opens help topic for the given help key using default system
* web browser. If help topic not found, builtin error page shown.
* @param key key which identified help topic
* @note added in QGIS 3.0
*/
static void openHelp( const QString& key );

/** Returns URI of the help topic for the given key. If help topic
* not found, URI of the builtin error page returned.
* @param key key which identified help topic
* @note added in QGIS 3.0
*/
static QUrl helpUrl( const QString& key );

private:
//! Constructor
QgsHelp();

//! Destructor
~QgsHelp();

/** Check if given URL accessible by issuing HTTP HEAD request.
* Returns true if URL accessible, false otherwise.
* @param url URL to check
* @note added in QGIS 3.0
*/
bool urlExists( const QString& url ) const;

static QgsHelp* sHelp;
};

#endif // QGSHELP_H

0 comments on commit 9a94da8

Please sign in to comment.