[libhandy/wip/haecker-felix/flap-widget] Child structs



commit b0cc4afe879ab16c31cef062210da291bb354dcb
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Mon Nov 23 17:05:18 2020 +0500

    Child structs

 src/hdy-flap.c | 372 +++++++++++++++++++++++++++------------------------------
 1 file changed, 176 insertions(+), 196 deletions(-)
---
diff --git a/src/hdy-flap.c b/src/hdy-flap.c
index 440f628a..c2cfc193 100644
--- a/src/hdy-flap.c
+++ b/src/hdy-flap.c
@@ -47,21 +47,20 @@
 
 #define HDY_SWIPE_BORDER 16
 
+typedef struct {
+  GtkWidget *widget;
+  GdkWindow *window;
+  GtkAllocation allocation;
+  gboolean visible;
+} ChildInfo;
+
 struct _HdyFlap
 {
   GtkContainer parent_instance;
 
-  GtkWidget *content;
-  GtkWidget *flap;
-  GtkWidget *separator;
-
-  GdkWindow *content_window;
-  GdkWindow *separator_window;
-  GdkWindow *flap_window;
-
-  GtkAllocation flap_allocation;
-  GtkAllocation content_allocation;
-  GtkAllocation separator_allocation;
+  ChildInfo content;
+  ChildInfo flap;
+  ChildInfo separator;
 
   HdyFlapFoldPolicy fold_policy;
   HdyFlapTransitionType transition_type;
@@ -341,10 +340,10 @@ pressed_cb (GtkGestureMultiPress *gesture,
     return;
   }
 
-  if (x >= self->flap_allocation.x &&
-      x <= self->flap_allocation.x + self->flap_allocation.width &&
-      y >= self->flap_allocation.y &&
-      y <= self->flap_allocation.y + self->flap_allocation.height) {
+  if (x >= self->flap.allocation.x &&
+      x <= self->flap.allocation.x + self->flap.allocation.width &&
+      y >= self->flap.allocation.y &&
+      y <= self->flap.allocation.y + self->flap.allocation.height) {
     gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
 
     return;
@@ -354,46 +353,47 @@ pressed_cb (GtkGestureMultiPress *gesture,
 }
 
 static void
-register_window (HdyFlap        *self,
-                 GtkWidget      *widget,
-                 GtkAllocation  *allocation,
-                 GdkWindow     **window)
+register_window (HdyFlap   *self,
+                 ChildInfo *info)
 {
   GdkWindowAttr attributes = { 0 };
   GdkWindowAttributesType attributes_mask;
 
-  attributes.x = allocation->x;
-  attributes.y = allocation->y;
-  attributes.width = allocation->width;
-  attributes.height = allocation->height;
+  if (!info->widget)
+    return;
+
+  attributes.x = info->allocation.x;
+  attributes.y = info->allocation.y;
+  attributes.width = info->allocation.width;
+  attributes.height = info->allocation.height;
   attributes.window_type = GDK_WINDOW_CHILD;
   attributes.wclass = GDK_INPUT_OUTPUT;
-  attributes.visual = gtk_widget_get_visual (widget);
-  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.visual = gtk_widget_get_visual (info->widget);
+  attributes.event_mask = gtk_widget_get_events (info->widget);
   attributes_mask = (GDK_WA_X | GDK_WA_Y) | GDK_WA_VISUAL;
 
   attributes.event_mask = gtk_widget_get_events (GTK_WIDGET (self)) |
-                          gtk_widget_get_events (widget);
+                          gtk_widget_get_events (info->widget);
 
-  *window = gdk_window_new (gtk_widget_get_window (GTK_WIDGET (self)),
-                            &attributes, attributes_mask);
-  gtk_widget_register_window (GTK_WIDGET (self), *window);
+  info->window = gdk_window_new (gtk_widget_get_window (GTK_WIDGET (self)),
+                                 &attributes, attributes_mask);
+  gtk_widget_register_window (GTK_WIDGET (self), info->window);
 
-  gtk_widget_set_parent_window (widget, *window);
+  gtk_widget_set_parent_window (info->widget, info->window);
 
-  gdk_window_show (*window);
+  gdk_window_show (info->window);
 }
 
 static void
-unregister_window (HdyFlap    *self,
-                   GdkWindow **window)
+unregister_window (HdyFlap   *self,
+                   ChildInfo *info)
 {
-  if (!*window)
+  if (!info->window)
     return;
 
-  gtk_widget_unregister_window (GTK_WIDGET (self), *window);
-  gdk_window_destroy (*window);
-  *window = NULL;
+  gtk_widget_unregister_window (GTK_WIDGET (self), info->window);
+  gdk_window_destroy (info->window);
+  info->window = NULL;
 }
 
 static gboolean
@@ -450,22 +450,22 @@ restack_windows (HdyFlap *self)
   gboolean content_above_flap = transition_is_content_above_flap (self);
 
   if (!content_above_flap) {
-    if (self->content_window)
-      gdk_window_raise (self->content_window);
+    if (self->content.window)
+      gdk_window_raise (self->content.window);
 
-    if (self->separator_window)
-      gdk_window_raise (self->separator_window);
+    if (self->separator.window)
+      gdk_window_raise (self->separator.window);
   }
 
-  if (self->flap_window)
-    gdk_window_raise (self->flap_window);
+  if (self->flap.window)
+    gdk_window_raise (self->flap.window);
 
   if (content_above_flap) {
-    if (self->separator_window)
-      gdk_window_raise (self->separator_window);
+    if (self->separator.window)
+      gdk_window_raise (self->separator.window);
 
-    if (self->content_window)
-      gdk_window_raise (self->content_window);
+    if (self->content.window)
+      gdk_window_raise (self->content.window);
   }
 }
 
@@ -479,6 +479,32 @@ get_start_or_end (HdyFlap *self)
   return (is_rtl && !is_horiz) ? GTK_PACK_END : GTK_PACK_START;
 }
 
+static void
+add_child (HdyFlap   *self,
+           ChildInfo *info)
+{
+  if (gtk_widget_get_realized (GTK_WIDGET (self))) {
+    register_window (self, info);
+    restack_windows (self);
+  }
+
+  gtk_widget_set_parent (info->widget, GTK_WIDGET (self));
+
+  info->visible = FALSE;
+}
+
+static void
+remove_child (HdyFlap   *self,
+              ChildInfo *info)
+{
+  if (gtk_widget_get_realized (GTK_WIDGET (self)))
+    unregister_window (self, info);
+
+  gtk_widget_unparent (info->widget);
+
+  info->visible = FALSE;
+}
+
 static inline void
 get_preferred_size (GtkWidget      *widget,
                     GtkOrientation  orientation,
@@ -504,11 +530,11 @@ compute_sizes (HdyFlap       *self,
   gint total, extra;
   gint flap_nat, content_nat;
 
-  if (!self->flap && !self->content)
+  if (!self->flap.widget && !self->content.widget)
     return;
 
-  if (self->separator)
-    get_preferred_size (self->separator, self->orientation, separator_size, NULL);
+  if (self->separator.widget)
+    get_preferred_size (self->separator.widget, self->orientation, separator_size, NULL);
   else
     *separator_size = 0;
 
@@ -517,25 +543,25 @@ compute_sizes (HdyFlap       *self,
   else
     total = alloc->height;
 
-  if (!self->flap) {
+  if (!self->flap.widget) {
     *content_size = total;
     *flap_size = 0;
 
     return;
   }
 
-  if (!self->content) {
+  if (!self->content.widget) {
     *content_size = 0;
     *flap_size = total;
 
     return;
   }
 
-  get_preferred_size (self->flap, self->orientation, flap_size, &flap_nat);
-  get_preferred_size (self->content, self->orientation, content_size, &content_nat);
+  get_preferred_size (self->flap.widget, self->orientation, flap_size, &flap_nat);
+  get_preferred_size (self->content.widget, self->orientation, content_size, &content_nat);
 
-  flap_expand = gtk_widget_compute_expand (self->flap, self->orientation);
-  content_expand = gtk_widget_compute_expand (self->content, self->orientation);
+  flap_expand = gtk_widget_compute_expand (self->flap.widget, self->orientation);
+  content_expand = gtk_widget_compute_expand (self->content.widget, self->orientation);
 
   if (folded) {
     *content_size = total;
@@ -543,7 +569,7 @@ compute_sizes (HdyFlap       *self,
     if (flap_expand) {
       *flap_size = total;
     } else {
-      get_preferred_size (self->flap, self->orientation, NULL, flap_size);
+      get_preferred_size (self->flap.widget, self->orientation, NULL, flap_size);
       *flap_size = MIN (*flap_size, total);
     }
 
@@ -584,11 +610,11 @@ compute_sizes (HdyFlap       *self,
   if (extra > 0) {
     GtkRequestedSize sizes[2];
 
-    sizes[0].data = self->flap;
+    sizes[0].data = self->flap.widget;
     sizes[0].minimum_size = *flap_size;
     sizes[0].natural_size = flap_nat;
 
-    sizes[1].data = self->content;
+    sizes[1].data = self->content.widget;
     sizes[1].minimum_size = *content_size;
     sizes[1].natural_size = content_nat;
 
@@ -675,7 +701,7 @@ compute_allocation (HdyFlap       *self,
   gint total, content_pos, flap_pos, separator_pos;
   gboolean content_above_flap = transition_is_content_above_flap (self);
 
-  if (!self->flap && !self->content && !self->separator)
+  if (!self->flap.widget && !self->content.widget && !self->separator.widget)
     return;
 
   content_alloc->x = 0;
@@ -701,7 +727,7 @@ compute_allocation (HdyFlap       *self,
     total = alloc->height;
   }
 
-  if (!self->flap)
+  if (!self->flap.widget)
     return;
 
   if (content_above_flap)
@@ -737,26 +763,28 @@ compute_allocation (HdyFlap       *self,
 }
 
 static inline void
-allocate_child (HdyFlap       *self,
-                GtkWidget     *widget,
-                GdkWindow     *window,
-                GtkAllocation *allocation,
-                gboolean       visible)
+allocate_child (HdyFlap   *self,
+                ChildInfo *info,
+                gboolean   visible)
 {
   GtkAllocation child_alloc;
 
-  if (!widget)
+  if (!info->widget)
     return;
 
-  gtk_widget_set_child_visible (widget, visible);
+  if (visible != info->visible) {
+    gtk_widget_set_child_visible (info->widget, visible);
+    info->visible = visible;
+  }
 
   if (gtk_widget_get_realized (GTK_WIDGET (self))) {
     if (visible) {
-      gdk_window_show_unraised (window);
-      gdk_window_move_resize (window, allocation->x, allocation->y,
-                              allocation->width, allocation->height);
+      gdk_window_show (info->window);
+      gdk_window_move_resize (info->window,
+                              info->allocation.x, info->allocation.y,
+                              info->allocation.width, info->allocation.height);
     } else {
-      gdk_window_hide (window);
+      gdk_window_hide (info->window);
     }
   }
 
@@ -765,10 +793,10 @@ allocate_child (HdyFlap       *self,
 
   child_alloc.x = 0;
   child_alloc.y = 0;
-  child_alloc.width = allocation->width;
-  child_alloc.height = allocation->height;
+  child_alloc.width = info->allocation.width;
+  child_alloc.height = info->allocation.height;
 
-  gtk_widget_size_allocate (widget, &child_alloc);
+  gtk_widget_size_allocate (info->widget, &child_alloc);
 }
 
 static void
@@ -786,9 +814,9 @@ hdy_flap_size_allocate (GtkWidget     *widget,
   if (self->fold_policy == HDY_FLAP_FOLD_POLICY_AUTO) {
     GtkRequisition flap_min, content_min, separator_min;
 
-    gtk_widget_get_preferred_size (self->flap, &flap_min, NULL);
-    gtk_widget_get_preferred_size (self->content, &content_min, NULL);
-    gtk_widget_get_preferred_size (self->separator, &separator_min, NULL);
+    gtk_widget_get_preferred_size (self->flap.widget, &flap_min, NULL);
+    gtk_widget_get_preferred_size (self->content.widget, &content_min, NULL);
+    gtk_widget_get_preferred_size (self->separator.widget, &separator_min, NULL);
 
     if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
       set_folded (self, alloc->width < content_min.width + flap_min.width + separator_min.width);
@@ -798,27 +826,13 @@ hdy_flap_size_allocate (GtkWidget     *widget,
 
   compute_allocation (self,
                       alloc,
-                      &self->flap_allocation,
-                      &self->content_allocation,
-                      &self->separator_allocation);
-
-  allocate_child (self,
-                  self->content,
-                  self->content_window,
-                  &self->content_allocation,
-                  TRUE);
-
-  allocate_child (self,
-                  self->separator,
-                  self->separator_window,
-                  &self->separator_allocation,
-                  self->reveal_progress > 0);
-
-  allocate_child (self,
-                  self->flap,
-                  self->flap_window,
-                  &self->flap_allocation,
-                  self->reveal_progress > 0);
+                      &self->flap.allocation,
+                      &self->content.allocation,
+                      &self->separator.allocation);
+
+  allocate_child (self, &self->content, TRUE);
+  allocate_child (self, &self->separator, self->reveal_progress > 0);
+  allocate_child (self, &self->flap, self->reveal_progress > 0);
 
   gtk_widget_set_clip (widget, alloc);
 }
@@ -842,14 +856,14 @@ hdy_flap_measure (GtkWidget      *widget,
   gint separator_min = 0, separator_nat = 0;
   gint min, nat;
 
-  if (self->content)
-    get_preferred_size (self->content, orientation, &content_min, &content_nat);
+  if (self->content.widget)
+    get_preferred_size (self->content.widget, orientation, &content_min, &content_nat);
 
-  if (self->flap)
-    get_preferred_size (self->flap, orientation, &flap_min, &flap_nat);
+  if (self->flap.widget)
+    get_preferred_size (self->flap.widget, orientation, &flap_min, &flap_nat);
 
-  if (self->separator)
-    get_preferred_size (self->separator, orientation, &separator_min, &separator_nat);
+  if (self->separator.widget)
+    get_preferred_size (self->separator.widget, orientation, &separator_min, &separator_nat);
 
   if (self->orientation == orientation &&
       self->fold_policy != HDY_FLAP_FOLD_POLICY_AUTO) {
@@ -924,38 +938,38 @@ hdy_flap_draw (GtkWidget *widget,
   GtkAllocation *shadow_alloc;
 
   if (!content_above_flap) {
-    if (self->content)
+    if (self->content.widget)
       gtk_container_propagate_draw (GTK_CONTAINER (self),
-                                    self->content,
+                                    self->content.widget,
                                     cr);
 
-    if (self->separator)
+    if (self->separator.widget)
       gtk_container_propagate_draw (GTK_CONTAINER (self),
-                                    self->separator,
+                                    self->separator.widget,
                                     cr);
   }
 
-  if (self->flap)
+  if (self->flap.widget)
     gtk_container_propagate_draw (GTK_CONTAINER (self),
-                                  self->flap,
+                                  self->flap.widget,
                                   cr);
 
   if (content_above_flap) {
-    if (self->separator)
+    if (self->separator.widget)
       gtk_container_propagate_draw (GTK_CONTAINER (self),
-                                    self->separator,
+                                    self->separator.widget,
                                     cr);
 
-    if (self->content)
+    if (self->content.widget)
       gtk_container_propagate_draw (GTK_CONTAINER (self),
-                                    self->content,
+                                    self->content.widget,
                                     cr);
   }
 
-  if (!self->flap)
+  if (!self->flap.widget)
     return GDK_EVENT_PROPAGATE;
 
-  shadow_alloc = content_above_flap ? &self->content_allocation : &self->flap_allocation;
+  shadow_alloc = content_above_flap ? &self->content.allocation : &self->flap.allocation;
 
   width = gtk_widget_get_allocated_width (widget);
   height = gtk_widget_get_allocated_height (widget);
@@ -995,7 +1009,7 @@ hdy_flap_draw (GtkWidget *widget,
     g_assert_not_reached ();
   }
 
-  if (progress < 1 && gtk_widget_get_mapped (self->flap)) {
+  if (progress < 1 && gtk_widget_get_mapped (self->flap.widget)) {
     cairo_save (cr);
     cairo_translate (cr, shadow_x, shadow_y);
     hdy_shadow_helper_draw_shadow (self->shadow_helper, cr, width, height,
@@ -1034,14 +1048,9 @@ hdy_flap_realize (GtkWidget *widget)
   gtk_widget_set_window (widget, window);
   gtk_widget_register_window (widget, window);
 
-  if (self->content)
-    register_window (self, self->content, &self->content_allocation, &self->content_window);
-
-  if (self->separator)
-    register_window (self, self->separator, &self->separator_allocation, &self->separator_window);
-
-  if (self->flap)
-    register_window (self, self->flap, &self->flap_allocation, &self->flap_window);
+  register_window (self, &self->content);
+  register_window (self, &self->separator);
+  register_window (self, &self->flap);
 
   restack_windows (self);
 }
@@ -1051,9 +1060,9 @@ hdy_flap_unrealize (GtkWidget *widget)
 {
   HdyFlap *self = HDY_FLAP (widget);
 
-  unregister_window (self, &self->content_window);
-  unregister_window (self, &self->separator_window);
-  unregister_window (self, &self->flap_window);
+  unregister_window (self, &self->content);
+  unregister_window (self, &self->separator);
+  unregister_window (self, &self->flap);
 
   GTK_WIDGET_CLASS (hdy_flap_parent_class)->unrealize (widget);
 }
@@ -1078,14 +1087,14 @@ hdy_flap_forall (GtkContainer *container,
 {
   HdyFlap *self = HDY_FLAP (container);
 
-  if (self->content)
-    callback (self->content, callback_data);
+  if (self->content.widget)
+    callback (self->content.widget, callback_data);
 
-  if (self->separator)
-    callback (self->separator, callback_data);
+  if (self->separator.widget)
+    callback (self->separator.widget, callback_data);
 
-  if (self->flap)
-    callback (self->flap, callback_data);
+  if (self->flap.widget)
+    callback (self->flap.widget, callback_data);
 }
 
 static void
@@ -1094,25 +1103,21 @@ hdy_flap_add (GtkContainer *container,
 {
   HdyFlap *self = HDY_FLAP (container);
 
-  if (self->content) {
+  if (self->content.widget) {
     g_warning ("Attempting to add a widget with type %s to a %s, "
                "but %s can only contain one widget at a time; "
                "it already contains a widget of type %s",
                g_type_name (G_OBJECT_TYPE (widget)),
                g_type_name (G_OBJECT_TYPE (self)),
                g_type_name (G_OBJECT_TYPE (self)),
-               g_type_name (G_OBJECT_TYPE (self->content)));
+               g_type_name (G_OBJECT_TYPE (self->content.widget)));
 
     return;
   }
 
-  if (gtk_widget_get_realized (GTK_WIDGET (self))) {
-    register_window (self, widget, &self->content_allocation, &self->content_window);
-    restack_windows (self);
-  }
+  self->content.widget = widget;
 
-  gtk_widget_set_parent (widget, GTK_WIDGET (self));
-  self->content = widget;
+  add_child (self, &self->content);
 }
 
 static void
@@ -1121,23 +1126,21 @@ hdy_flap_remove (GtkContainer *container,
 {
   HdyFlap *self = HDY_FLAP (container);
 
-  if (widget == self->flap) {
+  if (widget == self->flap.widget) {
     hdy_flap_set_flap (self, NULL);
 
     return;
   }
 
-  if (widget == self->separator) {
+  if (widget == self->separator.widget) {
     hdy_flap_set_separator (self, NULL);
 
     return;
   }
 
-  if (widget == self->content) {
-    if (gtk_widget_get_realized (GTK_WIDGET (self)))
-      unregister_window (self, &self->content_window);
-
-    g_clear_pointer (&self->content, gtk_widget_unparent);
+  if (widget == self->content.widget) {
+    remove_child (self, &self->content);
+    self->content.widget = NULL;
 
     return;
   }
@@ -1505,15 +1508,15 @@ hdy_flap_get_distance (HdySwipeable *swipeable)
   HdyFlap *self = HDY_FLAP (swipeable);
   gint flap, separator;
 
-  if (!self->flap)
+  if (!self->flap.widget)
     return 0;
 
   if (self->orientation == GTK_ORIENTATION_HORIZONTAL) {
-    flap = self->flap_allocation.width;
-    separator = self->separator_allocation.width;
+    flap = self->flap.allocation.width;
+    separator = self->separator.allocation.width;
   } else {
-    flap = self->flap_allocation.height;
-    separator = self->separator_allocation.height;
+    flap = self->flap.allocation.height;
+    separator = self->separator.allocation.height;
   }
 
   if (transition_is_content_above_flap (self))
@@ -1565,7 +1568,7 @@ hdy_flap_get_swipe_area (HdySwipeable           *swipeable,
   gdouble flap_factor, content_factor;
   gboolean content_above_flap;
 
-  if (!self->flap) {
+  if (!self->flap.widget) {
     rect->x = 0;
     rect->y = 0;
     rect->width = 0;
@@ -1593,8 +1596,8 @@ hdy_flap_get_swipe_area (HdySwipeable           *swipeable,
   }
 
   alloc = content_above_flap
-    ? &self->content_allocation
-    : &self->flap_allocation;
+    ? &self->content.allocation
+    : &self->flap.allocation;
 
   if (self->orientation == GTK_ORIENTATION_HORIZONTAL) {
     if (alloc->x <= 0) {
@@ -1665,7 +1668,7 @@ hdy_flap_get_flap (HdyFlap *self)
 {
   g_return_val_if_fail (HDY_IS_FLAP (self), NULL);
 
-  return self->flap;
+  return self->flap.widget;
 }
 
 /**
@@ -1682,29 +1685,19 @@ hdy_flap_set_flap (HdyFlap   *self,
   g_return_if_fail (HDY_IS_FLAP (self));
   g_return_if_fail (GTK_IS_WIDGET (flap) || flap == NULL);
 
-  if (self->flap == flap)
+  if (self->flap.widget == flap)
     return;
 
-  if (self->flap) {
-    if (gtk_widget_get_realized (GTK_WIDGET (self)))
-      unregister_window (self, &self->flap_window);
-
-    gtk_widget_unparent (self->flap);
-  }
-
-  self->flap = flap;
+  if (self->flap.widget)
+    remove_child (self, &self->flap);
 
-  if (self->flap) {
-    if (gtk_widget_get_realized (GTK_WIDGET (self))) {
-      register_window (self, self->flap, &self->flap_allocation, &self->flap_window);
-      restack_windows (self);
-    }
+  self->flap.widget = flap;
 
-    gtk_widget_set_parent (self->flap, GTK_WIDGET (self));
-  }
+  if (self->flap.widget)
+    add_child (self, &self->flap);
 
   if (self->tracker)
-    hdy_swipe_tracker_set_enabled (self->tracker, self->flap != NULL);
+    hdy_swipe_tracker_set_enabled (self->tracker, self->flap.widget != NULL);
 
   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_FLAP]);
 }
@@ -1722,7 +1715,7 @@ hdy_flap_get_separator (HdyFlap *self)
 {
   g_return_val_if_fail (HDY_IS_FLAP (self), NULL);
 
-  return self->separator;
+  return self->separator.widget;
 }
 
 /**
@@ -1739,29 +1732,16 @@ hdy_flap_set_separator (HdyFlap   *self,
   g_return_if_fail (HDY_IS_FLAP (self));
   g_return_if_fail (GTK_IS_WIDGET (separator) || separator == NULL);
 
-  if (self->separator == separator)
+  if (self->separator.widget == separator)
     return;
 
-  if (self->separator) {
-    if (gtk_widget_get_realized (GTK_WIDGET (self)))
-      unregister_window (self, &self->separator_window);
-
-    gtk_widget_unparent (self->separator);
-  }
+  if (self->separator.widget)
+    remove_child (self, &self->separator);
 
-  self->separator = separator;
+  self->separator.widget = separator;
 
-  if (self->separator) {
-    if (gtk_widget_get_realized (GTK_WIDGET (self))) {
-      register_window (self, self->separator, &self->separator_allocation, &self->separator_window);
-      restack_windows (self);
-    }
-
-    gtk_widget_set_parent (self->separator, GTK_WIDGET (self));
-  }
-
-  if (self->tracker)
-    hdy_swipe_tracker_set_enabled (self->tracker, self->separator != NULL);
+  if (self->separator.widget)
+    add_child (self, &self->separator);
 
   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SEPARATOR]);
 }


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