gvfs r1720 - in trunk: . hal programs



Author: gicmo
Date: Wed Apr  2 20:51:01 2008
New Revision: 1720
URL: http://svn.gnome.org/viewvc/gvfs?rev=1720&view=rev

Log:
Add icon fallbacks for encrypted drives/media. (#525153)

        * hal/hal-utils.h:
        * hal/hal-utils.c:
        Create new files for utility functions and move get_disc_icon()
        and get_disc_name() here.
        Also create get_themed_icon_with_fallbacks() to create
        GThemedIcons with default fallbacks but with the ability to
        pass in another name to create the fallbacks from then the
        icon name.

        * hal/ghalmount.c:
        * hal/ghalvolume.c:
        Use newly created get_themed_icon_with_fallbacks () and pass
        in custom fallback name for encrypted mounts/volumes (#525153).

        * hal/Makefile.am:
        Add hal-utils.[hc]

        * programs/gvfs-mount.c:
        Display the icon names for mounts/volumes if the icon is
        a GThemedIcon.

        [Merged from gnome-2-22]


Added:
   trunk/hal/hal-utils.c
   trunk/hal/hal-utils.h
Modified:
   trunk/ChangeLog
   trunk/hal/Makefile.am
   trunk/hal/ghalmount.c
   trunk/hal/ghalvolume.c
   trunk/programs/gvfs-mount.c

Modified: trunk/hal/Makefile.am
==============================================================================
--- trunk/hal/Makefile.am	(original)
+++ trunk/hal/Makefile.am	Wed Apr  2 20:51:01 2008
@@ -16,6 +16,7 @@
 
 
 libgiohal_volume_monitor_la_SOURCES =				\
+	hal-utils.c 		hal-utils.h \
 	hal-module.c					\
 	hal-marshal.c		hal-marshal.h		\
 	hal-device.c		hal-device.h		\

Modified: trunk/hal/ghalmount.c
==============================================================================
--- trunk/hal/ghalmount.c	(original)
+++ trunk/hal/ghalmount.c	Wed Apr  2 20:51:01 2008
@@ -36,6 +36,8 @@
 #include "ghalmount.h"
 #include "ghalvolume.h"
 
+#include "hal-utils.h"
+
 /* Protects all fields of GHalDrive that can change */
 G_LOCK_DEFINE_STATIC(hal_mount);
 
@@ -157,63 +159,6 @@
   return FALSE;
 }
 
-static const struct {
-  const char *disc_type;
-  const char *icon_name;
-  char *ui_name;
-  char *ui_name_blank;
-} disc_data[] = {
-  {"cd_rom",        "media-optical-cd-rom", N_("CD-ROM Disc"), N_("Blank CD-ROM Disc")},
-  {"cd_r",          "media-optical-cd-r", N_("CD-R Disc"), N_("Blank CD-R Disc")},
-  {"cd_rw",         "media-optical-cd-rw", N_("CD-RW Disc"), N_("Blank CD-RW Disc")},
-  {"dvd_rom",       "media-optical-dvd-rom", N_("DVD-ROM Disc"), N_("Blank DVD-ROM Disc")},
-  {"dvd_ram",       "media-optical-dvd-ram", N_("DVD-RAM Disc"), N_("Blank DVD-RAM Disc")},
-  {"dvd_r",         "media-optical-dvd-r", N_("DVD-ROM Disc"), N_("Blank DVD-ROM Disc")},
-  {"dvd_rw",        "media-optical-dvd-rw", N_("DVD-RW Disc"), N_("Blank DVD-RW Disc")},
-  {"dvd_plus_r",    "media-optical-dvd-r-plus", N_("DVD+R Disc"), N_("Blank DVD+R Disc")},
-  {"dvd_plus_rw",   "media-optical-dvd-rw-plus",  N_("DVD+RW Disc"), N_("Blank DVD+RW Disc")},
-  {"dvd_plus_r_dl", "media-optical-dvd-dl-r-plus", N_("DVD+R DL Disc"), N_("Blank DVD+R DL Disc")},
-  {"bd_rom",        "media-optical-bd-rom", N_("Blu-Ray Disc"), N_("Blank Blu-Ray Disc")},
-  {"bd_r",          "media-optical-bd-r", N_("Blu-Ray R Disc"), N_("Blank Blu-Ray R Disc")},
-  {"bd_re",         "media-optical-bd-re", N_("Blu-Ray RW Disc"), N_("Blank Blu-Ray RW Disc")},
-  {"hddvd_rom",     "media-optical-hddvd-rom", N_("HD DVD Disc"), N_("Blank HD DVD Disc")},
-  {"hddvd_r",       "media-optical-hddvd-r", N_("HD DVD-R Disc"), N_("Blank HD DVD-R Disc")},
-  {"hddvd_rw",      "media-optical-hddvd-rw", N_("HD DVD-RW Disc"), N_("Blank HD DVD-RW Disc")},
-  {"mo",            "media-optical-mo", N_("MO Disc"), N_("Blank MO Disc")},
-  {NULL,            "media-optical", N_("Disc"), N_("Blank Disc")}
-};
-
-static const char *
-get_disc_icon (const char *disc_type)
-{
-  int n;
-  
-  for (n = 0; disc_data[n].disc_type != NULL; n++)
-    {
-      if (strcmp (disc_data[n].disc_type, disc_type) == 0)
-        break;
-    }
-  
-  return disc_data[n].icon_name;
-}
-
-static const char *
-get_disc_name (const char *disc_type, gboolean is_blank)
-{
-  int n;
-  
-  for (n = 0; disc_data[n].disc_type != NULL; n++)
-    {
-      if (strcmp (disc_data[n].disc_type, disc_type) == 0)
-        break;
-    }
-  
-  if (is_blank)
-    return dgettext (GETTEXT_PACKAGE, disc_data[n].ui_name_blank);
-  else
-    return dgettext (GETTEXT_PACKAGE, disc_data[n].ui_name);
-}
-
 typedef struct _MountIconSearchData
 {
   GHalMount *mount;
@@ -388,6 +333,7 @@
   HalDevice *drive;
   char *name;
   const char *icon_name;
+  const char *icon_name_fallback;
   const char *drive_type;
   const char *drive_bus;
   gboolean drive_uses_removable_media;
@@ -437,14 +383,14 @@
   /*g_warning ("drive_bus='%s'", drive_bus); */
   /*g_warning ("drive_uses_removable_media=%d", drive_uses_removable_media); */
 
+  icon_name_fallback = NULL;
+
   if (strlen (volume_icon_from_hal) > 0)
     icon_name = volume_icon_from_hal;
   else if (strlen (icon_from_hal) > 0)
     icon_name = icon_from_hal;
   else if (is_audio_player)
     icon_name = "multimedia-player";
-  else if (is_crypto || is_crypto_cleartext)
-    icon_name = "media-encrypted";
   else if (strcmp (drive_type, "disk") == 0)
     {
       if (strcmp (drive_bus, "ide") == 0)
@@ -459,7 +405,7 @@
         icon_name = "drive-harddisk";
     }
   else if (strcmp (drive_type, "cdrom") == 0)
-    icon_name = g_strdup (get_disc_icon (volume_disc_type));
+    icon_name = get_disc_icon (volume_disc_type);
   else if (strcmp (drive_type, "floppy") == 0)
     icon_name = "media-floppy";
   else if (strcmp (drive_type, "tape") == 0)
@@ -475,7 +421,16 @@
   else
     icon_name = "drive-harddisk";
 
-  
+  /* Create default fallbacks for the icon_name by default
+   * with get_themed_icon_with_fallbacks () */
+  icon_name_fallback = icon_name;
+
+  /* Note: we are not chaning the default fallbacks
+   * so we get all the fallbacks if the media-encrytped
+   * icon is not there */
+  if (is_crypto || is_crypto_cleartext)
+    icon_name = "media-encrypted";
+
   if (strlen (volume_name_from_hal) > 0)
     name = g_strdup (volume_name_from_hal);
   else if (strlen (name_from_hal) > 0)
@@ -515,8 +470,9 @@
   if (m->override_icon != NULL)
     m->icon = g_object_ref (m->override_icon);
   else
-    m->icon = g_themed_icon_new_with_default_fallbacks (icon_name);
-    
+    m->icon = get_themed_icon_with_fallbacks (icon_name,
+                                              icon_name_fallback);
+
   /* If this is a CD-ROM, begin searching for an icon specified in
    * autorun.inf.
   **/

Modified: trunk/hal/ghalvolume.c
==============================================================================
--- trunk/hal/ghalvolume.c	(original)
+++ trunk/hal/ghalvolume.c	Wed Apr  2 20:51:01 2008
@@ -36,6 +36,8 @@
 #include "ghalvolume.h"
 #include "ghalmount.h"
 
+#include "hal-utils.h"
+
 /* Protects all fields of GHalDrive that can change */
 G_LOCK_DEFINE_STATIC(hal_volume);
 
@@ -63,6 +65,7 @@
 
   char *name;
   char *icon;
+  char *icon_fallback;
 };
 
 static void g_hal_volume_volume_iface_init (GVolumeIface *iface);
@@ -110,6 +113,7 @@
 
   g_free (volume->name);
   g_free (volume->icon);
+  g_free (volume->icon_fallback);
 
   if (G_OBJECT_CLASS (g_hal_volume_parent_class)->finalize)
     (*G_OBJECT_CLASS (g_hal_volume_parent_class)->finalize) (object);
@@ -146,50 +150,6 @@
   return FALSE;
 }
 
