[gnome-tetravex] More advanced functions.
- From: Arnaud B. <arnaudb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-tetravex] More advanced functions.
- Date: Sat, 19 Oct 2019 00:51:55 +0000 (UTC)
commit 8f34d13fd004b31a03b77e79aac9a2f5ae6ceccc
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date: Fri Oct 18 04:15:58 2019 +0200
More advanced functions.
src/gnome-tetravex.vala | 60 ++++++++++++++---------
src/help-overlay.ui | 128 +++++++++++++++++++++++++++++++-----------------
src/puzzle-view.vala | 28 +++++------
src/puzzle.vala | 98 ++++++++++++++++++++----------------
4 files changed, 190 insertions(+), 124 deletions(-)
---
diff --git a/src/gnome-tetravex.vala b/src/gnome-tetravex.vala
index 1260a2a..fab26ef 100644
--- a/src/gnome-tetravex.vala
+++ b/src/gnome-tetravex.vala
@@ -91,21 +91,25 @@ private class Tetravex : Gtk.Application
private const GLib.ActionEntry[] action_entries =
{
- { "new-game", new_game_cb },
- { "pause", pause_cb },
- { "solve", solve_cb },
- { "finish", finish_cb },
- { "scores", scores_cb },
- { "quit", quit },
- { "move-up", move_up },
- { "move-down", move_down },
- { "move-left", move_left },
- { "move-right", move_right },
- { "undo", undo_cb },
- { "redo", redo_cb },
- { "size", null, "s", "'2'", size_changed },
- { "help", help_cb },
- { "about", about_cb }
+ { "new-game", new_game_cb },
+ { "pause", pause_cb },
+ { "solve", solve_cb },
+ { "finish", finish_cb },
+ { "scores", scores_cb },
+ { "quit", quit },
+ { "move-up-l", move_up_l },
+ { "move-down-l", move_down_l },
+ { "move-left-l", move_left_l },
+ { "move-right-l", move_right_l },
+ { "move-up-r", move_up_r },
+ { "move-down-r", move_down_r },
+ { "move-left-r", move_left_r },
+ { "move-right-r", move_right_r },
+ { "undo", undo_cb },
+ { "redo", redo_cb },
+ { "size", null, "s", "'2'", size_changed },
+ { "help", help_cb },
+ { "about", about_cb }
};
private static int main (string[] args)
@@ -180,10 +184,14 @@ private class Tetravex : Gtk.Application
set_accels_for_action ("app.pause", { "<Primary>p",
"Pause" });
set_accels_for_action ("app.quit", { "<Primary>q" });
- set_accels_for_action ("app.move-up", { "<Primary>Up" });
- set_accels_for_action ("app.move-down", { "<Primary>Down" });
- set_accels_for_action ("app.move-left", { "<Primary>Left" });
- set_accels_for_action ("app.move-right", { "<Primary>Right" });
+ set_accels_for_action ("app.move-up-l", { "<Primary>Up" });
+ set_accels_for_action ("app.move-down-l", { "<Primary>Down" });
+ set_accels_for_action ("app.move-left-l", { "<Primary>Left" });
+ set_accels_for_action ("app.move-right-l", { "<Primary>Right" });
+ set_accels_for_action ("app.move-up-r", { "<Shift><Primary>Up" });
+ set_accels_for_action ("app.move-down-r", { "<Shift><Primary>Down" });
+ set_accels_for_action ("app.move-left-r", { "<Shift><Primary>Left" });
+ set_accels_for_action ("app.move-right-r", { "<Shift><Primary>Right" });
set_accels_for_action ("app.undo", { "<Primary>z" });
set_accels_for_action ("app.redo", { "<Shift><Primary>z" });
// F1 and friends are managed manually
@@ -748,16 +756,20 @@ private class Tetravex : Gtk.Application
new_game ();
}
- private void move_up () { view.move_up (); }
- private void move_down () { view.move_down (); }
- private void move_left ()
+ private void move_up_l () { view.move_up (/* left board */ true); }
+ private void move_down_l () { view.move_down (/* left board */ true); }
+ private void move_left_l ()
{
if (!puzzle.is_solved_right)
- view.move_left ();
+ view.move_left (/* left board */ true);
else if (!puzzle.paused && !view.tile_selected)
finish_cb ();
}
- private void move_right () { view.move_right (); }
+ private void move_right_l () { view.move_right (/* left board */ true); }
+ private void move_up_r () { view.move_up (/* left board */ false); }
+ private void move_down_r () { view.move_down (/* left board */ false); }
+ private void move_left_r () { view.move_left (/* left board */ false); }
+ private void move_right_r () { view.move_right (/* left board */ false); }
private void undo_cb ()
{
diff --git a/src/help-overlay.ui b/src/help-overlay.ui
index 4d18b99..6b1195a 100644
--- a/src/help-overlay.ui
+++ b/src/help-overlay.ui
@@ -24,65 +24,58 @@
<child>
<object class="GtkShortcutsSection">
<property name="visible">1</property>
- <property name="max-height">8</property>
+ <property name="max-height">10</property>
<child>
<object class="GtkShortcutsGroup">
<property name="visible">1</property>
- <!-- Translators: title of a section in the Keyboard Shortcuts dialog; contains "New Game",
"Pause", "Scores"... -->
- <property name="title" translatable="yes" context="shortcut window">Main functions</property>
+ <!-- Translators: title of a section in the Keyboard Shortcuts dialog; contains "Select where to
play", "Play on selected tile", "Select the given row", etc. -->
+ <property name="title" translatable="yes" context="shortcut window">Play with keyboard</property>
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">1</property>
- <property name="accelerator"><Ctrl>N</property>
- <!-- Translators: Ctrl-N shortcut description in the Keyboard Shortcuts dialog, section Main
Functions -->
- <property name="title" translatable="yes" context="shortcut window">Start a new
game</property>
+ <!-- Translators: Left/Right/Up/Down arrows actions description in the Keyboard Shortcuts
dialog, section "Play with keyboard"; moves highlight -->
+ <property name="title" translatable="yes" context="shortcut window">Move keyboard
highlight</property>
+ <property name="accelerator">Left Right Up Down</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">1</property>
- <property name="accelerator"><Ctrl>P Pause</property>
- <!-- Translators: Ctrl-P shortcut description in the Keyboard Shortcuts dialog, section Main
Functions -->
- <property name="title" translatable="yes" context="shortcut window">Pause the game</property>
+ <!-- Translators: Return/space actions description in the Keyboard Shortcuts dialog, section
"Play with keyboard"; depend on context -->
+ <property name="title" translatable="yes" context="shortcut window">Select, move or
unselect</property>
+ <property name="accelerator">Return space</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">1</property>
- <property name="accelerator"><Ctrl>H</property>
- <!-- Translators: Ctrl-H shortcut description in the Keyboard Shortcuts dialog, section Main
Functions -->
- <property name="title" translatable="yes" context="shortcut window">Solve the game</property>
+ <!-- Translators: numbers (1 to 6) actions description in the Keyboard Shortcuts dialog,
section "Play with keyboard"; depending on game size, you can only use 1 to 2 or up to 1 to 6 -->
+ <property name="title" translatable="yes" context="shortcut window">Select the given
row</property>
+ <property name="accelerator">1...6</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">1</property>
- <property name="accelerator"><Ctrl>I</property>
- <!-- Translators: Ctrl-I shortcut description in the Keyboard Shortcuts dialog, section Main
Functions -->
- <property name="title" translatable="yes" context="shortcut window">Show scores</property>
+ <!-- Translators: alphabetical chars (a to f) actions description in the Keyboard Shortcuts
dialog, section "Play with keyboard"; depending on game size, you can only use a to b or up to a to f; the
board is splitted in two parts, that is for the left one -->
+ <property name="title" translatable="yes" context="shortcut window">Select left box
column</property>
+ <property name="accelerator">a...f</property>
</object>
</child>
- </object>
- </child>
- <child>
- <object class="GtkShortcutsGroup">
- <property name="visible">True</property>
- <!-- Translators: title of a section in the Keyboard Shortcuts dialog; contains "Select where to
play" and "Play on selected tile" -->
- <property name="title" translatable="yes" context="shortcut window">Play with keyboard</property>
<child>
<object class="GtkShortcutsShortcut">
- <property name="visible">True</property>
- <!-- Translators: Left/Right/Up/Down arrows actions description in the Keyboard Shortcuts
dialog, moves highlight -->
- <property name="title" translatable="yes" context="shortcut window">Move keyboard
highlight</property>
- <property name="accelerator">Left Right Up Down</property>
+ <property name="visible">1</property>
+ <!-- Translators: capital alphabetical chars (A to F) actions description in the Keyboard
Shortcuts dialog, section "Play with keyboard"; depending on game size, you can only use A to B or up to A to
F; the board is splitted in two parts, that is for the right one -->
+ <property name="title" translatable="yes" context="shortcut window">Select right box
column</property>
+ <property name="accelerator"><Shift>A...<Shift>F</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
- <property name="visible">True</property>
- <!-- Translators: Return/space actions description in the Keyboard Shortcuts dialog; depend
on context -->
- <property name="title" translatable="yes" context="shortcut window">Select, unselect, or
move selected tile</property>
- <property name="accelerator">Return space</property>
+ <property name="visible">1</property>
+ <property name="accelerator"><Ctrl>Left</property>
+ <!-- Translators: Ctrl-Left shortcut (in some contexts) description in the Keyboard
Shortcuts dialog, section "Play with keyboard"; allows user to finish puzzle on the right part of the board,
and to then "validate", moving all tiles at the same time on the lift part of the board -->
+ <property name="title" translatable="yes" context="shortcut window">Validate right
box</property>
</object>
</child>
</object>
@@ -96,7 +89,7 @@
<object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator"><Primary>z</property>
- <!-- Translators: F1 shortcut description in the Keyboard Shortcuts dialog, section History;
verb, undoes last move -->
+ <!-- Translators: Ctrl-Z shortcut description in the Keyboard Shortcuts dialog, section
History; verb, undoes last move -->
<property name="title" translatable="yes" context="shortcut window">Undo</property>
</object>
</child>
@@ -104,12 +97,51 @@
<object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator"><Shift><Primary>z</property>
- <!-- Translators: F1 shortcut description in the Keyboard Shortcuts dialog, section History;
verb, redoes undone move -->
+ <!-- Translators: Shift-Ctrl-Z shortcut description in the Keyboard Shortcuts dialog,
section History; verb, redoes undone move -->
<property name="title" translatable="yes" context="shortcut window">Redo</property>
</object>
</child>
</object>
</child>
+ <child>
+ <object class="GtkShortcutsGroup">
+ <property name="visible">1</property>
+ <!-- Translators: title of a section in the Keyboard Shortcuts dialog; contains "New Game",
"Pause", "Scores"... -->
+ <property name="title" translatable="yes" context="shortcut window">Main functions</property>
+ <child>
+ <object class="GtkShortcutsShortcut">
+ <property name="visible">1</property>
+ <property name="accelerator"><Ctrl>N</property>
+ <!-- Translators: Ctrl-N shortcut description in the Keyboard Shortcuts dialog, section Main
Functions -->
+ <property name="title" translatable="yes" context="shortcut window">Start a new
game</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkShortcutsShortcut">
+ <property name="visible">1</property>
+ <property name="accelerator"><Ctrl>P Pause</property>
+ <!-- Translators: Ctrl-P shortcut description in the Keyboard Shortcuts dialog, section Main
Functions -->
+ <property name="title" translatable="yes" context="shortcut window">Pause the game</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkShortcutsShortcut">
+ <property name="visible">1</property>
+ <property name="accelerator"><Ctrl>H</property>
+ <!-- Translators: Ctrl-H shortcut description in the Keyboard Shortcuts dialog, section Main
Functions -->
+ <property name="title" translatable="yes" context="shortcut window">Solve the game</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkShortcutsShortcut">
+ <property name="visible">1</property>
+ <property name="accelerator"><Ctrl>I</property>
+ <!-- Translators: Ctrl-I shortcut description in the Keyboard Shortcuts dialog, section Main
Functions -->
+ <property name="title" translatable="yes" context="shortcut window">Show scores</property>
+ </object>
+ </child>
+ </object>
+ </child>
<child>
<object class="GtkShortcutsGroup">
<property name="visible">1</property>
@@ -188,26 +220,34 @@
</child>
<child>
<object class="GtkShortcutsShortcut">
- <property name="visible">True</property>
- <!-- Translators: numbers (1 to 6) actions description in the Keyboard Shortcuts dialog,
section Advanced gameplay; depending on game size, you can only use 1 to 2 or up to 1 to 6 -->
- <property name="title" translatable="yes" context="shortcut window">Select the given row, up
to game size</property>
- <property name="accelerator">1...6</property>
+ <property name="visible">1</property>
+ <property name="accelerator"><Shift><Ctrl>Up</property>
+ <!-- Translators: Shift-Ctrl-Up shortcut description in the Keyboard Shortcuts dialog,
section Advanced gameplay -->
+ <property name="title" translatable="yes" context="shortcut window">Move all the pieces in
the right box up by one</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
- <property name="visible">True</property>
- <!-- Translators: alphabetical chars (a to f) actions description in the Keyboard Shortcuts
dialog, section Advanced gameplay; depending on game size, you can only use a to b or up to a to f; the board
is splitted in two parts, that is for the left one -->
- <property name="title" translatable="yes" context="shortcut window">Select the given column
in the left board, up to game size</property>
- <property name="accelerator">a...f</property>
+ <property name="visible">1</property>
+ <property name="accelerator"><Shift><Ctrl>Down</property>
+ <!-- Translators: Shift-Ctrl-Down shortcut description in the Keyboard Shortcuts dialog,
section Advanced gameplay -->
+ <property name="title" translatable="yes" context="shortcut window">Move all the pieces in
the right box down by one</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
- <property name="visible">True</property>
- <!-- Translators: capital alphabetical chars (A to F) actions description in the Keyboard
Shortcuts dialog, section Advanced gameplay; depending on game size, you can only use A to B or up to A to F;
the board is splitted in two parts, that is for the right one -->
- <property name="title" translatable="yes" context="shortcut window">Select the given column
in the right board, up to game size</property>
- <property name="accelerator"><Shift>A...<Shift>F</property>
+ <property name="visible">1</property>
+ <property name="accelerator"><Shift><Ctrl>Left</property>
+ <!-- Translators: Shift-Ctrl-Left shortcut description in the Keyboard Shortcuts dialog,
section Advanced gameplay -->
+ <property name="title" translatable="yes" context="shortcut window">Move all the pieces in
the right box left by one</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkShortcutsShortcut">
+ <property name="visible">1</property>
+ <property name="accelerator"><Shift><Ctrl>Right</property>
+ <!-- Translators: Shift-Ctrl-Right shortcut description in the Keyboard Shortcuts dialog,
section Advanced gameplay -->
+ <property name="title" translatable="yes" context="shortcut window">Move all the pieces in
the right box right by one</property>
</object>
</child>
</object>
diff --git a/src/puzzle-view.vala b/src/puzzle-view.vala
index 45306f3..737209e 100644
--- a/src/puzzle-view.vala
+++ b/src/puzzle-view.vala
@@ -568,17 +568,17 @@ private class PuzzleView : Gtk.DrawingArea
}
}
- if (!tile_selected && !on_right_half (x))
+ if (!tile_selected)
{
uint8 tile_x;
uint8 tile_y;
- if (get_left_tile_coords (x, y, out tile_x, out tile_y))
+ if (get_tile_coords (x, y, out tile_x, out tile_y))
puzzle.try_move (tile_x, tile_y);
}
}
- private inline bool get_left_tile_coords (double event_x, double event_y, out uint8 tile_x, out uint8
tile_y)
+ private inline bool get_tile_coords (double event_x, double event_y, out uint8 tile_x, out uint8 tile_y)
{
- if (!get_left_tile_coord_x (event_x, out tile_x))
+ if (!get_tile_coord_x (event_x, out tile_x))
{
tile_y = 0; // garbage
return false;
@@ -587,9 +587,9 @@ private class PuzzleView : Gtk.DrawingArea
return false;
return true;
}
- private inline bool get_left_tile_coord_x (double event_x, out uint8 tile_x)
+ private inline bool get_tile_coord_x (double event_x, out uint8 tile_x)
{
- for (tile_x = 0; tile_x < puzzle.size; tile_x++)
+ for (tile_x = 0; tile_x < 2 * puzzle.size; tile_x++)
if (event_x > sockets_xs [tile_x, 0] && event_x < sockets_xs [tile_x, 0] + tilesize)
return true;
return false;
@@ -1137,27 +1137,27 @@ private class PuzzleView : Gtk.DrawingArea
* * moving all tiles
\*/
- internal void move_up ()
+ internal void move_up (bool left_board)
{
if (selected_tile == null)
- puzzle.move_up ();
+ puzzle.move_up (left_board);
}
- internal void move_down ()
+ internal void move_down (bool left_board)
{
if (selected_tile == null)
- puzzle.move_down ();
+ puzzle.move_down (left_board);
}
- internal void move_left ()
+ internal void move_left (bool left_board)
{
if (selected_tile == null)
- puzzle.move_left ();
+ puzzle.move_left (left_board);
}
- internal void move_right ()
+ internal void move_right (bool left_board)
{
if (selected_tile == null)
- puzzle.move_right ();
+ puzzle.move_right (left_board);
}
}
diff --git a/src/puzzle.vala b/src/puzzle.vala
index 706ba67..49b0230 100644
--- a/src/puzzle.vala
+++ b/src/puzzle.vala
@@ -326,121 +326,135 @@ private class Puzzle : Object
_switch_tiles (x0, y0, x1, y1, /* delay if finished */ 0, /* undoing or redoing */ false,
last_move_id);
}
- internal void move_up ()
+ internal void move_up (bool left_board)
{
- if (!can_move_up () || last_move_id == uint.MAX)
+ if (!can_move_up (left_board) || last_move_id == uint.MAX)
return;
last_move_id++;
+ uint8 base_x = left_board ? 0 : size;
for (uint8 y = 1; y < size; y++)
for (uint8 x = 0; x < size; x++)
- switch_one_of_many_tiles (x, y, x, y - 1);
+ switch_one_of_many_tiles (base_x + x, y, base_x + x, y - 1);
}
- private bool can_move_up ()
+ private bool can_move_up (bool left_board)
{
+ uint8 base_x = left_board ? 0 : size;
for (uint8 x = 0; x < size; x++)
- if (board [x, 0] != null)
+ if (board [base_x + x, 0] != null)
return false;
return true;
}
- internal void move_down ()
+ internal void move_down (bool left_board)
{
- if (!can_move_down () || last_move_id == uint.MAX)
+ if (!can_move_down (left_board) || last_move_id == uint.MAX)
return;
last_move_id++;
+ uint8 base_x = left_board ? 0 : size;
for (uint8 y = size - 1; y > 0; y--)
for (uint8 x = 0; x < size; x++)
- switch_one_of_many_tiles (x, y - 1, x, y);
+ switch_one_of_many_tiles (base_x + x, y - 1, base_x + x, y);
}
- private bool can_move_down ()
+ private bool can_move_down (bool left_board)
{
+ uint8 base_x = left_board ? 0 : size;
for (uint8 x = 0; x < size; x++)
- if (board [x, size - 1] != null)
+ if (board [base_x + x, size - 1] != null)
return false;
return true;
}
- internal void move_left ()
+ internal void move_left (bool left_board)
{
- if (!can_move_left () || last_move_id == uint.MAX)
+ if (!can_move_left (left_board) || last_move_id == uint.MAX)
return;
last_move_id++;
+ uint8 base_x = left_board ? 0 : size;
for (uint8 x = 1; x < size; x++)
for (uint8 y = 0; y < size; y++)
- switch_one_of_many_tiles (x, y, x - 1, y);
+ switch_one_of_many_tiles (base_x + x, y, base_x + x - 1, y);
}
- private bool can_move_left ()
+ private bool can_move_left (bool left_board)
{
+ uint8 left_column = left_board ? 0 : size;
for (uint8 y = 0; y < size; y++)
- if (board [0, y] != null)
+ if (board [left_column, y] != null)
return false;
return true;
}
- internal void move_right ()
+ internal void move_right (bool left_board)
{
- if (!can_move_right () || last_move_id == uint.MAX)
+ if (!can_move_right (left_board) || last_move_id == uint.MAX)
return;
last_move_id++;
+ uint8 base_x = left_board ? 0 : size;
for (uint8 x = size - 1; x > 0; x--)
for (uint8 y = 0; y < size; y++)
- switch_one_of_many_tiles (x - 1, y, x, y);
+ switch_one_of_many_tiles (base_x + x - 1, y, base_x + x, y);
}
- private bool can_move_right ()
+ private bool can_move_right (bool left_board)
{
+ uint8 right_column = left_board ? size - 1 : 2 * size - 1;
for (uint8 y = 0; y < size; y++)
- if (board [size - 1, y] != null)
+ if (board [right_column, y] != null)
return false;
return true;
}
internal void try_move (uint8 x, uint8 y)
- requires (x >= 0 && x < size)
- requires (y >= 0 && y < size)
+ requires (x < 2 * size)
+ requires (y < size)
{
+ bool left_board = x < size;
switch (can_move (x, y))
{
- case Direction.UP: move_up (); return;
- case Direction.DOWN: move_down (); return;
- case Direction.LEFT: move_left (); return;
- case Direction.RIGHT: move_right (); return;
+ case Direction.UP: move_up (left_board); return;
+ case Direction.DOWN: move_down (left_board); return;
+ case Direction.LEFT: move_left (left_board); return;
+ case Direction.RIGHT: move_right (left_board); return;
case Direction.NONE:
- default: return;
+ default: return;
}
}
private inline Direction can_move (uint8 x, uint8 y)
{
- if (left_half_board_is_empty ())
+ bool left_board = x < size;
+ if (half_board_is_empty (left_board))
return Direction.NONE;
- if (y == 0 && can_move_up ()
- && !(x == 0 && can_move_left ())
- && !(x == size - 1 && can_move_right ()))
+ uint8 left_column = left_board ? 0 : size;
+ uint8 right_column = left_board ? size - 1 : size * 2 - 1;
+
+ if (y == 0 && can_move_up (left_board)
+ && !(x == left_column && can_move_left (left_board))
+ && !(x == right_column && can_move_right (left_board)))
return Direction.UP;
- if (y == size - 1 && can_move_down ()
- && !(x == 0 && can_move_left ())
- && !(x == size - 1 && can_move_right ()))
+ if (y == size - 1 && can_move_down (left_board)
+ && !(x == left_column && can_move_left (left_board))
+ && !(x == right_column && can_move_right (left_board)))
return Direction.DOWN;
- if (x == 0 && can_move_left ()
- && !(y == 0 && can_move_up ())
- && !(y == size - 1 && can_move_down ()))
+ if (x == left_column && can_move_left (left_board)
+ && !(y == 0 && can_move_up (left_board))
+ && !(y == size - 1 && can_move_down (left_board)))
return Direction.LEFT;
- if (x == size - 1 && can_move_right ()
- && !(y == 0 && can_move_up ())
- && !(y == size - 1 && can_move_down ()))
+ if (x == right_column && can_move_right (left_board)
+ && !(y == 0 && can_move_up (left_board))
+ && !(y == size - 1 && can_move_down (left_board)))
return Direction.RIGHT;
return Direction.NONE;
}
- private inline bool left_half_board_is_empty ()
+ private inline bool half_board_is_empty (bool left_board)
{
+ uint8 base_x = left_board ? 0 : size;
for (uint8 x = 0; x < size; x++)
for (uint8 y = 0; y < size; y++)
- if (board [x, y] != null)
+ if (board [base_x + x, y] != null)
return false;
return true;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]