The Battle for Wesnoth  1.19.5+dev
file_dialog.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 - 2024
3  by Iris Morelle <shadowm2006@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
19 
20 #include "desktop/paths.hpp"
21 
22 /**
23  * Generic file dialog.
24  *
25  * This provides UI elements for browsing the filesystem and choosing a file
26  * path to open or create, and optionally allows creating new directories or
27  * deleting existing files and directories.
28  *
29  * Because of the sheer amount of unrelated options provided by this dialog,
30  * no parameter-based constructors or static @a execute() functions are
31  * provided. Use individual property setters after construction and before
32  * invoking show(), instead.
33  */
34 namespace gui2
35 {
36 
37 class listbox;
38 class text_box;
39 
40 namespace dialogs
41 {
42 
43 class file_dialog : public modal_dialog
44 {
45 public:
46  file_dialog();
47 
48  /**
49  * Gets the current dialog title text.
50  */
51  const std::string& title() const
52  {
53  return title_;
54  }
55 
56  /**
57  * Sets the current dialog title text.
58  */
59  file_dialog& set_title(const std::string& value)
60  {
61  title_ = value;
62  return *this;
63  }
64 
65  /**
66  * Gets the current dialog instructions/message text.
67  */
68  const std::string& message() const
69  {
70  return msg_;
71  }
72 
73  /**
74  * Sets the current dialog instructions/message text.
75  *
76  * The message text may contain Pango markup.
77  */
78  file_dialog& set_message(const std::string& value)
79  {
80  msg_ = value;
81  return *this;
82  }
83 
84  /**
85  * Gets the current file selection.
86  *
87  * @returns An absolute path to the selected file.
88  */
89  std::string path() const;
90 
91  /**
92  * Sets the initial file selection.
93  *
94  * If the path is found to refer to a file (more specifically, any
95  * non-directory object), that file is initially selected on the directory
96  * contents view and the file name box is set to contain its name. If the file
97  * does not exist, but the path leading up to it does, the directory contents
98  * view displays that path and there isn't an initial file selection or name
99  * set unless set_filename() is used first.
100  *
101  * If you want to set an initial file name hint/template, use set_filename()
102  * <b>after</b> calling this method.
103  */
104  file_dialog& set_path(const std::string& value);
105 
106  /**
107  * Sets the initial file name input but not the path.
108  *
109  * The file name needs not exist in the initial path selected with set_path().
110  *
111  * If this is used before set_path() and the path passed there points to a
112  * file, that file name will replace the one given here.
113  */
114  file_dialog& set_filename(const std::string& value);
115 
116  /**
117  * Sets allowed file extensions for file names in save mode.
118  *
119  * When this is set to a non-empty string and save mode is active, selecting
120  * file entries will cause their name portions to be highlighted in the name
121  * text box if their extensions match the provided template, and any time the
122  * text box is cleared it will position the cursor before the extension as a
123  * hint for the user. Additionally, the user will not be able to save the file
124  * with a wrong extension if this is set.
125  *
126  * In case of multiple extension, the first set extension is the default.
127  *
128  * The value provided to this method should be preceded by a dot if
129  * applicable (e.g. ".cfg").
130  */
131  file_dialog& set_extension(const std::string& value)
132  {
133  if (extension_.empty()) {
134  extension_ = value;
135  }
136  extensions_.push_back(value);
137  return *this;
138  }
139 
140  /**
141  * Whether user interface elements for manipulating existing objects are provided.
142  */
143  bool read_only() const
144  {
145  return read_only_;
146  }
147 
148  /**
149  * Whether to provide user interface elements for manipulating existing objects.
150  *
151  * This is initially disabled.
152  */
154  {
155  read_only_ = value;
156  return *this;
157  }
158 
159  /**
160  * Returns whether save mode is enabled.
161  *
162  * See set_save_mode() for more information.
163  */
164  bool save_mode() const
165  {
166  return save_mode_;
167  }
168 
169  /**
170  * Sets the dialog's behavior on non-existent file name inputs.
171  *
172  * This is initially disabled.
173  *
174  * When save mode is enabled, file names entered into the dialog by the user
175  * need not exist already (but their parent directories still do). Otherwise,
176  * the user is only able to select existing files.
177  */
179  {
180  save_mode_ = value;
181  return *this;
182  }
183 
184  /**
185  * Sets the OK button label.
186  *
187  * By default, "Save" is used when save_mode is enabled, and "Open" otherwise.
188  * Calling this method with an empty string will reset the label to the
189  * default.
190  */
191  file_dialog& set_ok_label(const std::string& value)
192  {
193  ok_label_ = value;
194  return *this;
195  }
196 
198  {
199  extra_paths_.emplace(path);
200  return *this;
201  }
202 
203 private:
204  std::string title_;
205  std::string msg_;
206  std::string ok_label_;
207 
208  std::string extension_;
209  std::string current_entry_;
210  std::string current_dir_;
211 
214 
215  std::vector<std::string> extensions_;
216 
217  std::vector<std::string> dir_files_;
218  std::vector<std::string> dir_subdirs_;
219 
220  std::vector<std::string> bookmark_paths_;
223  std::set<desktop::GAME_PATH_TYPES> extra_paths_;
224 
225  virtual const std::string& window_id() const override;
226 
227  virtual void pre_show() override;
228 
229  /** Handles dialog exit events and decides whether to proceed or not. */
230  bool on_exit(window& window);
231  /** Handles file/directory selection on single-click. */
232  void on_row_selected();
233  /** Handles selection or deselection of bookmarks. */
234  void on_bookmark_selected();
235  /** Handles Add Bookmark button press events. */
236  void on_bookmark_add_cmd();
237  /** Handles Remove Bookmark button press events. */
238  void on_bookmark_del_cmd();
239  /** Handles New Folder button press events. */
240  void on_dir_create_cmd();
241  /** Handles Delete button press events. */
242  void on_file_delete_cmd();
243 
244  /**
245  * Processes file view selection in reaction to row double-click events.
246  *
247  * It takes care of synchronizing the state, browsing to the new selection,
248  * and/or displaying an error message if appropriate
249  *
250  * @returns Whether to exit the dialog successfully (@a true) or continue
251  * (@a false).
252  */
254 
255  /**
256  * Processes textbox input in reaction to OK button/Enter key events.
257  *
258  * It takes care of synchronizing the state, browsing to the new selection,
259  * and/or displaying an error message if appropriate
260  *
261  * @returns Whether to exit the dialog successfully (@a true) or continue
262  * (@a false).
263  */
264  bool process_textbox_submit();
265 
266  bool process_submit_common(const std::string& name);
267 
268  /**
269  * Check if the filename is valid and disable save button if invalid
270  */
271  void check_filename();
272 
273  /**
274  * Updates the bookmarks bar state to reflect the internal state.
275  */
276  void sync_bookmarks_bar();
277 
278  std::string get_filelist_selection(class listbox& filelist);
279 
281  {
286  };
287 
288  /**
289  * Returns whether the given selection type is acceptable for closing the dialog.
290  *
291  * @todo This currently never returns @a true for SELECTION_IS_DIR, awaiting
292  * a need to implement a directory selection mode.
293  */
295 
296  /**
297  * Prompts the user before overwriting an existing file.
298  *
299  * This only makes sense in save mode.
300  *
301  * @returns @a true if the selection does not refer to an existing file or the
302  * user accepted the overwrite prompt; @a false otherwise.
303  */
304  bool confirm_overwrite(SELECTION_TYPE stype);
305 
306  /**
307  * Updates the internal state and returns the type of the selection.
308  *
309  * If the given @a name refers to a non-existent object, the internal state is
310  * unchanged.
311  */
312  SELECTION_TYPE register_new_selection(const std::string& name);
313 
314  void set_input_text(class text_box& t, const std::string& value);
315  void clear_input_text(class text_box& t);
316 
317  /**
318  * Updates the dialog contents to match the internal state.
319  */
320  void refresh_fileview();
321 
322  /**
323  * Row building helper for refresh_fileview().
324  *
325  * @param filelist Target for adding the new row.
326  * @param name Label, assumed to be a file name if
327  * check_selection = true.
328  * @param icon Row icon.
329  * @param check_selection Whether to set the row to selected if the current
330  * file name in the internal state matches the row's
331  * label/name.
332  */
333  void push_fileview_row(class listbox& filelist, const std::string& name, const std::string& icon, bool check_selection = true);
334 };
335 
336 } // namespace dialogs
337 } // namespace gui2
double t
Definition: astarsearch.cpp:63
file_dialog & set_extension(const std::string &value)
Sets allowed file extensions for file names in save mode.
file_dialog & set_ok_label(const std::string &value)
Sets the OK button label.
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.
Definition: file_dialog.hpp:51
void on_bookmark_add_cmd()
Handles Add Bookmark button press events.
file_dialog & set_title(const std::string &value)
Sets the current dialog title text.
Definition: file_dialog.hpp:59
file_dialog & set_read_only(bool value)
Whether to provide user interface elements for manipulating existing objects.
std::vector< std::string > bookmark_paths_
file_dialog & set_save_mode(bool value)
Sets the dialog's behavior on non-existent file name inputs.
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.
file_dialog & set_filename(const std::string &value)
Sets the initial file name input but not the path.
file_dialog & set_message(const std::string &value)
Sets the current dialog instructions/message text.
Definition: file_dialog.hpp:78
std::vector< std::string > dir_files_
void on_bookmark_selected()
Handles selection or deselection of bookmarks.
const std::string & message() const
Gets the current dialog instructions/message text.
Definition: file_dialog.hpp:68
void clear_input_text(class text_box &t)
bool is_selection_type_acceptable(SELECTION_TYPE stype) const
Returns whether the given selection type is acceptable for closing the dialog.
bool save_mode() const
Returns whether save mode is enabled.
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.
virtual const std::string & window_id() const override
The ID of the window to build.
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)
file_dialog & add_extra_path(desktop::GAME_PATH_TYPES path)
bool on_exit(window &window)
Handles dialog exit events and decides whether to proceed or not.
std::vector< std::string > dir_subdirs_
bool read_only() const
Whether user interface elements for manipulating existing objects are provided.
void on_bookmark_del_cmd()
Handles Remove Bookmark button press events.
std::vector< std::string > extensions_
Abstract base class for all modal dialogs.
The listbox class.
Definition: listbox.hpp:43
A widget that allows the user to input text in single line.
Definition: text_box.hpp:125
base class of top level items, the only item which needs to store the final canvases to draw on.
Definition: window.hpp:61
GAME_PATH_TYPES
Definition: paths.hpp:57
Various uncategorised dialogs.
Generic file dialog.
Desktop paths, storage media and bookmark functions.