-static const struct {
-  const char *disc_type;
-  const char *icon_name;
-  char *ui_name;
-  char *ui_name_blank;
-} disc_data[] = {
-  {"cd_rom",        "media-optical-cd-rom", N_("CD-ROM Disc"), N_("Blank CD-ROM Disc")},
-  {"cd_r",          "media-optical-cd-r", N_("CD-R Disc"), N_("Blank CD-R Disc")},
-  {"cd_rw",         "media-optical-cd-rw", N_("CD-RW Disc"), N_("Blank CD-RW Disc")},
-  {"dvd_rom",       "media-optical-dvd-rom", N_("DVD-ROM Disc"), N_("Blank DVD-ROM Disc")},
-  {"dvd_ram",       "media-optical-dvd-ram", N_("DVD-RAM Disc"), N_("Blank DVD-RAM Disc")},
-  {"dvd_r",         "media-optical-dvd-r", N_("DVD-ROM Disc"), N_("Blank DVD-ROM Disc")},
-  {"dvd_rw",        "media-optical-dvd-rw", N_("DVD-RW Disc"), N_("Blank DVD-RW Disc")},
-  {"dvd_plus_r",    "media-optical-dvd-r-plus", N_("DVD+R Disc"), N_("Blank DVD+R Disc")},
-  {"dvd_plus_rw",   "media-optical-dvd-rw-plus",  N_("DVD+RW Disc"), N_("Blank DVD+RW Disc")},
-  {"dvd_plus_r_dl", "media-optical-dvd-dl-r-plus", N_("DVD+R DL Disc"), N_("Blank DVD+R DL Disc")},
-  {"bd_rom",        "media-optical-bd-rom", N_("Blu-Ray Disc"), N_("Blank Blu-Ray Disc")},
-  {"bd_r",          "media-optical-bd-r", N_("Blu-Ray R Disc"), N_("Blank Blu-Ray R Disc")},
-  {"bd_re",         "media-optical-bd-re", N_("Blu-Ray RW Disc"), N_("Blank Blu-Ray RW Disc")},
-  {"hddvd_rom",     "media-optical-hddvd-rom", N_("HD DVD Disc"), N_("Blank HD DVD Disc")},
-  {"hddvd_r",       "media-optical-hddvd-r", N_("HD DVD-R Disc"), N_("Blank HD DVD-R Disc")},
-  {"hddvd_rw",      "media-optical-hddvd-rw", N_("HD DVD-RW Disc"), N_("Blank HD DVD-RW Disc")},
-  {"mo",            "media-optical-mo", N_("MO Disc"), N_("Blank MO Disc")},
-  {NULL,            "media-optical", N_("Disc"), N_("Blank Disc")}
-};
-
-static const char *
-get_disc_name (const char *disc_type, gboolean is_blank)
-{
-  int n;
-  
-  for (n = 0; disc_data[n].disc_type != NULL; n++)
-    {
-      if (strcmp (disc_data[n].disc_type, disc_type) == 0)
-        break;
-    }
-  
-  if (is_blank)
-    return dgettext (GETTEXT_PACKAGE, disc_data[n].ui_name_blank);
-  else
-    return dgettext (GETTEXT_PACKAGE, disc_data[n].ui_name);
-}
-
-
 #define KILOBYTE_FACTOR 1000.0
 #define MEGABYTE_FACTOR (1000.0 * 1000.0)
 #define GIGABYTE_FACTOR (1000.0 * 1000.0 * 1000.0)
