use python-sexy if available to have clickable links in chat window banner. fixes #2962
This commit is contained in:
parent
3c936682dc
commit
aff3697f06
|
@ -38,6 +38,7 @@ Gajim is a GTK+ app that loves GNOME. You can do 'make' so you don't require gno
|
|||
<li>notification-daemon or notify-python (and D-Bus) to get cooler popups</li>
|
||||
<li>D-Bus running to have gajim-remote working</li>
|
||||
<li>python-dbus bindings</li>
|
||||
<li>python-sexy to have clickable URLs in chat windows</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -28,6 +28,7 @@ import message_control
|
|||
import dialogs
|
||||
import history_window
|
||||
import notify
|
||||
import re
|
||||
|
||||
from common import gajim
|
||||
from common import helpers
|
||||
|
@ -46,7 +47,6 @@ try:
|
|||
except:
|
||||
HAS_GTK_SPELL = False
|
||||
|
||||
|
||||
# the next script, executed in the "po" directory,
|
||||
# generates the following list.
|
||||
##!/bin/sh
|
||||
|
@ -54,11 +54,15 @@ except:
|
|||
#echo "{_('en'):'en'",$LANG"}"
|
||||
langs = {_('English'): 'en', _('Belarusian'): 'be', _('Bulgarian'): 'bg', _('Breton'): 'br', _('Czech'): 'cs', _('German'): 'de', _('Greek'): 'el', _('British'): 'en_GB', _('Esperanto'): 'eo', _('Spanish'): 'es', _('Basque'): 'eu', _('French'): 'fr', _('Croatian'): 'hr', _('Italian'): 'it', _('Norwegian (b)'): 'nb', _('Dutch'): 'nl', _('Norwegian'): 'no', _('Polish'): 'pl', _('Portuguese'): 'pt', _('Brazilian Portuguese'): 'pt_BR', _('Russian'): 'ru', _('Serbian'): 'sr', _('Slovak'): 'sk', _('Swedish'): 'sv', _('Chinese (Ch)'): 'zh_CN'}
|
||||
|
||||
|
||||
################################################################################
|
||||
class ChatControlBase(MessageControl):
|
||||
'''A base class containing a banner, ConversationTextview, MessageTextView
|
||||
'''
|
||||
def make_href(self, match):
|
||||
url_color = gajim.config.get('urlmsgcolor')
|
||||
return '<a href="%s"><span color="%s">%s</span></a>' % (match.group(),
|
||||
url_color, match.group())
|
||||
|
||||
def get_font_attrs(self):
|
||||
''' get pango font attributes for banner from theme settings '''
|
||||
theme = gajim.config.get('roster_theme')
|
||||
|
@ -120,6 +124,9 @@ class ChatControlBase(MessageControl):
|
|||
event_keymod):
|
||||
pass # Derived should implement this rather than connecting to the event itself.
|
||||
|
||||
def status_url_clicked(self, widget, url):
|
||||
helpers.launch_browser_mailer('url', url)
|
||||
|
||||
def __init__(self, type_id, parent_win, widget_name, contact, acct,
|
||||
resource = None):
|
||||
MessageControl.__init__(self, type_id, parent_win, widget_name,
|
||||
|
@ -138,6 +145,22 @@ class ChatControlBase(MessageControl):
|
|||
id = widget.connect('button-press-event',
|
||||
self._on_banner_eventbox_button_press_event)
|
||||
self.handlers[id] = widget
|
||||
|
||||
self.urlfinder = re.compile("(https?://|www|ftp)[^ ]+")
|
||||
|
||||
if gajim.HAVE_PYSEXY:
|
||||
import sexy
|
||||
self.banner_status_label = sexy.UrlLabel()
|
||||
self.banner_status_label.connect('url_activated', self.status_url_clicked)
|
||||
else:
|
||||
self.banner_status_label = gtk.Label()
|
||||
self.banner_status_label.set_selectable(True)
|
||||
self.banner_status_label.set_alignment(0,0.5)
|
||||
|
||||
banner_vbox = self.xml.get_widget('banner_vbox')
|
||||
banner_vbox.pack_start(self.banner_status_label)
|
||||
self.banner_status_label.show()
|
||||
|
||||
# Init DND
|
||||
self.TARGET_TYPE_URI_LIST = 80
|
||||
self.dnd_list = [ ( 'text/uri-list', 0, self.TARGET_TYPE_URI_LIST ),
|
||||
|
@ -247,7 +270,6 @@ class ChatControlBase(MessageControl):
|
|||
spell.set_language(lang)
|
||||
except (gobject.GError, RuntimeError), msg:
|
||||
dialogs.AspellDictError(lang)
|
||||
self.style_event_id = 0
|
||||
self.conv_textview.tv.show()
|
||||
self._paint_banner()
|
||||
|
||||
|
@ -324,6 +346,7 @@ class ChatControlBase(MessageControl):
|
|||
banner_eventbox = self.xml.get_widget('banner_eventbox')
|
||||
banner_name_label = self.xml.get_widget('banner_name_label')
|
||||
self.disconnect_style_event(banner_name_label)
|
||||
self.disconnect_style_event(self.banner_status_label)
|
||||
if bgcolor:
|
||||
banner_eventbox.modify_bg(gtk.STATE_NORMAL,
|
||||
gtk.gdk.color_parse(bgcolor))
|
||||
|
@ -333,24 +356,32 @@ class ChatControlBase(MessageControl):
|
|||
if textcolor:
|
||||
banner_name_label.modify_fg(gtk.STATE_NORMAL,
|
||||
gtk.gdk.color_parse(textcolor))
|
||||
self.banner_status_label.modify_fg(gtk.STATE_NORMAL,
|
||||
gtk.gdk.color_parse(textcolor))
|
||||
default_fg = False
|
||||
else:
|
||||
default_fg = True
|
||||
if default_bg or default_fg:
|
||||
self._on_style_set_event(banner_name_label, None, default_fg,
|
||||
default_bg)
|
||||
self._on_style_set_event(self.banner_status_label, None, default_fg,
|
||||
default_bg)
|
||||
|
||||
def disconnect_style_event(self, widget):
|
||||
if self.style_event_id:
|
||||
widget.disconnect(self.style_event_id)
|
||||
del self.handlers[self.style_event_id]
|
||||
self.style_event_id = 0
|
||||
# Try to find the event_id
|
||||
found = False
|
||||
for id in self.handlers:
|
||||
if self.handlers[id] == widget:
|
||||
found = True
|
||||
break
|
||||
if found:
|
||||
widget.disconnect(id)
|
||||
del self.handlers[id]
|
||||
|
||||
def connect_style_event(self, widget, set_fg = False, set_bg = False):
|
||||
self.disconnect_style_event(widget)
|
||||
self.style_event_id = widget.connect('style-set',
|
||||
self._on_style_set_event, set_fg, set_bg)
|
||||
self.handlers[self.style_event_id] = widget
|
||||
id = widget.connect('style-set', self._on_style_set_event, set_fg, set_bg)
|
||||
self.handlers[id] = widget
|
||||
|
||||
def _on_style_set_event(self, widget, style, *opts):
|
||||
'''set style of widget from style class *.Frame.Eventbox
|
||||
|
@ -1162,6 +1193,7 @@ class ChatControl(ChatControlBase):
|
|||
self.status_tooltip.set_tip(banner_eventbox, status)
|
||||
self.status_tooltip.enable()
|
||||
banner_name_label.set_ellipsize(pango.ELLIPSIZE_END)
|
||||
self.banner_status_label.set_ellipsize(pango.ELLIPSIZE_END)
|
||||
status = helpers.reduce_chars_newlines(status, max_lines = 1)
|
||||
status_escaped = gobject.markup_escape_text(status)
|
||||
|
||||
|
@ -1192,9 +1224,15 @@ class ChatControl(ChatControlBase):
|
|||
# weight="heavy" size="x-large"
|
||||
label_text = '<span %s>%s</span><span %s>%s</span>' % \
|
||||
(font_attrs, name, font_attrs_small, acct_info)
|
||||
|
||||
if status_escaped:
|
||||
label_text += '\n<span %s>%s</span>' %\
|
||||
(font_attrs_small, status_escaped)
|
||||
if gajim.HAVE_PYSEXY:
|
||||
status_text = self.urlfinder.sub(self.make_href, status_escaped)
|
||||
status_text = '<span %s>%s</span>' % (font_attrs_small, status_text)
|
||||
else:
|
||||
status_text = '<span %s>%s</span>' % (font_attrs_small, status_escaped)
|
||||
|
||||
self.banner_status_label.set_markup(status_text)
|
||||
else:
|
||||
self.status_tooltip.disable()
|
||||
# setup the label that holds name and jid
|
||||
|
|
|
@ -142,6 +142,12 @@ try:
|
|||
except ImportError:
|
||||
HAVE_PYCRYPTO = False
|
||||
|
||||
HAVE_PYSEXY = True
|
||||
try:
|
||||
import sexy
|
||||
except ImportError:
|
||||
HAVE_PYSEXY = False
|
||||
|
||||
def get_nick_from_jid(jid):
|
||||
pos = jid.find('@')
|
||||
return jid[:pos]
|
||||
|
|
|
@ -98,6 +98,10 @@ class FeaturesWindow:
|
|||
_('Generate XHTML output from RST code (see http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html).'),
|
||||
_('Requires python-docutils.'),
|
||||
_('Requires python-docutils.')),
|
||||
_('libsexy'): (self.pysexy_available,
|
||||
_('Ability to have clickable URLs in chat window.'),
|
||||
_('Requires python-sexy.'),
|
||||
_('Requires python-sexy.')),
|
||||
}
|
||||
|
||||
# name, supported
|
||||
|
@ -294,3 +298,7 @@ class FeaturesWindow:
|
|||
except:
|
||||
return False
|
||||
return True
|
||||
|
||||
def pysexy_available(self):
|
||||
from common import gajim
|
||||
return gajim.HAVE_PYSEXY
|
||||
|
|
|
@ -481,6 +481,7 @@ class GroupchatControl(ChatControlBase):
|
|||
houses the room jid, subject.
|
||||
'''
|
||||
self.name_label.set_ellipsize(pango.ELLIPSIZE_END)
|
||||
self.banner_status_label.set_ellipsize(pango.ELLIPSIZE_END)
|
||||
font_attrs, font_attrs_small = self.get_font_attrs()
|
||||
if self.is_continued:
|
||||
nicks = []
|
||||
|
@ -495,16 +496,22 @@ class GroupchatControl(ChatControlBase):
|
|||
text = '<span %s>%s</span>' % (font_attrs, title)
|
||||
else:
|
||||
text = '<span %s>%s</span>' % (font_attrs, self.room_jid)
|
||||
self.name_label.set_markup(text)
|
||||
|
||||
if self.subject:
|
||||
subject = helpers.reduce_chars_newlines(self.subject, max_lines = 2)
|
||||
subject = gobject.markup_escape_text(subject)
|
||||
text += '\n<span %s>%s</span>' % (font_attrs_small, subject)
|
||||
if gajim.HAVE_PYSEXY:
|
||||
subject_text = self.urlfinder.sub(self.make_href, subject)
|
||||
subject_text = '<span %s>%s</span>' % (font_attrs_small,
|
||||
subject_text)
|
||||
else:
|
||||
subject_text = '<span %s>%s</span>' % (font_attrs_small, subject)
|
||||
self.banner_status_label.set_markup(subject_text)
|
||||
|
||||
# tooltip must always hold ALL the subject
|
||||
self.subject_tooltip.set_tip(self.event_box, self.subject)
|
||||
|
||||
self.name_label.set_markup(text)
|
||||
|
||||
def prepare_context_menu(self):
|
||||
'''sets sensitivity state for configure_room'''
|
||||
ag = gtk.accel_groups_from_object(self.parent_win.window)[0]
|
||||
|
|
Loading…
Reference in New Issue