seahorse r2682 - in trunk: . libseahorse pgp src
- From: nnielsen svn gnome org
- To: svn-commits-list gnome org
- Subject: seahorse r2682 - in trunk: . libseahorse pgp src
- Date: Tue, 16 Dec 2008 22:33:53 +0000 (UTC)
Author: nnielsen
Date: Tue Dec 16 22:33:53 2008
New Revision: 2682
URL: http://svn.gnome.org/viewvc/seahorse?rev=2682&view=rev
Log:
* libseahorse/seahorse-object.c: Lots of fixes on when to
realize objects.
* libseahorse/seahorse-object-widget.c: Don't do a window grab.
* pgp/seahorse-add-subkey.glade:
* pgp/seahorse-expires.glade:
* pgp/seahorse-gpgme-add-subkey.c:
* pgp/seahorse-gpgme-expires.c:
* pgp/seahorse-gpgme-key.c:
* pgp/seahorse-gpgme-key-op.c:
* pgp/seahorse-gpgme-subkey.c:
* pgp/seahorse-gpgme-uid.c:
* pgp/seahorse-gpgme-uid.h:
* pgp/seahorse-hkp-source.c:
* pgp/seahorse-ldap-source.c:
* pgp/seahorse-pgp-commands.c:
* pgp/seahorse-pgp-key.c:
* pgp/seahorse-pgp-key-properties.c:
* pgp/seahorse-pgp-private-key-properties.glade:
* pgp/seahorse-pgp-public-key-properties.glade:
* pgp/seahorse-pgp-signature.c:
* pgp/seahorse-pgp-subkey.c:
* pgp/seahorse-pgp-subkey.h:
* pgp/seahorse-pgp-uid.c:
* src/seahorse-keyserver-results.c:
* src/seahorse-keyserver-results.ui: Fix various PGP key operations. Lots of UI
fixes as well. Go through and test everything in the PGP dialogs.
Fixes for searching for remote keys.
Modified:
trunk/ChangeLog
trunk/libseahorse/seahorse-object-widget.c
trunk/libseahorse/seahorse-object.c
trunk/pgp/seahorse-add-subkey.glade
trunk/pgp/seahorse-expires.glade
trunk/pgp/seahorse-gpgme-add-subkey.c
trunk/pgp/seahorse-gpgme-expires.c
trunk/pgp/seahorse-gpgme-key-op.c
trunk/pgp/seahorse-gpgme-key.c
trunk/pgp/seahorse-gpgme-subkey.c
trunk/pgp/seahorse-gpgme-uid.c
trunk/pgp/seahorse-gpgme-uid.h
trunk/pgp/seahorse-hkp-source.c
trunk/pgp/seahorse-ldap-source.c
trunk/pgp/seahorse-pgp-commands.c
trunk/pgp/seahorse-pgp-key-properties.c
trunk/pgp/seahorse-pgp-key.c
trunk/pgp/seahorse-pgp-private-key-properties.glade
trunk/pgp/seahorse-pgp-public-key-properties.glade
trunk/pgp/seahorse-pgp-signature.c
trunk/pgp/seahorse-pgp-subkey.c
trunk/pgp/seahorse-pgp-subkey.h
trunk/pgp/seahorse-pgp-uid.c
trunk/src/seahorse-keyserver-results.c
trunk/src/seahorse-keyserver-results.ui
Modified: trunk/libseahorse/seahorse-object-widget.c
==============================================================================
--- trunk/libseahorse/seahorse-object-widget.c (original)
+++ trunk/libseahorse/seahorse-object-widget.c Tue Dec 16 22:33:53 2008
@@ -99,7 +99,6 @@
SeahorseWidget *swidget;
SeahorseObjectWidget *self;
GHashTable *widgets = NULL;
- GtkWindowGroup *group = NULL;
GQuark id;
GtkWidget *widget;
@@ -126,7 +125,6 @@
}
widget = seahorse_widget_get_toplevel (swidget);
- gtk_grab_remove (widget);
/* Remove from parent */
gtk_window_set_transient_for (GTK_WINDOW (widget), NULL);
@@ -248,10 +246,9 @@
g_hash_table_insert (groups, GUINT_TO_POINTER (id), group);
}
- /* get window, add it to the group, grab it, return it */
+ /* get window, add it to the group, return it */
widget = seahorse_widget_get_toplevel (swidget);
gtk_window_group_add_window (group, GTK_WINDOW (widget));
- gtk_grab_add (widget);
if (parent != NULL)
gtk_window_set_transient_for (GTK_WINDOW (widget), parent);
Modified: trunk/libseahorse/seahorse-object.c
==============================================================================
--- trunk/libseahorse/seahorse-object.c (original)
+++ trunk/libseahorse/seahorse-object.c Tue Dec 16 22:33:53 2008
@@ -341,49 +341,49 @@
switch (prop_id) {
case PROP_CONTEXT:
- g_value_set_object (value, self->pv->context);
+ g_value_set_object (value, seahorse_object_get_context (self));
break;
case PROP_SOURCE:
- g_value_set_object (value, self->pv->source);
+ g_value_set_object (value, seahorse_object_get_source (self));
break;
case PROP_PREFERRED:
- g_value_set_object (value, self->pv->preferred);
+ g_value_set_object (value, seahorse_object_get_preferred (self));
break;
case PROP_PARENT:
- g_value_set_object (value, self->pv->parent);
+ g_value_set_object (value, seahorse_object_get_parent (self));
break;
case PROP_ID:
- g_value_set_uint (value, self->pv->id);
+ g_value_set_uint (value, seahorse_object_get_id (self));
break;
case PROP_TAG:
- g_value_set_uint (value, self->pv->tag);
+ g_value_set_uint (value, seahorse_object_get_tag (self));
break;
case PROP_LABEL:
- g_value_set_string (value, self->pv->label);
+ g_value_set_string (value, seahorse_object_get_label (self));
break;
case PROP_NICKNAME:
- g_value_set_string (value, self->pv->nickname);
+ g_value_set_string (value, seahorse_object_get_nickname (self));
break;
case PROP_MARKUP:
- g_value_set_string (value, self->pv->markup);
+ g_value_set_string (value, seahorse_object_get_markup (self));
break;
case PROP_DESCRIPTION:
- g_value_set_string (value, self->pv->description);
+ g_value_set_string (value, seahorse_object_get_description (self));
break;
case PROP_ICON:
- g_value_set_string (value, self->pv->icon);
+ g_value_set_string (value, seahorse_object_get_icon (self));
break;
case PROP_IDENTIFIER:
- g_value_set_string (value, self->pv->identifier);
+ g_value_set_string (value, seahorse_object_get_identifier (self));
break;
case PROP_LOCATION:
- g_value_set_enum (value, self->pv->location);
+ g_value_set_enum (value, seahorse_object_get_location (self));
break;
case PROP_USAGE:
- g_value_set_enum (value, self->pv->usage);
+ g_value_set_enum (value, seahorse_object_get_usage (self));
break;
case PROP_FLAGS:
- g_value_set_uint (value, self->pv->flags);
+ g_value_set_uint (value, seahorse_object_get_flags (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
Modified: trunk/pgp/seahorse-add-subkey.glade
==============================================================================
--- trunk/pgp/seahorse-add-subkey.glade (original)
+++ trunk/pgp/seahorse-add-subkey.glade Tue Dec 16 22:33:53 2008
@@ -96,6 +96,46 @@
<property name="column_spacing">12</property>
<child>
+ <widget class="GtkCheckButton" id="never_expires">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">If key never expires</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Never E_xpires</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">True</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="never_expires_toggled"/>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="type">
+ <property name="visible">True</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ <signal name="changed" handler="type_changed"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">Key _Type:</property>
@@ -119,7 +159,7 @@
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
- <property name="x_options"></property>
+ <property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
@@ -148,7 +188,7 @@
<property name="right_attach">1</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
- <property name="x_options"></property>
+ <property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
@@ -176,70 +216,72 @@
<property name="right_attach">1</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
- <property name="x_options"></property>
+ <property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
- <widget class="GtkCheckButton" id="never_expires">
+ <widget class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
- <property name="tooltip" translatable="yes">If key never expires</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Never E_xpires</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">True</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="never_expires_toggled"/>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkSpinButton" id="length">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">Length of Key</property>
- <property name="can_focus">True</property>
- <property name="climb_rate">128</property>
- <property name="digits">0</property>
- <property name="numeric">True</property>
- <property name="update_policy">GTK_UPDATE_ALWAYS</property>
- <property name="snap_to_ticks">True</property>
- <property name="wrap">False</property>
- <property name="adjustment">1024 768 1024 1 128 0</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">0</property>
+ <property name="yscale">1</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">0</property>
+ <property name="right_padding">0</property>
+
+ <child>
+ <widget class="GtkSpinButton" id="length">
+ <property name="width_request">80</property>
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Length of Key</property>
+ <property name="can_focus">True</property>
+ <property name="climb_rate">128</property>
+ <property name="digits">0</property>
+ <property name="numeric">True</property>
+ <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+ <property name="snap_to_ticks">True</property>
+ <property name="wrap">False</property>
+ <property name="adjustment">1024 768 1024 1 128 0</property>
+ </widget>
+ </child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
- <property name="y_options"></property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
</packing>
</child>
<child>
- <widget class="GtkComboBox" id="type">
+ <widget class="GtkAlignment" id="datetime-placeholder">
<property name="visible">True</property>
- <property name="add_tearoffs">False</property>
- <property name="focus_on_click">True</property>
- <signal name="changed" handler="type_changed"/>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">1</property>
+ <property name="yscale">1</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">0</property>
+ <property name="right_padding">0</property>
+
+ <child>
+ <placeholder/>
+ </child>
</widget>
<packing>
<property name="left_attach">1</property>
- <property name="right_attach">3</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="y_options"></property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
</packing>
</child>
</widget>
Modified: trunk/pgp/seahorse-expires.glade
==============================================================================
--- trunk/pgp/seahorse-expires.glade (original)
+++ trunk/pgp/seahorse-expires.glade Tue Dec 16 22:33:53 2008
@@ -9,7 +9,7 @@
<property name="title" translatable="yes"></property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
+ <property name="modal">True</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
Modified: trunk/pgp/seahorse-gpgme-add-subkey.c
==============================================================================
--- trunk/pgp/seahorse-gpgme-add-subkey.c (original)
+++ trunk/pgp/seahorse-gpgme-add-subkey.c Tue Dec 16 22:33:53 2008
@@ -71,34 +71,12 @@
}
}
-static GtkWidget *
-get_expires (SeahorseWidget *swidget)
-{
- GtkWidget *widget;
- GList *children;
-
- g_return_val_if_fail (swidget != NULL, NULL);
-
- widget = seahorse_widget_get_widget (swidget, "table1");
- g_return_val_if_fail (widget != NULL, NULL);
-
- children = gtk_container_get_children (GTK_CONTAINER (widget));
- g_return_val_if_fail (children, NULL);
-
- /* The fifth element should be expires */
- widget = g_list_nth_data (children, 5);
-
- g_list_free (children);
-
- return widget;
-}
-
static void
never_expires_toggled (GtkToggleButton *togglebutton, SeahorseWidget *swidget)
{
GtkWidget *widget;
- widget = get_expires (swidget);
+ widget = GTK_WIDGET (g_object_get_data (G_OBJECT (swidget), "expires-datetime"));
g_return_if_fail (widget);
gtk_widget_set_sensitive (GTK_WIDGET (widget),
@@ -135,7 +113,7 @@
glade_xml_get_widget (swidget->xml, "never_expires"))))
expires = 0;
else {
- widget = get_expires (swidget);
+ widget = GTK_WIDGET (g_object_get_data (G_OBJECT (swidget), "expires-datetime"));
g_return_if_fail (widget);
egg_datetime_get_as_time_t (EGG_DATETIME (widget), &expires);
@@ -176,7 +154,7 @@
GtkTreeModel *model;
GtkTreeIter iter;
GtkCellRenderer *renderer;
- GtkWidget *widget;
+ GtkWidget *widget, *datetime;
swidget = seahorse_object_widget_new ("add-subkey", parent, SEAHORSE_OBJECT (pkey));
g_return_if_fail (swidget != NULL);
@@ -229,7 +207,13 @@
glade_xml_signal_connect_data (swidget->xml, "type_changed",
G_CALLBACK (type_changed), swidget);
- widget = seahorse_widget_get_widget (swidget, "table1");
- g_return_if_fail (widget != NULL);
- gtk_table_attach_defaults (GTK_TABLE (widget), egg_datetime_new (), 1, 2, 2, 3);
+
+ widget = seahorse_widget_get_widget (swidget, "datetime-placeholder");
+ g_return_if_fail (widget != NULL);
+
+ datetime = egg_datetime_new ();
+ gtk_container_add (GTK_CONTAINER (widget), datetime);
+ gtk_widget_show (datetime);
+ gtk_widget_set_sensitive (datetime, FALSE);
+ g_object_set_data (G_OBJECT (swidget), "expires-datetime", datetime);
}
Modified: trunk/pgp/seahorse-gpgme-expires.c
==============================================================================
--- trunk/pgp/seahorse-gpgme-expires.c (original)
+++ trunk/pgp/seahorse-gpgme-expires.c Tue Dec 16 22:33:53 2008
@@ -40,19 +40,25 @@
SeahorseGpgmeSubkey *subkey;
gpgme_error_t err;
time_t expiry = 0;
- struct tm t;
+ struct tm when;
subkey = SEAHORSE_GPGME_SUBKEY (g_object_get_data (G_OBJECT (swidget), "subkey"));
widget = glade_xml_get_widget (swidget->xml, "expire");
if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
- memset (&t, 0, sizeof(t));
+ memset (&when, 0, sizeof (when));
widget = glade_xml_get_widget (swidget->xml, "calendar");
- gtk_calendar_get_date (GTK_CALENDAR (widget), (guint*)&(t.tm_year),
- (guint*)&(t.tm_mon), (guint*)&(t.tm_mday));
- t.tm_year -= 1900;
- expiry = mktime (&t);
+ gtk_calendar_get_date (GTK_CALENDAR (widget), (guint*)&(when.tm_year),
+ (guint*)&(when.tm_mon), (guint*)&(when.tm_mday));
+ when.tm_year -= 1900;
+ expiry = mktime (&when);
+
+ if (expiry <= time (NULL)) {
+ seahorse_util_show_error (widget, _("Invalid expiry date"),
+ _("The expiry date must be in the future"));
+ return;
+ }
}
widget = seahorse_widget_get_widget (swidget, "all-controls");
@@ -96,7 +102,8 @@
swidget = seahorse_widget_new_allow_multiple ("expires", parent);
g_return_if_fail (swidget != NULL);
- g_object_set_data_full (G_OBJECT (swidget), "subkey", subkey, g_object_unref);
+ g_object_set_data_full (G_OBJECT (swidget), "subkey",
+ g_object_ref (subkey), g_object_unref);
glade_xml_signal_connect_data (swidget->xml, "on_calendar_change_button_clicked",
G_CALLBACK (ok_clicked), swidget);
Modified: trunk/pgp/seahorse-gpgme-key-op.c
==============================================================================
--- trunk/pgp/seahorse-gpgme-key-op.c (original)
+++ trunk/pgp/seahorse-gpgme-key-op.c Tue Dec 16 22:33:53 2008
@@ -556,7 +556,7 @@
signed_key = seahorse_gpgme_uid_get_pubkey (uid);
g_return_val_if_fail (signing_key, GPG_E (GPG_ERR_INV_VALUE));
- sign_index = seahorse_gpgme_uid_get_gpgme_index (uid) + 1;
+ sign_index = seahorse_gpgme_uid_get_actual_index (uid);
return sign_process (signed_key, signing_key, sign_index, check, options);
}
@@ -2098,7 +2098,7 @@
g_return_val_if_fail (key, GPG_E (GPG_ERR_INV_VALUE));
del_uid_parm.index = seahorse_gpgme_uid_get_actual_index (uid);
-
+
parms = seahorse_edit_parm_new (DEL_UID_START, del_uid_action,
del_uid_transit, &del_uid_parm);
@@ -2220,7 +2220,7 @@
PhotoIdAddParm photoid_add_parm;
gpgme_key_t key;
- g_return_val_if_fail (SEAHORSE_IS_GPGME_KEY (key), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
+ g_return_val_if_fail (SEAHORSE_IS_GPGME_KEY (pkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
g_return_val_if_fail (filename, GPG_E (GPG_ERR_INV_VALUE));
key = seahorse_gpgme_key_get_public (pkey);
Modified: trunk/pgp/seahorse-gpgme-key.c
==============================================================================
--- trunk/pgp/seahorse-gpgme-key.c (original)
+++ trunk/pgp/seahorse-gpgme-key.c Tue Dec 16 22:33:53 2008
@@ -53,8 +53,12 @@
gpgme_key_t seckey; /* The secret key */
gboolean has_secret; /* Whether we have a secret key or not */
+ GList *uids; /* We keep a copy of the uids. */
+
int list_mode; /* What to load our public key as */
gboolean photos_loaded; /* Photos were loaded */
+
+ gint block_loading; /* Loading is blocked while this flag is set */
};
/* -----------------------------------------------------------------------------
@@ -94,6 +98,9 @@
gboolean ret;
GQuark id;
+ if (self->pv->block_loading)
+ return;
+
list_mode |= self->pv->list_mode;
id = seahorse_object_get_id (SEAHORSE_OBJECT (self));
@@ -122,7 +129,7 @@
gboolean ret;
GQuark id;
- if (!self->pv->has_secret)
+ if (!self->pv->has_secret || self->pv->block_loading)
return;
id = seahorse_object_get_id (SEAHORSE_OBJECT (self));
@@ -146,7 +153,7 @@
static gboolean
require_key_uids (SeahorseGpgmeKey *self)
{
- return require_key_public (self, GPGME_KEYLIST_MODE_LOCAL);
+ return require_key_public (self, GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_SIGS);
}
static gboolean
@@ -159,6 +166,10 @@
load_key_photos (SeahorseGpgmeKey *self)
{
gpgme_error_t gerr;
+
+ if (self->pv->block_loading)
+ return;
+
gerr = seahorse_gpgme_key_op_photos_load (self);
if (!GPG_IS_OK (gerr))
g_message ("couldn't load key photos: %s", gpgme_strerror (gerr));
@@ -179,7 +190,6 @@
{
GArray *index_map;
GList *photos, *uids, *l;
- gboolean photos_loaded;
guint index, i;
g_assert (SEAHORSE_IS_GPGME_KEY (self));
@@ -191,12 +201,11 @@
* function is only to be called with uids from gpgme_user_id_t structs.
*/
- /* Prevent photos from actually loading if not already loaded */
- photos_loaded = self->pv->photos_loaded;
- self->pv->photos_loaded = TRUE;
+ ++self->pv->block_loading;
photos = seahorse_pgp_key_get_photos (SEAHORSE_PGP_KEY (self));
- self->pv->photos_loaded = photos_loaded;
-
+ uids = self->pv->uids;
+ --self->pv->block_loading;
+
/* First we build a bitmap of where all the photo uid indexes are */
index_map = g_array_new (FALSE, TRUE, sizeof (gboolean));
for (l = photos; l; l = g_list_next (l)) {
@@ -207,39 +216,59 @@
}
/* Now for each UID we add however many photo indexes are below the gpgme index */
- uids = seahorse_pgp_key_get_uids (SEAHORSE_PGP_KEY (self));
for (l = uids; l; l = g_list_next (l)) {
index = seahorse_gpgme_uid_get_gpgme_index (l->data);
for (i = 0; i < index_map->len && i < index; ++i) {
if(g_array_index (index_map, gboolean, index))
++index;
}
- seahorse_gpgme_uid_set_actual_index (l->data, index);
+ seahorse_gpgme_uid_set_actual_index (l->data, index + 1);
}
g_array_free (index_map, TRUE);
}
-static void
+static void
realize_uids (SeahorseGpgmeKey *self)
{
gpgme_user_id_t guid;
SeahorseGpgmeUid *uid;
- GList *list = NULL;
-
- if (self->pv->pubkey) {
+ GList *results = NULL;
+ gboolean changed = FALSE;
+ GList *uids;
- for (guid = self->pv->pubkey->uids; guid; guid = guid->next) {
- uid = seahorse_gpgme_uid_new (self->pv->pubkey, guid);
- list = seahorse_object_list_prepend (list, uid);
- g_object_unref (uid);
+ uids = self->pv->uids;
+ guid = self->pv->pubkey ? self->pv->pubkey->uids : NULL;
+
+ /* Look for out of sync or missing UIDs */
+ while (uids != NULL) {
+ g_return_if_fail (SEAHORSE_IS_GPGME_UID (uids->data));
+ uid = SEAHORSE_GPGME_UID (uids->data);
+ uids = g_list_next (uids);
+
+ /* Bring this UID up to date */
+ if (guid && seahorse_gpgme_uid_is_same (uid, guid)) {
+ if (seahorse_gpgme_uid_get_userid (uid) != guid) {
+ g_object_set (uid, "pubkey", self->pv->pubkey, "userid", guid, NULL);
+ changed = TRUE;
+ }
+ results = seahorse_object_list_append (results, uid);
+ guid = guid->next;
}
-
- list = g_list_reverse (list);
}
- seahorse_pgp_key_set_uids (SEAHORSE_PGP_KEY (self), list);
- seahorse_object_list_free (list);
+ /* Add new UIDs */
+ while (guid != NULL) {
+ uid = seahorse_gpgme_uid_new (self->pv->pubkey, guid);
+ changed = TRUE;
+ results = seahorse_object_list_append (results, uid);
+ g_object_unref (uid);
+ guid = guid->next;
+ }
+
+ if (changed)
+ seahorse_pgp_key_set_uids (SEAHORSE_PGP_KEY (self), results);
+ seahorse_object_list_free (results);
}
static void
@@ -278,7 +307,6 @@
seahorse_gpgme_key_realize (SeahorseObject *obj)
{
SeahorseGpgmeKey *self = SEAHORSE_GPGME_KEY (obj);
- SeahorseLocation loc;
SeahorseUsage usage;
guint flags;
@@ -324,18 +352,6 @@
g_object_set (obj, "flags", flags, NULL);
- /* The location */
- loc = seahorse_object_get_location (obj);
-
- if (self->pv->pubkey->keylist_mode & GPGME_KEYLIST_MODE_EXTERN &&
- loc <= SEAHORSE_LOCATION_REMOTE)
- loc = SEAHORSE_LOCATION_REMOTE;
-
- else if (loc <= SEAHORSE_LOCATION_LOCAL)
- loc = SEAHORSE_LOCATION_LOCAL;
-
- g_object_set (obj, "location", loc, NULL);
-
/* The type */
if (self->pv->seckey)
usage = SEAHORSE_USAGE_PRIVATE_KEY;
@@ -344,7 +360,9 @@
g_object_set (obj, "usage", usage, NULL);
+ ++self->pv->block_loading;
SEAHORSE_OBJECT_CLASS (seahorse_gpgme_key_parent_class)->realize (obj);
+ --self->pv->block_loading;
}
static void
@@ -393,6 +411,11 @@
{
SeahorseGpgmeKey *self = SEAHORSE_GPGME_KEY (base);
SEAHORSE_PGP_KEY_CLASS (seahorse_gpgme_key_parent_class)->set_uids (base, uids);
+
+ /* Keep our own copy of the UID list */
+ seahorse_object_list_free (self->pv->uids);
+ self->pv->uids = seahorse_object_list_copy (uids);
+
renumber_actual_uids (self);
}
@@ -425,6 +448,7 @@
seahorse_gpgme_key_init (SeahorseGpgmeKey *self)
{
self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, SEAHORSE_TYPE_GPGME_KEY, SeahorseGpgmeKeyPrivate);
+ g_object_set (self, "location", SEAHORSE_LOCATION_LOCAL, NULL);
}
static void
@@ -475,6 +499,9 @@
if (self->pv->seckey)
gpgme_key_unref (self->pv->seckey);
self->pv->pubkey = self->pv->seckey = NULL;
+
+ seahorse_object_list_free (self->pv->uids);
+ self->pv->uids = NULL;
G_OBJECT_CLASS (seahorse_gpgme_key_parent_class)->dispose (obj);
}
@@ -486,6 +513,7 @@
g_assert (self->pv->pubkey == NULL);
g_assert (self->pv->seckey == NULL);
+ g_assert (self->pv->uids == NULL);
G_OBJECT_CLASS (seahorse_gpgme_key_parent_class)->finalize (obj);
}
@@ -611,23 +639,19 @@
SeahorseValidity
seahorse_gpgme_key_get_validity (SeahorseGpgmeKey *self)
{
- GList *uids;
-
g_return_val_if_fail (SEAHORSE_IS_GPGME_KEY (self), SEAHORSE_VALIDITY_UNKNOWN);
if (!require_key_public (self, GPGME_KEYLIST_MODE_LOCAL))
return SEAHORSE_VALIDITY_UNKNOWN;
g_return_val_if_fail (self->pv->pubkey, SEAHORSE_VALIDITY_UNKNOWN);
+ g_return_val_if_fail (self->pv->pubkey->uids, SEAHORSE_VALIDITY_UNKNOWN);
- uids = seahorse_pgp_key_get_uids (SEAHORSE_PGP_KEY (self));
- g_return_val_if_fail (uids, SEAHORSE_VALIDITY_UNKNOWN);
-
if (self->pv->pubkey->revoked)
return SEAHORSE_VALIDITY_REVOKED;
if (self->pv->pubkey->disabled)
return SEAHORSE_VALIDITY_DISABLED;
- return seahorse_pgp_uid_get_validity (SEAHORSE_PGP_UID (uids->data));
+ return seahorse_gpgme_convert_validity (self->pv->pubkey->uids->validity);
}
SeahorseValidity
Modified: trunk/pgp/seahorse-gpgme-subkey.c
==============================================================================
--- trunk/pgp/seahorse-gpgme-subkey.c (original)
+++ trunk/pgp/seahorse-gpgme-subkey.c Tue Dec 16 22:33:53 2008
@@ -176,6 +176,7 @@
GObject *obj;
gpgme_subkey_t sub;
gint i, index;
+ guint flags;
g_return_if_fail (SEAHORSE_IS_GPGME_SUBKEY (self));
g_return_if_fail (subkey);
@@ -214,6 +215,25 @@
seahorse_pgp_subkey_set_length (base, subkey->length);
seahorse_pgp_subkey_set_description (base, description);
seahorse_pgp_subkey_set_fingerprint (base, fingerprint);
+ seahorse_pgp_subkey_set_created (base, subkey->timestamp);
+ seahorse_pgp_subkey_set_expires (base, subkey->expires);
+
+ /* The order below is significant */
+ flags = 0;
+ if (subkey->revoked)
+ flags |= SEAHORSE_FLAG_REVOKED;
+ if (subkey->expired)
+ flags |= SEAHORSE_FLAG_EXPIRED;
+ if (subkey->disabled)
+ flags |= SEAHORSE_FLAG_DISABLED;
+ if (flags == 0 && !subkey->invalid)
+ flags |= SEAHORSE_FLAG_IS_VALID;
+ if (subkey->can_encrypt)
+ flags |= SEAHORSE_FLAG_CAN_ENCRYPT;
+ if (subkey->can_sign)
+ flags |= SEAHORSE_FLAG_CAN_SIGN;
+
+ seahorse_pgp_subkey_set_flags (base, flags);
g_object_notify (obj, "subkey");
g_object_thaw_notify (obj);
Modified: trunk/pgp/seahorse-gpgme-uid.c
==============================================================================
--- trunk/pgp/seahorse-gpgme-uid.c (original)
+++ trunk/pgp/seahorse-gpgme-uid.c Tue Dec 16 22:33:53 2008
@@ -68,14 +68,21 @@
}
static void
-realize_signatures (SeahorseGpgmeUid *self, gpgme_user_id_t userid)
+realize_signatures (SeahorseGpgmeUid *self)
{
gpgme_key_sig_t gsig;
SeahorsePgpSignature *sig;
GList *sigs = NULL;
guint flags;
- for (gsig = userid->signatures; gsig; gsig = gsig->next) {
+ g_return_if_fail (self->pv->pubkey);
+ g_return_if_fail (self->pv->userid);
+
+ /* If this key was loaded without signatures, then leave them as is */
+ if ((self->pv->pubkey->keylist_mode & GPGME_KEYLIST_MODE_SIGS) == 0)
+ return;
+
+ for (gsig = self->pv->userid->signatures; gsig; gsig = gsig->next) {
sig = seahorse_pgp_signature_new (gsig->keyid);
/* Order of parsing these flags is important */
@@ -97,6 +104,27 @@
seahorse_object_list_free (sigs);
}
+static gboolean
+compare_strings (const gchar *a, const gchar *b)
+{
+ if (a == b)
+ return TRUE;
+ if (!a || !b)
+ return FALSE;
+ return g_str_equal (a, b);
+}
+
+static gboolean
+compare_pubkeys (gpgme_key_t a, gpgme_key_t b)
+{
+ g_assert (a);
+ g_assert (b);
+
+ g_return_val_if_fail (a->subkeys, FALSE);
+ g_return_val_if_fail (b->subkeys, FALSE);
+
+ return compare_strings (a->subkeys->keyid, b->subkeys->keyid);
+}
/* -----------------------------------------------------------------------------
* OBJECT
@@ -115,21 +143,10 @@
{
GObject *obj = G_OBJECT_CLASS (seahorse_gpgme_uid_parent_class)->constructor (type, n_props, props);
SeahorseGpgmeUid *self = NULL;
- SeahorseLocation loc;
if (obj) {
self = SEAHORSE_GPGME_UID (obj);
- g_return_val_if_fail (self->pv->pubkey, NULL);
-
- loc = seahorse_object_get_location (SEAHORSE_OBJECT (self));
- if (self->pv->pubkey->keylist_mode & GPGME_KEYLIST_MODE_EXTERN &&
- loc <= SEAHORSE_LOCATION_REMOTE)
- loc = SEAHORSE_LOCATION_REMOTE;
-
- else if (loc <= SEAHORSE_LOCATION_LOCAL)
- loc = SEAHORSE_LOCATION_LOCAL;
-
- g_object_set (self, "location", loc, NULL);
+ g_object_set (self, "location", SEAHORSE_LOCATION_LOCAL, NULL);
}
return obj;
@@ -162,13 +179,28 @@
GParamSpec *pspec)
{
SeahorseGpgmeUid *self = SEAHORSE_GPGME_UID (object);
-
+ gpgme_key_t pubkey;
+
switch (prop_id) {
case PROP_PUBKEY:
- g_return_if_fail (!self->pv->pubkey);
- self->pv->pubkey = g_value_get_boxed (value);
- if (self->pv->pubkey)
- gpgme_key_ref (self->pv->pubkey);
+ pubkey = g_value_get_boxed (value);
+ g_return_if_fail (pubkey);
+
+ if (pubkey != self->pv->pubkey) {
+
+ if (self->pv->pubkey) {
+ /* Should always be set to the same actual key */
+ g_return_if_fail (compare_pubkeys (pubkey, self->pv->pubkey));
+ gpgme_key_unref (self->pv->pubkey);
+ }
+
+ self->pv->pubkey = g_value_get_boxed (value);
+ if (self->pv->pubkey)
+ gpgme_key_ref (self->pv->pubkey);
+
+ /* This is expected to be set shortly along with pubkey */
+ self->pv->userid = NULL;
+ }
break;
case PROP_ACTUAL_INDEX:
seahorse_gpgme_uid_set_actual_index (self, g_value_get_uint (value));
@@ -208,7 +240,7 @@
g_object_class_install_property (gobject_class, PROP_PUBKEY,
g_param_spec_boxed ("pubkey", "Public Key", "GPGME Public Key that this uid is on",
- SEAHORSE_GPGME_BOXED_KEY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ SEAHORSE_GPGME_BOXED_KEY, G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_USERID,
g_param_spec_pointer ("userid", "User ID", "GPGME User ID",
@@ -263,6 +295,9 @@
g_return_if_fail (SEAHORSE_IS_GPGME_UID (self));
g_return_if_fail (userid);
+ if (self->pv->userid)
+ g_return_if_fail (seahorse_gpgme_uid_is_same (self, userid));
+
/* Make sure that this userid is in the pubkey */
index = -1;
for (i = 0, uid = self->pv->pubkey->uids; uid; ++i, uid = uid->next) {
@@ -296,7 +331,7 @@
seahorse_pgp_uid_set_comment (base, string);
g_free (string);
- realize_signatures (self, userid);
+ realize_signatures (self);
seahorse_pgp_uid_set_validity (base, seahorse_gpgme_convert_validity (userid->validity));
@@ -315,7 +350,7 @@
{
g_return_val_if_fail (SEAHORSE_IS_GPGME_UID (self), 0);
if(self->pv->actual_index < 0)
- return self->pv->gpgme_index;
+ return self->pv->gpgme_index + 1;
return self->pv->actual_index;
}
@@ -360,3 +395,12 @@
return ret;
}
+
+gboolean
+seahorse_gpgme_uid_is_same (SeahorseGpgmeUid *self, gpgme_user_id_t userid)
+{
+ g_return_val_if_fail (SEAHORSE_IS_GPGME_UID (self), FALSE);
+ g_return_val_if_fail (userid, FALSE);
+
+ return compare_strings (self->pv->userid->uid, userid->uid);
+}
Modified: trunk/pgp/seahorse-gpgme-uid.h
==============================================================================
--- trunk/pgp/seahorse-gpgme-uid.h (original)
+++ trunk/pgp/seahorse-gpgme-uid.h Tue Dec 16 22:33:53 2008
@@ -76,4 +76,7 @@
gchar* seahorse_gpgme_uid_calc_markup (gpgme_user_id_t userid,
guint flags);
+gboolean seahorse_gpgme_uid_is_same (SeahorseGpgmeUid *self,
+ gpgme_user_id_t userid);
+
#endif /* __SEAHORSE_GPGME_UID_H__ */
Modified: trunk/pgp/seahorse-hkp-source.c
==============================================================================
--- trunk/pgp/seahorse-hkp-source.c (original)
+++ trunk/pgp/seahorse-hkp-source.c Tue Dec 16 22:33:53 2008
@@ -399,10 +399,11 @@
gchar **v;
gchar *line, *t;
- SeahorsePgpKey *key;
+ SeahorsePgpKey *key = NULL;
GList *keys = NULL;
GList *subkeys = NULL;
GList *uids = NULL;
+ guint flags;
lines = g_strsplit (response, "\n", 0);
@@ -424,15 +425,12 @@
} else {
gchar *fingerprint, *fpr = NULL;
- gboolean revoked = FALSE;
const gchar *algo;
gboolean has_uid = TRUE;
SeahorsePgpSubkey *subkey;
-
- key = seahorse_pgp_key_new ();
- keys = g_list_prepend (keys, key);
- g_object_set (key, "location", SEAHORSE_LOCATION_REMOTE, NULL);
-
+
+ flags = SEAHORSE_FLAG_EXPORTABLE;
+
/* Cut the length and fingerprint */
fpr = strchr (v[0], '/');
if (fpr == NULL) {
@@ -462,18 +460,31 @@
g_strstrip (v[2]);
if (g_ascii_strcasecmp (v[2], "*** KEY REVOKED ***") == 0) {
- revoked = TRUE;
+ flags |= SEAHORSE_FLAG_REVOKED;
has_uid = FALSE;
}
-
+
+ if (key) {
+ seahorse_pgp_key_set_uids (SEAHORSE_PGP_KEY (key), uids);
+ seahorse_object_list_free (uids);
+ seahorse_pgp_key_set_subkeys (SEAHORSE_PGP_KEY (key), subkeys);
+ seahorse_object_list_free (subkeys);
+ uids = subkeys = NULL;
+ key = NULL;
+ }
+
+ key = seahorse_pgp_key_new ();
+ keys = g_list_prepend (keys, key);
+ g_object_set (key, "location", SEAHORSE_LOCATION_REMOTE, "flags",
+ flags, NULL);
+
/* Add all the info to the key */
subkey = seahorse_pgp_subkey_new ();
seahorse_pgp_subkey_set_keyid (subkey, fpr);
fingerprint = seahorse_pgp_subkey_calc_fingerprint (fpr);
seahorse_pgp_subkey_set_fingerprint (subkey, fingerprint);
g_free (fingerprint);
- if(revoked)
- seahorse_pgp_subkey_set_validity (subkey, SEAHORSE_VALIDITY_REVOKED);
+ seahorse_pgp_subkey_set_flags (subkey, flags);
seahorse_pgp_subkey_set_created (subkey, parse_hkp_date (v[1]));
seahorse_pgp_subkey_set_length (subkey, strtol (v[0], NULL, 10));
seahorse_pgp_subkey_set_algorithm (subkey, algo);
@@ -502,19 +513,18 @@
/* TODO: Implement signatures */
- /* Other junk */
- } else if (key) {
-
- seahorse_pgp_key_set_uids (SEAHORSE_PGP_KEY (key), uids);
- seahorse_object_list_free (uids);
- seahorse_pgp_key_set_subkeys (SEAHORSE_PGP_KEY (key), subkeys);
- seahorse_object_list_free (subkeys);
- uids = subkeys = NULL;
- }
+ }
}
g_strfreev (lines);
-
+
+ if (key) {
+ seahorse_pgp_key_set_uids (SEAHORSE_PGP_KEY (key), uids);
+ seahorse_object_list_free (uids);
+ seahorse_pgp_key_set_subkeys (SEAHORSE_PGP_KEY (key), subkeys);
+ seahorse_object_list_free (subkeys);
+ }
+
return keys;
}
Modified: trunk/pgp/seahorse-ldap-source.c
==============================================================================
--- trunk/pgp/seahorse-ldap-source.c (original)
+++ trunk/pgp/seahorse-ldap-source.c Tue Dec 16 22:33:53 2008
@@ -802,6 +802,7 @@
SeahorsePgpKey *key;
SeahorsePgpUid *uid;
GList *list;
+ guint flags;
/* Build up a subkey */
subkey = seahorse_pgp_subkey_new ();
@@ -809,19 +810,22 @@
fingerprint = seahorse_pgp_subkey_calc_fingerprint (fpr);
seahorse_pgp_subkey_set_fingerprint (subkey, fingerprint);
g_free (fingerprint);
- if (revoked)
- seahorse_pgp_subkey_set_validity (subkey, SEAHORSE_VALIDITY_REVOKED);
- else if (disabled)
- seahorse_pgp_subkey_set_validity (subkey, SEAHORSE_VALIDITY_DISABLED);
seahorse_pgp_subkey_set_created (subkey, timestamp);
seahorse_pgp_subkey_set_expires (subkey, expires);
seahorse_pgp_subkey_set_algorithm (subkey, algo);
seahorse_pgp_subkey_set_length (subkey, length);
-
+
+ flags = SEAHORSE_FLAG_EXPORTABLE;
+ if (revoked)
+ flags |= SEAHORSE_FLAG_REVOKED;
+ if (disabled)
+ flags |= SEAHORSE_FLAG_DISABLED;
+ seahorse_pgp_subkey_set_flags (subkey, flags);
+
/* Build up a uid */
uid = seahorse_pgp_uid_new (uidstr);
if (revoked)
- seahorse_pgp_subkey_set_validity (subkey, SEAHORSE_VALIDITY_REVOKED);
+ seahorse_pgp_uid_set_validity (uid, SEAHORSE_VALIDITY_REVOKED);
/* Now build them into a key */
key = seahorse_pgp_key_new ();
@@ -831,7 +835,8 @@
list = g_list_prepend (NULL, subkey);
seahorse_pgp_key_set_subkeys (key, list);
seahorse_object_list_free (list);
- g_object_set (key, "location", SEAHORSE_LOCATION_REMOTE, NULL);
+ g_object_set (key, "location", SEAHORSE_LOCATION_REMOTE,
+ "flags", flags, NULL);
add_key (lop->lsrc, key);
g_object_unref (key);
Modified: trunk/pgp/seahorse-pgp-commands.c
==============================================================================
--- trunk/pgp/seahorse-pgp-commands.c (original)
+++ trunk/pgp/seahorse-pgp-commands.c Tue Dec 16 22:33:53 2008
@@ -102,8 +102,8 @@
for (l = keys; l; l = g_list_next (l)) {
SeahorseObject* key = SEAHORSE_OBJECT (l->data);
- if (G_OBJECT_TYPE (key) != SEAHORSE_TYPE_PGP_KEY &&
- G_OBJECT_TYPE (key) != SEAHORSE_TYPE_PGP_UID) {
+ if (G_OBJECT_TYPE (key) != SEAHORSE_TYPE_GPGME_KEY &&
+ G_OBJECT_TYPE (key) != SEAHORSE_TYPE_GPGME_UID) {
enable = FALSE;
break;
}
@@ -126,7 +126,6 @@
seahorse_pgp_commands_show_properties (SeahorseCommands* base, SeahorseObject* obj)
{
g_return_if_fail (SEAHORSE_IS_OBJECT (obj));
- g_return_if_fail (seahorse_object_get_tag (obj) == SEAHORSE_PGP_TYPE);
if (G_TYPE_FROM_INSTANCE (G_OBJECT (obj)) == SEAHORSE_TYPE_PGP_UID ||
G_TYPE_FROM_INSTANCE (G_OBJECT (obj)) == SEAHORSE_TYPE_GPGME_UID)
Modified: trunk/pgp/seahorse-pgp-key-properties.c
==============================================================================
--- trunk/pgp/seahorse-pgp-key-properties.c (original)
+++ trunk/pgp/seahorse-pgp-key-properties.c Tue Dec 16 22:33:53 2008
@@ -581,7 +581,7 @@
photo = g_object_get_data (G_OBJECT (swidget), "current-photoid");
g_return_if_fail (!photo || SEAHORSE_IS_PGP_PHOTO (photo));
- is_gpgme = (photo && SEAHORSE_IS_GPGME_PHOTO (photo));
+ is_gpgme = SEAHORSE_IS_GPGME_KEY (pkey);
/* Show when adding a photo is possible */
show_glade_widget (swidget, "owner-photo-add-button",
@@ -589,7 +589,7 @@
/* Show when we have a photo to set as primary */
show_glade_widget (swidget, "owner-photo-primary-button",
- is_gpgme && etype == SEAHORSE_USAGE_PRIVATE_KEY && photo);
+ is_gpgme && etype == SEAHORSE_USAGE_PRIVATE_KEY && photos && photos->next);
/* Display this when there are any photo ids */
show_glade_widget (swidget, "owner-photo-delete-button",
@@ -952,6 +952,21 @@
}
static void
+details_subkey_selected (GtkTreeSelection *selection, SeahorseWidget *swidget)
+{
+ SeahorsePgpSubkey* subkey;
+ guint flags = 0;
+
+ subkey = get_selected_subkey (swidget);
+ if (subkey)
+ flags = seahorse_pgp_subkey_get_flags (subkey);
+
+ sensitive_glade_widget (swidget, "details-date-button", subkey != NULL);
+ sensitive_glade_widget (swidget, "details-revoke-button", subkey != NULL && !(flags & SEAHORSE_FLAG_REVOKED));
+ sensitive_glade_widget (swidget, "details-delete-button", subkey != NULL);
+}
+
+static void
details_add_subkey_button_clicked (GtkButton *button, SeahorseWidget *swidget)
{
SeahorseObject *object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
@@ -1099,7 +1114,21 @@
}
static void
-details_calendar_button_clicked (GtkWidget *widget, SeahorseWidget *swidget)
+details_expires_button_clicked (GtkWidget *widget, SeahorseWidget *swidget)
+{
+ GList *subkeys;
+ SeahorsePgpKey *pkey;
+
+ pkey = SEAHORSE_PGP_KEY (SEAHORSE_OBJECT_WIDGET (swidget)->object);
+ subkeys = seahorse_pgp_key_get_subkeys (pkey);
+ g_return_if_fail (subkeys);
+
+ seahorse_gpgme_expires_new (SEAHORSE_GPGME_SUBKEY (subkeys->data),
+ GTK_WINDOW (glade_xml_get_widget (swidget->xml, swidget->name)));
+}
+
+static void
+details_expires_subkey_clicked (GtkWidget *widget, SeahorseWidget *swidget)
{
SeahorsePgpSubkey *subkey;
SeahorsePgpKey *pkey;
@@ -1190,6 +1219,7 @@
{
SeahorseObject *object;
SeahorseUsage etype;
+ GtkWidget *widget;
object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
etype = seahorse_object_get_usage (object);
@@ -1198,7 +1228,7 @@
* if not the key owner, disable most everything
* if key owner, add the callbacks to the subkey buttons
*/
- if (etype == SEAHORSE_USAGE_PUBLIC_KEY ) {
+ if (etype == SEAHORSE_USAGE_PUBLIC_KEY) {
show_glade_widget (swidget, "details-actions-label", FALSE);
show_glade_widget (swidget, "details-export-button", FALSE);
show_glade_widget (swidget, "details-add-button", FALSE);
@@ -1211,15 +1241,21 @@
glade_xml_signal_connect_data (swidget->xml, "on_details_add_button_clicked",
G_CALLBACK (details_add_subkey_button_clicked), swidget);
glade_xml_signal_connect_data (swidget->xml, "on_details_calendar1_button_clicked",
- G_CALLBACK (details_calendar_button_clicked), swidget);
+ G_CALLBACK (details_expires_button_clicked), swidget);
glade_xml_signal_connect_data (swidget->xml, "on_details_calendar2_button_clicked",
- G_CALLBACK (details_calendar_button_clicked), swidget);
+ G_CALLBACK (details_expires_subkey_clicked), swidget);
glade_xml_signal_connect_data (swidget->xml, "on_details_revoke_button_clicked",
G_CALLBACK (details_revoke_subkey_button_clicked), swidget);
glade_xml_signal_connect_data (swidget->xml, "on_details_delete_button_clicked",
G_CALLBACK (details_del_subkey_button_clicked), swidget);
glade_xml_signal_connect_data (swidget->xml, "on_details_export_button_clicked",
G_CALLBACK (details_export_button_clicked), swidget);
+
+ /* Connect so we can enable and disable buttons as subkeys are selected */
+ widget = glade_xml_get_widget (swidget->xml, "details-subkey-tree");
+ g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)),
+ "changed", G_CALLBACK (details_subkey_selected), swidget);
+ details_subkey_selected (NULL, swidget);
}
glade_xml_signal_connect_data (swidget->xml, "on_details_trust_changed",
G_CALLBACK (trust_changed), swidget);
@@ -1254,7 +1290,7 @@
widget = glade_xml_get_widget (swidget->xml, "details-id-label");
if (widget) {
- label = seahorse_object_get_label (object);
+ label = seahorse_object_get_identifier (object);
gtk_label_set_text (GTK_LABEL (widget), label);
}
@@ -1314,7 +1350,9 @@
-1);
if (trust == seahorse_pgp_key_get_trust (pkey)) {
+ g_signal_handlers_block_by_func (widget, trust_changed, swidget);
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (widget), &iter);
+ g_signal_handlers_unblock_by_func (widget, trust_changed, swidget);
break;
}
@@ -1333,6 +1371,7 @@
/* This is our first time so create a store */
store = gtk_list_store_newv (SUBKEY_N_COLUMNS, (GType*)subkey_columns);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (widget), GTK_TREE_MODEL (store));
/* Make the columns for the view */
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget),
@@ -1361,21 +1400,20 @@
gchar *expiration_date;
gchar *created_date;
gulong expires;
+ guint flags;
subkey = SEAHORSE_PGP_SUBKEY (l->data);
expires = seahorse_pgp_subkey_get_expires (subkey);
- status = NULL;
+ flags = seahorse_pgp_subkey_get_flags (subkey);
+ status = "";
- if (seahorse_pgp_subkey_get_validity (subkey) == SEAHORSE_VALIDITY_REVOKED) {
+ if (flags & SEAHORSE_FLAG_REVOKED)
status = _("Revoked");
- } else if (expires) {
- GTimeVal timev;
- g_get_current_time(&timev);
- if (expires < timev.tv_sec)
- status = _("Expired");
- }
-
- if (status == NULL)
+ else if (flags & SEAHORSE_FLAG_EXPIRED)
+ status = _("Expired");
+ else if (flags & SEAHORSE_FLAG_DISABLED)
+ status = _("Disabled");
+ else if (flags & SEAHORSE_FLAG_IS_VALID)
status = _("Good");
if (expires == 0)
Modified: trunk/pgp/seahorse-pgp-key.c
==============================================================================
--- trunk/pgp/seahorse-pgp-key.c (original)
+++ trunk/pgp/seahorse-pgp-key.c Tue Dec 16 22:33:53 2008
@@ -202,7 +202,6 @@
g_object_set (obj, "usage", SEAHORSE_USAGE_PUBLIC_KEY, NULL);
}
-
g_object_set (obj,
"label", name,
"markup", markup,
@@ -404,14 +403,15 @@
GQuark
seahorse_pgp_key_calc_cannonical_id (const gchar *id)
{
- guint len = strlen (id);
+ guint len;
GQuark keyid;
gchar *t;
+
+ g_return_val_if_fail (id, 0);
+ len = strlen (id);
- if (len < 16) {
- g_warning ("invalid keyid (less than 16 chars): %s", id);
- return 0;
- }
+ if (len < 16)
+ g_message ("invalid keyid (less than 16 chars): %s", id);
if (len > 16)
id += len - 16;
Modified: trunk/pgp/seahorse-pgp-private-key-properties.glade
==============================================================================
--- trunk/pgp/seahorse-pgp-private-key-properties.glade (original)
+++ trunk/pgp/seahorse-pgp-private-key-properties.glade Tue Dec 16 22:33:53 2008
@@ -2490,7 +2490,7 @@
<widget class="GtkExpander" id="subkey-expander">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="expanded">False</property>
+ <property name="expanded">True</property>
<property name="spacing">0</property>
<signal name="activate" handler="on_subkey_expander_activate" last_modification_time="Fri, 07 Oct 2005 22:34:39 GMT"/>
Modified: trunk/pgp/seahorse-pgp-public-key-properties.glade
==============================================================================
--- trunk/pgp/seahorse-pgp-public-key-properties.glade (original)
+++ trunk/pgp/seahorse-pgp-public-key-properties.glade Tue Dec 16 22:33:53 2008
@@ -1211,71 +1211,85 @@
</child>
<child>
- <widget class="GtkButton" id="sign-button">
+ <widget class="GtkAlignment" id="alignment45">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="trust_sign_clicked" last_modification_time="Thu, 13 Oct 2005 16:53:04 GMT"/>
+ <property name="xalign">1</property>
+ <property name="yalign">0</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">0</property>
+ <property name="right_padding">0</property>
<child>
- <widget class="GtkAlignment" id="alignment22">
+ <widget class="GtkButton" id="sign-button">
<property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">0</property>
- <property name="right_padding">0</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="trust_sign_clicked" last_modification_time="Thu, 13 Oct 2005 16:53:04 GMT"/>
<child>
- <widget class="GtkHBox" id="hbox49">
+ <widget class="GtkAlignment" id="alignment22">
<property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">0</property>
+ <property name="right_padding">0</property>
<child>
- <widget class="GtkImage" id="image30">
+ <widget class="GtkHBox" id="hbox49">
<property name="visible">True</property>
- <property name="stock">gtk-index</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
+ <property name="homogeneous">False</property>
+ <property name="spacing">2</property>
- <child>
- <widget class="GtkLabel" id="label101">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Sign this Key</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
+ <child>
+ <widget class="GtkImage" id="image30">
+ <property name="visible">True</property>
+ <property name="stock">gtk-index</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label101">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Sign this Key</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
</widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
</child>
</widget>
</child>
@@ -1329,72 +1343,86 @@
</child>
<child>
- <widget class="GtkButton" id="revoke-button">
+ <widget class="GtkAlignment" id="alignment44">
<property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="trust_revoked_click" last_modification_time="Sun, 26 Mar 2006 22:29:13 GMT"/>
+ <property name="xalign">1</property>
+ <property name="yalign">0</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">0</property>
+ <property name="right_padding">0</property>
<child>
- <widget class="GtkAlignment" id="alignment25">
+ <widget class="GtkButton" id="revoke-button">
<property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">0</property>
- <property name="right_padding">0</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="trust_revoked_click" last_modification_time="Sun, 26 Mar 2006 22:29:13 GMT"/>
<child>
- <widget class="GtkHBox" id="hbox51">
+ <widget class="GtkAlignment" id="alignment25">
<property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">0</property>
+ <property name="right_padding">0</property>
<child>
- <widget class="GtkImage" id="image32">
+ <widget class="GtkHBox" id="hbox51">
<property name="visible">True</property>
- <property name="stock">gtk-remove</property>
- <property name="icon_size">4</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
+ <property name="homogeneous">False</property>
+ <property name="spacing">2</property>
- <child>
- <widget class="GtkLabel" id="label104">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Revoke Signature</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
+ <child>
+ <widget class="GtkImage" id="image32">
+ <property name="visible">True</property>
+ <property name="stock">gtk-remove</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label104">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Revoke Signature</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
</widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
</child>
</widget>
</child>
Modified: trunk/pgp/seahorse-pgp-signature.c
==============================================================================
--- trunk/pgp/seahorse-pgp-signature.c (original)
+++ trunk/pgp/seahorse-pgp-signature.c Tue Dec 16 22:33:53 2008
@@ -108,7 +108,8 @@
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
seahorse_pgp_signature_parent_class = g_type_class_peek_parent (klass);
-
+ g_type_class_add_private (klass, sizeof (SeahorsePgpSignaturePrivate));
+
gobject_class->finalize = seahorse_pgp_signature_finalize;
gobject_class->set_property = seahorse_pgp_signature_set_property;
gobject_class->get_property = seahorse_pgp_signature_get_property;
Modified: trunk/pgp/seahorse-pgp-subkey.c
==============================================================================
--- trunk/pgp/seahorse-pgp-subkey.c (original)
+++ trunk/pgp/seahorse-pgp-subkey.c Tue Dec 16 22:33:53 2008
@@ -34,7 +34,7 @@
PROP_0,
PROP_INDEX,
PROP_KEYID,
- PROP_VALIDITY,
+ PROP_FLAGS,
PROP_LENGTH,
PROP_ALGORITHM,
PROP_CREATED,
@@ -48,7 +48,7 @@
struct _SeahorsePgpSubkeyPrivate {
guint index;
gchar *keyid;
- SeahorseValidity validity;
+ guint flags;
guint length;
gchar *algorithm;
gulong created;
@@ -80,8 +80,8 @@
case PROP_KEYID:
g_value_set_string (value, seahorse_pgp_subkey_get_keyid (self));
break;
- case PROP_VALIDITY:
- g_value_set_uint (value, seahorse_pgp_subkey_get_validity (self));
+ case PROP_FLAGS:
+ g_value_set_uint (value, seahorse_pgp_subkey_get_flags (self));
break;
case PROP_LENGTH:
g_value_set_uint (value, seahorse_pgp_subkey_get_length (self));
@@ -117,8 +117,8 @@
case PROP_KEYID:
seahorse_pgp_subkey_set_keyid (self, g_value_get_string (value));
break;
- case PROP_VALIDITY:
- seahorse_pgp_subkey_set_validity (self, g_value_get_uint (value));
+ case PROP_FLAGS:
+ seahorse_pgp_subkey_set_flags (self, g_value_get_uint (value));
break;
case PROP_LENGTH:
seahorse_pgp_subkey_set_length (self, g_value_get_uint (value));
@@ -181,8 +181,8 @@
g_param_spec_string ("keyid", "Key ID", "GPG Key ID",
"", G_PARAM_READWRITE));
- g_object_class_install_property (gobject_class, PROP_VALIDITY,
- g_param_spec_uint ("validity", "Validity", "PGP subkey validity",
+ g_object_class_install_property (gobject_class, PROP_FLAGS,
+ g_param_spec_uint ("flags", "Flags", "PGP subkey flags",
0, G_MAXUINT, 0, G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_LENGTH,
@@ -251,19 +251,19 @@
g_object_notify (G_OBJECT (self), "keyid");
}
-SeahorseValidity
-seahorse_pgp_subkey_get_validity (SeahorsePgpSubkey *self)
+guint
+seahorse_pgp_subkey_get_flags (SeahorsePgpSubkey *self)
{
g_return_val_if_fail (SEAHORSE_IS_PGP_SUBKEY (self), 0);
- return self->pv->validity;
+ return self->pv->flags;
}
void
-seahorse_pgp_subkey_set_validity (SeahorsePgpSubkey *self, SeahorseValidity validity)
+seahorse_pgp_subkey_set_flags (SeahorsePgpSubkey *self, guint flags)
{
g_return_if_fail (SEAHORSE_IS_PGP_SUBKEY (self));
- self->pv->validity = validity;
- g_object_notify (G_OBJECT (self), "validity");
+ self->pv->flags = flags;
+ g_object_notify (G_OBJECT (self), "flags");
}
guint
Modified: trunk/pgp/seahorse-pgp-subkey.h
==============================================================================
--- trunk/pgp/seahorse-pgp-subkey.h (original)
+++ trunk/pgp/seahorse-pgp-subkey.h Tue Dec 16 22:33:53 2008
@@ -26,8 +26,6 @@
#include "seahorse-object.h"
-#include "seahorse-validity.h"
-
#define SEAHORSE_TYPE_PGP_SUBKEY (seahorse_pgp_subkey_get_type ())
#define SEAHORSE_PGP_SUBKEY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_PGP_SUBKEY, SeahorsePgpSubkey))
@@ -63,10 +61,10 @@
void seahorse_pgp_subkey_set_keyid (SeahorsePgpSubkey *self,
const gchar *keyid);
-SeahorseValidity seahorse_pgp_subkey_get_validity (SeahorsePgpSubkey *self);
+guint seahorse_pgp_subkey_get_flags (SeahorsePgpSubkey *self);
-void seahorse_pgp_subkey_set_validity (SeahorsePgpSubkey *self,
- SeahorseValidity validity);
+void seahorse_pgp_subkey_set_flags (SeahorsePgpSubkey *self,
+ guint flags);
const gchar* seahorse_pgp_subkey_get_algorithm (SeahorsePgpSubkey *self);
Modified: trunk/pgp/seahorse-pgp-uid.c
==============================================================================
--- trunk/pgp/seahorse-pgp-uid.c (original)
+++ trunk/pgp/seahorse-pgp-uid.c Tue Dec 16 22:33:53 2008
@@ -57,6 +57,19 @@
* INTERNAL HELPERS
*/
+static gchar*
+convert_string (const gchar *str)
+{
+ if (!str)
+ return NULL;
+
+ /* If not utf8 valid, assume latin 1 */
+ if (!g_utf8_validate (str, -1, NULL))
+ return g_convert (str, -1, "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
+
+ return g_strdup (str);
+}
+
#ifndef HAVE_STRSEP
/* code taken from glibc-2.2.1/sysdeps/generic/strsep.c */
char *
@@ -190,15 +203,17 @@
SeahorsePgpUid *self = SEAHORSE_PGP_UID (obj);
gchar *markup;
+ /* Don't realize if no name present */
+ if (!self->pv->name)
+ return;
+
self->pv->realized = TRUE;
SEAHORSE_OBJECT_CLASS (seahorse_pgp_uid_parent_class)->realize (obj);
- if (self->pv->name) {
- g_object_set (self, "label", self->pv->name ? self->pv->name : "", NULL);
- markup = seahorse_pgp_uid_calc_markup (self->pv->name, self->pv->email, self->pv->comment, 0);
- g_object_set (self, "markup", markup, NULL);
- g_free (markup);
- }
+ g_object_set (self, "label", self->pv->name ? self->pv->name : "", NULL);
+ markup = seahorse_pgp_uid_calc_markup (self->pv->name, self->pv->email, self->pv->comment, 0);
+ g_object_set (self, "markup", markup, NULL);
+ g_free (markup);
}
static void
@@ -401,7 +416,7 @@
g_return_if_fail (SEAHORSE_IS_PGP_UID (self));
g_free (self->pv->name);
- self->pv->name = g_strdup (name);
+ self->pv->name = convert_string (name);
obj = G_OBJECT (self);
g_object_freeze_notify (obj);
@@ -428,7 +443,7 @@
g_return_if_fail (SEAHORSE_IS_PGP_UID (self));
g_free (self->pv->email);
- self->pv->email = g_strdup (email);
+ self->pv->email = convert_string (email);
obj = G_OBJECT (self);
g_object_freeze_notify (obj);
@@ -455,7 +470,7 @@
g_return_if_fail (SEAHORSE_IS_PGP_UID (self));
g_free (self->pv->comment);
- self->pv->comment = g_strdup (comment);
+ self->pv->comment = convert_string (comment);
obj = G_OBJECT (self);
g_object_freeze_notify (obj);
Modified: trunk/src/seahorse-keyserver-results.c
==============================================================================
--- trunk/src/seahorse-keyserver-results.c (original)
+++ trunk/src/seahorse-keyserver-results.c Tue Dec 16 22:33:53 2008
@@ -176,7 +176,7 @@
}
static void
-on_key_import_keyring (SeahorseKeyserverResults* self, GtkAction* action)
+on_key_import_keyring (GtkAction* action, SeahorseKeyserverResults* self)
{
GList* keys;
SeahorseOperation* op;
Modified: trunk/src/seahorse-keyserver-results.ui
==============================================================================
--- trunk/src/seahorse-keyserver-results.ui (original)
+++ trunk/src/seahorse-keyserver-results.ui Tue Dec 16 22:33:53 2008
@@ -4,8 +4,6 @@
<menuitem action="key-import-keyring"/>
<menuitem action="file-export"/>
<separator/>
- <menuitem action="remote-find"/>
- <separator/>
<placeholder name="FileCommands">
<menuitem action="show-properties"/>
</placeholder>
@@ -15,6 +13,9 @@
<menu name="Edit" action="edit-menu">
<menuitem action="edit-export-clipboard"/>
</menu>
+ <menu name="Remote" action="remote-menu">
+ <menuitem action="remote-find"/>
+ </menu>
<menu name="Help" action="help-menu">
<menuitem action="help-show"/>
<!-- <menuitem action="app-about"/> -->
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]