Merge changes from default branch into refactoring branch
Hg: changed data/pixmaps/mic_active.png
This commit is contained in:
commit
022003239d
|
@ -465,7 +465,7 @@
|
|||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Show a menu of advanced functions (Alt+A)</property>
|
||||
<property name="tooltip" translatable="yes">Show a menu of advanced functions (Alt+D)</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<child>
|
||||
|
@ -934,7 +934,7 @@
|
|||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Show a menu of advanced functions (Alt+A)</property>
|
||||
<property name="tooltip" translatable="yes">Show a menu of advanced functions (Alt+D)</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<child>
|
||||
|
|
|
@ -1777,7 +1777,7 @@ $T will be replaced by auto-not-available timeout</property>
|
|||
<property name="receives_default">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="color">#000000000000</property>
|
||||
<signal name="color_set" handler="on_incoming_msg_colorbutton_color_set"/>
|
||||
<signal name="color_set" handler="on_incoming_nick_colorbutton_color_set"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
|
|
@ -85,12 +85,42 @@
|
|||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="accept_button">
|
||||
<property name="label" translatable="yes">gtk-ok</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="on_accept_button_clicked"/>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">3</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="stock">gtk-ok</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="accept_button_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_OK</property>
|
||||
<property name="use_underline">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 988 B |
Binary file not shown.
After Width: | Height: | Size: 963 B |
Binary file not shown.
After Width: | Height: | Size: 788 B |
Binary file not shown.
After Width: | Height: | Size: 773 B |
|
@ -65,6 +65,7 @@ opts = {
|
|||
'excludes': [
|
||||
'docutils'
|
||||
],
|
||||
'optimize': 2,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1213,10 +1213,22 @@ class ChatControl(ChatControlBase):
|
|||
self._audio_button = self.xml.get_widget('audio_togglebutton')
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
self._send_file_button = self.xml.get_widget('send_file_button')
|
||||
# add a special img for send file button
|
||||
|
@ -1818,31 +1830,43 @@ class ChatControl(ChatControlBase):
|
|||
|
||||
def on_audio_button_toggled(self, widget):
|
||||
if widget.get_active():
|
||||
path_to_img = os.path.join(gajim.DATA_DIR, 'pixmaps',
|
||||
'mic_active.png')
|
||||
if self.audio_state == self.JINGLE_STATE_AVAILABLE:
|
||||
sid = gajim.connections[self.account].startVoIP(
|
||||
self.contact.get_full_jid())
|
||||
self.set_audio_state('connecting', sid)
|
||||
else:
|
||||
path_to_img = os.path.join(gajim.DATA_DIR, 'pixmaps',
|
||||
'mic_inactive.png')
|
||||
session = gajim.connections[self.account].get_jingle_session(
|
||||
self.contact.get_full_jid(), self.audio_sid)
|
||||
if session:
|
||||
content = session.get_content('audio')
|
||||
if content:
|
||||
session.remove_content(content.creator, content.name)
|
||||
img = self._audio_button.get_property('image')
|
||||
img.set_from_file(path_to_img)
|
||||
|
||||
def on_video_button_toggled(self, widget):
|
||||
if widget.get_active():
|
||||
path_to_img = os.path.join(gajim.DATA_DIR, 'pixmaps',
|
||||
'cam_active.png')
|
||||
if self.video_state == self.JINGLE_STATE_AVAILABLE:
|
||||
sid = gajim.connections[self.account].startVideoIP(
|
||||
self.contact.get_full_jid())
|
||||
self.set_video_state('connecting', sid)
|
||||
else:
|
||||
path_to_img = os.path.join(gajim.DATA_DIR, 'pixmaps',
|
||||
'cam_inactive.png')
|
||||
session = gajim.connections[self.account].get_jingle_session(
|
||||
self.contact.get_full_jid(), self.video_sid)
|
||||
if session:
|
||||
content = session.get_content('video')
|
||||
if content:
|
||||
session.remove_content(content.creator, content.name)
|
||||
img = self._video_button.get_property('image')
|
||||
img.set_from_file(path_to_img)
|
||||
|
||||
def _toggle_gpg(self):
|
||||
if not self.gpg_is_active and not self.contact.keyID:
|
||||
|
|
|
@ -98,6 +98,28 @@ class StandardChatCommands(CommandContainer):
|
|||
raise CommandError(_('Command is not supported for zeroconf accounts'))
|
||||
gajim.connections[self.account].sendPing(self.contact)
|
||||
|
||||
@command('audio')
|
||||
@documentation(_("Toggle audio session"))
|
||||
def audio(self):
|
||||
if self.audio_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
raise CommandError(_("Video sessions are not available"))
|
||||
else:
|
||||
# A state of an audio session is toggled by inverting a state of the
|
||||
# appropriate button.
|
||||
state = self._audio_button.get_active()
|
||||
self._audio_button.set_active(not state)
|
||||
|
||||
@command('video')
|
||||
@documentation(_("Toggle video session"))
|
||||
def video(self):
|
||||
if self.video_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
raise CommandError(_("Video sessions are not available"))
|
||||
else:
|
||||
# A state of a video session is toggled by inverting a state of the
|
||||
# appropriate button.
|
||||
state = self._video_button.get_active()
|
||||
self._video_button.set_active(not state)
|
||||
|
||||
class StandardPrivateChatCommands(CommandContainer):
|
||||
"""
|
||||
This command container contains standard command which are unique to a
|
||||
|
|
|
@ -172,7 +172,7 @@ class AbstractClientCaps(object):
|
|||
def _is_hash_valid(self, identities, features, dataforms):
|
||||
''' To be implemented by subclassess '''
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
|
||||
class ClientCaps(AbstractClientCaps):
|
||||
''' The current XEP-115 implementation '''
|
||||
|
@ -252,7 +252,7 @@ class CapsCache(object):
|
|||
# another object, and we will have plenty of identical long
|
||||
# strings. therefore we can cache them
|
||||
__names = {}
|
||||
|
||||
|
||||
def __init__(self, hash_method, hash_, logger):
|
||||
# cached into db
|
||||
self.hash_method = hash_method
|
||||
|
|
|
@ -777,7 +777,10 @@ class Connection(ConnectionHandlers):
|
|||
self.server_resource = con.Resource
|
||||
if gajim.config.get_per('accounts', self.name, 'anonymous_auth'):
|
||||
# Get jid given by server
|
||||
old_jid = gajim.get_jid_from_account(self.name)
|
||||
gajim.config.set_per('accounts', self.name, 'name', con.User)
|
||||
new_jid = gajim.get_jid_from_account(self.name)
|
||||
self.dispatch('NEW_JID', (old_jid, new_jid))
|
||||
if auth:
|
||||
self.last_io = gajim.idlequeue.current_time()
|
||||
self.connected = 2
|
||||
|
@ -1298,7 +1301,7 @@ class Connection(ConnectionHandlers):
|
|||
# chatstates - if peer supports xep85 or xep22, send chatstates
|
||||
# please note that the only valid tag inside a message containing a <body>
|
||||
# tag is the active event
|
||||
if chatstate is not None:
|
||||
if chatstate is not None and contact:
|
||||
if ((composing_xep == 'XEP-0085' or not composing_xep) \
|
||||
and composing_xep != 'asked_once') or \
|
||||
contact.supports(common.xmpp.NS_CHATSTATES):
|
||||
|
@ -1327,7 +1330,8 @@ class Connection(ConnectionHandlers):
|
|||
|
||||
# XEP-0184
|
||||
if msgtxt and gajim.config.get_per('accounts', self.name,
|
||||
'request_receipt') and contact.supports(common.xmpp.NS_RECEIPTS):
|
||||
'request_receipt') and contact and contact.supports(
|
||||
common.xmpp.NS_RECEIPTS):
|
||||
msg_iq.setTag('request', namespace=common.xmpp.NS_RECEIPTS)
|
||||
|
||||
if session:
|
||||
|
@ -1576,8 +1580,8 @@ class Connection(ConnectionHandlers):
|
|||
to_whom_jid = jid
|
||||
if resource:
|
||||
to_whom_jid += '/' + resource
|
||||
iq = common.xmpp.Iq(to=to_whom_jid, typ='get', queryNS=\
|
||||
common.xmpp.NS_TIME_REVISED)
|
||||
iq = common.xmpp.Iq(to=to_whom_jid, typ='get')
|
||||
iq.addChild('time', namespace=common.xmpp.NS_TIME_REVISED)
|
||||
id_ = self.connection.getAnID()
|
||||
iq.setID(id_)
|
||||
if groupchat_jid:
|
||||
|
|
|
@ -73,7 +73,7 @@ class CommonContact(XMPPEntity):
|
|||
|
||||
def get_shown_name(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
def supports(self, requested_feature):
|
||||
'''
|
||||
Returns True if the contact has advertised to support the feature
|
||||
|
@ -297,6 +297,9 @@ class Contacts:
|
|||
def get_jid_list(self, account):
|
||||
return self._accounts[account].contacts.get_jid_list()
|
||||
|
||||
def change_contact_jid(self, old_jid, new_jid, account):
|
||||
return self._accounts[account].change_contact_jid(old_jid, new_jid)
|
||||
|
||||
def get_highest_prio_contact_from_contacts(self, contacts):
|
||||
if not contacts:
|
||||
return None
|
||||
|
@ -486,9 +489,17 @@ class Contacts_New():
|
|||
if group in contacts[0].groups:
|
||||
group_contacts += contacts
|
||||
return group_contacts
|
||||
|
||||
|
||||
|
||||
|
||||
def change_contact_jid(self, old_jid, new_jid):
|
||||
if old_jid not in self._contacts:
|
||||
return
|
||||
self._contacts[new_jid] = []
|
||||
for _contact in self._contacts[old_jid]:
|
||||
_contact.jid = new_jid
|
||||
self._contacts[new_jid].append(_contact)
|
||||
del self._contacts[old_jid]
|
||||
|
||||
|
||||
class GC_Contacts():
|
||||
|
||||
def __init__(self):
|
||||
|
|
|
@ -286,7 +286,10 @@ class HostTester(Socks5, IdleObject):
|
|||
elif self.state == 3:
|
||||
log.debug('Host authenticated to %s:%s' % (self.host, self.port))
|
||||
self.on_success()
|
||||
self.disconnect()
|
||||
self.state += 1
|
||||
else:
|
||||
assert False, 'unexpected state: %d' % self.state
|
||||
|
||||
def do_connect(self):
|
||||
try:
|
||||
|
@ -402,7 +405,10 @@ class ReceiverTester(Socks5, IdleObject):
|
|||
return
|
||||
log.debug('Receiver authenticated to %s:%s' % (self.host, self.port))
|
||||
self.on_success()
|
||||
self.disconnect()
|
||||
self.state += 1
|
||||
else:
|
||||
assert False, 'unexpected state: %d' % self.state
|
||||
|
||||
def do_connect(self):
|
||||
try:
|
||||
|
|
|
@ -41,14 +41,6 @@ except ImportError:
|
|||
USE_LIBASYNCNS = False
|
||||
log.debug("Import of libasyncns-python failed, getaddrinfo will block", exc_info=True)
|
||||
|
||||
# FIXME: Remove these prints before release, replace with a warning dialog.
|
||||
print >> sys.stderr, "=" * 79
|
||||
print >> sys.stderr, "libasyncns-python not installed which means:"
|
||||
print >> sys.stderr, " - nslookup will be used for SRV and TXT requests"
|
||||
print >> sys.stderr, " - getaddrinfo will block"
|
||||
print >> sys.stderr, "libasyncns-python can be found at https://launchpad.net/libasyncns-python"
|
||||
print >> sys.stderr, "=" * 79
|
||||
|
||||
|
||||
def get_resolver(idlequeue):
|
||||
if USE_LIBASYNCNS:
|
||||
|
|
|
@ -2860,7 +2860,7 @@ class RosterItemExchangeWindow:
|
|||
self.window = self.xml.get_widget('roster_item_exchange_window')
|
||||
|
||||
# Add Widgets.
|
||||
for widget_to_add in ['cancel_button', 'accept_button', 'type_label',
|
||||
for widget_to_add in ['accept_button_label', 'type_label',
|
||||
'body_scrolledwindow', 'body_textview', 'items_list_treeview']:
|
||||
self.__dict__[widget_to_add] = self.xml.get_widget(widget_to_add)
|
||||
|
||||
|
@ -2928,9 +2928,7 @@ class RosterItemExchangeWindow:
|
|||
model.set(iter, 0, True, 1, jid, 2, name, 3, groups)
|
||||
|
||||
# Change label for accept_button to action name instead of 'OK'.
|
||||
accept_button_label = self.accept_button.get_children()[0].\
|
||||
get_children()[0].get_children()[1]
|
||||
accept_button_label.set_label(_('Add'))
|
||||
self.accept_button_label.set_label(_('Add'))
|
||||
elif action == 'modify':
|
||||
for jid in self.exchange_list:
|
||||
groups = ''
|
||||
|
@ -2961,9 +2959,7 @@ class RosterItemExchangeWindow:
|
|||
model.set(iter, 0, True, 1, jid, 2, name, 3, groups)
|
||||
|
||||
# Change label for accept_button to action name instead of 'OK'.
|
||||
accept_button_label = self.accept_button.get_children()[0].\
|
||||
get_children()[0].get_children()[1]
|
||||
accept_button_label.set_label(_('Modify'))
|
||||
self.accept_button_label.set_label(_('Modify'))
|
||||
elif action == 'delete':
|
||||
for jid in self.exchange_list:
|
||||
groups = ''
|
||||
|
@ -2987,9 +2983,7 @@ class RosterItemExchangeWindow:
|
|||
model.set(iter, 0, True, 1, jid, 2, name, 3, groups)
|
||||
|
||||
# Change label for accept_button to action name instead of 'OK'.
|
||||
accept_button_label = self.accept_button.get_children()[0].\
|
||||
get_children()[0].get_children()[1]
|
||||
accept_button_label.set_label(_('Delete'))
|
||||
self.accept_button_label.set_label(_('Delete'))
|
||||
|
||||
if show_dialog:
|
||||
self.window.show_all()
|
||||
|
|
|
@ -263,6 +263,14 @@ class Interface:
|
|||
if self.remote_ctrl:
|
||||
self.remote_ctrl.raise_signal('AccountPresence', (show, account))
|
||||
|
||||
def handle_event_new_jid(self, account, data):
|
||||
#('NEW_JID', account, (old_jid, new_jid))
|
||||
'''
|
||||
This event is raised when our JID changed (most probably because we use
|
||||
anonymous account. We update contact and roster entry in this case.
|
||||
'''
|
||||
self.roster.rename_self_contact(data[0], data[1], account)
|
||||
|
||||
def edit_own_details(self, account):
|
||||
jid = gajim.get_jid_from_account(account)
|
||||
if 'profile' not in self.instances[account]:
|
||||
|
@ -1512,6 +1520,7 @@ class Interface:
|
|||
|
||||
def handle_event_signed_in(self, account, empty):
|
||||
'''SIGNED_IN event is emitted when we sign in, so handle it'''
|
||||
# ('SIGNED_IN', account, ())
|
||||
# block signed in notifications for 30 seconds
|
||||
gajim.block_signed_in_notifications[account] = True
|
||||
self.roster.set_actions_menu_needs_rebuild()
|
||||
|
@ -1998,6 +2007,7 @@ class Interface:
|
|||
'INFORMATION': [self.handle_event_information],
|
||||
'ERROR_ANSWER': [self.handle_event_error_answer],
|
||||
'STATUS': [self.handle_event_status],
|
||||
'NEW_JID': [self.handle_event_new_jid],
|
||||
'NOTIFY': [self.handle_event_notify],
|
||||
'MSGERROR': [self.handle_event_msgerror],
|
||||
'MSGSENT': [self.handle_event_msgsent],
|
||||
|
|
|
@ -473,7 +473,7 @@ class HtmlHandler(xml.sax.handler.ContentHandler):
|
|||
tag.href = href
|
||||
tag.type_ = type_ # to be used by the URL handler
|
||||
tag.connect('event', self.textview.html_hyperlink_handler, 'url', href)
|
||||
tag.set_property('foreground', '#0000ff')
|
||||
tag.set_property('foreground', gajim.config.get('urlmsgcolor'))
|
||||
tag.set_property('underline', pango.UNDERLINE_SINGLE)
|
||||
tag.is_anchor = True
|
||||
if title:
|
||||
|
|
|
@ -103,7 +103,7 @@ class MessageWindow(object):
|
|||
'<Control>l', '<Control>L', '<Control>n', '<Control>u',
|
||||
'<Control>b', '<Control><Shift>Tab', '<Control>Tab', '<Control>F4',
|
||||
'<Control>w', '<Control>Page_Up', '<Control>Page_Down', '<Alt>Right',
|
||||
'<Alt>Left', '<Alt>a', '<Alt>c', '<Alt>m', '<Alt>t', 'Escape'] + \
|
||||
'<Alt>Left', '<Alt>d', '<Alt>c', '<Alt>m', '<Alt>t', 'Escape'] + \
|
||||
['<Alt>'+str(i) for i in xrange(10)]
|
||||
accel_group = gtk.AccelGroup()
|
||||
for key in keys:
|
||||
|
@ -165,6 +165,8 @@ class MessageWindow(object):
|
|||
return
|
||||
if old_jid not in self._controls[account]:
|
||||
return
|
||||
if old_jid == new_jid:
|
||||
return
|
||||
self._controls[account][new_jid] = self._controls[account][old_jid]
|
||||
del self._controls[account][old_jid]
|
||||
|
||||
|
@ -403,7 +405,7 @@ class MessageWindow(object):
|
|||
control.chat_buttons_set_visible(not control.hide_chat_buttons)
|
||||
elif keyval == gtk.keysyms.m: # ALT + M show emoticons menu
|
||||
control.show_emoticons_menu()
|
||||
elif keyval == gtk.keysyms.a: # ALT + A show actions menu
|
||||
elif keyval == gtk.keysyms.d: # ALT + D show actions menu
|
||||
control.on_actions_button_clicked(control.actions_button)
|
||||
elif control.type_id == message_control.TYPE_GC and \
|
||||
keyval == gtk.keysyms.t: # ALT + t
|
||||
|
|
|
@ -134,11 +134,10 @@ class RosterWindow:
|
|||
return group_iter
|
||||
|
||||
|
||||
def _get_self_contact_iter(self, jid, account, model=None):
|
||||
def _get_self_contact_iter(self, account, model=None):
|
||||
''' Return the gtk.TreeIter of SelfContact or None if not found.
|
||||
|
||||
Keyword arguments:
|
||||
jid -- the jid of SelfContact
|
||||
account -- the account of SelfContact
|
||||
model -- the data model (default TreeFilterModel)
|
||||
|
||||
|
@ -153,8 +152,8 @@ class RosterWindow:
|
|||
while iterC:
|
||||
if model[iterC][C_TYPE] != 'self_contact':
|
||||
break
|
||||
iter_jid = model[iterC][C_JID]
|
||||
if iter_jid and jid == iter_jid.decode('utf-8'):
|
||||
iter_account = model[iterC][C_ACCOUNT]
|
||||
if account == iter_account.decode('utf-8'):
|
||||
return iterC
|
||||
iterC = model.iter_next(iterC)
|
||||
return None
|
||||
|
@ -177,7 +176,7 @@ class RosterWindow:
|
|||
return []
|
||||
|
||||
if jid == gajim.get_jid_from_account(account):
|
||||
contact_iter = self._get_self_contact_iter(jid, account, model)
|
||||
contact_iter = self._get_self_contact_iter(account, model)
|
||||
if contact_iter:
|
||||
return [contact_iter]
|
||||
else:
|
||||
|
@ -783,6 +782,21 @@ class RosterWindow:
|
|||
|
||||
return True
|
||||
|
||||
def rename_self_contact(self, old_jid, new_jid, account):
|
||||
'''Rename the self_contact jid
|
||||
|
||||
Keyword arguments:
|
||||
old_jid -- our old jid
|
||||
new_jid -- our new jid
|
||||
account -- the corresponding account.
|
||||
'''
|
||||
gajim.contacts.change_contact_jid(old_jid, new_jid, account)
|
||||
self_iter = self._get_self_contact_iter(account, model=self.model)
|
||||
if not self_iter:
|
||||
return
|
||||
self.model[self_iter][C_JID] = new_jid
|
||||
self.draw_contact(new_jid, account)
|
||||
|
||||
def add_groupchat(self, jid, account, status=''):
|
||||
'''Add groupchat to roster and draw it.
|
||||
Return the added contact instance.
|
||||
|
|
Loading…
Reference in New Issue