[gnome-games/sudoku-tube] Do clear and clear-by-tracker by controller



commit 6711288fa3644f2e4d60b49e80e0356a9c4dc0ba
Author: Zhang Sen <zh jesse gmail com>
Date:   Mon Aug 17 20:38:48 2009 +0800

    Do clear and clear-by-tracker by controller
    
    Not directly through model

 gnome-sudoku/src/lib/main.py  |    2 +-
 gnome-sudoku/src/lib/model.py |   26 +++++++++++++++-----------
 gnome-sudoku/src/lib/view.py  |   40 ++++++++++++++++++++++++++++++++++------
 3 files changed, 50 insertions(+), 18 deletions(-)
---
diff --git a/gnome-sudoku/src/lib/main.py b/gnome-sudoku/src/lib/main.py
index 620a736..8ff8b38 100644
--- a/gnome-sudoku/src/lib/main.py
+++ b/gnome-sudoku/src/lib/main.py
@@ -672,7 +672,7 @@ class SudokuGame(gconf_wrapper.GConfWrapper):
             self.is_fullscreen = True
 
     def clear_cb(self, action):
-        self._main_model.reset_grid()
+        self._main_grid_vew.do_clear()
 
     def clear_notes_cb(self, action):
         self._notes_model.clear_notes()
diff --git a/gnome-sudoku/src/lib/model.py b/gnome-sudoku/src/lib/model.py
index 7058e2b..6e6db95 100644
--- a/gnome-sudoku/src/lib/model.py
+++ b/gnome-sudoku/src/lib/model.py
@@ -205,17 +205,6 @@ class SudokuModel(gobject.GObject):
             observer.update(values)
         self._check_for_completeness()
 
-    def reset_grid (self):
-        """Reset grid to its original setup.
-        """
-
-        for x in range(self.group_size):
-            for y in range(self.group_size):
-                if not self.grid.virgin._get_(x, y):
-                    # conflicting values are not being tracked, so we have to
-                    # set_value on all the entries, instead of only filled ones
-                    self.set_value(x, y, 0)
-
     def _setup_virgin_grid(self, virgin):
         """both grid and initial_grid should be str"""
         virgin = virgin.replace(" ", "")
@@ -352,6 +341,21 @@ class ChangeValueCmd:
         self.execute = lambda: model.set_value(x, y, new)
         self.undo = lambda: model.set_value(x, y, old)
 
+class MultiChangeValueCmd:
+    def __init__(self, model, change_list):
+        """change_list should be list of (x, y, old, new)
+        """
+        self._model = model
+        self._list = change_list
+
+    def execute(self):
+        for x, y, old, new in self._list:
+            self._model.set_value(x, y, new)
+
+    def undo(self):
+        for x, y, old, new in self._list:
+            self._model.set_value(x, y, old)
+
 class AutoFillCmd:
     def __init__(self, model):
         self._model = model
diff --git a/gnome-sudoku/src/lib/view.py b/gnome-sudoku/src/lib/view.py
index a360a1e..9c05163 100644
--- a/gnome-sudoku/src/lib/view.py
+++ b/gnome-sudoku/src/lib/view.py
@@ -75,12 +75,14 @@ class _Tracker:
 
     def delete_by_tracker(self, identifier):
         """Delete all cells tracked by tracker ID identifier."""
+        change = []
         # copy the list, or there will be infinite-loop
         entries = self._trackers[identifier]
         self._trackers[identifier] = []
         for (x, y) in entries:
             self._tracker_by_coords[(x, y)] = None
-            self._sudoku_view.update_model(x, y, 0)
+            change.append((x, y))
+        self._sudoku_view.do_clear(change)
 
     def delete_except_for_tracker(self, identifier):
         for tracker_id in self._trackers:
@@ -210,6 +212,10 @@ class SudokuNumberGrid (gtk.AspectFrame):
 class SudokuView(SudokuNumberGrid):
 
     def __init__(self, group_size, controller=None):
+        """User commands take action through controller. The GUI is updated by
+        model. So in reality, it's like:
+            user_input -> controller -> model -> view
+        """
         SudokuNumberGrid.__init__(self, group_size)
 
         self._model = None
@@ -238,6 +244,8 @@ class SudokuView(SudokuNumberGrid):
         self._reset_notes()
 
     def connect_to_model(self, sudoku_model):
+        """Listening update from sudoku_model
+        """
         if not sudoku_model:
             return
         self._model = sudoku_model
@@ -313,8 +321,28 @@ class SudokuView(SudokuNumberGrid):
         cmd = model.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)
+    def _get_changed_list(self):
+        """Return all the boxes that are changed (compared to virgin puzzle)
+        """
+
+        res = []
+        for x in range(self.group_size):
+            for y in range(self.group_size):
+                if not self._model.get_virgin_value(x, y):
+                    # conflicting values are not being tracked, so we have to
+                    # set_value on all the entries, instead of only filled ones
+                    res.append((x, y))
+        return res
+
+    def do_clear(self, change_list=None):
+        res = []
+        if not change_list:
+            change_list = self._get_changed_list()
+        for x, y in change_list:
+            old = self.get_value(x, y)
+            res.append((x, y, old, 0))
+        cmd = model.MultiChangeValueCmd(self._model, res)
+        self._controller.execute_command(cmd)
 
     def _notes_changed_cb(self, widget, top_note, bottom_note):
         self._notes_model.set_notes(widget.x, widget.y, top_note, bottom_note)
@@ -392,12 +420,12 @@ class SudokuView(SudokuNumberGrid):
         limit_min, limit_max = 0, self.group_size - 1
         y_edge = [(limit_min, 'Up'), (limit_max, 'Down')]
         x_edge = [(limit_min, 'Left'), (limit_max, 'Right')]
-        opposite_edge = {limit_min: limit_max, limit_max: limit_min}
+        opposite = {limit_min: limit_max, limit_max: limit_min}
 
         if (y, direction) in y_edge:
-            return x, opposite_edge[y]
+            return x, opposite[y]
         elif (x, direction) in x_edge:
-            return opposite_edge[x], y
+            return opposite[x], y
         else:
             return None, None
 



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