def export_image (self, pngfile, htmlfile=None, puztitle="Crossword Puzzle",
solution=True):
# don't export if grid is not frozen
- if self.frozen_grid is False:
- raise FrozenGridException
+ self.assert_frozen_grid ()
# create cairo image surface and context
px = 30
# get the AcrossLite(TM) data for exporting
def export_acrosslite (self, title, author, copyright):
# don't export if grid is not frozen
- if self.frozen_grid is False:
- raise FrozenGridException
+ self.assert_frozen_grid ()
across_data = []
across_data.append ("<ACROSS PUZZLE>\r\n")
# setting a down word
def set_word_down (self, row, col, word):
- # if the grid is frozen the abort
- if self.frozen_grid is True:
- raise FrozenGridException
+ # if the grid is frozen then abort
+ self.assert_unfrozen_grid ()
# if the word length greater than totalrows - startrow
if len(word) > self.rows - row:
# setting an across word
def set_word_across (self, row, col, word):
- # if the grid is frozen the abort
- if self.frozen_grid is True:
- raise FrozenGridException
+ # if the grid is frozen then abort
+ self.assert_unfrozen_grid ()
# is the word length greater than totalcols - startcol?
if len(word) > self.cols - col:
self.frozen_grid = False
+ # raise an exception if the grid is frozen
+ def assert_unfrozen_grid (self):
+ if self.frozen_grid is True:
+ raise FrozenGridException
+
+ # raise an exception if the grid is NOT frozen
+ def assert_frozen_grid (self):
+ if self.frozen_grid is False:
+ raise FrozenGridException
+
# reset the entire grid
def reset_grid (self):
# run through the grid
# remove an across word at position
def remove_word_across (self, row, col):
# if grid is frozen don't allow removal of word
- if self.frozen_grid is True:
- raise FrozenGridException
+ assert_unfrozen_grid ()
word, brow, bcol, l = self.get_word_across (row, col)
# remove a down word at position
def remove_word_down (self, row, col):
# if grid is frozen don't allow removal of word
- if self.frozen_grid is True:
- raise FrozenGridException
+ self.assert_unfrozen_grid ()
word, brow, bcol, l = self.get_word_down (row, col)
# traverse from the beginn to end of the word and erase it
class MainWindow:
def gtk_main_quit (self, *args):
+ if self.puzzle:
+ dlg = gtk.MessageDialog (self.window, gtk.DIALOG_MODAL,
+ gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO,
+ "Puzzle is open. Are you sure you wish to quit?")
+ if dlg.run () == gtk.RESPONSE_NO:
+ dlg.destroy ()
+ return
+ dlg.destroy ()
+
gtk.main_quit ()
+ # callback for menu item quit activated event
+ def on_quit_activate (self, menuitem):
+ self.gtk_main_quit ()
+
# callback for puzzle grid mouse button release event
- def on_puzzlegrid_button_release_event (self, drawarea, event):
+ def on_puzzlegrid_button_press_event (self, drawarea, event):
self.window.set_focus (drawarea)
return True
clue])
def open_file (self, file):
- self.puzzle = cPickle.load (open (file, "rb"))
- self.selected_row = 0
- self.selected_col = 0
- self.window.set_title ("GetAClue player - " + file)
- self.load_clues ()
+ # try to open the file
+ try:
+ # load the puzzle
+ self.puzzle = cPickle.load (open (file, "rb"))
+ # assert that it is unfrozen otherwise raise frozen grid exception
+ self.puzzle.assert_frozen_grid ()
+
+ # set selected initial row and column to 0
+ self.selected_row = 0
+ self.selected_col = 0
+ self.window.set_title ("GetAClue player - " + file)
+ # load the clues
+ self.load_clues ()
+ # handle unpickling, and file errors
+ except (cPickle.UnpicklingError, IOError, OSError):
+ dlg = gtk.MessageDialog (self.window, gtk.DIALOG_MODAL,
+ gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE,
+ "Invalid file. Cannot be loaded")
+ dlg.run ()
+ dlg.destroy ()
+ # if the puzzle has no words, then it cannot be played obviously
+ except crosswordpuzzle.NoWordsException:
+ self.puzzle = None
+ dlg = gtk.MessageDialog (self.window, gtk.DIALOG_MODAL,
+ gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE,
+ "Word grid has no words. Cannot play")
+ dlg.run ()
+ dlg.destroy ()
+ # if the puzzle is not frozen then it cannot be played
+ except crosswordpuzzle.FrozenGridException:
+ self.puzzle = None
+ dlg = gtk.MessageDialog (self.window, gtk.DIALOG_MODAL,
+ gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE,
+ "Word grid is not finalized/frozen. Cannot play")
+ dlg.run ()
+ dlg.destroy ()
def __init__ (self, file_to_play = None):
# load the user interface
<property name="visible">True</property>
<property name="label" translatable="yes">_Quit</property>
<property name="use_underline">True</property>
+ <signal name="activate" handler="on_quit_activate"/>
</object>
</child>
</object>
<property name="use_underline">True</property>
</object>
</child>
+ <child>
+ <object class="GtkMenuItem" id="hidesolution">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Hide solution</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSeparatorMenuItem" id="sep2">
+ <property name="visible">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="verify">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Verify your board...</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
</object>
</child>
</object>
<property name="can_focus">True</property>
<property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
<signal name="expose_event" handler="on_puzzlegrid_expose_event"/>
+ <signal name="button_press_event" handler="on_puzzlegrid_button_press_event"/>
<signal name="key_press_event" handler="on_puzzlegrid_key_press_event"/>
<signal name="focus_in_event" handler="on_puzzlegrid_focus_in_event"/>
- <signal name="button_release_event" handler="on_puzzlegrid_button_release_event"/>
<signal name="focus_out_event" handler="on_puzzlegrid_focus_out_event"/>
</object>
</child>