@@ -332,11 +292,13 @@
     }
 
   mv->name = name;
+  mv->icon = _drive_get_icon (drive); /* use the drive icon since we're unmounted */
 
   if (is_crypto || is_crypto_cleartext)
-    mv->icon = g_strdup ("drive-encrypted");
-  else
-    mv->icon = _drive_get_icon (drive); /* use the drive icon since we're unmounted */
+    {
+      mv->icon_fallback = mv->icon;
+      mv->icon = g_strdup ("drive-encrypted");
+    }
 
   if (hal_device_get_property_bool (volume, "volume.is_mounted"))
     mv->mount_path = g_strdup (hal_device_get_property_string (volume, "volume.mount_point"));
@@ -690,11 +652,19 @@
 {
   GHalVolume *hal_volume = G_HAL_VOLUME (volume);
   GIcon *icon;
+  const char *name;
+  const char *fallback;
 
   G_LOCK (hal_volume);
-  icon = g_themed_icon_new_with_default_fallbacks (hal_volume->icon);
+  name = hal_volume->icon;
+
+  if (hal_volume->icon_fallback)
+    fallback = hal_volume->icon_fallback;
+  else /* if no custom fallbacks are set, use the icon to create them */
+    fallback = name;
+
+  icon = get_themed_icon_with_fallbacks (name, fallback);
   G_UNLOCK (hal_volume);
-  
   return icon;
 }
 

