[gnome-games/applygsoc2009: 73/76] Do clear and clear-by-tracker by controller



commit 45fed508317206adf5911c0f30f892faf68b3e38
Author: Pablo Castellano <pablog src gnome org>
Date:   Wed Sep 1 05:32:51 2010 +0200

    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 |   34 +++++++++++++-----------------
 gnome-sudoku/src/lib/view.py  |   46 ++++++++++++++++++++++++++++++++++------
 3 files changed, 55 insertions(+), 27 deletions(-)
---
diff --git a/gnome-sudoku/src/lib/main.py b/gnome-sudoku/src/lib/main.py
index 231fc3f..96cd592 100644
--- a/gnome-sudoku/src/lib/main.py
+++ b/gnome-sudoku/src/lib/main.py
@@ -290,7 +290,7 @@ class SudokuGame (gconf_wrapper.GConfWrapper):
             action.connect("activate", callback)
 
 	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 5664526..529bdec 100644
--- a/gnome-sudoku/src/lib/model.py
+++ b/gnome-sudoku/src/lib/model.py
@@ -156,25 +156,6 @@ class SudokuModel(gobject.GObject):
             self.animate_hint()
             self.hint_timer = gobject.timeout_add(150, self.animate_hint)
 
-    def reset_grid (self):
-        '''Remove all untracked values from the grid
-
-        This method is used to clear all untracked values from the grid for
-        the undo processing.  The tracked values and notes are handled higher
-        up by the caller.
-        '''
-        removed = []
-        for x in range(self.group_size):
-            for y in range(self.group_size):
-                if not self.grid.virgin._get_(x, y):
-                    e = self.__entries__[(x, y)]
-                    val = e.get_value()
-                    track = e.tracker_id
-                    if val and track == tracker_info.NO_TRACKER:
-                        removed.append((x, y, val))
-                    self.remove(x, y)
-        return removed
-
     def apply_notelist(self, notelist, apply_tracker = False):
         '''Re-apply notes
 
@@ -452,6 +433,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 6ee5190..6920f42 100644
--- a/gnome-sudoku/src/lib/view.py
+++ b/gnome-sudoku/src/lib/view.py
@@ -72,12 +72,15 @@ 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:
@@ -172,6 +175,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.hint_square = None
 #        self.tinfo = tracker_info.TrackerInfo()
@@ -199,10 +206,12 @@ class SudokuView(SudokuNumberGrid):
                 self.set_value(x, y, 0)
                 self.set_readonly_appearance(x, y, False)
 
-    def connect_to_model(self, model):
-        if not model:
+    def connect_to_model(self, sudoku_model):
+        """Listening update from sudoku_model
+        """
+        if not sudoku_model:
             return
-        self._model = model
+        self._model = sudoku_model
         model.add_observer(self)
         for x in range(self.group_size):
             for y in range(self.group_size):
@@ -270,6 +279,29 @@ class SudokuView(SudokuNumberGrid):
         cmd = model.ChangeValueCmd(self._model, x, y, old, new_number)
         self._controller.execute_command(cmd)
 
+    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)
 
@@ -349,12 +381,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]