Pastey Working listview filter and sort demo

--# ListView filter and sort 
include GtkEngine.e  
include std/sort.e  
object students = { --name, class, age  
 {"Fred",    "Senior",   18},  
 {"Sue",     "Junior",   16},  
 {"Kathleen","Freshman", 14},  
 {"Arnold",  "Freshman", 14},  
 {"Xavier",  "Junior",   18},  
 {"Kathy",   "Teacher",	 33},  
 {"Thelma",  "Sophmore", 15},  
 {"Ralph",   "Junior",   17},  
 {"Bill",    "Junior",	 17},  
 {"Kate",    "Senior",	 18},  
 {"Jane",    "Senior",   17},  
 {"Mo",	     "Freshman", 13},  
 {"Charlie", "Teacher",  40},  
 {"Louise",  "Sophmore", 16},  
 {"Alice",   "Junior",   17},  
 {"George",  "Freshman", 13},  
 {"Chris",   "Senior",   19},  
 {"Frank",   "Freshman", 15},  
integer name_sort_dir = 0, class_sort_dir = 0, age_sort_dir = 0  
	win = create(GtkWindow,"size=300x300,border=10,$destroy=Quit"),  
	pan = create(GtkBox,"orientation=horizontal,spacing=10"),  
	scr = create(GtkScrolledWindow),  
	tv  = create(GtkTreeView),  
	sel = get(tv,"selection"), 
	col1 = create(GtkColumn,"title=Name,type=text,text=1,sort=1"),  
	col2 = create(GtkColumn,"title=Class,type=text,text=2,sort=2"),  
	col3 = create(GtkColumn,"title=Age,type=text,text=3,sort=3"),  
	box  = create(GtkButtonBox,"orientation=vertical"),  
	btn1 = create(GtkButton,"Frosh","select_by_class","Freshman"),  
	btn2 = create(GtkButton,"Soph.","select_by_class","Sophmore"),  
	btn3 = create(GtkButton,"Juniors","select_by_class","Junior"),  
	btn4 = create(GtkButton,"Seniors","select_by_class","Senior"),  
	btn5 = create(GtkButton,"All","select_by_class",0),  
	btn6 = create(GtkButton,"gtk-about","Help"),  
	btn7 = create(GtkButton,"gtk-quit","Quit")  
object selected_class = 0 -- set by btn1..5  
constant stored = create(GtkListStore,{gSTR,gSTR,gINT})  
constant filtered = create(GtkTreeModelFilter,stored)  
    set(filtered,"visible func",_("Filter"))  
constant sorted = create(GtkTreeModelSort,filtered)  
	set(tv,"headers clickable",TRUE)  
        set(col1,"sort indicator",TRUE)  
        set(col2,"sort indicator",TRUE) 
        set(col3,"sort indicator",TRUE) 
	connect(tv,"row-activated","ShowStudentInfo") -- on dbl click; 
    -- we have to manually connect sorting functions  
    -- to the header clicks here, since we're also   
    -- using a filter (they don't work well together)  
global function ShowStudentInfo(atom view, atom path, atom col) 
object model = get(view,"model") 
atom iter = allocate(32) 
atom fn1 = define_proc("gtk_tree_model_get_iter",{P,P,P}) 
if get(model,"iter is valid",iter) then 
object name = get(model,"value",iter,1) 
object class = get(model,"value",iter,2) 
object age = get(model,"value",iter,3) 
Info(,,name,format("Age [] Class []",{age,class})) 
else display("Invalid iterator!") 
end if 
return 1 
end function 
global function SetSortCol(atom btn, integer col)  
switch col do  
    case NAME then  
	 name_sort_dir = not(name_sort_dir) -- toggle  
	 set(sorted,"sort column id",col,name_sort_dir+1)  
    case CLASS then	  
	 class_sort_dir = not(class_sort_dir) 
	 set(sorted,"sort column id",col,class_sort_dir+1)  
    case AGE then  
	 age_sort_dir = not(age_sort_dir) 
	 set(sorted,"sort column id",col,age_sort_dir+1)  
 end switch  
return 1  
end function  
global function select_by_class(atom ctl, object pattern)  
-- when filter selection changes, must re-filter  
 selected_class = unpack(pattern) -- grab the pattern (Junior,Senior..) 
 return 1  
end function  
global function Filter(atom model, atom iter)  
 -- if "all" are selected, no need for further work   
 if atom(selected_class) then return 1 end if  
 -- otherwise, check each item against the selected class;    
 object val = get(model,"value",iter,2) -- col 2 contains the student's class; 
return equal(val,selected_class)   
end function  
global function Help()  
return Info(win,"About","Tree Model Fiters",  

A tree model filter hides parts of an underlying tree model.  
It requires a custom Filter routine which returns 1 if the  
row should be shown, 0 otherwise.  
You must write a custom filter function, but it's easy,   
usually only a few lines of code.  
Implementing a custom filter also requires manually connecting  
a custom sort routine, if you want the filtered results sorted.  
This too, is relatively simple.   
Examine the source code for this program.  
<i>Hint: try ctl-f to open a search entry, then typing ka, for   
example, to find Kate, Kathleen, etc... Use the up/dn arrow keys  
to select prev/next match on list.</i>  

end function