Skip to content

Commit

Permalink
gui2/tfile_dialog: Add support for a filename extension hint
Browse files Browse the repository at this point in the history
This allows setting a hint in save mode so that the name portion of the
filename will be selected whenever the user selects a file with a
matching extension on the fileview, and so that whenever the textbox is
cleared by code (e.g. when browsing into directories) it is pre-filled
with the extension with the cursor at the start.

With this, the dialog is now feature-complete compared to the GUI1
version.
  • Loading branch information
irydacea committed Oct 5, 2016
1 parent 3fa0fc9 commit 8056d63
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 3 deletions.
38 changes: 35 additions & 3 deletions src/gui/dialogs/file_dialog.cpp
Expand Up @@ -36,6 +36,7 @@
#include "gui/widgets/window.hpp"
#include "gettext.hpp"
#include "log.hpp"
#include "serialization/unicode.hpp"

#include <functional>

Expand Down Expand Up @@ -106,6 +107,7 @@ tfile_dialog::tfile_dialog()
: title_(_("Find File"))
, msg_()
, ok_label_()
, extension_()
, current_entry_()
, current_dir_()
, read_only_(false)
Expand Down Expand Up @@ -383,6 +385,36 @@ tfile_dialog::SELECTION_TYPE tfile_dialog::register_new_selection(const std::str
return SELECTION_PARENT_NOT_FOUND;
}

void tfile_dialog::set_input_text(ttext_box& t, const std::string& value)
{
if(value.empty()) {
clear_input_text(t);
return;
}

t.set_value(value);

const size_t vallen = t.get_length();
const size_t extlen = utf8::size(extension_);

if(save_mode_ && extlen && vallen > extlen) {
// Highlight everything but the extension if it matches
if(value.substr(vallen - extlen) == extension_) {
t.set_selection(0, vallen - extlen);
}
}
}

void tfile_dialog::clear_input_text(ttext_box& t)
{
if(save_mode_ && !extension_.empty()) {
t.set_value(extension_);
t.set_selection(0, 0);
} else {
t.clear();
}
}

void tfile_dialog::refresh_fileview(twindow& window)
{
cursor::setter cur{cursor::WAIT};
Expand Down Expand Up @@ -423,7 +455,7 @@ void tfile_dialog::refresh_fileview(twindow& window)
}

find_widget<tcontrol>(&window, "current_dir", false).set_label(current_dir_);
find_widget<ttext_box>(&window, "filename", false).set_value(current_entry_);
set_input_text(find_widget<ttext_box>(&window, "filename", false), current_entry_);
}

void tfile_dialog::push_fileview_row(tlistbox& filelist, const std::string& name, const std::string& icon, bool check_selection)
Expand Down Expand Up @@ -464,9 +496,9 @@ void tfile_dialog::on_row_selected(twindow& window)

// Clear the textbox when selecting ..
if(current_entry_ != PARENT_DIR) {
file_textbox.set_value(current_entry_);
set_input_text(file_textbox, current_entry_);
} else {
file_textbox.clear();
clear_input_text(file_textbox);
}
}

Expand Down
22 changes: 22 additions & 0 deletions src/gui/dialogs/file_dialog.hpp
Expand Up @@ -105,6 +105,24 @@ class tfile_dialog : public tdialog
*/
tfile_dialog& set_filename(const std::string& value);

/**
* Sets the default file extension for file names in save mode.
*
* When this is set to a non-empty string and save mode is active, selecting
* file entries will cause their name portions to be highlighted in the name
* text box if their extensions match the provided template, and any time the
* text box is cleared it will position the cursor before the extension as a
* hint for the user.
*
* The value provided to this method should be preceded by a dot if
* applicable (e.g. ".cfg").
*/
tfile_dialog& set_extension(const std::string& value)
{
extension_ = value;
return *this;
}

/**
* Whether user interface elements for manipulating existing objects are provided.
*/
Expand Down Expand Up @@ -163,6 +181,7 @@ class tfile_dialog : public tdialog
std::string msg_;
std::string ok_label_;

std::string extension_;
std::string current_entry_;
std::string current_dir_;

Expand Down Expand Up @@ -237,6 +256,9 @@ class tfile_dialog : public tdialog
*/
SELECTION_TYPE register_new_selection(const std::string& name);

void set_input_text(class ttext_box& t, const std::string& value);
void clear_input_text(class ttext_box& t);

/**
* Updates the dialog contents to match the internal state.
*/
Expand Down

0 comments on commit 8056d63

Please sign in to comment.