~ubuntu-branches/ubuntu/karmic/quodlibet/karmic

« back to all changes in this revision

Viewing changes to quodlibet/plugins/editing.py

  • Committer: Bazaar Package Importer
  • Author(s): Luca Falavigna
  • Date: 2009-01-30 23:55:34 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20090130235534-l4e72ulw0vqfo17w
Tags: 2.0-1ubuntu1
* Merge from Debian experimental (LP: #276856), remaining Ubuntu changes:
  + debian/patches/40-use-music-profile.patch:
    - Use the "Music and Movies" pipeline per default.
* Refresh the above patch for new upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
# Copyright 2005 Joe Wreschnig
 
3
#
 
4
# This program is free software; you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License version 2 as
 
6
# published by the Free Software Foundation
 
7
#
 
8
# $Id: editing.py 4330 2008-09-14 03:19:26Z piman $
 
9
 
 
10
import gtk
 
11
 
 
12
from quodlibet.plugins import Manager
 
13
 
 
14
class RenameFilesPlugin(object):
 
15
    """Plugins of this type must subclass a GTK widget. They will be
 
16
    packed into the RenameFiles pane (currently a ScrolledWindow hidden
 
17
    with an expander, but that might change).
 
18
 
 
19
    The 'filter' function will be called with the song's original filename
 
20
    as a string (probably in the local filesystem encoding) and the proposed
 
21
    new filename as a unicode object. It should return an
 
22
    appropriate-transformed filename, still as a unicode object.
 
23
 
 
24
    The plugin must provide either a 'changed' or 'preview'. 'preview'
 
25
    causes the entire display to be re-previewed. 'changed' causes the
 
26
    Preview button to made sensitive, and Save to be disabled.
 
27
 
 
28
    If the 'active' attribute is false, the filter will not be called.
 
29
    This is particularly useful for gtk.CheckButtons.
 
30
 
 
31
    The '_order' attribute decides the sort order of the plugin. The
 
32
    default filters have orders between 1 and 2. Plugins have order 0 by
 
33
    default. Plugins with equal orders are sorted by class name."""
 
34
 
 
35
    _order = 0.0
 
36
    active = False
 
37
 
 
38
    def filter(self, original_filename, value): return value
 
39
    def filter_list(self, origs, names): return map(self.filter, origs, names)
 
40
 
 
41
    def __cmp__(self, other):
 
42
        return (cmp(self._order, other._order) or
 
43
                cmp(type(self).__name__, type(other).__name__))
 
44
 
 
45
class TagsFromPathPlugin(object):
 
46
    """Plugins of this type must subclass a GTK widget. They will be
 
47
    packed into the TagsFromPath pane (currently a ScrolledWindow hidden
 
48
    with an expander, but that might change).
 
49
 
 
50
    The 'filter' function will be called with the tag and proposed value
 
51
    as a unicode object. It should return an appropriate-transformed
 
52
    filename, still as a unicode object.
 
53
 
 
54
    If you need to work on a set of filenames at once, you should
 
55
    instead overload the 'filter_list' function, which takes two lists;
 
56
    one of original filenames, the other of proposed new filenames.
 
57
    The default filter_list function calls filter on each item.
 
58
 
 
59
    The plugin must provide either a 'changed' or 'preview'. 'preview'
 
60
    causes the entire display to be re-previewed. 'changed' causes the
 
61
    Preview button to made sensitive, and Save to be disabled.
 
62
 
 
63
    If the 'active' attribute is false, the filter will not be called.
 
64
    This is particularly useful for gtk.CheckButtons.
 
65
 
 
66
    The '_order' attribute decides the sort order of the plugin. The
 
67
    default filters have orders between 1 and 2. Plugins have order 0 by
 
68
    default. Plugins with equal orders are sorted by class name."""
 
69
 
 
70
    _order = 0
 
71
    active = False
 
72
 
 
73
    def filter(self, tag, value): return value
 
74
 
 
75
    def __cmp__(self, other):
 
76
        return (cmp(self._order, other._order) or
 
77
                cmp(type(self).__name__, type(other).__name__))
 
78
 
 
79
class EditTagsPlugin(gtk.ImageMenuItem):
 
80
    """Plugins of this type are subclasses of gtk.ImageMenuItem.
 
81
    They will be added to the context menu of the EditTags tree view.
 
82
 
 
83
    The 'tags' attribute is a list of tags this plugin should appear on,
 
84
    or false if it should appear for all tags. This must be a class
 
85
    attribute, as it is checked before instantiation.
 
86
 
 
87
    The 'needs' attribute is a list of tags that must be editable in
 
88
    the currently selected songs for the plugin to be sensitive.
 
89
 
 
90
    The constructor is called with the tag and value for that row. This
 
91
    can be used to set the sensitivity of the menu item, or change its
 
92
    text.
 
93
 
 
94
    When clicked, the 'activated' function is called on the object,
 
95
    again with the tag name and value. It should return a list of
 
96
    (tag, value) tuples to replace the previous tag/value with.
 
97
 
 
98
    The '_order' attribute decides the sort order of the plugin. The
 
99
    default items have orders between 0 and 1. Plugins have order 2.0 by
 
100
    default. Plugins with equal orders are sorted by class name.
 
101
 
 
102
    How to Handle Submenus
 
103
    ----------------------
 
104
    If the menu item is given a submenu, magic happens. In particular,
 
105
    the callbacks are proxied to the submenu's items, and are attached,
 
106
    via connect_object, to make sure activated is called on the original
 
107
    item.
 
108
 
 
109
    So, to handle submenus,
 
110
      1. Make a submenu and attach it to your menu item.2
 
111
      2. To each item in the submenu, attach its 'activate' signal to
 
112
         something appropriate to prepare the original item's
 
113
         activated method,
 
114
      3. Because that method will be called after the subitem is
 
115
         clicked on, and your activate handler runs.
 
116
    """
 
117
 
 
118
    tags = []
 
119
    needs = []
 
120
    _order = 2.0
 
121
 
 
122
    def activated(self, tag, value): return [(tag, value)]
 
123
 
 
124
    def connect(self, signal, callback, *args, **kwargs):
 
125
        if self.get_submenu():
 
126
            for item in self.get_submenu().get_children():
 
127
                item.connect_object(signal, callback, self, *args, **kwargs)
 
128
        else:
 
129
            super(EditTagsPlugin, self).connect(
 
130
                signal, callback, *args, **kwargs)
 
131
 
 
132
class EditingPlugins(Manager):
 
133
    Kinds = [EditTagsPlugin, RenameFilesPlugin, TagsFromPathPlugin]
 
134
 
 
135
    def RenamePlugins(self):
 
136
        return super(EditingPlugins, self).find_subclasses(RenameFilesPlugin)
 
137
 
 
138
    def TagsFromPathPlugins(self):
 
139
        return super(EditingPlugins, self).find_subclasses(TagsFromPathPlugin)
 
140
 
 
141
    def EditTagsPlugins(self):
 
142
        return super(EditingPlugins, self).find_subclasses(EditTagsPlugin)