OSDN Git Service

replace GtkTextView with DrawingArea.
authorAiwota Programmer <aiwotaprog@tetteke.tk>
Sat, 8 Dec 2007 07:18:38 +0000 (16:18 +0900)
committerAiwota Programmer <aiwotaprog@tetteke.tk>
Sat, 8 Dec 2007 07:18:38 +0000 (16:18 +0900)
src/FukuiNoNamari/thread_window.py
src/data/thread_window.glade

index 9d38f86..d40bd1c 100644 (file)
@@ -82,7 +82,39 @@ class WinWrap(winwrapbase.WinWrapBase):
     regular_cursor = gtk.gdk.Cursor(gtk.gdk.XTERM)
 
 
+    def relayout(self):
+        width = self.drawingarea.allocation.width
+        sum_height = 0
+        for layout in self.pangolayout:
+            layout.set_width(width * pango.SCALE)
+            layout.posY = sum_height
+            x, y = layout.get_pixel_size()
+            sum_height += y
+        self.drawingarea.set_size_request(-1, sum_height)
+
+    def draw_viewport(self, area):
+        gc = self.drawingarea.window.new_gc()
+        self.drawingarea.window.draw_rectangle(
+            self.drawingarea.style.base_gc[0],
+            True, area.x, area.y, area.width, area.height)
+
+        for layout in self.pangolayout:
+            w, h = layout.get_pixel_size()
+            if ((layout.posY >= area.y and
+                layout.posY < area.y + area.height) or
+                (layout.posY + h >= area.y and
+                 layout.posY + h < area.y + area.height) or
+                (layout.posY <= area.y and layout.posY + h >= area.y)):
+                self.drawingarea.window.draw_layout(gc, 0, layout.posY, layout)
+
+    def on_drawingarea_expose_event(self, widget, event, data=None):
+        self.relayout()
+        self.draw_viewport(event.area)
+        return True
+
     def __init__(self, uri):
+        self.pangolayout = []
+
         from BbsType import bbs_type_judge_uri
         from BbsType import bbs_type_exception
         self.bbs_type = bbs_type_judge_uri.get_type(uri)
@@ -101,14 +133,12 @@ class WinWrap(winwrapbase.WinWrapBase):
         self.window = self.widget_tree.get_widget("thread_window")
         self.toolbar = self.widget_tree.get_widget("toolbar")
         self.toolbar.unset_style()
-        self.statusbar = self.widget_tree.get_widget("appbar")
-        self.textview = self.widget_tree.get_widget("textview")
-        self.textview.drag_dest_unset()
+        self.statusbar = self.widget_tree.get_widget("statusbar")
+        self.drawingarea = self.widget_tree.get_widget("drawingarea")
+        self.viewport = self.drawingarea.parent
 
         self.initialize_buffer()
 
-        self.hint = HintWrap()
-
         sigdic = {"on_refresh_activate": self.update,
                   "on_compose_activate": self.on_compose_clicked,
                   "on_toolbar_activate": self.on_toolbar_activate,
@@ -118,6 +148,7 @@ class WinWrap(winwrapbase.WinWrapBase):
                   "on_quit_activate": self.on_quit_activate,
                   "on_show_board_activate": self.on_show_board_activate,
                   "on_delete_activate": self.on_delete_activate,
+                  "on_drawingarea_expose_event": self.on_drawingarea_expose_event,
                   "on_thread_window_delete_event":
                   self.on_thread_window_delete_event,
                   "on_add_bookmark_activate": self.on_add_bookmark_activate,
@@ -126,24 +157,21 @@ class WinWrap(winwrapbase.WinWrapBase):
                   "on_thread_window_destroy": self.on_thread_window_destroy}
         self.widget_tree.signal_autoconnect(sigdic)
 
-        self.textview.connect("event-after", self.on_event_after)
-        self.textview.connect("motion-notify-event",
-                              self.on_motion_notify_event)
-        self.textview.connect("visibility-notify-event",
-                              self.on_visibility_notify_event)
         self.restore()
-        self.window.show()
+        self.window.show_all()
 
         self.created()
 
     def initialize_buffer(self):
         self.textbuffer = gtk.TextBuffer()
-        self.textview.set_buffer(self.textbuffer)
+
         self.enditer = self.textbuffer.get_end_iter()
         self.boldtag = self.textbuffer.create_tag(weight=pango.WEIGHT_BOLD)
         self.leftmargintag = self.textbuffer.create_tag()
         self.leftmargintag.set_property("left-margin", 20)
 
+        
+
     def destroy(self):
         self.save()
         self.window.destroy()
