[Xword-commits] r76 - in trunk: . data data/icons debian root/usr root/usr/share root/usr/share/applications/hildon root/usr/share/dbus-1/services root/usr/share/xword

btb at garage.maemo.org btb at garage.maemo.org
Sat May 10 03:55:49 EEST 2008


Author: btb
Date: 2008-05-10 03:54:03 +0300 (Sat, 10 May 2008)
New Revision: 76

Added:
   trunk/data/
   trunk/data/backspace.xpm
   trunk/data/check.xpm
   trunk/data/crossword-check-all.png
   trunk/data/crossword-check.png
   trunk/data/crossword-clock.png
   trunk/data/crossword-solve.png
   trunk/data/down.xpm
   trunk/data/icons/
   trunk/data/icons/hicolor/
   trunk/data/left.xpm
   trunk/data/nextword.xpm
   trunk/data/prevword.xpm
   trunk/data/right.xpm
   trunk/data/solve.xpm
   trunk/data/swap.xpm
   trunk/data/up.xpm
   trunk/data/xword-logo.png
   trunk/data/xword-logo2.png
   trunk/data/xword.desktop
   trunk/data/xword.service
   trunk/xword
Removed:
   trunk/data/icons/hicolor/
   trunk/debian/xword.pypackager
   trunk/root/usr/bin/
   trunk/root/usr/share/applications/hildon/xword.desktop
   trunk/root/usr/share/dbus-1/services/xword.service
   trunk/root/usr/share/icons/
   trunk/root/usr/share/xword/backspace.xpm
   trunk/root/usr/share/xword/check.xpm
   trunk/root/usr/share/xword/crossword-check-all.png
   trunk/root/usr/share/xword/crossword-check.png
   trunk/root/usr/share/xword/crossword-clock.png
   trunk/root/usr/share/xword/crossword-solve.png
   trunk/root/usr/share/xword/down.xpm
   trunk/root/usr/share/xword/left.xpm
   trunk/root/usr/share/xword/nextword.xpm
   trunk/root/usr/share/xword/prevword.xpm
   trunk/root/usr/share/xword/right.xpm
   trunk/root/usr/share/xword/solve.xpm
   trunk/root/usr/share/xword/swap.xpm
   trunk/root/usr/share/xword/up.xpm
   trunk/root/usr/share/xword/xword-logo.png
   trunk/root/usr/share/xword/xword-logo2.png
Modified:
   trunk/debian/xword.install
Log:
get files organized since we don't need pypackager anymore


Copied: trunk/data/backspace.xpm (from rev 71, trunk/root/usr/share/xword/backspace.xpm)
===================================================================
--- trunk/data/backspace.xpm	                        (rev 0)
+++ trunk/data/backspace.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -0,0 +1,24 @@
+/* XPM */
+static char *backspace2_xpm[] = {
+"18 18 2 1",
+"0	c #000000",
+" 	c None",
+"                  ",
+"                  ",
+"                  ",
+"                  ",
+"      0           ",
+"     00           ",
+"    00            ",
+"   0000000000000  ",
+"  00           0  ",
+"  00           0  ",
+"   0000000000000  ",
+"    00            ",
+"     00           ",
+"      0           ",
+"                  ",
+"                  ",
+"                  ",
+"                  "
+};

Copied: trunk/data/check.xpm (from rev 71, trunk/root/usr/share/xword/check.xpm)
===================================================================
--- trunk/data/check.xpm	                        (rev 0)
+++ trunk/data/check.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -0,0 +1,24 @@
+/* XPM */
+static char *check_xpm[] = {
+"18 18 2 1",
+"0	c #000000",
+" 	c None",
+"                  ",
+"            0     ",
+"           0 0    ",
+"           0  0   ",
+"          0    0  ",
+"          0    0  ",
+"         0    0   ",
+"         0   0    ",
+"   0    0   0     ",
+"  0 0   0   0     ",
+" 0  0  0   0      ",
+" 0   00   0       ",
+"  0      0 0     0",
+"   0    0  0  0  0",
+"    0   0  0  0  0",
+"     0 0   0  0  0",
+"      0    0 0 0 0",
+"            0   0 "
+};

Copied: trunk/data/crossword-check-all.png (from rev 71, trunk/root/usr/share/xword/crossword-check-all.png)
===================================================================
(Binary files differ)

Copied: trunk/data/crossword-check.png (from rev 71, trunk/root/usr/share/xword/crossword-check.png)
===================================================================
(Binary files differ)

Copied: trunk/data/crossword-clock.png (from rev 71, trunk/root/usr/share/xword/crossword-clock.png)
===================================================================
(Binary files differ)

Copied: trunk/data/crossword-solve.png (from rev 71, trunk/root/usr/share/xword/crossword-solve.png)
===================================================================
(Binary files differ)

Copied: trunk/data/down.xpm (from rev 71, trunk/root/usr/share/xword/down.xpm)
===================================================================
--- trunk/data/down.xpm	                        (rev 0)
+++ trunk/data/down.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -0,0 +1,24 @@
+/* XPM */
+static char *down2_xpm[] = {
+"18 18 2 1",
+"0	c #000000",
+" 	c None",
+"        00        ",
+"        00        ",
+"        00        ",
+"        00        ",
+"        00        ",
+"        00        ",
+"        00        ",
+"        00        ",
+"        00        ",
+"        00        ",
+"        00        ",
+"  00    00    00  ",
+"   00   00   00   ",
+"    00  00  00    ",
+"     00 00 00     ",
+"      000000      ",
+"       0000       ",
+"        00        "
+};

Copied: trunk/data/icons (from rev 71, trunk/root/usr/share/icons)

Copied: trunk/data/icons/hicolor (from rev 75, trunk/root/usr/share/icons/hicolor)

Copied: trunk/data/left.xpm (from rev 71, trunk/root/usr/share/xword/left.xpm)
===================================================================
--- trunk/data/left.xpm	                        (rev 0)
+++ trunk/data/left.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -0,0 +1,24 @@
+/* XPM */
+static char *left2_xpm[] = {
+"18 18 2 1",
+"0	c #000000",
+" 	c None",
+"                  ",
+"                  ",
+"      0           ",
+"     00           ",
+"    00            ",
+"   00             ",
+"  00              ",
+" 00               ",
+"000000000000000000",
+"000000000000000000",
+" 00               ",
+"  00              ",
+"   00             ",
+"    00            ",
+"     00           ",
+"      0           ",
+"                  ",
+"                  "
+};

Copied: trunk/data/nextword.xpm (from rev 71, trunk/root/usr/share/xword/nextword.xpm)
===================================================================
--- trunk/data/nextword.xpm	                        (rev 0)
+++ trunk/data/nextword.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -0,0 +1,24 @@
+/* XPM */
+static char *nextword2_xpm[] = {
+"18 18 2 1",
+"0	c #000000",
+" 	c None",
+"                  ",
+"                  ",
+"   0    0         ",
+"   00   00        ",
+"    00   00       ",
+"     00   00      ",
+"      00   00     ",
+"       00   00    ",
+"        00   00   ",
+"        00   00   ",
+"       00   00    ",
+"      00   00     ",
+"     00   00      ",
+"    00   00       ",
+"   00   00        ",
+"   0    0         ",
+"                  ",
+"                  "
+};

Copied: trunk/data/prevword.xpm (from rev 71, trunk/root/usr/share/xword/prevword.xpm)
===================================================================
--- trunk/data/prevword.xpm	                        (rev 0)
+++ trunk/data/prevword.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -0,0 +1,24 @@
+/* XPM */
+static char *prevword2_xpm[] = {
+"18 18 2 1",
+"0	c #000000",
+" 	c None",
+"                  ",
+"                  ",
+"         0    0   ",
+"        00   00   ",
+"       00   00    ",
+"      00   00     ",
+"     00   00      ",
+"    00   00       ",
+"   00   00        ",
+"   00   00        ",
+"    00   00       ",
+"     00   00      ",
+"      00   00     ",
+"       00   00    ",
+"        00   00   ",
+"         0    0   ",
+"                  ",
+"                  "
+};

Copied: trunk/data/right.xpm (from rev 71, trunk/root/usr/share/xword/right.xpm)
===================================================================
--- trunk/data/right.xpm	                        (rev 0)
+++ trunk/data/right.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -0,0 +1,24 @@
+/* XPM */
+static char *right2_xpm[] = {
+"18 18 2 1",
+"0	c #000000",
+" 	c None",
+"                  ",
+"                  ",
+"           0      ",
+"           00     ",
+"            00    ",
+"             00   ",
+"              00  ",
+"               00 ",
+"000000000000000000",
+"000000000000000000",
+"               00 ",
+"              00  ",
+"             00   ",
+"            00    ",
+"           00     ",
+"           0      ",
+"                  ",
+"                  "
+};

Copied: trunk/data/solve.xpm (from rev 71, trunk/root/usr/share/xword/solve.xpm)
===================================================================
--- trunk/data/solve.xpm	                        (rev 0)
+++ trunk/data/solve.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -0,0 +1,24 @@
+/* XPM */
+static char *solve_xpm[] = {
+"18 18 2 1",
+"0	c #000000",
+" 	c None",
+"                  ",
+"      000         ",
+"    00   00       ",
+"   0       0      ",
+"  0   000   0     ",
+"  0  0   0  0     ",
+"  0000   0  0     ",
+"        0   0     ",
+"       0   0      ",
+"      0   0       ",
+"     0   0        ",
+"     0000         ",
+"           0     0",
+"     0000  0  0  0",
+"     0  0  0  0  0",
+"     0  0  0  0  0",
+"     0000  0 0 0 0",
+"            0   0 "
+};

Copied: trunk/data/swap.xpm (from rev 71, trunk/root/usr/share/xword/swap.xpm)
===================================================================
--- trunk/data/swap.xpm	                        (rev 0)
+++ trunk/data/swap.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -0,0 +1,24 @@
+/* XPM */
+static char *swap2_xpm[] = {
+"18 18 2 1",
+"0	c #000000",
+" 	c None",
+"  000             ",
+"  0 0             ",
+"00000000000000000 ",
+"0 0 0 0 0 0 0 0 0 ",
+"00000000000000000 ",
+"  0 0             ",
+"  000          0  ",
+"  0 0         000 ",
+"  000        0 0 0",
+"  0 0          0  ",
+"  000          0  ",
+"  0 0          0  ",
+"  000         0   ",
+"  0 0   0    0    ",
+"  000  0    0     ",
+"  0 0 000000      ",
+"  000  0          ",
+"        0         "
+};

Copied: trunk/data/up.xpm (from rev 71, trunk/root/usr/share/xword/up.xpm)
===================================================================
--- trunk/data/up.xpm	                        (rev 0)
+++ trunk/data/up.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -0,0 +1,24 @@
+/* XPM */
+static char *up2_xpm[] = {
+"18 18 2 1",
+"0	c #000000",
+" 	c None",
+"        00        ",
+"       0000       ",
+"      000000      ",
+"     00 00 00     ",
+"    00  00  00    ",
+"   00   00   00   ",
+"  00    00    00  ",
+"        00        ",
+"        00        ",
+"        00        ",
+"        00        ",
+"        00        ",
+"        00        ",
+"        00        ",
+"        00        ",
+"        00        ",
+"        00        ",
+"        00        "
+};

Copied: trunk/data/xword-logo.png (from rev 71, trunk/root/usr/share/xword/xword-logo.png)
===================================================================
(Binary files differ)

Copied: trunk/data/xword-logo2.png (from rev 71, trunk/root/usr/share/xword/xword-logo2.png)
===================================================================
(Binary files differ)

Copied: trunk/data/xword.desktop (from rev 71, trunk/root/usr/share/applications/hildon/xword.desktop)
===================================================================
--- trunk/data/xword.desktop	                        (rev 0)
+++ trunk/data/xword.desktop	2008-05-10 00:54:03 UTC (rev 76)
@@ -0,0 +1,13 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0.0
+Name=Xword
+GenericName=Crossword Puzzles
+Comment=Play crossword puzzles
+Exec=/usr/bin/xword
+X-Osso-Service=org.maemo.xword
+Icon=xword
+Terminal=false
+Type=Application
+MimeType=application/x-crossword;
+Categories=Game;LogicGame;

Copied: trunk/data/xword.service (from rev 71, trunk/root/usr/share/dbus-1/services/xword.service)
===================================================================
--- trunk/data/xword.service	                        (rev 0)
+++ trunk/data/xword.service	2008-05-10 00:54:03 UTC (rev 76)
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.maemo.xword
+Exec=/usr/bin/xword