Added: trunk/hal/hal-utils.c
==============================================================================
--- (empty file)
+++ trunk/hal/hal-utils.c	Wed Apr  2 20:51:01 2008
@@ -0,0 +1,144 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <davidz redhat com>
+ *         Christian Kellner <gicmo gnome org>
+ */
+
+#include <config.h>
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <gio/gio.h>
+
+#include "string.h"
+
+#include "hal-utils.h"
+
+static const struct {
+  const char *disc_type;
+  const char *icon_name;
+  char *ui_name;
+  char *ui_name_blank;
+} disc_data[] = {
+  {"cd_rom",        "media-optical-cd-rom", N_("CD-ROM Disc"), N_("Blank CD-ROM Disc")},
+  {"cd_r",          "media-optical-cd-r", N_("CD-R Disc"), N_("Blank CD-R Disc")},
+  {"cd_rw",         "media-optical-cd-rw", N_("CD-RW Disc"), N_("Blank CD-RW Disc")},
+  {"dvd_rom",       "media-optical-dvd-rom", N_("DVD-ROM Disc"), N_("Blank DVD-ROM Disc")},
+  {"dvd_ram",       "media-optical-dvd-ram", N_("DVD-RAM Disc"), N_("Blank DVD-RAM Disc")},
+  {"dvd_r",         "media-optical-dvd-r", N_("DVD-ROM Disc"), N_("Blank DVD-ROM Disc")},
+  {"dvd_rw",        "media-optical-dvd-rw", N_("DVD-RW Disc"), N_("Blank DVD-RW Disc")},
+  {"dvd_plus_r",    "media-optical-dvd-r-plus", N_("DVD+R Disc"), N_("Blank DVD+R Disc")},
+  {"dvd_plus_rw",   "media-optical-dvd-rw-plus",  N_("DVD+RW Disc"), N_("Blank DVD+RW Disc")},
+  {"dvd_plus_r_dl", "media-optical-dvd-dl-r-plus", N_("DVD+R DL Disc"), N_("Blank DVD+R DL Disc")},
+  {"bd_rom",        "media-optical-bd-rom", N_("Blu-Ray Disc"), N_("Blank Blu-Ray Disc")},
+  {"bd_r",          "media-optical-bd-r", N_("Blu-Ray R Disc"), N_("Blank Blu-Ray R Disc")},
+  {"bd_re",         "media-optical-bd-re", N_("Blu-Ray RW Disc"), N_("Blank Blu-Ray RW Disc")},
+  {"hddvd_rom",     "media-optical-hddvd-rom", N_("HD DVD Disc"), N_("Blank HD DVD Disc")},
+  {"hddvd_r",       "media-optical-hddvd-r", N_("HD DVD-R Disc"), N_("Blank HD DVD-R Disc")},
+  {"hddvd_rw",      "media-optical-hddvd-rw", N_("HD DVD-RW Disc"), N_("Blank HD DVD-RW Disc")},
+  {"mo",            "media-optical-mo", N_("MO Disc"), N_("Blank MO Disc")},
+  {NULL,            "media-optical", N_("Disc"), N_("Blank Disc")}
+};
+
+const char *
+get_disc_icon (const char *disc_type)
+{
+  int n;
+
+  for (n = 0; disc_data[n].disc_type != NULL; n++)
+    {
+      if (strcmp (disc_data[n].disc_type, disc_type) == 0)
+        break;
+    }
+
+  return disc_data[n].icon_name;
+}
+
+const char *
+get_disc_name (const char *disc_type, gboolean is_blank)
+{
+  int n;
+
+  for (n = 0; disc_data[n].disc_type != NULL; n++)
+    {
+      if (strcmp (disc_data[n].disc_type, disc_type) == 0)
+        break;
+    }
+
+  if (is_blank)
+    return dgettext (GETTEXT_PACKAGE, disc_data[n].ui_name_blank);
+  else
+    return dgettext (GETTEXT_PACKAGE, disc_data[n].ui_name);
+}
+
+/*
+ * Creates a GThemedIcon from icon_name and creates default
+ * fallbacks from fallbacks. Is smart in the case that icon_name
+ * and fallbacks are identically.
+ * Note: See the GThemedIcon documentation for more information
+ * on default fallbacks
+ */
+GIcon *
+get_themed_icon_with_fallbacks (const char *icon_name,
+                                const char *fallbacks)
+{
+  int i = 0, dashes = 0;
+  const char *p;
+  char *dashp;
+  char *last;
+  char **names;
+  GIcon *icon;
+
+  if (G_UNLIKELY (icon_name == NULL))
+    return NULL;
+
+  if (fallbacks == NULL)
+    return g_themed_icon_new (icon_name);
+
+  p = fallbacks;
+  while (*p)
+    {
+      if (*p == '-')
+        dashes++;
+      p++;
+    }
+
+  if (strcmp (icon_name, fallbacks))
+    {
+      names = g_new (char *, dashes + 3);
+      names[i++] = g_strdup (icon_name);
+    }
+  else
+    names = g_new (char *, dashes + 2);
+
+  names[i++] = last = g_strdup (fallbacks);
+
+  while ((dashp = strrchr (last, '-')) != NULL)
+    names[i++] = last = g_strndup (last, dashp - last);
+
+  names[i++] = NULL;
+  icon =  g_themed_icon_new_from_names (names, -1);
+  g_strfreev (names);
+
+  return icon;
+}
+

