Package: exfalso
Version: 1.0-2
Severity: normal
Tags: patch

Renaming files in exfalso is O(n^2) or worse.
Whenever a file is renamed, the library is updated. The library will now
call back to the editing pane ('changed') and update the preview, which
involves recomputing the names for all files selected and building a
whole new GTK tree model, as well as updating it in the UI.
This is especially noticeable when renaming a large (hundreds) number of
files, and you can see it significantly speeding up at the end.

The attached patch suspends updating of the preview (and thus
recomputing the tree model and all this) while the renaming is in
progress. It keeps the last argument passed to the preview function, and
when updating is re-enabled, it will trigger an update with the last
arguments. This led to a huge speed increase here.

-- System Information:
Debian Release: lenny/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: i386 (i686)

Kernel: Linux 2.6.26-rc3 (SMP w/2 CPU cores; PREEMPT)
Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages exfalso depends on:
ii  libgtk2.0-0                   2.12.10-1  The GTK+ graphical user interface 
ii  libmpcdec3                    1.2.2-1    Musepack (MPC) format library
ii  python                        2.5.2-1    An interactive high-level object-o
ii  python-central                0.6.7      register and build utility for Pyt
ii  python-gtk2                   2.12.1-4   Python bindings for the GTK+ widge
ii  python-mutagen                1.14-1     audio metadata editing library
ii  python-pyvorbis               1.3-2      A Python interface to the Ogg Vorb

exfalso recommends no packages.

-- no debconf information
Index: quodlibet/qltk/renamefiles.py
===================================================================
--- quodlibet/qltk/renamefiles.py       (Revision 4279)
+++ quodlibet/qltk/renamefiles.py       (Arbeitskopie)
@@ -73,6 +73,11 @@
         column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
         self.view.append_column(column)
 
+        # suspend preview to avoid slow renaming
+        self.__preview_suspended = False
+        self.__preview_need_update = False
+        self.__preview_last_param = None
+
         self.preview.connect_object('clicked', self.__preview, None)
 
         parent.connect_object('changed', self.__class__.__preview, self)
@@ -88,6 +93,8 @@
             self.save.set_sensitive(True)
 
     def __rename(self, library):
+        # block updates of the item list while we're renaming
+        self.__suspend_preview()
         model = self.view.get_model()
         win = WritingWindow(self, len(model))
         was_changed = []
@@ -120,11 +127,31 @@
                 if resp != gtk.RESPONSE_OK: break
             if win.step(): break
 
+        # re-enable updates
+        self.__unsuspend_preview()
         win.destroy()
         library.changed(was_changed)
         self.save.set_sensitive(False)
 
+    def __suspend_preview(self):
+        self.__preview_suspended = True
+
+    def __unsuspend_preview(self):
+        self.__preview_suspended = False
+        # execute pending updates
+        if self.__preview_need_update:
+            self.__preview(self.__preview_last_param)
+        # reset update cache
+        self.__preview_need_update = False
+        self.__preview_last_param = None
+
     def __preview(self, songs):
+        if self.__preview_suspended:
+            self.__preview_need_update = True
+            # when suspended, keep the last set of parameters
+            if songs:
+                self.__preview_last_param = songs
+            return
         model = self.view.get_model()
         if songs is None:
             songs = [row[0] for row in model]

Reply via email to