Added exception handling to opening file in player
authorHarishankar <v.harishankar@gmail.com>
Tue, 7 Dec 2010 09:14:49 +0000 (14:44 +0530)
committerHarishankar <v.harishankar@gmail.com>
Tue, 7 Dec 2010 09:14:49 +0000 (14:44 +0530)
Added exception handling to opening file in GetAClue player. Also
added assertion for frozen/unfrozen grid.

crosswordpuzzle.py
player_mainwindow.py
playerwindow.glade

index a02f469..d02890b 100644 (file)
@@ -136,8 +136,7 @@ class CrosswordPuzzle:
        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
@@ -226,8 +225,7 @@ class CrosswordPuzzle:
        # 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")
@@ -373,9 +371,8 @@ class CrosswordPuzzle:
 
        # 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:
@@ -428,9 +425,8 @@ class CrosswordPuzzle:
 
        # 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:
@@ -511,6 +507,16 @@ class CrosswordPuzzle:
 
                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
@@ -524,8 +530,7 @@ class CrosswordPuzzle:
        # 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)
 
@@ -541,8 +546,7 @@ class CrosswordPuzzle:
        # 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
index 4524106..3ea5420 100644 (file)
@@ -13,10 +13,23 @@ import crosswordpuzzle
 
 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
 
@@ -153,11 +166,42 @@ class MainWindow:
                                                        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
index d13e901..9fc4a78 100644 (file)
@@ -66,6 +66,7 @@
                         <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>