[gnome-system-monitor/wip/ubergraph] Added lineinfo GObject class



commit e36eec395b9207d73c29c9209c2c26ec5820e6c8
Author: Robert Roth <robert roth off gmail com>
Date:   Sun Oct 13 05:16:45 2013 +0300

    Added lineinfo GObject class

 src/system-monitor.c   |    9 +-
 uber/Makefile.am       |    2 +
 uber/g-ring.h          |    2 +
 uber/uber-graph.c      |   60 +----------
 uber/uber-graph.h      |    3 -
 uber/uber-line-graph.c |   17 ++--
 uber/uber-line-graph.h |    4 +-
 uber/uber-line-info.c  |  275 ++++++++++++++++++++++++++++++++++++++++++++++++
 uber/uber-line-info.h  |   79 ++++++++++++++
 9 files changed, 375 insertions(+), 76 deletions(-)
---
diff --git a/src/system-monitor.c b/src/system-monitor.c
index 19591ae..ecce497 100644
--- a/src/system-monitor.c
+++ b/src/system-monitor.c
@@ -98,8 +98,7 @@ main (gint   argc,   /* IN */
                gdk_rgba_parse(&color, default_colors[mod]);
                label = uber_label_new();
                uber_label_set_color(UBER_LABEL(label), &color);
-               uber_line_graph_add_line(UBER_LINE_GRAPH(cpu), &color,
-                                        UBER_LABEL(label));
+               uber_line_graph_add_line(UBER_LINE_GRAPH(cpu), &color);
                cpu_info.labels[i] = label;
                /*
                 * XXX: Add the line regardless. Just dont populate it if we don't
@@ -125,14 +124,14 @@ main (gint   argc,   /* IN */
            uber_label_set_text(UBER_LABEL(label),text);
         g_free(text);
            gdk_rgba_parse(&color, "#a40000");
-           uber_line_graph_add_line(UBER_LINE_GRAPH(net), &color, UBER_LABEL(label));
+           uber_line_graph_add_line(UBER_LINE_GRAPH(net), &color);
         net_info.labels[2*i] = label;
            label = uber_label_new();
            text = g_strdup_printf("%s Bytes Out", net_info.ifnames[i]);
            uber_label_set_text(UBER_LABEL(label),text);
         g_free(text);
            gdk_rgba_parse(&color, "#4e9a06");
-           uber_line_graph_add_line(UBER_LINE_GRAPH(net), &color, UBER_LABEL(label));
+           uber_line_graph_add_line(UBER_LINE_GRAPH(net), &color);
         net_info.labels[2*i+1] = label;
     }
        /*
@@ -145,6 +144,8 @@ main (gint   argc,   /* IN */
         */
        uber_graph_set_show_xlabels(UBER_GRAPH(cpu), FALSE);
        uber_graph_set_show_xlabels(UBER_GRAPH(net), FALSE);
+    uber_graph_set_fps(UBER_GRAPH(cpu), 35);
+    uber_graph_set_fps(UBER_GRAPH(net), 35);
        /*
         * Show widgets.
         */
diff --git a/uber/Makefile.am b/uber/Makefile.am
index 17682c4..f404d9f 100644
--- a/uber/Makefile.am
+++ b/uber/Makefile.am
@@ -5,6 +5,7 @@ INST_H_FILES =                          \
        uber.h                  \
        uber-graph.h            \
        uber-frame-source.h     \
+       uber-line-info.h                \
        uber-line-graph.h               \
        uber-label.h            \
        uber-range.h            \
@@ -19,6 +20,7 @@ libuber_1_0_la_SOURCES =              \
        $(NOINST_H_FILES)               \
        uber-graph.c            \
        uber-frame-source.c     \
+       uber-line-info.c                \
        uber-line-graph.c               \
        uber-label.c            \
        uber-range.c            \
diff --git a/uber/g-ring.h b/uber/g-ring.h
index 489f8df..34aa0a5 100644
--- a/uber/g-ring.h
+++ b/uber/g-ring.h
@@ -66,6 +66,8 @@ typedef struct
        guint   pos;
 } GRing;
 
+#define G_TYPE_RING       (g_ring_get_type ())
+
 GType  g_ring_get_type    (void) G_GNUC_CONST;
 GRing* g_ring_sized_new   (guint           element_size,
                            guint           reserved_size,
diff --git a/uber/uber-graph.c b/uber/uber-graph.c
index 63aee08..fa47ef0 100644
--- a/uber/uber-graph.c
+++ b/uber/uber-graph.c
@@ -105,8 +105,6 @@ struct _UberGraphPrivate
                                         * If false, draws will try to only add new
                                         * content to the back buffer.
                                         */
-       GtkWidget       *labels;        /* Container for graph labels. */
-       GtkWidget       *align;         /* Alignment for labels. */
        gint             fps_count;     /* Track actual FPS. */
 };
 
