16 #define GETTEXT_DOMAIN "wesnoth-lib"
41 #define ERR_FILEDLG LOG_STREAM(err, log_filedlg)
42 #define WRN_FILEDLG LOG_STREAM(warn, log_filedlg)
43 #define LOG_FILEDLG LOG_STREAM(info, log_filedlg)
44 #define DBG_FILEDLG LOG_STREAM(debug, log_filedlg)
50 const std::string icon_dir =
"icons/action/browse_25.png";
51 const std::string icon_parent =
"icons/action/undo_25.png";
52 const std::string icon_file =
"misc/file.png";
55 const std::string label_parent =
"..";
57 const std::string CURRENT_DIR =
".";
58 const std::string PARENT_DIR =
"..";
60 const int FILE_DIALOG_ITEM_RETVAL = 9001;
61 const int FILE_DIALOG_MAX_ENTRY_LENGTH = 42;
63 inline std::string concat_path(
const std::string& a,
const std::string&
b)
81 inline std::string filesystem_root()
87 inline void isort_dir_entries(std::vector<std::string>& entries)
92 std::sort(entries.begin(), entries.end(),
93 [](
const std::string& a,
const std::string&
b) { return translation::icompare(a, b) < 0; });
105 , title_(
_("Find File"))
116 , current_bookmark_()
117 , user_bookmarks_begin_()
169 text_box& file_textbox = find_widget<text_box>(
"filename");
170 button& save_btn = find_widget<button>(
"ok");
174 styled_widget& validation_msg = find_widget<styled_widget>(
"validation_msg");
177 bool wrong_ext =
false;
180 validation_msg.
set_label(
_(
"<span color='#00dcff' size='small'>please enter a filename</span>"));
185 if (
filename.size() >= extension.size()) {
187 if (ext == extension) {
202 validation_msg.
set_label(
VGETTEXT(
"<span color='red'><span face='DejaVuSans'>✘</span> <span size='small'>wrong extension, use $extensions</span></span>", i18n_strings));
205 validation_msg.
set_label(
_(
"<span color='red'><span face='DejaVuSans'>✘</span> <span size='small'>whitespace is not allowed in filename</span></span>"));
235 listbox& bookmarks_bar = find_widget<listbox>(
"bookmarks");
237 find_widget<styled_widget>(
"current_dir").set_text_ellipse_mode(PANGO_ELLIPSIZE_START);
247 bookmarks.insert(bookmarks.end(), sys_paths.begin(), sys_paths.end());
254 for(
const auto& pinfo : bookmarks) {
256 data[
"bookmark"][
"label"] = pinfo.display_name();
272 data[
"bookmark"][
"label"] = bookmark.label;
278 listbox& filelist = find_widget<listbox>(
"filelist");
279 text_box& file_textbox = find_widget<text_box>(
"filename");
290 button& mkdir_button = find_widget<button>(
"new_dir");
291 button& rm_button = find_widget<button>(
"delete_file");
292 button& bookmark_add_button = find_widget<button>(
"add_bookmark");
293 button& bookmark_del_button = find_widget<button>(
"remove_bookmark");
294 button& open_ext_button = find_widget<button>(
"open_ext");
310 open_ext_button.
set_tooltip(
_(
"Opening files is not supported, contact your packager"));
367 =
_(
"The file already exists. Do you wish to overwrite it?");
402 assert(
false &&
"Unimplemented selection mode or semantics");
410 listbox& filelist = find_widget<listbox>(
"filelist");
417 text_box& file_textbox = find_widget<text_box>(
"filename");
418 const std::string& input_name = file_textbox.
get_value();
433 if(row == 0 && !i_am_root) {
436 std::size_t
n = i_am_root ? row : row - 1;
446 assert(
false &&
"File list selection is out of range!");
456 std::string new_path, new_parent;
464 DBG_FILEDLG <<
"register_new_selection(): new selection '" << name <<
"' is relative to a root resource";
470 DBG_FILEDLG <<
"register_new_selection(): new selection '" << name <<
"' seems relative";
475 DBG_FILEDLG <<
"register_new_selection(): new selection '" << name <<
"' seems absolute";
478 DBG_FILEDLG <<
"register_new_selection(): new selection is " << new_path;
481 if(!new_path.empty()) {
483 DBG_FILEDLG <<
"register_new_selection(): new selection '" << name <<
"' is a directory: " << new_path;
490 DBG_FILEDLG <<
"register_new_selection(): new selection '" << name <<
"' is a file, symbolic link, or special: " << new_path;
501 if(!absolute_parent.empty()) {
502 DBG_FILEDLG <<
"register_new_selection(): new selection '" << name <<
"' does not exist or is not accessible, but parent exists";
508 DBG_FILEDLG <<
"register_new_selection(): new selection '" << name <<
"' does not exist or is not accessible";
522 const std::size_t vallen =
t.get_length();
527 if(value.substr(vallen - extlen) ==
extension_) {
528 t.set_selection(0, vallen - extlen);
537 t.set_selection(0, 0);
560 listbox& filelist = find_widget<listbox>(
"filelist");
561 button& rm_button = find_widget<button>(
"delete_file");
586 find_widget<styled_widget>(
"current_dir").set_label(
current_dir_);
596 std::string
label = name;
600 data[
"icon"][
"label"] = icon;
621 listbox& bookmarks_bar = find_widget<listbox>(
"bookmarks");
639 const int new_selection =
static_cast<int>(std::distance(
bookmark_paths_.begin(), it.base()) - 1);
641 assert(
static_cast<unsigned>(new_selection) < bookmarks_bar.
get_item_count());
645 bookmarks_bar.
select_row(
static_cast<unsigned>(new_selection),
true);
651 button& del_button = find_widget<button>(
"remove_bookmark");
662 listbox& filelist = find_widget<listbox>(
"filelist");
663 text_box& file_textbox = find_widget<text_box>(
"filename");
664 button& rm_button = find_widget<button>(
"delete_file");
687 text_box& file_textbox = find_widget<text_box>(
"filename");
690 listbox& bookmarks_bar = find_widget<listbox>(
"bookmarks");
693 if(new_selection < 0) {
709 button& del_button = find_widget<button>(
"remove_bookmark");
718 std::string
label = default_label;
726 label = default_label;
729 listbox& bookmarks_bar = find_widget<listbox>(
"bookmarks");
755 listbox& bookmarks_bar = find_widget<listbox>(
"bookmarks");
767 std::string new_dir_name;
769 if(folder_create::execute(new_dir_name)) {
770 const std::string& new_path = concat_path(
current_dir_, new_dir_name);
774 VGETTEXT(
"Could not create a new folder at $path|. Make sure you have the appropriate permissions to write to this location.",
775 {{
"path", new_path}}));
791 const std::string&
message = (is_dir
792 ?
_(
"The following folder and its contents will be permanently deleted:")
793 :
_(
"The following file will be permanently deleted:"))
794 +
"\n\n" + selection +
"\n\n" +
_(
"Do you wish to continue?");
800 const bool result = is_dir
806 VGETTEXT(
"Could not delete $path|. Make sure you have the appropriate permissions to write to this location.",
807 {{
"path", selection}}));
static bool execute(std::string &bookmark_name)
The execute function; see modal_dialog for more information.
void sync_bookmarks_bar()
Updates the bookmarks bar state to reflect the internal state.
bool process_submit_common(const std::string &name)
file_dialog & set_path(const std::string &value)
Sets the initial file selection.
const std::string & title() const
Gets the current dialog title text.
void on_bookmark_add_cmd()
Handles Add Bookmark button press events.
std::vector< std::string > bookmark_paths_
void check_filename()
Check if the filename is valid and disable save button if invalid.
SELECTION_TYPE register_new_selection(const std::string &name)
Updates the internal state and returns the type of the selection.
void set_input_text(class text_box &t, const std::string &value)
void on_file_delete_cmd()
Handles Delete button press events.
std::string path() const
Gets the current file selection.
@ SELECTION_PARENT_NOT_FOUND
file_dialog & set_filename(const std::string &value)
Sets the initial file name input but not the path.
std::vector< std::string > dir_files_
void on_bookmark_selected()
Handles selection or deselection of bookmarks.
void clear_input_text(class text_box &t)
std::string current_entry_
bool is_selection_type_acceptable(SELECTION_TYPE stype) const
Returns whether the given selection type is acceptable for closing the dialog.
bool process_fileview_submit()
Processes file view selection in reaction to row double-click events.
bool process_textbox_submit()
Processes textbox input in reaction to OK button/Enter key events.
virtual void pre_show() override
Actions to be taken before showing the window.
void on_dir_create_cmd()
Handles New Folder button press events.
int user_bookmarks_begin_
std::set< desktop::GAME_PATH_TYPES > extra_paths_
void on_row_selected()
Handles file/directory selection on single-click.
void push_fileview_row(class listbox &filelist, const std::string &name, const std::string &icon, bool check_selection=true)
Row building helper for refresh_fileview().
bool confirm_overwrite(SELECTION_TYPE stype)
Prompts the user before overwriting an existing file.
void refresh_fileview()
Updates the dialog contents to match the internal state.
std::string get_filelist_selection(class listbox &filelist)
bool on_exit(window &window)
Handles dialog exit events and decides whether to proceed or not.
std::vector< std::string > dir_subdirs_
void on_bookmark_del_cmd()
Handles Remove Bookmark button press events.
std::vector< std::string > extensions_
Main class to show messages to the user.
@ yes_no_buttons
Shows a yes and no button.
Abstract base class for all modal dialogs.
bool select_last_row(const bool select=true)
Does exactly as advertised: selects the list's last row.
grid & add_row(const widget_item &item, const int index=-1)
When an item in the list is selected by the user we need to update the state.
bool select_row(const unsigned row, const bool select=true)
Selects a row.
void remove_row(const unsigned row, unsigned count=1)
Removes a row in the listbox.
void clear()
Removes all the rows in the listbox, clearing it.
int get_selected_row() const
Returns the first selected row.
unsigned get_item_count() const
Returns the number of items in the listbox.
std::string get_value() const
A widget that allows the user to input text in single line.
base class of top level items, the only item which needs to store the final canvases to draw on.
void set_retval(const int retval, const bool close_window=true)
Sets there return value of the window.
void keyboard_capture(widget *widget)
void add_to_keyboard_chain(widget *widget)
Adds the widget to the keyboard chain.
void set_exit_hook(exit_hook mode, std::function< bool(window &)> func)
Sets the window's exit hook.
static lg::log_domain log_filedlg
Declarations for File-IO.
static std::string _(const char *str)
std::string label
What to show in the filter's drop-down list.
Standard logging facilities (interface).
std::vector< bookmark_info > user_bookmarks()
unsigned add_user_bookmark(const std::string &label, const std::string &path)
bool open_object([[maybe_unused]] const std::string &path_or_url)
@ GAME_USER_DATA_DIR
User data dir.
@ GAME_CORE_DATA_DIR
Game data dir.
void remove_user_bookmark(unsigned index)
constexpr bool open_object_is_supported()
Returns whether open_object() is supported/implemented for the current platform.
std::vector< path_info > system_paths(const std::set< SYSTEM_PATH_TYPES > &paths)
Returns a list of system-defined paths.
@ SYSTEM_USER_PROFILE
Path to the user's profile dir (e.g.
@ SYSTEM_ALL_DRIVES
Paths for each storage media found (Windows), /media and/or /mnt (X11, if non-empty).
@ SYSTEM_ROOTFS
Path to the root of the filesystem hierarchy (ignored on Windows).
std::vector< path_info > game_paths(const std::set< GAME_PATH_TYPES > &paths)
Returns a list of game-related paths.
bool is_relative(const std::string &path)
Returns whether the path seems to be relative.
bool is_root(const std::string &path)
Returns whether the path is the root of the file hierarchy.
void get_files_in_dir(const std::string &dir, std::vector< std::string > *files, std::vector< std::string > *dirs, name_mode mode, filter_mode filter, reorder_mode reorder, file_tree_checksum *checksum)
Get a list of all files and/or directories in a given directory.
std::string base_name(const std::string &file, const bool remove_extension)
Returns the base filename of a file, with directory name stripped.
bool delete_file(const std::string &filename)
static bool file_exists(const bfs::path &fpath)
bool is_directory(const std::string &fname)
Returns true if the given file is a directory.
bool delete_directory(const std::string &dirname, const bool keep_pbl)
std::string root_name(const std::string &path)
Returns the name of the root device if included in the given path.
std::string directory_name(const std::string &file)
Returns the directory name of a file, with filename stripped.
std::string nearest_extant_parent(const std::string &file)
Finds the nearest parent in existence for a file or directory.
char path_separator()
Returns the standard path separator for the current platform.
bool make_directory(const std::string &dirname)
bool is_path_sep(char c)
Returns whether c is a path separator.
std::string normalize_path(const std::string &fpath, bool normalize_separators, bool resolve_dot_entries)
Returns the absolute path of a file.
REGISTER_DIALOG(editor_edit_unit)
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification &signal)
Connects a signal handler for getting a notification upon modification.
void connect_signal_mouse_left_click(dispatcher &dispatcher, const signal &signal)
Connects a signal handler for a left mouse button click.
std::map< std::string, widget_item > widget_data
void show_transient_error_message(const std::string &message, const std::string &image, const bool message_use_markup)
Shows a transient error message to the user.
void show_message(const std::string &title, const std::string &msg, const std::string &button_caption, const bool auto_close, const bool message_use_markup, const bool title_use_markup)
Shows a message to the user.
@ OK
Dialog was closed with the OK button.
@ CANCEL
Dialog was closed with the CANCEL button.
std::size_t size(std::string_view str)
Length in characters of a UTF-8 string.
void ellipsis_truncate(std::string &str, const std::size_t size)
Truncates a string to a given utf-8 character count and then appends an ellipsis.
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
std::map< std::string, t_string > string_map
auto * find(Container &container, const Value &value)
Convenience wrapper for using find on a container without needing to comare to end()
Desktop environment interaction functions.
Desktop paths, storage media and bookmark functions.
std::string filename
Filename.
static map_location::direction n