PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/DisplayManual.cpp

https://bitbucket.org/widefido/js8call
C++ | 157 lines | 130 code | 17 blank | 10 comment | 9 complexity | 085aaa144fda23895ec4c97caba3200d MD5 | raw file
Possible License(s): GPL-3.0
  1. #include "DisplayManual.hpp"
  2. #include <QObject>
  3. #include <QNetworkAccessManager>
  4. #include <QNetworkRequest>
  5. #include <QNetworkReply>
  6. #include <QUrl>
  7. #include <QString>
  8. #include <QDir>
  9. #include <QFileInfo>
  10. #include <QDesktopServices>
  11. #include <QLocale>
  12. #include "revision_utils.hpp"
  13. #include "pimpl_impl.hpp"
  14. namespace
  15. {
  16. class token
  17. : public QObject
  18. {
  19. Q_OBJECT
  20. public:
  21. token (QUrl const& url, QString const& lang, QString const& name_we, QObject * parent = nullptr)
  22. : QObject {parent}
  23. , url_ {url}
  24. , lang_ {lang}
  25. , name_we_ {name_we}
  26. {
  27. }
  28. QUrl url_;
  29. QString lang_;
  30. QString name_we_;
  31. };
  32. }
  33. class DisplayManual::impl final
  34. : public QObject
  35. {
  36. Q_OBJECT
  37. public:
  38. impl (QNetworkAccessManager * qnam)
  39. : qnam_ {qnam}
  40. {
  41. connect (qnam_, &QNetworkAccessManager::finished, this, &DisplayManual::impl::reply_finished);
  42. }
  43. void display (QUrl const& url, QString const& name_we)
  44. {
  45. if (QNetworkAccessManager::Accessible != qnam_->networkAccessible ()) {
  46. // try and recover network access for QNAM
  47. qnam_->setNetworkAccessible (QNetworkAccessManager::Accessible);
  48. }
  49. // try and find a localized manual
  50. auto lang = QLocale::system ().name ();
  51. // try for language and country first
  52. auto file = name_we + '_' + lang + '-' + version () + ".html";
  53. auto target = url.resolved (file);
  54. QNetworkRequest request {target};
  55. request.setRawHeader ("User-Agent", "WSJT-X Manual Checker");
  56. request.setOriginatingObject (new token {url, lang, name_we, this});
  57. auto * reply = qnam_->head (request);
  58. outstanding_requests_ << reply;
  59. }
  60. void reply_finished (QNetworkReply * reply)
  61. {
  62. if (outstanding_requests_.contains (reply))
  63. {
  64. QUrl target;
  65. if (reply->error ())
  66. {
  67. if (auto * tok = qobject_cast<token *> (reply->request ().originatingObject ()))
  68. {
  69. auto pos = tok->lang_.lastIndexOf ('_');
  70. QString file;
  71. if (pos >= 0)
  72. {
  73. tok->lang_.truncate (pos);
  74. file = tok->name_we_ + '_' + tok->lang_ + '-' + version () + ".html";
  75. target = tok->url_.resolved (file);
  76. QNetworkRequest request {target};
  77. request.setRawHeader ("User-Agent", "WSJT-X Manual Checker");
  78. request.setOriginatingObject (tok);
  79. auto * reply = qnam_->head (request);
  80. outstanding_requests_ << reply;
  81. }
  82. else
  83. {
  84. // give up looking and request the default
  85. file = tok->name_we_ + '-' + version () + ".html";
  86. target = tok->url_.resolved (file);
  87. QDesktopServices::openUrl (target);
  88. delete tok;
  89. }
  90. }
  91. }
  92. else
  93. {
  94. // found it
  95. if (auto * tok = qobject_cast<token *> (reply->request ().originatingObject ()))
  96. {
  97. delete tok;
  98. }
  99. QDesktopServices::openUrl (reply->request ().url ());
  100. }
  101. outstanding_requests_.removeOne (reply);
  102. reply->deleteLater ();
  103. }
  104. }
  105. QNetworkAccessManager * qnam_;
  106. QList<QNetworkReply *> outstanding_requests_;
  107. };
  108. #include "DisplayManual.moc"
  109. DisplayManual::DisplayManual (QNetworkAccessManager * qnam, QObject * parent)
  110. : QObject {parent}
  111. , m_ {qnam}
  112. {
  113. }
  114. DisplayManual::~DisplayManual ()
  115. {
  116. }
  117. void DisplayManual::display_html_url (QUrl const& url, QString const& name_we)
  118. {
  119. m_->display (url, name_we);
  120. }
  121. void DisplayManual::display_html_file (QDir const& dir, QString const& name_we)
  122. {
  123. // try and find a localized manual
  124. auto lang = QLocale::system ().name ();
  125. // try for language and country first
  126. auto file = dir.absoluteFilePath (name_we + '_' + lang + '-' + version () + ".html");
  127. if (!QFileInfo::exists (file))
  128. {
  129. // try for language
  130. lang.truncate (lang.lastIndexOf ('_'));
  131. file = dir.absoluteFilePath (name_we + '_' + lang + '-' + version () + ".html");
  132. if (!QFileInfo::exists (file))
  133. {
  134. // use default
  135. file = dir.absoluteFilePath (name_we + '-' + version () + ".html");
  136. }
  137. }
  138. // may fail but browser 404 error is a good as anything
  139. QDesktopServices::openUrl (QUrl {"file:///" + file});
  140. }