[gtranslator] Add Profile quick selector. Fixes bug #609695.
- From: Ignacio Casal Quinteiro <icq src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtranslator] Add Profile quick selector. Fixes bug #609695.
- Date: Fri, 19 Feb 2010 13:38:24 +0000 (UTC)
commit b1d5afa0a6f7beaa1385425601fe11546a2d4b76
Author: Ignacio Casal Quinteiro <icq gnome org>
Date: Fri Feb 19 14:00:43 2010 +0100
Add Profile quick selector. Fixes bug #609695.
src/Makefile.am | 2 +
src/gtr-header.c | 74 ++++++++++---
src/gtr-header.h | 103 +++++++++----------
src/gtr-marshal.list | 1 +
src/gtr-window.c | 276 +++++++++++++++++++++++++++++++++++++++++++++++---
5 files changed, 373 insertions(+), 83 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 7d9440a..b37166f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -124,6 +124,8 @@ libgtranslator_la_SOURCES = \
gtr-context.c \
gtr-profile-manager.h \
gtr-profile-manager.c \
+ gtr-status-combo-box.h \
+ gtr-status-combo-box.c \
$(INST_H_FILES)
libgtranslator_la_LIBADD = \
diff --git a/src/gtr-header.c b/src/gtr-header.c
index fc4f5ca..66589c0 100644
--- a/src/gtr-header.c
+++ b/src/gtr-header.c
@@ -39,14 +39,16 @@
GtrHeaderPrivate))
G_DEFINE_TYPE (GtrHeader, gtr_header, GTR_TYPE_MSG)
- struct _GtrHeaderPrivate
- {
- gint nplurals;
- };
- static void
- gtr_header_set_field (GtrHeader * header,
- const gchar * field, const gchar * data)
+struct _GtrHeaderPrivate
+{
+ gint nplurals;
+ GtrProfile *profile;
+};
+
+static void
+gtr_header_set_field (GtrHeader * header,
+ const gchar * field, const gchar * data)
{
gchar *msgstr;
@@ -72,13 +74,18 @@ parse_nplurals (GtrHeader * header)
if (gtr_prefs_manager_get_use_profile_values () || !plural_forms)
{
const gchar *plural_form = NULL;
- GtrProfileManager *prof_manager;
GtrProfile *profile;
- /* TODO: Manage this also per document */
- prof_manager = gtr_profile_manager_get_default ();
- profile = gtr_profile_manager_get_active_profile (prof_manager);
- g_object_unref (prof_manager);
+ if (header->priv->profile != NULL)
+ profile = header->priv->profile;
+ else
+ {
+ GtrProfileManager *prof_manager;
+
+ prof_manager = gtr_profile_manager_get_default ();
+ profile = gtr_profile_manager_get_active_profile (prof_manager);
+ g_object_unref (prof_manager);
+ }
if (profile)
plural_form = gtr_profile_get_plural_forms (profile);
@@ -127,12 +134,21 @@ gtr_header_init (GtrHeader * header)
header->priv = GTR_HEADER_GET_PRIVATE (header);
header->priv->nplurals = -1;
+ header->priv->profile = NULL;
}
static void
-gtr_header_finalize (GObject * object)
+gtr_header_dispose (GObject * object)
{
- G_OBJECT_CLASS (gtr_header_parent_class)->finalize (object);
+ GtrHeader *header = GTR_HEADER (object);
+
+ if (header->priv->profile != NULL)
+ {
+ g_object_unref (header->priv->profile);
+ header->priv->profile = NULL;
+ }
+
+ G_OBJECT_CLASS (gtr_header_parent_class)->dispose (object);
}
static void
@@ -142,7 +158,7 @@ gtr_header_class_init (GtrHeaderClass * klass)
g_type_class_add_private (klass, sizeof (GtrHeaderPrivate));
- object_class->finalize = gtr_header_finalize;
+ object_class->dispose = gtr_header_dispose;
}
/* Public methods */
@@ -502,7 +518,10 @@ set_profile_values (GtrHeader *header, GtrProfileManager *prof_manager)
{
GtrProfile *active_profile;
- active_profile = gtr_profile_manager_get_active_profile (prof_manager);
+ if (header->priv->profile != NULL)
+ active_profile = header->priv->profile;
+ else
+ active_profile = gtr_profile_manager_get_active_profile (prof_manager);
if (gtr_prefs_manager_get_use_profile_values () && active_profile != NULL)
{
@@ -555,7 +574,11 @@ update_comments (GtrHeader *header, const gchar *comments,
gchar *current_year;
gint i;
- active_profile = gtr_profile_manager_get_active_profile (prof_manager);
+ if (header->priv->profile != NULL)
+ active_profile = header->priv->profile;
+ else
+ active_profile = gtr_profile_manager_get_active_profile (prof_manager);
+
current_year = gtr_utils_get_current_year ();
/* Save the previous translator to update the header's comment */
@@ -664,3 +687,20 @@ gtr_header_update_header (GtrHeader * header)
g_object_unref (prof_manager);
}
+
+void
+gtr_header_set_profile (GtrHeader *header,
+ GtrProfile *profile)
+{
+ g_return_if_fail (GTR_IS_HEADER (header));
+
+ header->priv->profile = g_object_ref (profile);
+}
+
+GtrProfile *
+gtr_header_get_profile (GtrHeader *header)
+{
+ g_return_val_if_fail (GTR_IS_HEADER (header), NULL);
+
+ return header->priv->profile;
+}
diff --git a/src/gtr-header.h b/src/gtr-header.h
index 27c587f..9f83070 100644
--- a/src/gtr-header.h
+++ b/src/gtr-header.h
@@ -28,12 +28,11 @@
#include <glib-object.h>
#include "gtr-msg.h"
+#include "gtr-profile.h"
G_BEGIN_DECLS
-/*
- * Utility Macros
- */
+/* Utility Macros */
#define GTR_TYPE_HEADER (gtr_header_get_type ())
#define GTR_HEADER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_HEADER, GtrHeader))
@@ -45,9 +44,7 @@ G_BEGIN_DECLS
/* Private structure type */
typedef struct _GtrHeaderPrivate GtrHeaderPrivate;
-/*
- * Main object structure
- */
+/* Main object structure */
typedef struct _GtrHeader GtrHeader;
struct _GtrHeader
@@ -58,9 +55,7 @@ struct _GtrHeader
GtrHeaderPrivate *priv;
};
-/*
- * Class definition
- */
+/* Class definition */
typedef struct _GtrHeaderClass GtrHeaderClass;
struct _GtrHeaderClass
@@ -68,64 +63,66 @@ struct _GtrHeaderClass
GtrMsgClass parent_class;
};
-/*
- * Public methods
- */
-GType
-gtr_header_get_type (void)
- G_GNUC_CONST;
+/* Public methods */
+GType gtr_header_get_type (void) G_GNUC_CONST;
- GType gtr_header_register_type (GTypeModule * module);
+GtrHeader *gtr_header_new (po_message_iterator_t iter,
+ po_message_t message);
- GtrHeader *gtr_header_new (po_message_iterator_t iter,
- po_message_t message);
+const gchar *gtr_header_get_comments (GtrHeader *header);
+void gtr_header_set_comments (GtrHeader *header,
+ const gchar *comments);
- const gchar *gtr_header_get_comments (GtrHeader * header);
- void gtr_header_set_comments (GtrHeader * header,
- const gchar * comments);
+gchar *gtr_header_get_prj_id_version (GtrHeader *header);
+void gtr_header_set_prj_id_version (GtrHeader *header,
+ const gchar *prj_id_version);
- gchar *gtr_header_get_prj_id_version (GtrHeader * header);
- void gtr_header_set_prj_id_version (GtrHeader * header,
- const gchar * prj_id_version);
+gchar *gtr_header_get_rmbt (GtrHeader *header);
+void gtr_header_set_rmbt (GtrHeader *header,
+ const gchar *rmbt);
- gchar *gtr_header_get_rmbt (GtrHeader * header);
- void gtr_header_set_rmbt (GtrHeader * header, const gchar * rmbt);
+gchar *gtr_header_get_pot_date (GtrHeader *header);
+void gtr_header_set_pot_date (GtrHeader *header,
+ const gchar *pot_date);
- gchar *gtr_header_get_pot_date (GtrHeader * header);
- void gtr_header_set_pot_date (GtrHeader * header,
- const gchar * pot_date);
+gchar *gtr_header_get_po_date (GtrHeader *header);
+void gtr_header_set_po_date (GtrHeader *header,
+ const gchar *po_date);
- gchar *gtr_header_get_po_date (GtrHeader * header);
- void gtr_header_set_po_date (GtrHeader * header, const gchar * po_date);
+gchar *gtr_header_get_translator (GtrHeader *header);
+gchar *gtr_header_get_tr_email (GtrHeader *header);
+void gtr_header_set_translator (GtrHeader *header,
+ const gchar *name,
+ const gchar *email);
- gchar *gtr_header_get_translator (GtrHeader * header);
- gchar *gtr_header_get_tr_email (GtrHeader * header);
- void gtr_header_set_translator (GtrHeader * header,
- const gchar * name, const gchar * email);
+gchar *gtr_header_get_language (GtrHeader *header);
+gchar *gtr_header_get_lg_email (GtrHeader *header);
+void gtr_header_set_language (GtrHeader *header,
+ const gchar *language,
+ const gchar *email);
- gchar *gtr_header_get_language (GtrHeader * header);
- gchar *gtr_header_get_lg_email (GtrHeader * header);
- void gtr_header_set_language (GtrHeader * header,
- const gchar * language,
- const gchar * email);
+gchar *gtr_header_get_mime_version (GtrHeader *header);
+void gtr_header_set_mime_version (GtrHeader *header,
+ const gchar *mime_version);
- gchar *gtr_header_get_mime_version (GtrHeader * header);
- void gtr_header_set_mime_version (GtrHeader * header,
- const gchar * mime_version);
+gchar *gtr_header_get_charset (GtrHeader *header);
+void gtr_header_set_charset (GtrHeader *header,
+ const gchar *charset);
- gchar *gtr_header_get_charset (GtrHeader * header);
- void gtr_header_set_charset (GtrHeader * header, const gchar * charset);
+gchar *gtr_header_get_encoding (GtrHeader *header);
+void gtr_header_set_encoding (GtrHeader *header,
+ const gchar *encoding);
- gchar *gtr_header_get_encoding (GtrHeader * header);
- void gtr_header_set_encoding (GtrHeader * header,
- const gchar * encoding);
+gchar *gtr_header_get_plural_forms (GtrHeader *header);
+void gtr_header_set_plural_forms (GtrHeader *header,
+ const gchar *plural_forms);
+gint gtr_header_get_nplurals (GtrHeader *header);
- gchar *gtr_header_get_plural_forms (GtrHeader * header);
- void gtr_header_set_plural_forms (GtrHeader * header,
- const gchar * plural_forms);
- gint gtr_header_get_nplurals (GtrHeader * header);
+void gtr_header_update_header (GtrHeader *header);
- void gtr_header_update_header (GtrHeader * header);
+void gtr_header_set_profile (GtrHeader *header,
+ GtrProfile *profile);
+GtrProfile *gtr_header_get_profile (GtrHeader *header);
G_END_DECLS
diff --git a/src/gtr-marshal.list b/src/gtr-marshal.list
index c26d68c..df5a2f2 100644
--- a/src/gtr-marshal.list
+++ b/src/gtr-marshal.list
@@ -1 +1,2 @@
BOOLEAN:NONE
+VOID:OBJECT,OBJECT
diff --git a/src/gtr-window.c b/src/gtr-window.c
index 860cef1..3d52a7c 100644
--- a/src/gtr-window.c
+++ b/src/gtr-window.c
@@ -38,6 +38,7 @@
#include "gtr-utils.h"
#include "gtr-window.h"
#include "gtr-profile-manager.h"
+#include "gtr-status-combo-box.h"
#include "egg-toolbars-model.h"
#include "egg-toolbar-editor.h"
@@ -62,6 +63,8 @@
#define GTR_STOCK_FUZZY_UNTRANS_NEXT "gtranslator-fuzzy-untranslated-next"
#define GTR_STOCK_FUZZY_UNTRANS_PREV "gtranslator-fuzzy-untranslated-prev"
+#define PROFILE_DATA "GtrWidnowProfileData"
+
#define GTR_WINDOW_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ( \
(object), \
GTR_TYPE_WINDOW, \
@@ -105,6 +108,7 @@ struct _GtrWindowPrivate
GdkWindowState window_state;
GtrProfileManager *prof_manager;
+ GtkWidget *profile_combo;
gboolean destroy_has_run : 1;
};
@@ -275,6 +279,10 @@ static const GtkActionEntry entries[] = {
G_CALLBACK (gtr_actions_documents_next_document)}
};
+static void profile_combo_changed (GtrStatusComboBox *combo,
+ GtkMenuItem *item,
+ GtrWindow *window);
+
/*
* Dock funcs
*/
@@ -972,9 +980,12 @@ notebook_switch_page (GtkNotebook * nb,
GList *msg;
GtrView *view;
GtrPo *po;
+ GtrHeader *header;
+ GtrProfile *profile;
gint n_pages;
GtkAction *action;
gchar *action_name;
+ GList *profile_items, *l;
tab = GTR_TAB (gtk_notebook_get_nth_page (nb, page_num));
if (tab == window->priv->active_tab)
@@ -1005,6 +1016,34 @@ notebook_switch_page (GtkNotebook * nb,
msg = gtr_po_get_current_message (po);
gtr_window_update_statusbar_message_count (tab, msg->data, window);
+ header = gtr_po_get_header (po);
+ profile = gtr_header_get_profile (header);
+
+ if (profile == NULL)
+ profile = gtr_profile_manager_get_active_profile (window->priv->prof_manager);
+
+ profile_items = gtr_status_combo_box_get_items (GTR_STATUS_COMBO_BOX (window->priv->profile_combo));
+
+ for (l = profile_items; l != NULL; l = g_list_next (l))
+ {
+ GtrProfile *item_profile;
+
+ item_profile = GTR_PROFILE (g_object_get_data (G_OBJECT (l->data),
+ PROFILE_DATA));
+
+ if (item_profile == profile)
+ {
+ g_signal_handlers_block_by_func (window->priv->profile_combo,
+ profile_combo_changed,
+ window);
+ gtr_status_combo_box_set_item (GTR_STATUS_COMBO_BOX (window->priv->profile_combo),
+ GTK_MENU_ITEM (l->data));
+ g_signal_handlers_unblock_by_func (window->priv->profile_combo,
+ profile_combo_changed,
+ window);
+ }
+ }
+
/* activate the right item in the documents menu */
action_name = g_strdup_printf ("Tab_%d", page_num);
action =
@@ -1029,15 +1068,17 @@ notebook_page_removed (GtkNotebook * notebook,
{
gint n_pages;
- /*
- * Set the window title
- */
+ /* Set the window title */
n_pages = gtk_notebook_get_n_pages (notebook);
if (n_pages == 1)
set_window_title (window, TRUE);
else
set_window_title (window, FALSE);
+ /* Hide the profile combo */
+ if (n_pages == 0)
+ gtk_widget_hide (window->priv->profile_combo);
+
update_documents_list_menu (window);
}
@@ -1128,15 +1169,16 @@ notebook_tab_added (GtkNotebook * notebook,
g_return_if_fail (GTR_IS_TAB (tab));
- /*
- * Set the window title
- */
+ /* Set the window title */
n_pages = gtk_notebook_get_n_pages (notebook);
if (n_pages == 1)
set_window_title (window, TRUE);
else
set_window_title (window, FALSE);
+ /* Show the profile combo */
+ gtk_widget_show (window->priv->profile_combo);
+
views = gtr_tab_get_all_views (tab, FALSE, TRUE);
while (views)
@@ -1170,8 +1212,8 @@ notebook_tab_added (GtkNotebook * notebook,
update_documents_list_menu (window);
- gtr_plugins_engine_update_plugins_ui
- (gtr_plugins_engine_get_default (), window, FALSE);
+ gtr_plugins_engine_update_plugins_ui (gtr_plugins_engine_get_default (),
+ window, FALSE);
}
void
@@ -1376,6 +1418,206 @@ disconnect_proxy_cb (GtkUIManager * manager,
}
static void
+profile_combo_changed (GtrStatusComboBox *combo,
+ GtkMenuItem *item,
+ GtrWindow *window)
+{
+ GtrTab *tab;
+ GtrPo *po;
+ GtrHeader *header;
+ GtrProfile *profile;
+
+ tab = gtr_window_get_active_tab (window);
+
+ if (tab == NULL)
+ return;
+
+ po = gtr_tab_get_po (tab);
+ header = gtr_po_get_header (po);
+
+ profile = GTR_PROFILE (g_object_get_data (G_OBJECT (item), PROFILE_DATA));
+
+ gtr_header_set_profile (header, profile);
+}
+
+static void
+fill_profile_combo (GtrWindow *window)
+{
+ GSList *profiles, *l;
+ GtkWidget *menu_item;
+ const gchar *name;
+
+ profiles = gtr_profile_manager_get_profiles (window->priv->prof_manager);
+
+ for (l = profiles; l != NULL; l = g_slist_next (l))
+ {
+ GtrProfile *profile = GTR_PROFILE (l->data);
+
+ name = gtr_profile_get_name (profile);
+ menu_item = gtk_menu_item_new_with_label (name);
+ gtk_widget_show (menu_item);
+
+ g_object_set_data (G_OBJECT (menu_item), PROFILE_DATA, profile);
+ gtr_status_combo_box_add_item (GTR_STATUS_COMBO_BOX (window->priv->profile_combo),
+ GTK_MENU_ITEM (menu_item),
+ name);
+ }
+
+ if (profiles == NULL)
+ {
+ name = _("No profile");
+
+ g_object_set_data (G_OBJECT (menu_item), PROFILE_DATA, NULL);
+ gtr_status_combo_box_add_item (GTR_STATUS_COMBO_BOX (window->priv->profile_combo),
+ GTK_MENU_ITEM (menu_item),
+ name);
+ }
+}
+
+static void
+create_statusbar (GtrWindow *window,
+ GtkWidget *box)
+{
+ window->priv->statusbar = gtr_statusbar_new ();
+
+ gtk_box_pack_end (GTK_BOX (box), window->priv->statusbar, TRUE, TRUE, 0);
+
+ gtk_widget_show (window->priv->statusbar);
+
+ window->priv->profile_combo = gtr_status_combo_box_new (_("Profile"));
+ gtk_box_pack_start (GTK_BOX (window->priv->statusbar),
+ window->priv->profile_combo, FALSE, TRUE, 0);
+
+ g_signal_connect (window->priv->profile_combo, "changed",
+ G_CALLBACK (profile_combo_changed), window);
+
+ fill_profile_combo (window);
+}
+
+static void
+on_active_profile_changed (GtrProfileManager *manager,
+ GtrProfile *profile,
+ GtrWindow *window)
+{
+ GList *items, *l;
+ GtrTab *tab;
+ GtrPo *po;
+ GtrHeader *header;
+
+ tab = gtr_window_get_active_tab (window);
+
+ if (tab == NULL)
+ return;
+
+ po = gtr_tab_get_po (tab);
+ header = gtr_po_get_header (po);
+
+ items = gtr_status_combo_box_get_items (GTR_STATUS_COMBO_BOX (window->priv->profile_combo));
+
+ for (l = items; l != NULL; l = g_list_next (l))
+ {
+ GtkMenuItem *menu_item;
+ GtrProfile *item_profile;
+
+ menu_item = GTK_MENU_ITEM (l->data);
+
+ item_profile = GTR_PROFILE (g_object_get_data (G_OBJECT (menu_item),
+ PROFILE_DATA));
+
+ if (item_profile == profile && gtr_header_get_profile (header) == NULL)
+ {
+ g_signal_handlers_block_by_func (window->priv->profile_combo,
+ profile_combo_changed, window);
+ gtr_status_combo_box_set_item (GTR_STATUS_COMBO_BOX (window->priv->profile_combo),
+ menu_item);
+ g_signal_handlers_unblock_by_func (window->priv->profile_combo,
+ profile_combo_changed, window);
+ }
+ }
+}
+
+static void
+on_profile_added (GtrProfileManager *manager,
+ GtrProfile *profile,
+ GtrWindow *window)
+{
+ GtkMenuItem *menu_item;
+ GList *items;
+
+ /* check that the item is not a "No profile" item */
+ items = gtr_status_combo_box_get_items (GTR_STATUS_COMBO_BOX (window->priv->profile_combo));
+
+ if (items->next == NULL &&
+ (g_object_get_data (G_OBJECT (items->data), PROFILE_DATA) == NULL))
+ {
+ menu_item = GTK_MENU_ITEM (items->data);
+
+ gtk_menu_item_set_label (menu_item,
+ gtr_profile_get_name (profile));
+
+ g_object_set_data (G_OBJECT (menu_item), PROFILE_DATA, profile);
+ }
+ else
+ {
+ const gchar *name;
+
+ name = gtr_profile_get_name (profile);
+ menu_item = GTK_MENU_ITEM (gtk_menu_item_new_with_label (name));
+ gtk_widget_show (GTK_WIDGET (menu_item));
+
+ g_object_set_data (G_OBJECT (menu_item), PROFILE_DATA, profile);
+ gtr_status_combo_box_add_item (GTR_STATUS_COMBO_BOX (window->priv->profile_combo),
+ menu_item, name);
+ }
+}
+
+static void
+on_profile_removed (GtrProfileManager *manager,
+ GtrProfile *profile,
+ GtrWindow *window)
+{
+ GList *items, *l;
+
+ items = gtr_status_combo_box_get_items (GTR_STATUS_COMBO_BOX (window->priv->profile_combo));
+
+ for (l = items; l != NULL; l = g_list_next (l))
+ {
+ GtrProfile *prof;
+
+ prof = GTR_PROFILE (g_object_get_data (G_OBJECT (l->data), PROFILE_DATA));
+ if (prof == profile)
+ gtr_status_combo_box_remove_item (GTR_STATUS_COMBO_BOX (window->priv->profile_combo),
+ GTK_MENU_ITEM (l->data));
+ }
+}
+
+static void
+on_profile_modified (GtrProfileManager *manager,
+ GtrProfile *old_profile,
+ GtrProfile *new_profile,
+ GtrWindow *window)
+{
+ GList *items, *l;
+
+ items = gtr_status_combo_box_get_items (GTR_STATUS_COMBO_BOX (window->priv->profile_combo));
+
+ for (l = items; l != NULL; l = g_list_next (l))
+ {
+ GtrProfile *profile;
+
+ profile = GTR_PROFILE (g_object_get_data (G_OBJECT (l->data), PROFILE_DATA));
+ if (profile == old_profile)
+ {
+ gtk_menu_item_set_label (GTK_MENU_ITEM (l->data),
+ gtr_profile_get_name (new_profile));
+ g_object_set_data (G_OBJECT (l->data), PROFILE_DATA, new_profile);
+
+ return;
+ }
+ }
+}
+
+static void
gtr_window_draw (GtrWindow * window)
{
GtkWidget *hbox; //Statusbar and progressbar
@@ -1519,11 +1761,7 @@ gtr_window_draw (GtrWindow * window)
gtk_widget_show (hbox);
/* statusbar & progress bar */
- window->priv->statusbar = gtr_statusbar_new ();
-
- gtk_box_pack_end (GTK_BOX (hbox), window->priv->statusbar, TRUE, TRUE, 0);
-
- gtk_widget_show (priv->statusbar);
+ create_statusbar (window, hbox);
}
static void
@@ -1537,8 +1775,20 @@ gtr_window_init (GtrWindow * window)
window->priv = GTR_WINDOW_GET_PRIVATE (window);
window->priv->destroy_has_run = FALSE;
+
+ /* Profile manager */
window->priv->prof_manager = gtr_profile_manager_get_default ();
+ g_signal_connect (window->priv->prof_manager, "active-profile-changed",
+ G_CALLBACK (on_active_profile_changed), window);
+ g_signal_connect (window->priv->prof_manager, "profile-added",
+ G_CALLBACK (on_profile_added), window);
+ g_signal_connect (window->priv->prof_manager, "profile-removed",
+ G_CALLBACK (on_profile_removed), window);
+ g_signal_connect (window->priv->prof_manager, "profile-modified",
+ G_CALLBACK (on_profile_modified), window);
+
+ /* set up the window widgets */
gtr_window_draw (window);
set_sensitive_according_to_window (window);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]