From 2dbfb58efe5e53b56bfda3ed21a3e41562205437 Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Mon, 24 Jul 2017 23:43:07 +0200 Subject: Add tools -> Generate CA Added file field to GuiForm --- src/gui_gtk.cc | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 133 insertions(+), 8 deletions(-) (limited to 'src/gui_gtk.cc') diff --git a/src/gui_gtk.cc b/src/gui_gtk.cc index 14c1f63..55ce88a 100644 --- a/src/gui_gtk.cc +++ b/src/gui_gtk.cc @@ -919,6 +919,15 @@ public: values_.emplace_back(new NumberValue(id, label, description, value)); } + void add_file(std::string const& id, std::string const& label, + std::string const& value, + std::string const& description, + bool must_exist, + std::vector const& filter) override { + values_.emplace_back(new FileValue(id, label, description, value, + must_exist, filter)); + } + std::string get_string(std::string const& id) const override { for (auto const& value : values_) { if (value->id_ == id && value->type_ == STRING) { @@ -948,6 +957,26 @@ public: return 0; } + std::string get_file(std::string const& id) const override { + for (auto const& value : values_) { + if (value->id_ == id && value->type_ == FILE) { + auto v = static_cast(value.get()); + if (v->must_exist_ && v->chooser_) { + std::string ret; + auto file = gtk_file_chooser_get_filename(v->chooser_); + if (file) { + ret.assign(file); + g_free(file); + } + return ret; + } + return v->value_; + } + } + assert(false); + return ""; + } + void set_error(std::string const& error) override { if (!error_) { assert(false); @@ -984,12 +1013,13 @@ public: auto label = gtk_label_new(text_.c_str()); gtk_label_set_width_chars(GTK_LABEL(label), 35); gtk_label_set_line_wrap(GTK_LABEL(label), true); - gtk_grid_attach(GTK_GRID(grid), label, 0, row++, 2, 1); + gtk_grid_attach(GTK_GRID(grid), label, 0, row++, 3, 1); } for (auto& value : values_) { auto label = gtk_label_new(value->label_.c_str()); value->entry_ = gtk_entry_new(); gtk_entry_set_activates_default(GTK_ENTRY(value->entry_), true); + GtkWidget* extra = nullptr; switch (value->type_) { case STRING: gtk_entry_set_text(GTK_ENTRY(value->entry_), @@ -1004,9 +1034,49 @@ public: GTK_INPUT_PURPOSE_DIGITS); break; } + case FILE: { + auto v = static_cast(value.get()); + if (v->must_exist_) { + gtk_widget_destroy(value->entry_); + auto button = gtk_file_chooser_button_new( + v->label_.c_str(), GTK_FILE_CHOOSER_ACTION_OPEN); + v->chooser_ = GTK_FILE_CHOOSER(button); + value->entry_ = button; + } else { + auto chooser = gtk_file_chooser_native_new( + v->label_.c_str(), + GTK_WINDOW(dialog_), + GTK_FILE_CHOOSER_ACTION_SAVE, + nullptr, nullptr); + extra = gtk_button_new_with_label("..."); + g_signal_connect(G_OBJECT(extra), "clicked", + G_CALLBACK(show_filechooser), v); + v->chooser_ = GTK_FILE_CHOOSER(chooser); + gtk_editable_set_editable(GTK_EDITABLE(value->entry_), false); + gtk_file_chooser_set_do_overwrite_confirmation(v->chooser_, true); + } + if (!v->value_.empty()) { + gtk_file_chooser_set_filename(v->chooser_, v->value_.c_str()); + } + for (auto const& filter : v->filter_) { + auto f = gtk_file_filter_new(); + gtk_file_filter_set_name(f, filter.name.c_str()); + for (auto const& mask : filter.masks) { + gtk_file_filter_add_pattern(f, mask.c_str()); + } + gtk_file_chooser_add_filter(v->chooser_, f); + } + break; + } } gtk_grid_attach(GTK_GRID(grid), label, 0, row, 1, 1); - gtk_grid_attach(GTK_GRID(grid), value->entry_, 1, row++, 1, 1); + if (extra) { + gtk_grid_attach(GTK_GRID(grid), value->entry_, 1, row, 1, 1); + gtk_grid_attach(GTK_GRID(grid), extra, 2, row, 1, 1); + } else { + gtk_grid_attach(GTK_GRID(grid), value->entry_, 1, row, 2, 1); + } + row++; if (!value->description_.empty()) { auto desc = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(desc), @@ -1014,15 +1084,15 @@ public: gtk_widget_set_halign(GTK_WIDGET(desc), GTK_ALIGN_END); gtk_label_set_line_wrap(GTK_LABEL(desc), true); gtk_label_set_max_width_chars(GTK_LABEL(desc), 35); - gtk_grid_attach(GTK_GRID(grid), desc, 0, row++, 2, 1); + gtk_grid_attach(GTK_GRID(grid), desc, 0, row++, 3, 1); } } error_ = gtk_label_new(""); gtk_label_set_xalign(GTK_LABEL(error_), 0.0); - gtk_grid_attach(GTK_GRID(grid), error_, 0, row++, 2, 1); + gtk_grid_attach(GTK_GRID(grid), error_, 0, row++, 3, 1); gtk_container_add(GTK_CONTAINER(content_area), grid); gtk_widget_show_all(dialog_); - row = add_extra_widgets(GTK_GRID(grid), row); + row = add_extra_widgets(GTK_GRID(grid), row, 3); gtk_widget_hide(error_); gtk_dialog_set_default_response(GTK_DIALOG(dialog_), GTK_RESPONSE_ACCEPT); gint result; @@ -1041,6 +1111,22 @@ public: get_number(value->entry_, &static_cast(value.get())->value_); break; + case FILE: { + auto v = static_cast(value.get()); + if (v->must_exist_) { + auto file = gtk_file_chooser_get_filename(v->chooser_); + if (file) { + v->value_ = file; + g_free(file); + } else { + v->value_.clear(); + } + } else { + g_object_unref(v->chooser_); + } + v->chooser_ = nullptr; + break; + } } value->entry_ = nullptr; } @@ -1055,6 +1141,7 @@ protected: enum Type { STRING, NUMBER, + FILE, }; struct Value { @@ -1089,6 +1176,20 @@ protected: } }; + struct FileValue : public Value { + std::string value_; + bool must_exist_; + std::vector filter_; + GtkFileChooser* chooser_; + + FileValue(std::string const& id, std::string const& label, + std::string const& description, std::string const& value, + bool must_exist, std::vector const& filter) + : Value(FILE, id, label, description), value_(value), + must_exist_(must_exist), filter_(filter) { + } + }; + virtual bool notify_about_to_close() { auto it = observers_.notify(); while (it.has_next()) { @@ -1110,7 +1211,31 @@ protected: return false; } - virtual gint add_extra_widgets(GtkGrid* UNUSED(grid), gint row) { + static void safe_entry_from_filename(GtkWidget* widget, + std::string const& filename) { + auto str = g_filename_to_utf8(filename.data(), filename.size(), + nullptr, nullptr, nullptr); + if (str) { + gtk_entry_set_text(GTK_ENTRY(widget), str); + g_free(str); + } else { + gtk_entry_set_text(GTK_ENTRY(widget), ""); + } + } + + static void show_filechooser(GtkButton* UNUSED(button), gpointer user_data) { + auto value = reinterpret_cast(user_data); + auto ret = gtk_native_dialog_run(GTK_NATIVE_DIALOG(value->chooser_)); + if (ret == GTK_RESPONSE_ACCEPT) { + auto file = gtk_file_chooser_get_filename(value->chooser_); + value->value_ = file; + g_free(file); + safe_entry_from_filename(value->entry_, value->value_); + } + } + + virtual gint add_extra_widgets(GtkGrid* UNUSED(grid), gint row, + gint UNUSED(colspan)) { return row; } @@ -1157,10 +1282,10 @@ public: } private: - gint add_extra_widgets(GtkGrid* layout, gint row) override { + gint add_extra_widgets(GtkGrid* layout, gint row, gint colspan) override { assert(!spinner_); spinner_ = gtk_spinner_new(); - gtk_grid_attach(layout, spinner_, 0, row++, 2, 1); + gtk_grid_attach(layout, spinner_, 0, row++, colspan, 1); return row; } -- cgit v1.2.3-70-g09d2