@@ -270,25 +268,6 @@ uber_graph_set_show_ylines (UberGraph *graph,       /* IN */
        gtk_widget_queue_draw(GTK_WIDGET(graph));
 }
 
-/**
- * uber_graph_get_labels:
- * @graph: A #UberGraph.
- *
- * XXX
- *
- * Returns: None.
- * Side effects: None.
- */
-GtkWidget*
-uber_graph_get_labels (UberGraph *graph) /* IN */
-{
-       UberGraphPrivate *priv;
-
-       g_return_val_if_fail(UBER_IS_GRAPH(graph), NULL);
-
-       priv = graph->priv;
-       return priv->align;
-}
 
 /**
  * uber_graph_scale_changed:
@@ -529,11 +508,7 @@ uber_graph_calculate_rects (UberGraph *graph) /* IN */
         */
        priv->nonvis_rect = priv->content_rect;
        priv->nonvis_rect.width = priv->dps_each * priv->x_slots;
-       /*
-        * Update positioning for label alignment.
-        */
-       gtk_alignment_set_padding(GTK_ALIGNMENT(priv->align),
-                                 6, 6, priv->content_rect.x, 0);
+
 }
 
 /**
@@ -1812,30 +1787,6 @@ uber_graph_get_preferred_height (GtkWidget      *widget, /* IN */
 }
 
 /**
- * uber_graph_add_label:
- * @graph: A #UberGraph.
- *
- * XXX
- *
- * Returns: None.
- * Side effects: None.
- */
-void
-uber_graph_add_label (UberGraph *graph, /* IN */
-                      UberLabel *label) /* IN */
-{
-       UberGraphPrivate *priv;
-
-       g_return_if_fail(UBER_IS_GRAPH(graph));
-       g_return_if_fail(UBER_IS_LABEL(label));
-
-       priv = graph->priv;
-       gtk_box_pack_start(GTK_BOX(priv->labels), GTK_WIDGET(label),
-                          TRUE, TRUE, 0);
-       gtk_widget_show(GTK_WIDGET(label));
-}
-
-/**
  * uber_graph_take_screenshot:
  * @graph: A #UberGraph.
  *
@@ -2154,12 +2105,5 @@ uber_graph_init (UberGraph *graph) /* IN */
        priv->full_draw = TRUE;
        priv->show_xlines = TRUE;
        priv->show_ylines = TRUE;
-       /*
-        * TODO: Support labels in a grid.
-        */
-       priv->labels = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3);
-       gtk_box_set_homogeneous (GTK_BOX(priv->labels), TRUE);
-       priv->align = gtk_alignment_new(.5, .5, 1., 1.);
-       gtk_container_add(GTK_CONTAINER(priv->align), priv->labels);
-       gtk_widget_show(priv->labels);
+
 }
