--- /dev/null
+# Copyright (C) 2007 by Aiwota Programmer
+# aiwotaprog@tetteke.tk
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import pango
+
+
+class ThreadView(gtk.HBox):
+
+ def __init__(self):
+ gtk.HBox.__init__(self, False, 0)
+ self.drawingarea = gtk.DrawingArea()
+ self.vscrollbar = gtk.VScrollbar()
+ self.pack_start(self.drawingarea)
+ self.pack_start(self.vscrollbar, expand=False)
+ self.adjustment = self.vscrollbar.get_adjustment()
+
+ self.drawingarea.add_events(gtk.gdk.SCROLL_MASK)
+
+ self.adjustment.step_increment = 20
+ self.drawingarea_prev_width = 0
+
+ self.drawingarea.connect(
+ "expose-event", self.on_drawingarea_expose_event)
+ self.drawingarea.connect(
+ "size-allocate", self.on_drawingarea_size_allocate)
+ self.drawingarea.connect(
+ "button-press-event", self.on_drawingarea_button_press_event)
+ self.drawingarea.connect(
+ "scroll-event", self.on_drawingarea_scroll_event)
+ self.vscrollbar.connect(
+ "value-changed", self.on_vscrollbar_value_changed)
+
+ self.initialize_buffer()
+
+ def initialize_buffer(self):
+ self.pangolayout = []
+
+ def add_layout(self, pangolayout):
+ self.pangolayout.append(pangolayout)
+
+ def create_pango_layout(self, text):
+ return self.drawingarea.create_pango_layout(text)
+
+ def redraw(self):
+ self.drawingarea.queue_draw()
+
+ def relayout(self):
+ width = self.drawingarea.allocation.width
+ sum_height = 0
+ for layout in self.pangolayout:
+ layout.set_width((width - layout.marginleft) * pango.SCALE)
+ layout.posY = sum_height
+ x, y = layout.get_pixel_size()
+ sum_height += y
+ self.adjustment.upper = sum_height
+
+ def jump(self, value):
+ if value > self.adjustment.upper - self.adjustment.page_size:
+ value = self.adjustment.upper - self.adjustment.page_size
+ self.adjustment.set_value(value)
+
+ def jump_to_layout(self, layout):
+ self.jump(layout.posY)
+
+ def jump_to_the_end(self):
+ value = self.adjustment.upper - self.adjustment.page_size
+ self.adjustment.set_value(value)
+
+ def jump_to_res(self, resnum):
+ for layout in self.pangolayout:
+ if layout.resnum == resnum:
+ self.jump_to_layout(layout)
+ return True
+ return False
+
+ def draw_viewport(self):
+ view_y = self.adjustment.get_value()
+ self.drawingarea.window.draw_rectangle(
+ self.drawingarea.style.base_gc[0],
+ True, 0, 0,
+ self.drawingarea.allocation.width,
+ self.drawingarea.allocation.height)
+
+ gc = self.drawingarea.window.new_gc()
+ for layout in self.pangolayout:
+ w, h = layout.get_pixel_size()
+ layout_top = layout.posY
+ layout_bottom = layout.posY + h
+ area_top = view_y
+ area_bottom = view_y + self.drawingarea.allocation.height
+ if layout_top <= area_bottom and layout_bottom >= area_top:
+ self.drawingarea.window.draw_layout(
+ gc, layout.marginleft, layout.posY - int(view_y), layout)
+
+ def on_drawingarea_expose_event(self, widget, event, data=None):
+ self.draw_viewport()
+
+ def on_drawingarea_size_allocate(self, widget, allocation, data=None):
+ if allocation.width != self.drawingarea_prev_width:
+ self.relayout()
+ self.drawingarea_prev_width = allocation.width
+ self.adjustment.page_size = self.drawingarea.allocation.height
+ self.adjustment.page_increment = self.drawingarea.allocation.height
+
+ def on_drawingarea_button_press_event(self, widget, event, data=None):
+ self.drawingarea.queue_draw()
+
+ def on_vscrollbar_value_changed(self, widget, data=None):
+ self.drawingarea.queue_draw()
+
+ def on_drawingarea_scroll_event(self, widget, event, data=None):
+ if event.direction == gtk.gdk.SCROLL_UP:
+ self.adjustment.value -= 66.476200804
+ if self.adjustment.value < self.adjustment.lower:
+ self.adjustment.value = self.adjustment.lower
+ if event.direction == gtk.gdk.SCROLL_DOWN:
+ self.adjustment.value += 66.476200804
+ max_value = self.adjustment.upper - self.adjustment.page_size
+ if self.adjustment.value > max_value:
+ self.adjustment.value = max_value
import winwrapbase
import bookmark_list
import bookmark_window
+import thread_view
GLADE_FILENAME = "thread_window.glade"
hand_cursor = gtk.gdk.Cursor(gtk.gdk.HAND2)
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 - layout.marginleft) * pango.SCALE)
- layout.posY = sum_height
- x, y = layout.get_pixel_size()
- sum_height += y
- self.adjustment.upper = sum_height
-
- def draw_viewport(self):
- view_y = self.adjustment.get_value()
- self.drawingarea.window.draw_rectangle(
- self.drawingarea.style.base_gc[0],
- True, 0, 0,
- self.drawingarea.allocation.width,
- self.drawingarea.allocation.height)
-
- gc = self.drawingarea.window.new_gc()
- for layout in self.pangolayout:
- w, h = layout.get_pixel_size()
- layout_top = layout.posY
- layout_bottom = layout.posY + h
- area_top = view_y
- area_bottom = view_y + self.drawingarea.allocation.height
- if layout_top <= area_bottom and layout_bottom >= area_top:
- self.drawingarea.window.draw_layout(
- gc, layout.marginleft, layout.posY - int(view_y), layout)
-
- def on_drawingarea_expose_event(self, widget, event, data=None):
- self.draw_viewport()
-
- def on_drawingarea_size_allocate(self, widget, allocation, data=None):
- if allocation.width != self.drawingarea.prev_width:
- self.relayout()
- self.drawingarea.prev_width = allocation.width
- self.adjustment.page_size = self.drawingarea.allocation.height
- self.adjustment.page_increment = self.drawingarea.allocation.height
-
- def on_drawingarea_button_press_event(self, widget, event, data=None):
- self.drawingarea.queue_draw()
-
- def on_vscrollbar_value_changed(self, widget, data=None):
- self.drawingarea.queue_draw()
-
- def on_drawingarea_scroll_event(self, widget, event, data=None):
- if event.direction == gtk.gdk.SCROLL_UP:
- self.adjustment.value -= 66.476200804
- if self.adjustment.value < self.adjustment.lower:
- self.adjustment.value = self.adjustment.lower
- if event.direction == gtk.gdk.SCROLL_DOWN:
- self.adjustment.value += 66.476200804
- max_value = self.adjustment.upper - self.adjustment.page_size
- if self.adjustment.value > max_value:
- self.adjustment.value = max_value
-
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)
self.toolbar = self.widget_tree.get_widget("toolbar")
self.toolbar.unset_style()
self.statusbar = self.widget_tree.get_widget("statusbar")
- self.drawingarea = self.widget_tree.get_widget("drawingarea")
- self.vscrollbar = self.widget_tree.get_widget("vscrollbar")
- self.adjustment = self.vscrollbar.get_adjustment()
- self.adjustment.step_increment = 20
+ self.vbox = self.widget_tree.get_widget("vbox")
- self.drawingarea.prev_width = 0
+ self.threadview = thread_view.ThreadView()
+ self.vbox.pack_start(self.threadview)
+ self.vbox.reorder_child(self.threadview, 2)
self.initialize_buffer()
"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_drawingarea_size_allocate":
- self.on_drawingarea_size_allocate,
"on_thread_window_delete_event":
self.on_thread_window_delete_event,
- "on_drawingarea_button_press_event":
- self.on_drawingarea_button_press_event,
- "on_drawingarea_scroll_event":
- self.on_drawingarea_scroll_event,
- "on_vscrollbar_value_changed":
- self.on_vscrollbar_value_changed,
"on_add_bookmark_activate": self.on_add_bookmark_activate,
"on_manage_bookmarks_activate": \
self.on_manage_bookmarks_activate,
self.leftmargintag = self.textbuffer.create_tag()
self.leftmargintag.set_property("left-margin", 20)
- self.pangolayout = []
+ self.threadview.initialize_buffer()
def destroy(self):
self.save()
for data, bold, href, margin in queue:
data = data.encode("utf8")
if current_margin != margin:
- layout = self.drawingarea.create_pango_layout(text)
+ layout = self.threadview.create_pango_layout(text)
layout.set_wrap(pango.WRAP_CHAR)
layout.posY = 0
layout.resnum = num
else:
layout.marginleft = 0
- self.pangolayout.append(layout)
+ self.threadview.add_layout(layout)
current_margin = margin
text = ""
text += data
if text != "":
- layout = self.drawingarea.create_pango_layout(text)
+ layout = self.threadview.create_pango_layout(text)
layout.set_wrap(pango.WRAP_CHAR)
layout.posY = 0
layout.resnum = num
layout.marginleft = 20
else:
layout.marginleft = 0
- self.pangolayout.append(layout)
- self.relayout()
- self.drawingarea.queue_draw()
+ self.threadview.add_layout(layout)
+ self.threadview.relayout()
+ self.threadview.redraw()
# taglist = []
# if bold:
# taglist.append(self.boldtag)
# self.textbuffer.insert(self.enditer, data)
def jump(self, value):
- def j():
- if value > self.adjustment.upper - self.adjustment.page_size:
- self.jump_to_the_end()
- else:
- self.adjustment.set_value(value)
- gobject.idle_add(j)
+ gobject.idle_add(self.threadview.jump, value)
def jump_to_layout(self, layout):
- gobject.idle_add(lambda : self.jump(layout.posY))
+ gobject.idle_add(self.threadview.jump_to_layout, layout)
def jump_to_the_end(self):
- def j():
- self.adjustment.set_value(
- self.adjustment.upper - self.adjustment.page_size)
- gobject.idle_add(j)
-# mark = self.textbuffer.get_mark(str(num+1))
-# if mark:
-# self.textview.scroll_to_mark(mark, 0)
+ gobject.idle_add(self.threadview.jump_to_the_end)
def lock(self):
if self.lock_obj:
print "unlock"
def jump_to_res(self, resnum):
- for layout in self.pangolayout:
- if layout.resnum == resnum:
- self.jump_to_layout(layout)
- return
+ if self.threadview.jump_to_res(resnum):
+ return
self.jump_request_num = resnum
def load(self, update=False):
<signal name="destroy" handler="on_thread_window_destroy"/>
<signal name="delete_event" handler="on_thread_window_delete_event"/>
<child>
- <widget class="GtkVBox" id="vbox1">
+ <widget class="GtkVBox" id="vbox">
<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>
</packing>
</child>
<child>
- <widget class="GtkHBox" id="hbox1">
- <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="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"/>
- <signal name="button_press_event" handler="on_drawingarea_button_press_event"/>
- <signal name="size_allocate" handler="on_drawingarea_size_allocate"/>
- <signal name="scroll_event" handler="on_drawingarea_scroll_event"/>
- </widget>
- </child>
- <child>
- <widget class="GtkVScrollbar" id="vscrollbar">
- <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="adjustment">0 0 100 1 10 10</property>
- <property name="restrict_to_fill_level">False</property>
- <signal name="value_changed" handler="on_vscrollbar_value_changed"/>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </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>