[Florob] show in roster and message window geolocalisation of a contact. Fixes #5485

This commit is contained in:
Yann Leboulanger 2009-12-07 18:32:42 +01:00
parent 6f1c17e3d6
commit 07be0727de
11 changed files with 144 additions and 15 deletions

View file

@ -103,13 +103,31 @@
<child>
<widget class="GtkImage" id="tune_image">
<property name="no_show_all">True</property>
<property name="pixbuf">../emoticons/static/music.png</property>
<property name="stock">None</property>
<property name="icon-size">1</property>
</widget>
<packing>
<property name="position">2</property>
</packing>
</child>
<child>
<widget class="GtkEventBox" id="location_eventbox">
<property name="visible">True</property>
<property name="visible_window">False</property>
<child>
<widget class="GtkImage" id="location_image">
<property name="no_show_all">True</property>
<property name="stock">None</property>
<property name="icon-size">1</property>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>
<child>
<widget class="GtkImage" id="audio_banner_image">
<property name="visible">True</property>
@ -117,7 +135,7 @@
<property name="icon-size">1</property>
</widget>
<packing>
<property name="position">3</property>
<property name="position">4</property>
</packing>
</child>
<child>
@ -127,7 +145,7 @@
<property name="icon-size">1</property>
</widget>
<packing>
<property name="position">4</property>
<property name="position">5</property>
</packing>
</child>
<child>
@ -139,7 +157,7 @@
</child>
</widget>
<packing>
<property name="position">5</property>
<property name="position">6</property>
</packing>
</child>
</widget>

View file