diff --git a/uber/uber-graph.h b/uber/uber-graph.h
index edad89b..b22dac8 100644
--- a/uber/uber-graph.h
+++ b/uber/uber-graph.h
@@ -84,11 +84,8 @@ void       uber_graph_set_fps          (UberGraph       *graph,
 void       uber_graph_redraw           (UberGraph       *graph);
 void       uber_graph_set_format       (UberGraph       *graph,
                                         UberGraphFormat  format);
-GtkWidget* uber_graph_get_labels       (UberGraph       *graph);
 void       uber_graph_get_content_area (UberGraph       *graph,
                                         GdkRectangle    *rect);
-void       uber_graph_add_label        (UberGraph       *graph,
-                                        UberLabel       *label);
 gboolean   uber_graph_get_show_xlines  (UberGraph       *graph);
 void       uber_graph_set_show_xlines  (UberGraph       *graph,
                                         gboolean         show_xlines);
diff --git a/uber/uber-line-graph.c b/uber/uber-line-graph.c
index f136d45..4f5ed89 100644
--- a/uber/uber-line-graph.c
+++ b/uber/uber-line-graph.c
@@ -225,8 +225,8 @@ uber_line_graph_get_autoscale (UberLineGraph *graph) /* IN */
  */
 gint
 uber_line_graph_add_line (UberLineGraph  *graph, /* IN */
-                          const GdkRGBA  *color, /* IN */
-                          UberLabel      *label) /* IN */
+                          const GdkRGBA  *color) /* IN */
+                          //UberLabel      *label) /* IN */
 {
        UberLineGraphPrivate *priv;
        LineInfo info = { 0 };
@@ -234,7 +234,7 @@ uber_line_graph_add_line (UberLineGraph  *graph, /* IN */
        g_return_val_if_fail(UBER_IS_LINE_GRAPH(graph), 0);
 
        priv = graph->priv;
-       info.width = 1.0;
+       info.width = 3;
        /*
         * Retrieve the lines color.
         */
@@ -249,7 +249,7 @@ uber_line_graph_add_line (UberLineGraph  *graph, /* IN */
        info.raw_data = g_ring_sized_new(sizeof(gdouble), priv->stride, NULL);
        uber_line_graph_init_ring(info.raw_data);
        /*
-        * Store the newly crated line.
+        * Store the newly created line.
         */
        g_array_append_val(priv->lines, info);
        /*
@@ -259,11 +259,10 @@ uber_line_graph_add_line (UberLineGraph  *graph, /* IN */
        /*
         * Attach label.
         */
-       if (label) {
-               uber_line_graph_bind_label(graph, priv->lines->len, label);
-               uber_graph_add_label(UBER_GRAPH(graph), label);
-               uber_label_set_color(label, &info.color);
-       }
+       //if (label) {
+       //      uber_line_graph_bind_label(graph, priv->lines->len, label);
+       //      uber_label_set_color(label, &info.color);
+       //}
        /*
         * Line indexes start from 1.
         */
diff --git a/uber/uber-line-graph.h b/uber/uber-line-graph.h
index f28eaea..5a9b309 100644
--- a/uber/uber-line-graph.h
+++ b/uber/uber-line-graph.h
@@ -69,8 +69,8 @@ struct _UberLineGraphClass
 };
 
 gint              uber_line_graph_add_line       (UberLineGraph     *graph,
-                                                  const GdkRGBA     *color,
-                                                  UberLabel         *label);
+                                                  const GdkRGBA     *color);
+                                                  //UberLabel         *label);
 cairo_antialias_t uber_line_graph_get_antialias  (UberLineGraph     *graph);
 GType             uber_line_graph_get_type       (void) G_GNUC_CONST;
 GtkWidget*        uber_line_graph_new            (void);
diff --git a/uber/uber-line-info.c b/uber/uber-line-info.c
new file mode 100644
index 0000000..b409d47
--- /dev/null
+++ b/uber/uber-line-info.c
@@ -0,0 +1,275 @@
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*-  */
+/*
+ * uber-line-info.c
+ * Copyright (C) 2013 Robert Roth <robert roth off gmail com>
+ * 
+ * uber-line-info.c 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 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * uber-line-info.c 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/>.
+ */
+
+#include "uber-line-info.h"
+
+enum
+{
+    PROP_0,
+
+    PROP_COLOR,
+    PROP_WIDTH,
+    PROP_DATA,
+    PROP_LABEL
+};
+
+/**
+ * uber_line_info_init_ring:
+ * @ring: A #GRing.
+ *
+ * Initialize the #GRing to default values (UBER_LINE_INFO_NO_VALUE).
+ *
+ * Returns: None.
+ * Side effects: None.
+ */
+static inline void
+uber_line_info_init_ring (GRing *ring) /* IN */
+{
+       gdouble val = UBER_LINE_INFO_NO_VALUE;
+       gint i;
+
+       g_return_if_fail(ring != NULL);
+
+       for (i = 0; i < ring->len; i++) {
+               g_ring_append_val(ring, val);
+       }
+}
+
+G_DEFINE_TYPE (UberLineInfo, uber_line_info, G_TYPE_OBJECT);
+
+struct _UberLineInfoPrivate
+{
+       GRing     *raw_data;
+       GdkRGBA    color;
+       gdouble    width;
+       GtkWidget *label;
+       guint      label_id;
+};
+
+static void
+uber_line_info_init (UberLineInfo *uber_line_info)
+{
+    /*
+        * Keep pointer to private data.
+        */
+       UberLineInfoPrivate *priv = UBER_LINE_INFO_GET_PRIVATE(uber_line_info);
+    priv->width = 1.0;
+    priv->label = NULL;
+    gdk_rgba_parse(&(priv->color), "#777777");
+    priv->raw_data = NULL;
+    //priv->dash_offset = 0;
+    //priv->dashes = NULL;
+    //priv->num_dashes = 0;
+  
+}
+
+static void
+uber_line_info_finalize (GObject *object)
+{
+  /* TODO: Add deinitalization code here */
+    UberLineInfoPrivate *priv = UBER_LINE_INFO_GET_PRIVATE(object);
+    g_ring_unref(priv->raw_data);
+    G_OBJECT_CLASS (uber_line_info_parent_class)->finalize (object);
+}
+
+const gdouble  
+uber_line_info_get_width      (UberLineInfo     *line)
+{
+    UberLineInfoPrivate *priv = UBER_LINE_INFO_GET_PRIVATE(line);  
+    return priv->width;
+}
+
+void           
+uber_line_info_set_width      (UberLineInfo     *line,
+                               const gdouble    width)
+{
+    UberLineInfoPrivate *priv = UBER_LINE_INFO_GET_PRIVATE(line);  
+    priv->width = width;
+}
+
+const GRing*   
+uber_line_info_get_data       (UberLineInfo     *line)
+{
+    UberLineInfoPrivate *priv = UBER_LINE_INFO_GET_PRIVATE(line);  
+    return priv->raw_data;
+}
+
+void           
+uber_line_info_set_data       (UberLineInfo     *line,
+                               GRing            *data)
+{
+    UberLineInfoPrivate *priv = UBER_LINE_INFO_GET_PRIVATE(line);  
+    if (priv->raw_data)
+        g_ring_unref(priv->raw_data);
+    priv->raw_data = data;
+}
+
+GdkRGBA* uber_line_info_get_color      (UberLineInfo     *line)
+{
+    UberLineInfoPrivate *priv = UBER_LINE_INFO_GET_PRIVATE(line);  
+    return &(priv->color);
+}
+
+void  uber_line_info_set_color      (UberLineInfo     *line,
+                                     GdkRGBA          *color)
+{
+    UberLineInfoPrivate *priv = UBER_LINE_INFO_GET_PRIVATE(line);  
+    priv->color = *color;
+}
+                                
+GtkWidget* uber_line_info_get_label      (UberLineInfo     *line)
+{
+    UberLineInfoPrivate *priv = UBER_LINE_INFO_GET_PRIVATE(line);  
+    return GTK_WIDGET(priv->label);
+}
+
+void  uber_line_info_set_label      (UberLineInfo     *line,
+                                     GtkWidget        *label)
+{
+    UberLineInfoPrivate *priv = UBER_LINE_INFO_GET_PRIVATE(line);  
+    priv->label = label;
+}
+
+static void
+uber_line_info_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+    g_return_if_fail (UBER_IS_LINE_INFO (object));
+    UberLineInfo *line = UBER_LINE_INFO(object);
+    switch (prop_id)
+    {
+        case PROP_COLOR:
+        //uber_line_info_set_color(object, g_value_get_boxed(value));
+        break;
+        case PROP_WIDTH:
+        uber_line_info_set_width(line, g_value_get_double(value));
+        break;
+        case PROP_DATA:
+        uber_line_info_set_data(line, g_value_get_boxed(value));
+        break;
+        case PROP_LABEL:
+        uber_line_info_set_label(line, g_value_get_boxed(value));
+        break;
+        default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+  }
+}
+
+static void
+uber_line_info_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+    g_return_if_fail (UBER_IS_LINE_INFO (object));
+
+    UberLineInfo *line = UBER_LINE_INFO(object);
+    switch (prop_id)
+    {
+        case PROP_COLOR:
+        //g_value_set_boxed(value, uber_line_info_get_color(object));
+        break;
+        case PROP_WIDTH:
+        g_value_set_double(value, uber_line_info_get_width(line));
+        break;
+        case PROP_DATA:
+        g_value_set_boxed(value, uber_line_info_get_data(line));
+        break;
+        case PROP_LABEL:
+        g_value_set_boxed(value, uber_line_info_get_label(line));
+        break;
+        default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+uber_line_info_class_init (UberLineInfoClass *klass)
+{
+    GObjectClass* object_class = G_OBJECT_CLASS (klass);
+  
+    object_class->finalize = uber_line_info_finalize;
+    object_class->set_property = uber_line_info_set_property;
+    object_class->get_property = uber_line_info_get_property;
+    g_type_class_add_private(object_class, sizeof(UberLineInfoPrivate));
+
+    g_object_class_install_property (object_class,
+                                   PROP_COLOR,
+                                   g_param_spec_boxed ("color",
+                                                       "color",
+                                                       "color",
+                                                        GDK_TYPE_RGBA,
+                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+
+    g_object_class_install_property (object_class,
+                                   PROP_WIDTH,
+                                   g_param_spec_double ("width",
+                                                        "width",
+                                                        "width",
+                                                        0.1,
+                                                        30.0,
+                                                        1.0,
+                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
+    g_object_class_install_property (object_class,
+                                   PROP_DATA,
+                                   g_param_spec_boxed ("data",
+                                                       "data",
+                                                       "data",
+                                                        G_TYPE_RING,
+                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
+                                                        
+    g_object_class_install_property (object_class,
+                                   PROP_LABEL,
+                                   g_param_spec_boxed ("label",
+                                                       "label",
+                                                       "color",
+                                                        GTK_TYPE_LABEL,
+                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
+}
+
+void
+uber_line_info_add_value      (UberLineInfo     *line, gdouble value)
+{
+    UberLineInfoPrivate *priv = UBER_LINE_INFO_GET_PRIVATE(line);
+    g_ring_append_val(priv->raw_data, value);
+}
+
+/**
+ * uber_line_info_new:
+ *
+ * Creates a new instance of #UberLineInfo.
+ *
+ * Returns: the newly created instance of #UberLineInfo with the specified data length.
+ * Side effects: None.
+ */
+UberLineInfo*
+uber_line_info_new (guint stride, GdkRGBA *color, gdouble width)
+{
+       UberLineInfo *line;
+
+       line = g_object_new(UBER_TYPE_LINE_INFO, NULL);
+    UberLineInfoPrivate *priv = UBER_LINE_INFO_GET_PRIVATE(line);
+    
+    priv->raw_data = g_ring_sized_new(sizeof(gdouble), stride, NULL);
+       uber_line_info_init_ring(priv->raw_data);
+    priv->color = *color;
+    priv->width = width;
+    
+       return UBER_LINE_INFO(line);
+}
+
diff --git a/uber/uber-line-info.h b/uber/uber-line-info.h
new file mode 100644
index 0000000..d12fdfc
--- /dev/null
+++ b/uber/uber-line-info.h
@@ -0,0 +1,79 @@
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*-  */
+/*
+ * uber-line-info.c
+ * Copyright (C) 2013 Robert Roth <robert roth off gmail com>
+ * 
+ * uber-line-info.c 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 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * uber-line-info.c 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 _UBER_LINE_INFO_H_
+#define _UBER_LINE_INFO_H_
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <math.h>
+#include "g-ring.h"
+
+G_BEGIN_DECLS
+
+#define UBER_TYPE_LINE_INFO             (uber_line_info_get_type ())
+#define UBER_LINE_INFO(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), UBER_TYPE_LINE_INFO, 
UberLineInfo))
+#define UBER_LINE_INFO_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), UBER_TYPE_LINE_INFO, 
UberLineInfoClass))
+#define UBER_IS_LINE_INFO(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UBER_TYPE_LINE_INFO))
+#define UBER_IS_LINE_INFO_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), UBER_TYPE_LINE_INFO))
+#define UBER_LINE_INFO_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), UBER_TYPE_LINE_INFO, 
UberLineInfoClass))
+
+#define UBER_LINE_INFO_NO_VALUE (NAN)
+
+typedef struct _UberLineInfoClass UberLineInfoClass;
+typedef struct _UberLineInfo UberLineInfo;
+typedef struct _UberLineInfoPrivate UberLineInfoPrivate;
+
+#define UBER_LINE_INFO_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE(obj, UBER_TYPE_LINE_INFO, 
UberLineInfoPrivate))
+
+struct _UberLineInfoClass
+{
+    GObjectClass parent_class;
+};
+
+struct _UberLineInfo
+{
+    GObject parent_instance;
+};
+
+GType uber_line_info_get_type (void) G_GNUC_CONST;
+
+const gdouble  uber_line_info_get_width      (UberLineInfo     *line);
+void           uber_line_info_set_width      (UberLineInfo     *line,
+                                              const gdouble    width);
+const GRing*   uber_line_info_get_data       (UberLineInfo     *line);
+void           uber_line_info_set_data       (UberLineInfo     *line,
+                                              GRing            *data);
+GdkRGBA       *uber_line_info_get_color      (UberLineInfo     *line);
+void           uber_line_info_set_color      (UberLineInfo     *line,
+                                              GdkRGBA          *color);
+GtkWidget     *uber_line_info_get_label      (UberLineInfo     *line);
+void           uber_line_info_set_label      (UberLineInfo     *line,
+                                              GtkWidget        *label);
+                                    
+void           uber_line_info_add_value      (UberLineInfo     *line,
+                                              gdouble value);
+UberLineInfo*  uber_line_info_new            (guint stride, 
+                                              GdkRGBA *color, 
+                                              gdouble width);
+                                              
+G_END_DECLS
+
+#endif /* _UBER_LINE_INFO_H_ */
+


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