@@ -156,10 +184,10 @@ class WinWrap(winwrapbase.WinWrapBase):
         submit_window.open(self.bbs_type.get_thread_uri())
 
     def on_toolbar_activate(self, widget):
-        if self.toolbar.parent.get_property("visible"):
-            self.toolbar.parent.hide()
+        if self.toolbar.get_property("visible"):
+            self.toolbar.hide()
         else:
-            self.toolbar.parent.show()
+            self.toolbar.show()
 
     def on_statusbar_activate(self, widget):
         if self.statusbar.get_property("visible"):
@@ -167,116 +195,6 @@ class WinWrap(winwrapbase.WinWrapBase):
         else:
             self.statusbar.show()
 
-    def on_event_after(self, widget, event):
-        if event.type != gtk.gdk.BUTTON_RELEASE:
-            return False
-        if event.button != 1:
-            return False
-        buffer = widget.get_buffer()
-
-        try:
-            start, end = buffer.get_selection_bounds()
-        except ValueError:
-            pass
-        else:
-            if start.get_offset() != end.get_offset():
-                return False
-
-        x, y = widget.window_to_buffer_coords(
-            gtk.TEXT_WINDOW_WIDGET, int (event.x), int(event.y))
-        iter = widget.get_iter_at_location(x, y)
-        if not iter.has_tag(self.leftmargintag) or x > 20:
-            tags = iter.get_tags()
-            for tag in tags:
-                href = tag.get_data("href")
-                if href:
-                    self.on_link_clicked(widget, href)
-        return False
-
-    def on_link_clicked(self, widget, href):
-
-        if not href.startswith("http://"):
-            # maybe a relative uri.
-            href = urlparse.urljoin(self.bbs_type.get_uri_base(), href)
-
-        try:
-            uri_opener.open_uri(href)
-        except bbs_type_exception.BbsTypeError:
-            # not supported, show with the web browser.
-            gnome.url_show(href)
-
-    def on_motion_notify_event(self, widget, event):
-        x, y = widget.window_to_buffer_coords(
-            gtk.TEXT_WINDOW_WIDGET, int(event.x), int(event.y))
-        self.set_cursor_if_appropriate(widget, x, y)
-        widget.window.get_pointer()
-        return False
-
-    def on_visibility_notify_event(self, widget, event):
-        wx, wy, mod = widget.window.get_pointer()
-        bx, by = widget.window_to_buffer_coords(gtk.TEXT_WINDOW_WIDGET, wx, wy)
-
-        self.set_cursor_if_appropriate(widget, bx, by)
-        return False
-
-    def set_cursor_if_appropriate(self, widget, x, y):
-        hovering = False
-        href = ""
-
-        buffer = widget.get_buffer()
-        iter = widget.get_iter_at_location(x, y)
-        if not iter.has_tag(self.leftmargintag) or x > 20:
-            tags = iter.get_tags()
-            for tag in tags:
-                href = tag.get_data("href")
-                if href:
-                    hovering = True
-
-        if hovering != self.hovering_over_link:
-            self.hovering_over_link = hovering
-
-        if self.hovering_over_link:
-            widget.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(
-                self.hand_cursor)
-            if href:
-                if not href.startswith("http://"):
-                    href = urlparse.urljoin(self.bbs_type.get_uri_base(), href)
-
-                strict_uri = self.bbs_type.get_thread_uri()
-                if href != strict_uri and href.startswith(strict_uri):
-                    resnum = href[len(strict_uri):]
-                    match = re.match("\d+", resnum)
-                    if match:
-                        resnum = int(match.group())
-                        if not self.hint.visible(resnum):
-                            mark = self.textbuffer.get_mark(str(resnum))
-                            n_mark = self.textbuffer.get_mark(str(resnum+1))
-                            if mark and n_mark:
-                                iter = self.textbuffer.get_iter_at_mark(mark)
-                                n_iter = self.textbuffer.get_iter_at_mark(
-                                    n_mark)
-                                text = self.textbuffer.get_text(
-                                    iter, n_iter, False)
-                                if text:
-                                    iter = self.textview.get_iter_at_location(
-                                        x, y)
-                                    rect = self.textview.get_iter_location(
-                                        iter)
-                                    x, y = \
-                                       self.textview.buffer_to_window_coords(
-                                        gtk.TEXT_WINDOW_WIDGET, rect.x, rect.y)
-                                    x, y = self.textview.translate_coordinates(
-                                        self.window, x, y)
-                                    wx, wy = self.window.get_position()
-                                    x += wx
-                                    y += wy
-                                    y += rect.height
-                                    self.hint.show(x, y, text, resnum)
-        else:
-            widget.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(
-                self.regular_cursor)
-            self.hint.destroy()
-
     def on_close_activate(self, widget):
         self.destroy()
 
