helper.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * helper.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "helper.h"
  12. #include "mainwindow_moc.h"
  13. #include "settingsView/csettingsview_moc.h"
  14. #include "modManager/cmodlistview_moc.h"
  15. #include "../lib/CConfigHandler.h"
  16. #include <QObject>
  17. #include <QScroller>
  18. #ifdef VCMI_ANDROID
  19. #include <QAndroidJniObject>
  20. #include <QtAndroid>
  21. #endif
  22. #ifdef VCMI_IOS
  23. #include "ios/revealdirectoryinfiles.h"
  24. #include "iOS_utils.h"
  25. #endif
  26. #ifdef VCMI_MOBILE
  27. static QScrollerProperties generateScrollerProperties()
  28. {
  29. QScrollerProperties result;
  30. result.setScrollMetric(QScrollerProperties::OvershootDragResistanceFactor, 0.25);
  31. result.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 0.25);
  32. result.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
  33. return result;
  34. }
  35. #endif
  36. #ifdef VCMI_ANDROID
  37. static QString safeEncode(QString uri)
  38. {
  39. // %-encode unencoded parts of string.
  40. // This is needed because Qt returns a mixed content url with %-encoded and unencoded parts. On Android >= 13 this causes problems reading these files, when using spaces and unicode characters in folder or filename.
  41. // Only these should be encoded (other typically %-encoded chars should not be encoded because this leads to errors).
  42. // Related, but seems not completly fixed (at least in our setup): https://bugreports.qt.io/browse/QTBUG-114435
  43. if (!uri.startsWith("content://", Qt::CaseInsensitive))
  44. return uri;
  45. return QString::fromUtf8(QUrl::toPercentEncoding(uri, "!#$&'()*+,/:;=?@[]<>{}\"`^~%"));
  46. }
  47. #endif
  48. namespace Helper
  49. {
  50. void loadSettings()
  51. {
  52. settings.init("config/settings.json", "vcmi:settings");
  53. persistentStorage.init("config/persistentStorage.json", "");
  54. }
  55. void reLoadSettings()
  56. {
  57. loadSettings();
  58. for(const auto widget : qApp->allWidgets())
  59. if(auto settingsView = qobject_cast<CSettingsView *>(widget))
  60. {
  61. settingsView->loadSettings();
  62. break;
  63. }
  64. getMainWindow()->updateTranslation();
  65. getMainWindow()->getModView()->reload();
  66. }
  67. void enableScrollBySwiping(QObject * scrollTarget)
  68. {
  69. #ifdef VCMI_MOBILE
  70. QScroller::grabGesture(scrollTarget, QScroller::LeftMouseButtonGesture);
  71. QScroller * scroller = QScroller::scroller(scrollTarget);
  72. scroller->setScrollerProperties(generateScrollerProperties());
  73. #endif
  74. }
  75. QString getRealPath(QString path)
  76. {
  77. #ifdef VCMI_ANDROID
  78. if(path.contains("content://", Qt::CaseInsensitive))
  79. {
  80. auto str = QAndroidJniObject::fromString(safeEncode(path));
  81. return QAndroidJniObject::callStaticObjectMethod("eu/vcmi/vcmi/util/FileUtil", "getFilenameFromUri", "(Ljava/lang/String;Landroid/content/Context;)Ljava/lang/String;", str.object<jstring>(), QtAndroid::androidContext().object()).toString();
  82. }
  83. return path;
  84. #else
  85. return path;
  86. #endif
  87. }
  88. bool performNativeCopy(QString src, QString dst)
  89. {
  90. #ifdef VCMI_ANDROID
  91. auto srcStr = QAndroidJniObject::fromString(safeEncode(src));
  92. auto dstStr = QAndroidJniObject::fromString(safeEncode(dst));
  93. QAndroidJniObject::callStaticObjectMethod("eu/vcmi/vcmi/util/FileUtil", "copyFileFromUri", "(Ljava/lang/String;Ljava/lang/String;Landroid/content/Context;)V", srcStr.object<jstring>(), dstStr.object<jstring>(), QtAndroid::androidContext().object());
  94. if(QFileInfo(dst).exists())
  95. return true;
  96. else
  97. return false;
  98. #else
  99. return QFile::copy(src, dst);
  100. #endif
  101. }
  102. void revealDirectoryInFileBrowser(QString path)
  103. {
  104. const auto dirUrl = QUrl::fromLocalFile(QFileInfo{path}.absoluteFilePath());
  105. #ifdef VCMI_IOS
  106. iOS_utils::revealDirectoryInFiles(dirUrl);
  107. #else
  108. QDesktopServices::openUrl(dirUrl);
  109. #endif
  110. }
  111. MainWindow * getMainWindow()
  112. {
  113. foreach(QWidget *w, qApp->allWidgets())
  114. if(auto mainWin = qobject_cast<MainWindow*>(w))
  115. return mainWin;
  116. return nullptr;
  117. }
  118. void keepScreenOn(bool isEnabled)
  119. {
  120. #if defined(VCMI_ANDROID)
  121. QtAndroid::runOnAndroidThread([isEnabled]
  122. {
  123. QtAndroid::androidActivity().callMethod<void>("keepScreenOn", "(Z)V", isEnabled);
  124. });
  125. #elif defined(VCMI_IOS)
  126. iOS_utils::keepScreenOn(isEnabled);
  127. #endif
  128. }
  129. }