123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- /*
- * Copyright (c) 2020, Linus Groh <linusg@serenityos.org>
- * Copyright (c) 2021, Spencer Dixon <spencercdixon@gmail.com>
- * Copyright (c) 2022, the SerenityOS developers.
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #include <AK/Function.h>
- #include <AK/Vector.h>
- #include <LibCore/ConfigFile.h>
- #include <LibCore/DirIterator.h>
- #include <LibCore/Process.h>
- #include <LibDesktop/AppFile.h>
- #include <LibFileSystem/FileSystem.h>
- namespace Desktop {
- ByteString AppFile::app_file_path_for_app(StringView app_name)
- {
- return ByteString::formatted("{}/{}.af", APP_FILES_DIRECTORY, app_name);
- }
- bool AppFile::exists_for_app(StringView app_name)
- {
- return FileSystem::exists(app_file_path_for_app(app_name));
- }
- NonnullRefPtr<AppFile> AppFile::get_for_app(StringView app_name)
- {
- return open(app_file_path_for_app(app_name));
- }
- NonnullRefPtr<AppFile> AppFile::open(StringView path)
- {
- return adopt_ref(*new AppFile(path));
- }
- void AppFile::for_each(Function<void(NonnullRefPtr<AppFile>)> callback, StringView directory)
- {
- Core::DirIterator di(directory, Core::DirIterator::SkipDots);
- if (di.has_error())
- return;
- while (di.has_next()) {
- auto name = di.next_path();
- if (!name.ends_with(".af"sv))
- continue;
- auto path = ByteString::formatted("{}/{}", directory, name);
- auto af = AppFile::open(path);
- if (!af->is_valid())
- continue;
- callback(af);
- }
- }
- AppFile::AppFile(StringView path)
- : m_config(Core::ConfigFile::open(path).release_value_but_fixme_should_propagate_errors())
- , m_valid(validate())
- {
- }
- bool AppFile::validate() const
- {
- if (m_config->read_entry("App", "Name").trim_whitespace().is_empty())
- return false;
- if (m_config->read_entry("App", "Executable").trim_whitespace().is_empty())
- return false;
- return true;
- }
- ByteString AppFile::name() const
- {
- auto name = m_config->read_entry("App", "Name").trim_whitespace().replace("&"sv, ""sv);
- VERIFY(!name.is_empty());
- return name;
- }
- ByteString AppFile::menu_name() const
- {
- auto name = m_config->read_entry("App", "Name").trim_whitespace();
- VERIFY(!name.is_empty());
- return name;
- }
- ByteString AppFile::executable() const
- {
- auto executable = m_config->read_entry("App", "Executable").trim_whitespace();
- VERIFY(!executable.is_empty());
- return executable;
- }
- ByteString AppFile::description() const
- {
- return m_config->read_entry("App", "Description").trim_whitespace();
- }
- ByteString AppFile::category() const
- {
- return m_config->read_entry("App", "Category").trim_whitespace();
- }
- ByteString AppFile::working_directory() const
- {
- return m_config->read_entry("App", "WorkingDirectory").trim_whitespace();
- }
- ByteString AppFile::icon_path() const
- {
- return m_config->read_entry("App", "IconPath").trim_whitespace();
- }
- GUI::Icon AppFile::icon() const
- {
- auto override_icon = icon_path();
- // FIXME: support pointing to actual .ico files
- if (!override_icon.is_empty())
- return GUI::FileIconProvider::icon_for_path(override_icon);
- return GUI::FileIconProvider::icon_for_path(executable());
- }
- bool AppFile::run_in_terminal() const
- {
- return m_config->read_bool_entry("App", "RunInTerminal", false);
- }
- bool AppFile::requires_root() const
- {
- return m_config->read_bool_entry("App", "RequiresRoot", false);
- }
- bool AppFile::exclude_from_system_menu() const
- {
- return m_config->read_bool_entry("App", "ExcludeFromSystemMenu", false);
- }
- Vector<ByteString> AppFile::launcher_mime_types() const
- {
- Vector<ByteString> mime_types;
- for (auto& entry : m_config->read_entry("Launcher", "MimeTypes").split(',')) {
- entry = entry.trim_whitespace();
- if (!entry.is_empty())
- mime_types.append(entry);
- }
- return mime_types;
- }
- Vector<ByteString> AppFile::launcher_file_types() const
- {
- Vector<ByteString> file_types;
- for (auto& entry : m_config->read_entry("Launcher", "FileTypes").split(',')) {
- entry = entry.trim_whitespace();
- if (!entry.is_empty())
- file_types.append(entry);
- }
- return file_types;
- }
- Vector<ByteString> AppFile::launcher_protocols() const
- {
- Vector<ByteString> protocols;
- for (auto& entry : m_config->read_entry("Launcher", "Protocols").split(',')) {
- entry = entry.trim_whitespace();
- if (!entry.is_empty())
- protocols.append(entry);
- }
- return protocols;
- }
- bool AppFile::spawn(ReadonlySpan<StringView> arguments) const
- {
- if (!is_valid())
- return false;
- auto pid = Core::Process::spawn(executable(), arguments, working_directory());
- if (pid.is_error())
- return false;
- return true;
- }
- }
|