OSDN Git Service

Add the participation of thread window in the program quit counter of windowlist
[fukui-no-namari/fukui-no-namari.git] / src / Hage1 / board_window.py
index 1da5a4c..a6ff35c 100644 (file)
@@ -21,14 +21,36 @@ import gtk
 import gtk.glade
 import os
 import time
+import gobject
 
 import board_data
 import thread_window
+import misc
+from threadlistmodel import ThreadListModel
+
+import windowlist
+import brdlist_window
+import brdlist
 
 GLADE_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                          "..", "data")
 GLADE_FILENAME = "board_window.glade"
 
+def open_board(bbs, board):
+    if not bbs:
+        raise ValueError, "parameter must not be empty"
+
+    key = "/" + bbs + "/" + board
+    window = windowlist.get_window(key)
+    if window:
+        # already opened
+        window.present()
+        pass
+    else:
+        win_wrap = WinWrap(bbs, board)
+        widget = win_wrap.widget_tree.get_widget("board_window")
+        windowlist.window_created(key, widget)
+
 
 class WinWrap:
 
@@ -37,12 +59,18 @@ class WinWrap:
         self.board = board
 
         glade_path = os.path.join(GLADE_DIR, GLADE_FILENAME)
-        self.mainwin = gtk.glade.XML(glade_path)
+        self.widget_tree = gtk.glade.XML(glade_path)
 
-        self.treeview = self.mainwin.get_widget("treeview")
-        self.treeview.set_rules_hint(True)
+        self.window = self.widget_tree.get_widget("board_window")
 
-        self.popupmenu = self.mainwin.get_widget("popup_menu")
+        title = brdlist.get(bbs, board, "name")
+        if title:
+            self.window.set_title(title)
+
+        self.treeview = self.widget_tree.get_widget("treeview")
+        self.treeview.set_model(ThreadListModel())
+
+        self.popupmenu = self.widget_tree.get_widget("popup_menu")
 
         renderer = gtk.CellRendererText()
 
@@ -50,14 +78,19 @@ class WinWrap:
         for i in range(1, len(ThreadListModel.column_names)):
             column_name = ThreadListModel.column_names[i]
             self.treeviewcolumn[column_name] = gtk.TreeViewColumn(
-                column_name, renderer, text=i)
+                column_name, renderer)
             self.treeviewcolumn[column_name].set_resizable(True)
             self.treeviewcolumn[column_name].set_reorderable(True)
             self.treeviewcolumn[column_name].set_clickable(True)
+            self.treeviewcolumn[column_name].set_cell_data_func(
+                renderer, self.on_cell_data, column_name)
             self.treeviewcolumn[column_name].connect(
                 "clicked", self.on_column_clicked, column_name)
             self.treeview.append_column(self.treeviewcolumn[column_name])
 
+        self.treeviewcolumn["lastModified"].set_cell_data_func(
+            renderer, self.on_data_lastmodified)
+
         sigdic = {"on_board_window_destroy": self.on_board_window_destroy,
                   "on_quit_activate": self.on_quit_activate,
                   "on_load_local_activate": self.on_load_local_activate,
@@ -66,15 +99,61 @@ class WinWrap:
                   lambda w,p,v: self.on_open_thread(w),
                   "on_treeview_button_press_event":
                   self.on_treeview_button_press_event,
+                  "on_close_activate":
+                  self.on_close_activate,
+                  "on_show_board_list_activate":
+                  self.on_show_board_list_activate,
                   "on_popup_menu_open_activate": self.on_open_thread}
-        self.mainwin.signal_autoconnect(sigdic)
+        self.widget_tree.signal_autoconnect(sigdic)
+
+    def updated_thread_highlight(self, column, cell, model, iter):
+
+        def is_updated_thread():
+            res = model.get_value(
+                iter, ThreadListModel.column_names.index("res"))
+            linecount = model.get_value(
+                iter, ThreadListModel.column_names.index("lineCount"))
+            return res != 0 and linecount != 0 and res > linecount
+
+        if is_updated_thread():
+            cell.set_property("weight", 800)
+        else:
+            cell.set_property("weight", 400)
+
+    def on_cell_data(self, column, cell, model, iter, column_name):
+        self.updated_thread_highlight(column, cell, model, iter)
+        column_num = ThreadListModel.column_names.index(column_name)
+        value = model.get_value(iter, column_num)
+        if model.get_column_type(column_num) == gobject.TYPE_INT:
+            if value == 0:
+                cell.set_property("text", "")
+            else:
+                cell.set_property("text", str(value))
+        else:
+            cell.set_property("text", value)
+
+    def on_data_lastmodified(self, column, cell, model, iter, user_data=None):
+        self.updated_thread_highlight(column, cell, model, iter)
+        lastmod = model.get_value(
+            iter, ThreadListModel.column_names.index("lastModified"))
+        if lastmod == 0:
+            cell.set_property("text", "")
+        else:
+            cell.set_property("text", time.strftime(
+                "%Y/%m/%d(%a) %H:%M:%S", time.localtime(lastmod)))
 
     def on_board_window_destroy(self, widget):
-        gtk.main_quit()
+        pass
 
     def on_quit_activate(self, widget):
         gtk.main_quit()
 
