OSDN Git Service

Statusbar, ThreadWindow
[fukui-no-namari/fukui-no-namari.git] / src / FukuiNoNamari / thread_window.py
index 20f6650..a6421e7 100644 (file)
@@ -74,15 +74,47 @@ def open_thread(uri, update=False):
         winwrap.load(update)
 
     # jump to the res if necessary.
-    strict_uri = winwrap.bbs_type.get_thread_uri()
-    if (winwrap.bbs_type.uri != strict_uri and
-        winwrap.bbs_type.uri.startswith(strict_uri)):
-        resnum = winwrap.bbs_type.uri[len(strict_uri):]
+    strict_uri = bbs_type.get_thread_uri()
+    if (bbs_type.uri != strict_uri and
+        bbs_type.uri.startswith(strict_uri)):
+        resnum = bbs_type.uri[len(strict_uri):]
         match = re.match("\d+", resnum)
         if match:
             resnum = int(match.group())
             winwrap.jump_to_res(resnum)
 
+
+class HTMLParserToThreadView:
+    def __init__(self, threadview, resnum, left_margin):
+        self.threadview = threadview
+        self.resnum = resnum
+        self.left_margin = left_margin
+        self.initialize()
+
+    def set_left_margin(self, left_margin):
+        self.left_margin = left_margin
+
+    def initialize(self):
+        self.layout = None
+
+    def on_new_line(self):
+        self.to_thread_view()
+        self.layout = self.threadview.create_res_layout(
+            self.left_margin, self.resnum)
+
+    def from_html_parser(self, data, bold, href):
+        if self.layout == None:
+            self.layout = self.threadview.create_res_layout(
+                self.left_margin, self.resnum)
+
+        self.layout.add_text(data, bold, href)
+
+    def to_thread_view(self):
+        if self.layout is not None:
+            gobject.idle_add(self.threadview.add_layout, self.layout)
+            self.initialize()
+
+
 class WinWrap(winwrapbase.WinWrapBase):
     hovering_over_link = False
     hand_cursor = gtk.gdk.Cursor(gtk.gdk.HAND2)
@@ -114,6 +146,27 @@ class WinWrap(winwrapbase.WinWrapBase):
         self.vbox.pack_start(self.threadview)
         self.vbox.reorder_child(self.threadview, 2)
 
+        self.threadview.on_uri_clicked = self.on_threadview_uri_clicked
+
+        self.statusbar_context_id = self.statusbar.get_context_id(
+            "Thread Window Status")
+        self.statusbar.push(self.statusbar_context_id, "OK.")
+
+        self.threadview.popupmenu = self.widget_tree.get_widget(
+            "popup_threadview_menu")
+        self.threadview.menu_openuri = self.widget_tree.get_widget(
+            "popup_threadview_menu_openuri")
+        self.threadview.menu_copylinkaddress = self.widget_tree.get_widget(
+            "popup_threadview_menu_copylinkaddress")
+        self.threadview.menu_separator_link = self.widget_tree.get_widget(
+            "popup_threadview_menu_separator_link")
+        self.threadview.menu_copyselection = self.widget_tree.get_widget(
+            "popup_threadview_menu_copyselection")
+        self.threadview.menu_openasuri = self.widget_tree.get_widget(
+            "popup_threadview_menu_openasuri")
+        self.threadview.menu_separator_selection = self.widget_tree.get_widget(
+            "popup_threadview_menu_separator_selection")
+
         self.initialize_buffer()
 
         sigdic = {"on_refresh_activate": self.update,
@@ -130,6 +183,16 @@ class WinWrap(winwrapbase.WinWrapBase):
                   "on_add_bookmark_activate": self.on_add_bookmark_activate,
                   "on_manage_bookmarks_activate": \
                   self.on_manage_bookmarks_activate,
+                  "on_popup_threadview_menu_openuri_activate":
+                  self.on_popup_threadview_menu_openuri_activate,
+                  "on_popup_threadview_menu_copylinkaddress_activate":
+                  self.on_popup_threadview_menu_copylinkaddress_activate,
+                  "on_popup_threadview_menu_copyselection_activate":
+                  self.on_popup_threadview_menu_copyselection_activate,
+                  "on_popup_threadview_menu_openasuri_activate":
+                  self.on_popup_threadview_menu_openasuri_activate,
+                  "on_popup_threadview_menu_refresh_activate":
+                  self.on_popup_threadview_menu_refresh_activate,
                   "on_thread_window_destroy": self.on_thread_window_destroy}
         self.widget_tree.signal_autoconnect(sigdic)
 