@@ -339,12 +257,13 @@ class WinWrap(winwrapbase.WinWrapBase):
         try:
             res = opener.open(req)
         except urllib2.HTTPError, e:
-            gobject.idle_add(
-                self.statusbar.set_status, "%d %s" % (e.code, e.msg))
+            pass
+#             gobject.idle_add(
+#                 lambda x: self.statusbar.push(0, x), "%d %s" % (e.code, e.msg))
         else:
             headers = res.info()
-            gobject.idle_add(
-                self.statusbar.set_status, "%d %s" % (res.code, res.msg))
+            gobject.idle_add(
+#                 lambda x: self.statusbar.push(0, x), "%d %s" % (res.code, res.msg))
 
             maybe_incomplete = False
             for line in res:
@@ -402,9 +321,9 @@ class WinWrap(winwrapbase.WinWrapBase):
                             num = self.jump_request_num
                             self.jump_request_num = 0
                             mark = self.textbuffer.get_mark(str(num))
-                            if mark:
-                                self.textview.scroll_to_mark(
-                                    mark, 0, True, 0, 0)
+#                            if mark:
+#                                self.textview.scroll_to_mark(
+#                                    mark, 0, True, 0, 0)
                     else:
                         self.jump_to_the_end(num)
 
@@ -427,8 +346,8 @@ class WinWrap(winwrapbase.WinWrapBase):
                     num = self.jump_request_num
                     self.jump_request_num = 0
                     mark = self.textbuffer.get_mark(str(num))
-                    if mark:
-                        self.textview.scroll_to_mark(mark, 0, True, 0, 0)
+#                    if mark:
+#                        self.textview.scroll_to_mark(mark, 0, True, 0, 0)
 
             gobject.idle_add(do_jump)
 
@@ -462,8 +381,8 @@ class WinWrap(winwrapbase.WinWrapBase):
                     num = self.jump_request_num
                     self.jump_request_num = 0
                     mark = self.textbuffer.get_mark(str(num))
-                    if mark:
-                        self.textview.scroll_to_mark(mark, 0, True, 0, 0)
+#                    if mark:
+#                        self.textview.scroll_to_mark(mark, 0, True, 0, 0)
                 else:
                     self.jump_to_the_end(num)
 
@@ -522,7 +441,7 @@ class WinWrap(winwrapbase.WinWrapBase):
         def process_res_queue(res_queue, num):
             self.process_queue(res_queue)
             # for next res
-            self.textbuffer.create_mark(str(num+1), self.enditer, True)
+            #self.textbuffer.create_mark(str(num+1), self.enditer, True)
 
         gobject.idle_add(
             process_res_queue, self.res_queue, self.num)
@@ -556,24 +475,31 @@ class WinWrap(winwrapbase.WinWrapBase):
         return tag
 
     def process_queue(self, queue):
+        text = ""
         for data, bold, href, margin in queue:
-            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)
+            text += data
+        layout = self.drawingarea.create_pango_layout(text)
+        layout.set_wrap(pango.WRAP_CHAR)
+        layout.posY = 0
+        self.pangolayout.append(layout)
+        self.relayout()
+#             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_to_the_end(self, num):
         mark = self.textbuffer.get_mark(str(num+1))
-        if mark:
-            self.textview.scroll_to_mark(mark, 0)
+#        if mark:
+#            self.textview.scroll_to_mark(mark, 0)
 
     def lock(self):
         if self.lock_obj:
@@ -596,11 +522,11 @@ class WinWrap(winwrapbase.WinWrapBase):
             if match:
                 resnum = match.group()
                 mark = self.textbuffer.get_mark(resnum)
-                if mark:
-                    self.textview.scroll_to_mark(mark, 0, True, 0, 0)
-                elif self.progress:
-                    # try later.
-                    self.jump_request_num = int(resnum)
+#                if mark:
+#                    self.textview.scroll_to_mark(mark, 0, True, 0, 0)
+#                elif self.progress:
+#                    # try later.
+#                    self.jump_request_num = int(resnum)
 
     def load(self, update=False):
         dat_path = misc.get_thread_dat_path(self.bbs_type)
@@ -618,7 +544,7 @@ class WinWrap(winwrapbase.WinWrapBase):
             # save only if dat file exists.
             if os.path.exists(dat_path):
                 window_width, window_height = self.window.get_size()
-                toolbar_visible = self.toolbar.parent.get_property("visible")
+                toolbar_visible = self.toolbar.get_property("visible")
                 statusbar_visible = self.statusbar.get_property("visible")
 
                 dirname = os.path.dirname(states_path)