Added: trunk/hal/hal-utils.h
==============================================================================
--- (empty file)
+++ trunk/hal/hal-utils.h	Wed Apr  2 20:51:01 2008
@@ -0,0 +1,40 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <davidz redhat com>
+ *         Chrsitian Kellner <gicmo gnome org>
+ */
+
+#ifndef __HAL_UTILS_H__
+#define __HAL_UTILS_H__
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+const char * get_disc_icon (const char *disc_type);
+const char * get_disc_name (const char *disc_type, gboolean is_blank);
+
+GIcon *      get_themed_icon_with_fallbacks (const char *icon_name,
+                                             const char *fallbacks);
+
+G_END_DECLS
+
+#endif /* __HAL_UTILS_H__ */

Modified: trunk/programs/gvfs-mount.c
==============================================================================
--- trunk/programs/gvfs-mount.c	(original)
+++ trunk/programs/gvfs-mount.c	Wed Apr  2 20:51:01 2008
@@ -270,6 +270,24 @@
   g_main_loop_run (main_loop);
 }
 
+static void
+show_themed_icon_names (GThemedIcon *icon, int indent)
+{
+  char **names;
+  char **iter;
+
+  g_print ("%*sthemed icons:", indent, " ");
+
+  names = NULL;
+
+  g_object_get (icon, "names", &names, NULL);
+
+  for (iter = names; *iter; iter++)
+    g_print ("  [%s]", *iter);
+
+  g_print ("\n");
+  g_strfreev (names);
+}
 
 static void
 list_mounts (GList *mounts,
@@ -282,6 +300,7 @@
   GVolume *volume;
   char *name, *uuid, *uri;
   GFile *root;
+  GIcon *icon;
   
   for (c = 0, l = mounts; l != NULL; l = l->next, c++)
     {
@@ -308,6 +327,16 @@
 	  uuid = g_mount_get_uuid (mount);
 	  if (uuid)
 	    g_print ("%*suuid=%s\n", indent + 2, "", uuid);
+
+      icon = g_mount_get_icon (mount);
+      if (icon)
+        {
+          if (G_IS_THEMED_ICON (icon))
+            show_themed_icon_names (G_THEMED_ICON (icon), indent + 2);
+
+          g_object_unref (icon);
+        }
+
 	  g_print ("%*scan_unmount=%d\n", indent + 2, "", g_mount_can_unmount (mount));
 	  g_print ("%*scan_eject=%d\n", indent + 2, "", g_mount_can_eject (mount));
 	  g_free (uuid);
@@ -319,8 +348,6 @@
     }  
 }
 
-
-
 static void
 list_volumes (GList *volumes,
 	      int indent,
@@ -334,6 +361,7 @@
   char *name;
   char *uuid;
   char **ids;
+  GIcon *icon;
   
   for (c = 0, l = volumes; l != NULL; l = l->next, c++)
     {
@@ -373,6 +401,15 @@
 	  uuid = g_volume_get_uuid (volume);
 	  if (uuid)
 	    g_print ("%*suuid=%s\n", indent + 2, "", uuid);
+      icon = g_volume_get_icon (volume);
+      if (icon)
+        {
+          if (G_IS_THEMED_ICON (icon))
+            show_themed_icon_names (G_THEMED_ICON (icon), indent + 2);
+
+          g_object_unref (icon);
+        }
+
 	  g_print ("%*scan_mount=%d\n", indent + 2, "", g_volume_can_mount (volume));
 	  g_print ("%*scan_eject=%d\n", indent + 2, "", g_volume_can_eject (volume));
 	  g_free (uuid);



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