1
2 """
3 Module implements Table filtering and searching functionality.
4 Created Oct 2008
5 Copyright (C) Damien Farrell
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 """
21
22 from Tkinter import *
23 import Pmw
24 from types import *
25 import re
26
28 if v1 in v2:
29 return True
30
32 if not v1 in v2:
33 return True
34
36 if v1==v2:
37 return True
38
40 if v1!=v2:
41 return True
42
44 if v2>v1:
45 return True
46 return False
47
49 if v2<v1:
50 return True
51 return False
52
56
60
62 if len(v2)>v1:
63 return True
64
66 try:
67 float(v2)
68 return True
69 except:
70 return False
71
73 """Apply a regular expression"""
74 print re.findall(v1,v2)
75 return
76
77 operatornames = {'=':equals,'!=':notequals,
78 'contains':contains,'excludes':excludes,
79 '>':greaterthan,'<':lessthan,
80 'starts with':startswith,
81 'ends with':endswith,
82 'has length':haslength,
83 'is number':isnumber}
84
86 """Module level method. Filter recs by several filters using a user provided
87 search function.
88 filters is a list of tuples of the form (key,value,operator,bool)
89 returns: found record keys"""
90
91 if filters == None:
92 return
93 F = filters
94 sets = []
95 for f in F:
96 col, val, op, boolean = f
97 names = searchfunc(col, val, op)
98 sets.append((set(names), boolean))
99 names = sets[0][0]
100 for s in sets[1:]:
101 b=s[1]
102 if b == 'AND':
103 names = names & s[0]
104 elif b == 'OR':
105 names = names | s[0]
106 elif b == 'NOT':
107 names = names - s[0]
108
109 names = list(names)
110 return names
111
113
114 - def __init__(self, parent, fields, callback=None, closecallback=None):
115 """Create a filtering gui frame.
116 Callback must be some method that can accept tuples of filter
117 parameters connected by boolean operators """
118 Frame.__init__(self, parent)
119 self.parent = parent
120 self.callback = callback
121 self.closecallback = closecallback
122 self.fields = fields
123 self.filters = []
124 self.addFilterBar()
125 addbutton=Button(self,text='Go', command=self.callback,bg='lightblue')
126 addbutton.grid(row=0,column=0,sticky='news',padx=2,pady=2)
127 addbutton=Button(self,text='+Add Filter', command=self.addFilterBar)
128 addbutton.grid(row=0,column=1,sticky='news',padx=2,pady=2)
129 cbutton=Button(self,text='Close', command=self.close)
130 cbutton.grid(row=0,column=2,sticky='news',padx=2,pady=2)
131 self.resultsvar=IntVar()
132 Label(self,text='found:').grid(row=0,column=3,sticky='nes')
133 Label(self,textvariable=self.resultsvar).grid(row=0,column=4,sticky='nws',padx=2,pady=2)
134 return
135
137 """Add filter"""
138 index = len(self.filters)
139 f = FilterBar(self, index, self.fields)
140 self.filters.append(f)
141 f.grid(row=index+1,column=0,columnspan=5,sticky='news',padx=2,pady=2)
142 return
143
145 """Close frame and do stuff in parent app if needed"""
146 self.closecallback()
147 self.destroy()
148 return
149
157
159 self.resultsvar.set(i)
160 return
161
163 """Class providing filter widgets"""
164 operators = ['contains','excludes','=','!=','>','<','starts with',
165 'ends with','has length','is number']
166 booleanops = ['AND','OR','NOT']
167 - def __init__(self, parent, index, fields):
168 Frame.__init__(self, parent)
169 self.parent=parent
170 self.index = index
171 self.filtercol=StringVar()
172 initial = fields[0]
173 filtercolmenu = Pmw.OptionMenu(self,
174 labelpos = 'w',
175 label_text = 'Column:',
176 menubutton_textvariable = self.filtercol,
177 items = fields,
178 initialitem = initial,
179 menubutton_width = 10)
180 filtercolmenu.grid(row=0,column=1,sticky='news',padx=2,pady=2)
181 self.operator=StringVar()
182 operatormenu = Pmw.OptionMenu(self,
183 menubutton_textvariable = self.operator,
184 items = self.operators,
185 initialitem = 'contains',
186 menubutton_width = 8)
187 operatormenu.grid(row=0,column=2,sticky='news',padx=2,pady=2)
188 self.filtercolvalue=StringVar()
189 valsbox=Entry(self,textvariable=self.filtercolvalue,width=20,bg='white')
190 valsbox.grid(row=0,column=3,sticky='news',padx=2,pady=2)
191 valsbox.bind("<Return>", self.parent.callback)
192 self.booleanop=StringVar()
193 booleanopmenu = Pmw.OptionMenu(self,
194 menubutton_textvariable = self.booleanop,
195 items = self.booleanops,
196 initialitem = 'AND',
197 menubutton_width = 6)
198 booleanopmenu.grid(row=0,column=0,sticky='news',padx=2,pady=2)
199
200 if self.index == 0:
201 booleanopmenu.component('menubutton').configure(state=DISABLED)
202 cbutton=Button(self,text='-', command=self.close)
203 cbutton.grid(row=0,column=5,sticky='news',padx=2,pady=2)
204 return
205
207 """Destroy and remove from parent"""
208 self.parent.filters.remove(self)
209 self.destroy()
210 return
211
213 """Get filter values for this instance"""
214 col = self.filtercol.get()
215 val = self.filtercolvalue.get()
216 op = self.operator.get()
217 booleanop = self.booleanop.get()
218 return col, val, op, booleanop
219