Modified: trunk/debian/xword.install
===================================================================
--- trunk/debian/xword.install	2008-05-10 00:15:32 UTC (rev 75)
+++ trunk/debian/xword.install	2008-05-10 00:54:03 UTC (rev 76)
@@ -1,6 +1,7 @@
-root/usr/share/applications/hildon/xword.desktop usr/share/applications/hildon/
-root/usr/share/dbus-1/services/xword.service usr/share/dbus-1/services/
-root/usr/share/icons/hicolor/26x26/apps/xword.png usr/share/icons/hicolor/26x26/apps/
-root/usr/share/icons/hicolor/scalable/apps/xword.png usr/share/icons/hicolor/scalable/apps/
-root/usr/share/xword/* usr/share/xword/
-root/usr/bin/xword usr/bin
+data/xword.desktop usr/share/applications/hildon/
+data/xword.service usr/share/dbus-1/services/
+data/icons/hicolor/26x26/apps/xword.png usr/share/icons/hicolor/26x26/apps/
+data/icons/hicolor/scalable/apps/xword.png usr/share/icons/hicolor/scalable/apps/
+data/*.png usr/share/xword/
+data/*.xpm usr/share/xword/
+xword usr/bin

Deleted: trunk/debian/xword.pypackager
===================================================================
--- trunk/debian/xword.pypackager	2008-05-10 00:15:32 UTC (rev 75)
+++ trunk/debian/xword.pypackager	2008-05-10 00:54:03 UTC (rev 76)
@@ -1,16 +0,0 @@
-(S'xword'
-S'1.0.7'
-S'games'
-S'all'
-S'optional'
-S'Bradley Bell <bradleyb at u.washington.edu>'
-S'python2.5, python2.5-hildon, python2.5-gtk2, python2.5-osso'
-S'Reads and writes crossword puzzles in the Across Lite file format.\n Xword is a Python / GTK program that allows you to solve puzzles in\n the Across Lite file format used by The New York Times and other\n sources. It has a clock for timing yourself. It also autosaves puzzles\n as you solve them so you can return to partially completed puzzles.'
-S'/home/user/trunk/root'
-S'/home/user/trunk/root/usr/share/icons/hicolor/scalable/apps/xword.png'
-S'#!/bin/sh\n/usr/bin/gtk-update-icon-cache -f /usr/share/icons/hicolor > /dev/null 2>&1'
-S'#!/bin/sh\n/usr/bin/gtk-update-icon-cache -f /usr/share/icons/hicolor > /dev/null 2>&1'
-S''
-S''
-tp1
-.

Deleted: trunk/root/usr/share/applications/hildon/xword.desktop
===================================================================
--- trunk/root/usr/share/applications/hildon/xword.desktop	2008-05-10 00:15:32 UTC (rev 75)
+++ trunk/root/usr/share/applications/hildon/xword.desktop	2008-05-10 00:54:03 UTC (rev 76)
@@ -1,13 +0,0 @@
-[Desktop Entry]
-Encoding=UTF-8
-Version=1.0.0
-Name=Xword
-GenericName=Crossword Puzzles
-Comment=Play crossword puzzles
-Exec=/usr/bin/xword
-X-Osso-Service=org.maemo.xword
-Icon=xword
-Terminal=false
-Type=Application
-MimeType=application/x-crossword;
-Categories=Game;LogicGame;

Deleted: trunk/root/usr/share/dbus-1/services/xword.service
===================================================================
--- trunk/root/usr/share/dbus-1/services/xword.service	2008-05-10 00:15:32 UTC (rev 75)
+++ trunk/root/usr/share/dbus-1/services/xword.service	2008-05-10 00:54:03 UTC (rev 76)
@@ -1,3 +0,0 @@
-[D-BUS Service]
-Name=org.maemo.xword
-Exec=/usr/bin/xword

Deleted: trunk/root/usr/share/xword/backspace.xpm
===================================================================
--- trunk/root/usr/share/xword/backspace.xpm	2008-05-10 00:15:32 UTC (rev 75)
+++ trunk/root/usr/share/xword/backspace.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -1,24 +0,0 @@
-/* XPM */
-static char *backspace2_xpm[] = {
-"18 18 2 1",
-"0	c #000000",
-" 	c None",
-"                  ",
-"                  ",
-"                  ",
-"                  ",
-"      0           ",
-"     00           ",
-"    00            ",
-"   0000000000000  ",
-"  00           0  ",
-"  00           0  ",
-"   0000000000000  ",
-"    00            ",
-"     00           ",
-"      0           ",
-"                  ",
-"                  ",
-"                  ",
-"                  "
-};

Deleted: trunk/root/usr/share/xword/check.xpm
===================================================================
--- trunk/root/usr/share/xword/check.xpm	2008-05-10 00:15:32 UTC (rev 75)
+++ trunk/root/usr/share/xword/check.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -1,24 +0,0 @@
-/* XPM */
-static char *check_xpm[] = {
-"18 18 2 1",
-"0	c #000000",
-" 	c None",
-"                  ",
-"            0     ",
-"           0 0    ",
-"           0  0   ",
-"          0    0  ",
-"          0    0  ",
-"         0    0   ",
-"         0   0    ",
-"   0    0   0     ",
-"  0 0   0   0     ",
-" 0  0  0   0      ",
-" 0   00   0       ",
-"  0      0 0     0",
-"   0    0  0  0  0",
-"    0   0  0  0  0",
-"     0 0   0  0  0",
-"      0    0 0 0 0",
-"            0   0 "
-};

Deleted: trunk/root/usr/share/xword/crossword-check-all.png
===================================================================
(Binary files differ)

Deleted: trunk/root/usr/share/xword/crossword-check.png
===================================================================
(Binary files differ)

Deleted: trunk/root/usr/share/xword/crossword-clock.png
===================================================================
(Binary files differ)

Deleted: trunk/root/usr/share/xword/crossword-solve.png
===================================================================
(Binary files differ)

Deleted: trunk/root/usr/share/xword/down.xpm
===================================================================
--- trunk/root/usr/share/xword/down.xpm	2008-05-10 00:15:32 UTC (rev 75)
+++ trunk/root/usr/share/xword/down.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -1,24 +0,0 @@
-/* XPM */
-static char *down2_xpm[] = {
-"18 18 2 1",
-"0	c #000000",
-" 	c None",
-"        00        ",
-"        00        ",
-"        00        ",
-"        00        ",
-"        00        ",
-"        00        ",
-"        00        ",
-"        00        ",
-"        00        ",
-"        00        ",
-"        00        ",
-"  00    00    00  ",
-"   00   00   00   ",
-"    00  00  00    ",
-"     00 00 00     ",
-"      000000      ",
-"       0000       ",
-"        00        "
-};

Deleted: trunk/root/usr/share/xword/left.xpm
===================================================================
--- trunk/root/usr/share/xword/left.xpm	2008-05-10 00:15:32 UTC (rev 75)
+++ trunk/root/usr/share/xword/left.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -1,24 +0,0 @@
-/* XPM */
-static char *left2_xpm[] = {
-"18 18 2 1",
-"0	c #000000",
-" 	c None",
-"                  ",
-"                  ",
-"      0           ",
-"     00           ",
-"    00            ",
-"   00             ",
-"  00              ",
-" 00               ",
-"000000000000000000",
-"000000000000000000",
-" 00               ",
-"  00              ",
-"   00             ",
-"    00            ",
-"     00           ",
-"      0           ",
-"                  ",
-"                  "
-};

Deleted: trunk/root/usr/share/xword/nextword.xpm
===================================================================
--- trunk/root/usr/share/xword/nextword.xpm	2008-05-10 00:15:32 UTC (rev 75)
+++ trunk/root/usr/share/xword/nextword.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -1,24 +0,0 @@
-/* XPM */
-static char *nextword2_xpm[] = {
-"18 18 2 1",
-"0	c #000000",
-" 	c None",
-"                  ",
-"                  ",
-"   0    0         ",
-"   00   00        ",
-"    00   00       ",
-"     00   00      ",
-"      00   00     ",
-"       00   00    ",
-"        00   00   ",
-"        00   00   ",
-"       00   00    ",
-"      00   00     ",
-"     00   00      ",
-"    00   00       ",
-"   00   00        ",
-"   0    0         ",
-"                  ",
-"                  "
-};

Deleted: trunk/root/usr/share/xword/prevword.xpm
===================================================================
--- trunk/root/usr/share/xword/prevword.xpm	2008-05-10 00:15:32 UTC (rev 75)
+++ trunk/root/usr/share/xword/prevword.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -1,24 +0,0 @@
-/* XPM */
-static char *prevword2_xpm[] = {
-"18 18 2 1",
-"0	c #000000",
-" 	c None",
-"                  ",
-"                  ",
-"         0    0   ",
-"        00   00   ",
-"       00   00    ",
-"      00   00     ",
-"     00   00      ",
-"    00   00       ",
-"   00   00        ",
-"   00   00        ",
-"    00   00       ",
-"     00   00      ",
-"      00   00     ",
-"       00   00    ",
-"        00   00   ",
-"         0    0   ",
-"                  ",
-"                  "
-};

Deleted: trunk/root/usr/share/xword/right.xpm
===================================================================
--- trunk/root/usr/share/xword/right.xpm	2008-05-10 00:15:32 UTC (rev 75)
+++ trunk/root/usr/share/xword/right.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -1,24 +0,0 @@
-/* XPM */
-static char *right2_xpm[] = {
-"18 18 2 1",
-"0	c #000000",
-" 	c None",
-"                  ",
-"                  ",
-"           0      ",
-"           00     ",
-"            00    ",
-"             00   ",
-"              00  ",
-"               00 ",
-"000000000000000000",
-"000000000000000000",
-"               00 ",
-"              00  ",
-"             00   ",
-"            00    ",
-"           00     ",
-"           0      ",
-"                  ",
-"                  "
-};

Deleted: trunk/root/usr/share/xword/solve.xpm
===================================================================
--- trunk/root/usr/share/xword/solve.xpm	2008-05-10 00:15:32 UTC (rev 75)
+++ trunk/root/usr/share/xword/solve.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -1,24 +0,0 @@
-/* XPM */
-static char *solve_xpm[] = {
-"18 18 2 1",
-"0	c #000000",
-" 	c None",
-"                  ",
-"      000         ",
-"    00   00       ",
-"   0       0      ",
-"  0   000   0     ",
-"  0  0   0  0     ",
-"  0000   0  0     ",
-"        0   0     ",
-"       0   0      ",
-"      0   0       ",
-"     0   0        ",
-"     0000         ",
-"           0     0",
-"     0000  0  0  0",
-"     0  0  0  0  0",
-"     0  0  0  0  0",
-"     0000  0 0 0 0",
-"            0   0 "
-};

Deleted: trunk/root/usr/share/xword/swap.xpm
===================================================================
--- trunk/root/usr/share/xword/swap.xpm	2008-05-10 00:15:32 UTC (rev 75)
+++ trunk/root/usr/share/xword/swap.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -1,24 +0,0 @@
-/* XPM */
-static char *swap2_xpm[] = {
-"18 18 2 1",
-"0	c #000000",
-" 	c None",
-"  000             ",
-"  0 0             ",
-"00000000000000000 ",
-"0 0 0 0 0 0 0 0 0 ",
-"00000000000000000 ",
-"  0 0             ",
-"  000          0  ",
-"  0 0         000 ",
-"  000        0 0 0",
-"  0 0          0  ",
-"  000          0  ",
-"  0 0          0  ",
-"  000         0   ",
-"  0 0   0    0    ",
-"  000  0    0     ",
-"  0 0 000000      ",
-"  000  0          ",
-"        0         "
-};

Deleted: trunk/root/usr/share/xword/up.xpm
===================================================================
--- trunk/root/usr/share/xword/up.xpm	2008-05-10 00:15:32 UTC (rev 75)
+++ trunk/root/usr/share/xword/up.xpm	2008-05-10 00:54:03 UTC (rev 76)
@@ -1,24 +0,0 @@
-/* XPM */
-static char *up2_xpm[] = {
-"18 18 2 1",
-"0	c #000000",
-" 	c None",
-"        00        ",
-"       0000       ",
-"      000000      ",
-"     00 00 00     ",
-"    00  00  00    ",
-"   00   00   00   ",
-"  00    00    00  ",
-"        00        ",
-"        00        ",
-"        00        ",
-"        00        ",
-"        00        ",
-"        00        ",
-"        00        ",
-"        00        ",
-"        00        ",
-"        00        ",
-"        00        "
-};

Deleted: trunk/root/usr/share/xword/xword-logo.png
===================================================================
(Binary files differ)

Deleted: trunk/root/usr/share/xword/xword-logo2.png
===================================================================
(Binary files differ)

