[gthumb: 4/14] find duplicates: use a simple object instead of a GthTask
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb: 4/14] find duplicates: use a simple object instead of a GthTask
- Date: Fri, 28 Jan 2011 00:53:29 +0000 (UTC)
commit 1acf9003adce0f8b95c14cde51311ab15164037f
Author: Paolo Bacchilega <paobac src gnome org>
Date: Wed Jan 26 22:34:39 2011 +0100
find duplicates: use a simple object instead of a GthTask
extensions/find_duplicates/Makefile.am | 4 +-
.../data/ui/find-duplicates-dialog.ui | 1 +
extensions/find_duplicates/dlg-find-duplicates.c | 14 +-
.../find_duplicates/gth-find-duplicates-task.h | 56 ----
...ind-duplicates-task.c => gth-find-duplicates.c} | 284 +++++++++-----------
extensions/find_duplicates/gth-find-duplicates.h | 56 ++++
6 files changed, 196 insertions(+), 219 deletions(-)
---
diff --git a/extensions/find_duplicates/Makefile.am b/extensions/find_duplicates/Makefile.am
index 7c92916..e4830a4 100644
--- a/extensions/find_duplicates/Makefile.am
+++ b/extensions/find_duplicates/Makefile.am
@@ -10,8 +10,8 @@ libfind_duplicates_la_SOURCES = \
callbacks.h \
dlg-find-duplicates.c \
dlg-find-duplicates.h \
- gth-find-duplicates-task.c \
- gth-find-duplicates-task.h \
+ gth-find-duplicates.c \
+ gth-find-duplicates.h \
main.c
libfind_duplicates_la_CFLAGS = $(GTHUMB_CFLAGS) -I$(top_srcdir) -I$(top_builddir)/gthumb
diff --git a/extensions/find_duplicates/data/ui/find-duplicates-dialog.ui b/extensions/find_duplicates/data/ui/find-duplicates-dialog.ui
index d1f20f7..552e825 100644
--- a/extensions/find_duplicates/data/ui/find-duplicates-dialog.ui
+++ b/extensions/find_duplicates/data/ui/find-duplicates-dialog.ui
@@ -19,6 +19,7 @@
<object class="GtkDialog" id="find_duplicates_dialog">
<property name="border_width">6</property>
<property name="title" translatable="yes">Search for Duplicates</property>
+ <property name="destroy_with_parent">True</property>
<property name="type_hint">dialog</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
diff --git a/extensions/find_duplicates/dlg-find-duplicates.c b/extensions/find_duplicates/dlg-find-duplicates.c
index fecf300..83414c8 100644
--- a/extensions/find_duplicates/dlg-find-duplicates.c
+++ b/extensions/find_duplicates/dlg-find-duplicates.c
@@ -23,7 +23,7 @@
#include <gtk/gtk.h>
#include <gthumb.h>
#include "dlg-find-duplicates.h"
-#include "gth-find-duplicates-task.h"
+#include "gth-find-duplicates.h"
#define GET_WIDGET(name) _gtk_builder_get_widget (data->builder, (name))
@@ -62,15 +62,11 @@ static void
ok_clicked_cb (GtkWidget *widget,
DialogData *data)
{
- GthTask *task;
+ gth_find_duplicates_exec (data->browser,
+ gth_location_chooser_get_current (GTH_LOCATION_CHOOSER (data->location_chooser)),
+ gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("include_subfolder_checkbutton"))),
+ g_list_nth_data (data->general_tests, gtk_combo_box_get_active (GTK_COMBO_BOX (GET_WIDGET ("file_type_combobox")))));
- task = gth_find_duplicates_task_new (data->browser,
- gth_location_chooser_get_current (GTH_LOCATION_CHOOSER (data->location_chooser)),
- gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("include_subfolder_checkbutton"))),
- g_list_nth_data (data->general_tests, gtk_combo_box_get_active (GTK_COMBO_BOX (GET_WIDGET ("file_type_combobox")))));
- gth_browser_exec_task (data->browser, task, FALSE);
-
- g_object_unref (task);
gtk_widget_destroy (data->dialog);
}
diff --git a/extensions/find_duplicates/gth-find-duplicates-task.c b/extensions/find_duplicates/gth-find-duplicates.c
similarity index 83%
rename from extensions/find_duplicates/gth-find-duplicates-task.c
rename to extensions/find_duplicates/gth-find-duplicates.c
index a1ee021..d163871 100644
--- a/extensions/find_duplicates/gth-find-duplicates-task.c
+++ b/extensions/find_duplicates/gth-find-duplicates.c
@@ -24,14 +24,14 @@
#include <glib/gi18n.h>
#include <gthumb.h>
#include <extensions/catalogs/gth-catalog.h>
-#include "gth-find-duplicates-task.h"
+#include "gth-find-duplicates.h"
#define GET_WIDGET(x) (_gtk_builder_get_widget (self->priv->builder, (x)))
#define BUFFER_SIZE 4096
-struct _GthFindDuplicatesTaskPrivate
+struct _GthFindDuplicatesPrivate
{
GthBrowser *browser;
GFile *location;
@@ -40,6 +40,7 @@ struct _GthFindDuplicatesTaskPrivate
GtkBuilder *builder;
GtkWidget *duplicates_list;
GString *attributes;
+ GCancellable *cancellable;
gboolean io_operation;
GthFileSource *file_source;
int n_duplicates;
@@ -90,17 +91,18 @@ duplicated_data_free (DuplicatedData *d_data)
static void
-gth_task_finalize (GObject *object)
+gth_find_duplicates_finalize (GObject *object)
{
- GthFindDuplicatesTask *self;
+ GthFindDuplicates *self;
- self = GTH_FIND_DUPLICATES_TASK (object);
+ self = GTH_FIND_DUPLICATES (object);
g_object_unref (self->priv->location);
_g_object_unref (self->priv->test);
_g_object_unref (self->priv->builder);
if (self->priv->attributes != NULL)
g_string_free (self->priv->attributes, TRUE);
+ g_object_unref (self->priv->cancellable);
_g_object_unref (self->priv->file_source);
_g_object_list_unref (self->priv->files);
_g_object_list_unref (self->priv->directories);
@@ -115,12 +117,78 @@ gth_task_finalize (GObject *object)
}
-static void search_directory (GthFindDuplicatesTask *self,
+static void
+gth_find_duplicates_class_init (GthFindDuplicatesClass *klass)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (GthFindDuplicatesPrivate));
+
+ object_class = (GObjectClass*) klass;
+ object_class->finalize = gth_find_duplicates_finalize;
+}
+
+
+static void
+gth_find_duplicates_init (GthFindDuplicates *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_FIND_DUPLICATES, GthFindDuplicatesPrivate);
+ self->priv->test = NULL;
+ self->priv->builder = NULL;
+ self->priv->attributes = NULL;
+ self->priv->io_operation = FALSE;
+ self->priv->n_duplicates = 0;
+ self->priv->duplicates_size = 0;
+ self->priv->file_source = NULL;
+ self->priv->files = NULL;
+ self->priv->directories = NULL;
+ self->priv->current_directory = NULL;
+ self->priv->current_file = NULL;
+ self->priv->checksum = NULL;
+ self->priv->file_stream = NULL;
+ self->priv->duplicated = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ (GDestroyNotify) duplicated_data_free);
+ self->priv->cancellable = g_cancellable_new ();
+}
+
+
+GType
+gth_find_duplicates_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo type_info = {
+ sizeof (GthFindDuplicatesClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gth_find_duplicates_class_init,
+ NULL,
+ NULL,
+ sizeof (GthFindDuplicates),
+ 0,
+ (GInstanceInitFunc) gth_find_duplicates_init
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "GthFindDuplicates",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+
+static void search_directory (GthFindDuplicates *self,
GFile *directory);
static void
-search_next_directory (GthFindDuplicatesTask *self)
+search_next_directory (GthFindDuplicates *self)
{
GList *first;
@@ -141,7 +209,7 @@ search_next_directory (GthFindDuplicatesTask *self)
}
-static void start_next_checksum (GthFindDuplicatesTask *self);
+static void start_next_checksum (GthFindDuplicates *self);
static void
@@ -149,13 +217,13 @@ file_input_stream_read_ready_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
- GthFindDuplicatesTask *self = user_data;
- GError *error = NULL;
- gssize buffer_size;
+ GthFindDuplicates *self = user_data;
+ GError *error = NULL;
+ gssize buffer_size;
buffer_size = g_input_stream_read_finish (G_INPUT_STREAM (source), result, &error);
if (buffer_size < 0) {
- gth_task_completed (GTH_TASK (self), error);
+ start_next_checksum (self);
return;
}
else if (buffer_size == 0) {
@@ -230,7 +298,7 @@ file_input_stream_read_ready_cb (GObject *source,
self->priv->buffer,
BUFFER_SIZE,
G_PRIORITY_DEFAULT,
- gth_task_get_cancellable (GTH_TASK (self)),
+ self->priv->cancellable,
file_input_stream_read_ready_cb,
self);
}
@@ -241,8 +309,8 @@ read_current_file_ready_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
- GthFindDuplicatesTask *self = user_data;
- GError *error = NULL;
+ GthFindDuplicates *self = user_data;
+ GError *error = NULL;
if (self->priv->file_stream != NULL)
g_object_unref (self->priv->file_stream);
@@ -256,14 +324,14 @@ read_current_file_ready_cb (GObject *source,
self->priv->buffer,
BUFFER_SIZE,
G_PRIORITY_DEFAULT,
- gth_task_get_cancellable (GTH_TASK (self)),
+ self->priv->cancellable,
file_input_stream_read_ready_cb,
self);
}
static void
-start_next_checksum (GthFindDuplicatesTask *self)
+start_next_checksum (GthFindDuplicates *self)
{
GList *link;
char *text;
@@ -293,7 +361,7 @@ start_next_checksum (GthFindDuplicatesTask *self)
g_file_read_async (self->priv->current_file->file,
G_PRIORITY_DEFAULT,
- gth_task_get_cancellable (GTH_TASK (self)),
+ self->priv->cancellable,
read_current_file_ready_cb,
self);
}
@@ -304,12 +372,13 @@ done_func (GObject *object,
GError *error,
gpointer user_data)
{
- GthFindDuplicatesTask *self = user_data;
+ GthFindDuplicates *self = user_data;
self->priv->io_operation = FALSE;
- if (error != NULL) {
- gth_task_completed (GTH_TASK (self), error);
+ if ((error != NULL) && ! g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ _gtk_error_dialog_from_gerror_show (GTK_WINDOW (self->priv->browser), _("Could not perform the operation"), &error);
+ gtk_widget_destroy (GET_WIDGET ("find_duplicates_dialog"));
return;
}
@@ -329,7 +398,7 @@ for_each_file_func (GFile *file,
GFileInfo *info,
gpointer user_data)
{
- GthFindDuplicatesTask *self = user_data;
+ GthFindDuplicates *self = user_data;
GthFileData *file_data;
if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
@@ -349,7 +418,7 @@ start_dir_func (GFile *directory,
GError **error,
gpointer user_data)
{
- GthFindDuplicatesTask *self = user_data;
+ GthFindDuplicates *self = user_data;
if (g_file_equal (directory, self->priv->current_directory))
return DIR_OP_CONTINUE;
@@ -361,8 +430,8 @@ start_dir_func (GFile *directory,
static void
-search_directory (GthFindDuplicatesTask *self,
- GFile *directory)
+search_directory (GthFindDuplicates *self,
+ GFile *directory)
{
char *uri;
char *text;
@@ -397,13 +466,12 @@ static void
find_duplicates_dialog_destroy_cb (GtkWidget *dialog,
gpointer user_data)
{
- GthFindDuplicatesTask *self = user_data;
- gth_task_completed (GTH_TASK (self), NULL);
+ g_object_unref (GTH_FIND_DUPLICATES (user_data));
}
static void
-update_file_list_sensitivity (GthFindDuplicatesTask *self)
+update_file_list_sensitivity (GthFindDuplicates *self)
{
GtkTreeModel *model;
GtkTreeIter iter;
@@ -432,9 +500,9 @@ static void
duplicates_list_view_selection_changed_cb (GtkIconView *iconview,
gpointer user_data)
{
- GthFindDuplicatesTask *self = user_data;
- GtkWidget *duplicates_view;
- int n_selected;
+ GthFindDuplicates *self = user_data;
+ GtkWidget *duplicates_view;
+ int n_selected;
duplicates_view = gth_file_list_get_view (GTH_FILE_LIST (self->priv->duplicates_list));
n_selected = gth_file_selection_get_n_selected (GTH_FILE_SELECTION (duplicates_view));
@@ -488,11 +556,11 @@ file_cellrenderertoggle_toggled_cb (GtkCellRendererToggle *cell_renderer,
char *path,
gpointer user_data)
{
- GthFindDuplicatesTask *self = user_data;
- GtkTreeModel *model;
- GtkTreePath *tree_path;
- GtkTreeIter iter;
- gboolean active;
+ GthFindDuplicates *self = user_data;
+ GtkTreeModel *model;
+ GtkTreePath *tree_path;
+ GtkTreeIter iter;
+ gboolean active;
model = GTK_TREE_MODEL (GET_WIDGET ("files_liststore"));
tree_path = gtk_tree_path_new_from_string (path);
@@ -511,7 +579,7 @@ file_cellrenderertoggle_toggled_cb (GtkCellRendererToggle *cell_renderer,
static GList *
-get_selected_files (GthFindDuplicatesTask *self)
+get_selected_files (GthFindDuplicates *self)
{
GtkTreeModel *model;
GtkTreeIter iter;
@@ -543,10 +611,10 @@ static void
view_button_clicked_cb (GtkWidget *button,
gpointer user_data)
{
- GthFindDuplicatesTask *self = user_data;
- GList *files;
- GthCatalog *catalog;
- GFile *catalog_file;
+ GthFindDuplicates *self = user_data;
+ GList *files;
+ GthCatalog *catalog;
+ GFile *catalog_file;
files = get_selected_files (self);
if (files == NULL)
@@ -566,8 +634,8 @@ view_button_clicked_cb (GtkWidget *button,
static void
-select_all_files (GthFindDuplicatesTask *self,
- gboolean active)
+select_all_files (GthFindDuplicates *self,
+ gboolean active)
{
GtkTreeModel *model;
GtkTreeIter iter;
@@ -588,7 +656,7 @@ static void
select_all_button_clicked_cb (GtkWidget *button,
gpointer user_data)
{
- select_all_files (GTH_FIND_DUPLICATES_TASK (user_data), TRUE);
+ select_all_files (GTH_FIND_DUPLICATES (user_data), TRUE);
}
@@ -596,18 +664,29 @@ static void
unselect_all_button_clicked_cb (GtkWidget *button,
gpointer user_data)
{
- select_all_files (GTH_FIND_DUPLICATES_TASK (user_data), FALSE);
+ select_all_files (GTH_FIND_DUPLICATES (user_data), FALSE);
}
-static void
-gth_find_duplicates_task_exec (GthTask *base)
+void
+gth_find_duplicates_exec (GthBrowser *browser,
+ GFile *location,
+ gboolean recursive,
+ const char *filter)
{
- GthFindDuplicatesTask *self = (GthFindDuplicatesTask *) base;
- const char *test_attributes;
+ GthFindDuplicates *self;
+ const char *test_attributes;
+
+ self = (GthFindDuplicates *) g_object_new (GTH_TYPE_FIND_DUPLICATES, NULL);
+
+ self->priv->browser = browser;
+ self->priv->location = g_object_ref (location);
+ self->priv->recursive = recursive;
+ if (filter != NULL)
+ self->priv->test = gth_main_get_registered_object (GTH_TYPE_TEST, filter);
self->priv->file_source = gth_main_get_file_source (self->priv->location);
- gth_file_source_set_cancellable (self->priv->file_source, gth_task_get_cancellable (GTH_TASK (self)));
+ gth_file_source_set_cancellable (self->priv->file_source, self->priv->cancellable);
self->priv->attributes = g_string_new (eel_gconf_get_boolean (PREF_FAST_FILE_TYPE, TRUE) ? GFILE_STANDARD_ATTRIBUTES_WITH_FAST_CONTENT_TYPE : GFILE_STANDARD_ATTRIBUTES_WITH_CONTENT_TYPE);
g_string_append (self->priv->attributes, ",gth::file::display-size");
@@ -635,8 +714,8 @@ gth_find_duplicates_task_exec (GthTask *base)
GET_WIDGET ("find_duplicates_dialog"));
g_signal_connect_swapped (GET_WIDGET ("stop_button"),
"clicked",
- G_CALLBACK (gth_task_cancel),
- self);
+ G_CALLBACK (g_cancellable_cancel),
+ self->priv->cancellable);
g_signal_connect (G_OBJECT (gth_file_list_get_view (GTH_FILE_LIST (self->priv->duplicates_list))),
"selection_changed",
G_CALLBACK (duplicates_list_view_selection_changed_cb),
@@ -659,106 +738,7 @@ gth_find_duplicates_task_exec (GthTask *base)
self);
gtk_widget_show (GET_WIDGET ("find_duplicates_dialog"));
- gth_task_dialog (GTH_TASK (self), TRUE, GET_WIDGET ("find_duplicates_dialog"));
+ gtk_window_set_transient_for (GTK_WINDOW (GET_WIDGET ("find_duplicates_dialog")), GTK_WINDOW (self->priv->browser));
search_directory (self, self->priv->location);
}
-
-
-static void
-gth_find_duplicates_task_cancelled (GthTask *self)
-{
- /* FIXME
- if (! GTH_FIND_DUPLICATES_TASK (self)->priv->io_operation)
- gth_task_completed (self, g_error_new_literal (GTH_TASK_ERROR, GTH_TASK_ERROR_CANCELLED, ""));
- */
-}
-
-
-static void
-gth_find_duplicates_task_class_init (GthFindDuplicatesTaskClass *class)
-{
- GObjectClass *object_class;
- GthTaskClass *task_class;
-
- parent_class = g_type_class_peek_parent (class);
-
- object_class = (GObjectClass*) class;
- object_class->finalize = gth_task_finalize;
-
- task_class = (GthTaskClass*) class;
- task_class->exec = gth_find_duplicates_task_exec;
- task_class->cancelled = gth_find_duplicates_task_cancelled;
-}
-
-
-static void
-gth_find_duplicates_task_init (GthFindDuplicatesTask *self)
-{
- self->priv = g_new0 (GthFindDuplicatesTaskPrivate, 1);
- self->priv->test = NULL;
- self->priv->builder = NULL;
- self->priv->attributes = NULL;
- self->priv->io_operation = FALSE;
- self->priv->n_duplicates = 0;
- self->priv->duplicates_size = 0;
- self->priv->file_source = NULL;
- self->priv->files = NULL;
- self->priv->directories = NULL;
- self->priv->current_directory = NULL;
- self->priv->current_file = NULL;
- self->priv->checksum = NULL;
- self->priv->file_stream = NULL;
- self->priv->duplicated = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- (GDestroyNotify) duplicated_data_free);
-}
-
-
-GType
-gth_find_duplicates_task_get_type (void)
-{
- static GType type = 0;
-
- if (! type) {
- GTypeInfo type_info = {
- sizeof (GthFindDuplicatesTaskClass),
- NULL,
- NULL,
- (GClassInitFunc) gth_find_duplicates_task_class_init,
- NULL,
- NULL,
- sizeof (GthFindDuplicatesTask),
- 0,
- (GInstanceInitFunc) gth_find_duplicates_task_init
- };
-
- type = g_type_register_static (GTH_TYPE_TASK,
- "GthFindDuplicatesTask",
- &type_info,
- 0);
- }
-
- return type;
-}
-
-
-GthTask *
-gth_find_duplicates_task_new (GthBrowser *browser,
- GFile *location,
- gboolean recursive,
- const char *filter)
-{
- GthFindDuplicatesTask *self;
-
- self = (GthFindDuplicatesTask *) g_object_new (GTH_TYPE_FIND_DUPLICATES_TASK, NULL);
-
- self->priv->browser = browser;
- self->priv->location = g_object_ref (location);
- self->priv->recursive = recursive;
- if (filter != NULL)
- self->priv->test = gth_main_get_registered_object (GTH_TYPE_TEST, filter);
-
- return (GthTask*) self;
-}
diff --git a/extensions/find_duplicates/gth-find-duplicates.h b/extensions/find_duplicates/gth-find-duplicates.h
new file mode 100644
index 0000000..9f456ef
--- /dev/null
+++ b/extensions/find_duplicates/gth-find-duplicates.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GTH_FIND_DUPLICATES_H
+#define GTH_FIND_DUPLICATES_H
+
+#include <glib-object.h>
+#include <gthumb.h>
+
+#define GTH_TYPE_FIND_DUPLICATES (gth_find_duplicates_get_type ())
+#define GTH_FIND_DUPLICATES(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTH_TYPE_FIND_DUPLICATES, GthFindDuplicates))
+#define GTH_FIND_DUPLICATES_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTH_TYPE_FIND_DUPLICATES, GthFindDuplicatesClass))
+#define GTH_IS_FIND_DUPLICATES_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTH_TYPE_FIND_DUPLICATES))
+#define GTH_IS_FIND_DUPLICATES_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTH_TYPE_FIND_DUPLICATES))
+#define GTH_FIND_DUPLICATES_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GTH_TYPE_FIND_DUPLICATES, GthFindDuplicatesClass))
+
+typedef struct _GthFindDuplicates GthFindDuplicates;
+typedef struct _GthFindDuplicatesPrivate GthFindDuplicatesPrivate;
+typedef struct _GthFindDuplicatesClass GthFindDuplicatesClass;
+
+struct _GthFindDuplicates
+{
+ GObject __parent;
+ GthFindDuplicatesPrivate *priv;
+};
+
+struct _GthFindDuplicatesClass
+{
+ GObjectClass __parent_class;
+};
+
+GType gth_find_duplicates_get_type (void) G_GNUC_CONST;
+void gth_find_duplicates_exec (GthBrowser *browser,
+ GFile *location,
+ gboolean recursive,
+ const char *filter);
+
+#endif /* GTH_FIND_DUPLICATES_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]