mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:47:36 +00:00
Chess: Import/Export chessboards using LibFileSystemAccessClient
With this change, the wpath and cpath promises as well as unveiling user's entire home directory are no longer needed. :^)
This commit is contained in:
parent
613feb1854
commit
9d7345d17b
4 changed files with 16 additions and 48 deletions
|
@ -13,4 +13,4 @@ set(SOURCES
|
||||||
)
|
)
|
||||||
|
|
||||||
serenity_app(Chess ICON app-chess)
|
serenity_app(Chess ICON app-chess)
|
||||||
target_link_libraries(Chess LibChess LibConfig LibGUI LibCore LibMain LibDesktop)
|
target_link_libraries(Chess LibChess LibConfig LibFileSystemAccessClient LibGUI LibCore LibMain LibDesktop)
|
||||||
|
|
|
@ -518,15 +518,8 @@ String ChessWidget::get_fen() const
|
||||||
return m_playback ? m_board_playback.to_fen() : m_board.to_fen();
|
return m_playback ? m_board_playback.to_fen() : m_board.to_fen();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChessWidget::import_pgn(StringView import_path)
|
void ChessWidget::import_pgn(Core::File& file)
|
||||||
{
|
{
|
||||||
auto file_or_error = Core::File::open(import_path, Core::OpenMode::ReadOnly);
|
|
||||||
if (file_or_error.is_error()) {
|
|
||||||
warnln("Couldn't open '{}': {}", import_path, file_or_error.error());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto& file = *file_or_error.value();
|
|
||||||
|
|
||||||
m_board = Chess::Board();
|
m_board = Chess::Board();
|
||||||
|
|
||||||
ByteBuffer bytes = file.read_all();
|
ByteBuffer bytes = file.read_all();
|
||||||
|
@ -618,20 +611,10 @@ bool ChessWidget::import_pgn(StringView import_path)
|
||||||
m_playback_move_number = m_board_playback.moves().size();
|
m_playback_move_number = m_board_playback.moves().size();
|
||||||
m_playback = true;
|
m_playback = true;
|
||||||
update();
|
update();
|
||||||
|
|
||||||
file.close();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChessWidget::export_pgn(StringView export_path) const
|
void ChessWidget::export_pgn(Core::File& file) const
|
||||||
{
|
{
|
||||||
auto file_or_error = Core::File::open(export_path, Core::OpenMode::WriteOnly);
|
|
||||||
if (file_or_error.is_error()) {
|
|
||||||
warnln("Couldn't open '{}': {}", export_path, file_or_error.error());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto& file = *file_or_error.value();
|
|
||||||
|
|
||||||
// Tag Pair Section
|
// Tag Pair Section
|
||||||
file.write("[Event \"Casual Game\"]\n"sv);
|
file.write("[Event \"Casual Game\"]\n"sv);
|
||||||
file.write("[Site \"SerenityOS Chess\"]\n"sv);
|
file.write("[Site \"SerenityOS Chess\"]\n"sv);
|
||||||
|
@ -669,9 +652,6 @@ bool ChessWidget::export_pgn(StringView export_path) const
|
||||||
file.write(" } "sv);
|
file.write(" } "sv);
|
||||||
file.write(Chess::Board::result_to_points(m_board.game_result(), m_board.turn()));
|
file.write(Chess::Board::result_to_points(m_board.game_result(), m_board.turn()));
|
||||||
file.write("\n"sv);
|
file.write("\n"sv);
|
||||||
|
|
||||||
file.close();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChessWidget::flip_board()
|
void ChessWidget::flip_board()
|
||||||
|
|
|
@ -48,8 +48,8 @@ public:
|
||||||
void set_show_available_moves(bool e) { m_show_available_moves = e; }
|
void set_show_available_moves(bool e) { m_show_available_moves = e; }
|
||||||
|
|
||||||
String get_fen() const;
|
String get_fen() const;
|
||||||
bool import_pgn(StringView import_path);
|
void import_pgn(Core::File&);
|
||||||
bool export_pgn(StringView export_path) const;
|
void export_pgn(Core::File&) const;
|
||||||
|
|
||||||
int resign();
|
int resign();
|
||||||
void flip_board();
|
void flip_board();
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
#include <LibCore/DirIterator.h>
|
#include <LibCore/DirIterator.h>
|
||||||
#include <LibCore/System.h>
|
#include <LibCore/System.h>
|
||||||
#include <LibDesktop/Launcher.h>
|
#include <LibDesktop/Launcher.h>
|
||||||
|
#include <LibFileSystemAccessClient/Client.h>
|
||||||
#include <LibGUI/ActionGroup.h>
|
#include <LibGUI/ActionGroup.h>
|
||||||
#include <LibGUI/Application.h>
|
#include <LibGUI/Application.h>
|
||||||
#include <LibGUI/Clipboard.h>
|
#include <LibGUI/Clipboard.h>
|
||||||
#include <LibGUI/FilePicker.h>
|
|
||||||
#include <LibGUI/Icon.h>
|
#include <LibGUI/Icon.h>
|
||||||
#include <LibGUI/Menu.h>
|
#include <LibGUI/Menu.h>
|
||||||
#include <LibGUI/Menubar.h>
|
#include <LibGUI/Menubar.h>
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
{
|
{
|
||||||
TRY(Core::System::pledge("stdio rpath wpath cpath recvfd sendfd thread proc exec unix"));
|
TRY(Core::System::pledge("stdio rpath recvfd sendfd thread proc exec unix"));
|
||||||
|
|
||||||
auto app = TRY(GUI::Application::try_create(arguments));
|
auto app = TRY(GUI::Application::try_create(arguments));
|
||||||
|
|
||||||
|
@ -31,8 +31,6 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
TRY(Desktop::Launcher::add_allowed_handler_with_only_specific_urls("/bin/Help", { URL::create_with_file_protocol("/usr/share/man/man6/Chess.md") }));
|
TRY(Desktop::Launcher::add_allowed_handler_with_only_specific_urls("/bin/Help", { URL::create_with_file_protocol("/usr/share/man/man6/Chess.md") }));
|
||||||
TRY(Desktop::Launcher::seal_allowlist());
|
TRY(Desktop::Launcher::seal_allowlist());
|
||||||
|
|
||||||
TRY(Core::System::pledge("stdio rpath wpath cpath recvfd sendfd thread proc exec"));
|
|
||||||
|
|
||||||
auto app_icon = TRY(GUI::Icon::try_create_default_icon("app-chess"sv));
|
auto app_icon = TRY(GUI::Icon::try_create_default_icon("app-chess"sv));
|
||||||
|
|
||||||
auto window = TRY(GUI::Window::try_create());
|
auto window = TRY(GUI::Window::try_create());
|
||||||
|
@ -42,7 +40,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
TRY(Core::System::unveil("/bin/ChessEngine", "x"));
|
TRY(Core::System::unveil("/bin/ChessEngine", "x"));
|
||||||
TRY(Core::System::unveil("/etc/passwd", "r"));
|
TRY(Core::System::unveil("/etc/passwd", "r"));
|
||||||
TRY(Core::System::unveil("/tmp/100/portal/launch", "rw"));
|
TRY(Core::System::unveil("/tmp/100/portal/launch", "rw"));
|
||||||
TRY(Core::System::unveil(Core::StandardPaths::home_directory(), "wcbr"sv));
|
TRY(Core::System::unveil("/tmp/portal/filesystemaccess", "rw"));
|
||||||
TRY(Core::System::unveil(nullptr, nullptr));
|
TRY(Core::System::unveil(nullptr, nullptr));
|
||||||
|
|
||||||
auto size = Config::read_i32("Chess"sv, "Display"sv, "size"sv, 512);
|
auto size = Config::read_i32("Chess"sv, "Display"sv, "size"sv, 512);
|
||||||
|
@ -69,30 +67,20 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
TRY(game_menu->try_add_separator());
|
TRY(game_menu->try_add_separator());
|
||||||
|
|
||||||
TRY(game_menu->try_add_action(GUI::Action::create("&Import PGN...", { Mod_Ctrl, Key_O }, [&](auto&) {
|
TRY(game_menu->try_add_action(GUI::Action::create("&Import PGN...", { Mod_Ctrl, Key_O }, [&](auto&) {
|
||||||
Optional<String> import_path = GUI::FilePicker::get_open_filepath(window);
|
auto result = FileSystemAccessClient::Client::the().try_open_file(window);
|
||||||
|
if (result.is_error())
|
||||||
if (!import_path.has_value())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!widget->import_pgn(import_path.value())) {
|
widget->import_pgn(result.value());
|
||||||
GUI::MessageBox::show(window, "Unable to import game.\n"sv, "Error"sv, GUI::MessageBox::Type::Error);
|
dbgln("Imported PGN file from {}", result.value()->filename());
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbgln("Imported PGN file from {}", import_path.value());
|
|
||||||
})));
|
})));
|
||||||
TRY(game_menu->try_add_action(GUI::Action::create("&Export PGN...", { Mod_Ctrl, Key_S }, [&](auto&) {
|
TRY(game_menu->try_add_action(GUI::Action::create("&Export PGN...", { Mod_Ctrl, Key_S }, [&](auto&) {
|
||||||
Optional<String> export_path = GUI::FilePicker::get_save_filepath(window, "Untitled", "pgn");
|
auto result = FileSystemAccessClient::Client::the().try_save_file(window, "Untitled", "pgn");
|
||||||
|
if (result.is_error())
|
||||||
if (!export_path.has_value())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!widget->export_pgn(export_path.value())) {
|
widget->export_pgn(result.value());
|
||||||
GUI::MessageBox::show(window, "Unable to export game.\n"sv, "Error"sv, GUI::MessageBox::Type::Error);
|
dbgln("Exported PGN file to {}", result.value()->filename());
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbgln("Exported PGN file to {}", export_path.value());
|
|
||||||
})));
|
})));
|
||||||
TRY(game_menu->try_add_action(GUI::Action::create("&Copy FEN", { Mod_Ctrl, Key_C }, [&](auto&) {
|
TRY(game_menu->try_add_action(GUI::Action::create("&Copy FEN", { Mod_Ctrl, Key_C }, [&](auto&) {
|
||||||
GUI::Clipboard::the().set_data(widget->get_fen().bytes());
|
GUI::Clipboard::the().set_data(widget->get_fen().bytes());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue