Commit 4b0a6fb6 authored by Eric Gregory's avatar Eric Gregory
Browse files

3515 saved search dialog disables OK button until search is valid

parent 8e357305
......@@ -10,6 +10,7 @@ public class SavedSearchDialog {
// Conatins a search row, with a type selector and remove button.
private class SearchRowContainer {
public signal void remove(SearchRowContainer this_row);
public signal void changed(SearchRowContainer this_row);
private Gtk.ComboBox type_combo;
private Gtk.HBox box;
......@@ -61,6 +62,7 @@ public class SavedSearchDialog {
private void on_type_changed() {
set_type(get_search_type());
changed(this);
}
private void set_type(SearchCondition.SearchType type) {
......@@ -116,6 +118,10 @@ public class SavedSearchDialog {
public SearchCondition get_search_condition() {
return my_row.get_search_condition();
}
public bool is_complete() {
return my_row.is_complete();
}
}
// Represents a row-type.
......@@ -128,6 +134,9 @@ public class SavedSearchDialog {
// Fills out the fields in this row based on an existing search condition (for edit mode.)
public abstract void populate(SearchCondition sc);
// Returns true if the row is valid and complete.
public abstract bool is_complete();
}
private class SearchRowText : SearchRow {
......@@ -149,10 +158,12 @@ public class SavedSearchDialog {
text_context.append_text(_("does not contain"));
text_context.append_text(_("is not set"));
text_context.set_active(0);
text_context.changed.connect(on_changed);
entry = new Gtk.Entry();
entry.set_width_chars(25);
entry.set_activates_default(true);
entry.changed.connect(on_changed);
box = new Gtk.HBox(false, 8);
box.pack_start(text_context, false, false, 0);
......@@ -160,6 +171,11 @@ public class SavedSearchDialog {
box.show_all();
}
~SearchRowText() {
text_context.changed.disconnect(on_changed);
entry.changed.disconnect(on_changed);
}
public override Gtk.Widget get_widget() {
return box;
}
......@@ -178,6 +194,14 @@ public class SavedSearchDialog {
text_context.set_active(text.context);
entry.set_text(text.text);
}
public override bool is_complete() {
return entry.text.chomp() != "";
}
private void on_changed() {
parent.changed(parent);
}
}
private class SearchRowMediaType : SearchRow {
......@@ -195,6 +219,7 @@ public class SavedSearchDialog {
media_context.append_text(_("is"));
media_context.append_text(_("is not"));
media_context.set_active(0);
media_context.changed.connect(on_changed);
// Ordering must correspond with SearchConditionMediaType.MediaType
media_type = new Gtk.ComboBox.text();
......@@ -202,6 +227,7 @@ public class SavedSearchDialog {
media_type.append_text(_("a raw photo"));
media_type.append_text(_("a video"));
media_type.set_active(0);
media_type.changed.connect(on_changed);
box = new Gtk.HBox(false, 8);
box.pack_start(media_context, false, false, 0);
......@@ -209,6 +235,11 @@ public class SavedSearchDialog {
box.show_all();
}
~SearchRowMediaType() {
media_context.changed.disconnect(on_changed);
media_type.changed.disconnect(on_changed);
}
public override Gtk.Widget get_widget() {
return box;
}
......@@ -227,6 +258,14 @@ public class SavedSearchDialog {
media_context.set_active(media.context);
media_type.set_active(media.media_type);
}
public override bool is_complete() {
return true;
}
private void on_changed() {
parent.changed(parent);
}
}
private class SearchRowFlagged : SearchRow {
......@@ -243,6 +282,7 @@ public class SavedSearchDialog {
flagged_state.append_text(_("flagged"));
flagged_state.append_text(_("not flagged"));
flagged_state.set_active(0);
flagged_state.changed.connect(on_changed);
box = new Gtk.HBox(false, 8);
box.pack_start(new Gtk.Label(_("is")), false, false, 0);
......@@ -250,6 +290,10 @@ public class SavedSearchDialog {
box.show_all();
}
~SearchRowFlagged() {
flagged_state.changed.disconnect(on_changed);
}
public override Gtk.Widget get_widget() {
return box;
}
......@@ -266,6 +310,14 @@ public class SavedSearchDialog {
assert(f != null);
flagged_state.set_active(f.state);
}
public override bool is_complete() {
return true;
}
private void on_changed() {
parent.changed(parent);
}
}
private class SearchRowRating : SearchRow {
......@@ -288,12 +340,14 @@ public class SavedSearchDialog {
rating.append_text(Resources.rating_combo_box(Rating.FOUR));
rating.append_text(Resources.rating_combo_box(Rating.FIVE));
rating.set_active(0);
rating.changed.connect(on_changed);
context = new Gtk.ComboBox.text();
context.append_text("and higher");
context.append_text("only");
context.append_text("and lower");
context.set_active(0);
context.changed.connect(on_changed);
box = new Gtk.HBox(false, 8);
box.pack_start(new Gtk.Label(_("is")), false, false, 0);
......@@ -302,6 +356,11 @@ public class SavedSearchDialog {
box.show_all();
}
~SearchRowRating() {
rating.changed.disconnect(on_changed);
context.changed.disconnect(on_changed);
}
public override Gtk.Widget get_widget() {
return box;
}
......@@ -320,6 +379,14 @@ public class SavedSearchDialog {
context.set_active(r.context);
rating.set_active(r.rating - Rating.REJECTED);
}
public override bool is_complete() {
return true;
}
private void on_changed() {
parent.changed(parent);
}
}
private Gtk.Builder builder;
......@@ -331,6 +398,7 @@ public class SavedSearchDialog {
private Gee.ArrayList<SearchRowContainer> row_list = new Gee.ArrayList<SearchRowContainer>();
private bool edit_mode = false;
private SavedSearch? previous_search = null;
private bool valid = false;
public SavedSearchDialog() {
setup_dialog();
......@@ -347,6 +415,7 @@ public class SavedSearchDialog {
dialog.set_default_response(Gtk.ResponseType.OK);
dialog.show_all();
set_valid(false);
}
public SavedSearchDialog.edit_existing(SavedSearch saved_search) {
......@@ -371,6 +440,11 @@ public class SavedSearchDialog {
dialog.set_default_response(Gtk.ResponseType.OK);
dialog.show_all();
set_valid(true);
}
~SavedSearchDialog() {
search_title.changed.disconnect(on_title_changed);
}
// Builds the dialog UI. Doesn't add buttons to the dialog or call dialog.show_all().
......@@ -387,6 +461,7 @@ public class SavedSearchDialog {
search_title = builder.get_object("Search title") as Gtk.Entry;
search_title.set_activates_default(true);
search_title.changed.connect(on_title_changed);
row_box = builder.get_object("row_box") as Gtk.VBox;
......@@ -422,15 +497,19 @@ public class SavedSearchDialog {
row_box.add(row.get_widget());
row_list.add(row);
row.remove.connect(on_remove_row);
row.changed.connect(on_row_changed);
set_valid(row.is_complete());
}
// Removes a row of search criteria.
private void on_remove_row(SearchRowContainer row) {
row.remove.disconnect(on_remove_row);
row.changed.disconnect(on_row_changed);
row_box.remove(row.get_widget());
row_list.remove(row);
if (row_list.size == 1)
row_list.get(0).allow_removal(false);
set_valid(true); // try setting to "true" since we removed a row
}
private void on_response(int response_id) {
......@@ -457,4 +536,44 @@ public class SavedSearchDialog {
SavedSearchTable.get_instance().create(search_title.get_text(), search_operator, conditions);
}
}
private void on_row_changed(SearchRowContainer row) {
set_valid(row.is_complete());
}
private void on_title_changed() {
set_valid(is_title_valid());
}
private bool is_title_valid() {
if (edit_mode && previous_search != null &&
previous_search.get_name() == search_title.get_text())
return true; // Title hasn't changed.
if (search_title.get_text().chomp() == "")
return false;
if (SavedSearchTable.get_instance().exists(search_title.get_text()))
return false;
return true;
}
// Call this with your new value for validity whenever a row or the title changes.
private void set_valid(bool v) {
if (!v) {
valid = false;
} else if (v != valid) {
if (is_title_valid()) {
// Go through rows to check validity.
int valid_rows = 0;
foreach (SearchRowContainer c in row_list) {
if (c.is_complete())
valid_rows++;
}
valid = (valid_rows == row_list.size);
} else {
valid = false; // title was invalid
}
}
dialog.set_response_sensitive(Gtk.ResponseType.OK, valid);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment