Merge lp://staging/~kkapp/lernid/bugfix-lp-530810 into lp://staging/lernid

Status: Merged
Approved by: Michael Budde
Approved revision: not available
Merge reported by: Michael Budde
Merged at revision: not available
Proposed branch: lp://staging/~kkapp/lernid/bugfix-lp-530810
Merge into: lp://staging/lernid
Diff against target: 256 lines (+105/-51)
3 files modified
lernid/widgets/Classroom.py (+8/-26)
lernid/widgets/IrcWidget.py (+91/-0)
lernid/widgets/NativeChatroom.py (+6/-25)
To merge this branch: bzr merge lp://staging/~kkapp/lernid/bugfix-lp-530810
Reviewer Review Type Date Requested Status
Michael Budde Approve
Review via email: mp+20505@code.staging.launchpad.net
To post a comment you must log in.
Revision history for this message
Алексей Капранов (Alex Kapranoff) (kkapp) wrote :

Fix my own bug by implementing clickable hyperlinks both in chat and classroom areas.

Revision history for this message
Michael Budde (mbudde) wrote :

Looks good. Great job.

review: Approve
191. By Michael Budde

Fix AttributeError

192. By Michael Budde

Highlight URLs in class and chatroom (LP: #530810)

Merge of lp:~kkapp/lernid/bugfix-lp-530810 by Alex Kapranoff

193. By Michael Budde

Add kkapp as a contributor

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lernid/widgets/Classroom.py'
2--- lernid/widgets/Classroom.py 2010-02-11 19:16:31 +0000
3+++ lernid/widgets/Classroom.py 2010-03-03 00:38:12 +0000
4@@ -22,15 +22,16 @@
5 import gtkmozembed
6 import pango
7 import time
8+import re
9
10 from lernid.CouchDBPreferences import Preferences
11-from lernid.widgets.Widget import Widget
12+from lernid.widgets.IrcWidget import IrcWidget
13
14 from lernid import IrcBackend
15 from lernid.LernidOptions import Options
16 from lernid.Statusbar import Statusbar
17
18-class Classroom(Widget):
19+class Classroom(IrcWidget):
20
21 __gtype_name__ = 'LernidClassroom'
22
23@@ -39,9 +40,9 @@
24 gobject.SIGNAL_RUN_LAST, None, (object, str, str)
25 ),
26 }
27-
28+
29 def __init__(self):
30- Widget.__init__(self, 'classroom')
31+ IrcWidget.__init__(self, 'classroom')
32 viewport = gtk.Viewport()
33 scroll = gtk.ScrolledWindow()
34 scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
35@@ -65,10 +66,12 @@
36 self._buffer.create_tag('gray', foreground=text_color)
37 highlight = self._textview.get_style().bg[gtk.STATE_SELECTED]
38 self._buffer.create_tag('highlight', foreground=highlight)
39+ self._init_hyperlinks()
40
41 self.show_all()
42
43 def do_event_connect(self, event_man, event):
44+ IrcWidget.do_event_connect(self, event_man, event)
45 self._server = IrcBackend.Server.get_server('irc.freenode.net', event.nick)
46 self._nick = event.nick
47 classchan = self._server.get_channel(Options.get('classroom', event.classroom))
48@@ -76,6 +79,7 @@
49 Statusbar.push_message(_('Joined classroom'), duration=10)
50 self.event_connect_signal(classchan, 'joined', joined)
51 self.event_connect_signal(classchan, 'message-received', self._message_received)
52+ self._browser = event_man.get_widget_by_name('browser')
53
54 def do_event_disconnect(self, event_man, event):
55 istart, iend = self._buffer.get_bounds()
56@@ -85,27 +89,6 @@
57 self._server.disconnect()
58 self.event_disconnect_signals()
59
60- def _append_to_buffer(self, text, sender=None, msgtype=None):
61- iend = self._buffer.get_end_iter()
62- if Preferences.get('show_irc_time'):
63- self._buffer.insert(iend, '\n[{0}] '.format(time.strftime(_('%H:%M'))))
64- else:
65- self._buffer.insert(iend, '\n')
66- if msgtype == IrcBackend.Channel.TYPE_ACTION:
67- self._buffer.insert(iend, ' * ')
68- if sender:
69- self._buffer.insert_with_tags_by_name(iend, sender+' ', 'gray')
70- self._buffer.insert(iend, text)
71- else:
72- if sender:
73- self._buffer.insert_with_tags_by_name(iend, '<%s> ' % sender, 'gray')
74- if self._nick in text and sender != self._nick:
75- self._buffer.insert_with_tags_by_name(iend, text, 'highlight')
76- else:
77- self._buffer.insert(iend, text)
78- self._at_bottom = (self._adjust.value == self._adjust.upper -
79- self._adjust.page_size)
80-
81 def _message_received(self, chan, sender, text, msgtype):
82 self._append_to_buffer(text, sender, msgtype)
83 self.emit('message-received', chan, sender, text)
84@@ -116,4 +99,3 @@
85 if self._at_bottom:
86 self._adjust.value = self._adjust.upper - self._adjust.page_size
87
88-
89
90=== added file 'lernid/widgets/IrcWidget.py'
91--- lernid/widgets/IrcWidget.py 1970-01-01 00:00:00 +0000
92+++ lernid/widgets/IrcWidget.py 2010-03-03 00:38:12 +0000
93@@ -0,0 +1,91 @@
94+#!/usr/bin/python
95+# -*- coding: utf-8 -*-
96+### BEGIN LICENSE
97+# Copyright (C) 2009 Jono Bacon <jono@ubuntu.com>
98+# Copyright (C) 2010 Michael Budde <mbudde@gmail.com>
99+#
100+#This program is free software: you can redistribute it and/or modify it
101+#under the terms of the GNU General Public License version 3, as published
102+#by the Free Software Foundation.
103+#
104+#This program is distributed in the hope that it will be useful, but
105+#WITHOUT ANY WARRANTY; without even the implied warranties of
106+#MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
107+#PURPOSE. See the GNU General Public License for more details.
108+#
109+#You should have received a copy of the GNU General Public License along
110+#with this program. If not, see <http://www.gnu.org/licenses/>.
111+### END LICENSE
112+
113+import gtk
114+import gobject
115+import gtkmozembed
116+import pango
117+import time
118+import re
119+
120+from lernid.widgets.Widget import Widget
121+from lernid.CouchDBPreferences import Preferences
122+
123+from lernid import IrcBackend
124+from lernid.LernidOptions import Options
125+from lernid.Statusbar import Statusbar
126+
127+class IrcWidget(Widget):
128+
129+ hand_cursor = gtk.gdk.Cursor(gtk.gdk.HAND2)
130+ regular_cursor = gtk.gdk.Cursor(gtk.gdk.XTERM)
131+
132+ def do_event_connect(self, event_man, event):
133+ self._browser = event_man.get_widget_by_name('browser')
134+
135+ def _init_hyperlinks(self):
136+ hyperlink_tag = self._buffer.create_tag('hyperlink', foreground='#0000ff',
137+ underline=pango.UNDERLINE_SINGLE)
138+ self._buffer.connect('mark-set', self._mark_set, hyperlink_tag)
139+ self._textview.connect('motion-notify-event', self._motion_notify, hyperlink_tag)
140+
141+ def _append_to_buffer(self, text, sender=None, msgtype=None):
142+ iend = self._buffer.get_end_iter()
143+ if Preferences.get('show_irc_time'):
144+ self._buffer.insert(iend, '\n[{0}] '.format(time.strftime(_('%H:%M'))))
145+ else:
146+ self._buffer.insert(iend, '\n')
147+ if msgtype == IrcBackend.Channel.TYPE_ACTION:
148+ self._buffer.insert(iend, ' * ')
149+ if sender:
150+ self._buffer.insert_with_tags_by_name(iend, sender+' ', 'gray')
151+ start_pos = iend.get_offset()
152+ self._buffer.insert(iend, text)
153+ else:
154+ if sender:
155+ self._buffer.insert_with_tags_by_name(iend, '<%s> ' % sender, 'gray')
156+ start_pos = iend.get_offset()
157+ if self._nick in text and sender != self._nick:
158+ self._buffer.insert_with_tags_by_name(iend, text, 'highlight')
159+ else:
160+ self._buffer.insert(iend, text)
161+ for url in re.finditer(r"https?://\S+", unicode(text, 'utf-8')):
162+ self._buffer.apply_tag_by_name('hyperlink',
163+ self._buffer.get_iter_at_offset(start_pos + url.start()),
164+ self._buffer.get_iter_at_offset(start_pos + url.end()))
165+ self._at_bottom = (self._adjust.value == self._adjust.upper -
166+ self._adjust.page_size)
167+
168+ def _mark_set(self, buf, text_iter, mark, tag):
169+ if mark.get_name() == 'insert':
170+ if text_iter.has_tag(tag):
171+ text_iter.backward_to_tag_toggle(tag)
172+ istart = text_iter.copy()
173+ text_iter.forward_to_tag_toggle(tag)
174+ self._browser.set_location(buf.get_text(istart, text_iter))
175+
176+ def _motion_notify(self, text_view, event, tag):
177+ x, y = text_view.window_to_buffer_coords(gtk.TEXT_WINDOW_WIDGET,
178+ int(event.x), int(event.y))
179+ iter = text_view.get_iter_at_location(x, y)
180+ if (iter.has_tag(tag)):
181+ text_view.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(self.hand_cursor)
182+ else:
183+ text_view.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(self.regular_cursor)
184+ return False
185
186=== modified file 'lernid/widgets/NativeChatroom.py'
187--- lernid/widgets/NativeChatroom.py 2010-02-24 21:37:04 +0000
188+++ lernid/widgets/NativeChatroom.py 2010-03-03 00:38:12 +0000
189@@ -27,11 +27,11 @@
190 import time
191
192 from lernid.CouchDBPreferences import Preferences
193-from lernid.widgets.Widget import Widget
194+from lernid.widgets.IrcWidget import IrcWidget
195
196 from lernid import IrcBackend
197
198-class Chatroom(Widget):
199+class Chatroom(IrcWidget):
200
201 __gtype_name__ = 'LernidNativeChatroom'
202
203@@ -42,7 +42,7 @@
204 }
205
206 def __init__(self):
207- Widget.__init__(self, 'chatroom')
208+ IrcWidget.__init__(self, 'chatroom')
209 self.set_property('can-focus', True)
210
211 builder = self.builder_with_file('ChatWidget.ui')
212@@ -70,8 +70,11 @@
213
214 self._questionbutton = builder.get_object('questionbutton')
215 self._questionbutton.connect('toggled', self._questionbutton_toggled)
216+
217+ self._init_hyperlinks()
218
219 def do_event_connect(self, eventman, event):
220+ IrcWidget.do_event_connect(self, eventman, event)
221 self._server = IrcBackend.Server.get_server('irc.freenode.net', event.nick)
222 self._nick = event.nick
223 self._chatchan = self._server.get_channel(event.chat)
224@@ -173,27 +176,6 @@
225 self._adjust.value = self._adjust.upper - self._adjust.page_size
226 self._append_to_buffer(text, self._nick)
227
228- def _append_to_buffer(self, text, sender=None, msgtype=None):
229- iend = self._buffer.get_end_iter()
230- if Preferences.get('show_irc_time'):
231- self._buffer.insert(iend, '\n[{0}] '.format(time.strftime(_('%H:%M'))))
232- else:
233- self._buffer.insert(iend, '\n')
234- if msgtype == IrcBackend.Channel.TYPE_ACTION:
235- self._buffer.insert(iend, ' * ')
236- if sender:
237- self._buffer.insert_with_tags_by_name(iend, sender+' ', 'gray')
238- self._buffer.insert(iend, text)
239- else:
240- if sender:
241- self._buffer.insert_with_tags_by_name(iend, '<%s> ' % sender, 'gray')
242- if self._nick in text and sender != self._nick:
243- self._buffer.insert_with_tags_by_name(iend, text, 'highlight')
244- else:
245- self._buffer.insert(iend, text)
246- self._at_bottom = (self._adjust.value == self._adjust.upper -
247- self._adjust.page_size)
248-
249 def _scroll(self, textview, alloc):
250 if self._at_bottom is None:
251 self._at_bottom = True
252@@ -203,4 +185,3 @@
253 def _questionbutton_toggled(self, *args):
254 self._input.grab_focus()
255
256-

Subscribers

People subscribed via source and target branches