Merge local changes.
| 
						 | 
				
			
			@ -1962,7 +1962,6 @@ $T will be replaced by auto-not-available timeout</property>
 | 
			
		|||
                              <packing>
 | 
			
		||||
                                <property name="left_attach">1</property>
 | 
			
		||||
                                <property name="right_attach">2</property>
 | 
			
		||||
                                <property name="x_options"></property>
 | 
			
		||||
                              </packing>
 | 
			
		||||
                            </child>
 | 
			
		||||
                            <child>
 | 
			
		||||
| 
						 | 
				
			
			@ -1975,7 +1974,6 @@ $T will be replaced by auto-not-available timeout</property>
 | 
			
		|||
                                <property name="right_attach">2</property>
 | 
			
		||||
                                <property name="top_attach">1</property>
 | 
			
		||||
                                <property name="bottom_attach">2</property>
 | 
			
		||||
                                <property name="x_options"></property>
 | 
			
		||||
                              </packing>
 | 
			
		||||
                            </child>
 | 
			
		||||
                            <child>
 | 
			
		||||
| 
						 | 
				
			
			@ -2066,7 +2064,6 @@ $T will be replaced by auto-not-available timeout</property>
 | 
			
		|||
                              <packing>
 | 
			
		||||
                                <property name="left_attach">1</property>
 | 
			
		||||
                                <property name="right_attach">2</property>
 | 
			
		||||
                                <property name="x_options"></property>
 | 
			
		||||
                              </packing>
 | 
			
		||||
                            </child>
 | 
			
		||||
                            <child>
 | 
			
		||||
| 
						 | 
				
			
			@ -2079,7 +2076,6 @@ $T will be replaced by auto-not-available timeout</property>
 | 
			
		|||
                                <property name="right_attach">2</property>
 | 
			
		||||
                                <property name="top_attach">1</property>
 | 
			
		||||
                                <property name="bottom_attach">2</property>
 | 
			
		||||
                                <property name="x_options"></property>
 | 
			
		||||
                              </packing>
 | 
			
		||||
                            </child>
 | 
			
		||||
                          </widget>
 | 
			
		||||
| 
						 | 
				
			
			@ -2102,6 +2098,74 @@ $T will be replaced by auto-not-available timeout</property>
 | 
			
		|||
                    <property name="position">1</property>
 | 
			
		||||
                  </packing>
 | 
			
		||||
                </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"><i>(example: stunserver.org)</i></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">●</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"><b>Connection</b></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>
 | 
			
		||||
              <packing>
 | 
			
		||||
                <property name="position">5</property>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
		 Before Width: | Height: | Size: 594 B  | 
| 
						 | 
				
			
			@ -1,4 +1,7 @@
 | 
			
		|||
iconsdir = $(pkgdatadir)/icons
 | 
			
		||||
nobase_dist_icons_DATA = $(srcdir)/*/*/*/*
 | 
			
		||||
 | 
			
		||||
systemiconsdir = $(datadir)/icons
 | 
			
		||||
nobase_dist_systemicons_DATA = $(srcdir)/*/*/*/gajim.*
 | 
			
		||||
 | 
			
		||||
MAINTAINERCLEANFILES = Makefile.in
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
		 Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB  | 
| 
		 Before Width: | Height: | Size: 988 B After Width: | Height: | Size: 988 B  | 
| 
		 Before Width: | Height: | Size: 963 B After Width: | Height: | Size: 963 B  | 
| 
		 Before Width: | Height: | Size: 189 B After Width: | Height: | Size: 189 B  | 
| 
		 Before Width: | Height: | Size: 788 B After Width: | Height: | Size: 788 B  | 
| 
		 Before Width: | Height: | Size: 773 B After Width: | Height: | Size: 773 B  | 
| 
		 Before Width: | Height: | Size: 209 B After Width: | Height: | Size: 209 B  | 
| 
		 Before Width: | Height: | Size: 353 B After Width: | Height: | Size: 353 B  | 
| 
		 Before Width: | Height: | Size: 790 B After Width: | Height: | Size: 790 B  | 
| 
		 Before Width: | Height: | Size: 844 B After Width: | Height: | Size: 844 B  | 
| 
		 Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB  | 
| 
		 Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB  | 
| 
		 Before Width: | Height: | Size: 994 B After Width: | Height: | Size: 994 B  | 
| 
		 Before Width: | Height: | Size: 874 B After Width: | Height: | Size: 874 B  | 
| 
		 Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB  | 
| 
		 Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1 KiB  | 
| 
		 Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB  | 
| 
		 Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB  | 
| 
		 Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB  | 
| 
		 Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB  | 
| 
		 Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB  | 
| 
		 Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB  | 
| 
		 Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1 KiB  | 
| 
		 Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB  | 
| 
		 Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB  | 
| 
		 Before Width: | Height: | Size: 959 B After Width: | Height: | Size: 959 B  | 
| 
		 Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB  | 
| 
		 Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB  | 
| 
		 Before Width: | Height: | Size: 997 B After Width: | Height: | Size: 997 B  | 
| 
		 Before Width: | Height: | Size: 766 B After Width: | Height: | Size: 766 B  | 
| 
		 Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB  | 
| 
		 Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB  | 
| 
		 Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB  | 
| 
		 Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB  | 
| 
		 Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB  | 
| 
		 Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB  | 
| 
		 Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB  | 
| 
		 Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB  | 
| 
		 Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB  | 
| 
		 Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB  | 
| 
		 Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB  | 
| 
		 Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB  | 
| 
		 Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB  | 
| 
		 Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB  | 
| 
		 Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB  | 
| 
		 Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB  | 
| 
		 Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB  | 
| 
		 Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB  | 
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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):
 | 
			
		||||
    """
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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]:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,17 +21,6 @@
 | 
			
		|||
## 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):
 | 
			
		||||
	"""
 | 
			
		||||
	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):
 | 
			
		||||
	"""
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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']
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 <someone@somewhere>
 | 
			
		||||
| 
						 | 
				
			
			@ -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 <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:
 | 
			
		||||
			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(
 | 
			
		||||
				'<b><span size="x-large">' +
 | 
			
		||||
				verification_status +
 | 
			
		||||
				'</span></b>')
 | 
			
		||||
				'<b><span size="x-large">%s</span></b>' % 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 <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''')
 | 
			
		||||
			self.window.set_title(verification_status)
 | 
			
		||||
			self.xml.get_widget('verification_status_label').set_markup(
 | 
			
		||||
				'<b><span size="x-large">' +
 | 
			
		||||
				verification_status +
 | 
			
		||||
				'</span></b>')
 | 
			
		||||
				'<b><span size="x-large">%s</span></b>' % 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) <b>does not match</b> 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 <b>you do not '
 | 
			
		||||
						 'trust his key</b>, so message <b>cannot</b> 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('<b><span size="x-large">%s</span></b>' % \
 | 
			
		||||
								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()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										73
									
								
								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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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?')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 = ('<html><img src="%(image)s" align=left />' \
 | 
			
		||||
				'%(title)s<br/>%(text)s</html>') % {'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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||