1 # Copyright (C) 2006 by Aiwota Programmer
2 # aiwotaprog@tetteke.tk
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.
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.
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
29 from threadlistmodel import ThreadListModel
31 GLADE_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)),
33 GLADE_FILENAME = "board_window.glade"
38 def __init__(self, bbs, board):
42 glade_path = os.path.join(GLADE_DIR, GLADE_FILENAME)
43 self.mainwin = gtk.glade.XML(glade_path)
45 self.treeview = self.mainwin.get_widget("treeview")
46 self.treeview.set_model(ThreadListModel())
47 self.treeview.set_rules_hint(True)
49 self.popupmenu = self.mainwin.get_widget("popup_menu")
51 renderer = gtk.CellRendererText()
53 self.treeviewcolumn = {}
54 for i in range(1, len(ThreadListModel.column_names)):
55 column_name = ThreadListModel.column_names[i]
56 self.treeviewcolumn[column_name] = gtk.TreeViewColumn(
57 column_name, renderer)
58 self.treeviewcolumn[column_name].set_resizable(True)
59 self.treeviewcolumn[column_name].set_reorderable(True)
60 self.treeviewcolumn[column_name].set_clickable(True)
61 self.treeviewcolumn[column_name].set_cell_data_func(
62 renderer, self.on_cell_data, column_name)
63 self.treeviewcolumn[column_name].connect(
64 "clicked", self.on_column_clicked, column_name)
65 self.treeview.append_column(self.treeviewcolumn[column_name])
67 self.treeviewcolumn["lastModified"].set_cell_data_func(
68 renderer, self.on_data_lastmodified)
70 sigdic = {"on_board_window_destroy": self.on_board_window_destroy,
71 "on_quit_activate": self.on_quit_activate,
72 "on_load_local_activate": self.on_load_local_activate,
73 "on_get_remote_activate": self.on_get_remote_activate,
74 "on_treeview_row_activated":
75 lambda w,p,v: self.on_open_thread(w),
76 "on_treeview_button_press_event":
77 self.on_treeview_button_press_event,
78 "on_popup_menu_open_activate": self.on_open_thread}
79 self.mainwin.signal_autoconnect(sigdic)
81 def updated_thread_highlight(self, column, cell, model, iter):
83 def is_updated_thread():
84 res = model.get_value(
85 iter, ThreadListModel.column_names.index("res"))
86 linecount = model.get_value(
87 iter, ThreadListModel.column_names.index("lineCount"))
88 return res != 0 and linecount != 0 and res > linecount
90 if is_updated_thread():
91 cell.set_property("weight", 800)
93 cell.set_property("weight", 400)
95 def on_cell_data(self, column, cell, model, iter, column_name):
96 self.updated_thread_highlight(column, cell, model, iter)
97 column_num = ThreadListModel.column_names.index(column_name)
98 value = model.get_value(iter, column_num)
99 if model.get_column_type(column_num) == gobject.TYPE_INT:
101 cell.set_property("text", "")
103 cell.set_property("text", str(value))
105 cell.set_property("text", value)
107 def on_data_lastmodified(self, column, cell, model, iter, user_data=None):
108 self.updated_thread_highlight(column, cell, model, iter)
109 lastmod = model.get_value(
110 iter, ThreadListModel.column_names.index("lastModified"))
112 cell.set_property("text", "")
114 cell.set_property("text", time.strftime(
115 "%Y/%m/%d(%a) %H:%M:%S", time.localtime(lastmod)))
117 def on_board_window_destroy(self, widget):
120 def on_quit_activate(self, widget):
123 def on_load_local_activate(self, widget):
124 t = board_data.LoadLocal(self.bbs, self.board, self.update_datastore)
127 def on_get_remote_activate(self, widget):
128 t = board_data.GetRemote(self.bbs, self.board, self.update_datastore)
131 def on_column_clicked(self, treeviewcolumn, column_name):
132 model = self.treeview.get_model()
134 model.sort(column_name)
135 self.reset_sort_indicator()
137 def reset_sort_indicator(self):
138 model = self.treeview.get_model()
140 sort_column_name, sort_reverse = model.get_sort()
141 for name,column in self.treeviewcolumn.iteritems():
142 column.set_sort_indicator(False)
143 if sort_column_name != "num" or sort_reverse:
144 self.treeviewcolumn[sort_column_name].set_sort_indicator(True)
146 self.treeviewcolumn[sort_column_name].set_sort_order(
149 self.treeviewcolumn[sort_column_name].set_sort_order(
152 def on_open_thread(self, widget):
153 treeselection = self.treeview.get_selection()
154 model, iter = treeselection.get_selected()
158 thread = model.get_value(iter, ThreadListModel.column_names.index("id"))
159 title = model.get_value(
160 iter, ThreadListModel.column_names.index("title"))
161 print thread + ':"' + title + '"', "activated"
163 thread_window.WinWrap(self.bbs, self.board, thread)
165 def on_treeview_button_press_event(self, widget, event):
166 if event.button == 3:
170 pthinfo = widget.get_path_at_pos(x, y)
171 if pthinfo is not None:
172 path, col, cellx, celly = pthinfo
174 widget.set_cursor(path, col, 0)
175 self.popupmenu.popup(None, None, None, event.button, time)
178 def update_datastore(self, datalist, lastmod):
179 print "reflesh datastore"
182 lastmod = misc.httpdate_to_secs(lastmod)
186 time_start = time.time()
188 for id, dic in datalist.iteritems():
192 if lastmod == 0 or dic["num"] == 0:
197 # avoid the Last-Modified time of subject.txt and
198 # the build time of thread is equal (zero division)
199 dur = lastmod - start
201 dic["average"] = 999999
203 dic["average"] = int(res * 60 * 60 * 24 / dur)
206 httpdate = dic["lastModified"]
208 secs = misc.httpdate_to_secs(httpdate)
209 dic["lastModified"] = secs
211 dic["lastModified"] = 0
213 list_list.append(dic)
215 model = self.treeview.get_model()
216 model.set_list(list_list)
217 self.reset_sort_indicator()
220 time_end = time.time()
221 print time_end - time_start