on Anne's karmic koala, gtk_events_pending() is much more often true than on my machi...
[booh] / bin / booh-classifier
index 9a7584888034155e95392fdcf11f699ecc5a10e1..a3c6beba40f36cd0341cc3c90f980d765ef68203 100644 (file)
@@ -271,7 +271,7 @@ class Entry
         return $config['thumbnails-height'].to_i
     end
 
-    attr_accessor :path, :guipath, :type, :angle, :button, :image, :alignment, :removed, :labeled
+    attr_accessor :path, :guipath, :type, :angle, :button, :image, :alignment, :removed, :labeled, :loader
 
     def initialize(path, type, guipath)
         @path = path
@@ -411,11 +411,6 @@ class Entry
     end
 
     private
-    def cleanup_dir(dir)
-        Dir.entries(dir).each { |file| file != '.' && file != '..' and File.delete(File.join(dir, file)) }
-        Dir.delete(dir)
-    end
-
     def load_into_pixbuf_full
         if @pixbuf_full.nil?
             msg 3, ">>> load_into_pixbuf_full #{path}"
@@ -440,18 +435,16 @@ class Entry
     end
 
     def load_into_pixbuf_at_size(&specify_size)
-        pixbuf = nil
         if @type == 'video'
-            tmp = Tempfile.new("boohclassifiertemp")
-            dest_dir = tmp.path
-            tmp.close!
-            Dir.mkdir(dest_dir)
-            orig_base = File.basename(path)
-            tmpdir = gen_video_thumbnail(path, false, 0)
-            if tmpdir.nil?
-                return
+            if @video_image_path.nil?
+                orig_base = File.basename(path)
+                tmpdir = gen_video_thumbnail(path, false, 0)
+                if tmpdir.nil?
+                    return
+                end
+                @video_image_path = "#{tmpdir}/00000001.jpg"
             end
-            image_path = "#{tmpdir}/00000001.jpg"
+            image_path = @video_image_path
         else
             image_path = @path
         end
@@ -463,41 +456,45 @@ class Entry
             end
         end
         begin
-            #- use a pixbuf loader and trigger Gtk.main_iteration on each chunk if needed, to keep the UI responsive even
+            #- use a pixbuf loader and check Gtk.events_pending? on each chunk, to keep the UI responsive even
             #- if loaded pictures are several MBs large
-            loader = Gdk::PixbufLoader.new
-            loader.signal_connect('size-prepared') { |l, w, h|
-                r = specify_size.call(w, h)
-                #msg 3, "specified sizes: #{r[0]} #{r[1]}"
-                loader.set_size(*specify_size.call(w, h))
-            }
-            id = loader.signal_connect('area-prepared') { pixbuf = loader.pixbuf }
-            if ! loader.load_not_freezing_ui(image_path, id)
+            if @loader.nil?
+                @loader = Gdk::PixbufLoader.new
+                @loader.signal_connect('size-prepared') { |l, w, h|
+                    @loader.set_size(*specify_size.call(w, h))
+                }
+                @loader.signal_connect('area-prepared') { @loaded_pixbuf = @loader.pixbuf }
+                @loader_offset = 0
+            end
+            msg 3, "calling load_not_freezing_ui on #{image_path}, offset #{@loader_offset}"
+            @loader_offset = @loader.load_not_freezing_ui(image_path, @loader_offset)
+            if @loader_offset > 0
                 #- interrupted
                 raise InterruptedLoading
             end
-            if pixbuf.nil?
+            @loader = nil
+            if @loaded_pixbuf.nil?
                 raise "Loaded pixbuf nil - #{path} #{image_path}"
             end
         rescue
             msg 0, "Cannot load #{image_path}: #{$!}"
             return
         ensure
-            if @type == 'video'
-                File.delete(image_path)
-                Dir.rmdir(tmpdir)
+            if @video_image_path && @loader.nil?
+                File.delete(@video_image_path)
+                Dir.rmdir(File.dirname(@video_image_path))
+                @video_image_path = nil
             end
         end
-        if pixbuf
+        if @loaded_pixbuf
             if @angle != 0
                 msg 3, ">>> load_into_pixbuf_full #{image_path} => rotate #{@angle}"
-                pixbuf = rotate_pixbuf(pixbuf, @angle)
+                @loaded_pixbuf = rotate_pixbuf(@loaded_pixbuf, @angle)
             end
         end
-        if @type == 'video'
-            cleanup_dir(dest_dir)
-        end
-        return pixbuf
+        retval = @loaded_pixbuf
+        @loaded_pixbuf = nil
+        return retval
     end
 
     def to_s
@@ -1898,7 +1895,20 @@ def reset_labels
     evt.modify_bg(Gtk::StateType::ACTIVE, $color_red.lighter)
 end
 
+def cleanup_loaders
+    $allentries.each { |e| 
+        if ! e.loader.nil?
+            begin
+                e.loader.close
+            rescue
+                #- ignore loader errors, at that point they are fairly normal
+            end
+        end
+    }
+end
+
 def reset_thumbnails
+    cleanup_loaders
     $allentries = []
     if $preloader_running
         $preloader_force_exit = true
@@ -1986,4 +1996,6 @@ if ARGV[0]
 end
 Gtk.main
 
+cleanup_loaders
+
 write_config