[seahorse] Try to make as many password dialogs transient as possible



commit 60613d6b70497bc6b7a41d6f0516de7550a540d3
Author: Stef Walter <stefw gnome org>
Date:   Tue Oct 15 18:06:05 2013 +0200

    Try to make as many password dialogs transient as possible
    
    Otherwise these become haphazard prompts that appear somewhere on
    the screen and could go to the background.

 pgp/seahorse-gpgme-dialogs.h      |    3 ++-
 pgp/seahorse-gpgme-generate.c     |    8 +++++---
 ssh/seahorse-ssh-askpass.c        |   29 ++++++++++++++++++++++++++++-
 ssh/seahorse-ssh-generate.c       |    3 ++-
 ssh/seahorse-ssh-key-properties.c |   12 +++++++++---
 ssh/seahorse-ssh-operation.c      |   35 +++++++++++++++++++++++++++++++----
 ssh/seahorse-ssh-operation.h      |    7 +++++++
 ssh/seahorse-ssh-source.c         |   12 ++++++++----
 ssh/seahorse-ssh-source.h         |    1 +
 ssh/seahorse-ssh-upload.c         |    2 +-
 10 files changed, 94 insertions(+), 18 deletions(-)
---
diff --git a/pgp/seahorse-gpgme-dialogs.h b/pgp/seahorse-gpgme-dialogs.h
index 4cfe64a..773d36e 100644
--- a/pgp/seahorse-gpgme-dialogs.h
+++ b/pgp/seahorse-gpgme-dialogs.h
@@ -56,7 +56,8 @@ void            seahorse_gpgme_generate_key         (SeahorseGpgmeKeyring *keyri
                                                      const gchar *comment,
                                                      guint type,
                                                      guint bits,
-                                                     time_t expires);
+                                                     time_t expires,
+                                                     GtkWindow *parent);
 
 void            seahorse_gpgme_add_revoker_new      (SeahorseGpgmeKey *pkey,
                                                      GtkWindow *parent);
