Merge local changes.

This commit is contained in:
Stephan Erb 2009-12-01 22:16:30 +01:00
commit b73bbb8cae
80 changed files with 344 additions and 334 deletions

View file

@ -1962,7 +1962,6 @@ $T will be replaced by auto-not-available timeout</property>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="right_attach">2</property> <property name="right_attach">2</property>
<property name="x_options"></property>
</packing> </packing>
</child> </child>
<child> <child>
@ -1975,7 +1974,6 @@ $T will be replaced by auto-not-available timeout</property>
<property name="right_attach">2</property> <property name="right_attach">2</property>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="bottom_attach">2</property> <property name="bottom_attach">2</property>
<property name="x_options"></property>
</packing> </packing>
</child> </child>
<child> <child>
@ -2066,7 +2064,6 @@ $T will be replaced by auto-not-available timeout</property>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="right_attach">2</property> <property name="right_attach">2</property>
<property name="x_options"></property>
</packing> </packing>
</child> </child>
<child> <child>
@ -2079,7 +2076,6 @@ $T will be replaced by auto-not-available timeout</property>
<property name="right_attach">2</property> <property name="right_attach">2</property>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="bottom_attach">2</property> <property name="bottom_attach">2</property>
<property name="x_options"></property>
</packing> </packing>
</child> </child>
</widget> </widget>
@ -2102,6 +2098,74 @@ $T will be replaced by auto-not-available timeout</property>
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
<child>
<widget class="GtkFrame" id="frame7">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<widget class="GtkAlignment" id="alignment9">
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
<widget class="GtkTable" id="table9">
<property name="visible">True</property>
<property name="n_columns">3</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
<widget class="GtkLabel" id="label24">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">STUN server:</property>
</widget>
<packing>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label25">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;i&gt;(example: stunserver.org)&lt;/i&gt;</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="stun_server_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label22">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Connection&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
</widget> </widget>
<packing> <packing>
<property name="position">5</property> <property name="position">5</property>

View file