@@ -690,57 +616,10 @@ class WinWrap(winwrapbase.WinWrapBase):
             self.window.set_default_size(window_width, window_height)
 
             if not toolbar_visible:
-                gobject.idle_add(self.toolbar.parent.hide,
+                gobject.idle_add(self.toolbar.hide,
                                  priority=gobject.PRIORITY_HIGH)
             if not statusbar_visible:
                 gobject.idle_add(self.statusbar.hide,
                                  priority=gobject.PRIORITY_HIGH)
         except:
             traceback.print_exc()
-
-
-class HintWrap:
-
-    def __init__(self):
-        self.window = None
-        self.textview = None
-        self.nums = None
-
-    def __del__(self):
-        print "destruct"
-        self.destroy()
-
-    def destroy(self):
-        if self.window:
-            self.window.destroy()
-        self.window = None
-        self.textview = None
-        self.nums = None
-
-    def show(self, x, y, text, *nums):
-        self.destroy()
-
-        self.window = gtk.Window(gtk.WINDOW_POPUP)
-        self.window.set_default_size(400, 10)
-        self.window.move(x, y)
-
-        self.textview = gtk.TextView()
-        self.window.add(self.textview)
-
-        self.textview.set_wrap_mode(gtk.WRAP_CHAR)
-        self.textview.set_editable(False)
-
-        buffer = self.textview.get_buffer()
-        buffer.set_text(text.rstrip())
-        self.nums = nums
-
-        self.window.show_all()
-
-    def visible(self, *nums):
-        if not self.nums or len(self.nums) != len(nums):
-            return False
-
-        for num, mun in itertools.izip(self.nums, nums):
-            if num != mun:
-                return False
-        return True
index 5d6702a..9d34a2e 100644 (file)
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--*- mode: xml -*-->
 <glade-interface>
-<requires lib="gnome"/>
-<requires lib="bonobo"/>
-
-<widget class="GnomeApp" id="thread_window">
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_NONE</property>
-  <property name="modal">False</property>
-  <property name="default_width">600</property>
-  <property name="default_height">600</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="enable_layout_config">True</property>
-  <signal name="destroy" handler="on_thread_window_destroy" last_modification_time="Wed, 16 Aug 2006 03:37:07 GMT"/>
-  <signal name="delete_event" handler="on_thread_window_delete_event" last_modification_time="Thu, 31 Aug 2006 10:56:18 GMT"/>
-
-  <child internal-child="dock">
-    <widget class="BonoboDock" id="bonobodock1">
-      <property name="visible">True</property>
-      <property name="allow_floating">True</property>
-
-      <child>
-       <widget class="BonoboDockItem" id="bonobodockitem1">
-         <property name="visible">True</property>
-         <property name="shadow_type">GTK_SHADOW_NONE</property>
-
-         <child>
-           <widget class="GtkMenuBar" id="menubar1">
-             <property name="visible">True</property>
-
-             <child>
-               <widget class="GtkMenuItem" id="file1">
-                 <property name="visible">True</property>
-                 <property name="stock_item">GNOMEUIINFO_MENU_FILE_TREE</property>
-
-                 <child>
-                   <widget class="GtkMenu" id="file1_menu">
-
-                     <child>
-                       <widget class="GtkImageMenuItem" id="show_board">
-                         <property name="visible">True</property>
-                         <property name="label" translatable="yes">Show Board</property>
-                         <property name="use_underline">True</property>
-                         <signal name="activate" handler="on_show_board_activate" last_modification_time="Mon, 21 Aug 2006 03:30:53 GMT"/>
-
-                         <child internal-child="image">
-                           <widget class="GtkImage" id="image22">
-                             <property name="visible">True</property>
-                             <property name="stock">gtk-go-up</property>
-                             <property name="icon_size">1</property>
-                             <property name="xalign">0.5</property>
-                             <property name="yalign">0.5</property>
-                             <property name="xpad">0</property>
-                             <property name="ypad">0</property>
-                           </widget>
-                         </child>
-                       </widget>
-                     </child>
-
-                     <child>
-                       <widget class="GtkImageMenuItem" id="compose">
-                         <property name="visible">True</property>
-                         <property name="label" translatable="yes">_Compose Message</property>
-                         <property name="use_underline">True</property>
-                         <signal name="activate" handler="on_compose_activate" last_modification_time="Thu, 31 Aug 2006 09:58:49 GMT"/>
-                         <accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="activate"/>
-
-                         <child internal-child="image">
-                           <widget class="GtkImage" id="image23">
-                             <property name="visible">True</property>
-                             <property name="stock">gnome-stock-mail-new</property>
-                             <property name="icon_size">1</property>
-                             <property name="xalign">0.5</property>
-                             <property name="yalign">0.5</property>
-                             <property name="xpad">0</property>
-                             <property name="ypad">0</property>
-                           </widget>
-                         </child>
-                       </widget>
-                     </child>
-
-                     <child>
-                       <widget class="GtkImageMenuItem" id="delete">
-                         <property name="visible">True</property>
-                         <property name="label" translatable="yes">_Delete Log</property>
-                         <property name="use_underline">True</property>
-                         <signal name="activate" handler="on_delete_activate" last_modification_time="Thu, 14 Sep 2006 04:44:02 GMT"/>
-
-                         <child internal-child="image">
-                           <widget class="GtkImage" id="image24">
-                             <property name="visible">True</property>
-                             <property name="stock">gtk-delete</property>
-                             <property name="icon_size">1</property>
-                             <property name="xalign">0.5</property>
-                             <property name="yalign">0.5</property>
-                             <property name="xpad">0</property>
-                             <property name="ypad">0</property>
-                           </widget>
-                         </child>
-                       </widget>
-                     </child>
-
-                     <child>
-                       <widget class="GtkSeparatorMenuItem" id="separator2">
-                         <property name="visible">True</property>
-                       </widget>
-                     </child>
-
-                     <child>
-                       <widget class="GtkImageMenuItem" id="close">
-                         <property name="visible">True</property>
-                         <property name="stock_item">GNOMEUIINFO_MENU_CLOSE_ITEM</property>
-                         <signal name="activate" handler="on_close_activate" last_modification_time="Wed, 16 Aug 2006 03:28:25 GMT"/>
-                       </widget>
-                     </child>
-
-                     <child>
-                       <widget class="GtkSeparatorMenuItem" id="separator1">
-                         <property name="visible">True</property>
-                       </widget>
-                     </child>
-
-                     <child>
-                       <widget class="GtkImageMenuItem" id="quit">
-                         <property name="visible">True</property>
-                         <property name="stock_item">GNOMEUIINFO_MENU_EXIT_ITEM</property>
-                         <signal name="activate" handler="on_quit_activate" last_modification_time="Wed, 16 Aug 2006 03:34:30 GMT"/>
-                       </widget>
-                     </child>
-                   </widget>
-                 </child>
-               </widget>
-             </child>
-
-             <child>
-               <widget class="GtkMenuItem" id="edit1">
-                 <property name="visible">True</property>
-                 <property name="stock_item">GNOMEUIINFO_MENU_EDIT_TREE</property>
-               </widget>
-             </child>
-
-             <child>
-               <widget class="GtkMenuItem" id="view1">
-                 <property name="visible">True</property>
-                 <property name="stock_item">GNOMEUIINFO_MENU_VIEW_TREE</property>
-
-                 <child>
-                   <widget class="GtkMenu" id="view1_menu">
-
-                     <child>
-                       <widget class="GtkImageMenuItem" id="refresh">
-                         <property name="visible">True</property>
-                         <property name="label" translatable="yes">_Refresh</property>
-                         <property name="use_underline">True</property>
-                         <signal name="activate" handler="on_refresh_activate" last_modification_time="Wed, 16 Aug 2006 03:34:22 GMT"/>
-                         <accelerator key="R" modifiers="GDK_CONTROL_MASK" signal="activate"/>
-
-                         <child internal-child="image">
-                           <widget class="GtkImage" id="image25">
-                             <property name="visible">True</property>
-                             <property name="stock">gtk-refresh</property>
-                             <property name="icon_size">1</property>
-                             <property name="xalign">0.5</property>
-                             <property name="yalign">0.5</property>
-                             <property name="xpad">0</property>
-                             <property name="ypad">0</property>
-                           </widget>
-                         </child>
-                       </widget>
-                     </child>
-
-                     <child>
-                       <widget class="GtkSeparatorMenuItem" id="separator3">
-                         <property name="visible">True</property>
-                       </widget>
-                     </child>
-
-                     <child>
-                       <widget class="GtkMenuItem" id="toolbar">
-                         <property name="visible">True</property>
-                         <property name="label" translatable="yes">_Toolbar</property>
-                         <property name="use_underline">True</property>
-                         <signal name="activate" handler="on_toolbar_activate" last_modification_time="Thu, 31 Aug 2006 09:57:31 GMT"/>
-                       </widget>
-                     </child>
-
-                     <child>
-                       <widget class="GtkMenuItem" id="statusbar">
-                         <property name="visible">True</property>
-                         <property name="label" translatable="yes">_Statusbar</property>
-                         <property name="use_underline">True</property>
-                         <signal name="activate" handler="on_statusbar_activate" last_modification_time="Thu, 31 Aug 2006 09:57:31 GMT"/>
-                       </widget>
-                     </child>
-                   </widget>
-                 </child>
-               </widget>
-             </child>
-
-             <child>
-               <widget class="GtkMenuItem" id="bookmarks1">
-                 <property name="visible">True</property>
-                 <property name="label" translatable="yes">_Bookmarks</property>
-                 <property name="use_underline">True</property>
-
-                 <child>
-                   <widget class="GtkMenu" id="bookmarks1_menu">
-
-                     <child>
-                       <widget class="GtkMenuItem" id="add_bookmark">
-                         <property name="visible">True</property>
-                         <property name="label" translatable="yes">Bookmark This Page</property>
-                         <property name="use_underline">True</property>
-                         <signal name="activate" handler="on_add_bookmark_activate" last_modification_time="Thu, 14 Sep 2006 12:23:15 GMT"/>
-                       </widget>
-                     </child>
-
-                     <child>
-                       <widget class="GtkMenuItem" id="manage_bookmarks">
-                         <property name="visible">True</property>
-                         <property name="label" translatable="yes">Show Bookmarks</property>
-                         <property name="use_underline">True</property>
-                         <signal name="activate" handler="on_manage_bookmarks_activate" last_modification_time="Thu, 14 Sep 2006 12:23:15 GMT"/>
-                       </widget>
-                     </child>
-                   </widget>
-                 </child>
-               </widget>
-             </child>
-
-             <child>
-               <widget class="GtkMenuItem" id="help1">
-                 <property name="visible">True</property>
-                 <property name="stock_item">GNOMEUIINFO_MENU_HELP_TREE</property>
-               </widget>
-             </child>
-           </widget>
-         </child>
-       </widget>
-       <packing>
-         <property name="placement">BONOBO_DOCK_TOP</property>
-         <property name="band">0</property>
-         <property name="position">0</property>
-         <property name="offset">0</property>
-         <property name="behavior">BONOBO_DOCK_ITEM_BEH_EXCLUSIVE|BONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL|BONOBO_DOCK_ITEM_BEH_LOCKED</property>
-       </packing>
-      </child>
-
-      <child>
-       <widget class="BonoboDockItem" id="bonobodockitem2">
-         <property name="visible">True</property>
-         <property name="shadow_type">GTK_SHADOW_OUT</property>
-
-         <child>
-           <widget class="GtkToolbar" id="toolbar">
-             <property name="visible">True</property>
-             <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
-             <property name="toolbar_style">GTK_TOOLBAR_BOTH</property>
-             <property name="tooltips">True</property>
-             <property name="show_arrow">True</property>
-
-             <child>
-               <widget class="GtkToolButton" id="toolbutton_refresh">
-                 <property name="visible">True</property>
-                 <property name="stock_id">gtk-refresh</property>
-                 <property name="visible_horizontal">True</property>
-                 <property name="visible_vertical">True</property>
-                 <property name="is_important">False</property>
-                 <signal name="clicked" handler="on_refresh_activate" last_modification_time="Thu, 31 Aug 2006 09:59:24 GMT"/>
-               </widget>
-               <packing>
-                 <property name="expand">False</property>
-                 <property name="homogeneous">True</property>
-               </packing>
-             </child>
-
-             <child>
-               <widget class="GtkToolButton" id="toolbutton_showboard">
-                 <property name="visible">True</property>
-                 <property name="label" translatable="yes">Board</property>
-                 <property name="use_underline">True</property>
-                 <property name="stock_id">gtk-go-up</property>
-                 <property name="visible_horizontal">True</property>
-                 <property name="visible_vertical">True</property>
-                 <property name="is_important">False</property>
-                 <signal name="clicked" handler="on_show_board_activate" last_modification_time="Thu, 31 Aug 2006 10:08:27 GMT"/>
-               </widget>
-               <packing>
-                 <property name="expand">False</property>
-                 <property name="homogeneous">True</property>
-               </packing>
-             </child>
-
-             <child>
-               <widget class="GtkToolButton" id="toolbutton_compose">
-                 <property name="visible">True</property>
-                 <property name="label" translatable="yes">Compose</property>
-                 <property name="use_underline">True</property>
-                 <property name="stock_id">gnome-stock-mail-new</property>
-                 <property name="visible_horizontal">True</property>
-                 <property name="visible_vertical">True</property>
-                 <property name="is_important">False</property>
-                 <signal name="clicked" handler="on_compose_activate" last_modification_time="Thu, 31 Aug 2006 09:59:12 GMT"/>
-               </widget>
-               <packing>
-                 <property name="expand">False</property>
-                 <property name="homogeneous">True</property>
-               </packing>
-             </child>
-
-             <child>
-               <widget class="GtkToolButton" id="toolbutton_delete">
-                 <property name="visible">True</property>
-                 <property name="stock_id">gtk-delete</property>
-                 <property name="visible_horizontal">True</property>
-                 <property name="visible_vertical">True</property>
-                 <property name="is_important">False</property>
-                 <signal name="clicked" handler="on_delete_activate" last_modification_time="Thu, 14 Sep 2006 04:42:06 GMT"/>
-               </widget>
-               <packing>
-                 <property name="expand">False</property>
-                 <property name="homogeneous">True</property>
-               </packing>
-             </child>
-           </widget>
-         </child>
-       </widget>
-       <packing>
-         <property name="placement">BONOBO_DOCK_TOP</property>
-         <property name="band">1</property>
-         <property name="position">0</property>
-         <property name="offset">0</property>
-         <property name="behavior">BONOBO_DOCK_ITEM_BEH_EXCLUSIVE|BONOBO_DOCK_ITEM_BEH_LOCKED</property>
-       </packing>
-      </child>
-
-      <child>
-       <widget class="GtkScrolledWindow" id="scrolledwindow1">
-         <property name="visible">True</property>
-         <property name="can_focus">True</property>
-         <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-         <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-         <property name="shadow_type">GTK_SHADOW_NONE</property>
-         <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
-         <child>
-           <widget class="GtkTextView" id="textview">
-             <property name="visible">True</property>
-             <property name="can_focus">True</property>
-             <property name="has_focus">True</property>
-             <property name="editable">False</property>
-             <property name="overwrite">False</property>
-             <property name="accepts_tab">True</property>
-             <property name="justification">GTK_JUSTIFY_LEFT</property>
-             <property name="wrap_mode">GTK_WRAP_CHAR</property>
-             <property name="cursor_visible">False</property>
-             <property name="pixels_above_lines">0</property>
-             <property name="pixels_below_lines">0</property>
-             <property name="pixels_inside_wrap">0</property>
-             <property name="left_margin">0</property>
-             <property name="right_margin">0</property>
-             <property name="indent">0</property>
-             <property name="text" translatable="yes"></property>
-           </widget>
-         </child>
-       </widget>
-      </child>
-    </widget>
-    <packing>
-      <property name="padding">0</property>
-      <property name="expand">True</property>
-      <property name="fill">True</property>
-    </packing>
-  </child>
-
-  <child internal-child="appbar">
-    <widget class="GnomeAppBar" id="appbar">
-      <property name="visible">True</property>
-      <property name="has_progress">True</property>
-      <property name="has_status">True</property>
-    </widget>
-    <packing>
-      <property name="padding">0</property>
-      <property name="expand">True</property>
-      <property name="fill">True</property>
-    </packing>
-  </child>
-</widget>
-
+  <widget class="GtkWindow" id="thread_window">
+    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+    <signal name="destroy" handler="on_thread_window_destroy"/>
+    <signal name="delete_event" handler="on_thread_window_delete_event"/>
+    <child>
+      <widget class="GtkVBox" id="vbox1">
+        <property name="visible">True</property>
+        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+        <child>
+          <widget class="GtkMenuBar" id="menubar1">
+            <property name="visible">True</property>
+            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+            <child>
+              <widget class="GtkMenuItem" id="menu_file">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="label" translatable="yes">_File</property>
+                <property name="use_underline">True</property>
+                <child>
+                  <widget class="GtkMenu" id="menu1">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <child>
+                      <widget class="GtkImageMenuItem" id="menu_file_show_board">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="label" translatable="yes">Show Board</property>
+                        <property name="use_underline">True</property>
+                        <signal name="activate" handler="on_show_board_activate"/>
+                        <child internal-child="image">
+                          <widget class="GtkImage" id="menu-item-image11">
+                            <property name="stock">gtk-go-up</property>
+                          </widget>
+                        </child>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkImageMenuItem" id="menu_file_compose">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="label" translatable="yes">_Compose Message</property>
+                        <property name="use_underline">True</property>
+                        <signal name="activate" handler="on_compose_activate"/>
+                        <accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+                        <child internal-child="image">
+                          <widget class="GtkImage" id="menu-item-image12">
+                            <property name="stock">gtk-edit</property>
+                          </widget>
+                        </child>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkImageMenuItem" id="menu_file_delete">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="label" translatable="yes">gtk-delete</property>
+                        <property name="use_underline">True</property>
+                        <property name="use_stock">True</property>
+                        <signal name="activate" handler="on_delete_activate"/>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkSeparatorMenuItem" id="menuitem1">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkImageMenuItem" id="menu_file_close">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="label" translatable="yes">gtk-close</property>
+                        <property name="use_underline">True</property>
+                        <property name="use_stock">True</property>
+                        <signal name="activate" handler="on_close_activate"/>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkImageMenuItem" id="menu_file_quit">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="label" translatable="yes">gtk-quit</property>
+                        <property name="use_underline">True</property>
+                        <property name="use_stock">True</property>
+                        <signal name="activate" handler="on_quit_activate"/>
+                      </widget>
+                    </child>
+                  </widget>
+                </child>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkMenuItem" id="menu_edit">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="label" translatable="yes">_Edit</property>
+                <property name="use_underline">True</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkMenuItem" id="menu_view">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="label" translatable="yes">_View</property>
+                <property name="use_underline">True</property>
+                <child>
+                  <widget class="GtkMenu" id="menu2">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <child>
+                      <widget class="GtkImageMenuItem" id="menu_view_refresh">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="label" translatable="yes">gtk-refresh</property>
+                        <property name="use_underline">True</property>
+                        <property name="use_stock">True</property>
+                        <signal name="activate" handler="on_refresh_activate"/>
+                        <accelerator key="R" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkSeparatorMenuItem" id="menuitem2">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkMenuItem" id="menu_view_toolbar">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="label" translatable="yes">_Toolbar</property>
+                        <property name="use_underline">True</property>
+                        <signal name="activate" handler="on_toolbar_activate"/>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkMenuItem" id="menu_view_statusbar">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="label" translatable="yes">_Statusbar</property>
+                        <property name="use_underline">True</property>
+                        <signal name="activate" handler="on_statusbar_activate"/>
+                      </widget>
+                    </child>
+                  </widget>
+                </child>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkMenuItem" id="menu_bookmarks">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="label" translatable="yes">_Bookmarks</property>
+                <property name="use_underline">True</property>
+                <child>
+                  <widget class="GtkMenu" id="menu4">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <child>
+                      <widget class="GtkMenuItem" id="menu_bookmarks_bookmarkthispage">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="label" translatable="yes">Bookmark This Page</property>
+                        <property name="use_underline">True</property>
+                        <signal name="activate" handler="on_add_bookmark_activate"/>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkMenuItem" id="menu_bookmarks_showbookmarks">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="label" translatable="yes">_Show Bookmarks</property>
+                        <property name="use_underline">True</property>
+                        <signal name="activate" handler="on_manage_bookmarks_activate"/>
+                      </widget>
+                    </child>
+                  </widget>
+                </child>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkMenuItem" id="menu_help">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="label" translatable="yes">_Help</property>
+                <property name="use_underline">True</property>
+                <child>
+                  <widget class="GtkMenu" id="menu3">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <child>
+                      <widget class="GtkImageMenuItem" id="imagemenuitem10">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="label" translatable="yes">gtk-about</property>
+                        <property name="use_underline">True</property>
+                        <property name="use_stock">True</property>
+                      </widget>
+                    </child>
+                  </widget>
+                </child>
+              </widget>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkToolbar" id="toolbar">
+            <property name="visible">True</property>
+            <property name="toolbar_style">GTK_TOOLBAR_BOTH</property>
+            <child>
+              <widget class="GtkToolButton" id="toolbutton_refresh">
+                <property name="visible">True</property>
+                <property name="stock_id">gtk-refresh</property>
+                <signal name="clicked" handler="on_refresh_activate"/>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkToolButton" id="toolbutton_showboard">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Board</property>
+                <property name="use_underline">True</property>
+                <property name="stock_id">gtk-go-up</property>
+                <signal name="clicked" handler="on_show_board_activate"/>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkToolButton" id="toolbutton_compose">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Compose</property>
+                <property name="use_underline">True</property>
+                <property name="stock_id">gnome-stock-mail-new</property>
+                <signal name="clicked" handler="on_compose_activate"/>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkToolButton" id="toolbutton_delete">
+                <property name="visible">True</property>
+                <property name="stock_id">gtk-delete</property>
+                <signal name="clicked" handler="on_delete_activate"/>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkScrolledWindow" id="scrolledwindow1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+            <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+            <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+            <child>
+              <widget class="GtkViewport" id="viewport1">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="resize_mode">GTK_RESIZE_QUEUE</property>
+                <child>
+                  <widget class="GtkDrawingArea" id="drawingarea">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <signal name="expose_event" handler="on_drawingarea_expose_event"/>
+                  </widget>
+                </child>
+              </widget>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkStatusbar" id="statusbar">
+            <property name="visible">True</property>
+            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+            <property name="spacing">2</property>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="position">3</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
 </glade-interface>