PageRenderTime 59ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/src/gui/qgshelp.cpp

http://github.com/qgis/Quantum-GIS
C++ | 178 lines | 153 code | 11 blank | 14 comment | 3 complexity | d54615cd5a8c47c983f69c4777f68652 MD5 | raw file
Possible License(s): LGPL-2.0, GPL-3.0, GPL-2.0, CC-BY-SA-3.0, MIT, 0BSD, BSD-3-Clause
  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. #include "qgshelp.h"
  16. #include "qgis.h"
  17. #include "qgssettings.h"
  18. #include "qgsapplication.h"
  19. #include "qgsexpressioncontext.h"
  20. #include "qgsmessagelog.h"
  21. #include "qgsexpressioncontextutils.h"
  22. #include <QUrl>
  23. #include <QFileInfo>
  24. #include <QTcpSocket>
  25. #include <QDesktopServices>
  26. #include <QRegularExpression>
  27. #include <QNetworkProxy>
  28. #include <QNetworkProxyFactory>
  29. #include <memory>
  30. void QgsHelp::openHelp( const QString &key )
  31. {
  32. QDesktopServices::openUrl( QgsHelp::helpUrl( key ) );
  33. }
  34. QUrl QgsHelp::helpUrl( const QString &key )
  35. {
  36. QUrl helpNotFound = QUrl::fromLocalFile( QgsApplication::pkgDataPath() + "/doc/nohelp.html" );
  37. QgsSettings settings;
  38. QStringList paths = settings.value( QStringLiteral( "help/helpSearchPath" ) ).toStringList();
  39. if ( paths.isEmpty() )
  40. {
  41. QgsMessageLog::logMessage( QObject::tr( "Help location is not configured!" ), QObject::tr( "QGIS Help" ) );
  42. return helpNotFound;
  43. }
  44. std::unique_ptr<QgsExpressionContextScope> scope( QgsExpressionContextUtils::globalScope() );
  45. QUrl helpUrl;
  46. QString helpPath, fullPath;
  47. bool helpFound = false;
  48. const auto constPaths = paths;
  49. for ( const QString &path : constPaths )
  50. {
  51. if ( path.endsWith( QLatin1String( "\\" ) ) || path.endsWith( QLatin1String( "/" ) ) )
  52. {
  53. fullPath = path.left( path.size() - 1 );
  54. }
  55. else
  56. {
  57. fullPath = path;
  58. }
  59. const auto constVariableNames = scope->variableNames();
  60. for ( const QString &var : constVariableNames )
  61. {
  62. QRegularExpression rx( QStringLiteral( "(<!\\$\\$)*(\\$%1)" ).arg( var ) );
  63. fullPath.replace( rx, scope->variable( var ).toString() );
  64. }
  65. fullPath.replace( QRegularExpression( QStringLiteral( "(\\$\\$)" ) ), QStringLiteral( "$" ) );
  66. helpPath = QStringLiteral( "%1/%2" ).arg( fullPath, key );
  67. QgsMessageLog::logMessage( QObject::tr( "Trying to open help using key '%1'. Full URI is '%2'…" ).arg( key ).arg( helpPath ), QObject::tr( "QGIS Help" ), Qgis::Info );
  68. if ( helpPath.startsWith( QLatin1String( "http" ) ) )
  69. {
  70. if ( !QgsHelp::urlExists( helpPath ) )
  71. {
  72. continue;
  73. }
  74. helpUrl = QUrl( helpPath );
  75. }
  76. else
  77. {
  78. QString filePath = helpPath.mid( 0, helpPath.lastIndexOf( QLatin1String( "#" ) ) );
  79. if ( !QFileInfo::exists( filePath ) )
  80. {
  81. continue;
  82. }
  83. helpUrl = QUrl::fromLocalFile( filePath );
  84. int pos = helpPath.lastIndexOf( QLatin1String( "#" ) );
  85. if ( pos != -1 )
  86. {
  87. helpUrl.setFragment( helpPath.mid( helpPath.lastIndexOf( QLatin1String( "#" ) ) + 1, -1 ) );
  88. }
  89. }
  90. helpFound = true;
  91. break;
  92. }
  93. return helpFound ? helpUrl : helpNotFound;
  94. }
  95. bool QgsHelp::urlExists( const QString &url )
  96. {
  97. QUrl helpUrl( url );
  98. QTcpSocket socket;
  99. QgsSettings settings;
  100. bool proxyEnabled = settings.value( QStringLiteral( "proxy/proxyEnabled" ), false ).toBool();
  101. if ( proxyEnabled )
  102. {
  103. QNetworkProxy proxy;
  104. QString proxyHost = settings.value( QStringLiteral( "proxy/proxyHost" ), QString() ).toString();
  105. int proxyPort = settings.value( QStringLiteral( "proxy/proxyPort" ), QString() ).toString().toInt();
  106. QString proxyUser = settings.value( QStringLiteral( "proxy/proxyUser" ), QString() ).toString();
  107. QString proxyPassword = settings.value( QStringLiteral( "proxy/proxyPassword" ), QString() ).toString();
  108. QString proxyTypeString = settings.value( QStringLiteral( "proxy/proxyType" ), QString() ).toString();
  109. if ( proxyTypeString == QLatin1String( "DefaultProxy" ) )
  110. {
  111. QList<QNetworkProxy> proxies = QNetworkProxyFactory::systemProxyForQuery();
  112. if ( !proxies.isEmpty() )
  113. {
  114. proxy = proxies.first();
  115. }
  116. }
  117. else
  118. {
  119. QNetworkProxy::ProxyType proxyType = QNetworkProxy::DefaultProxy;
  120. if ( proxyTypeString == QLatin1String( "Socks5Proxy" ) )
  121. {
  122. proxyType = QNetworkProxy::Socks5Proxy;
  123. }
  124. else if ( proxyTypeString == QLatin1String( "HttpProxy" ) )
  125. {
  126. proxyType = QNetworkProxy::HttpProxy;
  127. }
  128. else if ( proxyTypeString == QLatin1String( "HttpCachingProxy" ) )
  129. {
  130. proxyType = QNetworkProxy::HttpCachingProxy;
  131. }
  132. else if ( proxyTypeString == QLatin1String( "FtpCachingProxy" ) )
  133. {
  134. proxyType = QNetworkProxy::FtpCachingProxy;
  135. }
  136. proxy = QNetworkProxy( proxyType, proxyHost, proxyPort, proxyUser, proxyPassword );
  137. }
  138. socket.setProxy( proxy );
  139. }
  140. socket.connectToHost( helpUrl.host(), 80 );
  141. if ( socket.waitForConnected() )
  142. {
  143. socket.write( "HEAD " + helpUrl.path().toUtf8() + " HTTP/1.1\r\n"
  144. "Host: " + helpUrl.host().toUtf8() + "\r\n\r\n" );
  145. if ( socket.waitForReadyRead() )
  146. {
  147. QByteArray bytes = socket.readAll();
  148. if ( bytes.contains( "200 OK" ) || bytes.contains( "302 Found" ) || bytes.contains( "301 Moved" ) )
  149. {
  150. return true;
  151. }
  152. }
  153. }
  154. return false;
  155. }