resource_utils.h 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #pragma once
  2. #include <QCoreApplication>
  3. #include <QDir>
  4. #include <QFileInfo>
  5. #include <QString>
  6. #include <QStringList>
  7. namespace Utils::Resources {
  8. // Resolve resources that may have been relocated under a Qt QML module prefix.
  9. inline auto resolveResourcePath(const QString &path) -> QString {
  10. if (path.isEmpty()) {
  11. return path;
  12. }
  13. const bool is_resource = path.startsWith(QStringLiteral(":/"));
  14. const QString relative = is_resource ? path.mid(2) : QString{};
  15. auto exists = [](const QString &candidate) {
  16. QFileInfo const info(candidate);
  17. if (info.exists()) {
  18. return true;
  19. }
  20. QDir const dir(candidate);
  21. return dir.exists();
  22. };
  23. // For Qt resource paths, prefer a filesystem override when available so live
  24. // shader edits are picked up without rebuilding the resource bundle.
  25. if (is_resource) {
  26. auto search_upwards = [&](const QString &startDir) -> QString {
  27. if (startDir.isEmpty()) {
  28. return {};
  29. }
  30. QDir dir(startDir);
  31. for (int i = 0; i < 5; ++i) {
  32. QString candidate = dir.filePath(relative);
  33. if (exists(candidate)) {
  34. return candidate;
  35. }
  36. if (!dir.cdUp()) {
  37. break;
  38. }
  39. }
  40. return {};
  41. };
  42. if (QString candidate =
  43. search_upwards(QCoreApplication::applicationDirPath());
  44. !candidate.isEmpty()) {
  45. return candidate;
  46. }
  47. if (QString candidate = search_upwards(QDir::currentPath());
  48. !candidate.isEmpty()) {
  49. return candidate;
  50. }
  51. }
  52. if (exists(path)) {
  53. return path;
  54. }
  55. if (!is_resource) {
  56. return path;
  57. }
  58. static const QStringList kAlternateRoots = {
  59. QStringLiteral(":/StandardOfIron"),
  60. QStringLiteral(":/qt/qml/StandardOfIron"),
  61. QStringLiteral(":/qt/qml/default")};
  62. for (const auto &root : kAlternateRoots) {
  63. QString candidate = root;
  64. if (!candidate.endsWith('/')) {
  65. candidate.append('/');
  66. }
  67. candidate.append(relative);
  68. if (exists(candidate)) {
  69. return candidate;
  70. }
  71. }
  72. return path;
  73. }
  74. } // namespace Utils::Resources