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.
bool on_exit()
Handles dialog exit events and decides whether to proceed or not.
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)
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.
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, const Func &hook)
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