[shotwell/wip/gtk4: 1/2] Editing Tools, part 2
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [shotwell/wip/gtk4: 1/2] Editing Tools, part 2
- Date: Mon, 18 Apr 2022 09:36:33 +0000 (UTC)
commit 619381b2ebcb3ba84b598d7269c237870f6188ad
Author: Jens Georg <mail jensge org>
Date: Sun Apr 17 14:17:48 2022 +0200
Editing Tools, part 2
src/Photo.vala | 8 +---
src/PhotoPage.vala | 66 +++++++++++---------------
src/direct/DirectPhotoPage.vala | 10 ++--
src/editing_tools/EditingTool.vala | 2 +-
src/editing_tools/EditingToolWindow.vala | 12 +----
src/editing_tools/PhotoCanvas.vala | 2 +-
src/editing_tools/RGBHistogramManipulator.vala | 4 +-
src/editing_tools/StraightenTool.vala | 40 ++++++++--------
src/meson.build | 1 +
9 files changed, 62 insertions(+), 83 deletions(-)
---
diff --git a/src/Photo.vala b/src/Photo.vala
index 6f7240a2..c758d0c9 100644
--- a/src/Photo.vala
+++ b/src/Photo.vala
@@ -3444,7 +3444,7 @@ public abstract class Photo : PhotoSource, Dateable, Positionable {
Dimensions scaled_to_viewport;
Dimensions original = Dimensions();
Dimensions scaled = Dimensions();
- //EditingTools.RedeyeInstance[] redeye_instances = null;
+ EditingTools.RedeyeInstance[] redeye_instances = null;
Box crop;
double straightening_angle;
PixelTransformer transformer = null;
@@ -3457,7 +3457,7 @@ public abstract class Photo : PhotoSource, Dateable, Positionable {
is_scaled = !(get_dimensions().equals(scaled));
- //redeye_instances = get_raw_redeye_instances();
+ redeye_instances = get_raw_redeye_instances();
is_cropped = get_raw_crop(out crop);
@@ -3485,11 +3485,9 @@ public abstract class Photo : PhotoSource, Dateable, Positionable {
#if MEASURE_PIPELINE
timer.start();
#endif
-#if 0
foreach (EditingTools.RedeyeInstance instance in redeye_instances) {
pixbuf = do_redeye(pixbuf, instance);
}
- #endif
#if MEASURE_PIPELINE
redeye_time = timer.elapsed();
#endif
@@ -4292,7 +4290,6 @@ public abstract class Photo : PhotoSource, Dateable, Positionable {
set_raw_straighten(theta);
}
- #if 0
private Gdk.Pixbuf do_redeye(Gdk.Pixbuf pixbuf, EditingTools.RedeyeInstance inst) {
/* we remove redeye within a circular region called the "effect
extent." the effect extent is inscribed within its "bounding
@@ -4356,7 +4353,6 @@ public abstract class Photo : PhotoSource, Dateable, Positionable {
return pixbuf;
}
- #endif
private Gdk.Pixbuf red_reduce_pixel(Gdk.Pixbuf pixbuf, int x, int y) {
int px_start_byte_offset = (y * pixbuf.get_rowstride()) +
diff --git a/src/PhotoPage.vala b/src/PhotoPage.vala
index 38d13e26..1f3697d7 100644
--- a/src/PhotoPage.vala
+++ b/src/PhotoPage.vala
@@ -371,20 +371,18 @@ public abstract class EditingHostPage : SinglePhotoPage {
public const int PIXBUF_CACHE_COUNT = 5;
public const int ORIGINAL_PIXBUF_CACHE_COUNT = 5;
- private class EditingHostCanvas : Object { //EditingTools.PhotoCanvas {
+ private class EditingHostCanvas : EditingTools.PhotoCanvas {
private EditingHostPage host_page;
public EditingHostCanvas(EditingHostPage host_page) {
- #if 0
- base(host_page.get_container(), host_page.canvas.get_window(), host_page.get_photo(),
+ base(host_page.get_container(), host_page.canvas.get_native().get_surface(),
host_page.get_photo(),
host_page.get_cairo_context(), host_page.get_surface_dim(), host_page.get_scaled_pixbuf(),
host_page.get_scaled_pixbuf_position());
- #endif
this.host_page = host_page;
}
- public /* override */ void repaint() {
+ public override void repaint() {
host_page.repaint();
}
}
@@ -405,9 +403,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
private Gtk.Scale zoom_slider = null;
private Gtk.Button prev_button = new Gtk.Button.with_label(Resources.PREVIOUS_LABEL);
private Gtk.Button next_button = new Gtk.Button.with_label(Resources.NEXT_LABEL);
- # if 0
private EditingTools.EditingTool current_tool = null;
- #endif
private Gtk.ToggleButton current_editing_toggle = null;
private Gdk.Pixbuf cancel_editing_pixbuf = null;
private bool photo_missing = false;
@@ -461,7 +457,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
crop_button.set_icon_name("image-crop-symbolic");
crop_button.set_label(Resources.CROP_LABEL);
crop_button.set_tooltip_text(Resources.CROP_TOOLTIP);
-// crop_button.toggled.connect(on_crop_toggled);
+ crop_button.toggled.connect(on_crop_toggled);
toolbar.append(crop_button);
// straightening tool
@@ -469,7 +465,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
straighten_button.set_icon_name(Resources.STRAIGHTEN);
straighten_button.set_label(Resources.STRAIGHTEN_LABEL);
straighten_button.set_tooltip_text(Resources.STRAIGHTEN_TOOLTIP);
-// straighten_button.toggled.connect(on_straighten_toggled);
+ straighten_button.toggled.connect(on_straighten_toggled);
toolbar.append(straighten_button);
// redeye reduction tool
@@ -477,7 +473,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
redeye_button.set_icon_name("stock-eye-symbolic");
redeye_button.set_label(Resources.RED_EYE_LABEL);
redeye_button.set_tooltip_text(Resources.RED_EYE_TOOLTIP);
-// redeye_button.toggled.connect(on_redeye_toggled;
+ redeye_button.toggled.connect(on_redeye_toggled);
toolbar.append(redeye_button);
// adjust tool
@@ -485,14 +481,14 @@ public abstract class EditingHostPage : SinglePhotoPage {
adjust_button.set_icon_name(Resources.ADJUST);
adjust_button.set_label(Resources.ADJUST_LABEL);
adjust_button.set_tooltip_text(Resources.ADJUST_TOOLTIP);
-// adjust_button.toggled.connect(on_adjust_toggled);
+ adjust_button.toggled.connect(on_adjust_toggled);
toolbar.append(adjust_button);
// enhance tool
enhance_button = new Gtk.Button.with_label (Resources.ENHANCE_LABEL);
enhance_button.set_icon_name(Resources.ENHANCE);
enhance_button.set_tooltip_text(Resources.ENHANCE_TOOLTIP);
-// enhance_button.clicked.connect(on_enhance);
+ enhance_button.clicked.connect(on_enhance);
toolbar.append (enhance_button);
#if ENABLE_FACES
@@ -867,7 +863,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
cancel_zoom();
is_pan_in_progress = false;
- //deactivate_tool();
+ deactivate_tool();
// Ticket #3255 - Checkerboard page didn't `remember` what was selected
// when the user went into and out of the photo page without navigating
@@ -885,7 +881,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
public override void switching_to_fullscreen(FullscreenWindow fsw) {
base.switching_to_fullscreen(fsw);
- //deactivate_tool();
+ deactivate_tool();
cancel_zoom();
is_pan_in_progress = false;
@@ -1104,7 +1100,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
enhance_button.sensitive = sensitivity;
zoom_slider.sensitive = sensitivity;
- ////deactivate_tool();
+ //deactivate_tool();
}
// This should only be called when it's known that the photo is actually missing.
@@ -1197,7 +1193,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
return;
}
- //deactivate_tool();
+ deactivate_tool();
// swap out new photo and old photo and process change
Photo old_photo = get_photo();
@@ -1358,7 +1354,6 @@ public abstract class EditingHostPage : SinglePhotoPage {
rotate_button.sensitive = ((photo != null) && (!photo_missing) && photo.check_can_rotate()) ?
is_rotate_available(photo) : false;
- #if 0
crop_button.sensitive = ((photo != null) && (!photo_missing)) ?
EditingTools.CropTool.is_available(photo, scaling) : false;
redeye_button.sensitive = ((photo != null) && (!photo_missing)) ?
@@ -1369,7 +1364,6 @@ public abstract class EditingHostPage : SinglePhotoPage {
is_enhance_available(photo) : false;
straighten_button.sensitive = ((photo != null) && (!photo_missing)) ?
EditingTools.StraightenTool.is_available(photo, scaling) : false;
- #endif
base.update_actions(selected_count, count);
}
@@ -1439,7 +1433,6 @@ public abstract class EditingHostPage : SinglePhotoPage {
}
}
-#if 0
private void activate_tool(EditingTools.EditingTool tool) {
// cancel any zoom -- we don't currently allow tools to be used when an image is zoomed,
// though we may at some point in the future.
@@ -1489,9 +1482,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
// repaint entire view, with the tool now hooked in
repaint();
}
- #endif
- #if 0
private void deactivate_tool(Command? command = null, Gdk.Pixbuf? new_pixbuf = null,
Dimensions new_max_dim = Dimensions(), bool needs_improvement = false) {
if (current_tool == null)
@@ -1500,6 +1491,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
EditingTools.EditingTool tool = current_tool;
current_tool = null;
+ #if 0
// save the position of the tool
EditingTools.EditingToolWindow? tool_window = tool.get_tool_window();
if (tool_window != null && tool_window.has_user_moved()) {
@@ -1508,6 +1500,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
last_locations[tool.name + "_x"] = last_location_x;
last_locations[tool.name + "_y"] = last_location_y;
}
+ #endif
// deactivate with the tool taken out of the hooks and
// disconnect any signals we may have connected on activating
@@ -1551,7 +1544,6 @@ public abstract class EditingHostPage : SinglePhotoPage {
if (command != null)
get_command_manager().execute(command);
}
- #endif
// This virtual method is called only when the user double-clicks on the page and no tool
// is active
@@ -1857,13 +1849,11 @@ public abstract class EditingHostPage : SinglePhotoPage {
}
protected override void paint(Cairo.Context ctx, Dimensions ctx_dim) {
- #if 0
if (current_tool != null) {
current_tool.paint(ctx);
return;
}
- #endif
if (photo_missing && has_photo()) {
set_source_color_from_string(ctx, "#000");
@@ -2075,8 +2065,9 @@ public abstract class EditingHostPage : SinglePhotoPage {
return base.on_ctrl_released(event);
}
+ #endif
- protected void on_tool_button_toggled(Gtk.ToggleToolButton toggle, EditingTools.EditingTool.Factory
factory) {
+ protected void on_tool_button_toggled(Gtk.ToggleButton toggle, EditingTools.EditingTool.Factory factory)
{
// if the button is an activate, deactivate any current tool running; if the button is
// a deactivate, deactivate the current tool and exit
bool deactivating_only = (!toggle.active && current_editing_toggle == toggle);
@@ -2190,7 +2181,6 @@ public abstract class EditingHostPage : SinglePhotoPage {
EnhanceSingleCommand command = new EnhanceSingleCommand(get_photo());
get_command_manager().execute(command);
}
- #endif
public void on_copy_adjustments() {
if (!has_photo())
@@ -2209,7 +2199,6 @@ public abstract class EditingHostPage : SinglePhotoPage {
get_command_manager().execute(command);
}
-#if 0
private void place_tool_window() {
if (current_tool == null)
return;
@@ -2220,9 +2209,10 @@ public abstract class EditingHostPage : SinglePhotoPage {
// do this so window size is properly allocated, but window not shown
tool_window.set_transient_for(AppWindow.get_instance());
- tool_window.show_all();
- tool_window.hide();
+ tool_window.show();
+ tool_window.present();
+ #if 0
Gtk.Allocation tool_alloc;
tool_window.get_allocation(out tool_alloc);
int x, y;
@@ -2284,11 +2274,11 @@ public abstract class EditingHostPage : SinglePhotoPage {
tool_window.move(x, y);
tool_window.show();
tool_window.present();
+ #endif
}
- #endif
protected override void on_next_photo() {
- //deactivate_tool();
+ deactivate_tool();
if (!has_photo())
return;
@@ -2321,7 +2311,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
}
protected override void on_previous_photo() {
- //deactivate_tool();
+ deactivate_tool();
if (!has_photo())
return;
@@ -2445,13 +2435,13 @@ public class LibraryPhotoPage : EditingHostPage {
{ "RotateCounterclockwise", on_rotate_counterclockwise },
{ "FlipHorizontally", on_flip_horizontally },
{ "FlipVertically", on_flip_vertically },
- //{ "Enhance", on_enhance },
+ { "Enhance", on_enhance },
{ "CopyColorAdjustments", on_copy_adjustments },
{ "PasteColorAdjustments", on_paste_adjustments },
- //{ "Crop", toggle_crop },
- //{ "Straighten", toggle_straighten },
- //{ "RedEye", toggle_redeye },
- //{ "Adjust", toggle_adjust },
+ { "Crop", toggle_crop },
+ { "Straighten", toggle_straighten },
+ { "RedEye", toggle_redeye },
+ { "Adjust", toggle_adjust },
{ "Revert", on_revert },
{ "EditTitle", on_edit_title },
{ "EditComment", on_edit_comment },
@@ -3209,7 +3199,7 @@ public class LibraryPhotoPage : EditingHostPage {
#if ENABLE_FACES
private void on_faces_toggled() {
- //on_tool_button_toggled(faces_button, FacesTool.factory);
+ on_tool_button_toggled(faces_button, FacesTool.factory);
}
protected void toggle_faces() {
diff --git a/src/direct/DirectPhotoPage.vala b/src/direct/DirectPhotoPage.vala
index d510a291..5b794ecd 100644
--- a/src/direct/DirectPhotoPage.vala
+++ b/src/direct/DirectPhotoPage.vala
@@ -50,11 +50,11 @@ public class DirectPhotoPage : EditingHostPage {
{ "RotateCounterclockwise", on_rotate_counterclockwise },
{ "FlipHorizontally", on_flip_horizontally },
{ "FlipVertically", on_flip_vertically },
- //{ "Enhance", on_enhance },
- //{ "Crop", toggle_crop },
- //{ "Straighten", toggle_straighten },
- //{ "RedEye", toggle_redeye },
- //{ "Adjust", toggle_adjust },
+ { "Enhance", on_enhance },
+ { "Crop", toggle_crop },
+ { "Straighten", toggle_straighten },
+ { "RedEye", toggle_redeye },
+ { "Adjust", toggle_adjust },
{ "Revert", on_revert },
{ "AdjustDateTime", on_adjust_date_time },
{ "SetBackground", on_set_background },
diff --git a/src/editing_tools/EditingTool.vala b/src/editing_tools/EditingTool.vala
index 083e9027..bd1e5fcf 100644
--- a/src/editing_tools/EditingTool.vala
+++ b/src/editing_tools/EditingTool.vala
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
-public abstract class EditingTool {
+public abstract class EditingTools.EditingTool {
public PhotoCanvas canvas = null;
private EditingToolWindow tool_window = null;
diff --git a/src/editing_tools/EditingToolWindow.vala b/src/editing_tools/EditingToolWindow.vala
index e11d4658..068e8b78 100644
--- a/src/editing_tools/EditingToolWindow.vala
+++ b/src/editing_tools/EditingToolWindow.vala
@@ -1,5 +1,5 @@
// SPDX-License-Identifier:LGPL-2.1-or-later
-public abstract class EditingToolWindow : Gtk.Window {
+public abstract class EditingTools.EditingToolWindow : Gtk.Window {
private const int FRAME_BORDER = 6;
private Gtk.Frame layout_frame = new Gtk.Frame(null);
@@ -16,6 +16,7 @@ public abstract class EditingToolWindow : Gtk.Window {
// add_events(Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.KEY_PRESS_MASK);
focusable = true;
set_can_focus(true);
+ ((Gtk.Widget) this).set_opacity(Resources.TRANSIENT_WINDOW_OPACITY);
}
~EditingToolWindow() {
@@ -29,7 +30,6 @@ public abstract class EditingToolWindow : Gtk.Window {
return user_moved;
}
- public signal
#if 0
public override bool key_press_event(Gdk.EventKey event) {
if (base.key_press_event(event)) {
@@ -50,14 +50,6 @@ public abstract class EditingToolWindow : Gtk.Window {
}
#endif
-
- public override void realize() {
- // Force the use of gtk_widget_set_opacity; gtk_window_set_opacity is deprecated
- ((Gtk.Widget) this).set_opacity(Resources.TRANSIENT_WINDOW_OPACITY);
-
- base.realize();
- }
-
private void suppress_warnings(string? log_domain, LogLevelFlags log_levels, string message) {
// do nothing.
}
diff --git a/src/editing_tools/PhotoCanvas.vala b/src/editing_tools/PhotoCanvas.vala
index c0b9e9c5..43318b20 100644
--- a/src/editing_tools/PhotoCanvas.vala
+++ b/src/editing_tools/PhotoCanvas.vala
@@ -2,7 +2,7 @@
// The PhotoCanvas is an interface object between an EditingTool and its host. It provides objects
// and primitives for an EditingTool to obtain information about the image, to draw on the host's
// canvas, and to be signalled when the canvas and its pixbuf changes (is resized).
-public abstract class PhotoCanvas {
+public abstract class EditingTools.PhotoCanvas {
private Gtk.Window container;
private Gdk.Surface drawing_window;
private Photo photo;
diff --git a/src/editing_tools/RGBHistogramManipulator.vala b/src/editing_tools/RGBHistogramManipulator.vala
index 8ad89be7..dc82475e 100644
--- a/src/editing_tools/RGBHistogramManipulator.vala
+++ b/src/editing_tools/RGBHistogramManipulator.vala
@@ -34,6 +34,7 @@ public class RGBHistogramManipulator : Gtk.DrawingArea {
public RGBHistogramManipulator( ) {
set_size_request(CONTROL_WIDTH, CONTROL_HEIGHT);
can_focus = true;
+ focusable = true;
var focus = new Gtk.EventControllerFocus();
focus.leave.connect(queue_draw);
@@ -55,6 +56,7 @@ public class RGBHistogramManipulator : Gtk.DrawingArea {
add_controller(motion);
this.resize.connect(on_resize);
+ set_draw_func(on_draw);
}
private void on_resize(int width, int height) {
@@ -204,7 +206,7 @@ public class RGBHistogramManipulator : Gtk.DrawingArea {
return true;
}
- public void draw(Cairo.Context ctx, int width, int height) {
+ public void on_draw(Gtk.DrawingArea self, Cairo.Context ctx, int width, int height) {
var sctx = get_style_context();
sctx.save();
sctx.set_state (Gtk.StateFlags.NORMAL);
diff --git a/src/editing_tools/StraightenTool.vala b/src/editing_tools/StraightenTool.vala
index f427b99b..6d3cc2e3 100644
--- a/src/editing_tools/StraightenTool.vala
+++ b/src/editing_tools/StraightenTool.vala
@@ -125,27 +125,27 @@ public class StraightenTool : EditingTool {
angle_label.set_size_request(MIN_LABEL_SIZE,-1);
Gtk.Box slider_layout = new Gtk.Box(Gtk.Orientation.HORIZONTAL, CONTROL_SPACING);
- slider_layout.pack_start(angle_slider, true, true, 0);
+ slider_layout.append(angle_slider);
Gtk.Box button_layout = new Gtk.Box(Gtk.Orientation.HORIZONTAL, CONTROL_SPACING);
cancel_button.set_size_request(MIN_BUTTON_SIZE, -1);
reset_button.set_size_request(MIN_BUTTON_SIZE, -1);
ok_button.set_size_request(MIN_BUTTON_SIZE, -1);
- button_layout.pack_start(cancel_button, true, true, 0);
- button_layout.pack_start(reset_button, true, true, 0);
- button_layout.pack_start(ok_button, true, true, 0);
+ button_layout.append(cancel_button);
+ button_layout.append(reset_button);
+ button_layout.append(ok_button);
Gtk.Box main_layout = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
- main_layout.pack_start(description_label, true, true, 0);
- main_layout.pack_start(slider_layout, true, true, 0);
- main_layout.pack_start(angle_label, true, true, 0);
- main_layout.pack_start(button_layout, true, true, 0);
+ main_layout.append(description_label);
+ main_layout.append(slider_layout);
+ main_layout.append(angle_label);
+ main_layout.append(button_layout);
add(main_layout);
reset_button.clicked.connect(on_reset_clicked);
- set_position(Gtk.WindowPosition.CENTER_ON_PARENT);
+ //set_position(Gtk.WindowPosition.CENTER_ON_PARENT);
}
private void on_reset_clicked() {
@@ -252,20 +252,20 @@ public class StraightenTool : EditingTool {
canvas.repaint();
}
- public override bool on_keypress(Gdk.EventKey event) {
- if ((Gdk.keyval_name(event.keyval) == "KP_Enter") ||
- (Gdk.keyval_name(event.keyval) == "Enter") ||
- (Gdk.keyval_name(event.keyval) == "Return")) {
+ public override bool on_keypress(Gtk.EventControllerKey event, uint keyval, uint keycode,
Gdk.ModifierType modifiers) {
+ if ((Gdk.keyval_name(keyval) == "KP_Enter") ||
+ (Gdk.keyval_name(keyval) == "Enter") ||
+ (Gdk.keyval_name(keyval) == "Return")) {
on_ok_clicked();
return true;
}
- if (Gdk.keyval_name(event.keyval) == "Escape") {
+ if (Gdk.keyval_name(keyval) == "Escape") {
notify_cancel();
return true;
}
- return base.on_keypress(event);
+ return base.on_keypress(event, keyval, keycode, modifiers);
}
private void prepare_image() {
@@ -359,9 +359,7 @@ public class StraightenTool : EditingTool {
// set crosshair cursor
var drawing_window = canvas.get_drawing_window ();
- var display = drawing_window.get_display ();
- var cursor = new Gdk.Cursor.for_display (display,
- Gdk.CursorType.CROSSHAIR);
+ var cursor = new Gdk.Cursor.from_name ("crosshair", null);
drawing_window.set_cursor (cursor);
window = new StraightenToolWindow(canvas.get_container());
@@ -375,7 +373,7 @@ public class StraightenTool : EditingTool {
window.angle_label.set_text(tmp);
high_qual_repaint();
- window.show_all();
+ window.show();
}
/**
@@ -407,14 +405,14 @@ public class StraightenTool : EditingTool {
}
private void bind_window_handlers() {
- window.key_press_event.connect(on_keypress);
+ //window.key_press_event.connect(on_keypress);
window.ok_button.clicked.connect(on_ok_clicked);
window.cancel_button.clicked.connect(notify_cancel);
window.angle_slider.value_changed.connect(on_angle_changed);
}
private void unbind_window_handlers() {
- window.key_press_event.disconnect(on_keypress);
+ //window.key_press_event.disconnect(on_keypress);
window.ok_button.clicked.disconnect(on_ok_clicked);
window.cancel_button.clicked.disconnect(notify_cancel);
window.angle_slider.value_changed.disconnect(on_angle_changed);
diff --git a/src/meson.build b/src/meson.build
index 7c8932ad..77091ba3 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -73,6 +73,7 @@ executable(
'editing_tools/CropTool.vala',
'editing_tools/PhotoCanvas.vala',
'editing_tools/RedeyeTool.vala',
+ 'editing_tools/StraightenTool.vala',
'editing_tools/EditingToolWindow.vala',
'editing_tools/RGBHistogramManipulator.vala',
'faces/Face.vala',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]