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]