@@ -211,6 +274,38 @@ class WinWrap(winwrapbase.WinWrapBase):
         except OSError:
             traceback.print_exc()
 
+    def on_threadview_uri_clicked(self, uri):
+
+        if not uri.startswith("http://"):
+            # maybe a relative uri.
+            uri = urlparse.urljoin(self.bbs_type.get_uri_base(), uri)
+
+        try:
+            uri_opener.open_uri(uri)
+        except bbs_type_exception.BbsTypeError:
+            # not supported, show with the web browser.
+            gnome.url_show(uri)
+            
+    def on_popup_threadview_menu_openuri_activate(self, widget):
+        self.on_threadview_uri_clicked(widget.uri)
+
+    def on_popup_threadview_menu_copylinkaddress_activate(self, widget):
+        clip = gtk.Clipboard()
+        clip.set_text(widget.uri, len(widget.uri))
+
+    def on_popup_threadview_menu_copyselection_activate(self, widget):
+        text = self.threadview.get_selected_text()
+        if text and len(text) > 0:
+            clip = gtk.Clipboard()
+            text = text.encode("utf8")
+            clip.set_text(text, len(text))
+
+    def on_popup_threadview_menu_openasuri_activate(self, widget):
+        self.on_threadview_uri_clicked(self.threadview.get_selected_text())
+
+    def on_popup_threadview_menu_refresh_activate(self, widget):
+        self.update(widget)
+
     def http_get_dat(self, on_get_res):
         datfile_url = self.bbs_type.get_dat_uri()
 
@@ -227,19 +322,38 @@ class WinWrap(winwrapbase.WinWrapBase):
         if etag:
             req.add_header("If-None-Match", etag)
 
+        def push():
+            self.statusbar.pop(self.statusbar_context_id)
+            self.statusbar.push(self.statusbar_context_id, "GET...")
+        gobject.idle_add(push)
+
         req = self.bbs_type.set_extra_dat_request(req, self)
 
         opener = urllib2.build_opener(HTTPRedirectHandler302, HTTPDebugHandler)
         try:
             res = opener.open(req)
         except urllib2.HTTPError, e:
-            pass
-#             gobject.idle_add(
-#                 lambda x: self.statusbar.push(0, x), "%d %s" % (e.code, e.msg))
+            def push(code, msg):
+                message = "%d %s" % (code, msg)
+                self.statusbar.pop(self.statusbar_context_id)
+                self.statusbar.push(self.statusbar_context_id, message)
+            gobject.idle_add(push, e.code, e.msg)
         else:
             headers = res.info()
-#             gobject.idle_add(
-#                 lambda x: self.statusbar.push(0, x), "%d %s" % (res.code, res.msg))
+
+            if "Last-Modified" in headers:
+                la = headers["Last-Modified"]
+                def push(code, msg, lastm):
+                    message = "%d %s [%s]" % (code, msg, lastm)
+                    self.statusbar.pop(self.statusbar_context_id)
+                    self.statusbar.push(self.statusbar_context_id, message)
+                gobject.idle_add(push, res.code, res.msg, la)
+            else:
+                def push(code, msg):
+                    message = "%d %s" % (code, msg)
+                    self.statusbar.pop(self.statusbar_context_id)
+                    self.statusbar.push(self.statusbar_context_id, message)
+                gobject.idle_add(push, res.code, res.msg)
 
             maybe_incomplete = False
             for line in res:
@@ -372,8 +486,6 @@ class WinWrap(winwrapbase.WinWrapBase):
                 self.title = title
                 gobject.idle_add(self.window.set_title, title)
 
