[epiphany] Add a popup menu to copy username and password



commit ffc391d4b16ae2e9b4d70570ab3a2952ce77c88f
Author: William Jon McCann <william jon mccann gmail com>
Date:   Tue Dec 10 19:14:32 2013 +0100

    Add a popup menu to copy username and password
    
    https://bugzilla.gnome.org/show_bug.cgi?id=720239

 src/passwords-dialog.c            |   95 +++++++++++++++++++++++++++++++++++++
 src/resources/passwords-dialog.ui |   25 +++++++++-
 2 files changed, 119 insertions(+), 1 deletions(-)
---
diff --git a/src/passwords-dialog.c b/src/passwords-dialog.c
index e144502..3d626db 100644
--- a/src/passwords-dialog.c
+++ b/src/passwords-dialog.c
@@ -56,6 +56,9 @@ struct PasswordsDialogPrivate
        GtkWidget *clear_button;
        GtkWidget *password_column;
        GtkWidget *password_renderer;
+       GtkWidget *treeview_popup_menu;
+       GtkWidget *copy_password_menuitem;
+       GtkWidget *copy_username_menuitem;
 
        SecretService *ss;
        GCancellable *ss_cancellable;
@@ -269,6 +272,92 @@ on_search_entry_changed (GtkSearchEntry *entry,
 }
 
 static void
+get_selected_item (PasswordsDialog *dialog,
+                  char **o_username,
+                  char **o_password)
+{
+       GtkTreeSelection *selection;
+       GtkTreeModel *model;
+       GList *selected;
+       GtkTreeIter iter;
+       char *username = NULL;
+       char *password = NULL;
+
+       selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->priv->passwords_treeview));
+       selected = gtk_tree_selection_get_selected_rows (selection, &model);
+       gtk_tree_model_get_iter (model, &iter, selected->data);
+       gtk_tree_model_get (model, &iter,
+                           COL_PASSWORDS_USER, &username,
+                           COL_PASSWORDS_PASSWORD, &password,
+                           -1);
+       g_list_free_full (selected, (GDestroyNotify) gtk_tree_path_free);
+
+       if (o_username)
+               *o_username = g_strdup (username);
+       if (o_password)
+               *o_password = g_strdup (password);
+
+       g_free (username);
+       g_free (password);
+}
+
+static void
+on_copy_password_menuitem_activate (GtkMenuItem *menuitem,
+                                   PasswordsDialog *dialog)
+{
+       char *password = NULL;
+
+       get_selected_item (dialog, NULL, &password);
+       if (password != NULL) {
+               gtk_clipboard_set_text (gtk_widget_get_clipboard (GTK_WIDGET (menuitem),
+                                                                 GDK_SELECTION_CLIPBOARD),
+                                       password, -1);
+       }
+       g_free (password);
+}
+
+static void
+on_copy_username_menuitem_activate (GtkMenuItem *menuitem,
+                                   PasswordsDialog *dialog)
+{
+       char *username = NULL;
+
+       get_selected_item (dialog, &username, NULL);
+       if (username != NULL) {
+               gtk_clipboard_set_text (gtk_widget_get_clipboard (GTK_WIDGET (menuitem),
+                                                                 GDK_SELECTION_CLIPBOARD),
+                                       username, -1);
+       }
+       g_free (username);
+}
+
+static gboolean
+on_passwords_treeview_button_press_event (GtkWidget       *widget,
+                                         GdkEventButton  *event,
+                                         PasswordsDialog *dialog)
+{
+       if (event->button == 3) {
+               GtkTreeSelection *selection;
+               int n;
+
+               selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->priv->passwords_treeview));
+               n = gtk_tree_selection_count_selected_rows (selection);
+               if (n == 0)
+                       return FALSE;
+
+               gtk_widget_set_sensitive (dialog->priv->copy_password_menuitem, (n == 1));
+               gtk_widget_set_sensitive (dialog->priv->copy_username_menuitem, (n == 1));
+
+               gtk_menu_popup (GTK_MENU (dialog->priv->treeview_popup_menu),
+                               NULL, NULL, NULL, NULL,
+                               event->button, event->time);
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+static void
 passwords_dialog_class_init (PasswordsDialogClass *klass)
 {
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -288,12 +377,18 @@ passwords_dialog_class_init (PasswordsDialogClass *klass)
        gtk_widget_class_bind_template_child_private (widget_class, PasswordsDialog, 
show_passwords_toolbutton);
        gtk_widget_class_bind_template_child_private (widget_class, PasswordsDialog, password_column);
        gtk_widget_class_bind_template_child_private (widget_class, PasswordsDialog, password_renderer);
+       gtk_widget_class_bind_template_child_private (widget_class, PasswordsDialog, treeview_popup_menu);
+       gtk_widget_class_bind_template_child_private (widget_class, PasswordsDialog, copy_password_menuitem);
+       gtk_widget_class_bind_template_child_private (widget_class, PasswordsDialog, copy_username_menuitem);
 
        gtk_widget_class_bind_template_callback (widget_class, on_passwords_treeview_key_press_event);
+       gtk_widget_class_bind_template_callback (widget_class, on_passwords_treeview_button_press_event);
        gtk_widget_class_bind_template_callback (widget_class, on_treeview_selection_changed);
        gtk_widget_class_bind_template_callback (widget_class, on_remove_toolbutton_clicked);
        gtk_widget_class_bind_template_callback (widget_class, on_show_passwords_toolbutton_toggled);
        gtk_widget_class_bind_template_callback (widget_class, on_search_entry_changed);
+       gtk_widget_class_bind_template_callback (widget_class, on_copy_password_menuitem_activate);
+       gtk_widget_class_bind_template_callback (widget_class, on_copy_username_menuitem_activate);
 }
 
 static void
diff --git a/src/resources/passwords-dialog.ui b/src/resources/passwords-dialog.ui
index ddcac15..3add27b 100644
--- a/src/resources/passwords-dialog.ui
+++ b/src/resources/passwords-dialog.ui
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.16.0 on Tue Dec 10 17:15:21 2013 -->
+<!-- Generated with glade 3.16.0 on Tue Dec 10 19:19:35 2013 -->
 <interface>
   <!-- interface-requires gtk+ 3.10 -->
   <object class="GtkListStore" id="liststore">
@@ -130,6 +130,7 @@
                         <property name="enable_search">False</property>
                         <property name="search_column">0</property>
                         <signal name="key-press-event" handler="on_passwords_treeview_key_press_event" 
object="PasswordsDialog" swapped="no"/>
+                        <signal name="button-press-event" handler="on_passwords_treeview_button_press_event" 
object="PasswordsDialog" swapped="no"/>
                         <child internal-child="selection">
                           <object class="GtkTreeSelection" id="treeview-selection">
                             <property name="mode">multiple</property>
@@ -263,4 +264,26 @@
       <action-widget response="-7">close_button</action-widget>
     </action-widgets>
   </template>
+  <object class="GtkMenu" id="treeview_popup_menu">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <child>
+      <object class="GtkMenuItem" id="copy_password_menuitem">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">_Copy Password</property>
+        <property name="use_underline">True</property>
+        <signal name="activate" handler="on_copy_password_menuitem_activate" object="PasswordsDialog" 
swapped="no"/>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="copy_username_menuitem">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">C_opy Username</property>
+        <property name="use_underline">True</property>
+        <signal name="activate" handler="on_copy_username_menuitem_activate" object="PasswordsDialog" 
swapped="no"/>
+      </object>
+    </child>
+  </object>
 </interface>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]