2 #Copyright 2009 - 2010 Paul Hänsch
4 #This file is part of Viper.
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.
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.
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/>
26 class FilterDiag(Frame):
28 Widget to display filter list and
29 filter configuration dialogs
32 def __init__(self, parent = None):
33 Frame.__init__(self, parent)
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 )
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 )
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
68 def find_filter(self, chunk, flist, fidx):
70 Find the index of a filter in joined filter list
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
76 chunk - chunk in which the filter should be found
77 flist - filter list intersection
78 fidx - index of marked filter in intersection
81 while not chunk.filter_eq(chunk.filters[vc_idx], flist[list_idx]): vc_idx+=1
82 while list_idx != fidx:
84 while not chunk.filter_eq(chunk.filters[vc_idx], flist[list_idx]): vc_idx+=1
89 Delete a filter marked in intersection list
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)]
96 for vc in self.chunks: vc.chprops()
100 Move a filter up in intersection list
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))
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()
115 Move a filter down in intersection list
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))
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()
128 def apply_filter(self):
130 Add a filter to the selected chunks
132 When a filter was configured in the filters
133 plugin dialog, this function applies
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())
143 def load_plugins(self):
145 Import all plugins from plugin directory
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, ['*'])
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())
159 self.subgets['ob_filter'] = Pmw.OptionMenu(self.subgets['f_selector'],
161 command = self.select_filter)
162 self.subgets['ob_filter'].pack(side = LEFT, expand = True, fill = X)
164 def select_filter(self, name):
166 Bring up selected filter dialog
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 )
175 def set_chunks(self, chunks):
177 Rebuild list of marked (filter affected) chunks
181 if self.chunks.__len__() != chunks.__len__():
184 for chunk in self.chunks:
185 if chunk != chunks[idx]:
193 def rebuild_flist(self):
195 (Re)Display filter list in list box
197 self.subgets['lb_flist'].delete(0, END)
198 self.subgets['lb_flist'].insert(0, 'Calculating\nIntersection...')
199 if self.chunks == []:
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)
208 def filterList_lcs(self, f1, f2):
210 Calculate intersection of filters of
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])
219 g1 = self.filterList_lcs(f1[:-1], f2)
220 g2 = self.filterList_lcs(f1, f2[:-1])
221 if len(g2) > len(g1): return g2