OSDN Git Service

Make Filter exception safer.
[fukui-no-namari/fukui-no-namari.git] / src / FukuiNoNamari / threadlistmodel.py
1 # Copyright (C) 2006 by Aiwota Programmer
2 # aiwotaprog@tetteke.tk
3 #
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18 import pygtk
19 pygtk.require('2.0')
20 import gtk
21 import itertools
22
23
24 class ThreadListModel(gtk.GenericTreeModel):
25     column_types = (str, int, str, int, int, int, float)
26     column_names = ["id", "num", "title", "res", "lineCount",
27                     "lastModified", "average"]
28     column_width = [0, 30, 330, 50, 50, 200, 50]
29
30     def __init__(self):
31         gtk.GenericTreeModel.__init__(self)
32         self.original_list = []
33         self.list = []
34         self.order_dict = {}
35         self.sort_column_name = "num"
36         self.sort_reverse = False
37         self.filter_func = None
38
39         self.set_list([])
40
41     def modify_row(self, dict):
42         id = dict["id"]
43         if id in self.order_dict:
44             index = self.order_dict[id]
45             target_dict = self.list[index]
46             for name in self.column_names:
47                 if name in dict:
48                     target_dict[name] = dict[name]
49             self.row_changed(index, self.get_iter(index))
50
51     def refilter(self, filter_func):
52         before_size = len(self.list)
53         self.do_filter(filter_func)
54         after_size = len(self.list)
55         self.do_sort(self.sort_column_name, self.sort_reverse)
56         self.list_modified(before_size, after_size)
57         
58     def set_list(self, newlist):
59         self.original_list = newlist[:]
60         self.refilter(self.filter_func)
61
62     def build_order_dict(self):
63         # key: thread id, value: index in self.list
64         self.order_dict = dict(
65             [(item["id"], index) for index, item in enumerate(self.list)])
66
67     def list_modified(self, before_size, after_size):
68         if before_size > after_size:
69             print "remove", before_size-after_size, "threads"
70             for i in range(before_size - after_size):
71                 self.row_deleted(after_size)
72         elif after_size > before_size:
73             print "insert", after_size-before_size, "threads"
74             for i in range(before_size, after_size):
75                 self.row_inserted(i, self.get_iter(i))
76
77     def do_filter(self, filter_func):
78         # Set filter_func to self.filter_func after successful filtering.
79         # successful means no exception.
80
81         if not filter_func:
82             self.list = self.original_list[:]
83             self.filter_func = filter_func
84             return
85
86         predicate = lambda item: filter_func(self, item)
87         iterable = itertools.ifilter(predicate, self.original_list)
88         self.list = [item for item in iterable]
89         self.filter_func = filter_func
90
91     def compare(self, v1, v2, reverse):
92         if not reverse:
93             if v1 == 0 and v2 == 0:
94                 return 0
95             elif v1 == 0:
96                 return 1
97             elif v2 == 0:
98                 return -1
99         if v1 > v2:
100             return 1
101         elif v1 < v2:
102             return -1
103         else:
104             return 0
105
106     def get_sort(self):
107         return self.sort_column_name, self.sort_reverse
108
109     def do_sort(self, column_name, reverse):
110         if self.column_types[self.column_names.index(column_name)] == str:
111             self.list.sort(None, lambda dic: dic[column_name], reverse)
112         else:
113             h = lambda x, y: self.compare(x, y, reverse)
114             self.list.sort(h, lambda dic: dic[column_name], reverse)
115         self.build_order_dict()
116
117     def sort(self, column_name, order_specified=False, reverse=False):
118         old_order_dict = self.order_dict
119
120         if order_specified:
121             self.sort_reverse = reverse
122         else:
123             if column_name == self.sort_column_name:
124                 # sort reverse
125                 self.sort_reverse = not self.sort_reverse
126             else:
127                 self.sort_reverse = False
128         self.sort_column_name = column_name
129
130         self.do_sort(self.sort_column_name, self.sort_reverse)
131
132         neworder = [old_order_dict[item["id"]] for item in self.list]
133         self.rows_reordered(None, None, neworder)
134
135     def on_get_flags(self):
136         return gtk.TREE_MODEL_LIST_ONLY
137
138     def on_get_n_columns(self):
139         return len(self.column_types)
140
141     def on_get_column_type(self, n):
142         return self.column_types[n]
143
144     def on_get_iter(self, path):
145         try:
146             return self.list[path[0]]
147         except IndexError:
148             return None
149
150     def on_get_path(self, rowref):
151         return self.order_dict[rowref["id"]]
152
153     def on_get_value(self, rowref, column):
154         return rowref[self.column_names[column]]
155
156     def on_iter_next(self, rowref):
157         try:
158             i = self.order_dict[rowref["id"]] + 1
159             return self.list[i]
160         except IndexError:
161             return None
162
163     def on_iter_children(self, rowref):
164         if rowref:
165             return None
166         return self.list[0]
167
168     def on_iter_has_child(self, rowref):
169         return False
170
171     def on_iter_n_children(self, rowref):
172         if rowref:
173             return 0
174         return len(self.list)
175
176     def on_iter_nth_child(self, rowref, n):
177         if rowref:
178             return None
179         try:
180             return self.list[n]
181         except IndexError:
182             return None
183
184     def on_iter_parent(self, child):
185         return None