AppFile.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. * Copyright (c) 2020, Linus Groh <linusg@serenityos.org>
  3. * Copyright (c) 2021, Spencer Dixon <spencercdixon@gmail.com>
  4. * Copyright (c) 2022, the SerenityOS developers.
  5. *
  6. * SPDX-License-Identifier: BSD-2-Clause
  7. */
  8. #include <AK/Function.h>
  9. #include <AK/Vector.h>
  10. #include <LibCore/ConfigFile.h>
  11. #include <LibCore/DirIterator.h>
  12. #include <LibCore/Process.h>
  13. #include <LibDesktop/AppFile.h>
  14. namespace Desktop {
  15. NonnullRefPtr<AppFile> AppFile::get_for_app(StringView app_name)
  16. {
  17. auto path = String::formatted("{}/{}.af", APP_FILES_DIRECTORY, app_name);
  18. return open(path);
  19. }
  20. NonnullRefPtr<AppFile> AppFile::open(StringView path)
  21. {
  22. return adopt_ref(*new AppFile(path));
  23. }
  24. void AppFile::for_each(Function<void(NonnullRefPtr<AppFile>)> callback, StringView directory)
  25. {
  26. Core::DirIterator di(directory, Core::DirIterator::SkipDots);
  27. if (di.has_error())
  28. return;
  29. while (di.has_next()) {
  30. auto name = di.next_path();
  31. if (!name.ends_with(".af"))
  32. continue;
  33. auto path = String::formatted("{}/{}", directory, name);
  34. auto af = AppFile::open(path);
  35. if (!af->is_valid())
  36. continue;
  37. callback(af);
  38. }
  39. }
  40. AppFile::AppFile(StringView path)
  41. : m_config(Core::ConfigFile::open(path).release_value_but_fixme_should_propagate_errors())
  42. , m_valid(validate())
  43. {
  44. }
  45. bool AppFile::validate() const
  46. {
  47. if (m_config->read_entry("App", "Name").trim_whitespace().is_empty())
  48. return false;
  49. if (m_config->read_entry("App", "Executable").trim_whitespace().is_empty())
  50. return false;
  51. return true;
  52. }
  53. String AppFile::name() const
  54. {
  55. auto name = m_config->read_entry("App", "Name").trim_whitespace();
  56. VERIFY(!name.is_empty());
  57. return name;
  58. }
  59. String AppFile::executable() const
  60. {
  61. auto executable = m_config->read_entry("App", "Executable").trim_whitespace();
  62. VERIFY(!executable.is_empty());
  63. return executable;
  64. }
  65. String AppFile::description() const
  66. {
  67. return m_config->read_entry("App", "Description").trim_whitespace();
  68. }
  69. String AppFile::category() const
  70. {
  71. return m_config->read_entry("App", "Category").trim_whitespace();
  72. }
  73. String AppFile::icon_path() const
  74. {
  75. return m_config->read_entry("App", "IconPath").trim_whitespace();
  76. }
  77. GUI::Icon AppFile::icon() const
  78. {
  79. auto override_icon = icon_path();
  80. // FIXME: support pointing to actual .ico files
  81. if (!override_icon.is_empty())
  82. return GUI::FileIconProvider::icon_for_path(override_icon);
  83. return GUI::FileIconProvider::icon_for_path(executable());
  84. }
  85. bool AppFile::run_in_terminal() const
  86. {
  87. return m_config->read_bool_entry("App", "RunInTerminal", false);
  88. }
  89. Vector<String> AppFile::launcher_file_types() const
  90. {
  91. Vector<String> file_types;
  92. for (auto& entry : m_config->read_entry("Launcher", "FileTypes").split(',')) {
  93. entry = entry.trim_whitespace();
  94. if (!entry.is_empty())
  95. file_types.append(entry);
  96. }
  97. return file_types;
  98. }
  99. Vector<String> AppFile::launcher_protocols() const
  100. {
  101. Vector<String> protocols;
  102. for (auto& entry : m_config->read_entry("Launcher", "Protocols").split(',')) {
  103. entry = entry.trim_whitespace();
  104. if (!entry.is_empty())
  105. protocols.append(entry);
  106. }
  107. return protocols;
  108. }
  109. bool AppFile::spawn() const
  110. {
  111. if (!is_valid())
  112. return false;
  113. auto pid = Core::Process::spawn(executable());
  114. if (pid < 0)
  115. return false;
  116. return true;
  117. }
  118. }