diff --git a/data/glade/preferences_window.glade b/data/glade/preferences_window.glade
index d3ea20d10..c9d6a34b1 100644
--- a/data/glade/preferences_window.glade
+++ b/data/glade/preferences_window.glade
@@ -1962,7 +1962,6 @@ $T will be replaced by auto-not-available timeout
1
2
-
@@ -1975,7 +1974,6 @@ $T will be replaced by auto-not-available timeout
2
1
2
-
@@ -2066,7 +2064,6 @@ $T will be replaced by auto-not-available timeout
1
2
-
@@ -2079,7 +2076,6 @@ $T will be replaced by auto-not-available timeout
2
1
2
-
@@ -2102,6 +2098,74 @@ $T will be replaced by auto-not-available timeout
1
+
+
+ True
+ 0
+ none
+
+
+ True
+ 12
+
+
+ True
+ 3
+ 6
+ 6
+
+
+ True
+ 0
+ STUN server:
+
+
+ GTK_FILL
+
+
+
+
+ True
+ <i>(example: stunserver.org)</i>
+ True
+
+
+ 2
+ 3
+ GTK_FILL
+
+
+
+
+ True
+ True
+ ●
+
+
+ 1
+ 2
+
+
+
+
+
+
+
+
+ True
+ <b>Connection</b>
+ True
+
+
+ label_item
+
+
+
+
+ False
+ 2
+
+
5
diff --git a/data/pixmaps/Makefile.am b/data/pixmaps/Makefile.am
index ae122a971..a7eadc116 100644
--- a/data/pixmaps/Makefile.am
+++ b/data/pixmaps/Makefile.am
@@ -1,15 +1,5 @@
pixmapsdir = $(pkgdatadir)/data/pixmaps
nobase_dist_pixmaps_DATA = \
- $(srcdir)/events/*.png \
- $(srcdir)/agents/*.png \
- $(srcdir)/*.png \
- $(srcdir)/gajim.svg \
$(srcdir)/gajim.ico
-gajimpixmapdir = $(datadir)/pixmaps
-gajimpixmap_DATA = \
- $(srcdir)/gajim.png \
- $(srcdir)/gajim.svg \
- $(srcdir)/gajim_about.png
-
MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/pixmaps/gajim.icns b/data/pixmaps/gajim.icns
deleted file mode 100644
index 37516d5e8..000000000
Binary files a/data/pixmaps/gajim.icns and /dev/null differ
diff --git a/data/pixmaps/person.png b/data/pixmaps/person.png
deleted file mode 100644
index f2169a8a2..000000000
Binary files a/data/pixmaps/person.png and /dev/null differ
diff --git a/icons/Makefile.am b/icons/Makefile.am
index fb75f0ef3..e61275c37 100644
--- a/icons/Makefile.am
+++ b/icons/Makefile.am
@@ -1,4 +1,7 @@
iconsdir = $(pkgdatadir)/icons
nobase_dist_icons_DATA = $(srcdir)/*/*/*/*
+systemiconsdir = $(datadir)/icons
+nobase_dist_systemicons_DATA = $(srcdir)/*/*/*/gajim.*
+
MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/pixmaps/gajim_about.png b/icons/hicolor/128x128/apps/gajim_about.png
similarity index 100%
rename from data/pixmaps/gajim_about.png
rename to icons/hicolor/128x128/apps/gajim_about.png
diff --git a/data/pixmaps/cam_active.png b/icons/hicolor/16x16/actions/gajim-cam_active.png
similarity index 100%
rename from data/pixmaps/cam_active.png
rename to icons/hicolor/16x16/actions/gajim-cam_active.png
diff --git a/data/pixmaps/cam_inactive.png b/icons/hicolor/16x16/actions/gajim-cam_inactive.png
similarity index 100%
rename from data/pixmaps/cam_inactive.png
rename to icons/hicolor/16x16/actions/gajim-cam_inactive.png
diff --git a/data/pixmaps/kbd_input.png b/icons/hicolor/16x16/actions/gajim-kbd_input.png
similarity index 100%
rename from data/pixmaps/kbd_input.png
rename to icons/hicolor/16x16/actions/gajim-kbd_input.png
diff --git a/data/pixmaps/mic_active.png b/icons/hicolor/16x16/actions/gajim-mic_active.png
similarity index 100%
rename from data/pixmaps/mic_active.png
rename to icons/hicolor/16x16/actions/gajim-mic_active.png
diff --git a/data/pixmaps/mic_inactive.png b/icons/hicolor/16x16/actions/gajim-mic_inactive.png
similarity index 100%
rename from data/pixmaps/mic_inactive.png
rename to icons/hicolor/16x16/actions/gajim-mic_inactive.png
diff --git a/data/pixmaps/muc_separator.png b/icons/hicolor/16x16/actions/gajim-muc_separator.png
similarity index 100%
rename from data/pixmaps/muc_separator.png
rename to icons/hicolor/16x16/actions/gajim-muc_separator.png
diff --git a/data/pixmaps/receipt_missing.png b/icons/hicolor/16x16/actions/gajim-receipt_missing.png
similarity index 100%
rename from data/pixmaps/receipt_missing.png
rename to icons/hicolor/16x16/actions/gajim-receipt_missing.png
diff --git a/data/pixmaps/security-high.png b/icons/hicolor/16x16/actions/gajim-security_high.png
similarity index 100%
rename from data/pixmaps/security-high.png
rename to icons/hicolor/16x16/actions/gajim-security_high.png
diff --git a/data/pixmaps/security-low.png b/icons/hicolor/16x16/actions/gajim-security_low.png
similarity index 100%
rename from data/pixmaps/security-low.png
rename to icons/hicolor/16x16/actions/gajim-security_low.png
diff --git a/data/pixmaps/agents/aim.png b/icons/hicolor/32x32/categories/gajim-agent-aim.png
similarity index 100%
rename from data/pixmaps/agents/aim.png
rename to icons/hicolor/32x32/categories/gajim-agent-aim.png
diff --git a/data/pixmaps/agents/bytestreams.png b/icons/hicolor/32x32/categories/gajim-agent-bytestreams.png
similarity index 100%
rename from data/pixmaps/agents/bytestreams.png
rename to icons/hicolor/32x32/categories/gajim-agent-bytestreams.png
diff --git a/data/pixmaps/agents/conference.png b/icons/hicolor/32x32/categories/gajim-agent-conference.png
similarity index 100%
rename from data/pixmaps/agents/conference.png
rename to icons/hicolor/32x32/categories/gajim-agent-conference.png
diff --git a/data/pixmaps/agents/disc.png b/icons/hicolor/32x32/categories/gajim-agent-disc.png
similarity index 100%
rename from data/pixmaps/agents/disc.png
rename to icons/hicolor/32x32/categories/gajim-agent-disc.png
diff --git a/data/pixmaps/agents/error.png b/icons/hicolor/32x32/categories/gajim-agent-error.png
similarity index 100%
rename from data/pixmaps/agents/error.png
rename to icons/hicolor/32x32/categories/gajim-agent-error.png
diff --git a/data/pixmaps/agents/facebook.png b/icons/hicolor/32x32/categories/gajim-agent-facebook.png
similarity index 100%
rename from data/pixmaps/agents/facebook.png
rename to icons/hicolor/32x32/categories/gajim-agent-facebook.png
diff --git a/data/pixmaps/agents/gadu-gadu.png b/icons/hicolor/32x32/categories/gajim-agent-gadu-gadu.png
similarity index 100%
rename from data/pixmaps/agents/gadu-gadu.png
rename to icons/hicolor/32x32/categories/gajim-agent-gadu-gadu.png
diff --git a/data/pixmaps/agents/http-ws.png b/icons/hicolor/32x32/categories/gajim-agent-http-ws.png
similarity index 100%
rename from data/pixmaps/agents/http-ws.png
rename to icons/hicolor/32x32/categories/gajim-agent-http-ws.png
diff --git a/data/pixmaps/agents/icq.png b/icons/hicolor/32x32/categories/gajim-agent-icq.png
similarity index 100%
rename from data/pixmaps/agents/icq.png
rename to icons/hicolor/32x32/categories/gajim-agent-icq.png
diff --git a/data/pixmaps/agents/irc.png b/icons/hicolor/32x32/categories/gajim-agent-irc.png
similarity index 100%
rename from data/pixmaps/agents/irc.png
rename to icons/hicolor/32x32/categories/gajim-agent-irc.png
diff --git a/data/pixmaps/agents/jabber.png b/icons/hicolor/32x32/categories/gajim-agent-jabber.png
similarity index 100%
rename from data/pixmaps/agents/jabber.png
rename to icons/hicolor/32x32/categories/gajim-agent-jabber.png
diff --git a/data/pixmaps/agents/jud.png b/icons/hicolor/32x32/categories/gajim-agent-jud.png
similarity index 100%
rename from data/pixmaps/agents/jud.png
rename to icons/hicolor/32x32/categories/gajim-agent-jud.png
diff --git a/data/pixmaps/agents/mail.png b/icons/hicolor/32x32/categories/gajim-agent-mail.png
similarity index 100%
rename from data/pixmaps/agents/mail.png
rename to icons/hicolor/32x32/categories/gajim-agent-mail.png
diff --git a/data/pixmaps/agents/mrim.png b/icons/hicolor/32x32/categories/gajim-agent-mrim.png
similarity index 100%
rename from data/pixmaps/agents/mrim.png
rename to icons/hicolor/32x32/categories/gajim-agent-mrim.png
diff --git a/data/pixmaps/agents/msn.png b/icons/hicolor/32x32/categories/gajim-agent-msn.png
similarity index 100%
rename from data/pixmaps/agents/msn.png
rename to icons/hicolor/32x32/categories/gajim-agent-msn.png
diff --git a/data/pixmaps/agents/pubsub.png b/icons/hicolor/32x32/categories/gajim-agent-pubsub.png
similarity index 100%
rename from data/pixmaps/agents/pubsub.png
rename to icons/hicolor/32x32/categories/gajim-agent-pubsub.png
diff --git a/data/pixmaps/agents/rss.png b/icons/hicolor/32x32/categories/gajim-agent-rss.png
similarity index 100%
rename from data/pixmaps/agents/rss.png
rename to icons/hicolor/32x32/categories/gajim-agent-rss.png
diff --git a/data/pixmaps/agents/sip.png b/icons/hicolor/32x32/categories/gajim-agent-sip.png
similarity index 100%
rename from data/pixmaps/agents/sip.png
rename to icons/hicolor/32x32/categories/gajim-agent-sip.png
diff --git a/data/pixmaps/agents/sms.png b/icons/hicolor/32x32/categories/gajim-agent-sms.png
similarity index 100%
rename from data/pixmaps/agents/sms.png
rename to icons/hicolor/32x32/categories/gajim-agent-sms.png
diff --git a/data/pixmaps/agents/tv.png b/icons/hicolor/32x32/categories/gajim-agent-tv.png
similarity index 100%
rename from data/pixmaps/agents/tv.png
rename to icons/hicolor/32x32/categories/gajim-agent-tv.png
diff --git a/data/pixmaps/agents/weather.png b/icons/hicolor/32x32/categories/gajim-agent-weather.png
similarity index 100%
rename from data/pixmaps/agents/weather.png
rename to icons/hicolor/32x32/categories/gajim-agent-weather.png
diff --git a/data/pixmaps/agents/yahoo.png b/icons/hicolor/32x32/categories/gajim-agent-yahoo.png
similarity index 100%
rename from data/pixmaps/agents/yahoo.png
rename to icons/hicolor/32x32/categories/gajim-agent-yahoo.png
diff --git a/data/pixmaps/events/chat_msg_recv.png b/icons/hicolor/48x48/actions/gajim-chat_msg_recv.png
similarity index 100%
rename from data/pixmaps/events/chat_msg_recv.png
rename to icons/hicolor/48x48/actions/gajim-chat_msg_recv.png
diff --git a/data/pixmaps/events/connection_lost.png b/icons/hicolor/48x48/actions/gajim-connection_lost.png
similarity index 100%
rename from data/pixmaps/events/connection_lost.png
rename to icons/hicolor/48x48/actions/gajim-connection_lost.png
diff --git a/data/pixmaps/events/ft_done.png b/icons/hicolor/48x48/actions/gajim-ft_done.png
similarity index 100%
rename from data/pixmaps/events/ft_done.png
rename to icons/hicolor/48x48/actions/gajim-ft_done.png
diff --git a/data/pixmaps/events/ft_error.png b/icons/hicolor/48x48/actions/gajim-ft_error.png
similarity index 100%
rename from data/pixmaps/events/ft_error.png
rename to icons/hicolor/48x48/actions/gajim-ft_error.png
diff --git a/data/pixmaps/events/ft_request.png b/icons/hicolor/48x48/actions/gajim-ft_request.png
similarity index 100%
rename from data/pixmaps/events/ft_request.png
rename to icons/hicolor/48x48/actions/gajim-ft_request.png
diff --git a/data/pixmaps/events/ft_stopped.png b/icons/hicolor/48x48/actions/gajim-ft_stopped.png
similarity index 100%
rename from data/pixmaps/events/ft_stopped.png
rename to icons/hicolor/48x48/actions/gajim-ft_stopped.png
diff --git a/data/pixmaps/events/gc_invitation.png b/icons/hicolor/48x48/actions/gajim-gc_invitation.png
similarity index 100%
rename from data/pixmaps/events/gc_invitation.png
rename to icons/hicolor/48x48/actions/gajim-gc_invitation.png
diff --git a/data/pixmaps/events/new_email_recv.png b/icons/hicolor/48x48/actions/gajim-new_email_recv.png
similarity index 100%
rename from data/pixmaps/events/new_email_recv.png
rename to icons/hicolor/48x48/actions/gajim-new_email_recv.png
diff --git a/data/pixmaps/events/priv_msg_recv.png b/icons/hicolor/48x48/actions/gajim-priv_msg_recv.png
similarity index 100%
rename from data/pixmaps/events/priv_msg_recv.png
rename to icons/hicolor/48x48/actions/gajim-priv_msg_recv.png
diff --git a/data/pixmaps/security-high-big.png b/icons/hicolor/48x48/actions/gajim-security_high.png
similarity index 100%
rename from data/pixmaps/security-high-big.png
rename to icons/hicolor/48x48/actions/gajim-security_high.png
diff --git a/data/pixmaps/security-low-big.png b/icons/hicolor/48x48/actions/gajim-security_low.png
similarity index 100%
rename from data/pixmaps/security-low-big.png
rename to icons/hicolor/48x48/actions/gajim-security_low.png
diff --git a/data/pixmaps/events/single_msg_recv.png b/icons/hicolor/48x48/actions/gajim-single_msg_recv.png
similarity index 100%
rename from data/pixmaps/events/single_msg_recv.png
rename to icons/hicolor/48x48/actions/gajim-single_msg_recv.png
diff --git a/data/pixmaps/events/subscription_request.png b/icons/hicolor/48x48/actions/gajim-subscription_request.png
similarity index 100%
rename from data/pixmaps/events/subscription_request.png
rename to icons/hicolor/48x48/actions/gajim-subscription_request.png
diff --git a/data/pixmaps/events/unsubscribed.png b/icons/hicolor/48x48/actions/gajim-unsubscribed.png
similarity index 100%
rename from data/pixmaps/events/unsubscribed.png
rename to icons/hicolor/48x48/actions/gajim-unsubscribed.png
diff --git a/data/pixmaps/gajim.png b/icons/hicolor/64x64/apps/gajim.png
similarity index 100%
rename from data/pixmaps/gajim.png
rename to icons/hicolor/64x64/apps/gajim.png
diff --git a/data/pixmaps/gajim.svg b/icons/hicolor/scalable/apps/gajim.svg
similarity index 100%
rename from data/pixmaps/gajim.svg
rename to icons/hicolor/scalable/apps/gajim.svg
diff --git a/src/chat_control.py b/src/chat_control.py
index 7b52d8b34..9bf83be5d 100644
--- a/src/chat_control.py
+++ b/src/chat_control.py
@@ -1274,21 +1274,15 @@ class ChatControl(ChatControlBase):
id_ = self._audio_button.connect('toggled', self.on_audio_button_toggled)
self.handlers[id_] = self._audio_button
# add a special img
- path_to_img = os.path.join(gajim.DATA_DIR, 'pixmaps',
- 'mic_inactive.png')
- img = gtk.Image()
- img.set_from_file(path_to_img)
- self._audio_button.set_image(img)
+ gtkgui_helpers.add_image_to_button(self._audio_button,
+ 'gajim-mic_inactive')
self._video_button = self.xml.get_widget('video_togglebutton')
id_ = self._video_button.connect('toggled', self.on_video_button_toggled)
self.handlers[id_] = self._video_button
# add a special img
- path_to_img = os.path.join(gajim.DATA_DIR, 'pixmaps',
- 'cam_inactive.png')
- img = gtk.Image()
- img.set_from_file(path_to_img)
- self._video_button.set_image(img)
+ gtkgui_helpers.add_image_to_button(self._video_button,
+ 'gajim-cam_inactive')
self._send_file_button = self.xml.get_widget('send_file_button')
# add a special img for send file button
@@ -1796,12 +1790,13 @@ class ChatControl(ChatControlBase):
banner_name_label.set_tooltip_text(label_tooltip)
def on_jingle_button_toggled(self, widget, jingle_type):
- path_to_img = os.path.join(gajim.DATA_DIR, 'pixmaps', '%s_%s.png'
- % ({'audio': 'mic', 'video': 'cam'}[jingle_type],
- {True: 'active', False: 'inactive'}[widget.get_active()]))
+ img_name = '%s_%s' % ({'audio': 'mic', 'video': 'cam'}[jingle_type],
+ {True: 'active', False: 'inactive'}[widget.get_active()])
+ path_to_img = gtkgui_helpers.get_icon_path(img_name)
if widget.get_active():
- if getattr(self, jingle_type + '_state') == self.JINGLE_STATE_AVAILABLE:
+ if getattr(self, jingle_type + '_state') == \
+ self.JINGLE_STATE_AVAILABLE:
sid = getattr(gajim.connections[self.account],
'start_' + jingle_type)(self.contact.get_full_jid())
getattr(self, 'set_' + jingle_type + '_state')('connecting', sid)
@@ -1886,11 +1881,12 @@ class ChatControl(ChatControlBase):
if authenticated:
#About encrypted chat session
authenticated_string = _('and authenticated')
- self.lock_image.set_from_file(os.path.join(gajim.DATA_DIR, 'pixmaps', 'security-high.png'))
+ img_path = gtkgui_helpers.get_icon_path('gajim-security_high')
else:
#About encrypted chat session
authenticated_string = _('and NOT authenticated')
- self.lock_image.set_from_file(os.path.join(gajim.DATA_DIR, 'pixmaps', 'security-low.png'))
+ img_path = gtkgui_helpers.get_icon_path('gajim-security_low')
+ self.lock_image.set_from_file(img_path)
#status will become 'is' or 'is not', authentificaed will become
#'and authentificated' or 'and not authentificated', logged will become
diff --git a/src/command_system/errors.py b/src/command_system/errors.py
index 877a22acb..f687b72e3 100644
--- a/src/command_system/errors.py
+++ b/src/command_system/errors.py
@@ -20,13 +20,15 @@ class BaseError(Exception):
"""
def __init__(self, message, command=None, name=None):
+ self.message = message
+
self.command = command
self.name = name
if command and not name:
self.name = command.first_name
- super(BaseError, self).__init__(message)
+ super(BaseError, self).__init__()
class DefinitionError(BaseError):
"""
diff --git a/src/common/check_paths.py b/src/common/check_paths.py
index c4864fc78..122ab5528 100644
--- a/src/common/check_paths.py
+++ b/src/common/check_paths.py
@@ -27,18 +27,11 @@ import os
import sys
import stat
-import exceptions
from common import gajim
import logger
# DO NOT MOVE ABOVE OF import gajim
-try:
- import sqlite3 as sqlite # python 2.5
-except ImportError:
- try:
- from pysqlite2 import dbapi2 as sqlite
- except ImportError:
- raise exceptions.PysqliteNotAvailable
+import sqlite3 as sqlite
def create_log_db():
print _('creating logs database')
diff --git a/src/common/config.py b/src/common/config.py
index 5108e60b1..fb5f0ebfd 100644
--- a/src/common/config.py
+++ b/src/common/config.py
@@ -276,6 +276,7 @@ class Config:
'audio_output_device': [opt_str, 'autoaudiosink'],
'video_input_device': [opt_str, 'autovideosrc ! videoscale ! ffmpegcolorspace'],
'video_output_device': [opt_str, 'autovideosink'],
+ 'stun_server': [opt_str, '', _('STUN server to use when using jingle')],
}
__options_per_key = {
diff --git a/src/common/contacts.py b/src/common/contacts.py
index 25ffb8237..8f8397047 100644
--- a/src/common/contacts.py
+++ b/src/common/contacts.py
@@ -31,7 +31,7 @@
from common import caps
from common.account import Account
-import common.gajim
+import common.gajim
class XMPPEntity(object):
"""
@@ -175,9 +175,7 @@ class Contact(CommonContact):
def is_transport(self):
# if not '@' or '@' starts the jid then contact is transport
- if self.jid.find('@') <= 0:
- return True
- return False
+ return self.jid.find('@') <= 0
class GC_Contact(CommonContact):
@@ -443,18 +441,14 @@ class Contacts_New():
"""
Remove all contacts for a given jid
"""
- if jid not in self._contacts:
- return
- del self._contacts[jid]
+ if jid in self._contacts:
+ del self._contacts[jid]
def get_contacts(self, jid):
"""
Return the list of contact instances for this jid
"""
- if jid in self._contacts:
- return self._contacts[jid]
- else:
- return []
+ return self._contacts.get(jid, [])
def get_contact(self, jid, resource=None):
### WARNING ###
@@ -472,7 +466,6 @@ class Contacts_New():
for c in self._contacts[jid]:
if c.resource == resource:
return c
- return None
def iter_contacts(self):
for jid in self._contacts.keys():
@@ -492,7 +485,6 @@ class Contacts_New():
def get_first_contact_from_jid(self, jid):
if jid in self._contacts:
return self._contacts[jid][0]
- return None
def get_contacts_from_group(self, group):
"""
@@ -538,9 +530,8 @@ class GC_Contacts():
del self._rooms[gc_contact.room_jid]
def remove_room(self, room_jid):
- if room_jid not in self._rooms:
- return
- del self._rooms[room_jid]
+ if room_jid in self._rooms:
+ del self._rooms[room_jid]
def get_gc_list(self):
return self._rooms.keys()
@@ -643,7 +634,7 @@ class MetacontactManager():
def remove_metacontact(self, account, jid):
if not account in self._metacontacts_tags:
- return None
+ return
found = None
for tag in self._metacontacts_tags[account]:
diff --git a/src/common/dbus_support.py b/src/common/dbus_support.py
index 24d4525ac..4762b474d 100644
--- a/src/common/dbus_support.py
+++ b/src/common/dbus_support.py
@@ -63,7 +63,7 @@ class SystemBus:
raise exceptions.DbusNotSupported
if not self.present():
- raise exceptions.SystemBusNotPresent
+ raise exceptions.SystemBusNotPresent
return self.system_bus
def bus(self):
diff --git a/src/common/exceptions.py b/src/common/exceptions.py
index 75f5b8913..090255768 100644
--- a/src/common/exceptions.py
+++ b/src/common/exceptions.py
@@ -21,17 +21,6 @@
## along with Gajim. If not, see .
##
-class PysqliteNotAvailable(Exception):
- """
- Sqlite2 is not installed or python bindings are missing
- """
-
- def __init__(self):
- Exception.__init__(self)
-
- def __str__(self):
- return _('pysqlite2 (aka python-pysqlite2) dependency is missing. Exiting...')
-
class PysqliteOperationalError(Exception):
"""
Sqlite2 raised pysqlite2.dbapi2.OperationalError
@@ -86,7 +75,20 @@ class SessionBusNotPresent(Exception):
Exception.__init__(self)
def __str__(self):
- return _('Session bus is not available.\nTry reading http://trac.gajim.org/wiki/GajimDBus')
+ return _('Session bus is not available.\nTry reading %(url)s') % \
+ {'url': 'http://trac.gajim.org/wiki/GajimDBus'}
+
+class SystemBusNotPresent(Exception):
+ """
+ This exception indicates that there is no session daemon
+ """
+
+ def __init__(self):
+ Exception.__init__(self)
+
+ def __str__(self):
+ return _('System bus is not available.\nTry reading %(url)s') % \
+ {'url': 'http://trac.gajim.org/wiki/GajimDBus'}
class NegotiationError(Exception):
"""
diff --git a/src/common/jingle.py b/src/common/jingle.py
index 65803a2ed..f4c002ca6 100644
--- a/src/common/jingle.py
+++ b/src/common/jingle.py
@@ -25,7 +25,6 @@ Handles the jingle signalling protocol
# - video integration
# * config:
# - codecs
-# - STUN
# * figure out why it doesn't work with pidgin:
# That's maybe a bug in pidgin:
diff --git a/src/common/jingle_content.py b/src/common/jingle_content.py
index 703f1a054..0dd013660 100644
--- a/src/common/jingle_content.py
+++ b/src/common/jingle_content.py
@@ -23,6 +23,12 @@ def get_jingle_content(node):
return contents[namespace](node)
+class FailedApplication(Exception):
+ """
+ Exception that should be raised when a content fails to setup.
+ """
+
+
class JingleContent(object):
"""
An abstraction of content in Jingle sessions
@@ -106,6 +112,9 @@ class JingleContent(object):
payload=payload)
def send_candidate(self, candidate):
+ """
+ Send a transport candidate for a previously defined transport.
+ """
content = self.__content()
content.addChild(self.transport.make_transport([candidate]))
self.session.send_transport_info(content)
diff --git a/src/common/jingle_rtp.py b/src/common/jingle_rtp.py
index e64c175c0..2795e32ad 100644
--- a/src/common/jingle_rtp.py
+++ b/src/common/jingle_rtp.py
@@ -19,11 +19,12 @@ import gobject
import xmpp
import farsight, gst
+from glib import GError
import gajim
from jingle_transport import JingleTransportICEUDP
-from jingle_content import contents, JingleContent
+from jingle_content import contents, JingleContent, FailedApplication
class JingleRTPContent(JingleContent):
@@ -35,12 +36,12 @@ class JingleRTPContent(JingleContent):
self._dtmf_running = False
self.farsight_media = {'audio': farsight.MEDIA_TYPE_AUDIO,
'video': farsight.MEDIA_TYPE_VIDEO}[media]
- self.got_codecs = False
self.candidates_ready = False # True when local candidates are prepared
self.callbacks['session-initiate'] += [self.__on_remote_codecs]
self.callbacks['content-add'] += [self.__on_remote_codecs]
+ self.callbacks['description-info'] += [self.__on_remote_codecs]
self.callbacks['content-accept'] += [self.__on_remote_codecs,
self.__on_content_accept]
self.callbacks['session-accept'] += [self.__on_remote_codecs,
@@ -59,7 +60,7 @@ class JingleRTPContent(JingleContent):
# conference
self.conference = gst.element_factory_make('fsrtpconference')
- self.conference.set_property("sdes-cname", self.session.ourjid)
+ self.conference.set_property('sdes-cname', self.session.ourjid)
self.pipeline.add(self.conference)
self.funnel = None
@@ -69,8 +70,16 @@ class JingleRTPContent(JingleContent):
# FIXME: Consider a workaround, here...
# pidgin and telepathy-gabble don't follow the XEP, and it won't work
# due to bad controlling-mode
- params = {'controlling-mode': self.session.weinitiate,# 'debug': False}
- 'stun-ip': '69.0.208.27', 'debug': False}
+ params = {'controlling-mode': self.session.weinitiate, 'debug': False}
+ stun_server = gajim.config.get('stun-server')
+ if stun_server:
+ try:
+ ip = socket.getaddrinfo(stun_server, 0, socket.AF_UNSPEC,
+ socket.SOCK_STREAM)[0][4][0]
+ except socket.gaierror, (errnum, errstr):
+ log.warn('Lookup of stun ip failed: %s' % errstr)
+ else:
+ params['stun-ip'] = ip
self.p2pstream = self.p2psession.new_stream(participant,
farsight.DIRECTION_RECV, 'nice', params)
@@ -79,6 +88,18 @@ class JingleRTPContent(JingleContent):
return (JingleContent.is_ready(self) and self.candidates_ready
and self.p2psession.get_property('codecs-ready'))
+ def make_bin_from_config(self, config_key, pipeline, text):
+ try:
+ bin = gst.parse_bin_from_description(pipeline
+ % gajim.config.get(config_key), True)
+ return bin
+ except GError, error_str:
+ self.session.connection.dispatch('ERROR',
+ (_("%s configuration error") % text.capitalize(),
+ _("Couldn't setup %s. Check your configuration.\n\nError was:\n%s")
+ % (text, error_str)))
+ raise FailedApplication
+
def add_remote_candidates(self, candidates):
JingleContent.add_remote_candidates(self, candidates)
# FIXME: connectivity should not be etablished yet
@@ -87,6 +108,9 @@ class JingleRTPContent(JingleContent):
self.p2pstream.set_remote_candidates(candidates)
def batch_dtmf(self, events):
+ """
+ Send several DTMF tones
+ """
if self._dtmf_running:
raise Exception # TODO: Proper exception
self._dtmf_running = True
@@ -177,8 +201,6 @@ class JingleRTPContent(JingleContent):
"""
Get peer codecs from what we get from peer
"""
- if self.got_codecs:
- return
codecs = []
for codec in content.getTag('description').iterTags('payload-type'):
@@ -197,7 +219,6 @@ class JingleRTPContent(JingleContent):
# glib.GError: There was no intersection between the remote codecs and
# the local ones
self.p2pstream.set_remote_codecs(codecs)
- self.got_codecs = True
def iter_codecs(self):
codecs = self.p2psession.get_property('codecs')
@@ -252,17 +273,12 @@ class JingleAudio(JingleRTPContent):
self.p2psession.set_codec_preferences(codecs)
# the local parts
- try:
- self.sink = gst.parse_bin_from_description(gajim.config.get('audio_output_device'), True)
- except:
- self.session.connection.dispatch('ERROR', (_("Audio configuration error"),
- _("Couldn't setup audio output. Check your audio configuration.")))
+ # TODO: Add queues?
+ src_bin = self.make_bin_from_config('audio_input_device',
+ '%s ! audioconvert', _("audio input"))
- try:
- src_bin = gst.parse_bin_from_description(gajim.config.get('audio_input_device'), True)
- except:
- self.session.connection.dispatch('ERROR', (_("Audio configuration error"),
- _("Couldn't setup audio input. Check your audio configuration.")))
+ self.sink = self.make_bin_from_config('audio_output_device',
+ 'audioconvert ! %s', _("audio output"))
self.mic_volume = src_bin.get_by_name('gajim_vol')
self.mic_volume.set_property('volume', 1)
@@ -290,25 +306,19 @@ class JingleVideo(JingleRTPContent):
JingleRTPContent.setup_stream(self)
# the local parts
- try:
- src_bin = gst.parse_bin_from_description(gajim.config.get('video_input_device'), True)
- except:
- self.session.connection.dispatch('ERROR', (_("Video configuration error"),
- _("Couldn't setup video input. Check your video configuration.")))
- caps = gst.element_factory_make('capsfilter')
- caps.set_property('caps', gst.caps_from_string('video/x-raw-yuv, width=320, height=240'))
+ src_bin = self.make_bin_from_config('video_input_device',
+ '%s ! videoscale ! ffmpegcolorspace', _("video input"))
+ #caps = gst.element_factory_make('capsfilter')
+ #caps.set_property('caps', gst.caps_from_string('video/x-raw-yuv, width=320, height=240'))
- self.pipeline.add(src_bin, caps)
- src_bin.link(caps)
+ self.pipeline.add(src_bin)#, caps)
+ #src_bin.link(caps)
- try:
- self.sink = gst.parse_bin_from_description(gajim.config.get('video_output_device'), True)
- except:
- self.session.connection.dispatch('ERROR', (_("Video configuration error"),
- _("Couldn't setup video output. Check your video configuration.")))
+ self.sink = self.make_bin_from_config('video_output_device',
+ '%s ! videoscale ! ffmpegcolorspace', _("video output"))
self.pipeline.add(self.sink)
- caps.get_pad('src').link(self.p2psession.get_property('sink-pad'))
+ src_bin.get_pad('src').link(self.p2psession.get_property('sink-pad'))
self.p2pstream.connect('src-pad-added', self._on_src_pad_added)
# The following is needed for farsight to process ICE requests:
diff --git a/src/common/jingle_session.py b/src/common/jingle_session.py
index 5fcc19029..806207157 100644
--- a/src/common/jingle_session.py
+++ b/src/common/jingle_session.py
@@ -16,12 +16,11 @@ Handles Jingle sessions (XEP 0166)
"""
#TODO:
-# * Have JingleContent here
# * 'senders' attribute of 'content' element
# * security preconditions
# * actions:
# - content-modify
-# - description-info, session-info
+# - session-info
# - security-info
# - transport-accept, transport-reject
# - Tie-breaking
@@ -30,7 +29,7 @@ Handles Jingle sessions (XEP 0166)
import gajim #Get rid of that?
import xmpp
from jingle_transport import get_jingle_transport
-from jingle_content import get_jingle_content
+from jingle_content import get_jingle_content, FailedApplication
# FIXME: Move it to JingleSession.States?
class JingleStates(object):
@@ -55,7 +54,8 @@ class TieBreak(Exception):
class JingleSession(object):
"""
- This represents one jingle session
+ This represents one jingle session, that is, one or more content types
+ negotiated between an initiator and a responder.
"""
def __init__(self, con, weinitiate, jid, sid=None):
@@ -394,8 +394,8 @@ class JingleSession(object):
raise OutOfOrder
parse_result = self.__parse_contents(jingle)
- contents = parse_result[2]
- rejected_contents = parse_result[3]
+ contents = parse_result[0]
+ rejected_contents = parse_result[1]
for name, creator in rejected_contents:
# TODO
@@ -426,21 +426,13 @@ class JingleSession(object):
# error.
# Lets check what kind of jingle session does the peer want
- contents_ok, transports_ok, contents, pouet = self.__parse_contents(jingle)
+ contents, contents_rejected, reason = self.__parse_contents(jingle)
# If there's no content we understand...
- if not contents_ok:
+ if not contents:
# TODO: http://xmpp.org/extensions/xep-0166.html#session-terminate
reason = xmpp.Node('reason')
- reason.setTag('unsupported-applications')
- self.__ack(stanza, jingle, error, action)
- self._session_terminate(reason)
- raise xmpp.NodeProcessed
-
- if not transports_ok:
- # TODO: http://xmpp.org/extensions/xep-0166.html#session-terminate
- reason = xmpp.Node('reason')
- reason.setTag('unsupported-transports')
+ reason.setTag(reason)
self.__ack(stanza, jingle, error, action)
self._session_terminate(reason)
raise xmpp.NodeProcessed
@@ -485,26 +477,37 @@ class JingleSession(object):
# TODO: Needs some reworking
contents = []
contents_rejected = []
- contents_ok = False
- transports_ok = False
+ reasons = set()
for element in jingle.iterTags('content'):
transport = get_jingle_transport(element.getTag('transport'))
content_type = get_jingle_content(element.getTag('description'))
if content_type:
- contents_ok = True
- if transport:
- content = content_type(self, transport)
- self.add_content(element['name'],
- content, 'peer')
- contents.append((content.media,))
- transports_ok = True
- else:
- contents_rejected.append((element['name'], 'peer'))
+ try:
+ if transport:
+ content = content_type(self, transport)
+ self.add_content(element['name'],
+ content, 'peer')
+ contents.append((content.media,))
+ else:
+ reasons.add('unsupported-transports')
+ contents_rejected.append((element['name'], 'peer'))
+ except FailedApplication:
+ reasons.add('failed-application')
else:
contents_rejected.append((element['name'], 'peer'))
+ failed.add('unsupported-applications')
- return (contents_ok, transports_ok, contents, contents_rejected)
+ failure_reason = None
+
+ # Store the first reason of failure
+ for reason in ('failed-application', 'unsupported-transports',
+ 'unsupported-applications'):
+ if reason in reasons:
+ failure_reason = reason
+ break
+
+ return (contents, contents_rejected, failure_reason)
def __dispatch_error(self, error, jingle_error=None, text=None):
if jingle_error:
diff --git a/src/common/logger.py b/src/common/logger.py
index c484246db..507b29cfa 100644
--- a/src/common/logger.py
+++ b/src/common/logger.py
@@ -38,13 +38,7 @@ from cStringIO import StringIO
import exceptions
import gajim
-try:
- import sqlite3 as sqlite # python 2.5
-except ImportError:
- try:
- from pysqlite2 import dbapi2 as sqlite
- except ImportError:
- raise exceptions.PysqliteNotAvailable
+import sqlite3 as sqlite
import configpaths
LOG_DB_PATH = configpaths.gajimpaths['LOG_DB']
diff --git a/src/common/multimedia_helpers.py b/src/common/multimedia_helpers.py
index 59d8b635f..4a2a4fb2e 100644
--- a/src/common/multimedia_helpers.py
+++ b/src/common/multimedia_helpers.py
@@ -78,11 +78,9 @@ class VideoInputManager(DeviceManager):
self.detect_element('videotestsrc', _('Video test'),
'%s is-live=true')
# Auto src
- self.detect_element('autovideosrc', _('Autodetect'),
- '%s ! videoscale ! ffmpegcolorspace')
+ self.detect_element('autovideosrc', _('Autodetect'))
# V4L2 src ; TODO: Figure out why it doesn't work
- self.detect_element('v4l2src', _('V4L2: %s'),
- '%s ! videoscale ! ffmpegcolorspace')
+ self.detect_element('v4l2src', _('V4L2: %s'))
# Funny things, just to test...
# self.devices['GOOM'] = 'audiotestsrc ! goom'
# self.devices['screen'] = 'ximagesrc'
diff --git a/src/common/optparser.py b/src/common/optparser.py
index 33aaa8c9d..fa7b99daa 100644
--- a/src/common/optparser.py
+++ b/src/common/optparser.py
@@ -34,14 +34,7 @@ from common import gajim
from common import helpers
from common import caps
-import exceptions
-try:
- import sqlite3 as sqlite # python 2.5
-except ImportError:
- try:
- from pysqlite2 import dbapi2 as sqlite
- except ImportError:
- raise exceptions.PysqliteNotAvailable
+import sqlite3 as sqlite
import logger
class OptionsParser:
diff --git a/src/config.py b/src/config.py
index 2ff9ff73b..5b7a0c8ce 100644
--- a/src/config.py
+++ b/src/config.py
@@ -59,7 +59,12 @@ from common.zeroconf import connection_zeroconf
from common import dataforms
from common import GnuPG
-from common.multimedia_helpers import AudioInputManager, AudioOutputManager, VideoInputManager, VideoOutputManager
+try:
+ from common.multimedia_helpers import AudioInputManager, AudioOutputManager
+ from common.multimedia_helpers import VideoInputManager, VideoOutputManager
+ HAS_GST = True
+except ImportError:
+ HAS_GST = False
from common.exceptions import GajimGeneralException
@@ -416,8 +421,7 @@ class PreferencesWindow:
buf = self.xml.get_widget('msg_textview').get_buffer()
buf.connect('changed', self.on_msg_textview_changed)
- ### Style tab ###
- # Audio
+ ### Audio / Video tab ###
def create_av_combobox(opt_name, device_dict):
combobox = self.xml.get_widget(opt_name + '_combobox')
cell = gtk.CellRendererText()
@@ -431,10 +435,21 @@ class PreferencesWindow:
if gajim.config.get(opt_name + '_device') == value:
combobox.set_active(index)
- create_av_combobox('audio_input', AudioInputManager().get_devices())
- create_av_combobox('audio_output', AudioOutputManager().get_devices())
- create_av_combobox('video_input', VideoInputManager().get_devices())
- create_av_combobox('video_output', VideoOutputManager().get_devices())
+ if HAS_GST:
+ create_av_combobox('audio_input', AudioInputManager().get_devices())
+ create_av_combobox('audio_output', AudioOutputManager().get_devices())
+ create_av_combobox('video_input', VideoInputManager().get_devices())
+ create_av_combobox('video_output', VideoOutputManager().get_devices())
+ else:
+ for opt_name in ('audio_input', 'audio_output', 'video_input',
+ 'video_output'):
+ combobox = self.xml.get_widget(opt_name + '_combobox')
+ combobox.set_sensitive(False)
+
+ # Connection
+ entry = self.xml.get_widget('stun_server_entry')
+ entry.set_text(gajim.config.get('stun_server'))
+
### Advanced tab ###
# open links with
if os.name == 'nt':
@@ -1046,6 +1061,9 @@ class PreferencesWindow:
def on_video_output_combobox_changed(self, widget):
self.on_av_combobox_changed(widget, 'video_output')
+ def stun_server_entry_changed(self, widget):
+ gajim.config.set('stun_server', widget.get_text().decode('utf-8'))
+
def on_applications_combobox_changed(self, widget):
gajim.config.set('autodetect_browser_mailer', False)
if widget.get_active() == 4:
@@ -1419,8 +1437,7 @@ class AccountsWindow:
self.accounts_treeview = self.xml.get_widget('accounts_treeview')
self.remove_button = self.xml.get_widget('remove_button')
self.rename_button = self.xml.get_widget('rename_button')
- path_to_kbd_input_img = os.path.join(gajim.DATA_DIR, 'pixmaps',
- 'kbd_input.png')
+ path_to_kbd_input_img = gtkgui_helpers.get_icon_path('gajim-kbd_input')
img = self.xml.get_widget('rename_image')
img.set_from_file(path_to_kbd_input_img)
self.notebook = self.xml.get_widget('notebook')
@@ -3354,7 +3371,7 @@ class AccountCreationWizardWindow:
if self.modify:
img.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_DIALOG)
else:
- path_to_file = os.path.join(gajim.DATA_DIR, 'pixmaps', 'gajim.png')
+ path_to_file = gtkgui_helpers.get_icon_path('gajim', 48)
img.set_from_file(path_to_file)
self.show_vcard_checkbutton.set_active(not self.modify)
self.notebook.set_current_page(6) # show finish page
diff --git a/src/conversation_textview.py b/src/conversation_textview.py
index 292d524c2..b7ee783ab 100644
--- a/src/conversation_textview.py
+++ b/src/conversation_textview.py
@@ -169,10 +169,9 @@ class ConversationTextview(gobject.GObject):
)
)
- FOCUS_OUT_LINE_PIXBUF = gtk.gdk.pixbuf_new_from_file(os.path.join(
- gajim.DATA_DIR, 'pixmaps', 'muc_separator.png'))
- XEP0184_WARNING_PIXBUF = gtk.gdk.pixbuf_new_from_file(os.path.join(
- gajim.DATA_DIR, 'pixmaps', 'receipt_missing.png'))
+ FOCUS_OUT_LINE_PIXBUF = gtkgui_helpers.get_icon_pixmap('gajim-muc_separator')
+ XEP0184_WARNING_PIXBUF = gtkgui_helpers.get_icon_pixmap(
+ 'gajim-receipt_missing')
# smooth scroll constants
MAX_SCROLL_TIME = 0.4 # seconds
diff --git a/src/dialogs.py b/src/dialogs.py
index a82f3a8af..e9ed3344f 100644
--- a/src/dialogs.py
+++ b/src/dialogs.py
@@ -1190,8 +1190,7 @@ class AboutDialog:
dlg.props.wrap_license = True
- pixbuf = gtk.gdk.pixbuf_new_from_file(os.path.join(
- gajim.DATA_DIR, 'pixmaps', 'gajim_about.png'))
+ pixbuf = gtkgui_helpers.get_icon_pixmap('gajim-about', 64)
dlg.set_logo(pixbuf)
#here you write your name in the form Name FamilyName
@@ -2463,9 +2462,7 @@ class PopupNotificationWindow:
# default image
if not path_to_image:
- path_to_image = os.path.abspath(
- os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
- 'chat_msg_recv.png')) # img to display
+ path_to_image = gtkgui_helpers.get_icon_path('gajim-chat_msg_recv', 48)
if event_type == _('Contact Signed In'):
bg_color = 'limegreen'
@@ -4540,43 +4537,37 @@ class ESessionInfoWindow:
def update_info(self):
labeltext = _('''Your chat session with %(jid)s is encrypted.\n\nThis session's Short Authentication String is %(sas)s.''') % {'jid': self.session.jid, 'sas': self.session.sas}
- dir_ = os.path.join(gajim.DATA_DIR, 'pixmaps')
if self.session.verified_identity:
labeltext += '\n\n' + _('''You have already verified this contact's identity.''')
- security_image = 'security-high-big.png'
+ security_image = 'gajim-security_high'
if self.session.control:
self.session.control._show_lock_image(True, 'E2E', True,
- self.session.is_loggable(), True)
+ self.session.is_loggable(), True)
verification_status = _('''Contact's identity verified''')
self.window.set_title(verification_status)
self.xml.get_widget('verification_status_label').set_markup(
- '' +
- verification_status +
- '')
+ '%s' % verification_status)
self.xml.get_widget('dialog-action_area1').set_no_show_all(True)
self.button_label.set_text(_('Verify again...'))
else:
if self.session.control:
self.session.control._show_lock_image(True, 'E2E', True,
- self.session.is_loggable(), False)
+ self.session.is_loggable(), False)
labeltext += '\n\n' + _('''To be certain that only the expected person can read your messages or send you messages, you need to verify their identity by clicking the button below.''')
- security_image = 'security-low-big.png'
+ security_image = 'gajim-security_low'
verification_status = _('''Contact's identity NOT verified''')
self.window.set_title(verification_status)
self.xml.get_widget('verification_status_label').set_markup(
- '' +
- verification_status +
- '')
+ '%s' % verification_status)
self.button_label.set_text(_('Verify...'))
- path = os.path.join(dir_, security_image)
- filename = os.path.abspath(path)
- self.security_image.set_from_file(filename)
+ path = gtkgui_helpers.get_icon_path(security_image, 32)
+ self.security_image.set_from_file(path)
self.xml.get_widget('info_display').set_markup(labeltext)
@@ -4622,13 +4613,13 @@ class GPGInfoWindow:
verification_status = _('''Contact's identity NOT verified''')
info = _('The contact\'s key (%s) does not match the key '
'assigned in Gajim.') % keyID[:8]
- image = 'security-low-big.png'
+ image = 'gajim-security_low'
elif not keyID:
# No key assigned nor a key is used by remote contact
verification_status = _('No GPG key assigned')
info = _('No GPG key is assigned to this contact. So you cannot '
'encrypt messages.')
- image = 'security-low-big.png'
+ image = 'gajim-security_low'
else:
error = gajim.connections[account].gpg.encrypt('test', [keyID])[1]
if error:
@@ -4636,21 +4627,19 @@ class GPGInfoWindow:
info = _('GPG key is assigned to this contact, but you do not '
'trust his key, so message cannot be encrypted. Use '
'your GPG client to trust this key.')
- image = 'security-low-big.png'
+ image = 'gajim-security_low'
else:
verification_status = _('''Contact's identity verified''')
info = _('GPG Key is assigned to this contact, and you trust his '
'key, so messages will be encrypted.')
- image = 'security-high-big.png'
+ image = 'gajim-security_high'
status_label.set_markup('%s' % \
verification_status)
info_label.set_markup(info)
- dir_ = os.path.join(gajim.DATA_DIR, 'pixmaps')
- path = os.path.join(dir_, image)
- filename = os.path.abspath(path)
- security_image.set_from_file(filename)
+ path = gtkgui_helpers.get_icon_path(image, 32)
+ security_image.set_from_file(path)
xml.signal_autoconnect(self)
self.window.show_all()
diff --git a/src/disco.py b/src/disco.py
index da9021dd4..8e5bc1e92 100644
--- a/src/disco.py
+++ b/src/disco.py
@@ -73,44 +73,44 @@ def _gen_agent_type_info():
(0, 0): (None, None),
# Jabber server
- ('server', 'im'): (ToplevelAgentBrowser, 'jabber.png'),
- ('services', 'jabber'): (ToplevelAgentBrowser, 'jabber.png'),
- ('hierarchy', 'branch'): (AgentBrowser, 'jabber.png'),
+ ('server', 'im'): (ToplevelAgentBrowser, 'jabber'),
+ ('services', 'jabber'): (ToplevelAgentBrowser, 'jabber'),
+ ('hierarchy', 'branch'): (AgentBrowser, 'jabber'),
# Services
- ('conference', 'text'): (MucBrowser, 'conference.png'),
- ('headline', 'rss'): (AgentBrowser, 'rss.png'),
- ('headline', 'weather'): (False, 'weather.png'),
- ('gateway', 'weather'): (False, 'weather.png'),
- ('_jid', 'weather'): (False, 'weather.png'),
- ('gateway', 'sip'): (False, 'sip.png'),
- ('directory', 'user'): (None, 'jud.png'),
- ('pubsub', 'generic'): (PubSubBrowser, 'pubsub.png'),
- ('pubsub', 'service'): (PubSubBrowser, 'pubsub.png'),
- ('proxy', 'bytestreams'): (None, 'bytestreams.png'), # Socks5 FT proxy
- ('headline', 'newmail'): (ToplevelAgentBrowser, 'mail.png'),
+ ('conference', 'text'): (MucBrowser, 'conference'),
+ ('headline', 'rss'): (AgentBrowser, 'rss'),
+ ('headline', 'weather'): (False, 'weather'),
+ ('gateway', 'weather'): (False, 'weather'),
+ ('_jid', 'weather'): (False, 'weather'),
+ ('gateway', 'sip'): (False, 'sip'),
+ ('directory', 'user'): (None, 'jud'),
+ ('pubsub', 'generic'): (PubSubBrowser, 'pubsub'),
+ ('pubsub', 'service'): (PubSubBrowser, 'pubsub'),
+ ('proxy', 'bytestreams'): (None, 'bytestreams'), # Socks5 FT proxy
+ ('headline', 'newmail'): (ToplevelAgentBrowser, 'mail'),
# Transports
- ('conference', 'irc'): (ToplevelAgentBrowser, 'irc.png'),
- ('_jid', 'irc'): (False, 'irc.png'),
- ('gateway', 'aim'): (False, 'aim.png'),
- ('_jid', 'aim'): (False, 'aim.png'),
- ('gateway', 'gadu-gadu'): (False, 'gadu-gadu.png'),
- ('_jid', 'gadugadu'): (False, 'gadu-gadu.png'),
- ('gateway', 'http-ws'): (False, 'http-ws.png'),
- ('gateway', 'icq'): (False, 'icq.png'),
- ('_jid', 'icq'): (False, 'icq.png'),
- ('gateway', 'msn'): (False, 'msn.png'),
- ('_jid', 'msn'): (False, 'msn.png'),
- ('gateway', 'sms'): (False, 'sms.png'),
- ('_jid', 'sms'): (False, 'sms.png'),
- ('gateway', 'smtp'): (False, 'mail.png'),
- ('gateway', 'yahoo'): (False, 'yahoo.png'),
- ('_jid', 'yahoo'): (False, 'yahoo.png'),
- ('gateway', 'mrim'): (False, 'mrim.png'),
- ('_jid', 'mrim'): (False, 'mrim.png'),
- ('gateway', 'facebook'): (False, 'facebook.png'),
- ('_jid', 'facebook'): (False, 'facebook.png'),
+ ('conference', 'irc'): (ToplevelAgentBrowser, 'irc'),
+ ('_jid', 'irc'): (False, 'irc'),
+ ('gateway', 'aim'): (False, 'aim'),
+ ('_jid', 'aim'): (False, 'aim'),
+ ('gateway', 'gadu-gadu'): (False, 'gadu_gadu'),
+ ('_jid', 'gadugadu'): (False, 'gadu_gadu'),
+ ('gateway', 'http-ws'): (False, 'http_ws'),
+ ('gateway', 'icq'): (False, 'icq'),
+ ('_jid', 'icq'): (False, 'icq'),
+ ('gateway', 'msn'): (False, 'msn'),
+ ('_jid', 'msn'): (False, 'msn'),
+ ('gateway', 'sms'): (False, 'sms'),
+ ('_jid', 'sms'): (False, 'sms'),
+ ('gateway', 'smtp'): (False, 'mail'),
+ ('gateway', 'yahoo'): (False, 'yahoo'),
+ ('_jid', 'yahoo'): (False, 'yahoo'),
+ ('gateway', 'mrim'): (False, 'mrim'),
+ ('_jid', 'mrim'): (False, 'mrim'),
+ ('gateway', 'facebook'): (False, 'facebook'),
+ ('_jid', 'facebook'): (False, 'facebook'),
}
# Category type to "human-readable" description string, and sort priority
@@ -291,13 +291,12 @@ class ServicesCache:
info = _agent_type_info[(0, 0)]
filename = info[1]
if not filename: # we don't have an image to show for this type
- filename = 'jabber.png'
+ filename = 'jabber'
# Use the cache if possible
if filename in _icon_cache:
return _icon_cache[filename]
# Or load it
- filepath = os.path.join(gajim.DATA_DIR, 'pixmaps', 'agents', filename)
- pix = gtk.gdk.pixbuf_new_from_file(filepath)
+ pix = gtkgui_helpers.get_icon_pixmap('gajim-agent-' + filename, size=32)
# Store in cache
_icon_cache[filename] = pix
return pix
diff --git a/src/gajim.py b/src/gajim.py
index a2e58f4e7..d0ed38f20 100644
--- a/src/gajim.py
+++ b/src/gajim.py
@@ -322,8 +322,7 @@ def pid_alive():
return True
if pid_alive():
- path_to_file = os.path.join(gajim.DATA_DIR, 'pixmaps/gajim.png')
- pix = gtk.gdk.pixbuf_new_from_file(path_to_file)
+ pix = gtkgui_helpers.get_icon_pixmap('gajim', 48)
gtk.window_set_default_icon(pix) # set the icon to all newly opened wind
pritext = _('Gajim is already running')
sectext = _('Another instance of Gajim seems to be running\nRun anyway?')
diff --git a/src/gtkgui_helpers.py b/src/gtkgui_helpers.py
index ac9fa157e..01ec5d605 100644
--- a/src/gtkgui_helpers.py
+++ b/src/gtkgui_helpers.py
@@ -82,6 +82,15 @@ def get_icon_path(icon_name, size=16):
except gobject.GError, e:
log.error("Unable to find icon %s: %s" % (icon_name, str(e)))
+def add_image_to_menuitem(menuitem, icon_name):
+ img = gtk.Image()
+ path_img = get_icon_path(icon_name)
+ img.set_from_file(path_img)
+ menuitem.set_image(img)
+
+def add_image_to_button(button, icon_name):
+ add_image_to_menuitem(button, icon_name)
+
GLADE_DIR = os.path.join(gajim.DATA_DIR, 'glade')
def get_glade(file_name, root = None):
file_path = os.path.join(GLADE_DIR, file_name)
diff --git a/src/gui_interface.py b/src/gui_interface.py
index 859b9a9d1..337e53924 100644
--- a/src/gui_interface.py
+++ b/src/gui_interface.py
@@ -199,9 +199,7 @@ class Interface:
def handle_event_connection_lost(self, account, array):
# ('CONNECTION_LOST', account, [title, text])
- path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
- 'connection_lost.png')
- path = gtkgui_helpers.get_path_to_generic_or_avatar(path)
+ path = gtkgui_helpers.get_icon_path('gajim-connection_lost', 48)
notify.popup(_('Connection Failed'), account, account,
'connection_failed', path, array[0], array[1])
@@ -593,9 +591,7 @@ class Interface:
self.add_event(account, jid, 'subscription_request', (text, nick))
if helpers.allow_showing_notification(account):
- path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
- 'subscription_request.png')
- path = gtkgui_helpers.get_path_to_generic_or_avatar(path)
+ path = gtkgui_helpers.get_icon_path('gajim-subscription_request', 48)
event_type = _('Subscription request')
notify.popup(event_type, jid, account, 'subscription_request', path,
event_type, jid)
@@ -653,13 +649,12 @@ class Interface:
if helpers.allow_popup_window(account) or not self.systray_enabled:
self.show_unsubscribed_dialog(account, contact)
+ return
self.add_event(account, jid, 'unsubscribed', contact)
if helpers.allow_showing_notification(account):
- path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
- 'unsubscribed.png')
- path = gtkgui_helpers.get_path_to_generic_or_avatar(path)
+ path = gtkgui_helpers.get_icon_path('gajim-unsubscribed', 48)
event_type = _('Unsubscribed')
notify.popup(event_type, jid, account, 'unsubscribed', path,
event_type, jid)
@@ -1117,9 +1112,7 @@ class Interface:
array[3], array[4]))
if helpers.allow_showing_notification(account):
- path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
- 'gc_invitation.png')
- path = gtkgui_helpers.get_path_to_generic_or_avatar(path)
+ path = gtkgui_helpers.get_icon_path('gajim-gc_invitation', 48)
event_type = _('Groupchat Invitation')
notify.popup(event_type, jid, account, 'gc-invitation', path,
event_type, room_jid)
@@ -1139,7 +1132,7 @@ class Interface:
sectext += _('You are currently connected without your OpenPGP key.')
dialogs.WarningDialog(_('Your passphrase is incorrect'), sectext)
else:
- path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'warning.png')
+ path = gtkgui_helpers.get_icon_path('gajim-warning', 48)
notify.popup('warning', account, account, 'warning', path,
_('OpenGPG Passphrase Incorrect'),
_('You are currently connected without your OpenPGP key.'))
@@ -1276,8 +1269,7 @@ class Interface:
self.add_event(account, jid, 'file-send-error', file_props)
if helpers.allow_showing_notification(account):
- img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', 'ft_error.png')
- path = gtkgui_helpers.get_path_to_generic_or_avatar(img)
+ path = gtkgui_helpers.get_icon_path('gajim-ft_error', 48)
event_type = _('File Transfer Error')
notify.popup(event_type, jid, account, 'file-send-error', path,
event_type, file_props['name'])
@@ -1287,8 +1279,7 @@ class Interface:
gmail_new_messages = int(array[1])
gmail_messages_list = array[2]
if gajim.config.get('notify_on_new_gmail_email'):
- img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
- 'new_email_recv.png')
+ path = gtkgui_helpers.get_icon_path('gajim-new_email_recv', 48)
title = _('New mail on %(gmail_mail_address)s') % \
{'gmail_mail_address': jid}
text = i18n.ngettext('You have %d new mail conversation',
@@ -1311,7 +1302,6 @@ class Interface:
if gajim.config.get_per('soundevents', 'gmail_received', 'enabled'):
helpers.play_sound('gmail_received')
- path = gtkgui_helpers.get_path_to_generic_or_avatar(img)
notify.popup(_('New E-mail'), jid, account, 'gmail',
path_to_image=path, title=title,
text=text)
@@ -1343,9 +1333,7 @@ class Interface:
if helpers.allow_showing_notification(account):
# check if we should be notified
- img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', 'ft_error.png')
-
- path = gtkgui_helpers.get_path_to_generic_or_avatar(img)
+ path = gtkgui_helpers.get_icon_path('gajim-ft_error', 48)
event_type = _('File Transfer Error')
notify.popup(event_type, jid, account, msg_type, path,
title = event_type, text = file_props['name'])
@@ -1374,11 +1362,9 @@ class Interface:
self.add_event(account, jid, 'file-request', file_props)
if helpers.allow_showing_notification(account):
- img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
- 'ft_request.png')
+ path = gtkgui_helpers.get_icon_path('gajim-ft_request', 48)
txt = _('%s wants to send you a file.') % gajim.get_name_from_jid(
account, jid)
- path = gtkgui_helpers.get_path_to_generic_or_avatar(img)
event_type = _('File Transfer Request')
notify.popup(event_type, jid, account, 'file-request',
path_to_image = path, title = event_type, text = txt)
@@ -1449,11 +1435,11 @@ class Interface:
if event_type == _('File Transfer Completed'):
txt = _('You successfully received %(filename)s from %(name)s.')\
% {'filename': filename, 'name': name}
- img = 'ft_done.png'
+ img_name = 'gajim-ft_done'
else: # ft stopped
txt = _('File transfer of %(filename)s from %(name)s stopped.')\
% {'filename': filename, 'name': name}
- img = 'ft_stopped.png'
+ img_name = 'gajim-ft_stopped'
else:
receiver = file_props['receiver']
if hasattr(receiver, 'jid'):
@@ -1466,23 +1452,23 @@ class Interface:
if event_type == _('File Transfer Completed'):
txt = _('You successfully sent %(filename)s to %(name)s.')\
% {'filename': filename, 'name': name}
- img = 'ft_done.png'
+ img_name = 'gajim-ft_done'
else: # ft stopped
txt = _('File transfer of %(filename)s to %(name)s stopped.')\
% {'filename': filename, 'name': name}
- img = 'ft_stopped.png'
- img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', img)
- path = gtkgui_helpers.get_path_to_generic_or_avatar(img)
+ img_name = 'gajim-ft_stopped'
+ path = gtkgui_helpers.get_icon_path(img_name, 48)
else:
txt = ''
+ path = ''
if gajim.config.get('notify_on_file_complete') and \
(gajim.config.get('autopopupaway') or \
gajim.connections[account].connected in (2, 3)):
# we want to be notified and we are online/chat or we don't mind
# bugged when away/na/busy
- notify.popup(event_type, jid, account, msg_type, path_to_image = path,
- title = event_type, text = txt)
+ notify.popup(event_type, jid, account, msg_type, path_to_image=path,
+ title=event_type, text=txt)
def handle_event_stanza_arrived(self, account, stanza):
if account not in self.instances:
@@ -1766,11 +1752,9 @@ class Interface:
if helpers.allow_showing_notification(account):
# TODO: we should use another pixmap ;-)
- img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
- 'ft_request.png')
txt = _('%s wants to start a voice chat.') % gajim.get_name_from_jid(
account, peerjid)
- path = gtkgui_helpers.get_path_to_generic_or_avatar(img)
+ path = gtkgui_helpers.get_icon_path('gajim-mic_active', 48)
event_type = _('Voice Chat Request')
notify.popup(event_type, peerjid, account, 'jingle-incoming',
path_to_image = path, title = event_type, text = txt)
@@ -2778,8 +2762,8 @@ class Interface:
if status in ('chat', 'away', 'xa', 'dnd', 'invisible', 'offline'):
status = status + '.png'
elif status == 'online':
- prefix = os.path.join(gajim.DATA_DIR, 'pixmaps')
- status = 'gajim.png'
+ prefix = ''
+ status = gtkgui_helpers.get_icon_path('gajim', 32)
path = os.path.join(prefix, status)
try:
obj = bus.get_object('com.google.code.Awn', '/com/google/code/Awn')
@@ -3382,8 +3366,7 @@ class Interface:
import statusicon
self.systray = statusicon.StatusIcon()
- path_to_file = os.path.join(gajim.DATA_DIR, 'pixmaps', 'gajim.png')
- pix = gtk.gdk.pixbuf_new_from_file(path_to_file)
+ pix = gtkgui_helpers.get_icon_pixmap('gajim', 32)
# set the icon to all windows
gtk.window_set_default_icon(pix)
diff --git a/src/gui_menu_builder.py b/src/gui_menu_builder.py
index f18354175..5fd799a99 100644
--- a/src/gui_menu_builder.py
+++ b/src/gui_menu_builder.py
@@ -207,11 +207,7 @@ def get_contact_menu(contact, account, use_multiple_contacts=True,
if not our_jid:
# add a special img for rename menuitem
- path_to_kbd_input_img = os.path.join(gajim.DATA_DIR, 'pixmaps',
- 'kbd_input.png')
- img = gtk.Image()
- img.set_from_file(path_to_kbd_input_img)
- rename_menuitem.set_image(img)
+ gtkgui_helpers.add_image_to_menuitem(rename_menuitem, 'gajim-kbd_input')
muc_icon = gtkgui_helpers.load_icon('muc_active')
if muc_icon:
diff --git a/src/history_manager.py b/src/history_manager.py
index 5d171b75c..13dd22a62 100644
--- a/src/history_manager.py
+++ b/src/history_manager.py
@@ -102,19 +102,12 @@ C_NICKNAME
) = range(2, 6)
-try:
- import sqlite3 as sqlite # python 2.5
-except ImportError:
- try:
- from pysqlite2 import dbapi2 as sqlite
- except ImportError:
- raise exceptions.PysqliteNotAvailable
+import sqlite3 as sqlite
class HistoryManager:
def __init__(self):
- path_to_file = os.path.join(gajim.DATA_DIR, 'pixmaps/gajim.png')
- pix = gtk.gdk.pixbuf_new_from_file(path_to_file)
+ pix = gtkgui_helpers.get_icon_pixmap('gajim')
gtk.window_set_default_icon(pix) # set the icon to all newly opened windows
if not os.path.exists(LOG_DB_PATH):
diff --git a/src/htmltextview.py b/src/htmltextview.py
index 8b65d8f87..35a289ebb 100644
--- a/src/htmltextview.py
+++ b/src/htmltextview.py
@@ -892,8 +892,10 @@ class HtmlTextView(gtk.TextView):
def on_text_buffer_mark_set(self, location, mark, unused_data):
bounds = self.get_buffer().get_selection_bounds()
if bounds:
- clipboard = self.get_clipboard(gtk.gdk.SELECTION_PRIMARY)
- clipboard.set_text(self.get_selected_text())
+ # textview can be hidden while we add a new line in it.
+ if self.has_screen():
+ clipboard = self.get_clipboard(gtk.gdk.SELECTION_PRIMARY)
+ clipboard.set_text(self.get_selected_text())
def get_selected_text(self):
bounds = self.get_buffer().get_selection_bounds()
@@ -939,12 +941,12 @@ if __name__ == '__main__':
htmlview = ConversationTextview(None)
- path_to_file = os.path.join(gajim.DATA_DIR, 'pixmaps', 'muc_separator.png')
+ path = gtkgui_helpers.get_icon_path('gajim-muc_separator')
# use this for hr
- htmlview.tv.focus_out_line_pixbuf = gtk.gdk.pixbuf_new_from_file(path_to_file)
-
+ htmlview.tv.focus_out_line_pixbuf = gtk.gdk.pixbuf_new_from_file(path)
tooltip = tooltips.BaseTooltip()
+
def on_textview_motion_notify_event(widget, event):
"""
Change the cursor to a hand when we are over a mail or an url
diff --git a/src/notify.py b/src/notify.py
index 587c4e292..37a7fd267 100644
--- a/src/notify.py
+++ b/src/notify.py
@@ -234,16 +234,16 @@ def notify(event, jid, account, parameters, advanced_notif_num=None):
show_image = 'online.png'
suffix = '_notif_size_colored'
transport_name = gajim.get_transport_name_from_jid(jid)
- img = None
+ img_path = None
if transport_name:
- img = os.path.join(helpers.get_transport_path(transport_name),
+ img_path = os.path.join(helpers.get_transport_path(transport_name),
'48x48', show_image)
- if not img or not os.path.isfile(img):
+ if not img_path or not os.path.isfile(img_path):
iconset = gajim.config.get('iconset')
- img = os.path.join(helpers.get_iconset_path(iconset), '48x48',
+ img_path = os.path.join(helpers.get_iconset_path(iconset), '48x48',
show_image)
- path = gtkgui_helpers.get_path_to_generic_or_avatar(img,
- jid = jid, suffix = suffix)
+ path = gtkgui_helpers.get_path_to_generic_or_avatar(img_path, jid=jid,
+ suffix=suffix)
if event == 'status_change':
title = _('%(nick)s Changed Status') % \
{'nick': gajim.get_name_from_jid(account, jid)}
@@ -273,16 +273,14 @@ def notify(event, jid, account, parameters, advanced_notif_num=None):
elif event == 'new_message':
if message_type == 'normal': # single message
event_type = _('New Single Message')
- img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
- 'single_msg_recv.png')
+ img_name = 'gajim-single_msg_recv'
title = _('New Single Message from %(nickname)s') % \
{'nickname': nickname}
text = message
elif message_type == 'pm': # private message
event_type = _('New Private Message')
room_name = gajim.get_nick_from_jid(jid)
- img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
- 'priv_msg_recv.png')
+ img_name = 'gajim-priv_msg_recv'
title = _('New Private Message from group chat %s') % room_name
if message:
text = _('%(nickname)s: %(message)s') % {'nickname': nickname,
@@ -292,14 +290,13 @@ def notify(event, jid, account, parameters, advanced_notif_num=None):
else: # chat message
event_type = _('New Message')
- img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
- 'chat_msg_recv.png')
+ img_name = 'gajim-chat_msg_recv'
title = _('New Message from %(nickname)s') % \
{'nickname': nickname}
text = message
- path = gtkgui_helpers.get_path_to_generic_or_avatar(img)
+ img_path = gtkgui_helpers.get_icon_path(img_name, 48)
popup(event_type, jid, account, message_type,
- path_to_image=path, title=title, text=text)
+ path_to_image=img_path, title=title, text=text)
if do_sound:
snd_file = None
@@ -342,9 +339,7 @@ def popup(event_type, jid, account, msg_type='', path_to_image=None, title=None,
"""
# default image
if not path_to_image:
- path_to_image = os.path.abspath(
- os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
- 'chat_msg_recv.png')) # img to display
+ path_to_image = gtkgui_helpers.get_icon_path('gajim-chat_msg_recv', 48)
if gajim.HAVE_INDICATOR and event_type in (_('New Message'),
_('New Single Message'), _('New Private Message')):
@@ -529,9 +524,8 @@ class DesktopNotification:
ntype = 'unsubscribed'
else:
# default failsafe values
- self.path_to_image = os.path.abspath(
- os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
- 'chat_msg_recv.png')) # img to display
+ self.path_to_image = gtkgui_helpers.get_icon_path(
+ 'gajim-chat_msg_recv', 48)
ntype = 'im' # Notification Type
self.notif = dbus_support.get_notifications_interface(self)
@@ -554,8 +548,7 @@ class DesktopNotification:
notification_text = ('
' \
'%(title)s
%(text)s') % {'title': self.title,
'text': self.text, 'image': self.path_to_image}
- gajim_icon = os.path.abspath(os.path.join(gajim.DATA_DIR, 'pixmaps',
- 'gajim.png'))
+ gajim_icon = gtkgui_helpers.get_icon_path('gajim', 48)
self.notif.Notify(
dbus.String(_('Gajim')), # app_name (string)
dbus.UInt32(0), # replaces_id (uint)
diff --git a/src/roster_window.py b/src/roster_window.py
index 50249d642..9e56d3c97 100644
--- a/src/roster_window.py
+++ b/src/roster_window.py
@@ -4962,10 +4962,7 @@ class RosterWindow:
sub_menu.append(item)
item = gtk.ImageMenuItem(_('_Change Status Message'))
- path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'kbd_input.png')
- img = gtk.Image()
- img.set_from_file(path)
- item.set_image(img)
+ gtkgui_helpers.add_image_to_menuitem(item, 'gajim-kbd_input')
sub_menu.append(item)
item.connect('activate', self.on_change_status_message_activate,
account)
@@ -5063,10 +5060,7 @@ class RosterWindow:
sub_menu.append(item)
item = gtk.ImageMenuItem(_('_Change Status Message'))
- path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'kbd_input.png')
- img = gtk.Image()
- img.set_from_file(path)
- item.set_image(img)
+ gtkgui_helpers.add_image_to_menuitem(item, 'gajim-kbd_input')
sub_menu.append(item)
item.connect('activate', self.on_change_status_message_activate,
account)
@@ -5219,11 +5213,7 @@ class RosterWindow:
# Rename
rename_item = gtk.ImageMenuItem(_('Re_name'))
# add a special img for rename menuitem
- path_to_kbd_input_img = os.path.join(gajim.DATA_DIR, 'pixmaps',
- 'kbd_input.png')
- img = gtk.Image()
- img.set_from_file(path_to_kbd_input_img)
- rename_item.set_image(img)
+ gtkgui_helpers.add_image_to_menuitem(rename_item, 'gajim-kbd_input')
menu.append(rename_item)
rename_item.connect('activate', self.on_rename, 'group', group,
account)
@@ -5481,11 +5471,7 @@ class RosterWindow:
# Rename
item = gtk.ImageMenuItem(_('_Rename'))
# add a special img for rename menuitem
- path_to_kbd_input_img = os.path.join(gajim.DATA_DIR, 'pixmaps',
- 'kbd_input.png')
- img = gtk.Image()
- img.set_from_file(path_to_kbd_input_img)
- item.set_image(img)
+ gtkgui_helpers.add_image_to_menuitem(item, 'gajim-kbd_input')
manage_transport_submenu.append(item)
item.connect('activate', self.on_rename, 'agent', jid, account)
if gajim.account_is_disconnected(account):
@@ -5813,7 +5799,7 @@ class RosterWindow:
# Add a Separator (self._iter_is_separator() checks on string SEPARATOR)
liststore.append(['SEPARATOR', None, '', True])
- path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'kbd_input.png')
+ path = gtkgui_helpers.get_icon_path('gajim-kbd_input')
img = gtk.Image()
img.set_from_file(path)
# sensitivity to False because by default we're offline
diff --git a/src/statusicon.py b/src/statusicon.py
index 556fb9fa1..33c3fa063 100644
--- a/src/statusicon.py
+++ b/src/statusicon.py
@@ -207,10 +207,7 @@ class StatusIcon:
sub_menu.append(item)
item = gtk.ImageMenuItem(_('_Change Status Message...'))
- path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'kbd_input.png')
- img = gtk.Image()
- img.set_from_file(path)
- item.set_image(img)
+ gtkgui_helpers.add_image_to_menuitem(item, 'gajim-kbd_input')
sub_menu.append(item)
item.connect('activate', self.on_change_status_message_activate)