[evolution-patches] patch for gal keyboard navigation (51649)
- From: wu yang <Yang Wu sun com>
- To: Mike Kestner <mkestner ximian com>
- Cc: sceri-evolution-acc sun com, evolution-patches ximian com
- Subject: [evolution-patches] patch for gal keyboard navigation (51649)
- Date: Wed, 03 Dec 2003 23:47:20 +0800
Hi Mike,
This is a patch for gal keyboard navigation, fixed bug 51649
"Use keyboard to add a column into table head"
Could you take some time to review it?
Thanks
? docs/gal-api.html
? gal/a11y/e-table/gal-a11y-e-cell-combo.c
? gal/a11y/e-table/gal-a11y-e-cell-combo.h
? gal/a11y/e-table/gal-a11y-e-cell-popup.c
? gal/a11y/e-table/gal-a11y-e-cell-popup.h
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gal/ChangeLog,v
retrieving revision 1.834
diff -u -b -B -r1.834 ChangeLog
--- ChangeLog 2 Dec 2003 08:25:16 -0000 1.834
+++ ChangeLog 3 Dec 2003 15:39:21 -0000
@@ -1,3 +1,36 @@
+2003-12-03 Andrew Wu <yang wu sun com>
+
+ Fixes #51649
+
+ * gal/e-table/e-table-field-chooser-item.c:
+ (etfci_realize): Create GC for display focus rectangle.
+ (etfci_unrealize):destory GC.
+ (etfci_event):add some code deal with keyboard.
+
+ * e-table-field-chooser-item.h:
+ add two member for keyboard navigation.
+
+ * e-table-field-chooser.c:
+ (e_table_field_chooser_focus_in):
+ (e_table_field_chooser_focus_out):
+ redraw the canvas when focus changed.
+
+ * e-table-header-item.c:
+ (ethi_realize): Create GC for display focus rectangle.
+ (ethi_unrealize):destory GC.
+ (ethi_event):add some code deal with keyboard.
+
+ * e-table-header-item.h:
+ add one member for keyboard navigation.
+
+ * e-table-header-utils.c:
+ (e_table_header_draw_button):
+ add two arg. "is_selected" and "focus_gc" to draw rectangle.
+
+ * e-table.c:
+ (et_focus): add some code to switch table
+ focus between header and body.
+
2003-12-02 Bolian Yin <bolian yin sun com>
Fixes #51145
@@ -5,7 +38,7 @@
* gal/a11y/gal-a11y-e-table-item (eti_get_column_header): new impl.
(eti_ref_child): add column headers as children
-2003-11-23 Andrew Wu <yang wu sun com>
+2003-12-02 Andrew Wu <yang wu sun com>
Fixed Bug 51252, 51254, 51255.
* gal/e-table/e-table-header-item.c:
@@ -596,7 +629,7 @@
* Makefile.am : revert a broken CLEAN_FILES change. [42478]
-2003-05-18 Danilo Å egan <dsegan gmx net>
+2003-05-18 Danilo � egan <dsegan gmx net>
* configure.in: Added "sr" and "sr Latn" to ALL_LINGUAS.
@@ -3203,7 +3236,7 @@
* gal/unicode/gunidecomp.c (_g_utf8_normalize_wc): Handle the case
of invalid utf8 here by simply dropping any invalid characters.
-2001-12-11 Gustavo Giráldez <gustavo giraldez gmx net>
+2001-12-11 Gustavo Gir�¡ldez <gustavo giraldez gmx net>
* gal/e-table/e-table-header-item.c (ethi_unrealize): unregister
ETableHeaderItem widget as a drag target when unrealizing it.
@@ -3705,7 +3738,7 @@
in some iconv implementions that require the length arguments to
be valid pointers event if both buffers are NULL.
-2001-10-13 Carlos Perelló MarÃn <carlos gnome-db org>
+2001-10-13 Carlos PerellÃ?³ MarÃ?Ân <carlos gnome-db org>
* configure.in (ALL_LINGUAS): Added pt
@@ -6884,7 +6917,7 @@
calling gdk_fontset_load
2000-11-07 Jody Goldberg <jgoldberg home com>
- For : �RDI Gergõ <cactus cactus rulez org>
+ For : ��RDI Gerg�µ <cactus cactus rulez org>
* gal/widgets/gtk-combo-stack.[ch] : Improve selection display.
Index: gal/e-table/e-table-field-chooser-item.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-table-field-chooser-item.c,v
retrieving revision 1.21
diff -u -b -B -r1.21 e-table-field-chooser-item.c
--- gal/e-table/e-table-field-chooser-item.c 17 Nov 2002 00:02:53 -0000 1.21
+++ gal/e-table/e-table-field-chooser-item.c 3 Dec 2003 15:39:24 -0000
@@ -30,6 +30,7 @@
#include <libgnomecanvas/gnome-canvas-polygon.h>
#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk/gdkkeysyms.h>
#include "gal/util/e-i18n.h"
#include "gal/util/e-util.h"
@@ -54,6 +55,11 @@
static guint etfci_signals [LAST_SIGNAL] = { 0, };
#endif
+#define gray50_width 2
+#define gray50_height 2
+static const char gray50_bits[] = {
+ 0x02, 0x01, };
+
#define PARENT_OBJECT_TYPE gnome_canvas_item_get_type ()
#define ELEMENTS(x) (sizeof (x) / sizeof (x[0]))
@@ -424,6 +430,7 @@
{
ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
GdkWindow *window;
+ GdkBitmap *stipple;
if (GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)-> realize)
(*GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->realize)(item);
@@ -433,6 +440,15 @@
if (!etfci->font)
etfci_font_load (etfci);
+ /* Create GC for display focus rectangle */
+ etfci->focus_gc = gdk_gc_new (window);
+ gdk_gc_set_foreground (etfci->focus_gc, >K_WIDGET (item->canvas)->style->bg [GTK_STATE_NORMAL]);
+ gdk_gc_set_background (etfci->focus_gc, >K_WIDGET (item->canvas)->style->fg [GTK_STATE_NORMAL]);
+ stipple = gdk_bitmap_create_from_data (NULL, gray50_bits, gray50_width, gray50_height);
+ gdk_gc_set_ts_origin (etfci->focus_gc, 0, 0);
+ gdk_gc_set_stipple (etfci->focus_gc, stipple);
+ gdk_gc_set_fill (etfci->focus_gc, GDK_OPAQUE_STIPPLED);
+
etfci->drag_end_id = g_signal_connect (
item->canvas, "drag_end",
G_CALLBACK (etfci_drag_end), etfci);
@@ -451,6 +467,9 @@
gdk_font_unref (etfci->font);
etfci->font = NULL;
+ g_object_unref (etfci->focus_gc);
+ etfci->focus_gc = NULL;
+
g_signal_handler_disconnect (item->canvas, etfci->drag_end_id);
etfci->drag_end_id = 0;
g_signal_handler_disconnect (item->canvas, etfci->drag_data_get_id);
@@ -482,6 +501,7 @@
y1 = y2 = 0;
for (row = 0; row < rows; row++, y1 = y2){
ETableCol *ecol;
+ gboolean is_selected;
ecol = e_table_header_get_column (etfci->combined_header, row);
@@ -496,13 +516,21 @@
if (y2 < y)
continue;
+ if ((GTK_WIDGET_HAS_FOCUS (canvas)) && (etfci->selected_col == row))
+ is_selected = TRUE;
+ else
+ is_selected = FALSE;
+
+
e_table_header_draw_button (drawable, ecol,
style, state,
GTK_WIDGET (canvas),
-x, y1 - y,
width, height,
etfci->width, y2 - y1,
- E_TABLE_COL_ARROW_NONE);
+ E_TABLE_COL_ARROW_NONE,
+ is_selected,
+ etfci->focus_gc);
}
}
@@ -572,7 +600,9 @@
0, 0,
etfci->width, button_height,
etfci->width, button_height,
- E_TABLE_COL_ARROW_NONE);
+ E_TABLE_COL_ARROW_NONE,
+ TRUE,
+ etfci->focus_gc);
gtk_drag_set_icon_pixmap (context,
gdk_window_get_colormap (widget->window),
@@ -609,6 +639,9 @@
etfci->click_x = x;
etfci->click_y = y;
etfci->maybe_drag = TRUE;
+ etfci->selected_col = etfci_find_button(etfci, y);
+ e_canvas_item_grab_focus (item, TRUE);
+ gtk_widget_queue_draw (GTK_WIDGET (canvas));
}
break;
@@ -616,6 +649,53 @@
etfci->maybe_drag = FALSE;
break;
}
+ case GDK_KEY_PRESS: {
+ int header_count, combined_count;
+
+ header_count = e_table_header_count (etfci->header);
+ combined_count = e_table_header_count (etfci->combined_header);
+
+ switch (e->key.keyval) {
+ case GDK_KP_Enter:
+ case GDK_Return: {
+ ETableCol *ecol;
+
+ if (combined_count <= 0)
+ break;
+ ecol = e_table_header_get_column (etfci->combined_header,
+ etfci->selected_col);
+ if (ecol->disabled)
+ break;
+ e_table_header_add_column (etfci->header, ecol, header_count);
+ if (combined_count <= etfci->selected_col +1)
+ etfci->selected_col--;
+ break;
+ }
+ case GDK_Up:
+ case GDK_KP_Up:
+ case GDK_Left:
+ case GDK_KP_Left:
+ if (etfci->selected_col == 0)
+ etfci->selected_col = combined_count - 1;
+ else
+ etfci->selected_col--;
+ break;
+ case GDK_Down:
+ case GDK_KP_Down:
+ case GDK_Right:
+ case GDK_KP_Right:
+ if (etfci->selected_col == combined_count -1)
+ etfci->selected_col = 0;
+ else
+ etfci->selected_col++;
+ break;
+ default:
+ return FALSE;
+ }
+
+ gtk_widget_queue_draw (GTK_WIDGET (canvas));
+ break;
+ }
default:
return FALSE;
@@ -699,6 +779,8 @@
etfci->maybe_drag = 0;
etfci->drag_end_id = 0;
+
+ etfci->selected_col = 0;
e_canvas_item_set_reflow_callback(item, etfci_reflow);
}
Index: gal/e-table/e-table-field-chooser-item.h
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-table-field-chooser-item.h,v
retrieving revision 1.9
diff -u -b -B -r1.9 e-table-field-chooser-item.h
--- gal/e-table/e-table-field-chooser-item.h 17 Nov 2002 00:02:53 -0000 1.9
+++ gal/e-table/e-table-field-chooser-item.h 3 Dec 2003 15:39:24 -0000
@@ -62,6 +62,12 @@
int drag_col;
guint drag_data_get_id;
guint drag_end_id;
+
+ /*
+ * For keyboard navigation
+ */
+ int selected_col;
+ GdkGC *focus_gc;
} ETableFieldChooserItem;
typedef struct {
Index: gal/e-table/e-table-field-chooser.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-table-field-chooser.c,v
retrieving revision 1.19
diff -u -b -B -r1.19 e-table-field-chooser.c
--- gal/e-table/e-table-field-chooser.c 3 Nov 2003 02:06:01 -0000 1.19
+++ gal/e-table/e-table-field-chooser.c 3 Dec 2003 15:39:25 -0000
@@ -112,6 +112,18 @@
NULL );
}
+static void e_table_field_chooser_focus_in (GtkWidget *canvas, GdkEventFocus *event, ETableFieldChooser *etfc)
+{
+ e_canvas_item_grab_focus (etfc->item, TRUE);
+ gtk_widget_queue_draw (canvas);
+}
+
+static void e_table_field_chooser_focus_out (GtkWidget *canvas, GdkEventFocus *event, ETableFieldChooser *etfc)
+{
+ gtk_widget_queue_draw (canvas);
+}
+
+
static void resize(GnomeCanvas *canvas, ETableFieldChooser *etfc)
{
double height;
@@ -176,6 +188,12 @@
/* Connect the signals */
g_signal_connect (etfc->canvas, "size_allocate",
G_CALLBACK (allocate_callback),
+ etfc);
+ g_signal_connect (etfc->canvas, "focus_in_event",
+ G_CALLBACK (e_table_field_chooser_focus_in),
+ etfc);
+ g_signal_connect (etfc->canvas, "focus_out_event",
+ G_CALLBACK (e_table_field_chooser_focus_out),
etfc);
gtk_widget_pop_colormap ();
Index: gal/e-table/e-table-header-item.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-table-header-item.c,v
retrieving revision 1.126
diff -u -b -B -r1.126 e-table-header-item.c
--- gal/e-table/e-table-header-item.c 2 Dec 2003 07:55:14 -0000 1.126
+++ gal/e-table/e-table-header-item.c 3 Dec 2003 15:39:27 -0000
@@ -67,6 +67,11 @@
#define ARROW_DOWN_HEIGHT 16
#define ARROW_PTR 7
+#define gray50_width 2
+#define gray50_height 2
+static const char gray50_bits[] = {
+ 0x02, 0x01, };
+
/* Defines the tolerance for proximity of the column division to the cursor position */
#define TOLERANCE 4
@@ -536,11 +541,6 @@
gtk_widget_show_all (arrow_up);
}
-#define gray50_width 2
-#define gray50_height 2
-static char gray50_bits [] = {
- 0x02, 0x01, };
-
static void
ethi_add_destroy_marker (ETableHeaderItem *ethi)
{
@@ -890,7 +890,9 @@
ethi_realize (GnomeCanvasItem *item)
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
+ GtkWidget *canvas_widget = GTK_WIDGET (item->canvas);
GdkWindow *window;
+ GdkBitmap *stipple;
GtkTargetEntry ethi_drop_types [] = {
{ TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
};
@@ -929,6 +931,14 @@
ethi->drag_data_get_id = g_signal_connect (item->canvas, "drag_data_get",
G_CALLBACK (ethi_drag_data_get), ethi);
+ /* Create GC for display focus rectangle */
+ ethi->focus_gc = gdk_gc_new (window);
+ gdk_gc_set_foreground (ethi->focus_gc, >K_WIDGET (item->canvas)->style->bg [GTK_STATE_NORMAL]);
+ gdk_gc_set_background (ethi->focus_gc, >K_WIDGET (item->canvas)->style->fg [GTK_STATE_NORMAL]);
+ stipple = gdk_bitmap_create_from_data (NULL, gray50_bits, gray50_width, gray50_height);
+ gdk_gc_set_ts_origin (ethi->focus_gc, 0, 0);
+ gdk_gc_set_stipple (ethi->focus_gc, stipple);
+ gdk_gc_set_fill (ethi->focus_gc, GDK_OPAQUE_STIPPLED);
}
static void
@@ -938,6 +948,9 @@
gdk_font_unref (ethi->font);
+ g_object_unref (ethi->focus_gc);
+ ethi->focus_gc = NULL;
+
g_signal_handler_disconnect (item->canvas, ethi->drag_motion_id);
g_signal_handler_disconnect (item->canvas, ethi->drag_leave_id);
g_signal_handler_disconnect (item->canvas, ethi->drag_drop_id);
@@ -996,6 +1009,7 @@
for (col = 0; col < cols; col++, x1 = x2){
ETableCol *ecol = e_table_header_get_column (ethi->eth, col);
int col_width;
+ gboolean is_selected;
col_width = ecol->width;
@@ -1010,6 +1024,11 @@
if (x2 <= x1)
continue;
+ if ((GTK_WIDGET_HAS_FOCUS (canvas)) && (ethi->selected_col == col))
+ is_selected = TRUE;
+ else
+ is_selected = FALSE;
+
e_table_header_draw_button (drawable, ecol,
GTK_WIDGET (canvas)->style,
GTK_WIDGET_STATE (canvas),
@@ -1018,7 +1037,9 @@
width, height,
x2 - x1, ethi->height,
(ETableColArrow) g_hash_table_lookup (
- arrows, GINT_TO_POINTER (ecol->col_idx)));
+ arrows, GINT_TO_POINTER (ecol->col_idx)),
+ is_selected,
+ ethi->focus_gc);
}
g_hash_table_destroy (arrows);
@@ -1212,7 +1233,9 @@
col_width, ethi->height,
col_width, ethi->height,
(ETableColArrow) g_hash_table_lookup (
- arrows, GINT_TO_POINTER (ecol->col_idx)));
+ arrows, GINT_TO_POINTER (ecol->col_idx)),
+ TRUE,
+ ethi->focus_gc);
gtk_drag_set_icon_pixmap (
context,
gdk_window_get_colormap (widget->window),
@@ -1745,25 +1768,50 @@
col = e_table_header_get_column (ethi->eth, ethi->selected_col);
ethi_change_sort_state (ethi, col);
- } else if ((e->key.keyval == GDK_Right) || (e->key.keyval == GDK_KP_Right)) {
- ETableCol *col;
-
+ } else if (((e->key.keyval == GDK_Right) || (e->key.keyval == GDK_KP_Right))
+ && (e->key.state & GDK_MOD1_MASK)) {
+ if ((ethi->selected_col < 0) || (ethi->selected_col > ethi->eth->col_count - 1))
+ ethi->selected_col = 0;
+ if (ethi->selected_col >= ethi->eth->col_count - 1) {
+ e_table_header_move(ethi->eth, ethi->selected_col, 0);
+ ethi->selected_col = 0;
+ } else {
+ e_table_header_move(ethi->eth, ethi->selected_col, ethi->selected_col + 2);
+ ethi->selected_col++;
+ }
+ } else if (((e->key.keyval == GDK_Left) || (e->key.keyval == GDK_KP_Left))
+ && (e->key.state & GDK_MOD1_MASK)) {
+ if ((ethi->selected_col < 0) || (ethi->selected_col > ethi->eth->col_count - 1))
+ ethi->selected_col = 0;
+ if (ethi->selected_col <= 0) {
+ e_table_header_move(ethi->eth, ethi->selected_col, ethi->eth->col_count);
+ ethi->selected_col = ethi->eth->col_count - 1;
+ }
+ else {
+ e_table_header_move(ethi->eth, ethi->selected_col, ethi->selected_col - 1);
+ ethi->selected_col--;
+ }
+ } else if (((e->key.keyval == GDK_Right) || (e->key.keyval == GDK_KP_Right))
+ && !(e->key.state & GDK_MOD1_MASK)) {
if ((ethi->selected_col < 0) || (ethi->selected_col >= ethi->eth->col_count - 1))
ethi->selected_col = 0;
else
ethi->selected_col++;
- col = e_table_header_get_column (ethi->eth, ethi->selected_col);
- ethi_change_sort_state (ethi, col);
- } else if ((e->key.keyval == GDK_Left) || (e->key.keyval == GDK_KP_Left)) {
- ETableCol *col;
-
+ } else if (((e->key.keyval == GDK_Left) || (e->key.keyval == GDK_KP_Left))
+ && !(e->key.state & GDK_MOD1_MASK)) {
if ((ethi->selected_col <= 0) || (ethi->selected_col >= ethi->eth->col_count))
ethi->selected_col = ethi->eth->col_count - 1;
else
ethi->selected_col--;
- col = e_table_header_get_column (ethi->eth, ethi->selected_col);
- ethi_change_sort_state (ethi, col);
- }
+ } else
+ return FALSE;
+
+ gtk_widget_queue_draw (GTK_WIDGET (canvas));
+
+ break;
+
+ case GDK_FOCUS_CHANGE:
+ gtk_widget_queue_draw (GTK_WIDGET (canvas));
break;
default:
Index: gal/e-table/e-table-header-item.h
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-table-header-item.h,v
retrieving revision 1.29
diff -u -b -B -r1.29 e-table-header-item.h
--- gal/e-table/e-table-header-item.h 2 Dec 2003 07:55:14 -0000 1.29
+++ gal/e-table/e-table-header-item.h 3 Dec 2003 15:39:28 -0000
@@ -99,7 +99,7 @@
/* For keyboard navigation*/
int selected_col;
-
+ GdkGC *focus_gc;
} ETableHeaderItem;
typedef struct {
Index: gal/e-table/e-table-header-utils.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-table-header-utils.c,v
retrieving revision 1.15
diff -u -b -B -r1.15 e-table-header-utils.c
--- gal/e-table/e-table-header-utils.c 15 Apr 2003 21:34:31 -0000 1.15
+++ gal/e-table/e-table-header-utils.c 3 Dec 2003 15:39:28 -0000
@@ -31,6 +31,7 @@
#include <string.h> /* strlen() */
#include <glib.h>
+#include <gdk/gdk.h>
#include <gtk/gtkbutton.h>
#include <gtk/gtkwindow.h>
#include "e-table-defines.h"
@@ -326,6 +327,8 @@
* @button_width: Width for the complete button.
* @button_height: Height for the complete button.
* @arrow: Arrow type to use as a sort indicator.
+ * @is_selected: if it is selected, then draw a rectangle in it to mark it.
+ * @focus_gc: gc for draw rectangle.
*
* Draws a button suitable for a table header.
**/
@@ -335,7 +338,9 @@
GtkWidget *widget,
int x, int y, int width, int height,
int button_width, int button_height,
- ETableColArrow arrow)
+ ETableColArrow arrow,
+ gboolean is_selected,
+ GdkGC *focus_gc)
{
int xthick, ythick;
int inner_x, inner_y;
@@ -374,6 +379,12 @@
gtk_paint_box (style, drawable, state, GTK_SHADOW_OUT,
NULL, widget, "button",
x, y, button_width, button_height);
+
+ /* Draw a rectangle for a selected button */
+
+ if (is_selected)
+ gdk_draw_rectangle (drawable, focus_gc, FALSE,
+ x + 2, y + 2, button_width - 6 , button_height - 6);
/* Inside area */
Index: gal/e-table/e-table-header-utils.h
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-table-header-utils.h,v
retrieving revision 1.9
diff -u -b -B -r1.9 e-table-header-utils.h
--- gal/e-table/e-table-header-utils.h 17 Nov 2002 00:02:53 -0000 1.9
+++ gal/e-table/e-table-header-utils.h 3 Dec 2003 15:39:28 -0000
@@ -46,7 +46,9 @@
int height,
int button_width,
int button_height,
- ETableColArrow arrow);
+ ETableColArrow arrow,
+ gboolean is_selected,
+ GdkGC *focus_gc);
#ifdef __cplusplus
}
Index: gal/e-table/e-table-item.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-table-item.c,v
retrieving revision 1.231
diff -u -b -B -r1.231 e-table-item.c
--- gal/e-table/e-table-item.c 2 Dec 2003 07:40:27 -0000 1.231
+++ gal/e-table/e-table-item.c 3 Dec 2003 15:39:38 -0000
@@ -2708,7 +2708,7 @@
}
break;
} else {
- /* Let tab send you to the next widget. */
+ /* Let tab send you to the table head. */
return_val = FALSE;
break;
}
Index: gal/e-table/e-table.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-table.c,v
retrieving revision 1.228
diff -u -b -B -r1.228 e-table.c
--- gal/e-table/e-table.c 2 Dec 2003 07:55:14 -0000 1.228
+++ gal/e-table/e-table.c 3 Dec 2003 15:39:46 -0000
@@ -586,10 +586,12 @@
e_table = E_TABLE (container);
if (GTK_CONTAINER (container)->focus_child) {
- gtk_container_set_focus_child (GTK_CONTAINER (container), NULL);
- return FALSE;
+ if (GTK_CONTAINER (container)->focus_child == e_table->table_canvas)
+ gnome_canvas_item_grab_focus (e_table->header_item);
+ else if (GTK_CONTAINER (container)->focus_child == e_table->header_canvas)
+ focus_first_etable_item (e_table->group);
+ return TRUE;
}
-
return gtk_widget_child_focus (GTK_WIDGET (e_table->table_canvas), direction);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]