[gnome-games/sudoku-tube] Basic undo/redo



commit 17d8e5ba0d2834879b523f2178c22f6f0db1d4bc
Author: Zhang Sen <zh jesse gmail com>
Date:   Fri Jul 24 10:41:09 2009 +0800

    Basic undo/redo

 gnome-sudoku/src/lib/main.py |   32 ++++++++++++--------------------
 gnome-sudoku/src/lib/view.py |   28 ++++++++++++++++++++--------
 2 files changed, 32 insertions(+), 28 deletions(-)
---
diff --git a/gnome-sudoku/src/lib/main.py b/gnome-sudoku/src/lib/main.py
index f24a6c1..08cf33a 100644
--- a/gnome-sudoku/src/lib/main.py
+++ b/gnome-sudoku/src/lib/main.py
@@ -25,7 +25,8 @@ import timer
 import tracker_box
 from defaults import (APPNAME, APPNAME_SHORT, AUTHORS, COPYRIGHT, DESCRIPTION,
         LICENSE, MIN_NEW_PUZZLES, UI_DIR, VERSION, WEBSITE, WEBSITE_LABEL)
-from gtk_goodies import gconf_wrapper, Undo, dialog_extras
+from gtk_goodies import gconf_wrapper, dialog_extras
+import undo
 
 import contact_selector
 import networking
@@ -63,6 +64,7 @@ class UI (gconf_wrapper.GConfWrapper):
         self.sudoku_tracker = saver.SudokuTracker()
         self._main_model = None
         self._main_grid_vew = None
+        self._history_manager = None
         self.setup_gui()
 
         self.tube_handler = tube_handler.TubeHandler(self.tube_service,
@@ -197,12 +199,12 @@ class UI (gconf_wrapper.GConfWrapper):
     def setup_gui (self):
         self.initialize_prefs()
         self.setup_main_window()
+        self.setup_undo()
         self._setup_main_boxes()
 
         self.setup_color()
         self.setup_actions()
         return
-        self.setup_undo()
         self.setup_autosave()
         #TODO
 #        self.w.add_accel_group(self.uimanager.get_accel_group())
@@ -232,7 +234,7 @@ class UI (gconf_wrapper.GConfWrapper):
         side_grid_container = self.builder.get_object("side_grid_container")
         tracker_ui_container = self.builder.get_object("tracker_ui_container")
 
-        self._main_grid_vew = view.SudokuView(group_size=9)
+        self._main_grid_vew = view.SudokuView(9, self._history_manager)
         self._main_grid_vew.connect('puzzle-finished', self.you_win_callback)
         main_grid_container.pack_start(self._main_grid_vew, padding=6)
 
@@ -300,25 +302,15 @@ class UI (gconf_wrapper.GConfWrapper):
             action.connect("activate", callback)
 
     def setup_undo (self):
-        # TODO
-        return
         self.cleared = [] # used for Undo memory
         self.cleared_notes = [] # used for Undo memory
-        # Set up our UNDO stuff
-        undo_widg = self.builder.get_object('Undo')
-        redo_widg = self.builder.get_object('Redo')
-        self.history = Undo.UndoHistoryList(undo_widg, redo_widg)
-        for entry in self.gsd.__entries__.values():
-            Undo.UndoableGenericWidget(entry, self.history,
-                                       set_method = 'set_value_from_undo',
-                                       pre_change_signal = 'value-about-to-change'
-                                       )
-            Undo.UndoableGenericWidget(entry, self.history,
-                                       set_method = 'set_notes',
-                                       get_method = 'get_note_text',
-                                       signal = 'notes-changed',
-                                       pre_change_signal = 'value-about-to-change',
-                                       )
+        undo_action = self.builder.get_object('Undo')
+        redo_action = self.builder.get_object('Redo')
+        self._history_manager = undo.HistoryManager(undo_action, redo_action)
+        undo_action.connect("activate",
+                lambda *args: self._history_manager.undo())
+        redo_action.connect("activate",
+                lambda *args: self._history_manager.redo())
 
     def setup_autosave (self):
         gobject.timeout_add_seconds(self.gconf['auto_save_interval'] or 60, # in seconds...
diff --git a/gnome-sudoku/src/lib/view.py b/gnome-sudoku/src/lib/view.py
index 8e32715..cf2c1b6 100644
--- a/gnome-sudoku/src/lib/view.py
+++ b/gnome-sudoku/src/lib/view.py
@@ -7,6 +7,7 @@ import gobject
 
 import colors
 import number_box
+import undo
 
 
 TRACKER_COLORS = [
@@ -170,6 +171,9 @@ class SudokuNumberGrid (gtk.AspectFrame):
         for e in self.__entries__.values():
             e.modify_bg(gtk.STATE_NORMAL, color)
 
+    def get_value(self, x, y):
+        return self.__entries__[(x, y)].get_value()
+
     def set_value(self, x, y, value):
         if not value:
             tid = self._tracker.get_tracker_by_coord(x, y)
@@ -201,7 +205,7 @@ class SudokuView(SudokuNumberGrid, gobject.GObject):
             "puzzle-finished": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ())
             }
 
-    def __init__(self, group_size):
+    def __init__(self, group_size, controller=None):
         SudokuNumberGrid.__init__(self, group_size)
         gobject.GObject.__init__(self)
 
@@ -209,12 +213,15 @@ class SudokuView(SudokuNumberGrid, gobject.GObject):
         self._do_highlight_cells = False
         self._notes_model = None
 
-        for e in self.__entries__.values():
-            e.show()
-            e.connect('number-changed', self._number_changed_cb)
-            e.connect('notes-changed', self._notes_changed_cb)
-            e.connect('focus-in-event', self._focus_callback)
-            e.connect('key-press-event', self._key_press_cb)
+        self._controller = controller
+        if controller:
+            # if controller is not set, we don't react to any user interaction
+            for e in self.__entries__.values():
+                e.show()
+                e.connect('number-changed', self._number_changed_cb)
+                e.connect('notes-changed', self._notes_changed_cb)
+                e.connect('focus-in-event', self._focus_callback)
+                e.connect('key-press-event', self._key_press_cb)
 
         self._tracker = _Tracker(self)
 
@@ -278,7 +285,12 @@ class SudokuView(SudokuNumberGrid, gobject.GObject):
             self.__entries__[(x, y)].set_notes((top_note, bottom_note))
 
     def _number_changed_cb(self, widget, new_number):
-        self.update_model(widget.x, widget.y, new_number)
+        x, y = widget.x, widget.y
+        # Use the displayed value, instead of that from the grid;
+        # because conflicting value doesn't get into the grid
+        old = self.get_value(x, y)
+        cmd = undo.ChangeValueCmd(self._model, x, y, old, new_number)
+        self._controller.execute_command(cmd)
 
     def update_model(self, x, y, value):
         self._model.set_value(x, y, value)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]