-        self.res_queue = []
-
         line = line.decode(self.bbs_type.encoding, "replace")
         m = self.bbs_type.dat_reg.match(line)
         if m:
@@ -398,15 +510,18 @@ class WinWrap(winwrapbase.WinWrapBase):
                     date += " ID:" + id
             self.reselems_to_buffer(num, name, mail, date, msg)
         else:
-            self.res_queue.append((str(self.num)+"\n", False, None, False))
-            self.res_queue.append((line, False, None, True))
+            self.reselems_to_buffer(
+                str(self.num), "Invalid Name", "Invalid Mail",
+                "Invalid Date", line)
             print "maybe syntax error.", self.num, line
 
-        self.process_queue(self.res_queue, self.num)
-
     def reselems_to_buffer(self, num, name, mail, date, msg):
+        pipe = HTMLParserToThreadView(self.threadview, num, 0)
         p = barehtmlparser.BareHTMLParser(
-            lambda d,b,h: self.res_queue.append((d,b,h,False)))
+            pipe.from_html_parser, pipe.on_new_line)
+
+        # First, create a pango layout for num,name,mail,date
+        # 'margin left' is 0
         # number
         p.feed(str(num) + " ")
 
@@ -418,75 +533,27 @@ class WinWrap(winwrapbase.WinWrapBase):
 
         # date
         p.feed(date)
-        p.feed("<br>")
+        p.flush()
+
+        pipe.to_thread_view()
 
+
+        # Second, create a pango layout for message
+        # 'margin left' is 20
         # msg
-        p.reset_func(lambda d,b,h: self.res_queue.append((d,b,h,True)))
+        pipe.set_left_margin(20)
         p.feed(msg.lstrip(" "))
 
-        p.feed("<br><br>")
+        p.feed("<br>")
         p.close()
 
+        pipe.to_thread_view()
+
     def href_tag(self, href):
         tag = self.textbuffer.create_tag(underline=pango.UNDERLINE_SINGLE)
         tag.set_data("href", href)
         return tag
 
-    def process_queue(self, queue, num):
-        text = ""
-        current_margin = False
-        attrlist = pango.AttrList()
-        for data, bold, href, margin in queue:
-            data = data.encode("utf8")
-            if current_margin != margin:
-                layout = self.threadview.create_pango_layout(text)
-                layout.set_wrap(pango.WRAP_CHAR)
-                layout.posY = 0
-                layout.resnum = num
-                layout.set_attributes(attrlist)
-                if current_margin:
-                    layout.marginleft = 20
-                else:
-                    layout.marginleft = 0
-                gobject.idle_add(self.threadview.add_layout, layout)
-
-                current_margin = margin
-                text = ""
-                attrlist = pango.AttrList()
-
-            if bold:
-                attrlist.insert(pango.AttrWeight(
-                    pango.WEIGHT_BOLD, len(text), len(text) + len(data)))
-            if href:
-                attrlist.insert(pango.AttrUnderline(
-                    pango.UNDERLINE_SINGLE, len(text), len(text) + len(data)))
-
-            text += data
-
-        if text != "":
-            layout = self.threadview.create_pango_layout(text)
-            layout.set_wrap(pango.WRAP_CHAR)
-            layout.posY = 0
-            layout.resnum = num
-            layout.set_attributes(attrlist)
-            if current_margin:
-                layout.marginleft = 20
-            else:
-                layout.marginleft = 0
-        gobject.idle_add(self.threadview.add_layout, layout)
-#             taglist = []
-#             if bold:
-#                 taglist.append(self.boldtag)
-#             if href:
-#                 taglist.append(self.href_tag(href))
-#             if margin:
-#                 taglist.append(self.leftmargintag)
-#
-#            if taglist:
-#                self.textbuffer.insert_with_tags(self.enditer, data, *taglist)
-#            else:
-#                self.textbuffer.insert(self.enditer, data)
-
     def jump(self, value):
         gobject.idle_add(self.threadview.jump, value)