[Florob] show in roster and message window geolocalisation of a contact. Fixes #5485
This commit is contained in:
parent
6f1c17e3d6
commit
07be0727de
11 changed files with 144 additions and 15 deletions
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
BIN
icons/hicolor/16x16/actions/gajim-earth.png
Normal file
BIN
icons/hicolor/16x16/actions/gajim-earth.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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?')],
|
||||
|
|
|
@ -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'):
|
||||
|
|
|
@ -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):
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
Loading…
Add table
Reference in a new issue