+    def on_close_activate(self, widget):
+        self.window.destroy()
+
+    def on_show_board_list_activate(self, widget):
+        brdlist_window.open_brdlist(self.bbs)
+
     def on_load_local_activate(self, widget):
         t = board_data.LoadLocal(self.bbs, self.board, self.update_datastore)
         t.start()
@@ -115,7 +194,7 @@ class WinWrap:
             iter, ThreadListModel.column_names.index("title"))
         print thread + ':"' + title + '"', "activated"
 
-        thread_window.WinWrap(self.bbs, self.board, thread)
+        thread_window.open_thread(self.bbs, self.board, thread)
 
     def on_treeview_button_press_event(self, widget, event):
         if event.button == 3:
@@ -130,125 +209,51 @@ class WinWrap:
                 self.popupmenu.popup(None, None, None, event.button, time)
             return 1
 
-    def update_datastore(self, datalist):
+    def update_datastore(self, datalist, lastmod):
         print "reflesh datastore"
 
+        try:
+            lastmod = misc.httpdate_to_secs(lastmod)
+        except:
+            lastmod = 0
+
         time_start = time.time()
         list_list = []
         for id, dic in datalist.iteritems():
             dic["id"] = id
+
+            # average
+            if lastmod == 0 or dic["num"] == 0:
+                dic["average"] = 0
+            else:
+                res = dic["res"]
+                start = int(id)
+                # avoid the Last-Modified time of subject.txt and
+                # the build time of thread is equal (zero division)
+                dur = lastmod - start
+                if dur == 0:
+                    dic["average"] = 999999
+                else:
+                    dic["average"] = int(res * 60 * 60 * 24 / dur)
+
+            # lastModified
+            httpdate = dic["lastModified"]
+            try:
+                secs = misc.httpdate_to_secs(httpdate)
+                dic["lastModified"] = secs
+            except ValueError:
+                dic["lastModified"] = 0
+            
             list_list.append(dic)
 
         model = self.treeview.get_model()
-        if model:
-            sort_column_name, sort_reverse = model.get_sort()
-            model = ThreadListModel(list_list, sort_column_name, sort_reverse)
-        else:
-            model = ThreadListModel(list_list)
-        self.treeview.set_model(model)
+        model.set_list(list_list)
+
+        # redraw visible area after set list to model
+        self.treeview.queue_draw()
 
         self.reset_sort_indicator()
 
         print "end"
         time_end = time.time()
         print time_end - time_start
-
-
-class ThreadListModel(gtk.GenericTreeModel):
-    column_types = (str, int, str, int, int, str)
-    column_names = ["id", "num", "title", "res", "lineCount", "lastModified"]
-
-    def __init__(self, list, sort_column_name="num", sort_reverse=False):
-        gtk.GenericTreeModel.__init__(self)
-        self.list = list
-        self.sort_column_name = sort_column_name
-        self.sort_reverse = sort_reverse
-        self.do_sort(self.sort_column_name, self.sort_reverse)
-
-    def compare(self, v1, v2, reverse):
-        if not reverse:
-            if v1 == 0 and v2 == 0:
-                return 0
-            elif v1 == 0:
-                return 1
-            elif v2 == 0:
-                return -1
-        return v1 - v2
-
-    def get_sort(self):
-        return self.sort_column_name, self.sort_reverse
-
-    def do_sort(self, column_name, reverse):
-        if self.column_types[self.column_names.index(column_name)] == str:
-            self.list.sort(None, lambda dic: dic[column_name], reverse)
-        else:
-            h = lambda x, y: self.compare(x, y, reverse)
-            self.list.sort(h, lambda dic: dic[column_name], reverse)
-
-    def sort(self, column_name):
-        oldorder_dic = {}
-        for index, item in enumerate(self.list):
-            oldorder_dic[item["id"]] = index
-
-        if column_name == self.sort_column_name:
-            # sort reverse
-            self.sort_reverse = not self.sort_reverse
-        else:
-            self.sort_column_name = column_name
-            self.sort_reverse = False
-
-        self.do_sort(self.sort_column_name, self.sort_reverse)
-
-        neworder = []
-        for item in self.list:
-            neworder.append(oldorder_dic[item["id"]])
-        self.rows_reordered(None, None, neworder)
-
-    def on_get_flags(self):
-        return gtk.TREE_MODEL_LIST_ONLY
-
-    def on_get_n_columns(self):
-        return len(self.column_types)
-
-    def on_get_column_type(self, n):
-        return self.column_types[n]
-
-    def on_get_iter(self, path):
-        return self.list[path[0]]
-
-    def on_get_path(self, rowref):
-        return self.list.index(rowref)
-
-    def on_get_value(self, rowref, column):
-        return rowref[self.column_names[column]]
-
-    def on_iter_next(self, rowref):
-        try:
-            i = self.list.index(rowref)+1
-            return self.list[i]
-        except IndexError:
-            return None
-
-    def on_iter_children(self, rowref):
-        if rowref:
-            return None
-        return self.list[0]
-
-    def on_iter_has_child(self, rowref):
-        return False
-
-    def on_iter_n_children(self, rowref):
-        if rowref:
-            return 0
-        return len(self.list)
-
-    def on_iter_nth_child(self, rowref, n):
-        if rowref:
-            return None
-        try:
-            return self.list[n]
-        except IndexError:
-            return None
-
-    def on_iter_parent(child):
-        return None