diff --git a/pgp/seahorse-gpgme-generate.c b/pgp/seahorse-gpgme-generate.c
index 1595da4..e4e7073 100644
--- a/pgp/seahorse-gpgme-generate.c
+++ b/pgp/seahorse-gpgme-generate.c
@@ -202,7 +202,8 @@ seahorse_gpgme_generate_key (SeahorseGpgmeKeyring *keyring,
                              const gchar *comment,
                              guint type,
                              guint bits,
-                             time_t expires)
+                             time_t expires,
+                             GtkWindow *parent)
 {
        GCancellable *cancellable;
        const gchar *pass;
@@ -212,6 +213,7 @@ seahorse_gpgme_generate_key (SeahorseGpgmeKeyring *keyring,
        dialog = seahorse_passphrase_prompt_show (_("Passphrase for New PGP Key"),
                                                  _("Enter the passphrase for your new key twice."),
                                                  NULL, NULL, TRUE);
+       gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
        if (gtk_dialog_run (dialog) == GTK_RESPONSE_ACCEPT) {
                pass = seahorse_passphrase_prompt_get (dialog);
                cancellable = g_cancellable_new ();
@@ -324,8 +326,8 @@ on_gpgme_generate_response (GtkDialog *dialog,
     /* Less confusing with less on the screen */
     gtk_widget_hide (seahorse_widget_get_toplevel (swidget));
 
-    seahorse_gpgme_generate_key (keyring, name, email, comment, type, bits, expires);
-
+    seahorse_gpgme_generate_key (keyring, name, email, comment, type, bits, expires,
+                                 gtk_window_get_transient_for (GTK_WINDOW (dialog)));
 
     seahorse_widget_destroy (swidget);
     g_free (name);
diff --git a/ssh/seahorse-ssh-askpass.c b/ssh/seahorse-ssh-askpass.c
index bfea5fb..9828b67 100644
--- a/ssh/seahorse-ssh-askpass.c
+++ b/ssh/seahorse-ssh-askpass.c
@@ -27,15 +27,21 @@
 #include "seahorse-passphrase.h"
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+
 int
 main (int argc, char* argv[])
 {
+       GdkWindow *transient_for = NULL;
        GtkDialog *dialog;
        const gchar *title;
        const gchar *argument;
@@ -43,6 +49,7 @@ main (int argc, char* argv[])
        const gchar *flags;
        gint result;
        const gchar *pass;
+       gulong xid;
        gssize len;
 
        bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
@@ -54,7 +61,20 @@ main (int argc, char* argv[])
        /* Non buffered stdout */
        setvbuf (stdout, 0, _IONBF, 0);
 
-       /* TODO: Change lousy default, rarely used, and string freeze right now */
+#ifdef GDK_WINDOWING_X11
+       argument = g_getenv ("SEAHORSE_SSH_ASKPASS_PARENT");
+       if (argument) {
+               GdkDisplay *display = gdk_display_get_default ();
+               if (GDK_IS_X11_DISPLAY (display)) {
+                       xid = strtoul (argument, NULL, 10);
+                       if (xid != 0)
+                               transient_for = gdk_x11_window_foreign_new_for_display (display, xid);
+                       if (transient_for == NULL)
+                               g_warning ("Couldn't find window to be transient for: %s", argument);
+               }
+       }
+#endif
+
        title = g_getenv ("SEAHORSE_SSH_ASKPASS_TITLE");
        if (!title || !title[0])
                title = _("Enter your Secure Shell passphrase:");
@@ -101,6 +121,11 @@ main (int argc, char* argv[])
 
        g_free (message);
 
+       if (transient_for) {
+               gdk_window_set_transient_for (gtk_widget_get_window (GTK_WIDGET (dialog)),
+                                             transient_for);
+       }
+
        result = 1;
        if (gtk_dialog_run (dialog) == GTK_RESPONSE_ACCEPT) {
                pass = seahorse_passphrase_prompt_get (dialog);
@@ -113,6 +138,8 @@ main (int argc, char* argv[])
                }
        }
 
+       if (transient_for)
+               g_object_unref (transient_for);
        gtk_widget_destroy (GTK_WIDGET (dialog));
        return result;
 }
diff --git a/ssh/seahorse-ssh-generate.c b/ssh/seahorse-ssh-generate.c
index 4d917fc..cd170fa 100644
--- a/ssh/seahorse-ssh-generate.c
+++ b/ssh/seahorse-ssh-generate.c
@@ -184,7 +184,8 @@ on_response (GtkDialog *dialog, gint response, SeahorseWidget *swidget)
 
     /* We start creation */
     cancellable = g_cancellable_new ();
-    seahorse_ssh_op_generate_async (src, email, type, bits, cancellable,
+    seahorse_ssh_op_generate_async (src, email, type, bits,
+                                    gtk_window_get_transient_for (GTK_WINDOW (dialog)), cancellable,
                                     upload ? on_generate_complete_and_upload : on_generate_complete,
                                     NULL);
     seahorse_progress_show (cancellable, _("Creating Secure Shell Key"), FALSE);
diff --git a/ssh/seahorse-ssh-key-properties.c b/ssh/seahorse-ssh-key-properties.c
index 329cd57..fade71e 100644
--- a/ssh/seahorse-ssh-key-properties.c
+++ b/ssh/seahorse-ssh-key-properties.c
@@ -93,6 +93,7 @@ on_ssh_comment_activate (GtkWidget *entry,
        SeahorseSSHSource *source;
        const gchar *text;
        ssh_rename_closure *closure;
+       GtkWidget *window;
 
        skey = SEAHORSE_SSH_KEY (SEAHORSE_OBJECT_WIDGET (swidget)->object);
        source = SEAHORSE_SSH_SOURCE (seahorse_object_get_place (SEAHORSE_OBJECT (skey)));
@@ -104,12 +105,13 @@ on_ssh_comment_activate (GtkWidget *entry,
                return;
 
        gtk_widget_set_sensitive (entry, FALSE);
+       window = gtk_widget_get_toplevel (entry);
 
        closure = g_new0 (ssh_rename_closure, 1);
        closure->swidget = g_object_ref (swidget);
        closure->entry = GTK_ENTRY (entry);
        closure->original = g_strdup (skey->keydata->comment ? skey->keydata->comment : "");
-       seahorse_ssh_op_rename_async (source, skey, text,
+       seahorse_ssh_op_rename_async (source, skey, text, GTK_WINDOW (window),
                                      NULL, on_rename_complete, closure);
 }
 
@@ -144,14 +146,16 @@ on_ssh_trust_toggled (GtkToggleButton *button,
        SeahorseSSHSource *source;
        SeahorseSSHKey *skey;
        gboolean authorize;
+       GtkWidget *window;
 
        skey = SEAHORSE_SSH_KEY (SEAHORSE_OBJECT_WIDGET (swidget)->object);
        source = SEAHORSE_SSH_SOURCE (seahorse_object_get_place (SEAHORSE_OBJECT (skey)));
 
        authorize = gtk_toggle_button_get_active (button);
        gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE);
+       window = gtk_widget_get_toplevel (GTK_WIDGET (button));
 
-       seahorse_ssh_op_authorize_async (source, skey, authorize,
+       seahorse_ssh_op_authorize_async (source, skey, authorize, GTK_WINDOW (window),
                                         NULL, on_authorize_complete, g_object_ref (button));
 }
 
@@ -178,13 +182,15 @@ on_ssh_passphrase_button_clicked (GtkWidget *widget,
 {
        GObject *object;
        GtkWidget *button;
+       GtkWidget *window;
 
        object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
 
        button = seahorse_widget_get_widget (swidget, "passphrase-button");
        gtk_widget_set_sensitive (button, FALSE);
+       window = gtk_widget_get_toplevel (widget);
 
-       seahorse_ssh_op_change_passphrase_async (SEAHORSE_SSH_KEY (object), NULL,
+       seahorse_ssh_op_change_passphrase_async (SEAHORSE_SSH_KEY (object), GTK_WINDOW (window), NULL,
                                                 on_passphrase_complete, g_object_ref (button));
 }
 
diff --git a/ssh/seahorse-ssh-operation.c b/ssh/seahorse-ssh-operation.c
index 5bc6dce..de15673 100644
--- a/ssh/seahorse-ssh-operation.c
+++ b/ssh/seahorse-ssh-operation.c
@@ -40,6 +40,10 @@
 #include <glib/gi18n.h>
 #include <glib/gstdio.h>
 
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+
 #define COMMAND_PASSWORD "PASSWORD "
 #define COMMAND_PASSWORD_LEN   9
 
@@ -48,6 +52,7 @@ typedef struct {
        const gchar *message;
        const gchar *argument;
        const gchar *flags;
+       gulong transient_for;
 } SeahorseSshPromptInfo;
 
 typedef struct {
@@ -335,6 +340,7 @@ static void
 on_spawn_setup_child (gpointer user_data)
 {
        SeahorseSshPromptInfo *prompt = user_data;
+       gchar *parent;
 
        /* No terminal for this process */
        setsid ();
@@ -347,6 +353,11 @@ on_spawn_setup_child (gpointer user_data)
        g_setenv ("LANG", "C", TRUE);
 
        if (prompt != NULL) {
+               if (prompt->transient_for) {
+                       parent = g_strdup_printf ("%lu", prompt->transient_for);
+                       g_setenv ("SEAHORSE_SSH_ASKPASS_PARENT", parent, TRUE);
+                       g_free (parent);
+               }
                if (prompt->title)
                        g_setenv ("SEAHORSE_SSH_ASKPASS_TITLE", prompt->title, TRUE);
                if (prompt->message)
@@ -361,6 +372,7 @@ seahorse_ssh_operation_async (SeahorseSSHSource *source,
                               const gchar *command,
                               const gchar *input,
                               gssize length,
+                              GtkWindow *parent,
                               GCancellable *cancellable,
                               GAsyncReadyCallback callback,
                               SeahorseSshPromptInfo *prompt,
@@ -381,6 +393,14 @@ seahorse_ssh_operation_async (SeahorseSSHSource *source,
                g_return_if_reached ();
        }
 
+#ifdef GDK_WINDOWING_X11
+       if (parent) {
+               GdkWindow *window = gtk_widget_get_window (GTK_WIDGET (parent));
+               if (window != NULL)
+                       prompt->transient_for = gdk_x11_window_get_xid (window);
+       }
+#endif
+
        res = g_simple_async_result_new (G_OBJECT (source), callback, user_data,
                                         seahorse_ssh_operation_async);
        closure = g_new0 (ssh_operation_closure, 1);
@@ -495,6 +515,7 @@ seahorse_ssh_op_upload_async (SeahorseSSHSource *source,
                               const gchar *username,
                               const gchar *hostname,
                               const gchar *port,
+                              GtkWindow *transient_for,
                               GCancellable *cancellable,
                               GAsyncReadyCallback callback,
                               gpointer user_data)
@@ -535,7 +556,7 @@ seahorse_ssh_op_upload_async (SeahorseSSHSource *source,
                               username, hostname, port ? "-p" : "", port ? port : "");
 
        seahorse_ssh_operation_async (SEAHORSE_SSH_SOURCE (source), cmd, data->str, data->len,
-                                     cancellable, on_upload_send_complete,
+                                     transient_for, cancellable, on_upload_send_complete,
                                      &prompt, g_object_ref (res));
 
        g_string_free (data, TRUE);
@@ -581,6 +602,7 @@ on_change_passphrase_complete (GObject *source,
 
 void
 seahorse_ssh_op_change_passphrase_async  (SeahorseSSHKey *key,
+                                          GtkWindow *transient_for,
                                           GCancellable *cancellable,
                                           GAsyncReadyCallback callback,
                                           gpointer user_data)
@@ -603,7 +625,7 @@ seahorse_ssh_op_change_passphrase_async  (SeahorseSSHKey *key,
        g_simple_async_result_set_op_res_gpointer (res, g_object_ref (key), g_object_unref);
 
        cmd = g_strdup_printf (SSH_KEYGEN_PATH " -p -f '%s'", key->keydata->privfile);
-       seahorse_ssh_operation_async (SEAHORSE_SSH_SOURCE (place), cmd, NULL, 0, cancellable,
+       seahorse_ssh_operation_async (SEAHORSE_SSH_SOURCE (place), cmd, NULL, 0, transient_for, cancellable,
                                      on_change_passphrase_complete, &prompt, g_object_ref (res));
 
        g_free (cmd);
@@ -671,6 +693,7 @@ seahorse_ssh_op_generate_async (SeahorseSSHSource *source,
                                 const gchar *email,
                                 guint type,
                                 guint bits,
+                                GtkWindow *transient_for,
                                 GCancellable *cancellable,
                                 GAsyncReadyCallback callback,
                                 gpointer user_data)
@@ -701,7 +724,7 @@ seahorse_ssh_op_generate_async (SeahorseSSHSource *source,
                               bits, algo, comment, closure->filename);
        g_free (comment);
 
-       seahorse_ssh_operation_async (source, cmd, NULL, 0, cancellable,
+       seahorse_ssh_operation_async (source, cmd, NULL, 0, transient_for, cancellable,
                                      on_generate_complete, &prompt, g_object_ref (res));
 
        g_free (cmd);
@@ -733,6 +756,7 @@ void
 seahorse_ssh_op_import_public_async (SeahorseSSHSource *source,
                                      SeahorseSSHKeyData *data,
                                      const gchar* filename,
+                                     GtkWindow *transient_for,
                                      GCancellable *cancellable,
                                      GAsyncReadyCallback callback,
                                      gpointer user_data)
@@ -837,6 +861,7 @@ void
 seahorse_ssh_op_import_private_async (SeahorseSSHSource *source,
                                       SeahorseSSHSecData *data,
                                       const gchar *filename,
+                                      GtkWindow *transient_for,
                                       GCancellable *cancellable,
                                       GAsyncReadyCallback callback,
                                       gpointer user_data)
@@ -882,7 +907,7 @@ seahorse_ssh_op_import_private_async (SeahorseSSHSource *source,
 
        /* Start command to generate public key */
        cmd = g_strdup_printf (SSH_KEYGEN_PATH " -y -f '%s'", privfile);
-       seahorse_ssh_operation_async (source, cmd, NULL, 0, cancellable,
+       seahorse_ssh_operation_async (source, cmd, NULL, 0, transient_for, cancellable,
                                      on_import_private_complete, &prompt,
                                      g_object_ref (res));
 
@@ -923,6 +948,7 @@ void
 seahorse_ssh_op_authorize_async (SeahorseSSHSource *source,
                                  SeahorseSSHKey *key,
                                  gboolean authorize,
+                                 GtkWindow *transient_for,
                                  GCancellable *cancellable,
                                  GAsyncReadyCallback callback,
                                  gpointer user_data)
@@ -1010,6 +1036,7 @@ void
 seahorse_ssh_op_rename_async (SeahorseSSHSource *source,
                               SeahorseSSHKey *key,
                               const gchar *newcomment,
+                              GtkWindow *transient_for,
                               GCancellable *cancellable,
                               GAsyncReadyCallback callback,
                               gpointer user_data)
diff --git a/ssh/seahorse-ssh-operation.h b/ssh/seahorse-ssh-operation.h
index 6704f9b..575947b 100644
--- a/ssh/seahorse-ssh-operation.h
+++ b/ssh/seahorse-ssh-operation.h
@@ -32,6 +32,7 @@ void              seahorse_ssh_op_upload_async             (SeahorseSSHSource *s
                                                             const gchar *username,
                                                             const gchar *hostname,
                                                             const gchar *port,
+                                                            GtkWindow *transient_for,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
@@ -44,6 +45,7 @@ void              seahorse_ssh_op_generate_async           (SeahorseSSHSource *s
                                                             const gchar *email,
                                                             guint type,
                                                             guint bits,
+                                                            GtkWindow *transient_for,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
@@ -53,6 +55,7 @@ SeahorseObject *  seahorse_ssh_op_generate_finish          (SeahorseSSHSource *s
                                                             GError **error);
 
 void              seahorse_ssh_op_change_passphrase_async  (SeahorseSSHKey *key,
+                                                            GtkWindow *transient_for,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
@@ -64,6 +67,7 @@ gboolean          seahorse_ssh_op_change_passphrase_finish (SeahorseSSHKey *key,
 void              seahorse_ssh_op_import_public_async      (SeahorseSSHSource *source,
                                                             SeahorseSSHKeyData *data,
                                                             const gchar* filename,
+                                                            GtkWindow *transient_for,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
@@ -75,6 +79,7 @@ gchar *           seahorse_ssh_op_import_public_finish     (SeahorseSSHSource *s
 void              seahorse_ssh_op_import_private_async     (SeahorseSSHSource *source,
                                                             SeahorseSSHSecData *data,
                                                             const gchar* filename,
+                                                            GtkWindow *transient_for,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
@@ -86,6 +91,7 @@ gchar *           seahorse_ssh_op_import_private_finish    (SeahorseSSHSource *s
 void              seahorse_ssh_op_authorize_async          (SeahorseSSHSource *source,
                                                             SeahorseSSHKey *skey,
                                                             gboolean authorize,
+                                                            GtkWindow *transient_for,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
@@ -97,6 +103,7 @@ gboolean          seahorse_ssh_op_authorize_finish         (SeahorseSSHSource *s
 void              seahorse_ssh_op_rename_async             (SeahorseSSHSource *source,
                                                             SeahorseSSHKey *key,
                                                             const gchar *newcomment,
+                                                            GtkWindow *transient_for,
                                                             GCancellable *cancellable,
                                                             GAsyncReadyCallback callback,
                                                             gpointer user_data);
diff --git a/ssh/seahorse-ssh-source.c b/ssh/seahorse-ssh-source.c
index 73e2977..1f015f0 100644
--- a/ssh/seahorse-ssh-source.c
+++ b/ssh/seahorse-ssh-source.c
@@ -714,6 +714,7 @@ seahorse_ssh_source_load_finish (SeahorsePlace *place,
 typedef struct {
        SeahorseSSHSource *source;
        GCancellable *cancellable;
+       GtkWindow *transient_for;
        gint imports;
 } source_import_closure;
 
@@ -722,6 +723,7 @@ source_import_free (gpointer data)
 {
        source_import_closure *closure = data;
        g_object_unref (closure->source);
+       g_clear_object (&closure->transient_for);
        g_clear_object (&closure->cancellable);
        g_free (closure);
 }
@@ -760,8 +762,8 @@ on_import_found_public_key (SeahorseSSHKeyData *data,
 
        fullpath = seahorse_ssh_source_file_for_public (closure->source, FALSE);
        seahorse_ssh_op_import_public_async (closure->source, data, fullpath,
-                                            closure->cancellable, on_import_public_complete,
-                                            g_object_ref (res));
+                                            closure->transient_for, closure->cancellable,
+                                            on_import_public_complete, g_object_ref (res));
        closure->imports++;
        g_free (fullpath);
        seahorse_ssh_key_data_free (data);
@@ -801,8 +803,8 @@ on_import_found_private_key (SeahorseSSHSecData *data,
        source_import_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
 
        seahorse_ssh_op_import_private_async (closure->source, data, NULL,
-                                             closure->cancellable, on_import_private_complete,
-                                             g_object_ref (res));
+                                             closure->transient_for, closure->cancellable,
+                                             on_import_private_complete, g_object_ref (res));
 
        seahorse_ssh_sec_data_free (data);
        return TRUE;
@@ -811,6 +813,7 @@ on_import_found_private_key (SeahorseSSHSecData *data,
 void
 seahorse_ssh_source_import_async (SeahorseSSHSource *self,
                                   GInputStream *input,
+                                  GtkWindow *transient_for,
                                   GCancellable *cancellable,
                                   GAsyncReadyCallback callback,
                                   gpointer user_data)
@@ -825,6 +828,7 @@ seahorse_ssh_source_import_async (SeahorseSSHSource *self,
        closure = g_new0 (source_import_closure, 1);
        closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
        closure->source = g_object_ref (self);
+       closure->transient_for = transient_for ? g_object_ref (transient_for) : NULL;
        g_simple_async_result_set_op_res_gpointer (res, closure, source_import_free);
 
        contents = (gchar*)seahorse_util_read_to_memory (input, NULL);
diff --git a/ssh/seahorse-ssh-source.h b/ssh/seahorse-ssh-source.h
index 39db4c9..4d614a1 100644
--- a/ssh/seahorse-ssh-source.h
+++ b/ssh/seahorse-ssh-source.h
@@ -86,6 +86,7 @@ guchar*              seahorse_ssh_source_export_private     (SeahorseSSHSource *
 
 void                 seahorse_ssh_source_import_async       (SeahorseSSHSource *self,
                                                              GInputStream *input,
+                                                             GtkWindow *transient_for,
                                                              GCancellable *cancellable,
                                                              GAsyncReadyCallback callback,
                                                              gpointer user_data);
diff --git a/ssh/seahorse-ssh-upload.c b/ssh/seahorse-ssh-upload.c
index d6fd41d..c516646 100644
--- a/ssh/seahorse-ssh-upload.c
+++ b/ssh/seahorse-ssh-upload.c
@@ -125,7 +125,7 @@ upload_keys (SeahorseWidget *swidget)
 
     /* Start an upload process */
     seahorse_ssh_op_upload_async (SEAHORSE_SSH_SOURCE (seahorse_object_get_place (keys->data)),
-                                  keys, user, host, port, cancellable, on_upload_complete, NULL);
+                                  keys, user, host, port, NULL, cancellable, on_upload_complete, NULL);
 
     g_free (host);
     g_free (user);


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