001:
002:
003:
004:
005:
006:
007:
008:
009: reloadable=True
010: reloadables=[]
011:
012:
013:
014: import itertools,bisect
015: import gtk
016: from treemodel import filttab
017: from filttab import canonical
018:
019:
020:
021: class FiltMaster(object):
022:
023:
024:
025:
026: def __init__(self,rows=[],ncols=None,wcols=None,xcols=[],*p,**pp):
027: if ncols==None and wcols==None:
028: ncols=1
029: wcols=[False]
030: elif ncols==None:
031: assert isinstance(wcols,list)
032: ncols=len(wcols)
033: elif wcols==None:
034: assert isinstance(ncols,int) and ncols>=1
035: wcols=[False]*ncols
036: else:
037: assert isinstance(ncols,int) and ncols>=1
038: assert isinstance(wcols,list) and len(wcols)==ncols
039: assert isinstance(xcols,list)
040: if rows:
041: assert isinstance(rows[0],tuple)
042: mcols=len(rows[0])
043: assert mcols==ncols+len(xcols)
044: else:
045: mcols=ncols+len(xcols)
046: self.presorted=zip(itertools.count(),rows)
047: for s in self.presorted:
048: assert isinstance(s[1],tuple) and len(s[1])==mcols
049: self.mcols=mcols
050: self.ncols=ncols
051: self.wcols=wcols
052: self.xcols=xcols[:]
053: self.p=p
054: self.pp=pp
055: self.master=[
056: ((0,),(0,s[1][0]<>""),[],s,True,canonical(s[1][0]))
057: for s in self.presorted
058: ]
059:
060:
061: def clone_master(self):
062: clone=FiltMaster(
063: rows=[],
064: ncols=self.ncols,
065: wcols=self.wcols,
066: xcols=self.xcols,
067: *self.p,**self.pp
068: )
069: clone.presorted=self.presorted
070: clone.master=self.master[:]
071: try:
072: clone.category=dict(self.category)
073: clone.sortable=list(self.sortable)
074: except AttributeError:
075: pass
076: return clone
077:
078: def activate_category_attribute(self):
079: self.sortable=[(c,s[0]) for (c,x,xs,s,q,y) in self.master]
080: self.category=dict([(i,c) for (c,i) in self.sortable])
081:
082: def add_strikethrough_attribute(self):
083: self.xcols.append((False,bool))
084: self.master=[
085: (c,x,xs,(s[0],s[1]+(False,)),q,y)
086: for (c,x,xs,s,q,y) in self.master
087: ]
088: self.activate_category_attribute()
089:
090: def factory_init(self,filt,comp,inpt):
091: filt.history=[("",0,filt.filtered_nil()+self.master)]
092: if not comp:
093: filt.clear()
094: for (c,x,xs,s,q,y) in self.master:
095: filt.append(s[1])
096: else:
097: filt.filter_comprehend(comp,inpt)
098:
099: def FiltTable(self,comp="",inpt=None):
100: filt=filttab.FiltTable(
101: rows=[],
102: ncols=self.ncols,
103: wcols=self.wcols,
104: xcols=self.xcols,
105: *self.p,**self.pp
106: )
107: self.factory_init(filt,comp,inpt)
108: return filt
109:
110: def FiltCombo(self,comp="",inpt=None):
111: filt=filttab.FiltCombo(
112: rows=[],
113: ncols=self.ncols,
114: wcols=self.wcols,
115: xcols=self.xcols,
116: *self.p,**self.pp
117: )
118: self.factory_init(filt,comp,inpt)
119: if not comp:
120: filt.show_filter()
121: return filt
122:
123: def set_strikethrough(self,index):
124: self.change_master(
125: index,
126: (2,),
127: lambda c,x,xs,s,q,y: ((2,),x,xs,(s[0],s[1][:-1]+(True,)),q,y),
128: )
129:
130: def clear_strikethrough(self,index):
131: self.change_master(
132: index,
133: (0,),
134: lambda c,x,xs,s,q,y: ((0,),x,xs,(s[0],s[1][:-1]+(False,)),q,y),
135: )
136:
137: def set_field(self,index,f,v):
138: def field(c,x,xs,s,q,y):
139: slist=list(s[1])
140: slist[f]=v
141: return (c,x,xs,(s[0],tuple(slist)),q,y)
142: self.change_master(index,None,field)
143:
144: def change_master(self,index,newcategory,modifier):
145: assert isinstance(index,int)
146: if not 0<=index<len(self.presorted): return
147:
148: masteri=bisect.bisect_left(
149: self.sortable,(self.category[index],index)
150: )
151: assert self.sortable[masteri]==(self.category[index],index)
152: if newcategory==None:
153: oldrow=self.master[masteri]
154: newrow=modifier(*oldrow)
155: self.master[masteri]=newrow
156: else:
157:
158: self.category[index]=newcategory
159: oldkey=self.sortable.pop(masteri)
160: newkey=(newcategory,index)
161: oldrow=self.master.pop(masteri)
162: newrow=modifier(*oldrow)
163:
164: insort=bisect.bisect_left(self.sortable,newkey)
165: self.sortable.insert(insort,newkey)
166: self.master.insert(insort,newrow)
167:
168: def append_to_master(self,row):
169: n=len(self.master)
170: assert isinstance(row,tuple)
171: assert 0<=len(row)-self.ncols<=len(self.xcols)
172: self.presorted=self.presorted+[(n,row[:self.mcols])]
173: ext=tuple([xnil for (xnil,x) in self.xcols[len(row)-self.ncols:]])
174: bisect.insort(
175: self.master,
176: ((0,),(0,row[0]<>""),[],(n,row+ext),True,canonical(row[0]))
177: )
178:
179: def get_row(self,index):
180: if isinstance(index,int) and 0<=index<len(self.presorted):
181: return self.presorted[index][1]
182: else:
183: return None
184:
185: