Merge lp:~widelands-dev/widelands/bug-1610507-disallowed-filename-characters into lp:widelands
- bug-1610507-disallowed-filename-characters
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 8722 |
Proposed branch: | lp:~widelands-dev/widelands/bug-1610507-disallowed-filename-characters |
Merge into: | lp:widelands |
Diff against target: |
473 lines (+148/-56) 16 files modified
src/editor/ui_menus/main_menu_save_map.cc (+5/-2) src/editor/ui_menus/main_menu_save_map.h (+1/-0) src/editor/ui_menus/main_menu_save_map_make_directory.cc (+6/-3) src/editor/ui_menus/main_menu_save_map_make_directory.h (+1/-0) src/graphic/text_layout.cc (+7/-0) src/graphic/text_layout.h (+4/-0) src/io/CMakeLists.txt (+0/-21) src/io/filesystem/CMakeLists.txt (+23/-0) src/io/filesystem/filesystem.cc (+70/-0) src/io/filesystem/filesystem.h (+4/-0) src/io/filesystem/layered_filesystem.cc (+0/-16) src/io/filesystem/layered_filesystem.h (+1/-2) src/ui_basic/panel.cc (+20/-9) src/ui_basic/panel.h (+1/-1) src/wui/game_main_menu_save_game.cc (+4/-2) src/wui/game_main_menu_save_game.h (+1/-0) |
To merge this branch: | bzr merge lp:~widelands-dev/widelands/bug-1610507-disallowed-filename-characters |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Notabilis | Approve | ||
Review via email: mp+346442@code.launchpad.net |
Commit message
Added tooltip to file save and make directory edit boxes if illegal filename is being entered. Also, some refactoring:
- New function as_listitem in text layout
- Fixed tooltip drawing for modal panels
- Some code style tweaks to Panel
- Filename checks now live directly in Filesystem
Description of the change
bunnybot (widelandsofficial) wrote : | # |
bunnybot (widelandsofficial) wrote : | # |
Continuous integration builds have changed state:
Travis build 3540. State: passed. Details: https:/
Appveyor build 3344. State: success. Details: https:/
Notabilis (notabilis27) wrote : | # |
Nice change, I like the tooltip! Works as intended and code is looking good.
Some remarks:
- Maybe add the tooltip to the OK button as well? At least for me that would be the more likely place where I would notice it.
- Is the smaller font for the list in the tooltip intentional?
- Maybe calculate the tooltip text only once and store it as static string in the file system class?
Not really related: I noticed that in the editor->make directory dialog the OK button is initially disabled, even though it should (?) be enabled. This is done intentionally by calling set_enabled(false) when creating the dialog, even though the directory name is valid and can be used. Is there a reason for disabling it?
GunChleoc (gunchleoc) wrote : | # |
It is disabled because the text is always empty at the start, and empty names aren't allowed.
I like your suggestions and we should implement them before merging this.
The smaller text in the list is intentional - I have another branch for the editor info tool that uses the new listitem function too, and I wanted a consistent look.
Notabilis (notabilis27) wrote : | # |
In the case of the "make directory" dialog the default value of the edit box is "unnamed". This is a valid name (changing and changing it back is accepted) but the OK button is initially disabled anyway.
GunChleoc (gunchleoc) wrote : | # |
OK, that's a bug then.
GunChleoc (gunchleoc) wrote : | # |
OK button is fixed. Thanks for the review and testing :)
@bunnybot merge
Preview Diff
1 | === modified file 'src/editor/ui_menus/main_menu_save_map.cc' |
2 | --- src/editor/ui_menus/main_menu_save_map.cc 2018-05-22 06:54:12 +0000 |
3 | +++ src/editor/ui_menus/main_menu_save_map.cc 2018-05-31 17:12:19 +0000 |
4 | @@ -68,7 +68,8 @@ |
5 | UI::ButtonStyle::kWuiPrimary, |
6 | _("Map Options")), |
7 | editbox_label_( |
8 | - this, padding_, tabley_ + tableh_ + 3 * padding_, butw_, buth_, _("Filename:")) { |
9 | + this, padding_, tabley_ + tableh_ + 3 * padding_, butw_, buth_, _("Filename:")), |
10 | + illegal_filename_tooltip_(FileSystem::illegal_filename_tooltip()) { |
11 | set_current_directory(curdir_); |
12 | |
13 | // Make room for edit_options_ button |
14 | @@ -220,7 +221,9 @@ |
15 | */ |
16 | void MainMenuSaveMap::edit_box_changed() { |
17 | // Prevent the user from creating nonsense file names, like e.g. ".." or "...". |
18 | - ok_.set_enabled(LayeredFileSystem::is_legal_filename(editbox_->text())); |
19 | + const bool is_legal_filename = FileSystem::is_legal_filename(editbox_->text()); |
20 | + ok_.set_enabled(is_legal_filename); |
21 | + editbox_->set_tooltip(is_legal_filename ? "" : illegal_filename_tooltip_); |
22 | } |
23 | |
24 | void MainMenuSaveMap::reset_editbox_or_die(const std::string& current_filename) { |
25 | |
26 | === modified file 'src/editor/ui_menus/main_menu_save_map.h' |
27 | --- src/editor/ui_menus/main_menu_save_map.h 2018-05-10 15:57:43 +0000 |
28 | +++ src/editor/ui_menus/main_menu_save_map.h 2018-05-31 17:12:19 +0000 |
29 | @@ -55,6 +55,7 @@ |
30 | |
31 | UI::Textarea editbox_label_; |
32 | UI::EditBox* editbox_; |
33 | + const std::string illegal_filename_tooltip_; |
34 | }; |
35 | |
36 | #endif // end of include guard: WL_EDITOR_UI_MENUS_MAIN_MENU_SAVE_MAP_H |
37 | |
38 | === modified file 'src/editor/ui_menus/main_menu_save_map_make_directory.cc' |
39 | --- src/editor/ui_menus/main_menu_save_map_make_directory.cc 2018-04-27 06:11:05 +0000 |
40 | +++ src/editor/ui_menus/main_menu_save_map_make_directory.cc 2018-05-31 17:12:19 +0000 |
41 | @@ -54,7 +54,8 @@ |
42 | butw_, |
43 | buth_, |
44 | UI::ButtonStyle::kWuiSecondary, |
45 | - _("Cancel")) { |
46 | + _("Cancel")), |
47 | + illegal_filename_tooltip_(FileSystem::illegal_filename_tooltip()) { |
48 | |
49 | vbox_.add(&label_); |
50 | vbox_.add_space(padding_); |
51 | @@ -66,7 +67,7 @@ |
52 | ok_button_.sigclicked.connect( |
53 | boost::bind(&MainMenuSaveMapMakeDirectory::end_modal<UI::Panel::Returncodes>, |
54 | boost::ref(*this), UI::Panel::Returncodes::kOk)); |
55 | - ok_button_.set_enabled(false); |
56 | + ok_button_.set_enabled(!dirname_.empty()); |
57 | cancel_button_.sigclicked.connect( |
58 | boost::bind(&MainMenuSaveMapMakeDirectory::end_modal<UI::Panel::Returncodes>, |
59 | boost::ref(*this), UI::Panel::Returncodes::kBack)); |
60 | @@ -80,6 +81,8 @@ |
61 | void MainMenuSaveMapMakeDirectory::edit_changed() { |
62 | const std::string& text = edit_.text(); |
63 | // Prevent the user from creating nonsense directory names, like e.g. ".." or "...". |
64 | - ok_button_.set_enabled(LayeredFileSystem::is_legal_filename(text)); |
65 | + const bool is_legal_filename = FileSystem::is_legal_filename(text); |
66 | + ok_button_.set_enabled(is_legal_filename); |
67 | + edit_.set_tooltip(is_legal_filename ? "" : illegal_filename_tooltip_); |
68 | dirname_ = text; |
69 | } |
70 | |
71 | === modified file 'src/editor/ui_menus/main_menu_save_map_make_directory.h' |
72 | --- src/editor/ui_menus/main_menu_save_map_make_directory.h 2018-04-07 16:59:00 +0000 |
73 | +++ src/editor/ui_menus/main_menu_save_map_make_directory.h 2018-05-31 17:12:19 +0000 |
74 | @@ -50,6 +50,7 @@ |
75 | UI::EditBox edit_; |
76 | UI::Button ok_button_; |
77 | UI::Button cancel_button_; |
78 | + const std::string illegal_filename_tooltip_; |
79 | void edit_changed(); |
80 | }; |
81 | |
82 | |
83 | === modified file 'src/graphic/text_layout.cc' |
84 | --- src/graphic/text_layout.cc 2018-05-05 17:10:37 +0000 |
85 | +++ src/graphic/text_layout.cc 2018-05-31 17:12:19 +0000 |
86 | @@ -141,6 +141,13 @@ |
87 | return f.str(); |
88 | } |
89 | |
90 | +/// Bullet list item |
91 | +std::string as_listitem(const std::string& txt, int ptsize, const RGBColor& clr) { |
92 | + static boost::format f("<div width=100%%><div><p><font size=%d color=%s>•</font></p></div><div><p><space gap=6></p></div><div width=*><p><font size=%d color=%s>%s<vspace gap=6></font></p></div></div>"); |
93 | + f % ptsize % clr.hex_value() % ptsize % clr.hex_value() % txt; |
94 | + return f.str(); |
95 | +} |
96 | + |
97 | std::string as_richtext(const std::string& txt) { |
98 | static boost::format f("<rt>%s</rt>"); |
99 | f % txt; |
100 | |
101 | === modified file 'src/graphic/text_layout.h' |
102 | --- src/graphic/text_layout.h 2018-04-07 16:59:00 +0000 |
103 | +++ src/graphic/text_layout.h 2018-05-31 17:12:19 +0000 |
104 | @@ -84,6 +84,10 @@ |
105 | const RGBColor& clr = UI_FONT_CLR_FG, |
106 | UI::FontSet::Face face = UI::FontSet::Face::kSans); |
107 | |
108 | +std::string as_listitem(const std::string&, |
109 | + int ptsize = UI_FONT_SIZE_SMALL, |
110 | + const RGBColor& clr = UI_FONT_CLR_FG); |
111 | + |
112 | std::string as_richtext(const std::string&); |
113 | std::string as_tooltip(const std::string&); |
114 | std::string as_waresinfo(const std::string&); |
115 | |
116 | === modified file 'src/io/CMakeLists.txt' |
117 | --- src/io/CMakeLists.txt 2016-02-06 11:11:24 +0000 |
118 | +++ src/io/CMakeLists.txt 2018-05-31 17:12:19 +0000 |
119 | @@ -23,24 +23,3 @@ |
120 | io_filesystem |
121 | io_stream |
122 | ) |
123 | - |
124 | -wl_library(io_filesystem |
125 | - SRCS |
126 | - filesystem/disk_filesystem.cc |
127 | - filesystem/disk_filesystem.h |
128 | - filesystem/filesystem.cc |
129 | - filesystem/filesystem.h |
130 | - filesystem/filesystem_exceptions.h |
131 | - filesystem/layered_filesystem.cc |
132 | - filesystem/layered_filesystem.h |
133 | - filesystem/zip_exceptions.h |
134 | - filesystem/zip_filesystem.cc |
135 | - filesystem/zip_filesystem.h |
136 | - DEPENDS |
137 | - base_exceptions |
138 | - base_log |
139 | - base_macros |
140 | - io_fileread |
141 | - io_stream |
142 | - third_party_minizip |
143 | -) |
144 | |
145 | === modified file 'src/io/filesystem/CMakeLists.txt' |
146 | --- src/io/filesystem/CMakeLists.txt 2012-02-15 21:25:34 +0000 |
147 | +++ src/io/filesystem/CMakeLists.txt 2018-05-31 17:12:19 +0000 |
148 | @@ -1,1 +1,24 @@ |
149 | add_subdirectory(test) |
150 | + |
151 | +wl_library(io_filesystem |
152 | + SRCS |
153 | + disk_filesystem.cc |
154 | + disk_filesystem.h |
155 | + filesystem.cc |
156 | + filesystem.h |
157 | + filesystem_exceptions.h |
158 | + layered_filesystem.cc |
159 | + layered_filesystem.h |
160 | + zip_exceptions.h |
161 | + zip_filesystem.cc |
162 | + zip_filesystem.h |
163 | + DEPENDS |
164 | + base_exceptions |
165 | + base_i18n |
166 | + base_log |
167 | + base_macros |
168 | + graphic_text_layout |
169 | + io_fileread |
170 | + io_stream |
171 | + third_party_minizip |
172 | +) |
173 | |
174 | === modified file 'src/io/filesystem/filesystem.cc' |
175 | --- src/io/filesystem/filesystem.cc 2018-05-12 04:17:53 +0000 |
176 | +++ src/io/filesystem/filesystem.cc 2018-05-31 17:12:19 +0000 |
177 | @@ -32,6 +32,9 @@ |
178 | #include <string> |
179 | #include <vector> |
180 | |
181 | +// We have to add Boost to this block to make codecheck happy |
182 | +#include <boost/algorithm/string/predicate.hpp> |
183 | +#include <boost/format.hpp> |
184 | #ifdef _WIN32 |
185 | #include <direct.h> |
186 | #include <io.h> |
187 | @@ -43,8 +46,10 @@ |
188 | #include <sys/stat.h> |
189 | #include <unistd.h> |
190 | |
191 | +#include "base/i18n.h" |
192 | #include "base/log.h" |
193 | #include "config.h" |
194 | +#include "graphic/text_layout.h" |
195 | #include "io/filesystem/disk_filesystem.h" |
196 | #include "io/filesystem/layered_filesystem.h" |
197 | #include "io/filesystem/zip_exceptions.h" |
198 | @@ -60,6 +65,34 @@ |
199 | #define PATH_MAX MAX_PATH |
200 | #endif |
201 | |
202 | + |
203 | +namespace { |
204 | +// Characters that are allowed in filenames, but not at the beginning |
205 | +const std::vector<std::string> illegal_filename_starting_characters{ |
206 | + ".", |
207 | + "-", |
208 | + " ", // Keep the blank last |
209 | +}; |
210 | + |
211 | +// Characters that are disallowed anywhere in a filename |
212 | +// No potential file separators or other potentially illegal characters |
213 | +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx |
214 | +// http://www.linfo.org/file_name.html |
215 | +// https://support.apple.com/en-us/HT202808 |
216 | +// We can't just regex for word & digit characters here because of non-Latin scripts. |
217 | +const std::vector<std::string> illegal_filename_characters{ |
218 | + "<", |
219 | + ">", |
220 | + ":", |
221 | + "\"", |
222 | + "|", |
223 | + "?", |
224 | + "*", |
225 | + "/", |
226 | + "\\", |
227 | +}; |
228 | +} // namespace |
229 | + |
230 | /** |
231 | * \param path A file or directory name |
232 | * \return True if ref path is absolute and within this FileSystem, false otherwise |
233 | @@ -148,6 +181,43 @@ |
234 | #endif |
235 | } |
236 | |
237 | +bool FileSystem::is_legal_filename(const std::string& filename) { |
238 | + if (filename.empty()) { |
239 | + return false; |
240 | + } |
241 | + for (const std::string& illegal_start : illegal_filename_starting_characters) { |
242 | + if (boost::starts_with(filename, illegal_start)) { |
243 | + return false; |
244 | + } |
245 | + } |
246 | + for (const std::string& illegal_char : illegal_filename_characters) { |
247 | + if (boost::contains(filename, illegal_char)) { |
248 | + return false; |
249 | + } |
250 | + } |
251 | + return true; |
252 | +} |
253 | + |
254 | +std::string FileSystem::illegal_filename_tooltip() { |
255 | + std::vector<std::string> starting_characters; |
256 | + for (const std::string& character : illegal_filename_starting_characters) { |
257 | + if (character == " ") { |
258 | + /** TRANSLATORS: Part of tooltip entry for characters in illegal filenames. replaces tha blank space in a list of illegal characters */ |
259 | + starting_characters.push_back(pgettext("illegal_filename_characters", "blank space")); |
260 | + } else { |
261 | + starting_characters.push_back(character); |
262 | + } |
263 | + } |
264 | + /** TRANSLATORS: Tooltip entry for characters in illegal filenames. %s is a list of illegal characters */ |
265 | + const std::string illegal_start(as_listitem((boost::format(pgettext("illegal_filename_characters", "%s at the start of the filename")) % richtext_escape(i18n::localize_list(starting_characters, i18n::ConcatenateWith::OR))).str(), UI_FONT_SIZE_MESSAGE)); |
266 | + |
267 | + /** TRANSLATORS: Tooltip entry for characters in illegal filenames. %s is a list of illegal characters */ |
268 | + const std::string illegal(as_listitem((boost::format(pgettext("illegal_filename_characters", "%s anywhere in the filename")) % richtext_escape(i18n::localize_list(illegal_filename_characters, i18n::ConcatenateWith::OR))).str(), UI_FONT_SIZE_MESSAGE)); |
269 | + |
270 | + /** TRANSLATORS: Tooltip header for characters in illegal filenames. This is followed by a list of bullet points */ |
271 | + return (boost::format("%s%s%s") % pgettext("illegal_filename_characters", "The following characters are not allowed:") % illegal_start % illegal).str(); |
272 | +} |
273 | + |
274 | // TODO(unknown): Write homedir detection for non-getenv-systems |
275 | std::string FileSystem::get_homedir() { |
276 | std::string homedir; |
277 | |
278 | === modified file 'src/io/filesystem/filesystem.h' |
279 | --- src/io/filesystem/filesystem.h 2018-04-07 16:59:00 +0000 |
280 | +++ src/io/filesystem/filesystem.h 2018-05-31 17:12:19 +0000 |
281 | @@ -108,6 +108,10 @@ |
282 | std::string canonicalize_name(std::string path) const; |
283 | bool is_path_absolute(const std::string& path) const; |
284 | |
285 | + /// Returns true if the filename is legal in all operating systems |
286 | + static bool is_legal_filename(const std::string& filename); |
287 | + static std::string illegal_filename_tooltip(); |
288 | + |
289 | // Returns the path separator, i.e. \ on windows and / everywhere else. |
290 | static char file_separator(); |
291 | |
292 | |
293 | === modified file 'src/io/filesystem/layered_filesystem.cc' |
294 | --- src/io/filesystem/layered_filesystem.cc 2018-04-07 16:59:00 +0000 |
295 | +++ src/io/filesystem/layered_filesystem.cc 2018-05-31 17:12:19 +0000 |
296 | @@ -22,16 +22,12 @@ |
297 | #include <cstdio> |
298 | #include <memory> |
299 | |
300 | -#include <boost/algorithm/string/predicate.hpp> |
301 | -#include <boost/regex.hpp> |
302 | - |
303 | #include "base/log.h" |
304 | #include "base/wexception.h" |
305 | #include "io/fileread.h" |
306 | #include "io/streamread.h" |
307 | |
308 | LayeredFileSystem* g_fs; |
309 | - |
310 | LayeredFileSystem::LayeredFileSystem() : home_(nullptr) { |
311 | } |
312 | |
313 | @@ -41,18 +37,6 @@ |
314 | LayeredFileSystem::~LayeredFileSystem() { |
315 | } |
316 | |
317 | -bool LayeredFileSystem::is_legal_filename(const std::string& filename) { |
318 | - // No potential file separators or other potentially illegal characters |
319 | - // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx |
320 | - // http://www.linfo.org/file_name.html |
321 | - // https://support.apple.com/en-us/HT202808 |
322 | - // We can't just regex for word & digit characters here because of non-Latin scripts. |
323 | - boost::regex re(".*[<>:\"|?*/\\\\].*"); |
324 | - return !filename.empty() && !boost::starts_with(filename, ".") && |
325 | - !boost::starts_with(filename, " ") && !boost::starts_with(filename, "-") && |
326 | - !boost::regex_match(filename, re); |
327 | -} |
328 | - |
329 | /** |
330 | * Just assume that at least one of our child FSs is writable |
331 | */ |
332 | |
333 | === modified file 'src/io/filesystem/layered_filesystem.h' |
334 | --- src/io/filesystem/layered_filesystem.h 2018-04-07 16:59:00 +0000 |
335 | +++ src/io/filesystem/layered_filesystem.h 2018-05-31 17:12:19 +0000 |
336 | @@ -58,8 +58,7 @@ |
337 | |
338 | std::set<std::string> list_directory(const std::string& path) override; |
339 | |
340 | - /// Returns true if the filename is legal in all operating systems |
341 | - static bool is_legal_filename(const std::string& filename); |
342 | + |
343 | bool is_writable() const override; |
344 | bool file_exists(const std::string& path) override; |
345 | bool is_directory(const std::string& path) override; |
346 | |
347 | === modified file 'src/ui_basic/panel.cc' |
348 | --- src/ui_basic/panel.cc 2018-05-14 06:59:39 +0000 |
349 | +++ src/ui_basic/panel.cc 2018-05-31 17:12:19 +0000 |
350 | @@ -143,8 +143,9 @@ |
351 | app->set_mouse_lock(false); // more paranoia :-) |
352 | |
353 | Panel* forefather = this; |
354 | - while (Panel* const p = forefather->parent_) |
355 | - forefather = p; |
356 | + while (forefather->parent_ != nullptr) { |
357 | + forefather = forefather->parent_; |
358 | + } |
359 | |
360 | default_cursor_ = g_gr->images().get("images/ui_basic/cursor.png"); |
361 | default_cursor_click_ = g_gr->images().get("images/ui_basic/cursor_click.png"); |
362 | @@ -175,13 +176,16 @@ |
363 | app->handle_input(&input_callback); |
364 | |
365 | if (start_time >= next_think_time) { |
366 | - if (app->should_die()) |
367 | + if (app->should_die()) { |
368 | end_modal<Returncodes>(Returncodes::kBack); |
369 | + } |
370 | |
371 | do_think(); |
372 | |
373 | - if (flags_ & pf_child_die) |
374 | + if (flags_ & pf_child_die) { |
375 | check_child_death(); |
376 | + } |
377 | + |
378 | next_think_time = start_time + kGameLogicDelay; |
379 | } |
380 | |
381 | @@ -190,7 +194,13 @@ |
382 | forefather->do_draw(rt); |
383 | rt.blit((app->get_mouse_position() - Vector2i(3, 7)), |
384 | app->is_mouse_pressed() ? default_cursor_click_ : default_cursor_); |
385 | - forefather->do_tooltip(); |
386 | + |
387 | + if (is_modal()) { |
388 | + do_tooltip(); |
389 | + } else { |
390 | + forefather->do_tooltip(); |
391 | + } |
392 | + |
393 | g_gr->refresh(); |
394 | next_draw_time = start_time + draw_delay; |
395 | } |
396 | @@ -594,8 +604,7 @@ |
397 | * false otherwise. |
398 | */ |
399 | bool Panel::handle_tooltip() { |
400 | - RenderTarget& rt = *g_gr->get_render_target(); |
401 | - return draw_tooltip(rt, tooltip()); |
402 | + return draw_tooltip(tooltip()); |
403 | } |
404 | |
405 | /** |
406 | @@ -1060,13 +1069,15 @@ |
407 | /** |
408 | * Draw the tooltip. Return true on success |
409 | */ |
410 | -bool Panel::draw_tooltip(RenderTarget& dst, const std::string& text) { |
411 | +bool Panel::draw_tooltip(const std::string& text) { |
412 | if (text.empty()) { |
413 | return false; |
414 | } |
415 | + |
416 | + RenderTarget& dst = *g_gr->get_render_target(); |
417 | std::string text_to_render = text; |
418 | if (!is_richtext(text_to_render)) { |
419 | - text_to_render = as_tooltip(text); |
420 | + text_to_render = as_tooltip(text_to_render); |
421 | } |
422 | |
423 | constexpr uint32_t kTipWidthMax = 360; |
424 | |
425 | === modified file 'src/ui_basic/panel.h' |
426 | --- src/ui_basic/panel.h 2018-04-27 06:11:05 +0000 |
427 | +++ src/ui_basic/panel.h 2018-05-31 17:12:19 +0000 |
428 | @@ -311,7 +311,7 @@ |
429 | static void play_new_chat_member(); |
430 | static void play_new_chat_message(); |
431 | |
432 | - static bool draw_tooltip(RenderTarget&, const std::string& text); |
433 | + static bool draw_tooltip(const std::string& text); |
434 | void draw_background(RenderTarget& dst, const UI::PanelStyleInfo&); |
435 | void draw_background(RenderTarget& dst, Recti rect, const UI::PanelStyleInfo&); |
436 | |
437 | |
438 | === modified file 'src/wui/game_main_menu_save_game.cc' |
439 | --- src/wui/game_main_menu_save_game.cc 2018-05-22 06:54:12 +0000 |
440 | +++ src/wui/game_main_menu_save_game.cc 2018-05-31 17:12:19 +0000 |
441 | @@ -65,7 +65,8 @@ |
442 | cancel_(&buttons_box_, "cancel", 0, 0, 0, 0, UI::ButtonStyle::kWuiSecondary, _("Cancel")), |
443 | ok_(&buttons_box_, "ok", 0, 0, 0, 0, UI::ButtonStyle::kWuiPrimary, _("OK")), |
444 | |
445 | - curdir_(kSaveDir) { |
446 | + curdir_(kSaveDir), |
447 | + illegal_filename_tooltip_(FileSystem::illegal_filename_tooltip()) { |
448 | |
449 | layout(); |
450 | |
451 | @@ -133,8 +134,9 @@ |
452 | |
453 | void GameMainMenuSaveGame::edit_box_changed() { |
454 | // Prevent the user from creating nonsense directory names, like e.g. ".." or "...". |
455 | - const bool is_legal_filename = LayeredFileSystem::is_legal_filename(filename_editbox_.text()); |
456 | + const bool is_legal_filename = FileSystem::is_legal_filename(filename_editbox_.text()); |
457 | ok_.set_enabled(is_legal_filename); |
458 | + filename_editbox_.set_tooltip(is_legal_filename ? "" : illegal_filename_tooltip_); |
459 | load_or_save_.delete_button()->set_enabled(false); |
460 | load_or_save_.clear_selections(); |
461 | } |
462 | |
463 | === modified file 'src/wui/game_main_menu_save_game.h' |
464 | --- src/wui/game_main_menu_save_game.h 2018-05-10 15:57:43 +0000 |
465 | +++ src/wui/game_main_menu_save_game.h 2018-05-31 17:12:19 +0000 |
466 | @@ -79,6 +79,7 @@ |
467 | UI::Button cancel_, ok_; |
468 | |
469 | std::string curdir_; |
470 | + const std::string illegal_filename_tooltip_; |
471 | }; |
472 | |
473 | #endif // end of include guard: WL_WUI_GAME_MAIN_MENU_SAVE_GAME_H |
Continuous integration builds have changed state:
Travis build 3534. State: failed. Details: https:/ /travis- ci.org/ widelands/ widelands/ builds/ 382014340. /ci.appveyor. com/project/ widelands- dev/widelands/ build/_ widelands_ dev_widelands_ bug_1610507_ disallowed_ filename_ characters- 3338.
Appveyor build 3338. State: success. Details: https:/