]> git.plutz.net Git - viper/blob - filters.py
implemeted most basic cropping controls
[viper] / filters.py
1 #encoding: utf-8
2 #Copyright 2009 - 2010 Paul Hänsch
3
4 #This file is part of Viper.
5
6 #Viper is free software: you can redistribute it and/or modify
7 #it under the terms of the GNU General Public License as published by
8 #the Free Software Foundation, either version 3 of the License, or
9 #(at your option) any later version.
10
11 #Viper is distributed in the hope that it will be useful,
12 #but WITHOUT ANY WARRANTY; without even the implied warranty of
13 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 #GNU General Public License for more details.
15
16 #You should have received a copy of the GNU General Public License
17 #along with Viper.  If not, see <http://www.gnu.org/licenses/>
18
19 from Tkinter import *
20 from plugin import *
21 import threading
22 import Pmw
23 import sys
24 import os
25
26 class FilterDiag(Frame):
27     """
28     Widget to display filter list and
29     filter configuration dialogs
30     """
31
32     def __init__(self, parent = None):
33         Frame.__init__(self, parent)
34
35         self.subgets = {}
36         self.plugins = []
37         self.chunks  = []
38
39         self.subgets['f_flist'] = LabelFrame( self, text = 'Applied Filters:' )
40         self.subgets['f_flist'].pack( side = LEFT, fill = Y, expand = True, anchor = W )
41         self.subgets['f_flist_upper'] = Frame(self.subgets['f_flist'])
42         self.subgets['f_flist_upper'].pack( side = TOP, expand = True, fill = BOTH)
43         self.subgets['lb_flist'] = Listbox(self.subgets['f_flist_upper'], width = 24 )
44         self.subgets['lb_flist'].pack( side = LEFT, anchor = W, fill = Y, expand = True )
45         self.subgets['sb_flist'] = Scrollbar(self.subgets['f_flist_upper'], orient = VERTICAL, 
46                                            command = self.subgets['lb_flist'].yview)
47         self.subgets['sb_flist'].pack( side = RIGHT, fill = Y, expand = True, anchor = E )
48         self.subgets['lb_flist'].config(yscrollcommand = self.subgets['sb_flist'].set)
49         self.subgets['b_del'] = Button(self.subgets['f_flist'], text = 'Delete', command=self.b_del)
50         self.subgets['b_del'].pack( side = LEFT, anchor = S, fill = X, expand = True )
51         self.subgets['b_up'] = Button(self.subgets['f_flist'], text = 'Up', command = self.b_up)
52         self.subgets['b_up'].pack( side = LEFT, anchor = S, fill = X, expand = True )
53         self.subgets['b_down'] = Button(self.subgets['f_flist'], text = 'Down', command = self.b_down)
54         self.subgets['b_down'].pack( side = LEFT, anchor = S, fill = X, expand = True )
55
56         self.subgets['f_filterCfg'] = Frame(self)
57         self.subgets['f_filterCfg'].pack( side = LEFT, expand = True, fill = BOTH, anchor = W )
58         self.subgets['f_selector'] = Frame(self.subgets['f_filterCfg'])
59         self.subgets['f_selector'].pack( side = TOP, expand = True, fill = X, anchor = N )
60
61         self.subgets['b_filter'] = Button(self.subgets['f_selector'], text = 'Apply Filter',
62                                           command = self.apply_filter)
63         self.subgets['b_filter'].pack(side = RIGHT, expand = True, fill = X)
64         self.subgets['f_pluginCfg'] = None
65
66         self.load_plugins()
67
68     def find_filter(self, chunk, flist, fidx):
69         """
70         Find the index of a filter in joined filter list
71
72         When several chunks are marked the filter list will display the
73         intersecion set of the filters, these chunks hold.
74         This function finds the chunks filter line marked in the intersection
75
76         chunk - chunk in which the filter should be found
77         flist - filter list intersection
78         fidx  - index of marked filter in intersection
79         """
80         vc_idx = list_idx = 0
81         while not chunk.filter_eq(chunk.filters[vc_idx], flist[list_idx]): vc_idx+=1
82         while list_idx != fidx:
83             list_idx+=1
84             while not chunk.filter_eq(chunk.filters[vc_idx], flist[list_idx]): vc_idx+=1
85         return vc_idx
86
87     def b_del(self):
88         """
89         Delete a filter marked in intersection list
90         """
91         active = self.subgets['lb_flist'].index(ANCHOR)
92         flist = self.subgets['lb_flist'].get(0, END)
93         if active == self.subgets['lb_flist'].index(ANCHOR):
94             for vc in self.chunks: del vc.filters[self.find_filter(vc, flist, active)]
95         self.rebuild_flist()
96         for vc in self.chunks: vc.chprops()
97
98     def b_up(self):
99         """
100         Move a filter up in intersection list
101         """
102         active = self.subgets['lb_flist'].index(ANCHOR)
103         flist = self.subgets['lb_flist'].get(0, END)
104         for vc in self.chunks:
105             rem = self.find_filter(vc, flist, active)
106             subst = self.find_filter(vc, flist, active - 1)
107             vc.filters.insert(subst, vc.filters.pop(rem))
108         self.rebuild_flist()
109         self.subgets['lb_flist'].selection_anchor(active - 1)
110         self.subgets['lb_flist'].selection_set(active - 1, active - 1)
111         for vc in self.chunks: vc.chprops()
112
113     def b_down(self):
114         """
115         Move a filter down in intersection list
116         """
117         active = self.subgets['lb_flist'].index(ANCHOR)
118         flist = self.subgets['lb_flist'].get(0, END)
119         for vc in self.chunks:
120             rem = self.find_filter(vc, flist, active)
121             subst = self.find_filter(vc, flist, active + 1)
122             vc.filters.insert(subst, vc.filters.pop(rem))
123         self.rebuild_flist()
124         self.subgets['lb_flist'].selection_anchor(active + 1)
125         self.subgets['lb_flist'].selection_set(active + 1, active + 1)
126         for vc in self.chunks: vc.chprops()
127
128     def apply_filter(self):
129         """
130         Add a filter to the selected chunks
131
132         When a filter was configured in the filters
133         plugin dialog, this function applies
134         the filter.
135         """
136         if self.subgets['f_pluginCfg'] != None:
137             for vc in self.chunks:
138                 print 'adding filter: '
139                 print self.subgets['f_pluginCfg'].subcommand()
140                 vc.add_filter(self.subgets['f_pluginCfg'].subcommand())
141         self.rebuild_flist()
142
143     def load_plugins(self):
144         """
145         Import all plugins from plugin directory
146         """
147         sys.path.insert(0, 'plugins/')
148         for plugin in os.listdir(sys.path[0]):
149             if plugin[-3:] == '.py':
150                 __import__(plugin[:-3], None, None, ['*'])
151
152         plugins = []
153         for f_class in F_Plugin.__subclasses__():
154             self.plugins.append(f_class(self.subgets['f_filterCfg']))
155         for f_class in self.plugins:
156             if f_class.is_available():
157                 plugins.append(f_class.name())
158
159         self.subgets['ob_filter'] = Pmw.OptionMenu(self.subgets['f_selector'],
160                                                    items = plugins,
161                                                    command = self.select_filter)
162         self.subgets['ob_filter'].pack(side = LEFT, expand = True, fill = X)
163
164     def select_filter(self, name):
165         """
166         Bring up selected filter dialog
167         """
168         for plugin in self.plugins:
169             if name == plugin.name():
170                 if self.subgets['f_pluginCfg'] != None:
171                     self.subgets['f_pluginCfg'].pack_forget()
172                 self.subgets['f_pluginCfg'] = plugin
173                 self.subgets['f_pluginCfg'].pack( side = BOTTOM, expand = True, fill = BOTH )
174
175     def set_chunks(self, chunks):
176         """
177         Rebuild list of marked (filter affected) chunks
178         """
179         diff = False
180         idx = 0
181         if self.chunks.__len__() != chunks.__len__():
182             diff = True
183         else:
184             for chunk in self.chunks:
185                 if chunk != chunks[idx]:
186                     diff = True
187                 idx += 1
188
189         if diff:
190             self.chunks = chunks
191             self.rebuild_flist()
192
193     def rebuild_flist(self):
194         """
195         (Re)Display filter list in list box
196         """
197         self.subgets['lb_flist'].delete(0, END)
198         self.subgets['lb_flist'].insert(0, 'Calculating\nIntersection...')
199         if self.chunks == []:
200             filters = []
201         else:
202             filters = list(self.chunks[0].filters)
203             for vc in self.chunks: filters = self.filterList_lcs(filters, vc.filters)
204         self.subgets['lb_flist'].delete( 0, END)
205         for filter in filters:
206             self.subgets['lb_flist'].insert(END, filter)
207
208     def filterList_lcs(self, f1, f2):
209         """
210         Calculate intersection of filters of
211         different chunks
212         """
213         #longest common sequence algorythm
214         if len(f1) == 0 or len(f2) == 0: return []
215         if self.chunks[0].filter_eq(f1[-1], f2[-1]):
216             ret = self.filterList_lcs(f1[:-1], f2[:-1])
217             ret.append(f1[-1])
218             return ret
219         g1 = self.filterList_lcs(f1[:-1], f2)
220         g2 = self.filterList_lcs(f1, f2[:-1])
221         if len(g2) > len(g1): return g2
222         else: return g1
223