@ -1,15 +1,5 @@
pixmapsdir = $(pkgdatadir)/data/pixmaps pixmapsdir = $(pkgdatadir)/data/pixmaps
nobase_dist_pixmaps_DATA = \ nobase_dist_pixmaps_DATA = \
$(srcdir)/events/*.png \
$(srcdir)/agents/*.png \
$(srcdir)/*.png \
$(srcdir)/gajim.svg \
$(srcdir)/gajim.ico $(srcdir)/gajim.ico
gajimpixmapdir = $(datadir)/pixmaps
gajimpixmap_DATA = \
$(srcdir)/gajim.png \
$(srcdir)/gajim.svg \
$(srcdir)/gajim_about.png
MAINTAINERCLEANFILES = Makefile.in MAINTAINERCLEANFILES = Makefile.in

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 594 B

View file

@ -1,4 +1,7 @@
iconsdir = $(pkgdatadir)/icons iconsdir = $(pkgdatadir)/icons
nobase_dist_icons_DATA = $(srcdir)/*/*/*/* nobase_dist_icons_DATA = $(srcdir)/*/*/*/*
systemiconsdir = $(datadir)/icons
nobase_dist_systemicons_DATA = $(srcdir)/*/*/*/gajim.*
MAINTAINERCLEANFILES = Makefile.in MAINTAINERCLEANFILES = Makefile.in

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

Before

Width:  |  Height:  |  Size: 988 B

After

Width:  |  Height:  |  Size: 988 B

View file

Before

Width:  |  Height:  |  Size: 963 B

After

Width:  |  Height:  |  Size: 963 B

View file

Before

Width:  |  Height:  |  Size: 189 B

After

Width:  |  Height:  |  Size: 189 B

View file

Before

Width:  |  Height:  |  Size: 788 B

After

Width:  |  Height:  |  Size: 788 B

View file

Before

Width:  |  Height:  |  Size: 773 B

After

Width:  |  Height:  |  Size: 773 B

View file

Before

Width:  |  Height:  |  Size: 209 B

After

Width:  |  Height:  |  Size: 209 B

View file

Before

Width:  |  Height:  |  Size: 353 B

After

Width:  |  Height:  |  Size: 353 B

View file

Before

Width:  |  Height:  |  Size: 790 B

After

Width:  |  Height:  |  Size: 790 B

View file

Before

Width:  |  Height:  |  Size: 844 B

After

Width:  |  Height:  |  Size: 844 B

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 994 B

After

Width:  |  Height:  |  Size: 994 B

View file

Before

Width:  |  Height:  |  Size: 874 B

After

Width:  |  Height:  |  Size: 874 B

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2 KiB

View file

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 959 B

After

Width:  |  Height:  |  Size: 959 B

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

Before

Width:  |  Height:  |  Size: 997 B

After

Width:  |  Height:  |  Size: 997 B

View file

Before

Width:  |  Height:  |  Size: 766 B

After

Width:  |  Height:  |  Size: 766 B

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View file

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View file

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View file

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View file

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -1274,21 +1274,15 @@ class ChatControl(ChatControlBase):
id_ = self._audio_button.connect('toggled', self.on_audio_button_toggled) id_ = self._audio_button.connect('toggled', self.on_audio_button_toggled)
self.handlers[id_] = self._audio_button self.handlers[id_] = self._audio_button
# add a special img # add a special img
path_to_img = os.path.join(gajim.DATA_DIR, 'pixmaps', gtkgui_helpers.add_image_to_button(self._audio_button,
'mic_inactive.png') 'gajim-mic_inactive')
img = gtk.Image()
img.set_from_file(path_to_img)
self._audio_button.set_image(img)
self._video_button = self.xml.get_widget('video_togglebutton') self._video_button = self.xml.get_widget('video_togglebutton')
id_ = self._video_button.connect('toggled', self.on_video_button_toggled) id_ = self._video_button.connect('toggled', self.on_video_button_toggled)
self.handlers[id_] = self._video_button self.handlers[id_] = self._video_button
# add a special img # add a special img
path_to_img = os.path.join(gajim.DATA_DIR, 'pixmaps', gtkgui_helpers.add_image_to_button(self._video_button,
'cam_inactive.png') 'gajim-cam_inactive')
img = gtk.Image()
img.set_from_file(path_to_img)
self._video_button.set_image(img)
self._send_file_button = self.xml.get_widget('send_file_button') self._send_file_button = self.xml.get_widget('send_file_button')
# add a special img for 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) banner_name_label.set_tooltip_text(label_tooltip)
def on_jingle_button_toggled(self, widget, jingle_type): def on_jingle_button_toggled(self, widget, jingle_type):
path_to_img = os.path.join(gajim.DATA_DIR, 'pixmaps', '%s_%s.png' img_name = '%s_%s' % ({'audio': 'mic', 'video': 'cam'}[jingle_type],
% ({'audio': 'mic', 'video': 'cam'}[jingle_type], {True: 'active', False: 'inactive'}[widget.get_active()])
{True: 'active', False: 'inactive'}[widget.get_active()])) path_to_img = gtkgui_helpers.get_icon_path(img_name)
if widget.get_active(): 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], sid = getattr(gajim.connections[self.account],
'start_' + jingle_type)(self.contact.get_full_jid()) 'start_' + jingle_type)(self.contact.get_full_jid())
getattr(self, 'set_' + jingle_type + '_state')('connecting', sid) getattr(self, 'set_' + jingle_type + '_state')('connecting', sid)
@ -1886,11 +1881,12 @@ class ChatControl(ChatControlBase):
if authenticated: if authenticated:
#About encrypted chat session #About encrypted chat session
authenticated_string = _('and authenticated') 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: else:
#About encrypted chat session #About encrypted chat session
authenticated_string = _('and NOT authenticated') 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 #status will become 'is' or 'is not', authentificaed will become
#'and authentificated' or 'and not authentificated', logged will become #'and authentificated' or 'and not authentificated', logged will become

View file

@ -20,13 +20,15 @@ class BaseError(Exception):
""" """
def __init__(self, message, command=None, name=None): def __init__(self, message, command=None, name=None):
self.message = message
self.command = command self.command = command
self.name = name self.name = name
if command and not name: if command and not name:
self.name = command.first_name self.name = command.first_name
super(BaseError, self).__init__(message) super(BaseError, self).__init__()
class DefinitionError(BaseError): class DefinitionError(BaseError):
""" """

View file

@ -27,18 +27,11 @@ import os
import sys import sys
import stat import stat
import exceptions
from common import gajim from common import gajim
import logger import logger
# DO NOT MOVE ABOVE OF import gajim # DO NOT MOVE ABOVE OF import gajim
try: import sqlite3 as sqlite
import sqlite3 as sqlite # python 2.5
except ImportError:
try:
from pysqlite2 import dbapi2 as sqlite
except ImportError:
raise exceptions.PysqliteNotAvailable
def create_log_db(): def create_log_db():
print _('creating logs database') print _('creating logs database')

View file

@ -276,6 +276,7 @@ class Config:
'audio_output_device': [opt_str, 'autoaudiosink'], 'audio_output_device': [opt_str, 'autoaudiosink'],
'video_input_device': [opt_str, 'autovideosrc ! videoscale ! ffmpegcolorspace'], 'video_input_device': [opt_str, 'autovideosrc ! videoscale ! ffmpegcolorspace'],
'video_output_device': [opt_str, 'autovideosink'], 'video_output_device': [opt_str, 'autovideosink'],
'stun_server': [opt_str, '', _('STUN server to use when using jingle')],
} }
__options_per_key = { __options_per_key = {

View file

@ -31,7 +31,7 @@
from common import caps from common import caps
from common.account import Account from common.account import Account
import common.gajim import common.gajim
class XMPPEntity(object): class XMPPEntity(object):
""" """
@ -175,9 +175,7 @@ class Contact(CommonContact):
def is_transport(self): def is_transport(self):
# if not '@' or '@' starts the jid then contact is transport # if not '@' or '@' starts the jid then contact is transport
if self.jid.find('@') <= 0: return self.jid.find('@') <= 0
return True
return False
class GC_Contact(CommonContact): class GC_Contact(CommonContact):
@ -443,18 +441,14 @@ class Contacts_New():
""" """
Remove all contacts for a given jid Remove all contacts for a given jid
""" """
if jid not in self._contacts: if jid in self._contacts:
return del self._contacts[jid]
del self._contacts[jid]
def get_contacts(self, jid): def get_contacts(self, jid):
""" """
Return the list of contact instances for this jid Return the list of contact instances for this jid
""" """
if jid in self._contacts: return self._contacts.get(jid, [])
return self._contacts[jid]
else:
return []
def get_contact(self, jid, resource=None): def get_contact(self, jid, resource=None):
### WARNING ### ### WARNING ###
@ -472,7 +466,6 @@ class Contacts_New():
for c in self._contacts[jid]: for c in self._contacts[jid]:
if c.resource == resource: if c.resource == resource:
return c return c
return None
def iter_contacts(self): def iter_contacts(self):
for jid in self._contacts.keys(): for jid in self._contacts.keys():
@ -492,7 +485,6 @@ class Contacts_New():
def get_first_contact_from_jid(self, jid): def get_first_contact_from_jid(self, jid):
if jid in self._contacts: if jid in self._contacts:
return self._contacts[jid][0] return self._contacts[jid][0]
return None
def get_contacts_from_group(self, group): def get_contacts_from_group(self, group):
""" """
@ -538,9 +530,8 @@ class GC_Contacts():
del self._rooms[gc_contact.room_jid] del self._rooms[gc_contact.room_jid]
def remove_room(self, room_jid): def remove_room(self, room_jid):
if room_jid not in self._rooms: if room_jid in self._rooms:
return del self._rooms[room_jid]
del self._rooms[room_jid]
def get_gc_list(self): def get_gc_list(self):
return self._rooms.keys() return self._rooms.keys()
@ -643,7 +634,7 @@ class MetacontactManager():
def remove_metacontact(self, account, jid): def remove_metacontact(self, account, jid):
if not account in self._metacontacts_tags: if not account in self._metacontacts_tags:
return None return
found = None found = None
for tag in self._metacontacts_tags[account]: for tag in self._metacontacts_tags[account]:

View file

@ -63,7 +63,7 @@ class SystemBus:
raise exceptions.DbusNotSupported raise exceptions.DbusNotSupported
if not self.present(): if not self.present():
raise exceptions.SystemBusNotPresent raise exceptions.SystemBusNotPresent
return self.system_bus return self.system_bus
def bus(self): def bus(self):

View file

@ -21,17 +21,6 @@
## along with Gajim. If not, see <http://www.gnu.org/licenses/>. ## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
## ##
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): class PysqliteOperationalError(Exception):
""" """
Sqlite2 raised pysqlite2.dbapi2.OperationalError Sqlite2 raised pysqlite2.dbapi2.OperationalError
@ -86,7 +75,20 @@ class SessionBusNotPresent(Exception):
Exception.__init__(self) Exception.__init__(self)
def __str__(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): class NegotiationError(Exception):
""" """

View file

@ -25,7 +25,6 @@ Handles the jingle signalling protocol
# - video integration # - video integration
# * config: # * config:
# - codecs # - codecs
# - STUN
# * figure out why it doesn't work with pidgin: # * figure out why it doesn't work with pidgin:
# That's maybe a bug in pidgin: # That's maybe a bug in pidgin:

View file

@ -23,6 +23,12 @@ def get_jingle_content(node):
return contents[namespace](node) return contents[namespace](node)
class FailedApplication(Exception):
"""
Exception that should be raised when a content fails to setup.
"""
class JingleContent(object): class JingleContent(object):
""" """
An abstraction of content in Jingle sessions An abstraction of content in Jingle sessions
@ -106,6 +112,9 @@ class JingleContent(object):
payload=payload) payload=payload)
def send_candidate(self, candidate): def send_candidate(self, candidate):
"""
Send a transport candidate for a previously defined transport.
"""
content = self.__content() content = self.__content()
content.addChild(self.transport.make_transport([candidate])) content.addChild(self.transport.make_transport([candidate]))
self.session.send_transport_info(content) self.session.send_transport_info(content)

View file

@ -19,11 +19,12 @@ import gobject
import xmpp import xmpp
import farsight, gst import farsight, gst
from glib import GError
import gajim import gajim
from jingle_transport import JingleTransportICEUDP from jingle_transport import JingleTransportICEUDP
from jingle_content import contents, JingleContent from jingle_content import contents, JingleContent, FailedApplication
class JingleRTPContent(JingleContent): class JingleRTPContent(JingleContent):
@ -35,12 +36,12 @@ class JingleRTPContent(JingleContent):
self._dtmf_running = False self._dtmf_running = False
self.farsight_media = {'audio': farsight.MEDIA_TYPE_AUDIO, self.farsight_media = {'audio': farsight.MEDIA_TYPE_AUDIO,
'video': farsight.MEDIA_TYPE_VIDEO}[media] 'video': farsight.MEDIA_TYPE_VIDEO}[media]
self.got_codecs = False
self.candidates_ready = False # True when local candidates are prepared self.candidates_ready = False # True when local candidates are prepared
self.callbacks['session-initiate'] += [self.__on_remote_codecs] self.callbacks['session-initiate'] += [self.__on_remote_codecs]
self.callbacks['content-add'] += [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.callbacks['content-accept'] += [self.__on_remote_codecs,
self.__on_content_accept] self.__on_content_accept]
self.callbacks['session-accept'] += [self.__on_remote_codecs, self.callbacks['session-accept'] += [self.__on_remote_codecs,
@ -59,7 +60,7 @@ class JingleRTPContent(JingleContent):
# conference # conference
self.conference = gst.element_factory_make('fsrtpconference') 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.pipeline.add(self.conference)
self.funnel = None self.funnel = None
@ -69,8 +70,16 @@ class JingleRTPContent(JingleContent):
# FIXME: Consider a workaround, here... # FIXME: Consider a workaround, here...
# pidgin and telepathy-gabble don't follow the XEP, and it won't work # pidgin and telepathy-gabble don't follow the XEP, and it won't work
# due to bad controlling-mode # due to bad controlling-mode
params = {'controlling-mode': self.session.weinitiate,# 'debug': False} params = {'controlling-mode': self.session.weinitiate, 'debug': False}
'stun-ip': '69.0.208.27', '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, self.p2pstream = self.p2psession.new_stream(participant,
farsight.DIRECTION_RECV, 'nice', params) farsight.DIRECTION_RECV, 'nice', params)
@ -79,6 +88,18 @@ class JingleRTPContent(JingleContent):
return (JingleContent.is_ready(self) and self.candidates_ready return (JingleContent.is_ready(self) and self.candidates_ready
and self.p2psession.get_property('codecs-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): def add_remote_candidates(self, candidates):
JingleContent.add_remote_candidates(self, candidates) JingleContent.add_remote_candidates(self, candidates)
# FIXME: connectivity should not be etablished yet # FIXME: connectivity should not be etablished yet
@ -87,6 +108,9 @@ class JingleRTPContent(JingleContent):
self.p2pstream.set_remote_candidates(candidates) self.p2pstream.set_remote_candidates(candidates)
def batch_dtmf(self, events): def batch_dtmf(self, events):
"""
Send several DTMF tones
"""
if self._dtmf_running: if self._dtmf_running:
raise Exception # TODO: Proper exception raise Exception # TODO: Proper exception
self._dtmf_running = True self._dtmf_running = True
@ -177,8 +201,6 @@ class JingleRTPContent(JingleContent):
""" """
Get peer codecs from what we get from peer Get peer codecs from what we get from peer
""" """
if self.got_codecs:
return
codecs = [] codecs = []
for codec in content.getTag('description').iterTags('payload-type'): 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 # glib.GError: There was no intersection between the remote codecs and
# the local ones # the local ones
self.p2pstream.set_remote_codecs(codecs) self.p2pstream.set_remote_codecs(codecs)
self.got_codecs = True
def iter_codecs(self): def iter_codecs(self):
codecs = self.p2psession.get_property('codecs') codecs = self.p2psession.get_property('codecs')
@ -252,17 +273,12 @@ class JingleAudio(JingleRTPContent):
self.p2psession.set_codec_preferences(codecs) self.p2psession.set_codec_preferences(codecs)
# the local parts # the local parts
try: # TODO: Add queues?
self.sink = gst.parse_bin_from_description(gajim.config.get('audio_output_device'), True) src_bin = self.make_bin_from_config('audio_input_device',
except: '%s ! audioconvert', _("audio input"))
self.session.connection.dispatch('ERROR', (_("Audio configuration error"),
_("Couldn't setup audio output. Check your audio configuration.")))
try: self.sink = self.make_bin_from_config('audio_output_device',
src_bin = gst.parse_bin_from_description(gajim.config.get('audio_input_device'), True) 'audioconvert ! %s', _("audio output"))
except:
self.session.connection.dispatch('ERROR', (_("Audio configuration error"),
_("Couldn't setup audio input. Check your audio configuration.")))
self.mic_volume = src_bin.get_by_name('gajim_vol') self.mic_volume = src_bin.get_by_name('gajim_vol')
self.mic_volume.set_property('volume', 1) self.mic_volume.set_property('volume', 1)
@ -290,25 +306,19 @@ class JingleVideo(JingleRTPContent):
JingleRTPContent.setup_stream(self) JingleRTPContent.setup_stream(self)
# the local parts # the local parts
try: src_bin = self.make_bin_from_config('video_input_device',
src_bin = gst.parse_bin_from_description(gajim.config.get('video_input_device'), True) '%s ! videoscale ! ffmpegcolorspace', _("video input"))
except: #caps = gst.element_factory_make('capsfilter')
self.session.connection.dispatch('ERROR', (_("Video configuration error"), #caps.set_property('caps', gst.caps_from_string('video/x-raw-yuv, width=320, height=240'))
_("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'))
self.pipeline.add(src_bin, caps) self.pipeline.add(src_bin)#, caps)
src_bin.link(caps) #src_bin.link(caps)
try: self.sink = self.make_bin_from_config('video_output_device',
self.sink = gst.parse_bin_from_description(gajim.config.get('video_output_device'), True) '%s ! videoscale ! ffmpegcolorspace', _("video output"))
except:
self.session.connection.dispatch('ERROR', (_("Video configuration error"),
_("Couldn't setup video output. Check your video configuration.")))
self.pipeline.add(self.sink) 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) self.p2pstream.connect('src-pad-added', self._on_src_pad_added)
# The following is needed for farsight to process ICE requests: # The following is needed for farsight to process ICE requests:

View file

@ -16,12 +16,11 @@ Handles Jingle sessions (XEP 0166)
""" """
#TODO: #TODO:
# * Have JingleContent here
# * 'senders' attribute of 'content' element # * 'senders' attribute of 'content' element
# * security preconditions # * security preconditions
# * actions: # * actions:
# - content-modify # - content-modify
# - description-info, session-info # - session-info
# - security-info # - security-info
# - transport-accept, transport-reject # - transport-accept, transport-reject
# - Tie-breaking # - Tie-breaking
@ -30,7 +29,7 @@ Handles Jingle sessions (XEP 0166)
import gajim #Get rid of that? import gajim #Get rid of that?
import xmpp import xmpp
from jingle_transport import get_jingle_transport 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? # FIXME: Move it to JingleSession.States?
class JingleStates(object): class JingleStates(object):
@ -55,7 +54,8 @@ class TieBreak(Exception):
class JingleSession(object): 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): def __init__(self, con, weinitiate, jid, sid=None):
@ -394,8 +394,8 @@ class JingleSession(object):
raise OutOfOrder raise OutOfOrder
parse_result = self.__parse_contents(jingle) parse_result = self.__parse_contents(jingle)
contents = parse_result[2] contents = parse_result[0]
rejected_contents = parse_result[3] rejected_contents = parse_result[1]
for name, creator in rejected_contents: for name, creator in rejected_contents:
# TODO # TODO
@ -426,21 +426,13 @@ class JingleSession(object):
# error. # error.
# Lets check what kind of jingle session does the peer want # 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 there's no content we understand...
if not contents_ok: if not contents:
# TODO: http://xmpp.org/extensions/xep-0166.html#session-terminate # TODO: http://xmpp.org/extensions/xep-0166.html#session-terminate
reason = xmpp.Node('reason') reason = xmpp.Node('reason')
reason.setTag('unsupported-applications') reason.setTag(reason)
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')
self.__ack(stanza, jingle, error, action) self.__ack(stanza, jingle, error, action)
self._session_terminate(reason) self._session_terminate(reason)
raise xmpp.NodeProcessed raise xmpp.NodeProcessed
@ -485,26 +477,37 @@ class JingleSession(object):
# TODO: Needs some reworking # TODO: Needs some reworking
contents = [] contents = []
contents_rejected = [] contents_rejected = []
contents_ok = False reasons = set()
transports_ok = False
for element in jingle.iterTags('content'): for element in jingle.iterTags('content'):
transport = get_jingle_transport(element.getTag('transport')) transport = get_jingle_transport(element.getTag('transport'))
content_type = get_jingle_content(element.getTag('description')) content_type = get_jingle_content(element.getTag('description'))
if content_type: if content_type:
contents_ok = True try:
if transport: if transport:
content = content_type(self, transport) content = content_type(self, transport)
self.add_content(element['name'], self.add_content(element['name'],
content, 'peer') content, 'peer')
contents.append((content.media,)) contents.append((content.media,))
transports_ok = True else:
else: reasons.add('unsupported-transports')
contents_rejected.append((element['name'], 'peer')) contents_rejected.append((element['name'], 'peer'))
except FailedApplication:
reasons.add('failed-application')
else: else:
contents_rejected.append((element['name'], 'peer')) 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): def __dispatch_error(self, error, jingle_error=None, text=None):
if jingle_error: if jingle_error:

View file

@ -38,13 +38,7 @@ from cStringIO import StringIO
import exceptions import exceptions
import gajim import gajim
try: import sqlite3 as sqlite
import sqlite3 as sqlite # python 2.5
except ImportError:
try:
from pysqlite2 import dbapi2 as sqlite
except ImportError:
raise exceptions.PysqliteNotAvailable
import configpaths import configpaths
LOG_DB_PATH = configpaths.gajimpaths['LOG_DB'] LOG_DB_PATH = configpaths.gajimpaths['LOG_DB']

View file

@ -78,11 +78,9 @@ class VideoInputManager(DeviceManager):
self.detect_element('videotestsrc', _('Video test'), self.detect_element('videotestsrc', _('Video test'),
'%s is-live=true') '%s is-live=true')
# Auto src # Auto src
self.detect_element('autovideosrc', _('Autodetect'), self.detect_element('autovideosrc', _('Autodetect'))
'%s ! videoscale ! ffmpegcolorspace')
# V4L2 src ; TODO: Figure out why it doesn't work # V4L2 src ; TODO: Figure out why it doesn't work
self.detect_element('v4l2src', _('V4L2: %s'), self.detect_element('v4l2src', _('V4L2: %s'))
'%s ! videoscale ! ffmpegcolorspace')
# Funny things, just to test... # Funny things, just to test...
# self.devices['GOOM'] = 'audiotestsrc ! goom' # self.devices['GOOM'] = 'audiotestsrc ! goom'
# self.devices['screen'] = 'ximagesrc' # self.devices['screen'] = 'ximagesrc'

View file

@ -34,14 +34,7 @@ from common import gajim
from common import helpers from common import helpers
from common import caps from common import caps
import exceptions import sqlite3 as sqlite
try:
import sqlite3 as sqlite # python 2.5
except ImportError:
try:
from pysqlite2 import dbapi2 as sqlite
except ImportError:
raise exceptions.PysqliteNotAvailable
import logger import logger
class OptionsParser: class OptionsParser:

View file

@ -59,7 +59,12 @@ from common.zeroconf import connection_zeroconf
from common import dataforms from common import dataforms
from common import GnuPG 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 from common.exceptions import GajimGeneralException
@ -416,8 +421,7 @@ class PreferencesWindow:
buf = self.xml.get_widget('msg_textview').get_buffer() buf = self.xml.get_widget('msg_textview').get_buffer()
buf.connect('changed', self.on_msg_textview_changed) buf.connect('changed', self.on_msg_textview_changed)
### Style tab ### ### Audio / Video tab ###
# Audio
def create_av_combobox(opt_name, device_dict): def create_av_combobox(opt_name, device_dict):
combobox = self.xml.get_widget(opt_name + '_combobox') combobox = self.xml.get_widget(opt_name + '_combobox')
cell = gtk.CellRendererText() cell = gtk.CellRendererText()
@ -431,10 +435,21 @@ class PreferencesWindow:
if gajim.config.get(opt_name + '_device') == value: if gajim.config.get(opt_name + '_device') == value:
combobox.set_active(index) combobox.set_active(index)
create_av_combobox('audio_input', AudioInputManager().get_devices()) if HAS_GST:
create_av_combobox('audio_output', AudioOutputManager().get_devices()) create_av_combobox('audio_input', AudioInputManager().get_devices())
create_av_combobox('video_input', VideoInputManager().get_devices()) create_av_combobox('audio_output', AudioOutputManager().get_devices())
create_av_combobox('video_output', VideoOutputManager().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 ### ### Advanced tab ###
# open links with # open links with
if os.name == 'nt': if os.name == 'nt':
@ -1046,6 +1061,9 @@ class PreferencesWindow:
def on_video_output_combobox_changed(self, widget): def on_video_output_combobox_changed(self, widget):
self.on_av_combobox_changed(widget, 'video_output') 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): def on_applications_combobox_changed(self, widget):
gajim.config.set('autodetect_browser_mailer', False) gajim.config.set('autodetect_browser_mailer', False)
if widget.get_active() == 4: if widget.get_active() == 4:
@ -1419,8 +1437,7 @@ class AccountsWindow:
self.accounts_treeview = self.xml.get_widget('accounts_treeview') self.accounts_treeview = self.xml.get_widget('accounts_treeview')
self.remove_button = self.xml.get_widget('remove_button') self.remove_button = self.xml.get_widget('remove_button')
self.rename_button = self.xml.get_widget('rename_button') self.rename_button = self.xml.get_widget('rename_button')
path_to_kbd_input_img = os.path.join(gajim.DATA_DIR, 'pixmaps', path_to_kbd_input_img = gtkgui_helpers.get_icon_path('gajim-kbd_input')
'kbd_input.png')
img = self.xml.get_widget('rename_image') img = self.xml.get_widget('rename_image')
img.set_from_file(path_to_kbd_input_img) img.set_from_file(path_to_kbd_input_img)
self.notebook = self.xml.get_widget('notebook') self.notebook = self.xml.get_widget('notebook')
@ -3354,7 +3371,7 @@ class AccountCreationWizardWindow:
if self.modify: if self.modify:
img.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_DIALOG) img.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_DIALOG)
else: 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) img.set_from_file(path_to_file)
self.show_vcard_checkbutton.set_active(not self.modify) self.show_vcard_checkbutton.set_active(not self.modify)
self.notebook.set_current_page(6) # show finish page self.notebook.set_current_page(6) # show finish page

View file

@ -169,10 +169,9 @@ class ConversationTextview(gobject.GObject):
) )
) )
FOCUS_OUT_LINE_PIXBUF = gtk.gdk.pixbuf_new_from_file(os.path.join( FOCUS_OUT_LINE_PIXBUF = gtkgui_helpers.get_icon_pixmap('gajim-muc_separator')
gajim.DATA_DIR, 'pixmaps', 'muc_separator.png')) XEP0184_WARNING_PIXBUF = gtkgui_helpers.get_icon_pixmap(
XEP0184_WARNING_PIXBUF = gtk.gdk.pixbuf_new_from_file(os.path.join( 'gajim-receipt_missing')
gajim.DATA_DIR, 'pixmaps', 'receipt_missing.png'))
# smooth scroll constants # smooth scroll constants
MAX_SCROLL_TIME = 0.4 # seconds MAX_SCROLL_TIME = 0.4 # seconds

View file

@ -1190,8 +1190,7 @@ class AboutDialog:
dlg.props.wrap_license = True dlg.props.wrap_license = True
pixbuf = gtk.gdk.pixbuf_new_from_file(os.path.join( pixbuf = gtkgui_helpers.get_icon_pixmap('gajim-about', 64)
gajim.DATA_DIR, 'pixmaps', 'gajim_about.png'))
dlg.set_logo(pixbuf) dlg.set_logo(pixbuf)
#here you write your name in the form Name FamilyName <someone@somewhere> #here you write your name in the form Name FamilyName <someone@somewhere>
@ -2463,9 +2462,7 @@ class PopupNotificationWindow:
# default image # default image
if not path_to_image: if not path_to_image:
path_to_image = os.path.abspath( path_to_image = gtkgui_helpers.get_icon_path('gajim-chat_msg_recv', 48)
os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
'chat_msg_recv.png')) # img to display
if event_type == _('Contact Signed In'): if event_type == _('Contact Signed In'):
bg_color = 'limegreen' bg_color = 'limegreen'
@ -4540,43 +4537,37 @@ class ESessionInfoWindow:
def update_info(self): def update_info(self):
labeltext = _('''Your chat session with <b>%(jid)s</b> is encrypted.\n\nThis session's Short Authentication String is <b>%(sas)s</b>.''') % {'jid': self.session.jid, 'sas': self.session.sas} labeltext = _('''Your chat session with <b>%(jid)s</b> is encrypted.\n\nThis session's Short Authentication String is <b>%(sas)s</b>.''') % {'jid': self.session.jid, 'sas': self.session.sas}
dir_ = os.path.join(gajim.DATA_DIR, 'pixmaps')
if self.session.verified_identity: if self.session.verified_identity:
labeltext += '\n\n' + _('''You have already verified this contact's 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: if self.session.control:
self.session.control._show_lock_image(True, 'E2E', True, 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''') verification_status = _('''Contact's identity verified''')
self.window.set_title(verification_status) self.window.set_title(verification_status)
self.xml.get_widget('verification_status_label').set_markup( self.xml.get_widget('verification_status_label').set_markup(
'<b><span size="x-large">' + '<b><span size="x-large">%s</span></b>' % verification_status)
verification_status +
'</span></b>')
self.xml.get_widget('dialog-action_area1').set_no_show_all(True) self.xml.get_widget('dialog-action_area1').set_no_show_all(True)
self.button_label.set_text(_('Verify again...')) self.button_label.set_text(_('Verify again...'))
else: else:
if self.session.control: if self.session.control:
self.session.control._show_lock_image(True, 'E2E', True, 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 <b>only</b> the expected person can read your messages or send you messages, you need to verify their identity by clicking the button below.''') labeltext += '\n\n' + _('''To be certain that <b>only</b> 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''') verification_status = _('''Contact's identity NOT verified''')
self.window.set_title(verification_status) self.window.set_title(verification_status)
self.xml.get_widget('verification_status_label').set_markup( self.xml.get_widget('verification_status_label').set_markup(
'<b><span size="x-large">' + '<b><span size="x-large">%s</span></b>' % verification_status)
verification_status +
'</span></b>')
self.button_label.set_text(_('Verify...')) self.button_label.set_text(_('Verify...'))
path = os.path.join(dir_, security_image) path = gtkgui_helpers.get_icon_path(security_image, 32)
filename = os.path.abspath(path) self.security_image.set_from_file(path)
self.security_image.set_from_file(filename)
self.xml.get_widget('info_display').set_markup(labeltext) self.xml.get_widget('info_display').set_markup(labeltext)
@ -4622,13 +4613,13 @@ class GPGInfoWindow:
verification_status = _('''Contact's identity NOT verified''') verification_status = _('''Contact's identity NOT verified''')
info = _('The contact\'s key (%s) <b>does not match</b> the key ' info = _('The contact\'s key (%s) <b>does not match</b> the key '
'assigned in Gajim.') % keyID[:8] 'assigned in Gajim.') % keyID[:8]
image = 'security-low-big.png' image = 'gajim-security_low'
elif not keyID: elif not keyID:
# No key assigned nor a key is used by remote contact # No key assigned nor a key is used by remote contact
verification_status = _('No GPG key assigned') verification_status = _('No GPG key assigned')
info = _('No GPG key is assigned to this contact. So you cannot ' info = _('No GPG key is assigned to this contact. So you cannot '
'encrypt messages.') 'encrypt messages.')
image = 'security-low-big.png' image = 'gajim-security_low'
else: else:
error = gajim.connections[account].gpg.encrypt('test', [keyID])[1] error = gajim.connections[account].gpg.encrypt('test', [keyID])[1]
if error: if error:
@ -4636,21 +4627,19 @@ class GPGInfoWindow:
info = _('GPG key is assigned to this contact, but <b>you do not ' info = _('GPG key is assigned to this contact, but <b>you do not '
'trust his key</b>, so message <b>cannot</b> be encrypted. Use ' 'trust his key</b>, so message <b>cannot</b> be encrypted. Use '
'your GPG client to trust this key.') 'your GPG client to trust this key.')
image = 'security-low-big.png' image = 'gajim-security_low'
else: else:
verification_status = _('''Contact's identity verified''') verification_status = _('''Contact's identity verified''')
info = _('GPG Key is assigned to this contact, and you trust his ' info = _('GPG Key is assigned to this contact, and you trust his '
'key, so messages will be encrypted.') 'key, so messages will be encrypted.')
image = 'security-high-big.png' image = 'gajim-security_high'
status_label.set_markup('<b><span size="x-large">%s</span></b>' % \ status_label.set_markup('<b><span size="x-large">%s</span></b>' % \
verification_status) verification_status)
info_label.set_markup(info) info_label.set_markup(info)
dir_ = os.path.join(gajim.DATA_DIR, 'pixmaps') path = gtkgui_helpers.get_icon_path(image, 32)
path = os.path.join(dir_, image) security_image.set_from_file(path)
filename = os.path.abspath(path)
security_image.set_from_file(filename)
xml.signal_autoconnect(self) xml.signal_autoconnect(self)
self.window.show_all() self.window.show_all()

View file

@ -73,44 +73,44 @@ def _gen_agent_type_info():
(0, 0): (None, None), (0, 0): (None, None),
# Jabber server # Jabber server
('server', 'im'): (ToplevelAgentBrowser, 'jabber.png'), ('server', 'im'): (ToplevelAgentBrowser, 'jabber'),
('services', 'jabber'): (ToplevelAgentBrowser, 'jabber.png'), ('services', 'jabber'): (ToplevelAgentBrowser, 'jabber'),
('hierarchy', 'branch'): (AgentBrowser, 'jabber.png'), ('hierarchy', 'branch'): (AgentBrowser, 'jabber'),
# Services # Services
('conference', 'text'): (MucBrowser, 'conference.png'), ('conference', 'text'): (MucBrowser, 'conference'),
('headline', 'rss'): (AgentBrowser, 'rss.png'), ('headline', 'rss'): (AgentBrowser, 'rss'),
('headline', 'weather'): (False, 'weather.png'), ('headline', 'weather'): (False, 'weather'),
('gateway', 'weather'): (False, 'weather.png'), ('gateway', 'weather'): (False, 'weather'),
('_jid', 'weather'): (False, 'weather.png'), ('_jid', 'weather'): (False, 'weather'),
('gateway', 'sip'): (False, 'sip.png'), ('gateway', 'sip'): (False, 'sip'),
('directory', 'user'): (None, 'jud.png'), ('directory', 'user'): (None, 'jud'),
('pubsub', 'generic'): (PubSubBrowser, 'pubsub.png'), ('pubsub', 'generic'): (PubSubBrowser, 'pubsub'),
('pubsub', 'service'): (PubSubBrowser, 'pubsub.png'), ('pubsub', 'service'): (PubSubBrowser, 'pubsub'),
('proxy', 'bytestreams'): (None, 'bytestreams.png'), # Socks5 FT proxy ('proxy', 'bytestreams'): (None, 'bytestreams'), # Socks5 FT proxy
('headline', 'newmail'): (ToplevelAgentBrowser, 'mail.png'), ('headline', 'newmail'): (ToplevelAgentBrowser, 'mail'),
# Transports # Transports
('conference', 'irc'): (ToplevelAgentBrowser, 'irc.png'), ('conference', 'irc'): (ToplevelAgentBrowser, 'irc'),
('_jid', 'irc'): (False, 'irc.png'), ('_jid', 'irc'): (False, 'irc'),
('gateway', 'aim'): (False, 'aim.png'), ('gateway', 'aim'): (False, 'aim'),
('_jid', 'aim'): (False, 'aim.png'), ('_jid', 'aim'): (False, 'aim'),
('gateway', 'gadu-gadu'): (False, 'gadu-gadu.png'), ('gateway', 'gadu-gadu'): (False, 'gadu_gadu'),
('_jid', 'gadugadu'): (False, 'gadu-gadu.png'), ('_jid', 'gadugadu'): (False, 'gadu_gadu'),
('gateway', 'http-ws'): (False, 'http-ws.png'), ('gateway', 'http-ws'): (False, 'http_ws'),
('gateway', 'icq'): (False, 'icq.png'), ('gateway', 'icq'): (False, 'icq'),
('_jid', 'icq'): (False, 'icq.png'), ('_jid', 'icq'): (False, 'icq'),
('gateway', 'msn'): (False, 'msn.png'), ('gateway', 'msn'): (False, 'msn'),
('_jid', 'msn'): (False, 'msn.png'), ('_jid', 'msn'): (False, 'msn'),
('gateway', 'sms'): (False, 'sms.png'), ('gateway', 'sms'): (False, 'sms'),
('_jid', 'sms'): (False, 'sms.png'), ('_jid', 'sms'): (False, 'sms'),
('gateway', 'smtp'): (False, 'mail.png'), ('gateway', 'smtp'): (False, 'mail'),
('gateway', 'yahoo'): (False, 'yahoo.png'), ('gateway', 'yahoo'): (False, 'yahoo'),
('_jid', 'yahoo'): (False, 'yahoo.png'), ('_jid', 'yahoo'): (False, 'yahoo'),
('gateway', 'mrim'): (False, 'mrim.png'), ('gateway', 'mrim'): (False, 'mrim'),
('_jid', 'mrim'): (False, 'mrim.png'), ('_jid', 'mrim'): (False, 'mrim'),
('gateway', 'facebook'): (False, 'facebook.png'), ('gateway', 'facebook'): (False, 'facebook'),
('_jid', 'facebook'): (False, 'facebook.png'), ('_jid', 'facebook'): (False, 'facebook'),
} }
# Category type to "human-readable" description string, and sort priority # Category type to "human-readable" description string, and sort priority
@ -291,13 +291,12 @@ class ServicesCache:
info = _agent_type_info[(0, 0)] info = _agent_type_info[(0, 0)]
filename = info[1] filename = info[1]
if not filename: # we don't have an image to show for this type if not filename: # we don't have an image to show for this type
filename = 'jabber.png' filename = 'jabber'
# Use the cache if possible # Use the cache if possible
if filename in _icon_cache: if filename in _icon_cache:
return _icon_cache[filename] return _icon_cache[filename]
# Or load it # Or load it
filepath = os.path.join(gajim.DATA_DIR, 'pixmaps', 'agents', filename) pix = gtkgui_helpers.get_icon_pixmap('gajim-agent-' + filename, size=32)
pix = gtk.gdk.pixbuf_new_from_file(filepath)
# Store in cache # Store in cache
_icon_cache[filename] = pix _icon_cache[filename] = pix
return pix return pix

View file

@ -322,8 +322,7 @@ def pid_alive():
return True return True
if pid_alive(): if pid_alive():
path_to_file = os.path.join(gajim.DATA_DIR, 'pixmaps/gajim.png') pix = gtkgui_helpers.get_icon_pixmap('gajim', 48)
pix = gtk.gdk.pixbuf_new_from_file(path_to_file)
gtk.window_set_default_icon(pix) # set the icon to all newly opened wind gtk.window_set_default_icon(pix) # set the icon to all newly opened wind
pritext = _('Gajim is already running') pritext = _('Gajim is already running')
sectext = _('Another instance of Gajim seems to be running\nRun anyway?') sectext = _('Another instance of Gajim seems to be running\nRun anyway?')

View file

@ -82,6 +82,15 @@ def get_icon_path(icon_name, size=16):
except gobject.GError, e: except gobject.GError, e:
log.error("Unable to find icon %s: %s" % (icon_name, str(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') GLADE_DIR = os.path.join(gajim.DATA_DIR, 'glade')
def get_glade(file_name, root = None): def get_glade(file_name, root = None):
file_path = os.path.join(GLADE_DIR, file_name) file_path = os.path.join(GLADE_DIR, file_name)

View file

@ -199,9 +199,7 @@ class Interface:
def handle_event_connection_lost(self, account, array): def handle_event_connection_lost(self, account, array):
# ('CONNECTION_LOST', account, [title, text]) # ('CONNECTION_LOST', account, [title, text])
path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', path = gtkgui_helpers.get_icon_path('gajim-connection_lost', 48)
'connection_lost.png')
path = gtkgui_helpers.get_path_to_generic_or_avatar(path)
notify.popup(_('Connection Failed'), account, account, notify.popup(_('Connection Failed'), account, account,
'connection_failed', path, array[0], array[1]) 'connection_failed', path, array[0], array[1])
@ -593,9 +591,7 @@ class Interface:
self.add_event(account, jid, 'subscription_request', (text, nick)) self.add_event(account, jid, 'subscription_request', (text, nick))
if helpers.allow_showing_notification(account): if helpers.allow_showing_notification(account):
path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', path = gtkgui_helpers.get_icon_path('gajim-subscription_request', 48)
'subscription_request.png')
path = gtkgui_helpers.get_path_to_generic_or_avatar(path)
event_type = _('Subscription request') event_type = _('Subscription request')
notify.popup(event_type, jid, account, 'subscription_request', path, notify.popup(event_type, jid, account, 'subscription_request', path,
event_type, jid) event_type, jid)
@ -653,13 +649,12 @@ class Interface:
if helpers.allow_popup_window(account) or not self.systray_enabled: if helpers.allow_popup_window(account) or not self.systray_enabled:
self.show_unsubscribed_dialog(account, contact) self.show_unsubscribed_dialog(account, contact)
return
self.add_event(account, jid, 'unsubscribed', contact) self.add_event(account, jid, 'unsubscribed', contact)
if helpers.allow_showing_notification(account): if helpers.allow_showing_notification(account):
path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', path = gtkgui_helpers.get_icon_path('gajim-unsubscribed', 48)
'unsubscribed.png')
path = gtkgui_helpers.get_path_to_generic_or_avatar(path)
event_type = _('Unsubscribed') event_type = _('Unsubscribed')
notify.popup(event_type, jid, account, 'unsubscribed', path, notify.popup(event_type, jid, account, 'unsubscribed', path,
event_type, jid) event_type, jid)
@ -1117,9 +1112,7 @@ class Interface:
array[3], array[4])) array[3], array[4]))
if helpers.allow_showing_notification(account): if helpers.allow_showing_notification(account):
path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', path = gtkgui_helpers.get_icon_path('gajim-gc_invitation', 48)
'gc_invitation.png')
path = gtkgui_helpers.get_path_to_generic_or_avatar(path)
event_type = _('Groupchat Invitation') event_type = _('Groupchat Invitation')
notify.popup(event_type, jid, account, 'gc-invitation', path, notify.popup(event_type, jid, account, 'gc-invitation', path,
event_type, room_jid) event_type, room_jid)
@ -1139,7 +1132,7 @@ class Interface:
sectext += _('You are currently connected without your OpenPGP key.') sectext += _('You are currently connected without your OpenPGP key.')
dialogs.WarningDialog(_('Your passphrase is incorrect'), sectext) dialogs.WarningDialog(_('Your passphrase is incorrect'), sectext)
else: 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, notify.popup('warning', account, account, 'warning', path,
_('OpenGPG Passphrase Incorrect'), _('OpenGPG Passphrase Incorrect'),
_('You are currently connected without your OpenPGP key.')) _('You are currently connected without your OpenPGP key.'))
@ -1276,8 +1269,7 @@ class Interface:
self.add_event(account, jid, 'file-send-error', file_props) self.add_event(account, jid, 'file-send-error', file_props)
if helpers.allow_showing_notification(account): if helpers.allow_showing_notification(account):
img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', 'ft_error.png') path = gtkgui_helpers.get_icon_path('gajim-ft_error', 48)
path = gtkgui_helpers.get_path_to_generic_or_avatar(img)
event_type = _('File Transfer Error') event_type = _('File Transfer Error')
notify.popup(event_type, jid, account, 'file-send-error', path, notify.popup(event_type, jid, account, 'file-send-error', path,
event_type, file_props['name']) event_type, file_props['name'])
@ -1287,8 +1279,7 @@ class Interface:
gmail_new_messages = int(array[1]) gmail_new_messages = int(array[1])
gmail_messages_list = array[2] gmail_messages_list = array[2]
if gajim.config.get('notify_on_new_gmail_email'): if gajim.config.get('notify_on_new_gmail_email'):
img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', path = gtkgui_helpers.get_icon_path('gajim-new_email_recv', 48)
'new_email_recv.png')
title = _('New mail on %(gmail_mail_address)s') % \ title = _('New mail on %(gmail_mail_address)s') % \
{'gmail_mail_address': jid} {'gmail_mail_address': jid}
text = i18n.ngettext('You have %d new mail conversation', text = i18n.ngettext('You have %d new mail conversation',
@ -1311,7 +1302,6 @@ class Interface:
if gajim.config.get_per('soundevents', 'gmail_received', 'enabled'): if gajim.config.get_per('soundevents', 'gmail_received', 'enabled'):
helpers.play_sound('gmail_received') helpers.play_sound('gmail_received')
path = gtkgui_helpers.get_path_to_generic_or_avatar(img)
notify.popup(_('New E-mail'), jid, account, 'gmail', notify.popup(_('New E-mail'), jid, account, 'gmail',
path_to_image=path, title=title, path_to_image=path, title=title,
text=text) text=text)
@ -1343,9 +1333,7 @@ class Interface:
if helpers.allow_showing_notification(account): if helpers.allow_showing_notification(account):
# check if we should be notified # check if we should be notified
img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', 'ft_error.png') path = gtkgui_helpers.get_icon_path('gajim-ft_error', 48)
path = gtkgui_helpers.get_path_to_generic_or_avatar(img)
event_type = _('File Transfer Error') event_type = _('File Transfer Error')
notify.popup(event_type, jid, account, msg_type, path, notify.popup(event_type, jid, account, msg_type, path,
title = event_type, text = file_props['name']) title = event_type, text = file_props['name'])
@ -1374,11 +1362,9 @@ class Interface:
self.add_event(account, jid, 'file-request', file_props) self.add_event(account, jid, 'file-request', file_props)
if helpers.allow_showing_notification(account): if helpers.allow_showing_notification(account):
img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', path = gtkgui_helpers.get_icon_path('gajim-ft_request', 48)
'ft_request.png')
txt = _('%s wants to send you a file.') % gajim.get_name_from_jid( txt = _('%s wants to send you a file.') % gajim.get_name_from_jid(
account, jid) account, jid)
path = gtkgui_helpers.get_path_to_generic_or_avatar(img)
event_type = _('File Transfer Request') event_type = _('File Transfer Request')
notify.popup(event_type, jid, account, 'file-request', notify.popup(event_type, jid, account, 'file-request',
path_to_image = path, title = event_type, text = txt) path_to_image = path, title = event_type, text = txt)
@ -1449,11 +1435,11 @@ class Interface:
if event_type == _('File Transfer Completed'): if event_type == _('File Transfer Completed'):
txt = _('You successfully received %(filename)s from %(name)s.')\ txt = _('You successfully received %(filename)s from %(name)s.')\
% {'filename': filename, 'name': name} % {'filename': filename, 'name': name}
img = 'ft_done.png' img_name = 'gajim-ft_done'
else: # ft stopped else: # ft stopped
txt = _('File transfer of %(filename)s from %(name)s stopped.')\ txt = _('File transfer of %(filename)s from %(name)s stopped.')\
% {'filename': filename, 'name': name} % {'filename': filename, 'name': name}
img = 'ft_stopped.png' img_name = 'gajim-ft_stopped'
else: else:
receiver = file_props['receiver'] receiver = file_props['receiver']
if hasattr(receiver, 'jid'): if hasattr(receiver, 'jid'):
@ -1466,23 +1452,23 @@ class Interface:
if event_type == _('File Transfer Completed'): if event_type == _('File Transfer Completed'):
txt = _('You successfully sent %(filename)s to %(name)s.')\ txt = _('You successfully sent %(filename)s to %(name)s.')\
% {'filename': filename, 'name': name} % {'filename': filename, 'name': name}
img = 'ft_done.png' img_name = 'gajim-ft_done'
else: # ft stopped else: # ft stopped
txt = _('File transfer of %(filename)s to %(name)s stopped.')\ txt = _('File transfer of %(filename)s to %(name)s stopped.')\
% {'filename': filename, 'name': name} % {'filename': filename, 'name': name}
img = 'ft_stopped.png' img_name = 'gajim-ft_stopped'
img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', img) path = gtkgui_helpers.get_icon_path(img_name, 48)
path = gtkgui_helpers.get_path_to_generic_or_avatar(img)
else: else:
txt = '' txt = ''
path = ''
if gajim.config.get('notify_on_file_complete') and \ if gajim.config.get('notify_on_file_complete') and \
(gajim.config.get('autopopupaway') or \ (gajim.config.get('autopopupaway') or \
gajim.connections[account].connected in (2, 3)): gajim.connections[account].connected in (2, 3)):
# we want to be notified and we are online/chat or we don't mind # we want to be notified and we are online/chat or we don't mind
# bugged when away/na/busy # bugged when away/na/busy
notify.popup(event_type, jid, account, msg_type, path_to_image = path, notify.popup(event_type, jid, account, msg_type, path_to_image=path,
title = event_type, text = txt) title=event_type, text=txt)
def handle_event_stanza_arrived(self, account, stanza): def handle_event_stanza_arrived(self, account, stanza):
if account not in self.instances: if account not in self.instances:
@ -1766,11 +1752,9 @@ class Interface:
if helpers.allow_showing_notification(account): if helpers.allow_showing_notification(account):
# TODO: we should use another pixmap ;-) # 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( txt = _('%s wants to start a voice chat.') % gajim.get_name_from_jid(
account, peerjid) 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') event_type = _('Voice Chat Request')
notify.popup(event_type, peerjid, account, 'jingle-incoming', notify.popup(event_type, peerjid, account, 'jingle-incoming',
path_to_image = path, title = event_type, text = txt) path_to_image = path, title = event_type, text = txt)
@ -2778,8 +2762,8 @@ class Interface:
if status in ('chat', 'away', 'xa', 'dnd', 'invisible', 'offline'): if status in ('chat', 'away', 'xa', 'dnd', 'invisible', 'offline'):
status = status + '.png' status = status + '.png'
elif status == 'online': elif status == 'online':
prefix = os.path.join(gajim.DATA_DIR, 'pixmaps') prefix = ''
status = 'gajim.png' status = gtkgui_helpers.get_icon_path('gajim', 32)
path = os.path.join(prefix, status) path = os.path.join(prefix, status)
try: try:
obj = bus.get_object('com.google.code.Awn', '/com/google/code/Awn') obj = bus.get_object('com.google.code.Awn', '/com/google/code/Awn')
@ -3382,8 +3366,7 @@ class Interface:
import statusicon import statusicon
self.systray = statusicon.StatusIcon() self.systray = statusicon.StatusIcon()
path_to_file = os.path.join(gajim.DATA_DIR, 'pixmaps', 'gajim.png') pix = gtkgui_helpers.get_icon_pixmap('gajim', 32)
pix = gtk.gdk.pixbuf_new_from_file(path_to_file)
# set the icon to all windows # set the icon to all windows
gtk.window_set_default_icon(pix) gtk.window_set_default_icon(pix)

View file

@ -207,11 +207,7 @@ def get_contact_menu(contact, account, use_multiple_contacts=True,
if not our_jid: if not our_jid:
# add a special img for rename menuitem # add a special img for rename menuitem
path_to_kbd_input_img = os.path.join(gajim.DATA_DIR, 'pixmaps', gtkgui_helpers.add_image_to_menuitem(rename_menuitem, 'gajim-kbd_input')
'kbd_input.png')
img = gtk.Image()
img.set_from_file(path_to_kbd_input_img)
rename_menuitem.set_image(img)
muc_icon = gtkgui_helpers.load_icon('muc_active') muc_icon = gtkgui_helpers.load_icon('muc_active')
if muc_icon: if muc_icon:

View file

@ -102,19 +102,12 @@ C_NICKNAME
) = range(2, 6) ) = range(2, 6)
try: import sqlite3 as sqlite
import sqlite3 as sqlite # python 2.5
except ImportError:
try:
from pysqlite2 import dbapi2 as sqlite
except ImportError:
raise exceptions.PysqliteNotAvailable
class HistoryManager: class HistoryManager:
def __init__(self): def __init__(self):
path_to_file = os.path.join(gajim.DATA_DIR, 'pixmaps/gajim.png') pix = gtkgui_helpers.get_icon_pixmap('gajim')
pix = gtk.gdk.pixbuf_new_from_file(path_to_file)
gtk.window_set_default_icon(pix) # set the icon to all newly opened windows gtk.window_set_default_icon(pix) # set the icon to all newly opened windows
if not os.path.exists(LOG_DB_PATH): if not os.path.exists(LOG_DB_PATH):

View file

@ -892,8 +892,10 @@ class HtmlTextView(gtk.TextView):
def on_text_buffer_mark_set(self, location, mark, unused_data): def on_text_buffer_mark_set(self, location, mark, unused_data):
bounds = self.get_buffer().get_selection_bounds() bounds = self.get_buffer().get_selection_bounds()
if bounds: if bounds:
clipboard = self.get_clipboard(gtk.gdk.SELECTION_PRIMARY) # textview can be hidden while we add a new line in it.
clipboard.set_text(self.get_selected_text()) if self.has_screen():
clipboard = self.get_clipboard(gtk.gdk.SELECTION_PRIMARY)
clipboard.set_text(self.get_selected_text())
def get_selected_text(self): def get_selected_text(self):
bounds = self.get_buffer().get_selection_bounds() bounds = self.get_buffer().get_selection_bounds()
@ -939,12 +941,12 @@ if __name__ == '__main__':
htmlview = ConversationTextview(None) 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 # 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() tooltip = tooltips.BaseTooltip()
def on_textview_motion_notify_event(widget, event): def on_textview_motion_notify_event(widget, event):
""" """
Change the cursor to a hand when we are over a mail or an url Change the cursor to a hand when we are over a mail or an url

View file

@ -234,16 +234,16 @@ def notify(event, jid, account, parameters, advanced_notif_num=None):
show_image = 'online.png' show_image = 'online.png'
suffix = '_notif_size_colored' suffix = '_notif_size_colored'
transport_name = gajim.get_transport_name_from_jid(jid) transport_name = gajim.get_transport_name_from_jid(jid)
img = None img_path = None
if transport_name: 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) '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') 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) show_image)
path = gtkgui_helpers.get_path_to_generic_or_avatar(img, path = gtkgui_helpers.get_path_to_generic_or_avatar(img_path, jid=jid,
jid = jid, suffix = suffix) suffix=suffix)
if event == 'status_change': if event == 'status_change':
title = _('%(nick)s Changed Status') % \ title = _('%(nick)s Changed Status') % \
{'nick': gajim.get_name_from_jid(account, jid)} {'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': elif event == 'new_message':
if message_type == 'normal': # single message if message_type == 'normal': # single message
event_type = _('New Single Message') event_type = _('New Single Message')
img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', img_name = 'gajim-single_msg_recv'
'single_msg_recv.png')
title = _('New Single Message from %(nickname)s') % \ title = _('New Single Message from %(nickname)s') % \
{'nickname': nickname} {'nickname': nickname}
text = message text = message
elif message_type == 'pm': # private message elif message_type == 'pm': # private message
event_type = _('New Private Message') event_type = _('New Private Message')
room_name = gajim.get_nick_from_jid(jid) room_name = gajim.get_nick_from_jid(jid)
img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', img_name = 'gajim-priv_msg_recv'
'priv_msg_recv.png')
title = _('New Private Message from group chat %s') % room_name title = _('New Private Message from group chat %s') % room_name
if message: if message:
text = _('%(nickname)s: %(message)s') % {'nickname': nickname, text = _('%(nickname)s: %(message)s') % {'nickname': nickname,
@ -292,14 +290,13 @@ def notify(event, jid, account, parameters, advanced_notif_num=None):
else: # chat message else: # chat message
event_type = _('New Message') event_type = _('New Message')
img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', img_name = 'gajim-chat_msg_recv'
'chat_msg_recv.png')
title = _('New Message from %(nickname)s') % \ title = _('New Message from %(nickname)s') % \
{'nickname': nickname} {'nickname': nickname}
text = message 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, 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: if do_sound:
snd_file = None snd_file = None
@ -342,9 +339,7 @@ def popup(event_type, jid, account, msg_type='', path_to_image=None, title=None,
""" """
# default image # default image
if not path_to_image: if not path_to_image:
path_to_image = os.path.abspath( path_to_image = gtkgui_helpers.get_icon_path('gajim-chat_msg_recv', 48)
os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
'chat_msg_recv.png')) # img to display
if gajim.HAVE_INDICATOR and event_type in (_('New Message'), if gajim.HAVE_INDICATOR and event_type in (_('New Message'),
_('New Single Message'), _('New Private Message')): _('New Single Message'), _('New Private Message')):
@ -529,9 +524,8 @@ class DesktopNotification:
ntype = 'unsubscribed' ntype = 'unsubscribed'
else: else:
# default failsafe values # default failsafe values
self.path_to_image = os.path.abspath( self.path_to_image = gtkgui_helpers.get_icon_path(
os.path.join(gajim.DATA_DIR, 'pixmaps', 'events', 'gajim-chat_msg_recv', 48)
'chat_msg_recv.png')) # img to display
ntype = 'im' # Notification Type ntype = 'im' # Notification Type
self.notif = dbus_support.get_notifications_interface(self) self.notif = dbus_support.get_notifications_interface(self)
@ -554,8 +548,7 @@ class DesktopNotification:
notification_text = ('<html><img src="%(image)s" align=left />' \ notification_text = ('<html><img src="%(image)s" align=left />' \
'%(title)s<br/>%(text)s</html>') % {'title': self.title, '%(title)s<br/>%(text)s</html>') % {'title': self.title,
'text': self.text, 'image': self.path_to_image} 'text': self.text, 'image': self.path_to_image}
gajim_icon = os.path.abspath(os.path.join(gajim.DATA_DIR, 'pixmaps', gajim_icon = gtkgui_helpers.get_icon_path('gajim', 48)
'gajim.png'))
self.notif.Notify( self.notif.Notify(
dbus.String(_('Gajim')), # app_name (string) dbus.String(_('Gajim')), # app_name (string)
dbus.UInt32(0), # replaces_id (uint) dbus.UInt32(0), # replaces_id (uint)

View file

@ -4962,10 +4962,7 @@ class RosterWindow:
sub_menu.append(item) sub_menu.append(item)
item = gtk.ImageMenuItem(_('_Change Status Message')) item = gtk.ImageMenuItem(_('_Change Status Message'))
path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'kbd_input.png') gtkgui_helpers.add_image_to_menuitem(item, 'gajim-kbd_input')
img = gtk.Image()
img.set_from_file(path)
item.set_image(img)
sub_menu.append(item) sub_menu.append(item)
item.connect('activate', self.on_change_status_message_activate, item.connect('activate', self.on_change_status_message_activate,
account) account)
@ -5063,10 +5060,7 @@ class RosterWindow:
sub_menu.append(item) sub_menu.append(item)
item = gtk.ImageMenuItem(_('_Change Status Message')) item = gtk.ImageMenuItem(_('_Change Status Message'))
path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'kbd_input.png') gtkgui_helpers.add_image_to_menuitem(item, 'gajim-kbd_input')
img = gtk.Image()
img.set_from_file(path)
item.set_image(img)
sub_menu.append(item) sub_menu.append(item)
item.connect('activate', self.on_change_status_message_activate, item.connect('activate', self.on_change_status_message_activate,
account) account)
@ -5219,11 +5213,7 @@ class RosterWindow:
# Rename # Rename
rename_item = gtk.ImageMenuItem(_('Re_name')) rename_item = gtk.ImageMenuItem(_('Re_name'))
# add a special img for rename menuitem # add a special img for rename menuitem
path_to_kbd_input_img = os.path.join(gajim.DATA_DIR, 'pixmaps', gtkgui_helpers.add_image_to_menuitem(rename_item, 'gajim-kbd_input')
'kbd_input.png')
img = gtk.Image()
img.set_from_file(path_to_kbd_input_img)
rename_item.set_image(img)
menu.append(rename_item) menu.append(rename_item)
rename_item.connect('activate', self.on_rename, 'group', group, rename_item.connect('activate', self.on_rename, 'group', group,
account) account)
@ -5481,11 +5471,7 @@ class RosterWindow:
# Rename # Rename
item = gtk.ImageMenuItem(_('_Rename')) item = gtk.ImageMenuItem(_('_Rename'))
# add a special img for rename menuitem # add a special img for rename menuitem
path_to_kbd_input_img = os.path.join(gajim.DATA_DIR, 'pixmaps', gtkgui_helpers.add_image_to_menuitem(item, 'gajim-kbd_input')
'kbd_input.png')
img = gtk.Image()
img.set_from_file(path_to_kbd_input_img)
item.set_image(img)
manage_transport_submenu.append(item) manage_transport_submenu.append(item)
item.connect('activate', self.on_rename, 'agent', jid, account) item.connect('activate', self.on_rename, 'agent', jid, account)
if gajim.account_is_disconnected(account): if gajim.account_is_disconnected(account):
@ -5813,7 +5799,7 @@ class RosterWindow:
# Add a Separator (self._iter_is_separator() checks on string SEPARATOR) # Add a Separator (self._iter_is_separator() checks on string SEPARATOR)
liststore.append(['SEPARATOR', None, '', True]) 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 = gtk.Image()
img.set_from_file(path) img.set_from_file(path)
# sensitivity to False because by default we're offline # sensitivity to False because by default we're offline

View file

@ -207,10 +207,7 @@ class StatusIcon:
sub_menu.append(item) sub_menu.append(item)
item = gtk.ImageMenuItem(_('_Change Status Message...')) item = gtk.ImageMenuItem(_('_Change Status Message...'))
path = os.path.join(gajim.DATA_DIR, 'pixmaps', 'kbd_input.png') gtkgui_helpers.add_image_to_menuitem(item, 'gajim-kbd_input')
img = gtk.Image()
img.set_from_file(path)
item.set_image(img)
sub_menu.append(item) sub_menu.append(item)
item.connect('activate', self.on_change_status_message_activate) item.connect('activate', self.on_change_status_message_activate)