Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/chat
diff options
context:
space:
mode:
authorMarco Pesenti Gritti <mpg@redhat.com>2006-04-25 21:47:49 (GMT)
committer Marco Pesenti Gritti <mpg@redhat.com>2006-04-25 21:47:49 (GMT)
commit1676e5edcc177c7016618cb71c2eacb6984e741f (patch)
tree8b3dd0453c0767f2e15e66b6d04ab892701990f8 /chat
parente5cd418e7ed952c1c760ea80f6df36944999faae (diff)
Implement links. Require new gecko-embed
Diffstat (limited to 'chat')
-rwxr-xr-xchat/chat.py42
-rw-r--r--chat/richtext.py91
2 files changed, 121 insertions, 12 deletions
diff --git a/chat/chat.py b/chat/chat.py
index 0bacf8f..f5e7315 100755
--- a/chat/chat.py
+++ b/chat/chat.py
@@ -142,6 +142,13 @@ class ChatActivity(activity.Activity):
self._buddy_list = BuddyList.BuddyList(self._realname)
self._buddy_list.add_buddy_listener(self._on_buddy_presence_event)
+ bus = dbus.SessionBus()
+ proxy_obj = bus.get_object('com.redhat.Sugar.Browser', '/com/redhat/Sugar/Browser')
+ self.browser_shell = dbus.Interface(proxy_obj, 'com.redhat.Sugar.BrowserShell')
+
+ def __link_clicked_cb(self, view, address):
+ self.browser_shell.open_browser(address)
+
def _create_chat(self):
chat_vbox = gtk.VBox()
chat_vbox.set_spacing(6)
@@ -154,7 +161,8 @@ class ChatActivity(activity.Activity):
sw = gtk.ScrolledWindow()
sw.set_shadow_type(gtk.SHADOW_IN)
sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
- self._chat_view = gtk.TextView()
+ self._chat_view = richtext.RichTextView()
+ self._chat_view.connect("link-clicked", self.__link_clicked_cb)
sw.add(self._chat_view)
self._chat_view.show()
chat_vbox.pack_start(sw)
@@ -164,7 +172,7 @@ class ChatActivity(activity.Activity):
chat_view_sw = gtk.ScrolledWindow()
chat_view_sw.set_shadow_type(gtk.SHADOW_IN)
chat_view_sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- self._editor = gtk.TextView(rich_buf)
+ self._editor = richtext.RichTextView(rich_buf)
self._editor.connect("key-press-event", self.__key_press_event_cb)
self._editor.set_size_request(-1, 50)
chat_view_sw.add(self._editor)
@@ -229,6 +237,34 @@ class ChatActivity(activity.Activity):
return vbox
+ def _create_toolbar(self, rich_buf):
+ toolbar = richtext.RichTextToolbar(rich_buf)
+
+ item = gtk.MenuToolButton(None, "Links")
+ item.set_menu(gtk.Menu())
+ item.connect("show-menu", self.__show_link_menu_cb)
+ toolbar.insert(item, -1)
+ item.show()
+
+ return toolbar
+
+ def __link_activate_cb(self, item, link):
+ buf = self._editor.get_buffer()
+ buf.append_link(link['title'], link['address'])
+
+ def __show_link_menu_cb(self, button):
+ menu = gtk.Menu()
+
+ links = self.browser_shell.get_links()
+
+ for link in links:
+ item = gtk.MenuItem(link['title'], False)
+ item.connect("activate", self.__link_activate_cb, link)
+ menu.append(item)
+ item.show()
+
+ button.set_menu(menu)
+
def _ui_setup(self, plug):
vbox = gtk.VBox(False, 6)
@@ -246,7 +282,7 @@ class ChatActivity(activity.Activity):
vbox.pack_start(hbox)
hbox.show()
- toolbar = richtext.RichTextToolbar(rich_buf)
+ toolbar = self._create_toolbar(rich_buf)
vbox.pack_start(toolbar, False);
toolbar.show()
diff --git a/chat/richtext.py b/chat/richtext.py
index 15e7912..da7293c 100644
--- a/chat/richtext.py
+++ b/chat/richtext.py
@@ -1,11 +1,43 @@
#!/usr/bin/env python
import pygtk
+import gobject
pygtk.require('2.0')
import gtk
import pango
import xml.sax
+class RichTextView(gtk.TextView):
+
+ __gsignals__ = {
+ 'link-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([gobject.TYPE_STRING]))
+ }
+
+ def __init__(self, rich_buf = None):
+ gtk.TextView.__init__(self, rich_buf)
+# self.connect("motion-notify-event", self.__motion_notify_cb)
+ self.connect("button-press-event", self.__button_press_cb)
+
+# def __motion_notify_cb(self, widget, event):
+# if event.is_hint:
+# [x, y, state] = event.window.get_pointer();
+
+ def __button_press_cb(self, widget, event):
+ buf = self.get_buffer()
+ it = self.get_iter_at_location(int(event.x), int(event.y))
+ if it.has_tag(buf.get_tag_table().lookup("link")):
+ address_tag = buf.get_tag_table().lookup("link-address")
+
+ address_end = it.copy()
+ address_end.backward_to_tag_toggle(address_tag)
+
+ address_start = address_end.copy()
+ address_start.backward_to_tag_toggle(address_tag)
+
+ address = buf.get_text(address_start, address_end)
+ self.emit("link-clicked", address)
+
class RichTextBuffer(gtk.TextBuffer):
def __init__(self):
gtk.TextBuffer.__init__(self)
@@ -14,6 +46,11 @@ class RichTextBuffer(gtk.TextBuffer):
self.__create_tags()
self.active_tags = []
+
+ def append_link(self, title, address):
+ it = self.get_iter_at_mark(self.get_insert())
+ self.insert_with_tags_by_name(it, address, "link", "link-address")
+ self.insert_with_tags_by_name(it, title, "link")
def apply_tag(self, tag_name):
self.active_tags.append(tag_name)
@@ -32,6 +69,13 @@ class RichTextBuffer(gtk.TextBuffer):
self.remove_tag_by_name(tag_name, start, end)
def __create_tags(self):
+ tag = self.create_tag("link")
+ tag.set_property("underline", pango.UNDERLINE_SINGLE)
+ tag.set_property("foreground", "#0000FF")
+
+ tag = self.create_tag("link-address")
+ tag.set_property("invisible", True)
+
tag = self.create_tag("bold")
tag.set_property("weight", pango.WEIGHT_BOLD)
@@ -137,6 +181,8 @@ class RichTextHandler(xml.sax.handler.ContentHandler):
if name != "richtext":
tag = self.serializer.deserialize_element(name, attrs)
self.tags.append(tag)
+ if name == "link":
+ self.href = attrs['href']
def characters(self, data):
start_it = it = self.buf.get_end_iter()
@@ -146,6 +192,9 @@ class RichTextHandler(xml.sax.handler.ContentHandler):
for tag in self.tags:
self.buf.apply_tag_by_name(tag, start_it, it)
+ if tag == "link":
+ self.buf.insert_with_tags_by_name(start_it, self.href,
+ "link", "link-address")
def endElement(self, name):
if name != "richtext":
@@ -162,15 +211,25 @@ class RichTextSerializer:
return "italic"
elif el_name == "font":
return "font-size-" + attributes["size"]
+ elif el_name == "link":
+ return "link"
else:
return None
- def serialize_tag_start(self, tag):
+ def serialize_tag_start(self, tag, it):
name = tag.get_property("name")
if name == "bold":
return "<bold>"
elif name == "italic":
return "<italic>"
+ elif name == "link":
+ address_tag = self.buf.get_tag_table().lookup("link-address")
+ end = it.copy()
+ end.forward_to_tag_toggle(address_tag)
+ address = self.buf.get_text(it, end)
+ return "<link " + "href=\"" + address + "\">"
+ elif name == "link-address":
+ return ""
elif name.startswith("font-size-"):
tag_name = name.replace("font-size-", "", 1)
return "<font size=\"" + tag_name + "\">"
@@ -179,16 +238,22 @@ class RichTextSerializer:
def serialize_tag_end(self, tag):
name = tag.get_property("name")
- if tag.get_property("name") == "bold":
+ if name == "bold":
return "</bold>"
- elif tag.get_property("name") == "italic":
+ elif name == "italic":
return "</italic>"
+ elif name == "link":
+ return "</link>"
+ elif name == "link-address":
+ return ""
elif name.startswith("font-size-"):
return "</font>"
else:
return "</unknown>"
-
+
def serialize(self, buf):
+ self.buf = buf
+
xml = "<richtext>"
next_it = buf.get_start_iter()
@@ -207,11 +272,15 @@ class RichTextSerializer:
break
tags_to_reopen.append(open_tag)
- for tag in tags_to_reopen + it.get_toggled_tags(True):
+ for tag in tags_to_reopen:
self._open_tags.append(tag)
- xml += self.serialize_tag_start(tag)
+ xml += self.serialize_tag_start(tag, it)
- xml += buf.get_text(it, next_it)
+ for tag in it.get_toggled_tags(True):
+ self._open_tags.append(tag)
+ xml += self.serialize_tag_start(tag, it)
+
+ xml += buf.get_text(it, next_it, False)
if next_it.is_end():
self._open_tags.reverse()
@@ -232,6 +301,9 @@ class RichTextSerializer:
def test_quit(window, rich_buf):
print RichTextSerializer().serialize(rich_buf)
gtk.main_quit()
+
+def link_clicked(view, address):
+ print "Link clicked " + address
if __name__ == "__main__":
window = gtk.Window()
@@ -246,12 +318,13 @@ if __name__ == "__main__":
xml_string += "<bold><italic>Test</italic>one</bold>\n"
xml_string += "<bold><italic>Test two</italic></bold>"
xml_string += "<font size=\"xx-small\">Test three</font>"
-
+ xml_string += "<link href=\"http://www.gnome.org\">Test link</link>"
xml_string += "</richtext>"
RichTextSerializer().deserialize(xml_string, rich_buf)
- view = gtk.TextView(rich_buf)
+ view = RichTextView(rich_buf)
+ view.connect("link-clicked", link_clicked)
vbox.pack_start(view)
view.show()