/* * Copyright (C) 2005 Kouji TAKAO * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include "gpass/configuration.h" #include "gpass/error.h" #include "attribute-widgets.h" #include "password-generator.h" /*********************************************************** * * GPassGnomeAttribute * ***********************************************************/ static GObjectClass *parent_base_class = NULL; static void gnome_attribute_initialize(GTypeInstance *instance, gpointer g_class) { GPassGnomeAttribute *self = GPASS_GNOME_ATTRIBUTE(instance); self->attribute = NULL; self->label = NULL; self->widget = NULL; } enum { BASE_PROP_0, BASE_PROP_ATTRIBUTE, }; static void gnome_attribute_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GPassGnomeAttribute *self = GPASS_GNOME_ATTRIBUTE(object); GtkWidget *label, *eventbox; GtkTooltips *tooltips; switch (prop_id) { case BASE_PROP_ATTRIBUTE: self->attribute = g_value_get_object(value); g_object_ref(self->attribute); label = g_object_new(GTK_TYPE_LABEL, "label", self->attribute->nick, "xalign", 0.0, NULL); gtk_widget_show(label); eventbox = g_object_new(GTK_TYPE_EVENT_BOX, NULL); gtk_widget_set_usize(eventbox, 80, -1); gtk_container_add(GTK_CONTAINER(eventbox), label); tooltips = g_object_new(GTK_TYPE_TOOLTIPS, NULL); gtk_tooltips_set_tip(tooltips, eventbox, self->attribute->blurb, NULL); self->label = eventbox; GPASS_GNOME_ATTRIBUTE_GET_CLASS(self)->create_widget(self); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void gnome_attribute_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GPassGnomeAttribute *self = GPASS_GNOME_ATTRIBUTE(object); switch (prop_id) { case BASE_PROP_ATTRIBUTE: GPASS_GNOME_ATTRIBUTE_GET_CLASS(self)->widget_to_value(self); g_value_set_object(value, self->attribute); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void gnome_attribute_finalize(GObject *object) { GPassGnomeAttribute *self = GPASS_GNOME_ATTRIBUTE(object); if (self->attribute != NULL) { g_object_unref(self->attribute); } if (self->label != NULL) { g_object_unref(self->label); } if (self->widget != NULL) { g_object_unref(self->widget); } G_OBJECT_CLASS(parent_base_class)->finalize(object); } static void gnome_attribute_class_initialize(gpointer g_class, gpointer g_class_data) { GObjectClass *gobject_class = G_OBJECT_CLASS(g_class); parent_base_class = g_type_class_peek_parent(g_class); gobject_class->set_property = gnome_attribute_set_property; gobject_class->get_property = gnome_attribute_get_property; gobject_class->finalize = gnome_attribute_finalize; g_object_class_install_property (gobject_class, BASE_PROP_ATTRIBUTE, g_param_spec_object("attribute", _("GPassAttribute"), _("The object of GPassAttribute"), GPASS_TYPE_ATTRIBUTE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } GType gpass_gnome_attribute_get_type(void) { static GType type = 0; if (type == 0) { static const GTypeInfo info = { sizeof(GPassGnomeAttributeClass), NULL, NULL, gnome_attribute_class_initialize, NULL, NULL, sizeof(GPassGnomeAttribute), 0, gnome_attribute_initialize }; type = g_type_register_static(G_TYPE_OBJECT, "GPassGnomeAttribute", &info, G_TYPE_FLAG_ABSTRACT); } return type; } GPassGnomeAttribute * gpass_gnome_attribute_new(GPassAttribute *attribute) { GType type; switch (attribute->type) { case GPASS_ATTRIBUTE_TYPE_INTEGER: type = GPASS_TYPE_GNOME_INTEGER_ATTRIBUTE; break; case GPASS_ATTRIBUTE_TYPE_BOOLEAN: type = GPASS_TYPE_GNOME_BOOLEAN_ATTRIBUTE; break; case GPASS_ATTRIBUTE_TYPE_TIME: type = GPASS_TYPE_GNOME_TIME_ATTRIBUTE; break; case GPASS_ATTRIBUTE_TYPE_STRING: case GPASS_ATTRIBUTE_TYPE_URL: type = GPASS_TYPE_GNOME_STRING_ATTRIBUTE; break; case GPASS_ATTRIBUTE_TYPE_TEXT: type = GPASS_TYPE_GNOME_TEXT_ATTRIBUTE; break; case GPASS_ATTRIBUTE_TYPE_PASSWORD: type = GPASS_TYPE_GNOME_PASSWORD_ATTRIBUTE; break; case GPASS_ATTRIBUTE_TYPE_ENTRY_TYPE: type = GPASS_TYPE_GNOME_TYPE_ATTRIBUTE; break; default: return NULL; } return GPASS_GNOME_ATTRIBUTE (g_object_new(type, "attribute", attribute, NULL)); } static GError * gpass_gnome_attribute_set_valist(GPassGnomeAttribute *self, va_list ap) { gchar *error_message = NULL; G_VALUE_COLLECT(self->attribute->value, ap, 0, &error_message); if (error_message != NULL) { GError *error = NULL; g_set_error(&error, 0, 0, error_message); g_free(error_message); return error; } GPASS_GNOME_ATTRIBUTE_GET_CLASS(self)->value_to_widget(self); return NULL; } GError * gpass_gnome_attribute_set(GPassGnomeAttribute *self, ...) { va_list ap; GError *error; va_start(ap, self); error = gpass_gnome_attribute_set_valist(self, ap); va_end(ap); return error; } static GError * gpass_gnome_attribute_get_valist(GPassGnomeAttribute *self, va_list ap) { gchar *error_message = NULL; GPASS_GNOME_ATTRIBUTE_GET_CLASS(self)->widget_to_value(self); G_VALUE_LCOPY(self->attribute->value, ap, 0, &error_message); if (error_message != NULL) { GError *error = NULL; g_set_error(&error, 0, 0, error_message); g_free(error_message); return error; } return NULL; } GError * gpass_gnome_attribute_get(GPassGnomeAttribute *self, ...) { va_list ap; GError *error; va_start(ap, self); error = gpass_gnome_attribute_get_valist(self, ap); va_end(ap); return error; } /*********************************************************** * * GPassGnomeTypeAttribute * ***********************************************************/ enum { COLUMN_TYPE, COLUMN_NICK, COLUMN_ICON_ID, NUM_COLUMNS }; static void type_changed(GtkWidget *widget, gpointer user_data) { GPassGnomeTypeAttribute *self = GPASS_GNOME_TYPE_ATTRIBUTE(user_data); g_object_notify(G_OBJECT(self), "attribute"); } static void gnome_type_attribute_create_widget(GPassGnomeAttribute *base) { GtkWidget *combo_box; GtkListStore *store; GtkCellRenderer *cell; store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_STRING, /* type */ G_TYPE_STRING, /* nick */ G_TYPE_STRING); /* icon-id */ base->widget = combo_box = g_object_new(GTK_TYPE_COMBO_BOX, "model", store, NULL); g_object_unref(store); cell = g_object_new(GTK_TYPE_CELL_RENDERER_PIXBUF, NULL); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo_box), cell, FALSE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell, "stock-id", COLUMN_ICON_ID, NULL); cell = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo_box), cell, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), cell, "text", COLUMN_NICK, NULL); g_signal_connect(combo_box, "changed", G_CALLBACK(type_changed), base); } static void gnome_type_attribute_value_to_widget(GPassGnomeAttribute *base) { GtkComboBox *combo = GTK_COMBO_BOX(base->widget); GtkTreeModel *model = gtk_combo_box_get_model(combo); GtkTreeIter iter; const gchar *attr_type, *combo_type; if (!gtk_tree_model_get_iter_first(model, &iter)) { return; } gpass_attribute_get(base->attribute, &attr_type); do { gtk_tree_model_get(model, &iter, COLUMN_TYPE, &combo_type, -1); if (strcmp(attr_type, combo_type) == 0) { gtk_combo_box_set_active_iter(combo, &iter); return; } } while (gtk_tree_model_iter_next(model, &iter)); } static void gnome_type_attribute_widget_to_value(GPassGnomeAttribute *base) { GtkComboBox *combo = GTK_COMBO_BOX(base->widget); GtkTreeModel *model = gtk_combo_box_get_model(combo); GtkTreeIter iter; const gchar *type; if (!gtk_combo_box_get_active_iter(combo, &iter)) { return; } gtk_tree_model_get(model, &iter, COLUMN_TYPE, &type, -1); gpass_attribute_set(base->attribute, type); } static void gnome_type_attribute_class_initialize(gpointer g_class, gpointer g_class_data) { GPassGnomeAttributeClass *base_class = GPASS_GNOME_ATTRIBUTE_CLASS(g_class); base_class->create_widget = gnome_type_attribute_create_widget; base_class->value_to_widget = gnome_type_attribute_value_to_widget; base_class->widget_to_value = gnome_type_attribute_widget_to_value; } GType gpass_gnome_type_attribute_get_type(void) { static GType type = 0; if (type == 0) { static const GTypeInfo info = { sizeof(GPassGnomeTypeAttributeClass), NULL, NULL, gnome_type_attribute_class_initialize, NULL, NULL, sizeof(GPassGnomeTypeAttribute), 0, NULL, }; type = g_type_register_static(GPASS_TYPE_GNOME_ATTRIBUTE, "GPassGnomeTypeAttribute", &info, 0); } return type; } void gpass_gnome_type_attribute_append(GPassGnomeTypeAttribute *self, GPassEntryFactoryCursor *cursor) { GPassGnomeAttribute *base = GPASS_GNOME_ATTRIBUTE(self); GtkListStore *store = GTK_LIST_STORE (gtk_combo_box_get_model(GTK_COMBO_BOX(base->widget))); GtkTreeIter iter; const gchar *type, *nick, *icon_id; gtk_list_store_append(store, &iter); g_object_get(cursor, "type", &type, "nick", &nick, "icon_id", &icon_id, NULL); gtk_list_store_set(store, &iter, COLUMN_TYPE, type, COLUMN_NICK, nick, COLUMN_ICON_ID, icon_id, -1); } void gpass_gnome_type_attribute_clear(GPassGnomeTypeAttribute *self) { GPassGnomeAttribute *base = GPASS_GNOME_ATTRIBUTE(self); GtkListStore *store = GTK_LIST_STORE (gtk_combo_box_get_model(GTK_COMBO_BOX(base->widget))); gtk_list_store_clear(store); } /*********************************************************** * * GPassGnomeIntegerAttribute * ***********************************************************/ static void gnome_integer_attribute_value_to_widget(GPassGnomeAttribute *base) { gint value; gpass_attribute_get(base->attribute, &value); g_object_set(base->widget, "value", (gdouble) value, NULL); } static void gnome_integer_attribute_widget_to_value(GPassGnomeAttribute *base) { gdouble value; g_object_get(base->widget, "value", &value, NULL); gpass_attribute_set(base->attribute, (gint) value); } static void gnome_integer_attribute_create_widget(GPassGnomeAttribute *base) { base->widget = g_object_new(GTK_TYPE_SPIN_BUTTON, "digit", 0, "numeric", TRUE, NULL); gnome_integer_attribute_value_to_widget(base); } static void gnome_integer_attribute_class_initialize(gpointer g_class, gpointer g_class_data) { GPassGnomeAttributeClass *base_class = GPASS_GNOME_ATTRIBUTE_CLASS(g_class); base_class->create_widget = gnome_integer_attribute_create_widget; base_class->value_to_widget = gnome_integer_attribute_value_to_widget; base_class->widget_to_value = gnome_integer_attribute_widget_to_value; } GType gpass_gnome_integer_attribute_get_type(void) { static GType type = 0; if (type == 0) { static const GTypeInfo info = { sizeof(GPassGnomeIntegerAttributeClass), NULL, NULL, gnome_integer_attribute_class_initialize, NULL, NULL, sizeof(GPassGnomeIntegerAttribute), 0, NULL, }; type = g_type_register_static(GPASS_TYPE_GNOME_ATTRIBUTE, "GPassGnomeIntegerAttribute", &info, 0); } return type; } /*********************************************************** * * GPassGnomeBooleanAttribute * ***********************************************************/ static void set_label(GtkWidget *widget, gboolean active) { const gchar *label; if (active) { label = _("Yes"); } else { label = _("No"); } g_object_set(widget, "label", label, NULL); } static void gnome_boolean_attribute_value_to_widget(GPassGnomeAttribute *base) { gboolean active; gpass_attribute_get(base->attribute, &active); g_object_set(base->widget, "active", active, NULL); set_label(base->widget, active); } static void gnome_boolean_attribute_widget_to_value(GPassGnomeAttribute *base) { gboolean active; g_object_get(base->widget, "active", &active, NULL); gpass_attribute_set(base->attribute, active); } static void gnome_boolean_attribute_on_toggled(GtkWidget *widget, gpointer user_data) { gboolean active; g_object_get(widget, "active", &active, NULL); set_label(widget, active); } static void gnome_boolean_attribute_create_widget(GPassGnomeAttribute *base) { base->widget = g_object_new(GTK_TYPE_CHECK_BUTTON, "draw_indicator", FALSE, NULL); gnome_boolean_attribute_value_to_widget(base); g_signal_connect(base->widget, "toggled", G_CALLBACK(gnome_boolean_attribute_on_toggled), NULL); } static void gnome_boolean_attribute_class_initialize(gpointer g_class, gpointer g_class_data) { GPassGnomeAttributeClass *base_class = GPASS_GNOME_ATTRIBUTE_CLASS(g_class); base_class->create_widget = gnome_boolean_attribute_create_widget; base_class->value_to_widget = gnome_boolean_attribute_value_to_widget; base_class->widget_to_value = gnome_boolean_attribute_widget_to_value; } GType gpass_gnome_boolean_attribute_get_type(void) { static GType type = 0; if (type == 0) { static const GTypeInfo info = { sizeof(GPassGnomeBooleanAttributeClass), NULL, NULL, gnome_boolean_attribute_class_initialize, NULL, NULL, sizeof(GPassGnomeBooleanAttribute), 0, NULL, }; type = g_type_register_static(GPASS_TYPE_GNOME_ATTRIBUTE, "GPassGnomeBooleanAttribute", &info, 0); } return type; } /*********************************************************** * * GPassGnomeTimeAttribute * ***********************************************************/ static void gnome_time_attribute_value_to_widget(GPassGnomeAttribute *base) { GtkWidget *date, *hour, *min, *sec; struct tm tm; time_t t; gpass_attribute_get(base->attribute, &t); if (localtime_r(&t, &tm) == NULL) { /* todo: error */ } date = g_object_get_data(G_OBJECT(base->widget), "date"); g_object_set(date, "time", t, NULL); hour = g_object_get_data(G_OBJECT(base->widget), "hour"); g_object_set(hour, "value", (gdouble) tm.tm_hour, NULL); min = g_object_get_data(G_OBJECT(base->widget), "min"); g_object_set(min, "value", (gdouble) tm.tm_min, NULL); sec = g_object_get_data(G_OBJECT(base->widget), "sec"); g_object_set(sec, "value", (gdouble) tm.tm_sec, NULL); } static void gnome_time_attribute_widget_to_value(GPassGnomeAttribute *base) { GtkWidget *date, *hour, *min, *sec; struct tm tm; time_t t; gdouble value; date = g_object_get_data(G_OBJECT(base->widget), "date"); g_object_get(date, "time", &t, NULL); if (localtime_r(&t, &tm) == NULL) { /* todo: error */ } hour = g_object_get_data(G_OBJECT(base->widget), "hour"); g_object_get(hour, "value", &value, NULL); tm.tm_hour = (int) value; min = g_object_get_data(G_OBJECT(base->widget), "min"); g_object_get(min, "value", &value, NULL); tm.tm_min = (int) value; sec = g_object_get_data(G_OBJECT(base->widget), "sec"); g_object_get(sec, "value", &value, NULL); tm.tm_sec = (int) value; t = mktime(&tm); if (t == -1) { /* error */ } gpass_attribute_set(base->attribute, t); } static void gnome_time_attribute_create_widget(GPassGnomeAttribute *base) { GtkWidget *hbox, *date, *hour, *min, *sec, *label; GtkAdjustment *adj; base->widget = hbox = g_object_new(GTK_TYPE_HBOX, NULL); date = gnome_date_edit_new((time_t) 0, FALSE, FALSE); gtk_widget_show(date); gtk_box_pack_start(GTK_BOX(hbox), date, TRUE, TRUE, 2); adj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 24.0, 1.0, 4.0, 0.0)); hour = gtk_spin_button_new(adj, 1.0, 0); gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(hour), TRUE); gtk_widget_show(hour); gtk_box_pack_start(GTK_BOX(hbox), hour, FALSE, FALSE, 2); label = g_object_new(GTK_TYPE_LABEL, "label", ":", NULL); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2); adj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 60.0, 1.0, 10.0, 0.0)); min = gtk_spin_button_new(adj, 1.0, 0); gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(min), TRUE); gtk_widget_show(min); gtk_box_pack_start(GTK_BOX(hbox), min, FALSE, FALSE, 2); label = g_object_new(GTK_TYPE_LABEL, "label", ":", NULL); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2); adj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 60.0, 1.0, 10.0, 0.0)); sec = gtk_spin_button_new(adj, 1.0, 0); gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(sec), TRUE); gtk_widget_show(sec); gtk_box_pack_start(GTK_BOX(hbox), sec, FALSE, FALSE, 2); g_object_set_data(G_OBJECT(base->widget), "date", date); g_object_set_data(G_OBJECT(base->widget), "hour", hour); g_object_set_data(G_OBJECT(base->widget), "min", min); g_object_set_data(G_OBJECT(base->widget), "sec", sec); gnome_time_attribute_value_to_widget(base); } static void gnome_time_attribute_class_initialize(gpointer g_class, gpointer g_class_data) { GPassGnomeAttributeClass *base_class = GPASS_GNOME_ATTRIBUTE_CLASS(g_class); base_class->create_widget = gnome_time_attribute_create_widget; base_class->value_to_widget = gnome_time_attribute_value_to_widget; base_class->widget_to_value = gnome_time_attribute_widget_to_value; } GType gpass_gnome_time_attribute_get_type(void) { static GType type = 0; if (type == 0) { static const GTypeInfo info = { sizeof(GPassGnomeTimeAttributeClass), NULL, NULL, gnome_time_attribute_class_initialize, NULL, NULL, sizeof(GPassGnomeTimeAttribute), 0, NULL, }; type = g_type_register_static(GPASS_TYPE_GNOME_ATTRIBUTE, "GPassGnomeTimeAttribute", &info, 0); } return type; } /*********************************************************** * * GPassGnomeStringAttribute * ***********************************************************/ static void gnome_string_attribute_value_to_widget(GPassGnomeAttribute *base) { const gchar *str; gpass_attribute_get(base->attribute, &str); if (str == NULL) { str = ""; } g_object_set(base->widget, "text", str, NULL); } static void gnome_string_attribute_widget_to_value(GPassGnomeAttribute *base) { const gchar *str; g_object_get(base->widget, "text", &str, NULL); gpass_attribute_set(base->attribute, str); } static void gnome_string_attribute_create_widget(GPassGnomeAttribute *base) { base->widget = g_object_new(GTK_TYPE_ENTRY, NULL); gnome_string_attribute_value_to_widget(base); } static void gnome_string_attribute_class_initialize(gpointer g_class, gpointer g_class_data) { GPassGnomeAttributeClass *base_class = GPASS_GNOME_ATTRIBUTE_CLASS(g_class); base_class->create_widget = gnome_string_attribute_create_widget; base_class->value_to_widget = gnome_string_attribute_value_to_widget; base_class->widget_to_value = gnome_string_attribute_widget_to_value; } GType gpass_gnome_string_attribute_get_type(void) { static GType type = 0; if (type == 0) { static const GTypeInfo info = { sizeof(GPassGnomeStringAttributeClass), NULL, NULL, gnome_string_attribute_class_initialize, NULL, NULL, sizeof(GPassGnomeStringAttribute), 0, NULL, }; type = g_type_register_static(GPASS_TYPE_GNOME_ATTRIBUTE, "GPassGnomeStringAttribute", &info, 0); } return type; } /*********************************************************** * * GPassGnomeTextAttribute * ***********************************************************/ static void gnome_text_attribute_value_to_widget(GPassGnomeAttribute *base) { const gchar *str; GtkWidget *text = g_object_get_data(G_OBJECT(base->widget), "text"); GtkTextBuffer *buffer; gpass_attribute_get(base->attribute, &str); if (str == NULL) { str = ""; } g_object_get(text, "buffer", &buffer, NULL); gtk_text_buffer_set_text(buffer, str, -1); } static void gnome_text_attribute_widget_to_value(GPassGnomeAttribute *base) { GtkWidget *text = g_object_get_data(G_OBJECT(base->widget), "text"); GtkTextBuffer *buffer; GtkTextIter start, end; gchar *str; g_object_get(text, "buffer", &buffer, NULL); gtk_text_buffer_get_start_iter(buffer, &start); gtk_text_buffer_get_end_iter(buffer, &end); str = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); gpass_attribute_set(base->attribute, str); g_free(str); } static void gnome_text_attribute_create_widget(GPassGnomeAttribute *base) { GtkWidget *scroll, *text; base->widget = scroll = g_object_new(GTK_TYPE_SCROLLED_WINDOW, "hscrollbar_policy", GTK_POLICY_AUTOMATIC, "vscrollbar_policy", GTK_POLICY_AUTOMATIC, "shadow_type", GTK_SHADOW_IN, NULL); text = g_object_new(GTK_TYPE_TEXT_VIEW, NULL); gtk_widget_show(text); gtk_container_add(GTK_CONTAINER(scroll), text); g_object_set_data(G_OBJECT(base->widget), "text", text); gnome_text_attribute_value_to_widget(base); } static void gnome_text_attribute_class_initialize(gpointer g_class, gpointer g_class_data) { GPassGnomeAttributeClass *base_class = GPASS_GNOME_ATTRIBUTE_CLASS(g_class); base_class->create_widget = gnome_text_attribute_create_widget; base_class->value_to_widget = gnome_text_attribute_value_to_widget; base_class->widget_to_value = gnome_text_attribute_widget_to_value; } GType gpass_gnome_text_attribute_get_type(void) { static GType type = 0; if (type == 0) { static const GTypeInfo info = { sizeof(GPassGnomeTextAttributeClass), NULL, NULL, gnome_text_attribute_class_initialize, NULL, NULL, sizeof(GPassGnomeTextAttribute), 0, NULL, }; type = g_type_register_static(GPASS_TYPE_GNOME_ATTRIBUTE, "GPassGnomeTextAttribute", &info, 0); } return type; } /*********************************************************** * * GPassGnomePasswordAttribute * ***********************************************************/ static void gnome_password_attribute_value_to_widget(GPassGnomeAttribute *base) { GtkWidget *entry = g_object_get_data(G_OBJECT(base->widget), "entry"); const gchar *str; gpass_attribute_get(base->attribute, &str); if (str == NULL) { str = ""; } g_object_set(entry, "text", str, NULL); } static void gnome_password_attribute_widget_to_value(GPassGnomeAttribute *base) { GtkWidget *entry = g_object_get_data(G_OBJECT(base->widget), "entry"); const gchar *str; g_object_get(entry, "text", &str, NULL); gpass_attribute_set(base->attribute, str); } static void gnome_password_attribute_on_clicked(GtkWidget *widget, gpointer user_data) { GPassGnomePasswordAttribute *self = GPASS_GNOME_PASSWORD_ATTRIBUTE(user_data); GPassPasswordGenerator *generator = g_object_new(GPASS_TYPE_PASSWORD_GENERATOR, "template", "password-generator", NULL); GPassViewResult view_result; GError *error; error = gpass_view_run(GPASS_VIEW(generator), &view_result); if (error != NULL) { gpass_error_show_and_exit(error); } if (view_result == GPASS_VIEW_RESULT_SUCCEED) { GPassGnomeAttribute *base = GPASS_GNOME_ATTRIBUTE(self); GtkWidget *entry = g_object_get_data(G_OBJECT(base->widget), "entry"); const gchar *password; g_object_get(generator, "password", &password, NULL); g_object_set(entry, "text", password, NULL); } g_object_unref(generator); } static void gnome_password_attribute_create_widget(GPassGnomeAttribute *base) { GPassGnomePasswordAttribute *self = GPASS_GNOME_PASSWORD_ATTRIBUTE(base); GtkWidget *hbox, *entry, *image, *button; GPassConfiguration *config = gpass_configuration_instance(); gboolean visible_secrets; base->widget = hbox = g_object_new(GTK_TYPE_HBOX, NULL); g_object_get(config, "visible_secrets", &visible_secrets, NULL); entry = g_object_new(GTK_TYPE_ENTRY, "visibility", visible_secrets, NULL); gtk_widget_show(entry); gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); image = g_object_new(GTK_TYPE_IMAGE, "stock", "gtk-execute", "icon_size", GTK_ICON_SIZE_BUTTON, NULL); button = g_object_new(GTK_TYPE_BUTTON, "label", _("_Generate"), "use-underline", TRUE, "image", image, NULL); gtk_widget_show(button); g_signal_connect(button, "clicked", G_CALLBACK(gnome_password_attribute_on_clicked), self); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 4); g_object_set_data(G_OBJECT(hbox), "entry", entry); gnome_password_attribute_value_to_widget(base); } static void gnome_password_attribute_class_initialize(gpointer g_class, gpointer g_class_data) { GPassGnomeAttributeClass *base_class = GPASS_GNOME_ATTRIBUTE_CLASS(g_class); base_class->create_widget = gnome_password_attribute_create_widget; base_class->value_to_widget = gnome_password_attribute_value_to_widget; base_class->widget_to_value = gnome_password_attribute_widget_to_value; } GType gpass_gnome_password_attribute_get_type(void) { static GType type = 0; if (type == 0) { static const GTypeInfo info = { sizeof(GPassGnomePasswordAttributeClass), NULL, NULL, gnome_password_attribute_class_initialize, NULL, NULL, sizeof(GPassGnomePasswordAttribute), 0, NULL, }; type = g_type_register_static(GPASS_TYPE_GNOME_ATTRIBUTE, "GPassGnomePasswordAttribute", &info, 0); } return type; }