@ -127,6 +127,24 @@
<property name="position">4</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="show_location_in_roster_checkbutton">
<property name="label" translatable="yes">Display _location of contacts in roster</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="has_tooltip">True</property>
<property name="tooltip" translatable="yes">If checked, Gajim will display the location of contacts in the roster window</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_show_location_in_roster_checkbutton_toggled"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">5</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox3">
<property name="visible">True</property>
@ -172,7 +190,7 @@
</child>
</widget>
<packing>
<property name="position">5</property>
<property name="position">6</property>
</packing>
</child>
</widget>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -1338,6 +1338,7 @@ class ChatControl(ChatControlBase):
self._pep_images['mood'] = self.xml.get_widget('mood_image')
self._pep_images['activity'] = self.xml.get_widget('activity_image')
self._pep_images['tune'] = self.xml.get_widget('tune_image')
self._pep_images['location'] = self.xml.get_widget('location_image')
self.update_all_pep_types()
# keep timeout id and window obj for possible big avatar
@ -1375,6 +1376,11 @@ class ChatControl(ChatControlBase):
self.on_avatar_eventbox_button_press_event)
self.handlers[id_] = widget
widget = self.xml.get_widget('location_eventbox')
id_ = widget.connect('button-release-event',
self.on_location_eventbox_button_release_event)
self.handlers[id_] = widget
for key in ('1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '0', '#'):
widget = self.xml.get_widget(key + '_button')
id_ = widget.connect('pressed', self.on_num_button_pressed, key)
@ -1678,6 +1684,14 @@ class ChatControl(ChatControlBase):
menu.show_all()
menu.popup(None, None, None, event.button, event.time)
return True
def on_location_eventbox_button_release_event(self, widget, event):
if 'location' in self.contact.pep:
location = self.contact.pep['location']._pep_specific_data
if ('lat' in location) and ('lon' in location):
uri = 'http://www.openstreetmap.org/?mlat=%(lat)s&mlon=%(lon)s&' + \
'zoom=16' % {'lat': location['lat'], 'lon': location['lon']}
helpers.launch_browser_mailer('url', uri)
def _on_window_motion_notify(self, widget, event):
"""

View file

@ -225,6 +225,7 @@ class Config:
'show_mood_in_roster': [opt_bool, True, '', True],
'show_activity_in_roster': [opt_bool, True, '', True],
'show_tunes_in_roster': [opt_bool, True, '', True],
'show_location_in_roster': [opt_bool, True, '', True],
'avatar_position_in_roster': [opt_str, 'right', _('Define the position of the avatar in roster. Can be left or right'), True],
'ask_avatars_on_startup': [opt_bool, True, _('If True, Gajim will ask for avatar each contact that did not have an avatar last time or has one cached that is too old.')],
'print_status_in_chats': [opt_bool, True, _('If False, Gajim will no longer print status line in chats when a contact changes his or her status and/or his or her status message.')],
@ -353,6 +354,7 @@ class Config:
'subscribe_activity': [opt_bool, True],
'subscribe_tune': [opt_bool, True],
'subscribe_nick': [opt_bool, True],
'subscribe_location': [opt_bool, True],
'ignore_unknown_contacts': [ opt_bool, False ],
'send_os_info': [ opt_bool, True ],
'log_encrypted_sessions': [opt_bool, True, _('When negotiating an encrypted session, should Gajim assume you want your messages to be logged?')],

View file

@ -1294,6 +1294,8 @@ def update_optional_features(account = None):
gajim.gajim_optional_features[a].append(xmpp.NS_TUNE + '+notify')
if gajim.config.get_per('accounts', a, 'subscribe_nick'):
gajim.gajim_optional_features[a].append(xmpp.NS_NICK + '+notify')
if gajim.config.get_per('accounts', a, 'subscribe_location'):
gajim.gajim_optional_features[a].append(xmpp.NS_LOCATION + '+notify')
if gajim.config.get('outgoing_chat_state_notifactions') != 'disabled':
gajim.gajim_optional_features[a].append(xmpp.NS_CHATSTATES)
if not gajim.config.get('ignore_incoming_xhtml'):

View file

@ -191,6 +191,11 @@ ACTIVITIES = {
TUNE_DATA = ['artist', 'title', 'source', 'track', 'length']
LOCATION_DATA = ['accuracy', 'alt', 'area', 'bearing', 'building', 'country',
'countrycode', 'datum', 'description', 'error', 'floor', 'lat',
'locality', 'lon', 'postalcode', 'region', 'room', 'speed', 'street',
'text', 'timestamp', 'uri']
import gobject
import gtk
@ -442,8 +447,47 @@ class UserNicknamePEP(AbstractPEP):
gajim.nicks[account] = self._pep_specific_data
class UserLocationPEP(AbstractPEP):
'''XEP-0080: User Location'''
type = 'location'
namespace = xmpp.NS_LOCATION
def _extract_info(self, items):
location_dict = {}
for item in items.getTags('item'):
location_tag = item.getTag('geoloc')
if location_tag:
for child in location_tag.getChildren():
name = child.getName().strip()
data = child.getData().strip()
if child.getName() in LOCATION_DATA:
location_dict[name] = data
retracted = items.getTag('retract') or not location_dict
return (location_dict, retracted)
def asPixbufIcon(self):
gtkgui_helpers.get_icon_path('gajim-earth')
return gtk.gdk.pixbuf_new_from_file(path)
def asMarkupText(self):
assert not self._retracted
location = self._pep_specific_data
location_string = ''
for entry in location.keys():
text = location[entry]
text = gobject.markup_escape_text(text)
location_string += '\n<b>%(tag)s</b>: %(text)s' % \
{'tag': entry.capitalize(), 'text': text}
return location_string.strip()
SUPPORTED_PERSONAL_USER_EVENTS = [UserMoodPEP, UserTunePEP, UserActivityPEP,
UserNicknamePEP]
UserNicknamePEP, UserLocationPEP]
class ConnectionPEP(object):

View file

@ -72,6 +72,7 @@ NS_JINGLE_RTP_VIDEO='urn:xmpp:jingle:apps:rtp:video' # XEP-01
NS_JINGLE_RAW_UDP='urn:xmpp:jingle:transports:raw-udp:1' # XEP-0177
NS_JINGLE_ICE_UDP='urn:xmpp:jingle:transports:ice-udp:1' # XEP-0176
NS_LAST ='jabber:iq:last'
NS_LOCATION ='http://jabber.org/protocol/geoloc' # XEP-0080
NS_MESSAGE ='message' # Jabberd2
NS_MOOD ='http://jabber.org/protocol/mood' # XEP-0107
NS_MUC ='http://jabber.org/protocol/muc'

View file

@ -137,6 +137,11 @@ class PreferencesWindow:
self.xml.get_widget('show_tunes_in_roster_checkbutton'). \
set_active(st)
# Display location in roster
st = gajim.config.get('show_location_in_roster')
self.xml.get_widget('show_location_in_roster_checkbutton'). \
set_active(st)
# Sort contacts by show
st = gajim.config.get('sort_by_show_in_roster')
self.xml.get_widget('sort_by_show_in_roster_checkbutton').set_active(st)
@ -615,6 +620,10 @@ class PreferencesWindow:
self.on_checkbutton_toggled(widget, 'show_tunes_in_roster')
gajim.interface.roster.setup_and_draw_roster()
def on_show_location_in_roster_checkbutton_toggled(self, widget):
self.on_checkbutton_toggled(widget, 'show_location_in_roster')
gajim.interface.roster.setup_and_draw_roster()
def on_emoticons_combobox_changed(self, widget):
active = widget.get_active()
model = widget.get_model()

View file

@ -79,9 +79,10 @@ from common.pep import MOODS, ACTIVITIES
C_MOOD_PIXBUF,
C_ACTIVITY_PIXBUF,
C_TUNE_PIXBUF,
C_LOCATION_PIXBUF,
C_AVATAR_PIXBUF, # avatar_pixbuf
C_PADLOCK_PIXBUF, # use for account row only
) = range(10)
) = range(11)
class RosterWindow:
"""
@ -293,7 +294,7 @@ class RosterWindow:
self.model.append(None, [
gajim.interface.jabber_state_images['16'][show],
gobject.markup_escape_text(account), 'account',
our_jid, account, None, None, None, None,
our_jid, account, None, None, None, None, None,
tls_pixbuf])
self.draw_account(account)
@ -370,7 +371,7 @@ class RosterWindow:
child_iterG = self.model.append(child_iterA,
[gajim.interface.jabber_state_images['16']['closed'],
gobject.markup_escape_text(group),
'group', group, account, None, None, None, None, None])
'group', group, account, None, None, None, None, None, None])
self.draw_group(group, account)
if contact.is_transport():
@ -385,7 +386,7 @@ class RosterWindow:
i_ = self.model.append(child_iterG, (None,
contact.get_shown_name(), typestr,
contact.jid, account, None, None, None,
None, None))
None, None, None))
added_iters.append(i_)
# Restore the group expand state
@ -627,7 +628,7 @@ class RosterWindow:
child_iterA = self._get_account_iter(account, self.model)
self.model.append(child_iterA, (None, gajim.nicks[account],
'self_contact', jid, account, None, None, None, None,
None))
None, None))
self.draw_completely(jid, account)
self.draw_account(account)
@ -1050,6 +1051,11 @@ class RosterWindow:
self.model[child_iter][C_TUNE_PIXBUF] = pep['tune'].asPixbufIcon()
else:
self.model[child_iter][C_TUNE_PIXBUF] = None
if gajim.config.get('show_location_in_roster') and 'location' in pep:
self.model[child_iter][C_LOCATION_PIXBUF] = pep['location'].asPixbufIcon()
else:
self.model[child_iter][C_LOCATION_PIXBUF] = None
return False
def draw_group(self, group, account):
@ -1264,6 +1270,8 @@ class RosterWindow:
return gajim.config.get('show_activity_in_roster')
elif pep_type == 'tune':
return gajim.config.get('show_tunes_in_roster')
elif pep_type == 'location':
return gajim.config.get('show_location_in_roster')
else:
return False
@ -1362,10 +1370,11 @@ class RosterWindow:
"""
self.modelfilter = None
# (icon, name, type, jid, account, editable, mood_pixbuf,
# activity_pixbuf, tune_pixbuf avatar_pixbuf, padlock_pixbuf)
# activity_pixbuf, tune_pixbuf, location_pixbuf, avatar_pixbuf,
# padlock_pixbuf)
self.model = gtk.TreeStore(gtk.Image, str, str, str, str,
gtk.gdk.Pixbuf, gtk.gdk.Pixbuf, gtk.gdk.Pixbuf,
gtk.gdk.Pixbuf, gtk.gdk.Pixbuf)
gtk.gdk.Pixbuf, gtk.gdk.Pixbuf, gtk.gdk.Pixbuf)
self.model.set_sort_func(1, self._compareIters)
self.model.set_sort_column_id(1, gtk.SORT_ASCENDING)
@ -5892,9 +5901,16 @@ class RosterWindow:
col.set_cell_data_func(render_pixbuf,
self._fill_pep_pixbuf_renderer, C_TUNE_PIXBUF)
render_pixbuf = gtk.CellRendererPixbuf()
col.pack_start(render_pixbuf, expand=False)
col.add_attribute(render_pixbuf, 'pixbuf', C_LOCATION_PIXBUF)
col.set_cell_data_func(render_pixbuf,
self._fill_pep_pixbuf_renderer, C_LOCATION_PIXBUF)
self._pep_type_to_model_column = {'mood': C_MOOD_PIXBUF,
'activity': C_ACTIVITY_PIXBUF,
'tune': C_TUNE_PIXBUF}
'tune': C_TUNE_PIXBUF,
'location': C_LOCATION_PIXBUF}
if gajim.config.get('avatar_position_in_roster') == 'right':
add_avatar_renderer()

View file

@ -600,7 +600,7 @@ class RosterTooltip(NotificationAreaTooltip):
def _append_pep_info(self, contact, properties):
"""
Append Tune, Mood, Activity information of the specified contact
Append Tune, Mood, Activity, Location information of the specified contact
to the given property list.
"""
if 'mood' in contact.pep:
@ -618,6 +618,11 @@ class RosterTooltip(NotificationAreaTooltip):
tune_string = _('Tune:') + ' %s' % tune
properties.append((tune_string, None))
if 'location' in contact.pep:
location = contact.pep['location'].asMarkupText()
location_string = _('Location:') + ' %s' % location
properties.append((location_string, None))
class FileTransfersTooltip(BaseTooltip):
"""