add "dark" theme, work on themes
[booh] / lib / booh / UndoHandler.rb
index a2dbf4001be8e79b6da5d53e6de9ea41b648ef16..5b978089d2564f125d78f434d1bdd74cde8a4389 100644 (file)
@@ -1,5 +1,3 @@
-#!/usr/bin/ruby
-#
 #                         *  BOOH  *
 #
 # A.k.a `Best web-album Of the world, Or your money back, Humerus'.
@@ -20,6 +18,7 @@
 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 require 'gettext'
+require 'gtk2'
 include GetText
 bindtextdomain("booh")
 
@@ -27,31 +26,56 @@ module UndoHandler
 
     @undo_actions = []
     @redo_actions = []
+    @batch_mode = false
 
     module_function
 
     def save_undo(name, closure, params)
-        @undo_actions << { :name => name, :closure => closure, :params => params }
+        entry = { :name => name, :closure => closure, :params => params }
+        if @batch_mode
+            @batch << entry
+        else
+            @undo_actions << [ entry ]
+        end
+        @redo_actions = []
     end
 
     def undo(statusbar)
-        todo = @undo_actions.pop
-        redo_closure = todo[:closure].call(*todo[:params])
-        statusbar.pop(0)
-        statusbar.push(0, utf8(_("Undo %s.") % todo[:name]))
-        @redo_actions << { :name => todo[:name], :redo => redo_closure, :undo => todo }
+        all_todos = @undo_actions.pop
+        redos = []
+        all_todos.reverse.each { |todo|
+            redo_closure = todo[:closure].call(*todo[:params])
+            statusbar.pop(0)
+            statusbar.push(0, utf8(_("Undo %s.") % todo[:name]))
+            redos << { :name => todo[:name], :redo => redo_closure, :undo => todo }
+        }
+        @redo_actions << redos
         return !@undo_actions.empty?
     end
 
     def redo(statusbar)
-        redo_item = @redo_actions.pop
-        redo_item[:redo].call
-        statusbar.pop(0)
-        statusbar.push(0, utf8(_("Redo %s.") % redo_item[:name]))
-        @undo_actions << redo_item[:undo]
+        all_redos = @redo_actions.pop
+        undos = []
+        all_redos.reverse.each { |redo_item|
+            redo_item[:redo].call
+            statusbar.pop(0)
+            statusbar.push(0, utf8(_("Redo %s.") % redo_item[:name]))
+            undos << redo_item[:undo]
+        }
+        @undo_actions << undos
         return !@redo_actions.empty?
     end
 
+    def begin_batch
+        @batch_mode = true
+        @batch = []
+    end
+
+    def end_batch
+        @batch_mode = false
+        @undo_actions << @batch
+    end
+
     def cleanup
         @undo_actions.clear
         @redo_actions.clear