The Battle for Wesnoth  1.19.0-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 the default file extension 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.
124  *
125  * The value provided to this method should be preceded by a dot if
126  * applicable (e.g. ".cfg").
127  */
128  file_dialog& set_extension(const std::string& value)
129  {
130  extension_ = value;
131  return *this;
132  }
133 
134  /**
135  * Whether user interface elements for manipulating existing objects are provided.
136  */
137  bool read_only() const
138  {
139  return read_only_;
140  }
141 
142  /**
143  * Whether to provide user interface elements for manipulating existing objects.
144  *
145  * This is initially disabled.
146  */
148  {
149  read_only_ = value;
150  return *this;
151  }
152 
153  /**
154  * Returns whether save mode is enabled.
155  *
156  * See set_save_mode() for more information.
157  */
158  bool save_mode() const
159  {
160  return save_mode_;
161  }
162 
163  /**
164  * Sets the dialog's behavior on non-existent file name inputs.
165  *
166  * This is initially disabled.
167  *
168  * When save mode is enabled, file names entered into the dialog by the user
169  * need not exist already (but their parent directories still do). Otherwise,
170  * the user is only able to select existing files.
171  */
173  {
174  save_mode_ = value;
175  return *this;
176  }
177 
178  /**
179  * Sets the OK button label.
180  *
181  * By default, "Save" is used when save_mode is enabled, and "Open" otherwise.
182  * Calling this method with an empty string will reset the label to the
183  * default.
184  */
185  file_dialog& set_ok_label(const std::string& value)
186  {
187  ok_label_ = value;
188  return *this;
189  }
190 
192  {
193  extra_paths_.emplace(path);
194  return *this;
195  }
196 
197 private:
198  std::string title_;
199  std::string msg_;
200  std::string ok_label_;
201 
202  std::string extension_;
203  std::string current_entry_;
204  std::string current_dir_;
205 
208 
209  std::vector<std::string> dir_files_;
210  std::vector<std::string> dir_subdirs_;
211 
212  std::vector<std::string> bookmark_paths_;
215  std::set<desktop::GAME_PATH_TYPES> extra_paths_;
216 
217  virtual const std::string& window_id() const override;
218 
219  virtual void pre_show(window& window) override;
220 
221  /** Handles dialog exit events and decides whether to proceed or not. */
222  bool on_exit(window& window);
223  /** Handles file/directory selection on single-click. */
224  void on_row_selected();
225  /** Handles selection or deselection of bookmarks. */
226  void on_bookmark_selected();
227  /** Handles Add Bookmark button press events. */
228  void on_bookmark_add_cmd();
229  /** Handles Remove Bookmark button press events. */
230  void on_bookmark_del_cmd();
231  /** Handles New Folder button press events. */
232  void on_dir_create_cmd();
233  /** Handles Delete button press events. */
234  void on_file_delete_cmd();
235 
236  /**
237  * Processes file view selection in reaction to row double-click events.
238  *
239  * It takes care of synchronizing the state, browsing to the new selection,
240  * and/or displaying an error message if appropriate
241  *
242  * @returns Whether to exit the dialog successfully (@a true) or continue
243  * (@a false).
244  */
246 
247  /**
248  * Processes textbox input in reaction to OK button/Enter key events.
249  *
250  * It takes care of synchronizing the state, browsing to the new selection,
251  * and/or displaying an error message if appropriate
252  *
253  * @returns Whether to exit the dialog successfully (@a true) or continue
254  * (@a false).
255  */
256  bool process_textbox_submit();
257 
258  bool process_submit_common(const std::string& name);
259 
260  /**
261  * Updates the bookmarks bar state to reflect the internal state.
262  */
263  void sync_bookmarks_bar();
264 
265  std::string get_filelist_selection(class listbox& filelist);
266 
268  {
273  };
274 
275  /**
276  * Returns whether the given selection type is acceptable for closing the dialog.
277  *
278  * @todo This currently never returns @a true for SELECTION_IS_DIR, awaiting
279  * a need to implement a directory selection mode.
280  */
282 
283  /**
284  * Prompts the user before overwriting an existing file.
285  *
286  * This only makes sense in save mode.
287  *
288  * @returns @a true if the selection does not refer to an existing file or the
289  * user accepted the overwrite prompt; @a false otherwise.
290  */
291  bool confirm_overwrite(SELECTION_TYPE stype);
292 
293  /**
294  * Updates the internal state and returns the type of the selection.
295  *
296  * If the given @a name refers to a non-existent object, the internal state is
297  * unchanged.
298  */
299  SELECTION_TYPE register_new_selection(const std::string& name);
300 
301  void set_input_text(class text_box& t, const std::string& value);
302  void clear_input_text(class text_box& t);
303 
304  /**
305  * Updates the dialog contents to match the internal state.
306  */
307  void refresh_fileview();
308 
309  /**
310  * Row building helper for refresh_fileview().
311  *
312  * @param filelist Target for adding the new row.
313  * @param name Label, assumed to be a file name if
314  * check_selection = true.
315  * @param icon Row icon.
316  * @param check_selection Whether to set the row to selected if the current
317  * file name in the internal state matches the row's
318  * label/name.
319  */
320  void push_fileview_row(class listbox& filelist, const std::string& name, const std::string& icon, bool check_selection = true);
321 };
322 
323 } // namespace dialogs
324 } // namespace gui2
double t
Definition: astarsearch.cpp:63
file_dialog & set_extension(const std::string &value)
Sets the default file extension 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.
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.
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)
virtual void pre_show(window &window) override
Actions to be taken before showing the window.
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.
Abstract base class for all modal dialogs.
The listbox class.
Definition: listbox.hpp:43
Class for a single line text area.
Definition: text_box.hpp:142
base class of top level items, the only item which needs to store the final canvases to draw on.
Definition: window.hpp:63
GAME_PATH_TYPES
Definition: paths.hpp:57
Various uncategorised dialogs.
Generic file dialog.
Desktop paths, storage media and bookmark functions.