Copied: trunk/xword (from rev 74, trunk/root/usr/bin/xword)
===================================================================
--- trunk/xword	                        (rev 0)
+++ trunk/xword	2008-05-10 00:54:03 UTC (rev 76)
@@ -0,0 +1,2279 @@
+#!/usr/bin/python
+
+__version__ = "1.0.7"
+
+__license__ = """
+Copyright (c) 2005-2006,
+  Bill McCloskey    <bill.mccloskey at gmail.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+3. The names of the contributors may not be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+"""
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gtk.gdk
+import gobject
+
+try:
+    import hildon
+    has_hildon = True
+except:
+    has_hildon = False
+
+try:
+    import osso
+    has_osso = True
+except:
+    has_osso = False
+
+try:
+    import gnomeprint
+    import gnomeprint.ui
+    has_print = True
+except:
+    has_print = False
+
+import pango
+import sys
+import time
+import os, os.path
+import md5
+import pickle
+import ConfigParser
+
+HOME_PATH = '/usr/share/xword'
+if os.path.exists('data/check.xpm'): HOME_PATH = 'data'
+CHECK_ICON = HOME_PATH + '/crossword-check.png'
+CHECK_ALL_ICON = HOME_PATH + '/crossword-check-all.png'
+SOLVE_ICON = HOME_PATH + '/crossword-solve.png'
+TIMER_ICON = HOME_PATH + '/crossword-clock.png'
+ABOUT_ICON = HOME_PATH + '/xword-logo2.png'
+
+MIN_BOX_SIZE = 12 
+MAX_BOX_SIZE = 40
+
+ACROSS = 0
+DOWN = 1
+
+NO_ERROR = 0
+MISTAKE = 1
+FIXED_MISTAKE = 2
+CHEAT = 3
+
+MENU_OPEN = 1
+MENU_SAVE = 2
+MENU_PRINT = 3
+MENU_CLOSE = 4
+MENU_QUIT = 5
+
+MENU_SKIP = 10
+
+layouts = [
+    ('Only Puzzle', 'puzzle'),
+    ('Right Side', ('H', 'puzzle', 550, ('V', 'across', 250, 'down'))),
+    ('Left Side', ('H', ('V', 'across', 250, 'down'), 200, 'puzzle')),
+    ('Left and Right', ('H', ('H', 'across', 175, 'puzzle'), 725, 'down')),
+    ('Top', ('V', ('H', 'across', 450, 'down'), 200, 'puzzle')),
+    ('Bottom', ('V', 'puzzle', 400, ('H', 'across', 450, 'down'))),
+    ('Top and Bottom', ('V', 'across', 150, ('V', 'puzzle', 300, 'down')))
+    ]
+
+toolbar_layouts = [
+    ('Off', 'puzzle', 'N'),
+    ('Checks on Left', 'checks','L'),
+    ('Checks on Right', 'checks','R'),
+    ('Keyboard on Left', 'keyboard','L'),
+    ('Keyboard on Right', 'keyboard','R')
+    ]
+
+
+def time_str(t):
+    total = int(t)
+    secs = total % 60
+    mins = (total / 60) % 60
+    hrs = (total / 3600)
+    return "%d:%02d:%02d" % (hrs, mins, secs)
+
+class BinaryFile:
+    def __init__(self, filename=None):
+        f = file(filename, 'rb')
+        self.data = list(f.read())
+        f.close()
+        self.index = 0
+
+    def save(self, filename):
+        f = file(filename, 'wb+')
+        f.write(''.join(self.data))
+        f.close()
+
+    def seek(self, pos):
+        self.index = pos
+
+    def write_char(self, c):
+        self.data[self.index] = c
+        self.index += 1
+
+    def read_char(self):
+        c = self.data[self.index]
+        self.index += 1
+        return c
+
+    def read_chars(self, n):
+        c = []
+        for i in range(n):
+            c.append(self.read_char())
+        return c
+
+    def read_byte(self):
+        return ord(self.read_char())
+
+    def read_short(self):
+        return self.read_byte() + 256 * self.read_byte()
+
+    def read_string(self):
+        if self.index == len(self.data): return ''
+        s = ''
+        c = self.read_char()
+        while ord(c) is not 0 and self.index < len(self.data):
+            s += c
+            c = self.read_char()
+
+        result = s
+        ellipsis_char = 133
+        result = result.replace(chr(ellipsis_char), '...')
+        result = unicode(result, 'iso_8859-1')
+        return result
+
+    def hashcode(self):
+        m = md5.new()
+        m.update(''.join(self.data))
+        return m.hexdigest()
+
+class PersistentPuzzle:
+    def __init__(self):
+        self.responses = {}
+        self.errors = {}
+        self.clock = 0
+        self.notes = ''
+
+    def get_size(self, m):
+        width = 0
+        height = 0
+        for (x, y) in m.keys():
+            if x > width: width = x
+            if y > height: height = y
+        width += 1
+        height += 1
+
+        return (width, height)
+
+    def to_binary(self):
+        (width, height) = self.get_size(self.responses)
+        bin1 = [' ']*width*height
+        bin2 = [' ']*width*height
+
+        for ((x, y), r) in self.responses.items():
+            index = y * width + x
+            bin1[index] = self.responses[x, y]
+            if bin1[index] == '': bin1[index] = chr(0)
+
+        for ((x, y), r) in self.errors.items():
+            index = y * width + x
+            bin2[index] = chr(self.errors[x, y])
+
+        bin = ''.join(bin1 + bin2)
+        return '%d %d %d %s %s%c' % (width, height, int(self.clock), bin, self.notes, chr(0))
+
+    def get_int(self, s, pos):
+        pos0 = pos
+        while pos < len(s) and s[pos].isdigit(): pos += 1
+        return (int(s[pos0:pos]), pos)
+
+    def get_string(self, s, pos):
+        str = ''
+        while pos < len(s) and ord(s[pos]) is not 0:
+            str += s[pos]
+            pos += 1
+        return (str, pos)
+
+    def from_binary(self, bin):
+        pos = 0
+        (width, pos) = self.get_int(bin, pos)
+        pos += 1
+        (height, pos) = self.get_int(bin, pos)
+        pos += 1
+        (self.clock, pos) = self.get_int(bin, pos)
+        pos += 1
+
+        count = width*height
+        bin1 = bin[pos:pos+count]
+        pos += count
+        bin2 = bin[pos:pos+count]
+        pos += count
+
+        pos += 1
+        (self.notes, pos) = self.get_string(bin, pos)
+
+        self.responses = {}
+        self.errors = {}
+
+        i = 0
+        for y in range(height):
+            for x in range(width):
+                if bin1[i] == chr(0): self.responses[x, y] = ''
+                else: self.responses[x, y] = bin1[i]
+                self.errors[x, y] = ord(bin2[i])
+                i += 1
+
+class Puzzle:
+    def __init__(self, filename):
+        self.load_file(filename)
+
+    def load_file(self, filename):
+        f = BinaryFile(filename)
+        self.f = f
+
+        cksum = f.read_short()
+        file_magic = f.read_string()
+        assert(file_magic == "ACROSS&DOWN")
+
+        cksum_cib = f.read_short()
+        magic_10 = f.read_chars(4)
+        magic_14 = f.read_chars(4)
+        # most puzzles are v 1.2, cryptic puzzles are 1.3
+        puz_version = f.read_string()
+
+        f.seek(0x2c)
+        self.width = f.read_byte()
+        self.height = f.read_byte()
+        self.clue_count = f.read_short()
+
+        f.seek(0x34)
+        self.answers = {}
+        self.errors = {}
+        for y in range(self.height):
+            for x in range(self.width):
+                self.answers[x, y] = f.read_char()
+                self.errors[x, y] = NO_ERROR
+
+        self.responses = {}
+        for y in range(self.height):
+            for x in range(self.width):
+                c = f.read_char()
+                if c == '-': c = ''
+                self.responses[x, y] = c
+
+        def massage(s):
+            # skips unprintable characters
+            snew = ''
+            for c in s:
+                if ord(c) >= ord(' ') and ord(c) <= ord('~'): snew += c
+            return snew
+
+        self.title = massage(f.read_string())
+        self.author = massage(f.read_string())
+        self.copyright = massage(f.read_string())
+
+        self.clues = []
+        for n in range(self.clue_count):
+            self.clues.append(f.read_string())
+
+        self.all_clues = self.clues[:]
+
+        self.notes = f.read_string()
+
+        self.setup()
+
+    def setup(self):
+        self.across_clues = {}
+        self.down_clues = {}
+        self.across_map = {}
+        self.down_map = {}
+        self.number_map = {}
+        self.number_rev_map = {}
+        self.mode_maps = [self.across_map, self.down_map]
+        self.mode_clues = [self.across_clues, self.down_clues]
+        self.is_across = {}
+        self.is_down = {}
+        number = 1
+        used_number = False
+        for y in range(self.height):
+            for x in range(self.width):
+                is_fresh_x = self.is_black(x-1, y)
+                is_fresh_y = self.is_black(x, y-1)
+
+                if not self.is_black(x, y):
+                    if is_fresh_x:
+                        if self.is_black(x+1, y):
+                            self.across_map[x, y] = 0
+                        else:
+                            self.across_map[x, y] = number
+                            self.across_clues[number] = self.clues.pop(0)
+                            used_number = True
+                    else: self.across_map[x, y] = self.across_map[x-1, y]
+
+                    if is_fresh_y:
+                        if self.is_black(x, y+1): # see April 30, 2006 puzzle
+                            self.down_map[x, y] = 0
+                        else:
+                            self.down_map[x, y] = number
+                            self.down_clues[number] = self.clues.pop(0)
+                            used_number = True
+                    else: self.down_map[x, y] = self.down_map[x, y-1]
+
+                    if used_number:
+                        self.is_across[number] = is_fresh_x
+                        self.is_down[number] = is_fresh_y
+                        self.number_map[number] = (x, y)
+                        self.number_rev_map[x, y] = number
+                        number += 1
+                        used_number = False
+                else:
+                    self.across_map[x, y] = 0
+                    self.down_map[x, y] = 0
+        self.max_number = number-1
+
+    def hashcode(self):
+        (width, height) = (self.width, self.height)
+
+        data = [' ']*width*height
+        for ((x, y), r) in self.responses.items():
+            index = y * width + x
+            if r == '.': data[index] = '1'
+            else: data[index] = '0'
+
+        s1 = ''.join(data)
+        s2 = ';'.join(self.all_clues)
+
+        m = md5.new()
+        m.update(s1 + s2)
+        return m.hexdigest()
+
+    def save(self, fname):
+        f = self.f
+        f.seek(0x34 + self.width * self.height)
+        for y in range(self.height):
+            for x in range(self.width):
+                c = self.responses[x, y]
+                if c == '': c = '-'
+                f.write_char(c)
+        f.save(fname)
+
+    def is_black(self, x, y):
+        return self.responses.get((x, y), '.') == '.'
+
+    def clue(self, x, y, mode):
+        if mode is ACROSS: return self.across_clues[self.across_map[x, y]]
+        if mode is DOWN: return self.down_clues[self.down_map[x, y]]
+
+    def number(self, x, y, mode):
+        return self.mode_maps[mode][x, y]
+
+    def next_cell(self, x, y, mode, incr, skip_black):
+        (xo, yo) = (x, y)
+        while True:
+            if mode is ACROSS:
+                if x+incr < 0 or x+incr >= self.width: return ((x, y), True)
+                x += incr
+            else:
+                if y+incr < 0 or y+incr >= self.height: return ((x, y), True)
+                y += incr
+
+            if not skip_black or not self.is_black(x, y): break
+            (xo, yo) = (x, y)
+
+        if self.is_black(x, y): return ((xo, yo), True)
+        else: return ((x, y), False)
+
+    def find_blank_cell_recursive(self, x, y, mode, incr):
+        if self.responses[x, y] == '' or self.errors[x, y] == MISTAKE:
+            return (x, y)
+        else:
+            ((x, y), hit) = self.next_cell(x, y, mode, incr, False)
+            if hit: return None
+            else: return self.find_blank_cell_recursive(x, y, mode, incr)
+
+    def find_blank_cell(self, x, y, mode, incr):
+        r = self.find_blank_cell_recursive(x, y, mode, incr)
+        if r == None: return (x, y)
+        else: return r
+
+    def is_cell_correct(self, x, y):
+        return self.responses[x, y] == self.answers[x, y]
+
+    def is_puzzle_correct(self):
+        for x in range(self.width):
+            for y in range(self.height):
+                if not self.is_black(x, y) and not self.is_cell_correct(x, y):
+                    return False
+        return True
+
+    def incr_number(self, x, y, mode, incr):
+        n = self.mode_maps[mode][x, y]
+        while True:
+            n += incr
+            if not self.number_map.has_key(n): return 0
+            if mode == ACROSS and self.is_across[n]: break
+            if mode == DOWN and self.is_down[n]: break
+        return n
+
+    def final_number(self, mode):
+        n = self.max_number
+        while True:
+            if mode == ACROSS and self.is_across[n]: break
+            if mode == DOWN and self.is_down[n]: break
+            n -= 1
+        return n
+
+class PrintFont:
+    def __init__(self, family, style, size):
+        self.face = gnomeprint.font_face_find_from_family_and_style(family,
+                                                                    style)
+        self.font = gnomeprint.font_find_closest(self.face.get_name(), size)
+        self.size = size
+
+    def measure_text(self, s):
+        w = 0.0
+        for c in s:
+            glyph = self.face.lookup_default(ord(c))
+            w += self.face.get_glyph_width(glyph) * 0.001 *self.font.get_size()
+        return w
+
+class ClueArea:
+    def __init__(self, puzzle, font_size, col_height_fun):
+        self.puzzle = puzzle
+
+        self.clue_font = PrintFont('Serif', 'Regular', font_size)
+        self.label_font = PrintFont('Serif', 'Bold', font_size)
+
+        spacer = 'This is the width of a column'
+        self.col_width = self.clue_font.measure_text(spacer)
+        self.num_width = self.clue_font.measure_text('100. ')
+        self.text_width = (self.col_width - self.num_width) * 0.9
+
+        self.col_height_fun = col_height_fun
+        self.col_num = 0
+        
+        self.y = self.col_height_fun(0, self.col_width) - self.clue_font.size
+        self.x = self.num_width
+
+        self.items = []
+        self.group_start = None
+        self.setup()
+
+    def add_item(self, x, y, font, text):
+        self.items = self.items + [(x, y, font, text)]
+
+    def nextcol(self):
+        self.col_num += 1
+        self.x += self.col_width
+
+        x = self.x - self.num_width
+        h = self.col_height_fun(x, x + self.col_width)
+        self.y = h - self.clue_font.size
+
+    def open_group(self):
+        self.group_start = self.items
+        if self.y < 0: self.nextcol()
+
+    def close_group(self):
+        if self.y < 0:
+            self.items = self.group_start
+            return False
+        else:
+            return True
+
+    def draw(self, gpc, x0, y0):
+        for (x, y, font, text) in self.items:
+            gpc.setfont(font.font)
+            gpc.moveto(x + x0, y + y0)
+            gpc.show(text)
+
+    def add_wrapped_text(self, width, font, text):
+        words = text.split(' ')
+        lines = []
+        while len(words) > 0:
+            w = 0.0
+            line = []
+            while len(words) > 0 and w < width:
+                if len(line) > 0:
+                    w += font.measure_text(' ')
+                word = words.pop(0)
+                line.append(word)
+                w += font.measure_text(word)
+
+            if w >= width and len(line) == 1:
+                i = 0
+                w = 0.0
+                word = line[0]
+                while True:
+                    w += font.measure_text(word[i])
+                    if w > width: break
+                    i += 1
+                line = [word[:i]]
+                words = [word[i:]] + words
+            elif w >= width:
+                words = [line.pop()] + words
+            lines.append(line)
+
+        for line in lines:
+            s = ' '.join(line)
+            self.add_item(self.x, self.y, font, s)
+            self.y -= font.size
+
+    def add_space(self, pct):
+        self.y -= self.clue_font.size * pct
+
+    def add_label(self, label):
+        start = self.x
+        stop = self.x + self.text_width
+        w = self.label_font.measure_text(label)
+        x0 = start + (stop - start - w)/2
+
+        self.add_item(x0, self.y, self.label_font, label)
+        self.y -= self.label_font.size
+
+    def add_column(self, name, mode):
+        first = True
+        for n in range(1, self.puzzle.max_number+1):
+            m = self.puzzle.mode_clues[mode]
+            if m.has_key(n):
+                clue = m[n]
+                num = '%d. ' % n
+                nw = self.clue_font.measure_text(num)
+
+                while True:
+                    self.open_group()
+                    if first:
+                        self.add_label(name)
+                        self.add_space(1.0)
+                        
+                    self.add_item(self.x - nw, self.y, self.clue_font, num)
+                    self.add_wrapped_text(self.text_width,self.clue_font, clue)
+
+                    if self.close_group(): break
+
+                self.add_space(0.5)
+                if first: first = False
+
+    def setup(self):
+        self.add_column('Across', ACROSS)
+        self.add_space(1.0)
+        self.add_column('Down', DOWN)
+
+    def width(self):
+        return (self.col_num + 1) * self.col_width
+
+class PuzzlePrinter:
+    def __init__(self, puzzle):
+        self.puzzle = puzzle
+
+    def draw_banner(self, r):
+        (left, bottom, right, top) = r
+
+        h = top - bottom
+        size = int(h * 0.7)
+        font = PrintFont('Serif', 'Regular', size)
+
+        self.gpc.setfont(font.font)
+        width = font.measure_text(self.puzzle.title)
+        x0 = left + (right - left - width)/2
+        y0 = top - size
+        self.gpc.moveto(x0, y0)
+        self.gpc.show(self.puzzle.title)
+
+    def draw_box(self, x, y, r):
+        (left, bottom, right, top) = r
+        gpc = self.gpc
+
+        gpc.rect_stroked(left, bottom, (right-left), (top-bottom))
+        if self.puzzle.is_black(x, y):
+            gpc.rect_filled(left, bottom, (right-left), (top-bottom))
+
+        if self.puzzle.number_rev_map.has_key((x, y)):
+            gpc.setfont(self.num_font.font)
+            n = self.puzzle.number_rev_map[x, y]
+            gpc.moveto(left + self.box_size*0.05, top - self.box_size*0.35)
+            gpc.show(str(n))
+
+        gpc.setfont(self.let_font.font)
+        w = self.let_font.measure_text(self.puzzle.responses[x, y])
+        x0 = left + (right - left - w)/2
+        gpc.moveto(x0, bottom + self.box_size*0.2)
+        gpc.show(self.puzzle.responses[x, y])
+
+        if self.puzzle.errors[x, y] != NO_ERROR:
+            gpc.moveto(right - self.box_size*0.3, top)
+            gpc.lineto(right, top)
+            gpc.lineto(right, top - self.box_size*0.3)
+            gpc.fill()
+
+    def min_puzzle_size(self, r):
+        puzzle = self.puzzle
+        (left, bottom, right, top) = r
+
+        self.banner_size = 18
+
+        bw = (right - left)/float(puzzle.width)
+        bh = (top - bottom - self.banner_size)/float(puzzle.height)
+        box_size = int(min(bw, bh))
+        self.box_size = box_size
+
+        w = box_size * puzzle.width
+        h = box_size * puzzle.height
+        return (w, h + self.banner_size)
+
+    def draw_puzzle(self, r):
+        puzzle = self.puzzle
+        box_size = self.box_size
+        (left, bottom, right, top) = r
+
+        w = box_size * puzzle.width
+        h = box_size * puzzle.height
+
+        banner_box = (left, top - self.banner_size, right, top)
+        self.draw_banner(banner_box)
+
+        left += ((right - left) - w)/2
+        top -= self.banner_size
+
+        self.num_font = PrintFont('Sans', 'Regular', box_size * 0.3)
+        self.let_font = PrintFont('Sans', 'Regular', box_size * 0.6)
+
+        for y in range(puzzle.height):
+            for x in range(puzzle.width):
+                r = (left + x*box_size,
+                     top - (y+1)*box_size,
+                     left + (x+1)*box_size,
+                     top - y*box_size)
+                self.draw_box(x, y, r)
+
+    def draw_clues(self, r, coltop):
+        (left, bottom, right, top) = r
+
+        maxw = right - left
+
+        def coltoprel(x0, x1):
+            return coltop(x0 + left, x1 + left) - bottom
+
+        size = 12
+        while True:
+            area = ClueArea(self.puzzle, size, coltoprel)
+            w = area.width()
+            if w <= maxw: break
+            size -= 1
+
+        area.draw(self.gpc, left, bottom)
+        return area.col_width
+
+    def units(self, length):
+        i = 0
+        while i < len(length) and (length[i].isdigit() or length[i] == '.'):
+            i += 1
+        num = length[:i].strip()
+        units = length[i:].strip()
+
+        if units == '': return float(num)
+
+        u = gnomeprint.unit_get_by_abbreviation(units)
+        if u == None:
+            print 'Bad unit:', length
+            return 0.0
+        return float(num) * u.unittobase
+        
+    def draw(self, config):
+        w = self.units(config.get(gnomeprint.KEY_PAPER_WIDTH))
+        h = self.units(config.get(gnomeprint.KEY_PAPER_HEIGHT))
+        
+        left = self.units(config.get(gnomeprint.KEY_PAGE_MARGIN_LEFT))
+        top = self.units(config.get(gnomeprint.KEY_PAGE_MARGIN_TOP))
+        right = self.units(config.get(gnomeprint.KEY_PAGE_MARGIN_RIGHT))
+        bottom = self.units(config.get(gnomeprint.KEY_PAGE_MARGIN_BOTTOM))
+
+        if config.get(gnomeprint.KEY_PAGE_ORIENTATION) == 'R90':
+            (w, h) = (h, w)
+            (left, bottom, right, top) = (bottom, left, top, right)
+
+        right = w - right
+        top = h - top
+        banner_size = 14
+
+        self.gpc.beginpage("1")
+
+        #self.gpc.rect_stroked(left, bottom, right-left, top-bottom)
+
+        if h > w:
+            mid = (top + bottom) / 2
+            r = (left, mid, right, top)
+        else:
+            mid = (left + right)/2
+            r = (left, bottom, mid, top)
+
+        (w, h) = self.min_puzzle_size(r)
+        h += 0.05 * h
+
+        def coltop(x0, x1):
+            if ((x0 >= left and x0 <= left+w) or (x1 >= left and x1 <= left+w)
+                or (x0 <= left and x1 >= left+w)):
+                return top - h
+            else:
+                return top
+            
+        fullr = (left, bottom, right, top)
+        col_width = self.draw_clues(fullr, coltop)
+
+        w = int((w+col_width-1)/col_width) * col_width
+        r = (r[0], r[1], left+w, r[3])
+        self.draw_puzzle(r)
+
+        self.gpc.showpage()
+
+    def do_preview(self, config, dialog):
+        job = gnomeprint.Job(config)
+        self.gpc = job.get_context()
+        job.close()
+        self.draw(config)
+        w = gnomeprint.ui.JobPreview(job, 'Print Preview')
+        w.set_property('allow-grow', 1)
+        w.set_property('allow-shrink', 1)
+        w.set_transient_for(dialog)
+        w.show_all()
+
+    def do_print(self, dialog, res, job):
+        config = job.get_config()
+
+        if res == gnomeprint.ui.DIALOG_RESPONSE_CANCEL:
+            dialog.destroy()
+        elif res == gnomeprint.ui.DIALOG_RESPONSE_PREVIEW:
+            self.do_preview(config, dialog)
+        elif res == gnomeprint.ui.DIALOG_RESPONSE_PRINT:
+            dialog.destroy()
+            self.gpc = job.get_context()
+            self.draw(config)
+            job.close()
+            job.print_()
+
+    def print_puzzle(self, win):
+        job = gnomeprint.Job(gnomeprint.config_default())
+        dialog = gnomeprint.ui.Dialog(job, "Print...", 0)
+        dialog.connect('response', self.do_print, job)
+        dialog.set_transient_for(win)
+        dialog.show()
+
+class PuzzleWidget:
+    def __init__(self, puzzle, control, min_box_size=20):
+        self.puzzle = puzzle
+        self.control = control
+        self.min_box_size = min_box_size
+        
+        self.area = gtk.DrawingArea()
+        self.pango = self.area.create_pango_layout('')
+        self.area.connect('expose-event', self.expose_event)
+        self.area.connect('configure-event', self.configure_event)
+        self.area.set_flags(gtk.CAN_FOCUS)
+
+        self.sw = gtk.ScrolledWindow()
+        self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        self.sw.add_with_viewport(self.area)
+
+        self.widget = self.sw
+        self.set_puzzle(puzzle, control)
+
+    def set_puzzle(self, puzzle, control):
+        self.puzzle = puzzle
+        self.control = control
+
+        if puzzle:
+            width = puzzle.width * self.min_box_size
+            height = puzzle.height * self.min_box_size
+            self.area.set_size_request(width, height)
+        else:
+            self.box_size = self.min_box_size
+
+        self.area.queue_draw_area(0, 0, 32768, 32768)
+
+    def configure_event(self, area, event):
+        width, height = event.width, event.height
+
+        if self.puzzle:
+            bw = width / self.puzzle.width
+            bh = height / self.puzzle.height
+            self.box_size = min(bw, bh)
+            
+            self.width = self.box_size * self.puzzle.width
+            self.height = self.box_size * self.puzzle.height
+            
+            self.x = (width - self.width) / 2
+            self.y = (height - self.height) / 2
+        else:
+            self.width = width
+            self.height = height
+            self.x = 0
+            self.y = 0
+
+    def expose_event(self, area, event):
+        if self.puzzle: self.draw_puzzle()
+        else: self.draw_empty()
+
+    def draw_empty(self):
+        pass
+
+    def draw_puzzle(self):
+        view = self.area.window
+        cm = view.get_colormap()
+        self.white = cm.alloc_color('white')
+        self.black = cm.alloc_color('black')
+        self.red = cm.alloc_color('red')
+        self.gray = cm.alloc_color('LightGray')
+
+        num_size = int(self.box_size * 0.25)
+        let_size = int(self.box_size * 0.45)
+        self.num_font = pango.FontDescription('Sans %d' % num_size)
+        self.let_font = pango.FontDescription('Sans %d' % let_size)
+
+        self.gc = view.new_gc(foreground = self.white, background = self.white)
+        view.draw_rectangle(self.gc, True, self.x, self.y,
+                            self.width, self.height)
+
+        self.gc.set_foreground(self.black)
+        view.draw_rectangle(self.gc, False, self.x, self.y,
+                            self.width, self.height)
+
+        for y in range(self.puzzle.height):
+            for x in range(self.puzzle.width):
+                self.draw_box(x, y)
+        
+        return True
+
+    def draw_triangle(self, x0, y0, color, filled):
+        view = self.area.window
+
+        self.gc.set_foreground(color)
+        length = int(self.box_size * 0.3)
+        view.draw_polygon(self.gc, filled,
+                          [(x0 + self.box_size - length, y0),
+                           (x0 + self.box_size, y0),
+                           (x0 + self.box_size, y0 + length)])
+        self.gc.set_foreground(self.black)
+
+    def draw_box_data(self, x0, y0, n, letter, error):
+        view = self.area.window
+
+        self.pango.set_font_description(self.num_font)
+        self.pango.set_text(n)
+        view.draw_layout(self.gc, int(x0 + self.box_size*0.08), y0, self.pango)
+
+        self.pango.set_font_description(self.let_font)
+        self.pango.set_text(letter)
+        (w, h) = self.pango.get_pixel_size()
+        x1 = int(x0 + (self.box_size - w) / 2)
+        y1 = int(y0 + self.box_size * 0.3)
+        view.draw_layout(self.gc, x1, y1, self.pango)
+
+        if error == MISTAKE:
+            view.draw_line(self.gc, x0, y0,
+                           x0 + self.box_size, y0 + self.box_size)
+            view.draw_line(self.gc, x0, y0 + self.box_size,
+                           x0 + self.box_size, y0)
+        elif error == FIXED_MISTAKE:
+            self.draw_triangle(x0, y0, self.black, True)
+        elif error == CHEAT:
+            self.draw_triangle(x0, y0, self.red, True)
+            self.draw_triangle(x0, y0, self.black, False)
+
+    def draw_box(self, x, y):
+        view = self.area.window
+
+        x0 = self.x + x*self.box_size
+        y0 = self.y + y*self.box_size
+
+        if self.control.is_main_selection(x, y): color = self.red
+        elif self.control.is_selected(x, y): color = self.gray
+        elif self.puzzle.is_black(x, y): color = self.black
+        else: color = self.white
+
+        self.gc.set_foreground(color)
+        view.draw_rectangle(self.gc, True, x0, y0,
+                            self.box_size, self.box_size)
+
+        self.gc.set_foreground(self.black)
+        view.draw_rectangle(self.gc, False, x0, y0,
+                            self.box_size, self.box_size)
+
+        letter = self.puzzle.responses[x, y]
+        error = self.puzzle.errors[x, y]
+        
+        if self.puzzle.number_rev_map.has_key((x, y)):
+            n = str(self.puzzle.number_rev_map[x, y])
+        else:
+            n = ''
+
+        self.draw_box_data(x0, y0, n, letter, error)
+
+    def translate_position(self, x, y):
+        x -= self.x
+        y -= self.y
+        return (int(x / self.box_size), int(y / self.box_size))
+
+    def update(self, x, y):
+        x0 = self.x + x*self.box_size
+        y0 = self.y + y*self.box_size
+        self.area.queue_draw_area(x0, y0, self.box_size, self.box_size)
+
+class ClueWidget:
+    def __init__(self, control):
+        self.control = control
+
+        width = 0
+        height = 22
+
+        self.area = gtk.DrawingArea()
+        self.pango = self.area.create_pango_layout('')
+        self.area.set_size_request(width, height)
+        self.area.connect('expose-event', self.expose_event)
+        self.area.connect('configure-event', self.configure_event)
+
+        self.widget = self.area
+
+    def set_controller(self, control):
+        self.control = control
+        self.update()
+
+    def configure_event(self, area, event):
+        self.width, self.height = event.width, event.height
+        self.pango.set_width(self.width * pango.SCALE)
+        
+    def expose_event(self, area, event):
+        view = self.area.window
+        cm = view.get_colormap()
+        self.black = cm.alloc_color('black')
+        self.gc = view.new_gc(foreground = self.black)
+        
+        size = 14
+        while True:
+            font = pango.FontDescription('Sans %d' % size)
+            self.pango.set_font_description(font)
+            self.pango.set_text(self.control.get_selected_word())
+            w, h = self.pango.get_pixel_size()
+
+            if h <= self.height: break
+            size -= 1
+
+        x = (self.width - w) / 2
+        y = (self.height - h) / 2
+        view.draw_layout(self.gc, x, y, self.pango)
+
+    def update(self):
+        self.area.queue_draw_area(0, 0, self.width, self.height)
+
+class PuzzleController:
+    def __init__(self, puzzle):
+        self.puzzle = puzzle
+
+        self.handlers = []
+        self.selection = []
+
+        self.mode = ACROSS
+        (x, y) = (0, 0)
+        if puzzle.is_black(x, y):
+            ((x, y), _) = puzzle.next_cell(0, 0, ACROSS, 1, True)
+        self.move_to(x, y)
+
+    def connect(self, ev, handler):
+        self.handlers.append((ev, handler))
+
+    def do_update(self, signal_ev, *args):
+        for (ev, h) in self.handlers:
+            if ev == signal_ev: h(*args)
+
+    def signal(self):
+        self.move_to(self.x, self.y)
+
+    def get_selection(self):
+        x, y, mode = self.x, self.y, self.mode
+
+        sel = []
+        if mode is ACROSS:
+            index = x
+            while not self.puzzle.is_black(index, y):
+                sel.append((index, y))
+                index -= 1
+            index = x+1
+            while not self.puzzle.is_black(index, y):
+                sel.append((index, y))
+                index += 1
+        else:
+            index = y
+            while not self.puzzle.is_black(x, index):
+                sel.append((x, index))
+                index -= 1
+            index = y+1
+            while not self.puzzle.is_black(x, index):
+                sel.append((x, index))
+                index += 1
+        return sel
+
+    def switch_mode(self):
+        if self.mode is ACROSS:
+            if not self.puzzle.down_map[self.x, self.y]:
+                return
+        if self.mode is DOWN:
+            if not self.puzzle.across_map[self.x, self.y]:
+                return
+
+        self.mode = 1-self.mode
+
+        old_sel = self.selection
+        self.selection = self.get_selection()
+
+        for (x, y) in old_sel + self.selection:
+            self.do_update('box-update', x, y)
+
+        self.do_update('title-update')
+
+    def move_to(self, x, y):
+        if not self.puzzle.is_black(x, y):
+            self.x = x
+            self.y = y
+
+            if self.mode is ACROSS:
+                if not self.puzzle.across_map[self.x, self.y]:
+                    self.switch_mode()
+            if self.mode is DOWN:
+                if not self.puzzle.down_map[self.x, self.y]:
+                    self.switch_mode()
+
+            old_sel = self.selection
+            self.selection = self.get_selection()
+
+            for (xp, yp) in old_sel + self.selection:
+                self.do_update('box-update', xp, yp)
+
+            self.do_update('title-update')
+            self.do_update('across-update', self.puzzle.number(x, y, ACROSS))
+            self.do_update('down-update', self.puzzle.number(x, y, DOWN))
+
+    def select_word(self, mode, n):
+        if mode <> self.mode: self.switch_mode()
+        (x, y) = self.puzzle.number_map[n]
+        (x, y) = self.puzzle.find_blank_cell(x, y, mode, 1)
+        self.move_to(x, y)
+
+    def set_letter(self, letter):
+        self.puzzle.responses[self.x, self.y] = letter
+        if self.puzzle.errors[self.x, self.y] == MISTAKE:
+            self.puzzle.errors[self.x, self.y] = FIXED_MISTAKE
+            
+        self.do_update('box-update', self.x, self.y)
+
+        if self.puzzle.is_puzzle_correct():
+            self.do_update('puzzle-finished')
+
+    def erase_letter(self):
+        self.set_letter('')
+
+    def move(self, dir, amt, skip_black=True):
+        if self.mode == dir:
+            ((x, y), _) = self.puzzle.next_cell(self.x, self.y,
+                                                self.mode, amt, skip_black)
+            self.move_to(x, y)
+        else:
+            self.switch_mode()
+
+    def back_space(self):
+        if self.puzzle.responses[self.x, self.y] == '':
+            self.move(self.mode, -1, False)
+            self.erase_letter()
+        else:
+            self.erase_letter()
+
+    def next_word(self, incr):
+        n = self.puzzle.incr_number(self.x, self.y, self.mode, incr)
+        if n == 0:
+            self.switch_mode()
+            if incr == 1: n = 1
+            else: n = self.puzzle.final_number(self.mode)
+        (x, y) = self.puzzle.number_map[n]
+        (x, y) = self.puzzle.find_blank_cell(x, y, self.mode, 1)
+        self.move_to(x, y)
+
+    def input_char(self, skip_filled, c):
+        c = c.upper()
+        self.set_letter(c)
+        ((x, y), hit) = self.puzzle.next_cell(self.x, self.y,
+                                              self.mode, 1, False)
+        if skip_filled:
+            (x, y) = self.puzzle.find_blank_cell(x, y, self.mode, 1)
+
+        self.move_to(x, y)
+
+    def check_word(self):
+        correct = True
+        for (x, y) in self.selection:
+            if not self.puzzle.is_cell_correct(x, y):
+                if self.puzzle.responses[x, y] <> '':
+                    self.puzzle.errors[x, y] = MISTAKE
+                    correct = False
+                    self.do_update('box-update', x, y)
+
+        self.do_update('check-word-result', correct)
+
+    def check_puzzle(self):
+        correct = True
+        for (x, y) in self.puzzle.responses.keys():
+            if not self.puzzle.is_cell_correct(x, y):
+                if self.puzzle.responses[x, y] <> '':
+                    self.puzzle.errors[x, y] = MISTAKE
+                    correct = False
+                    self.do_update('box-update', x, y)
+
+        self.do_update('check-puzzle-result', correct)
+
+    def solve_word(self):
+        for (x, y) in self.selection:
+            if not self.puzzle.is_cell_correct(x, y):
+                self.puzzle.errors[x, y] = CHEAT
+                self.puzzle.responses[x, y] = self.puzzle.answers[x, y]
+                self.do_update('box-update', x, y)
+                    
+        if self.puzzle.is_puzzle_correct():
+            self.do_update('puzzle-finished')
+
+    def is_selected(self, x, y):
+        return ((x, y) in self.selection)
+
+    def is_main_selection(self, x, y):
+        return (x == self.x and y == self.y)
+
+    def get_selected_word(self):
+        return self.puzzle.clue(self.x, self.y, self.mode)
+
+    def get_clues(self, mode):
+        clues = []
+        m = self.puzzle.mode_clues[mode]
+        for n in range(1, self.puzzle.max_number+1):
+            if m.has_key(n): clues.append((n, m[n]))
+        return clues
+
+class DummyController:
+    def __init__(self):
+        pass
+
+    def connect(self, ev, handler):
+        pass
+
+    def signal(self):
+        pass
+
+    def switch_mode(self):
+        pass
+
+    def move_to(self, x, y):
+        pass
+
+    def select_word(self, mode, n):
+        pass
+
+    def set_letter(self, letter):
+        pass
+
+    def erase_letter(self):
+        pass
+
+    def move(self, dir, amt):
+        pass
+
+    def back_space(self):
+        pass
+
+    def next_word(self, incr):
+        pass
+
+    def input_char(self, skip_filled, c):
+        pass
+
+    def check_word(self):
+        pass
+
+    def check_puzzle(self):
+        pass
+
+    def solve_word(self):
+        pass
+
+    def is_selected(self, x, y):
+        return False
+
+    def is_main_selection(self, x, y):
+        return False
+
+    def get_selected_word(self):
+        return 'Welcome. Please open a puzzle.'
+
+    def get_clues(self, mode):
+        return []
+
+
+class RecentList:
+    def __init__(self):
+        self.max_entries = 5
+        self.recent_list = []
+
+    def add(self,newentry):
+        self.delete(newentry)
+        self.recent_list.insert(0,newentry)
+        if len(self.recent_list) > self.max_entries:
+            del self.recent_list[-1]
+
+    def delete(self,newentry):
+        if newentry in self.recent_list:
+            try:
+                self.recent_list.remove(newentry)
+            except ValueError:
+                pass
+
+    def set(self, newlist=[]):
+        self.recent_list = newlist
+
+
+class PuzzleWindow:
+    def __init__(self, puzzle):
+        self.clock_time = 0.0
+        self.clock_running = False
+
+        self.win = None
+        self.set_puzzle(puzzle)
+
+        if self.puzzle: self.control = PuzzleController(self.puzzle)
+        else: self.control = DummyController()
+
+        self.recent_menu = gtk.Menu()
+        self.recent = RecentList()
+
+        self.skip_filled = False
+        self.layout = 0
+        self.toolbar_layout = 4
+        self.window_size = (800, 480)
+        self.maximized = False
+        self.fullscreen = False
+        self.positions = layouts[self.layout][1]
+        self.default_loc = None
+        self.last_file = None
+        self.min_box_size = 20
+
+        title = 'Crossword Puzzle'
+        if self.puzzle: title = 'Crossword Puzzle - %s' % self.puzzle.title
+        
+        if has_hildon:
+            win = hildon.Window()
+        else:
+            win = gtk.Window()
+        self.handler = win.connect('destroy', lambda w: self.exit())
+        win.set_title(title)
+        win.connect('size-allocate', self.resize_window)
+        win.connect('window-state-event', self.state_event)
+        self.win = win
+
+        self.read_config()
+
+        win.resize(self.window_size[0], self.window_size[1])
+        if self.maximized: win.maximize()
+
+        self.cur_layout = None
+        self.letterbar1 = None
+
+        menubox = gtk.VBox()
+        self.menubar = self.create_menubar()
+        menubox.pack_start(self.menubar, False, False, 0)
+        self.update_recent_menu()
+
+        win.add(menubox)
+
+        self.box = gtk.HBox()
+        menubox.pack_start(self.box, True, True, 0)
+
+        self.toolbox = gtk.HBox()
+        self.box.pack_start(self.toolbox, False, False, 0)
+
+        self.toolbar = self.create_toolbar()
+        self.letterbar1 = self.create_letterbar(['A','D','G','J','M','P',
+            'S','V','Y','ISO_Left_Tab','Left','F12'])
+        self.letterbar2 = self.create_letterbar(['B','E','H','K','N','Q',
+            'T','W','Z','Up','Return','Down'])
+        self.letterbar3 = self.create_letterbar(['C','F','I','L','O','R',
+            'U','X','BackSpace','Tab','Right','Escape'])
+
+        self.create_widgets()
+        self.setup_controller()
+
+        self.vbox = gtk.VBox()
+        self.box.pack_start(self.vbox, True, True, 0)
+
+        self.cur_layout = self.generate_layout(self.positions)
+        self.vbox.pack_start(self.cur_layout, True, True, 0)
+
+        self.set_toolbar_layout(self.toolbar_layout)
+
+        gobject.timeout_add(500, self.idle_event)
+        win.connect('key-press-event', self.key_event)
+
+        if not self.puzzle: self.enable_controls(False)
+
+        if has_hildon:
+            menu = gtk.Menu()
+            for child in self.menubar.get_children():
+                child.reparent(menu)
+            self.win.set_menu(menu)
+            self.menubar.destroy()
+
+        win.show_all()
+
+        self.control.signal()
+        self.puzzle_widget.area.grab_focus()
+
+        if self.last_file and os.path.exists(self.last_file): 
+            self.do_open_file(self.last_file)
+
+    def enable_controls(self, enabled):
+        def enable(w): w.set_property('sensitive', enabled)
+        
+        enable(self.menu_items['save'])
+        enable(self.menu_items['properties'])
+        if has_print:
+            enable(self.menu_items['print'])
+        enable(self.toolbar_items['Check Word'])
+        enable(self.toolbar_items['Check Puzzle'])
+        enable(self.toolbar_items['Solve Word'])
+        enable(self.clock_button)
+
+    def setup_controller(self):
+        self.control.connect('puzzle-finished', self.puzzle_finished)
+        self.control.connect('box-update', self.puzzle_widget.update)
+        self.control.connect('title-update', self.clue_widget.update)
+        self.control.connect('across-update', self.across_update)
+        self.control.connect('down-update', self.down_update)
+        self.control.connect('check-word-result', self.check_result)
+        self.control.connect('check-puzzle-result', self.check_result)
+
+    def do_open_file(self, fname, start_over = False):
+        if self.clock_running:
+            self.clock_button.set_active(False)
+        
+        if self.puzzle: self.write_puzzle()
+
+        try:
+            self.set_puzzle(Puzzle(fname), start_over)
+        except:
+            self.notify("%s could not be loaded" % fname)
+            return
+        self.last_file = fname
+        self.recent.add(fname)
+        self.update_recent_menu()
+        self.control = PuzzleController(self.puzzle)
+        self.setup_controller()
+        self.clue_widget.set_controller(self.control)
+        self.puzzle_widget.set_puzzle(self.puzzle, self.control)
+
+        self.load_list(ACROSS)
+        self.load_list(DOWN)
+        self.enable_controls(True)
+        if has_hildon:
+            self.notify("Opened puzzle '" + self.puzzle.title + "'")
+
+        self.idle_event()
+
+    def do_save_file(self, fname):
+        self.default_loc = os.path.dirname(fname)
+        self.puzzle.save(fname)
+
+    def get_puzzle_file(self, puzzle):
+        dir = os.path.expanduser('~/.crossword_puzzles')
+        try: os.mkdir(dir)
+        except OSError: pass
+
+        return dir + os.sep + puzzle.hashcode()
+
+    def clear_puzzle(self):
+        if self.last_file: self.do_open_file(self.last_file, True)
+
+    def load_puzzle(self, fname, f):
+        pp = PersistentPuzzle()
+        try:
+            pp.from_binary(f.read())
+            
+            self.puzzle.responses = pp.responses
+            self.puzzle.errors = pp.errors
+            if len(pp.notes) > 0:
+                self.puzzle.notes = pp.notes
+            self.clock_time = pp.clock
+        except:
+            self.notify('The saved puzzle is corrupted. It will not be used.')
+            os.remove(fname)
+
+        f.close()
+
+    def set_puzzle(self, puzzle, start_over = False):
+        self.clock_time = 0.0
+
+        self.puzzle = puzzle
+        if not self.puzzle: return
+        
+        fname = self.get_puzzle_file(puzzle)
+
+        try: f = file(fname, 'r')
+        except IOError: return
+
+        if not start_over:
+            self.load_puzzle(fname, f)
+
+    def write_puzzle(self):
+        if not self.puzzle: return
+        
+        pp = PersistentPuzzle()
+        pp.responses = self.puzzle.responses
+        pp.errors = self.puzzle.errors
+
+        if self.clock_running:
+            self.clock_time += (time.time() - self.clock_start)
+        pp.clock = self.clock_time
+
+        pp.notes = self.puzzle.notes
+
+        fname = self.get_puzzle_file(self.puzzle)
+        f = file(fname, 'w+')
+        f.write(pp.to_binary())
+        f.close()
+
+    def exit(self):
+        self.write_puzzle()
+        self.write_config()
+        gtk.main_quit()
+
+    def notify(self, msg):
+        if has_hildon:
+            hildon.hildon_banner_show_information(self.win, None, msg)
+        else:
+            dialog = gtk.MessageDialog(parent=self.win,
+                                       type=gtk.MESSAGE_INFO,
+                                       buttons=gtk.BUTTONS_OK,
+                                       message_format=msg)
+            dialog.connect("response", lambda dlg, resp: dlg.destroy())
+            dialog.show()
+
+    def ask(self, msg, opts):
+        dialog = gtk.MessageDialog(parent=self.win,
+                                   flags=gtk.DIALOG_MODAL,
+                                   type=gtk.MESSAGE_QUESTION,
+                                   message_format=msg)
+
+        i = 0
+        for opt in opts:
+            dialog.add_button(opt, i)
+            i += 1
+        dialog.set_default_response(i-1)
+
+        dialog.show()
+        r = dialog.run()
+        dialog.destroy()
+
+        return r
+
+    def show_properties(self):
+        show_props = gtk.Dialog('Properties', self.win)
+        show_props.set_has_separator(False)
+        show_props.set_resizable(False)
+        vbox_left = gtk.VBox()
+        title = gtk.Label('Title:')
+        title.set_alignment(1, 1)
+        author = gtk.Label('Author:')
+        author.set_alignment(1, 1)
+        copyright = gtk.Label('Copyright:')
+        copyright.set_alignment(1, 1)
+        vbox_left.pack_start(title, False, False, 1)
+        vbox_left.pack_start(author, False, False, 1)
+        vbox_left.pack_start(copyright, False, False, 1)
+        vbox_right = gtk.VBox()
+        title2 = gtk.Label(self.puzzle.title)
+        author2 = gtk.Label(self.puzzle.author)
+        copyright2 = gtk.Label(self.puzzle.copyright)
+        vbox_right.pack_start(title2, False, False, 1)
+        vbox_right.pack_start(author2, False, False, 1)
+        vbox_right.pack_start(copyright2, False, False, 1)
+        hbox = gtk.HBox()
+        hbox.pack_start(vbox_left, False, False, 2)
+        hbox.pack_start(vbox_right, False, False, 2)
+        show_props.vbox.pack_start(hbox, False, False, 15)
+        show_props.vbox.show_all()
+        close_button = show_props.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
+        close_button.grab_focus()
+        show_props.run()
+        show_props.destroy()
+
+    def show_notepad(self):
+        notepad = gtk.Dialog('Notepad', self.win)
+        notepad.set_has_separator(False)
+        notepad.set_resizable(True)
+        textbuf = gtk.TextBuffer()
+        textbuf.set_text(self.puzzle.notes)
+        textview = gtk.TextView(textbuf)
+        scrollwin = gtk.ScrolledWindow()
+        scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        scrollwin.add(textview)
+        notepad.vbox.pack_start(scrollwin, True, True, 0)
+        notepad.vbox.show_all()
+        close_button = notepad.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
+        close_button.grab_focus()
+        notepad.set_size_request(650, 350)
+        notepad.run()
+        (start, end) = textbuf.get_bounds()
+        self.puzzle.notes = textbuf.get_slice(start, end, True)
+        notepad.destroy()
+
+    def show_about(self):
+        # Help > About
+        self.about_dialog = gtk.AboutDialog()
+        try:
+            self.about_dialog.set_transient_for(self.win)
+            self.about_dialog.set_modal(True)
+        except:
+            pass
+        self.about_dialog.set_name('Xword')
+        self.about_dialog.set_version(__version__)
+        self.about_dialog.set_comments('The Crossword puzzle player.')
+        self.about_dialog.set_license(__license__)
+        self.about_dialog.set_authors(
+            ['Bill McCloskey <bill.mccloskey at gmail.com>\n' +
+             'Maemo Port: Bradley Bell <bradleyb at u.washington.edu>\n' +
+             'and Terrence Fleury <terrencegf at gmail.com>'])
+#        gtk.about_dialog_set_url_hook(self.show_website, "http://xword.garage.maemo.org")
+        self.about_dialog.set_website_label("http://xword.garage.maemo.org")
+        icon_path = ABOUT_ICON
+        try:
+            icon_pixbuf = gtk.gdk.pixbuf_new_from_file(icon_path)
+            self.about_dialog.set_logo(icon_pixbuf)
+        except:
+            pass
+        self.about_dialog.connect('response', self.close_about)
+        self.about_dialog.connect('delete_event', self.close_about)
+        self.about_dialog.show_all()
+
+    def close_about(self, event, data=None):
+        self.about_dialog.hide()
+        return True
+
+    def prompt_min_box_size(self):
+        dialog = gtk.Dialog(None, self.win,
+                     gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
+                     (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
+                      gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
+        box = gtk.HBox();
+        dialog.vbox.pack_start(box)
+        label = gtk.Label("Minimum Box Size:");
+        box.pack_start(label)
+        adjust = gtk.Adjustment(self.min_box_size,
+            MIN_BOX_SIZE,MAX_BOX_SIZE,2,0,0)
+        spin = gtk.SpinButton(adjust)
+        box.pack_start(spin)
+        dialog.show_all();
+        r = dialog.run()
+        if r == gtk.RESPONSE_ACCEPT:
+            spinval = spin.get_value_as_int()
+            if spinval != self.min_box_size:
+                self.min_box_size = spinval
+                self.puzzle_widget.min_box_size = spinval
+                self.puzzle_widget.set_puzzle(self.puzzle, self.control)
+        dialog.destroy()
+
+    def create_widgets(self):
+        self.widgets = {}
+
+        vbox = gtk.VBox()
+        
+        clue = ClueWidget(self.control)
+        vbox.pack_start(clue.widget, False, False, 0)
+        self.clue_widget = clue
+
+        puzzle = PuzzleWidget(self.puzzle, self.control, self.min_box_size)
+        puzzle.area.connect('key-press-event', self.puzzle_key_event)
+        vbox.pack_start(puzzle.widget, True, True, 0)
+        self.puzzle_widget = puzzle
+
+        self.widgets['puzzle'] = vbox
+
+        puzzle.widget.connect('button-press-event', self.button_event, puzzle)
+
+        self.tree_paths = {}
+        self.trees = {}
+
+        self.widgets['across'] = self.create_list(ACROSS)
+        self.widgets['down'] = self.create_list(DOWN)
+        self.load_list(ACROSS)
+        self.load_list(DOWN)
+            
+    def generate_layout(self, layout):
+        if type(layout) == str:
+            return self.widgets[layout]
+        else:
+            if layout[0] == 'H': w = gtk.HPaned()
+            elif layout[0] == 'V': w = gtk.VPaned()
+            
+            w.add1(self.generate_layout(layout[1]))
+            w.add2(self.generate_layout(layout[3]))
+            w.set_position(layout[2])
+            w.show()
+            
+            return w
+
+    def set_layout(self, index):
+        if not self.cur_layout: return
+
+        for w in self.widgets.values():
+            p = w.get_parent()
+            if p: p.remove(w)
+
+        p = self.cur_layout.get_parent()
+        if p: p.remove(self.cur_layout)
+        
+        self.cur_layout = None
+        self.layout = index
+        self.positions = layouts[index][1]
+        self.cur_layout = self.generate_layout(self.positions)
+        self.vbox.pack_start(self.cur_layout, True, True, 0)
+
+        self.win.show_all()
+        self.puzzle_widget.area.grab_focus()
+
+    def get_layout(self, widget):
+        kind = widget.get_name()
+        if kind == 'GtkHPaned':
+            children = widget.get_children()
+            return ('H',
+                    self.get_layout(children[0]),
+                    widget.get_position(),
+                    self.get_layout(children[1]))
+        elif kind == 'GtkVPaned':
+            children = widget.get_children()
+            return ('V',
+                    self.get_layout(children[0]),
+                    widget.get_position(),
+                    self.get_layout(children[1]))
+        else:
+            for (name, w) in self.widgets.items():
+                if w is widget: return name
+
+    def set_toolbar_layout(self, index):
+        if not self.letterbar1: return
+
+        self.toolbar_layout = index
+        for child in self.toolbox.get_children():
+            self.toolbox.remove(child)
+
+        if toolbar_layouts[index][1] == 'checks':
+            self.toolbox.pack_start(self.toolbar,False,False,0)
+        elif toolbar_layouts[index][1] == 'keyboard':
+            self.toolbox.pack_start(self.letterbar1,False,False,0)
+            self.toolbox.pack_start(self.letterbar2,False,False,0)
+            self.toolbox.pack_start(self.letterbar3,False,False,0)
+
+        if toolbar_layouts[index][2] == 'L':
+            self.box.reorder_child(self.toolbox,0)
+        elif toolbar_layouts[index][2] == 'R':
+            self.box.reorder_child(self.toolbox,-1)
+
+        self.win.show_all()
+
+    def state_event(self, w, event):
+        state = int(event.new_window_state)
+        self.maximized = (state & gtk.gdk.WINDOW_STATE_MAXIMIZED) <> 0
+        self.fullscreen = (state & gtk.gdk.WINDOW_STATE_FULLSCREEN) <> 0
+
+    def resize_window(self, widget, allocation):
+        if not self.maximized:
+            self.window_size = self.win.get_size()
+
+    def update_recent_menu(self):
+        for child in self.recent_menu.get_children():
+            self.recent_menu.remove(child)
+        if len(self.recent.recent_list) == 0:
+            self.menu_items['recent'].set_property('sensitive', False)
+        else:
+            self.menu_items['recent'].set_property('sensitive', True)
+            for item in self.recent.recent_list:
+                m = gtk.MenuItem(item.split(os.sep)[-1])
+                m.connect('activate', self.menu_selected, 'recent', item)
+                self.recent_menu.append(m)
+        self.recent_menu.show_all()
+
+    def create_menubar(self):
+        accel = gtk.AccelGroup()
+
+        self.menu_items = {}
+
+        def create_item(args, action, key, klass, active):
+            item = klass(**args)
+            if active: item.set_active(True)
+            item.connect('activate', self.menu_selected, action)
+            if not has_hildon and key:
+                item.add_accelerator('activate', accel, ord(key),
+                                     gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE)
+            return item
+
+        def create_menu_item(label, action, key=None, klass=gtk.MenuItem,
+                             active=False):
+            return create_item({ 'label': label }, action, key, klass, active)
+
+        def create_radio_item(label, action, group, active):
+            return create_item({ 'label': label, 'group': group },
+                               action, None, gtk.RadioMenuItem, active)
+
+        def append(menu, name, item):
+            self.menu_items[name] = item
+            menu.append(item)
+
+        menubar = gtk.MenuBar()
+
+        file_menu = gtk.MenuItem('_File')
+        menubar.append(file_menu)
+
+        menu = gtk.Menu()
+        file_menu.set_submenu(menu)
+
+        append(menu, 'open', create_menu_item('Open', MENU_OPEN, 'O'))
+        item = create_menu_item('Recent', 0)
+        item.set_submenu(self.recent_menu)
+        append(menu, 'recent', item)
+        append(menu, 'save', create_menu_item('Save', MENU_SAVE, 'S'))
+        if has_print:
+            append(menu, 'print', create_menu_item('Print...', MENU_PRINT, 'P'))
+        append(menu, 'properties', create_menu_item('Properties...', 'properties'))
+        append(menu, '', gtk.SeparatorMenuItem())
+        append(menu, 'close', create_menu_item('Close', MENU_CLOSE, 'W'))
+        append(menu, 'quit', create_menu_item('Quit', MENU_QUIT, 'Q'))
+
+        puzzle_menu = gtk.MenuItem('Puzzle')
+        menubar.append(puzzle_menu)
+
+        menu=gtk.Menu()
+        puzzle_menu.set_submenu(menu)
+
+        append(menu, 'check_word', create_menu_item('Check Word', 'Check Word'))
+        append(menu, 'check_puzzle', create_menu_item('Check Puzzle', 'Check Puzzle'))
+        append(menu, 'solve_word', create_menu_item('Solve Word', 'Solve Word'))
+        append(menu, 'clear_puzzle', create_menu_item('Clear Puzzle', 'Clear Puzzle'))
+        append(menu, 'notepad', create_menu_item('Notepad...', 'notepad'))
+
+        prefs_menu = gtk.MenuItem('Preferences')
+        menubar.append(prefs_menu)
+            
+        menu = gtk.Menu()
+        prefs_menu.set_submenu(menu)
+            
+        append(menu, 'skip-filled',
+               create_menu_item('Skip Filled', MENU_SKIP, None,
+                                gtk.CheckMenuItem, self.skip_filled))
+
+        append(menu, 'min_box_size', 
+            create_menu_item('Set Min Box Size', 'min_box_size'))
+
+        item = create_menu_item('Toolbar Layout', 0)
+        append(menu, 'toolbar', item)
+
+        menu1 = gtk.Menu()
+        item.set_submenu(menu1)
+
+        g = None
+        i = -1
+        for (name, layout, side) in toolbar_layouts:
+            item = create_radio_item(name, i-10, g, -(i+1)==self.toolbar_layout)
+            menu1.append(item)
+            if not g: item.set_active(True)
+            g = item
+            i -= 1
+
+        item = create_menu_item('Word List Layout', 0)
+        append(menu, 'layout', item)
+        
+        menu = gtk.Menu()
+        item.set_submenu(menu)
+        
+        g = None
+        i = -1
+        for (name, layout) in layouts:
+            item = create_radio_item(name, i, g, -(i+1) == self.layout)
+            menu.append(item)
+            if not g: item.set_active(True)
+            g = item
+            i -= 1
+
+        help_menu = gtk.MenuItem('Help')
+        menubar.append(help_menu)
+
+        menu = gtk.Menu()
+        help_menu.set_submenu(menu)
+
+        append(menu, 'about', create_menu_item('About', 'about'))
+
+        self.win.add_accel_group(accel)
+        return menubar
+
+    def menu_selected(self, item, action, extra=None):
+        if action == MENU_QUIT:
+            self.exit()
+        elif action == MENU_CLOSE:
+            self.exit()
+        elif action == MENU_SKIP:
+            self.skip_filled = not self.skip_filled
+        elif action == MENU_OPEN:
+            self.open_file()
+        elif action == 'recent':
+            self.open_recent(extra)
+        elif action == MENU_SAVE:
+            self.save_file()
+        elif action == MENU_PRINT:
+            self.print_puzzle()
+        elif action == 'Check Word':
+            self.control.check_word()
+        elif action == 'Check Puzzle':
+            self.control.check_puzzle()
+        elif action == 'Solve Word':
+            self.control.solve_word()
+        elif action == 'Clear Puzzle':
+            self.clear_puzzle()
+        elif action == 'notepad':
+            self.show_notepad()
+        elif action == 'properties':
+            self.show_properties()
+        elif action == 'about':
+            self.show_about()
+        elif action == 'min_box_size':
+            self.prompt_min_box_size()
+        elif action < -10:
+            toolbar_layout = -(action+11)
+            if toolbar_layout <> self.toolbar_layout:
+                self.set_toolbar_layout(toolbar_layout)
+        elif action < 0:
+            layout = -(action+1)
+            if layout <> self.layout: self.set_layout(layout)
+
+    def create_toolbar_item(self, label, icon, tooltip, is_toggle=False):
+        if icon:
+            img = gtk.Image()
+            if icon[-4:] == '.png': img.set_from_file(icon)
+            else: img.set_from_stock(icon, gtk.ICON_SIZE_SMALL_TOOLBAR)
+        else:
+            img = None
+
+        if gtk.pygtk_version >= (2,3,90):
+            if is_toggle:
+                item = gtk.ToggleToolButton()
+                item.set_label(label)
+                item.set_icon_widget(img)
+            else:
+                item = gtk.ToolButton(img, label)
+
+            item.connect('clicked', self.toolbar_event, label)
+            self.toolbar.insert(item, -1)
+            self.toolbar_items[label] = item
+            return item
+        else:
+            if is_toggle:
+                x = self.toolbar.append_element(gtk.TOOLBAR_CHILD_TOGGLEBUTTON,
+                                                None, label, tooltip, tooltip,
+                                                img, self.toolbar_event, label)
+            else:
+                x = self.toolbar.append_item(label, tooltip, tooltip, img,
+                                             self.toolbar_event, label)
+            self.toolbar_items[label] = x
+            return x
+
+    def create_separator_toolitem(self):
+        if gtk.pygtk_version >= (2,3,90):
+            item = gtk.SeparatorToolItem()
+            item.set_draw(False)
+            item.set_expand(True)
+            self.toolbar.insert(item, -1)
+        else:
+            # I don't know how to do this
+            pass
+
+    def create_toolbar(self):
+        self.toolbar_items = {}
+        
+        toolbar = gtk.Toolbar()
+        toolbar.set_style(gtk.TOOLBAR_BOTH)
+        toolbar.set_orientation(gtk.ORIENTATION_VERTICAL)
+        self.toolbar = toolbar
+
+        self.create_toolbar_item('Quit', gtk.STOCK_QUIT, 'Quit')
+        self.create_toolbar_item('Open', gtk.STOCK_OPEN, 'Open')
+        self.create_toolbar_item('Check Word', CHECK_ICON,
+                                 'Check a word')
+        self.create_toolbar_item('Check Puzzle', CHECK_ALL_ICON,
+                                 'Check all words in the puzzle')
+        self.create_toolbar_item('Solve Word', SOLVE_ICON,
+                                 'Cheat to get a word')
+        self.create_separator_toolitem()
+        b = self.create_toolbar_item('', TIMER_ICON,
+                                     'Enable or disable the clock', True)
+        self.clock_button = b
+        self.idle_event()
+
+        return toolbar
+
+    def load_icon(self,filename):
+        img = gtk.Image()
+        img.set_from_file(filename)
+        return img
+
+    def create_letterbar(self,itemlist):
+        letterbar = gtk.Toolbar()
+        letterbar.set_style(gtk.TOOLBAR_ICONS)
+        letterbar.set_orientation(gtk.ORIENTATION_VERTICAL)
+
+        for item in itemlist:
+            if item == 'Left': button = gtk.ToolButton(
+                         self.load_icon(HOME_PATH+'/left.xpm'),None)
+            elif item == 'Right': button = gtk.ToolButton(
+                         self.load_icon(HOME_PATH+'/right.xpm'),None)
+            elif item == 'Up': button = gtk.ToolButton(
+                         self.load_icon(HOME_PATH+'/up.xpm'),None)
+            elif item == 'Down': button = gtk.ToolButton(
+                         self.load_icon(HOME_PATH+'/down.xpm'),None)
+            elif item == 'BackSpace': button = gtk.ToolButton(
+                         self.load_icon(HOME_PATH+'/backspace.xpm'),None)
+            elif item == 'Return': button = gtk.ToolButton(
+                         self.load_icon(HOME_PATH+'/swap.xpm'),None)
+            elif item == 'Tab': button = gtk.ToolButton(
+                         self.load_icon(HOME_PATH+'/nextword.xpm'),None)
+            elif item == 'ISO_Left_Tab': button = gtk.ToolButton(
+                         self.load_icon(HOME_PATH+'/prevword.xpm'),None)
+            elif item == 'Escape': button = gtk.ToolButton(
+                         self.load_icon(HOME_PATH+'/check.xpm'),None)
+            elif item == 'F12': button = gtk.ToolButton(
+                         self.load_icon(HOME_PATH+'/solve.xpm'),None)
+            else:
+                button = gtk.ToolButton(None,item)
+
+            button.connect('clicked',self.letterbar_event,item)
+            letterbar.insert(button,-1)
+
+        return letterbar
+
+    def create_list(self, mode):
+        if mode == ACROSS: label = 'Across'
+        else: label = 'Down'
+
+        tree = gtk.TreeView()
+        column = gtk.TreeViewColumn(label, gtk.CellRendererText(), text=1)
+        tree.append_column(column)
+        tree.connect('row-activated', self.select_changed, mode)
+        tree.set_property('can-focus', False)
+
+        scroll = gtk.ScrolledWindow()
+        scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        scroll.add(tree)
+
+        self.trees[mode] = tree
+        
+        return scroll
+
+    def load_list(self, mode):
+        self.tree_paths[mode] = {}
+        store = gtk.ListStore(int, str)
+        i = 0
+        for (n, clue) in self.control.get_clues(mode):
+            self.tree_paths[mode][n] = i
+            store.append((n, '%d. %s' % (n, clue)))
+            i += 1
+
+        self.trees[mode].set_model(store)
+
+    def select_changed(self, tree, path, column, mode):
+        store = tree.get_model()
+        n = store.get_value(store.get_iter(path), 0)
+        self.control.select_word(mode, n)
+        
+    def across_update(self, an):
+        if self.tree_paths.has_key(ACROSS):
+            selection = self.trees[ACROSS].get_selection()
+            if an:
+                selection.select_path(self.tree_paths[ACROSS][an])
+                self.trees[ACROSS].scroll_to_cell(self.tree_paths[ACROSS][an])
+            else:
+                selection.unselect_all()
+
+    def down_update(self, dn):
+        if self.tree_paths.has_key(DOWN):
+            selection = self.trees[DOWN].get_selection()
+            if dn:
+                selection.select_path(self.tree_paths[DOWN][dn])
+                self.trees[DOWN].scroll_to_cell(self.tree_paths[DOWN][dn])
+            else:
+                selection.unselect_all()
+
+    def idle_event(self):
+        t = time.time()
+        if self.clock_running:
+            total = int(self.clock_time + (t - self.clock_start))
+        else:
+            total = int(self.clock_time)
+        s = time_str(total)
+        sold = self.clock_button.get_label()
+        if sold <> s: self.clock_button.set_label(s)
+
+        return True
+
+    def toolbar_event(self, widget, event):
+        if event == 'Quit':
+            self.exit()
+        elif event == 'Open':
+            self.open_file()
+        elif event == 'Check Word':
+            self.control.check_word()
+        elif event == 'Check Puzzle':
+            self.control.check_puzzle()
+        elif event == 'Solve Word':
+            self.control.solve_word()
+        else: # it must be the clock
+            self.clock_running = not self.clock_running
+            if self.clock_running:
+                self.clock_start = time.time()
+            else:
+                self.clock_time += (time.time() - self.clock_start)
+
+    def letterbar_event(self, widget, event):
+        keypress = gtk.gdk.Event(gtk.gdk.KEY_PRESS)
+        keypress.keyval = int(gtk.gdk.keyval_from_name(event))
+        if len(event) is 1 and event.isalpha():
+            self.puzzle_key_event('',keypress)
+        else:
+            self.key_event('',keypress)
+
+    def button_event(self, widget, event, puzzle):
+        if event.type is gtk.gdk.BUTTON_PRESS:
+            (x, y) = puzzle.translate_position(
+                         event.x+puzzle.widget.get_hadjustment().get_value(), 
+                         event.y+puzzle.widget.get_vadjustment().get_value())
+            if x == self.control.x and y == self.control.y:
+                self.control.switch_mode()
+            else:
+                if event.button is 3: self.control.switch_mode()
+                self.control.move_to(x, y)
+
+    def key_event(self, item, event):
+        name = gtk.gdk.keyval_name(event.keyval)
+        
+        c = self.control
+
+        if name == 'Right': c.move(ACROSS, 1)
+        elif name == 'Left': c.move(ACROSS, -1)
+        elif name == 'Up': c.move(DOWN, -1)
+        elif name == 'Down': c.move(DOWN, 1)
+        elif name == 'BackSpace': c.back_space()
+        elif name == 'Return': c.switch_mode()
+        elif name == 'Tab': c.next_word(1)
+        elif name == 'ISO_Left_Tab': c.next_word(-1)
+        elif name == 'F6':
+            if self.fullscreen:
+                self.win.unfullscreen()
+            else:
+                self.win.fullscreen()
+        elif name == 'F7': c.next_word(1)
+        elif name == 'F8': c.next_word(-1)
+        elif name == 'Escape': c.check_word()
+        elif name == 'F12': c.solve_word()
+        else: return False
+
+        return True
+
+    def puzzle_key_event(self, item, event):
+        name = gtk.gdk.keyval_name(event.keyval)
+        c = self.control
+        if len(name) is 1 and name.isalpha():
+            c.input_char(self.skip_filled, name)
+            return True
+        else:
+            return False
+
+    def puzzle_finished(self):
+        self.notify('You have solved the puzzle!')
+        if self.clock_running:
+            self.clock_button.set_active(False)
+
+    def check_result(self, correct):
+        if correct: msg = 'No mistakes found.'
+        else: msg = 'Incorrect.'
+
+        self.notify(msg)
+
+    def open_file(self):
+        def open_cb(w, open_dlg):
+            self.do_open_file(open_dlg.get_filename())
+            open_dlg.destroy()
+        
+        if gtk.pygtk_version < (2,3,90):
+            dlg = gtk.FileSelection('Select a puzzle')
+            dlg.connect('destroy', lambda w: dlg.destroy())
+            dlg.ok_button.connect('clicked', open_cb, dlg)
+            dlg.cancel_button.connect('clicked', lambda w: dlg.destroy())
+            if self.default_loc: dlg.set_filename(self.default_loc + os.sep)
+            dlg.show()
+        else:
+            if has_hildon:
+                dlg = hildon.FileChooserDialog(self.win,
+                                               gtk.FILE_CHOOSER_ACTION_OPEN)
+            else:
+                dlg = gtk.FileChooserDialog("Open...",
+                                            None,
+                                            gtk.FILE_CHOOSER_ACTION_OPEN,
+                                            (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+                                             gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+            dlg.set_default_response(gtk.RESPONSE_OK)
+            if self.default_loc: dlg.set_current_folder(self.default_loc)
+
+            response = dlg.run()
+            if response == gtk.RESPONSE_OK:
+                open_cb(None, dlg)
+            else:
+                dlg.destroy()
+
+    def save_file(self):
+        def save_cb(w, save_dlg):
+            self.do_save_file(save_dlg.get_filename())
+            save_dlg.destroy()
+        
+        if gtk.pygtk_version < (2,3,90):
+            dlg = gtk.FileSelection('Name the puzzle')
+            dlg.connect('destroy', lambda w: dlg.destroy())
+            dlg.ok_button.connect('clicked', save_cb, dlg)
+            dlg.cancel_button.connect('clicked', lambda w: dlg.destroy())
+            if self.default_loc: dlg.set_filename(self.default_loc + os.sep)
+            dlg.show()
+        else:
+            if has_hildon:
+                dlg = hildon.FileChooserDialog(self.win,
+                                               gtk.FILE_CHOOSER_ACTION_SAVE)
+            else:
+                dlg = gtk.FileChooserDialog("Save As...",
+                                            None,
+                                            gtk.FILE_CHOOSER_ACTION_SAVE,
+                                            (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+                                             gtk.STOCK_SAVE, gtk.RESPONSE_OK))
+            dlg.set_default_response(gtk.RESPONSE_OK)
+            if self.default_loc: dlg.set_current_folder(self.default_loc)
+
+            response = dlg.run()
+            if response == gtk.RESPONSE_OK:
+                save_cb(None, dlg)
+            else:
+                dlg.destroy()
+
+    def open_recent(self, filename):
+        if filename != None:
+            if os.path.exists(filename):
+                self.do_open_file(filename)
+            else:
+                self.notify('File not found.')
+                self.recent.delete(filename)
+                self.update_recent_menu()
+
+    def print_puzzle(self):
+        if has_print:
+            pr = PuzzlePrinter(self.puzzle)
+            pr.print_puzzle(self.win)
+        else:
+            self.notify('Printing libraries are not installed. Please'
+                        + ' install the Python wrapper for gnomeprint.')
+
+    def read_config(self):
+        c = ConfigParser.ConfigParser()
+        c.read(os.path.expanduser('~/.crossword.cfg'))
+        if c.has_section('options'):
+            if c.has_option('options', 'skip_filled'):
+                self.skip_filled = c.getboolean('options', 'skip_filled')
+            if c.has_option('options', 'layout'):
+                self.layout = c.getint('options', 'layout')
+            if c.has_option('options', 'toolbar_layout'):
+                self.toolbar_layout = c.getint('options', 'toolbar_layout')
+            if c.has_option('options', 'positions'):
+                self.positions = eval(c.get('options', 'positions'))
+            if c.has_option('options', 'window_size'):
+                self.window_size = eval(c.get('options', 'window_size'))
+            if c.has_option('options', 'maximized'):
+                self.maximized = eval(c.get('options', 'maximized'))
+            if c.has_option('options', 'default_loc'):
+                self.default_loc = eval(c.get('options', 'default_loc'))
+            if c.has_option('options', 'last_file'):
+                self.last_file = eval(c.get('options', 'last_file'))
+            if c.has_option('options', 'min_box_size'):
+                self.min_box_size = c.getint('options', 'min_box_size')
+            if c.has_option('options', 'recent_list'):
+                self.recent.set(eval(c.get('options', 'recent_list')));
+
+    def write_config(self):
+        c = ConfigParser.ConfigParser()
+        c.add_section('options')
+        c.set('options', 'skip_filled', self.skip_filled)
+        c.set('options', 'layout', self.layout)
+        c.set('options', 'toolbar_layout', self.toolbar_layout)
+        c.set('options', 'positions', repr(self.get_layout(self.cur_layout)))
+        c.set('options', 'window_size', repr(self.window_size))
+        c.set('options', 'maximized', repr(self.maximized))
+        c.set('options', 'default_loc', repr(self.default_loc))
+        c.set('options', 'last_file', repr(self.last_file))
+        c.set('options', 'min_box_size', self.min_box_size)
+        c.set('options', 'recent_list', repr(self.recent.recent_list))
+        c.write(file(os.path.expanduser('~/.crossword.cfg'), 'w'))
+
+
+def osso_callback(interface, method, arguments, user_data):
+    if method == 'mime_open':
+        filename = arguments[0]
+        if filename.startswith('file://'):
+            filename = filename[7:]
+        if os.path.exists(filename):
+            w.do_open_file(filename)
+
+if __name__ == '__main__':
+    if has_osso:
+        osso_c = osso.Context("xword", __version__, False)
+        osso_rpc = osso.Rpc(osso_c)
+        osso_rpc.set_rpc_callback("org.maemo.xword", "/org/maemo/xword",
+                                  "org.maemo.xword", osso_callback, osso_c)
+
+    p = None
+    if len(sys.argv) == 2 and os.path.exists(sys.argv[1]):
+        try:
+            p = Puzzle(sys.argv[1])
+        except:
+            print "%s could not be loaded" % sys.argv[1]
+            p = None
+
+    w = PuzzleWindow(p)
+    gtk.main()



More information about the Xword-commits mailing list