[nautilus-actions] Improve writability management of provider and item
- From: Pierre Wieser <pwieser src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [nautilus-actions] Improve writability management of provider and item
- Date: Mon, 14 Dec 2009 18:47:34 +0000 (UTC)
commit ccc0e96a59216c3b988b78ae133f60385348a74d
Author: Pierre Wieser <pwieser trychlos org>
Date: Sun Dec 13 02:13:19 2009 +0100
Improve writability management of provider and item
ChangeLog | 14 +++++++
TODO | 17 ++++----
nautilus-actions/api/na-iio-provider.h | 14 ++++++-
nautilus-actions/nact/nact-iactions-list.c | 11 ++---
nautilus-actions/nact/nact-main-menubar.c | 42 +++++++++++--------
nautilus-actions/nact/nact-window.c | 57 ++++++++++++++++----------
nautilus-actions/nact/nact-window.h | 3 +-
nautilus-actions/runtime/na-io-provider.c | 59 ++++++++++++++++++++++++----
nautilus-actions/runtime/na-io-provider.h | 16 ++++----
nautilus-actions/runtime/na-pivot.c | 28 +++++++++++++
nautilus-actions/runtime/na-pivot.h | 1 +
11 files changed, 188 insertions(+), 74 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 58a0761..7305113 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,20 @@
2009-12-12 Pierre Wieser <pwieser trychlos org>
* nautilus-actions/nact/nact-window.c:
+ * nautilus-actions/nact/nact-window.h
+ (nact_window_is_lockdown): Removed function.
+ (nact_window_is_writable_provider, nact_window_has_writable_providers):
+ New functions.
+
+ * nautilus-actions/runtime/na-io-provider.c:
+ * nautilus-actions/runtime/na-io-provider.h
+ (na_io_provider_is_willing_to_write): New function.
+
+ * nautilus-actions/runtime/na-pivot.c:
+ * nautilus-actions/runtime/na-pivot.h (na_pivot_has_writable_providers):
+ New function.
+
+ * nautilus-actions/nact/nact-window.c:
* nautilus-actions/nact/nact-window.h (nact_window_is_lockdown):
Check if the provider of the current item is locked down.
diff --git a/TODO b/TODO
index ae5cf0a..5b2a01f 100644
--- a/TODO
+++ b/TODO
@@ -99,14 +99,13 @@
- desktop provider: fix default toolbar label
-- lockdown:
- all entry fields should be readonly
+- readonly_item or locked_provider:
+ all entry/button fields should be readonly
-- actually, each provider may be unwritable
- a) because it returns FALSE on na_io_provider_is_writable
- b) because the sysadmin has put a special key in GConf to lock this provider
- So:
- - each provider must be adressable by an id
- - we have mandatory/io-provider/id/lockdown key
+- add get_id/get_version to module api
-- add a get_version to module api
+- when duplicating a profile
+ na_object_item_is_readonly: assertion `NA_IS_OBJECT_ITEM( item )' failed
+ GLib-GObject-WARNING **: invalid cast from `NAObjectProfile' to `NAObjectItem'
+
+- new/edit options depend of writability status of the parent menu if any
diff --git a/nautilus-actions/api/na-iio-provider.h b/nautilus-actions/api/na-iio-provider.h
index 1fe2cac..014f4b8 100644
--- a/nautilus-actions/api/na-iio-provider.h
+++ b/nautilus-actions/api/na-iio-provider.h
@@ -73,7 +73,9 @@ typedef struct {
* To avoid any collision, the IO provider id is allocated by the
* Nautilus-Actions maintainer team. If you wish develop a new IO
* provider, and so need a new provider id, please contact the
- * maintainers (see nautilus-actions.doap)
+ * maintainers (see nautilus-actions.doap).
+ *
+ * The provider must implement this function.
*/
gchar * ( *get_id ) ( const NAIIOProvider *instance );
@@ -82,6 +84,8 @@ typedef struct {
* @instance: the #NAIIOProvider provider.
*
* Returns: the version of this API supported by the IO provider.
+ *
+ * The provider must implement this function.
*/
guint ( *get_version ) ( const NAIIOProvider *instance );
@@ -110,7 +114,13 @@ typedef struct {
*
* Note that the I/O provider may return a positive writability
* flag when considering the whole I/O storage subsystem, while not
- * being able to update/write/delete a particular item.
+ * being able to update/write/delete a particular item
+ * (see is_writable function below).
+ *
+ * Note also that, even if the I/O provider is willing to write,
+ * a sysadmin may have locked down it, by putting a 'true' value
+ * in the key '/apps/nautilus-actions/mandatory/<provider_id>/locked'
+ * (see na_io_provider_is_willing_to_write).
*/
gboolean ( *is_willing_to_write )( const NAIIOProvider *instance );
diff --git a/nautilus-actions/nact/nact-iactions-list.c b/nautilus-actions/nact/nact-iactions-list.c
index af888b5..dff13f8 100644
--- a/nautilus-actions/nact/nact-iactions-list.c
+++ b/nautilus-actions/nact/nact-iactions-list.c
@@ -1634,15 +1634,13 @@ display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *m
gboolean modified = FALSE;
gboolean valid = TRUE;
IActionsListInstanceData *ialid;
- gboolean locked;
- gboolean readonly;
+ gboolean writable_provider;
+ gboolean readonly_item;
gtk_tree_model_get( model, iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
g_object_unref( object );
g_return_if_fail( NA_IS_OBJECT( object ));
- locked = nact_window_is_locked( NACT_WINDOW( instance ), NA_OBJECT_ITEM( object ));
-
ialid = get_instance_data( instance );
label = na_object_get_label( object );
g_object_set( cell, "style-set", FALSE, NULL );
@@ -1652,7 +1650,8 @@ display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *m
modified = na_object_is_modified( object );
valid = na_object_is_valid( object );
- readonly = na_object_is_readonly( object );
+ readonly_item = na_object_is_readonly( object );
+ writable_provider = nact_window_is_writable_provider( NACT_WINDOW( instance ), NA_OBJECT_ITEM( object ));
if( modified ){
g_object_set( cell, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL );
@@ -1660,7 +1659,7 @@ display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *m
if( !valid ){
g_object_set( cell, "foreground", "Red", "foreground-set", TRUE, NULL );
}
- if( !locked && !readonly ){
+ if( writable_provider && !readonly_item ){
g_object_set( cell, "editable", TRUE, NULL );
}
}
diff --git a/nautilus-actions/nact/nact-main-menubar.c b/nautilus-actions/nact/nact-main-menubar.c
index c9797ae..f10bf19 100644
--- a/nautilus-actions/nact/nact-main-menubar.c
+++ b/nautilus-actions/nact/nact-main-menubar.c
@@ -606,13 +606,16 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
gboolean delete_enabled;
gboolean clipboard_is_empty;
gboolean new_item_enabled;
- gboolean readonly;
- gboolean locked;
+ gboolean readonly_item;
+ gboolean writable_provider;
+ gboolean writable_item;
+ gboolean has_writables;
g_debug( "%s: window=%p", thisfn, ( void * ) window );
g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
mis = ( MenubarIndicatorsStruct * ) g_object_get_data( G_OBJECT( window ), MENUBAR_PROP_INDICATORS );
+ has_writables = nact_window_has_writable_providers( NACT_WINDOW( window ));
g_object_get(
G_OBJECT( window ),
@@ -624,17 +627,19 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
g_return_if_fail( !profile || NA_IS_OBJECT_PROFILE( profile ));
has_modified = nact_main_window_has_modified_items( window );
- readonly = item ? na_object_is_readonly( item ) : FALSE;
- locked = item ? nact_window_is_lockdown( NACT_WINDOW( window ), NA_OBJECT_ITEM( item )) : FALSE;
+ readonly_item = item ? na_object_is_readonly( item ) : FALSE;
+ writable_provider = item ? nact_window_is_writable_provider( NACT_WINDOW( window ), NA_OBJECT_ITEM( item )) : FALSE;
+ writable_item = writable_provider && !readonly_item;
/* new menu enabled if selection is a menu or an action */
/* new action enabled if selection is a menu or an action */
new_item_enabled = ( selected_row == NULL || NA_IS_OBJECT_ITEM( selected_row ));
- enable_item( window, "NewMenuItem", new_item_enabled && !locked );
- enable_item( window, "NewActionItem", new_item_enabled && !locked );
+ enable_item( window, "NewMenuItem", new_item_enabled && has_writables );
+ enable_item( window, "NewActionItem", new_item_enabled && has_writables );
/* new profile enabled if selection is relative to only one writable action */
- enable_item( window, "NewProfileItem", item != NULL && !NA_IS_OBJECT_MENU( item ) && !readonly && !locked );
+ enable_item( window, "NewProfileItem",
+ item != NULL && !NA_IS_OBJECT_MENU( item ) && writable_item );
/* save enabled if at least one item has been modified */
enable_item( window, "SaveItem", has_modified || mis->level_zero_order_changed );
@@ -649,22 +654,22 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
/* cut/copy/duplicate/delete enabled when selection not empty */
/* cut/delete require a writable item */
- cut_enabled = ( mis->treeview_has_focus || mis->popup_handler ) && count_selected > 0 && !readonly &&!locked;
- copy_enabled = ( mis->treeview_has_focus || mis->popup_handler ) && count_selected > 0;
- duplicate_enabled = ( mis->treeview_has_focus || mis->popup_handler ) && count_selected > 0 && !locked;
- delete_enabled = ( mis->treeview_has_focus || mis->popup_handler ) && count_selected > 0 && !readonly && !locked;
+ cut_enabled = ( mis->treeview_has_focus || mis->popup_handler ) && count_selected > 0 && writable_item && has_writables;
+ copy_enabled = ( mis->treeview_has_focus || mis->popup_handler ) && count_selected > 0 && has_writables;
+ duplicate_enabled = ( mis->treeview_has_focus || mis->popup_handler ) && count_selected > 0 && has_writables;
+ delete_enabled = ( mis->treeview_has_focus || mis->popup_handler ) && count_selected > 0 && writable_item;
/* paste enabled if
* - simple selection
* - clipboard contains only profiles, and current selection is a profile
* - clipboard contains actions or menus, and current selection is a menu or an action */
paste_enabled = FALSE;
- if(( mis->treeview_has_focus || mis->popup_handler ) && count_selected <= 1 && !locked ){
+ if(( mis->treeview_has_focus || mis->popup_handler ) && count_selected <= 1 ){
if( !clipboard_is_empty ){
if( mis->clipboard_profiles ){
- paste_enabled = item && NA_IS_OBJECT_ACTION( item ) && !readonly;
+ paste_enabled = item && NA_IS_OBJECT_ACTION( item ) && writable_item;
} else {
- paste_enabled = ( item != NULL );
+ paste_enabled = ( item != NULL ) && has_writables;
}
}
}
@@ -675,13 +680,13 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
* - or current item is a menu
* do not paste into if current selection is a profile */
paste_into_enabled = FALSE;
- if(( mis->treeview_has_focus || mis->popup_handler ) && count_selected <= 1 && !locked ){
+ if(( mis->treeview_has_focus || mis->popup_handler ) && count_selected <= 1 ){
if( mis->selected_menus + mis->selected_actions ){
if( !clipboard_is_empty ){
if( mis->clipboard_profiles ){
- paste_into_enabled = item && NA_IS_OBJECT_ACTION( item ) && !readonly;
+ paste_into_enabled = item && NA_IS_OBJECT_ACTION( item ) && writable_item;
} else {
- paste_into_enabled = item && NA_IS_OBJECT_MENU( item );
+ paste_into_enabled = item && NA_IS_OBJECT_MENU( item ) && writable_item && has_writables;
}
}
}
@@ -703,7 +708,8 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
enable_item( window, "ExpandAllItem", count_list > 0 );
enable_item( window, "CollapseAllItem", count_list > 0 );
- /* import item always enabled */
+ /* import item enabled if at least one writable provider */
+ enable_item( window, "ImportItem", has_writables );
/* export item enabled if IActionsList store contains actions */
enable_item( window, "ExportItem", mis->have_exportables );
diff --git a/nautilus-actions/nact/nact-window.c b/nautilus-actions/nact/nact-window.c
index f556824..782f91f 100644
--- a/nautilus-actions/nact/nact-window.c
+++ b/nautilus-actions/nact/nact-window.c
@@ -38,7 +38,6 @@
#include <api/na-iio-provider.h>
#include <api/na-object-api.h>
-#include <runtime/na-gconf-utils.h>
#include <runtime/na-io-provider.h>
#include <runtime/na-iprefs.h>
#include <runtime/na-utils.h>
@@ -198,49 +197,63 @@ nact_window_get_pivot( NactWindow *window )
}
/**
- * nact_window_is_lockdown:
+ * nact_window_is_writable_provider:
* @window: this #NactWindow instance.
* @item: the current item.
*
- * Returns: %TRUE if the configuration of the item's provider is locked
- * to be read-only, %FALSE else.
+ * Returns: %TRUE if the item's provider is willing to write, %FALSE else.
*
* If the provider item has not yet any provider, i.e. has never been
* saved elsewhere, then we return %FALSE, assuming that we eventually
- * find a willing-to-write provider.
+ * find at least one willing-to-write provider.
*/
gboolean
-nact_window_is_lockdown( NactWindow *window, const NAObjectItem *item )
+nact_window_is_writable_provider( NactWindow *window, const NAObjectItem *item )
{
- static const gchar *thisfn = "nact_window_is_lockdown";
- gboolean locked;
+ gboolean writable;
NAPivot *pivot;
NAIIOProvider *provider;
- gchar *id;
- gchar *key;
- GConfClient *gconf;
- locked = FALSE;
+ writable = FALSE;
- g_return_val_if_fail( NACT_IS_WINDOW( window ), locked );
- g_return_val_if_fail( NA_IS_OBJECT_ITEM( item ), locked );
+ g_return_val_if_fail( NACT_IS_WINDOW( window ), writable );
+ g_return_val_if_fail( NA_IS_OBJECT_ITEM( item ), writable );
if( !window->private->dispose_has_run ){
pivot = nact_window_get_pivot( window );
provider = na_object_get_provider( item );
if( provider ){
- id = na_io_provider_get_id( pivot, provider );
- key = g_strdup_printf( "%s/mandatory/%s/lockdown", NAUTILUS_ACTIONS_GCONF_BASEDIR, id );
- gconf = na_iprefs_get_gconf_client( NA_IPREFS( pivot ));
- locked = na_gconf_utils_read_bool( gconf, key, TRUE, locked );
- g_debug( "%s: id=%s, locked=%s", thisfn, id, locked ? "True":"False" );
- g_free( key );
- g_free( id );
+ writable = na_io_provider_is_willing_to_write( pivot, provider );
}
}
- return( locked );
+ return( writable );
+}
+
+/**
+ * nact_window_has_writable_providers:
+ * @window: this #NactWindow instance.
+ *
+ * Returns: %TRUE if at least one I/O provider is writable, %FALSE else.
+ */
+gboolean
+nact_window_has_writable_providers( NactWindow *window )
+{
+ gboolean has_writables;
+ NAPivot *pivot;
+
+ has_writables = FALSE;
+
+ g_return_val_if_fail( NACT_IS_WINDOW( window ), has_writables );
+
+ if( !window->private->dispose_has_run ){
+
+ pivot = nact_window_get_pivot( window );
+ has_writables = na_pivot_has_writable_providers( pivot );
+ }
+
+ return( has_writables );
}
/**
diff --git a/nautilus-actions/nact/nact-window.h b/nautilus-actions/nact/nact-window.h
index 64b2bba..f586d5b 100644
--- a/nautilus-actions/nact/nact-window.h
+++ b/nautilus-actions/nact/nact-window.h
@@ -75,7 +75,8 @@ GType nact_window_get_type( void );
NAPivot *nact_window_get_pivot( NactWindow *window );
-gboolean nact_window_is_lockdown( NactWindow *window, const NAObjectItem *item );
+gboolean nact_window_is_writable_provider( NactWindow *window, const NAObjectItem *item );
+gboolean nact_window_has_writable_providers( NactWindow *window );
gboolean nact_window_save_item( NactWindow *window, NAObjectItem *item );
gboolean nact_window_delete_item( NactWindow *window, const NAObjectItem *item );
diff --git a/nautilus-actions/runtime/na-io-provider.c b/nautilus-actions/runtime/na-io-provider.c
index 4fce93e..b4d4e49 100644
--- a/nautilus-actions/runtime/na-io-provider.c
+++ b/nautilus-actions/runtime/na-io-provider.c
@@ -37,6 +37,7 @@
#include <api/na-iio-provider.h>
#include <api/na-object-api.h>
+#include "na-gconf-utils.h"
#include "na-io-provider.h"
#include "na-iprefs.h"
#include "na-utils.h"
@@ -77,6 +78,7 @@ na_io_provider_register_callbacks( const NAPivot *pivot )
/**
* na_io_provider_get_id:
+ * @pivot: the current #NAPivot instance.
* @provider: the #NAIIOProvider whose id is to be returned.
*
* Returns: the provider's id as a newly allocated string which should
@@ -96,7 +98,26 @@ na_io_provider_get_id( const NAPivot *pivot, const NAIIOProvider *provider )
}
/**
+ * na_io_provider_get_name:
+ * @pivot: the current #NAPivot instance.
+ * @provider: the #NAIIOProvider whose name is to be returned.
+ *
+ * Returns: a displayble name for the provider, as a newly allocated
+ * string which should be g_free() by the caller.
+ */
+gchar *
+na_io_provider_get_name( const NAPivot *pivot, const NAIIOProvider *provider )
+{
+ gchar *name;
+
+ name = na_pivot_get_module_name( pivot, G_OBJECT( provider ));
+
+ return( name );
+}
+
+/**
* na_io_provider_get_version:
+ * @pivot: the current #NAPivot instance.
* @provider: the #NAIIOProvider whose id is to be returned.
*
* Returns: the API's version the provider supports.
@@ -115,20 +136,42 @@ na_io_provider_get_version( const NAPivot *pivot, const NAIIOProvider *provider
}
/**
- * na_io_provider_get_name:
+ * na_io_provider_is_willing_to_write:
+ * @pivot: the current #NAPivot instance.
* @provider: the #NAIIOProvider whose name is to be returned.
*
- * Returns: a displayble name for the provider, as a newly allocated
- * string which should be g_free() by the caller.
+ * Returns: %TRUE if the I/O provider is willing to write _and_ it didn't
+ * has been locked down by a sysadmin.
*/
-gchar *
-na_io_provider_get_name( const NAPivot *pivot, const NAIIOProvider *provider )
+gboolean
+na_io_provider_is_willing_to_write( const NAPivot *pivot, const NAIIOProvider *provider )
{
- gchar *name;
+ static const gchar *thisfn = "na_io_provider_is_willing_to_write";
+ gboolean writable;
+ gboolean locked;
+ GConfClient *gconf;
+ gchar *id;
+ gchar *key;
- name = na_pivot_get_module_name( pivot, G_OBJECT( provider ));
+ writable = FALSE;
+ locked = FALSE;
- return( name );
+ if( NA_IIO_PROVIDER_GET_INTERFACE( provider )->is_willing_to_write ){
+
+ writable = NA_IIO_PROVIDER_GET_INTERFACE( provider )->is_willing_to_write( provider );
+
+ if( writable ){
+ id = na_io_provider_get_id( pivot, provider );
+ key = g_strdup_printf( "%s/mandatory/%s/locked", NAUTILUS_ACTIONS_GCONF_BASEDIR, id );
+ gconf = na_iprefs_get_gconf_client( NA_IPREFS( pivot ));
+ locked = na_gconf_utils_read_bool( gconf, key, TRUE, locked );
+ g_debug( "%s: id=%s, locked=%s", thisfn, id, locked ? "True":"False" );
+ g_free( key );
+ g_free( id );
+ }
+ }
+
+ return( writable && !locked );
}
/**
diff --git a/nautilus-actions/runtime/na-io-provider.h b/nautilus-actions/runtime/na-io-provider.h
index 97d9191..52f0456 100644
--- a/nautilus-actions/runtime/na-io-provider.h
+++ b/nautilus-actions/runtime/na-io-provider.h
@@ -44,16 +44,16 @@
G_BEGIN_DECLS
-void na_io_provider_register_callbacks( const NAPivot *pivot );
+void na_io_provider_register_callbacks( const NAPivot *pivot );
-gchar *na_io_provider_get_id( const NAPivot *pivot, const NAIIOProvider *provider );
-guint na_io_provider_get_version( const NAPivot *pivot, const NAIIOProvider *provider );
+gchar *na_io_provider_get_id( const NAPivot *pivot, const NAIIOProvider *provider );
+gchar *na_io_provider_get_name( const NAPivot *pivot, const NAIIOProvider *provider );
+guint na_io_provider_get_version( const NAPivot *pivot, const NAIIOProvider *provider );
+gboolean na_io_provider_is_willing_to_write( const NAPivot *pivot, const NAIIOProvider *provider );
-gchar *na_io_provider_get_name( const NAPivot *pivot, const NAIIOProvider *provider );
-
-GList *na_io_provider_read_items( const NAPivot *pivot, GSList **messages );
-guint na_io_provider_write_item( const NAPivot *pivot, NAObjectItem *item, GSList **messages );
-guint na_io_provider_delete_item( const NAPivot *pivot, const NAObjectItem *item, GSList **messages );
+GList *na_io_provider_read_items( const NAPivot *pivot, GSList **messages );
+guint na_io_provider_write_item( const NAPivot *pivot, NAObjectItem *item, GSList **messages );
+guint na_io_provider_delete_item( const NAPivot *pivot, const NAObjectItem *item, GSList **messages );
G_END_DECLS
diff --git a/nautilus-actions/runtime/na-pivot.c b/nautilus-actions/runtime/na-pivot.c
index 16a3a5c..beeb670 100644
--- a/nautilus-actions/runtime/na-pivot.c
+++ b/nautilus-actions/runtime/na-pivot.c
@@ -474,6 +474,34 @@ na_pivot_free_providers( GList *providers )
}
/**
+ * na_pivot_has_writable_providers:
+ * @pivot: this #NAPivot instance.
+ *
+ * Returns: %TRUE if at least one I/O provider is writable, %FALSE else.
+ */
+gboolean
+na_pivot_has_writable_providers( const NAPivot *pivot )
+{
+ gboolean has_writable;
+ GList *providers, *ip;
+
+ has_writable = FALSE;
+
+ g_return_val_if_fail( NA_IS_PIVOT( pivot ), has_writable );
+
+ if( !pivot->private->dispose_has_run ){
+
+ providers = na_pivot_get_providers( pivot, NA_IIO_PROVIDER_TYPE );
+ for( ip = providers ; ip && !has_writable ; ip = ip->next ){
+ has_writable = na_io_provider_is_willing_to_write( pivot, NA_IIO_PROVIDER( ip->data ));
+ }
+ na_pivot_free_providers( providers );
+ }
+
+ return( has_writable );
+}
+
+/**
* na_pivot_get_items:
* @pivot: this #NAPivot instance.
*
diff --git a/nautilus-actions/runtime/na-pivot.h b/nautilus-actions/runtime/na-pivot.h
index 98087c9..5cd7813 100644
--- a/nautilus-actions/runtime/na-pivot.h
+++ b/nautilus-actions/runtime/na-pivot.h
@@ -127,6 +127,7 @@ GList *na_pivot_get_providers( const NAPivot *pivot, GType type );
GObject *na_pivot_get_provider( const NAPivot *pivot, GType type );
void na_pivot_release_provider( const GObject *provider );
void na_pivot_free_providers( GList *providers );
+gboolean na_pivot_has_writable_providers( const NAPivot *pivot );
GList *na_pivot_get_items( const NAPivot *pivot );
void na_pivot_load_items( NAPivot *pivot );
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]