events are now saved in an Event class. show in roster/systray options in Advanced Notification Control (for incomming messages) now work.

This commit is contained in:
Yann Leboulanger 2006-09-02 21:01:11 +00:00
parent 7046a19af0
commit a67eaba727
16 changed files with 543 additions and 371 deletions

View File

@ -24,6 +24,7 @@ import gtkgui_helpers
import message_control
import dialogs
import history_window
import notify
from common import gajim
from common import helpers
@ -71,6 +72,16 @@ class ChatControlBase(MessageControl):
font_attrs_small = 'font_desc="%s" size="small"' % font.to_string()
return (font_attrs, font_attrs_small)
def get_nb_unread(self):
jid = self.contact.jid
if self.resource:
jid += '/' + self.resource
type_ = self.type_id
if type_ == message_control.TYPE_GC:
type_ = 'gc_msg'
return len(gajim.events.get_events(self.account, jid, ['printed_' + type_,
type_]))
def draw_banner(self):
self._paint_banner()
self._update_banner_state_image()
@ -144,8 +155,6 @@ class ChatControlBase(MessageControl):
self.typing_new = False
self.orig_msg = ''
self.nb_unread = 0
# Emoticons menu
# set image no matter if user wants at this time emoticons or not
# (so toggle works ok)
@ -480,12 +489,25 @@ class ChatControlBase(MessageControl):
gajim.last_message_time[self.account][full_jid] = time.time()
urgent = True
if (not self.parent_win.get_active_jid() or \
full_jid != self.parent_win.get_active_jid() or \
not self.parent_win.is_active() or not end) and \
kind in ('incoming', 'incoming_queue'):
self.nb_unread += 1
if gajim.interface.systray_capabilities and self.notify_on_new_messages():
gajim.interface.systray.add_jid(full_jid, self.account, self.type_id)
full_jid != self.parent_win.get_active_jid() or \
not self.parent_win.is_active() or not end) and \
kind in ('incoming', 'incoming_queue'):
if self.notify_on_new_messages():
type_ = 'printed_' + self.type_id
if self.type_id == message_control.TYPE_GC:
type_ = 'printed_gc_msg'
show_in_roster = notify.get_show_in_roster('message_received',
self.account, self.contact)
show_in_systray = notify.get_show_in_systray('message_received',
self.account, self.contact)
event = gajim.events.create_event(type_, None,
show_in_roster = show_in_roster,
show_in_systray = show_in_systray)
gajim.events.add_event(self.account, full_jid, event)
# We need to redraw contact if we show in roster
if show_in_roster:
gajim.interface.roster.draw_contact(self.contact.jid,
self.account)
self.parent_win.redraw_tab(self)
if not self.parent_win.is_active():
ctrl = gajim.interface.msg_win_mgr.get_control(full_jid,
@ -510,6 +532,7 @@ class ChatControlBase(MessageControl):
else: # we are the beginning of buffer
buffer.insert_at_cursor('%s ' % str_)
self.msg_textview.grab_focus()
def on_emoticons_button_clicked(self, widget):
'''popup emoticons menu'''
gajim.interface.emoticon_menuitem_clicked = self.append_emoticon
@ -554,15 +577,18 @@ class ChatControlBase(MessageControl):
if state:
jid = self.contact.jid
if self.conv_textview.at_the_end():
#we are at the end
if self.nb_unread > 0:
self.nb_unread = self.get_specific_unread()
# we are at the end
type_ = 'printed_' + self.type_id
if self.type_id == message_control.TYPE_GC:
type_ = 'printed_gc_msg'
if not gajim.events.remove_events(self.account, self.get_full_jid(),
types = [type_]):
# There were events to remove
self.parent_win.redraw_tab(self)
self.parent_win.show_title()
if gajim.interface.systray_capabilities:
gajim.interface.systray.remove_jid(self.get_full_jid(),
self.account,
self.type_id)
# redraw roster
gajim.interface.roster.draw_contact(jid, self.account)
gajim.interface.roster.show_title()
self.msg_textview.grab_focus()
# Note, we send None chatstate to preserve current
self.parent_win.redraw_tab(self)
@ -635,22 +661,28 @@ class ChatControlBase(MessageControl):
return True
def on_conversation_vadjustment_value_changed(self, widget):
if not self.nb_unread:
return
if self.resource:
jid = self.contact.get_full_jid()
else:
jid = self.contact.jid
type_ = self.type_id
if type_ == message_control.TYPE_GC:
type_ = 'gc_msg'
if not len(gajim.events.get_events(self.account, jid, ['printed_' + type_,
type_])):
return
if self.conv_textview.at_the_end() and \
self.parent_win.get_active_control() == self and \
self.parent_win.window.is_active():
#we are at the end
self.nb_unread = self.get_specific_unread()
self.parent_win.redraw_tab(self)
self.parent_win.show_title()
if gajim.interface.systray_capabilities:
gajim.interface.systray.remove_jid(jid, self.account,
self.type_id)
# we are at the end
type_ = self.type_id
if type_ == message_control.TYPE_GC:
type_ = 'gc_msg'
if not gajim.events.remove_events(self.account, self.get_full_jid(),
types = ['printed_' + type_, type_]):
# There were events to remove
self.parent_win.redraw_tab(self)
self.parent_win.show_title()
def sent_messages_scroll(self, direction, conv_buf):
size = len(self.sent_history)
@ -1140,7 +1172,12 @@ class ChatControl(ChatControlBase):
def get_tab_label(self, chatstate):
unread = ''
num_unread = self.nb_unread
if self.resource:
jid = self.contact.get_full_jid()
else:
jid = self.contact.jid
num_unread = len(gajim.events.get_events(self.account, jid,
['printed_' + self.type_id, self.type_id]))
if num_unread == 1 and not gajim.config.get('show_unread_tab_icon'):
unread = '*'
elif num_unread > 1:
@ -1183,7 +1220,12 @@ class ChatControl(ChatControlBase):
return (label_str, color)
def get_tab_image(self):
num_unread = self.nb_unread
if self.resource:
jid = self.contact.get_full_jid()
else:
jid = self.contact.jid
num_unread = len(gajim.events.get_events(self.account, jid,
['printed_' + self.type_id, self.type_id]))
# Set tab image (always 16x16); unread messages show the 'message' image
tab_img = None
@ -1192,8 +1234,8 @@ class ChatControl(ChatControlBase):
self.contact.jid, icon_name = 'message')
tab_img = img_16['message']
else:
contact = gajim.contacts.get_contact_with_highest_priority(self.account,
self.contact.jid)
contact = gajim.contacts.get_contact_with_highest_priority(
self.account, self.contact.jid)
if not contact or self.resource:
# For transient contacts
contact = self.contact
@ -1369,10 +1411,9 @@ class ChatControl(ChatControlBase):
# Remove bigger avatar window
if self.bigger_avatar_window:
self.bigger_avatar_window.destroy()
# Clean up systray
if gajim.interface.systray_capabilities and self.nb_unread > 0:
gajim.interface.systray.remove_jid(self.contact.jid, self.account,
self.type_id)
# Clean events
gajim.events.remove_events(self.account, self.get_full_jid(),
types = ['printed_' + self.type_id, self.type_id])
# remove all register handlers on wigets, created by self.xml
# to prevent circular references among objects
for i in self.handlers.keys():
@ -1474,14 +1515,11 @@ class ChatControl(ChatControlBase):
if restore_how_many <= 0:
return
timeout = gajim.config.get('restore_timeout') # in minutes
# number of messages that are in queue and are already logged
pending_how_many = 0 # we want to avoid duplication
if gajim.awaiting_events[self.account].has_key(jid):
events = gajim.awaiting_events[self.account][jid]
for event in events:
if event[0] == 'chat':
pending_how_many += 1
events = gajim.events.get_events(self.account, jid, ['chat'])
# number of messages that are in queue and are already logged, we want
# to avoid duplication
pending_how_many = len(events)
rows = gajim.logger.get_last_conversation_lines(jid, restore_how_many,
pending_how_many, timeout, self.account)
@ -1522,7 +1560,7 @@ class ChatControl(ChatControlBase):
jid_with_resource = jid
if self.resource:
jid_with_resource += '/' + self.resource
l = gajim.awaiting_events[self.account][jid_with_resource]
events = gajim.events.get_events(self.account, jid_with_resource)
# Is it a pm ?
is_pm = False
@ -1530,15 +1568,12 @@ class ChatControl(ChatControlBase):
control = gajim.interface.msg_win_mgr.get_control(room_jid, self.account)
if control and control.type_id == message_control.TYPE_GC:
is_pm = True
events_to_keep = []
# list of message ids which should be marked as read
message_ids = []
for event in l:
typ = event[0]
if typ != 'chat':
events_to_keep.append(event)
for event in events:
if event.type_ != 'chat':
continue
data = event[1]
data = event.parameters
kind = data[2]
if kind == 'error':
kind = 'info'
@ -1548,22 +1583,16 @@ class ChatControl(ChatControlBase):
encrypted = data[4], subject = data[1])
if len(data) > 6 and isinstance(data[6], int):
message_ids.append(data[6])
# remove from gc nb_unread if it's pm or from roster
if is_pm:
control.nb_unread -= 1
else:
gajim.interface.roster.nb_unread -= 1
if message_ids:
gajim.logger.set_read_messages(message_ids)
if is_pm:
control.parent_win.show_title()
else:
gajim.interface.roster.show_title()
# Keep only non-messages events
if len(events_to_keep):
gajim.awaiting_events[self.account][jid_with_resource] = events_to_keep
else:
del gajim.awaiting_events[self.account][jid_with_resource]
gajim.events.remove_events(self.account, jid_with_resource,
types = ['chat'])
self.parent_win.show_title()
self.parent_win.redraw_tab(self)
# redraw roster
gajim.interface.roster.show_title()
typ = 'chat' # Is it a normal chat or a pm ?
# reset to status image in gc if it is a pm
if is_pm:
@ -1573,8 +1602,6 @@ class ChatControl(ChatControlBase):
gajim.interface.roster.draw_contact(jid, self.account)
# Redraw parent too
gajim.interface.roster.draw_parent_contact(jid, self.account)
if gajim.interface.systray_capabilities:
gajim.interface.systray.remove_jid(jid_with_resource, self.account, typ)
if (self.contact.show == 'offline' or self.contact.show == 'error'):
showOffline = gajim.config.get('showoffline')
if not showOffline and typ == 'chat' and \

230
src/common/events.py Normal file
View File

@ -0,0 +1,230 @@
## common/events.py
##
## Contributors for this file:
## - Yann Le Boulanger <asterix@lagaule.org>
##
## Copyright (C) 2006 Yann Le Boulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org>
## Nikos Kouremenos <nkour@jabber.org>
## Dimitur Kirov <dkirov@gmail.com>
## Travis Shirk <travis@pobox.com>
## Norman Rasmussen <norman@rasmussen.co.za>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
## by the Free Software Foundation; version 2 only.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
import time
import gajim
class Event:
'''Information concerning each event'''
def __init__(self, type_, time_, parameters, show_in_roster = False,
show_in_systray = True):
''' type_ in chat, normal, file-request, file-error, file-completed,
file-request-error, file-send-error, file-stopped, gc_msg, pm,
printed_chat, printed_gc_msg, printed_pm
parameters is (per type_):
chat, normal: [message, subject, kind, time, encrypted, resource,
msg_id]
where kind in error, incoming
file-*: file_props
gc_msg: None
printed_*: None
messages that are already printed in chat, but not read'''
self.type_ = type_
self.time_ = time_
self.parameters = parameters
self.show_in_roster = show_in_roster
self.show_in_systray = show_in_systray
class Events:
'''Information concerning all events'''
def __init__(self):
self._events = {} # list of events {acct: {jid1: [E1, E2]}, }
def change_account_name(self, old_name, new_name):
if self._events.has_key(old_name):
self._events[new_name] = self._events[old_name]
del self._events[old_name]
def add_account(self, account):
self._events[account] = {}
def get_accounts(self):
return self._events.keys()
def remove_account(self, account):
del self._events[account]
def create_event(self, type_, parameters, time_ = time.time(),
show_in_roster = False, show_in_systray = True):
return Event(type_, time_, parameters, show_in_roster,
show_in_systray)
def add_event(self, account, jid, event):
# No such account before ?
if not self._events.has_key(account):
self._events[account] = {jid: [event]}
# no such jid before ?
elif not self._events[account].has_key(jid):
self._events[account][jid] = [event]
else:
self._events[account][jid].append(event)
if event.show_in_systray:
gajim.interface.systray.set_img()
def remove_events(self, account, jid, event = None, types = []):
'''if event is not speficied, remove all events from this jid,
optionnaly only from given type
return True if no such event found'''
if not self._events.has_key(account):
return True
if not self._events[account].has_key(jid):
return True
if event: # remove only one event
if event in self._events[account][jid]:
if len(self._events[account][jid]) == 1:
del self._events[account][jid]
else:
self._events[account][jid].remove(event)
gajim.interface.systray.set_img()
return
else:
return True
if types:
new_list = [] # list of events to keep
for ev in self._events[account][jid]:
if ev.type_ not in types:
new_list.append(ev)
if len(new_list) == len(self._events[account][jid]):
return True
if new_list:
self._events[account][jid] = new_list
else:
del self._events[account][jid]
gajim.interface.systray.set_img()
return
# no event nor type given, remove them all
del self._events[account][jid]
gajim.interface.systray.set_img()
def get_nb_events(self, types = []):
return self._get_nb_events(types = types)
def get_events(self, account, jid = None, types = []):
'''if event is not speficied, remove all events from this jid,
optionnaly only from given type'''
if not self._events.has_key(account):
return []
if not jid:
return self._events[account]
if not self._events[account].has_key(jid):
return []
events_list = [] # list of events
for ev in self._events[account][jid]:
if not types or ev.type_ in types:
events_list.append(ev)
return events_list
def get_first_event(self, account, jid = None, type_ = None):
'''Return the first event of type type_ if given'''
events_list = self.get_events(account, jid, type_)
# be sure it's bigger than latest event
first_event_time = time.time() + 1
first_event = None
for event in events_list:
if event.time_ < first_event_time:
first_event_time = event.time_
first_event = event
return first_event
def _get_nb_events(self, account = None, jid = None, attribute = None, types = []):
'''return the number of events'''
nb = 0
if account:
accounts = [account]
else:
accounts = self._events.keys()
for acct in accounts:
if not self._events.has_key(acct):
continue
if jid:
jids = [jid]
else:
jids = self._events[acct].keys()
for j in jids:
if not self._events[acct].has_key(j):
continue
for event in self._events[acct][j]:
if types and event.type_ not in types:
continue
if not attribute or \
attribute == 'systray' and event.show_in_systray or \
attribute == 'roster' and event.show_in_roster:
nb += 1
return nb
def _get_some_events(self, attribute):
'''attribute in systray, roster'''
events = {}
for account in self._events:
events[account] = {}
for jid in self._events[account]:
events[account][jid] = []
for event in self._events[account][jid]:
if attribute == 'systray' and event.show_in_systray or \
attribute == 'roster' and event.show_in_roster:
events[account][jid].append(event)
if not events[account][jid]:
del events[account][jid]
if not events[account]:
del events[account]
return events
def _get_first_event_with_attribute(self, events):
'''get the first event
events is in the form {account1: {jid1: [ev1, ev2], },. }'''
# be sure it's bigger than latest event
first_event_time = time.time() + 1
first_account = None
first_jid = None
first_event = None
for account in events:
for jid in events[account]:
for event in events[account][jid]:
if event.time_ < first_event_time:
first_event_time = event.time_
first_account = account
first_jid = jid
first_event = event
return first_account, first_jid, first_event
def get_nb_systray_events(self, types = []):
'''returns the number of events displayedin roster'''
return self._get_nb_events(attribute = 'systray', types = types)
def get_systray_events(self):
'''return all events that must be displayed in systray:
{account1: {jid1: [ev1, ev2], },. }'''
return self._get_some_events('systray')
def get_first_systray_event(self):
events = self.get_systray_events()
return self._get_first_event_with_attribute(events)
def get_nb_roster_events(self, account = None, jid = None, types = []):
'''returns the number of events displayedin roster'''
return self._get_nb_events(attribute = 'roster', account = account,
jid = jid, types = types)
def get_roster_events(self):
'''return all events that must be displayed in roster:
{account1: {jid1: [ev1, ev2], },. }'''
return self._get_some_events('roster')

View File

@ -23,6 +23,7 @@ import locale
import config
from contacts import Contacts
from events import Events
interface = None # The actual interface (the gtk one for the moment)
config = config.Config()
@ -98,14 +99,8 @@ groups = {} # list of groups
newly_added = {} # list of contacts that has just signed in
to_be_removed = {} # list of contacts that has just signed out
awaiting_events = {} # list of messages/FT reveived but not printed
# awaiting_events[jid] = (type, (data1, data2, ...))
# if type in ('chat', 'normal'): data = (message, subject, kind, time,
# encrypted, resource)
# kind can be (incoming, error)
# if type in file-request, file-request-error, file-send-error, file-error,
# file-completed, file-stopped:
# data = file_props
events = Events()
nicks = {} # list of our nick names in each account
# should we block 'contact signed in' notifications for this account?
# this is only for the first 30 seconds after we change our show
@ -287,18 +282,6 @@ def get_hostname_from_account(account_name, use_srv = False):
return config.get_per('accounts', account_name, 'custom_host')
return config.get_per('accounts', account_name, 'hostname')
def get_first_event(account, jid, typ = None):
'''returns the first event of the given type from the awaiting_events queue'''
if not awaiting_events[account].has_key(jid):
return None
q = awaiting_events[account][jid]
if not typ:
return q[0]
for ev in q:
if ev[0] == typ:
return ev
return None
def get_notification_image_prefix(jid):
'''returns the prefix for the notification images'''
transport_name = get_transport_name_from_jid(jid)

View File

@ -513,9 +513,9 @@ def get_global_status():
def get_icon_name_to_show(contact, account = None):
'''Get the icon name to show in online, away, requested, ...'''
if account and gajim.awaiting_events[account].has_key(contact.jid):
if account and gajim.events.get_nb_roster_events(account, contact.jid):
return 'message'
if account and gajim.awaiting_events[account].has_key(
if account and gajim.events.get_nb_roster_events(account,
contact.get_full_jid()):
return 'message'
if contact.jid.find('@') <= 0: # if not '@' or '@' starts the jid ==> agent
@ -772,3 +772,23 @@ def allow_sound_notification(sound_event, advanced_notif_num = None):
if gajim.config.get_per('soundevents', sound_event, 'enabled'):
return True
return False
def get_chat_control(account, contact):
full_jid_with_resource = contact.jid
if contact.resource:
full_jid_with_resource += '/' + contact.resource
highest_contact = gajim.contacts.get_contact_with_highest_priority(
account, contact.jid)
# Look for a chat control that has the given resource, or default to
# one without resource
ctrl = gajim.interface.msg_win_mgr.get_control(full_jid_with_resource,
account)
if ctrl:
return ctrl
elif not highest_contact or not highest_contact.resource:
# unknow contact or offline message
return gajim.interface.msg_win_mgr.get_control(contact.jid, account)
elif highest_contact and contact.resource != \
highest_contact.resource:
return None
return gajim.interface.msg_win_mgr.get_control(contact.jid, account)

View File

@ -1213,7 +1213,7 @@ class AccountModificationWindow:
_('You are currently connected to the server'),
_('To change the account name, you must be disconnected.'))
return
if len(gajim.awaiting_events[self.account]):
if len(gajim.events.get_events(self.account)):
dialogs.ErrorDialog(_('Unread events'),
_('To change the account name, you must read all pending '
'events.'))
@ -1322,7 +1322,6 @@ class AccountModificationWindow:
if name != self.account:
#update variables
gajim.interface.instances[name] = gajim.interface.instances[self.account]
gajim.awaiting_events[name] = gajim.awaiting_events[self.account]
gajim.nicks[name] = gajim.nicks[self.account]
gajim.block_signed_in_notifications[name] = \
gajim.block_signed_in_notifications[self.account]
@ -1339,23 +1338,17 @@ class AccountModificationWindow:
gajim.status_before_autoaway[self.account]
gajim.contacts.change_account_name(self.account, name)
gajim.events.change_account_name(self.account, name)
#upgrade account variable in opened windows
# upgrade account variable in opened windows
for kind in ('infos', 'disco', 'chats', 'gc', 'gc_config'):
for j in gajim.interface.instances[name][kind]:
gajim.interface.instances[name][kind][j].account = name
#upgrade account in systray
if gajim.interface.systray_capabilities:
for list in gajim.interface.systray.jids:
if list[0] == self.account:
list[0] = name
# ServiceCache object keep old property account
if hasattr(gajim.connections[self.account], 'services_cache'):
gajim.connections[self.account].services_cache.account = name
del gajim.interface.instances[self.account]
del gajim.awaiting_events[self.account]
del gajim.nicks[self.account]
del gajim.block_signed_in_notifications[self.account]
del gajim.groups[self.account]
@ -1780,7 +1773,7 @@ class AccountsWindow:
if not iter:
return
account = model.get_value(iter, 0).decode('utf-8')
if len(gajim.awaiting_events[account]):
if len(gajim.events.get_events(account)):
dialogs.ErrorDialog(_('Unread events'),
_('Read all pending events before removing this account.'))
return
@ -2285,7 +2278,6 @@ class RemoveAccountWindow:
gajim.config.del_per('accounts', self.account)
gajim.interface.save_config()
del gajim.interface.instances[self.account]
del gajim.awaiting_events[self.account]
del gajim.nicks[self.account]
del gajim.block_signed_in_notifications[self.account]
del gajim.groups[self.account]
@ -2911,7 +2903,6 @@ _('You can set advanced account options by pressing Advanced button, or later by
# update variables
gajim.interface.instances[self.account] = {'infos': {}, 'disco': {},
'chats': {}, 'gc': {}, 'gc_config': {}}
gajim.awaiting_events[self.account] = {}
gajim.connections[self.account].connected = 0
gajim.groups[self.account] = {}
gajim.contacts.add_account(self.account)

View File

@ -445,12 +445,11 @@ _('Connection with peer cannot be established.'))
jid = gajim.get_jid_without_resource(other)
else: # It's a Contact instance
jid = other.jid
if gajim.awaiting_events[account].has_key(jid):
for event in gajim.awaiting_events[account][jid]:
if event[0] in ('file-error', 'file-completed',
'file-request-error', 'file-send-error', 'file-stopped') and \
event[1]['sid'] == file_props['sid']:
gajim.interface.remove_event(account, jid, event)
for ev_type in ('file-error', 'file-completed', 'file-request-error',
'file-send-error', 'file-stopped'):
for event in gajim.events.get_events(account, jid, [ev_type]):
if event.parameters[1]['sid'] == file_props['sid']:
gajim.events.remove_events(account, jid, event)
del(self.files_props[sid[0]][sid[1:]])
del(file_props)

View File

@ -389,7 +389,7 @@ class Interface:
else:
contact1 = gajim.contacts.get_first_contact_from_jid(account, ji)
if not contact1:
# presence of another resource of out jid
# presence of another resource of our jid
if resource == gajim.connections[account].server_resource:
return
contact1 = gajim.contacts.create_contact(jid = ji,
@ -570,8 +570,8 @@ class Interface:
# Is it a first or next message received ?
first = False
if not chat_control and not gajim.awaiting_events[account].has_key(
jid_of_control):
if not chat_control and not gajim.events.get_events(account,
jid_of_control, ['chat']):
# It's a first message and not a Private Message
first = True
@ -973,7 +973,7 @@ class Interface:
c = contacts[0]
self.roster.remove_contact(c, account)
gajim.contacts.remove_jid(account, jid)
if gajim.awaiting_events[account].has_key(c.jid):
if gajim.events.get_events(account, c.jid):
keyID = ''
attached_keys = gajim.config.get_per('accounts', account,
'attached_gpg_keys').split()
@ -1108,60 +1108,48 @@ class Interface:
path_to_bw_file = path_to_file + '_notif_size_bw.png'
bwbuf.save(path_to_bw_file, 'png')
def add_event(self, account, jid, typ, args):
'''add an event to the awaiting_events var'''
# We add it to the awaiting_events queue
def add_event(self, account, jid, type_, args):
'''add an event to the gajim.events var'''
# We add it to the gajim.events queue
# Do we have a queue?
jid = gajim.get_jid_without_resource(jid)
qs = gajim.awaiting_events[account]
no_queue = False
if not qs.has_key(jid):
no_queue = True
qs[jid] = []
qs[jid].append((typ, args))
self.roster.nb_unread += 1
no_queue = len(gajim.events.get_events(account, jid)) == 0
event_type = None
# type_ can be gc-invitation file-send-error file-error file-request-error
# file-request file-completed file-stopped
# event_type can be in advancedNotificationWindow.events_list
event_types = {'file-request': 'ft_request',
'file-completed': 'ft_finished'}
if type_ in event_types:
event_type = event_types[type_]
show_in_roster = notify.get_show_in_roster(event_type, account, jid)
show_in_systray = notify.get_show_in_systray(event_type, account, jid)
event = gajim.events.create_event(type_, args,
show_in_roster = show_in_roster,
show_in_systray = show_in_systray)
gajim.events.add_event(account, jid, event)
self.roster.show_title()
if no_queue: # We didn't have a queue: we change icons
self.roster.draw_contact(jid, account)
if self.systray_capabilities:
self.systray.add_jid(jid, account, typ)
def redraw_roster_systray(self, account, jid, typ = None):
self.roster.nb_unread -= 1
self.roster.show_title()
self.roster.draw_contact(jid, account)
if self.systray_capabilities:
self.systray.remove_jid(jid, account, typ)
def remove_first_event(self, account, jid, typ = None):
qs = gajim.awaiting_events[account]
event = gajim.get_first_event(account, jid, typ)
qs[jid].remove(event)
# Is it the last event?
if not len(qs[jid]):
del qs[jid]
if not gajim.config.get('showoffline'):
contact = gajim.contacts.get_contact_with_highest_priority(account,
jid)
if contact:
self.roster.really_remove_contact(contact, account)
self.redraw_roster_systray(account, jid, typ)
def remove_first_event(self, account, jid, type_ = None):
event = gajim.events.get_first_event(account, jid, type_)
self.remove_event(account, jid, event)
def remove_event(self, account, jid, event):
qs = gajim.awaiting_events[account]
if not event in qs[jid]:
if gajim.events.remove_events(account, jid, event):
# No such event found
return
qs[jid].remove(event)
# Is it the last event?
if not len(qs[jid]):
del qs[jid]
# no other event?
if not len(gajim.events.get_events(account, jid)):
if not gajim.config.get('showoffline'):
contact = gajim.contacts.get_contact_with_highest_priority(account,
jid)
if contact:
self.roster.really_remove_contact(contact, account)
self.redraw_roster_systray(account, jid, event[0])
self.roster.show_title()
self.roster.draw_contact(jid, account)
def handle_event_file_request_error(self, account, array):
jid = array[0]
@ -1210,7 +1198,8 @@ class Interface:
if helpers.allow_showing_notification(account):
img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
'ft_request.png')
txt = _('%s wants to send you a file.') % gajim.get_name_from_jid(account, jid)
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',
@ -1245,7 +1234,8 @@ class Interface:
msg_type = ''
event_type = ''
if file_props['error'] == 0 and gajim.config.get('notify_on_file_complete'):
if file_props['error'] == 0 and gajim.config.get(
'notify_on_file_complete'):
msg_type = 'file-completed'
event_type = _('File Transfer Completed')
elif file_props['error'] == -1:
@ -1712,14 +1702,14 @@ class Interface:
err_str)
sys.exit()
def handle_event(self, account, jid, typ):
def handle_event(self, account, jid, type_):
w = None
fjid = jid
resource = gajim.get_resource_from_jid(jid)
jid = gajim.get_jid_without_resource(jid)
if typ == message_control.TYPE_GC:
if type_ in ('printed_gc_msg', 'gc_msg'):
w = self.msg_win_mgr.get_window(jid, account)
elif typ == message_control.TYPE_CHAT:
elif type_ in ('printed_chat', 'chat'):
if self.msg_win_mgr.has_window(fjid, account):
w = self.msg_win_mgr.get_window(fjid, account)
else:
@ -1729,30 +1719,30 @@ class Interface:
self.roster.new_chat(contact, account, resource = resource)
w = self.msg_win_mgr.get_window(fjid, account)
gajim.last_message_time[account][jid] = 0 # long time ago
elif typ == message_control.TYPE_PM:
elif type_ in ('printed_pm', 'pm'):
if self.msg_win_mgr.has_window(fjid, account):
w = self.msg_win_mgr.get_window(fjid, account)
else:
room_jid = jid
nick = resource
gc_contact = gajim.contacts.get_gc_contact(account, room_jid,
nick)
nick)
if gc_contact:
show = gc_contact.show
else:
show = 'offline'
gc_contact = gajim.contacts.create_gc_contact(room_jid = room_jid,
name = nick, show = show)
gc_contact = gajim.contacts.create_gc_contact(
room_jid = room_jid, name = nick, show = show)
c = gajim.contacts.contact_from_gc_contact(gc_contact)
self.roster.new_chat(c, account, private_chat = True)
w = self.msg_win_mgr.get_window(fjid, account)
elif typ in ('normal', 'file-request', 'file-request-error',
'file-send-error', 'file-error', 'file-stopped', 'file-completed'):
elif type_ in ('normal', 'file-request', 'file-request-error',
'file-send-error', 'file-error', 'file-stopped', 'file-completed'):
# Get the first single message event
ev = gajim.get_first_event(account, jid, typ)
event = gajim.events.get_first_event(account, jid, type_)
# Open the window
self.roster.open_event(account, jid, ev)
elif typ == 'gmail':
self.roster.open_event(account, jid, event)
elif type_ == 'gmail':
if gajim.config.get_per('accounts', account, 'savepass'):
url = ('http://www.google.com/accounts/ServiceLoginAuth?service=mail&Email=%s&Passwd=%s&continue=https://mail.google.com/mail') %\
(urllib.quote(gajim.config.get_per('accounts', account, 'name')),
@ -1760,12 +1750,12 @@ class Interface:
else:
url = ('http://mail.google.com/')
helpers.launch_browser_mailer('url', url)
elif typ == 'gc-invitation':
ev = gajim.get_first_event(account, jid, typ)
data = ev[1]
elif type_ == 'gc-invitation':
event = gajim.events.get_first_event(account, jid, type_)
data = event.parameters
dialogs.InvitationReceivedDialog(account, data[0], jid, data[2],
data[1])
self.remove_first_event(account, jid, typ)
gajim.events.remove_events(account, jid, event)
if w:
w.set_active_tab(fjid, account)
w.window.present()
@ -1860,7 +1850,6 @@ class Interface:
gajim.automatic_rooms[a] = {}
gajim.newly_added[a] = []
gajim.to_be_removed[a] = []
gajim.awaiting_events[a] = {}
gajim.nicks[a] = gajim.config.get_per('accounts', a, 'name')
gajim.block_signed_in_notifications[a] = True
gajim.sleeper_state[a] = 0

View File

@ -446,10 +446,7 @@ class GroupchatControl(ChatControlBase):
def on_private_message(self, nick, msg, tim):
# Do we have a queue?
fjid = self.room_jid + '/' + nick
qs = gajim.awaiting_events[self.account]
no_queue = True
if qs.has_key(fjid):
no_queue = False
no_queue = len(gajim.events.get_events(self.account, fjid)) == 0
# We print if window is opened
pm_control = gajim.interface.msg_win_mgr.get_control(fjid, self.account)
@ -457,9 +454,9 @@ class GroupchatControl(ChatControlBase):
pm_control.print_conversation(msg, tim = tim)
return
if no_queue:
qs[fjid] = []
qs[fjid].append(('chat', (msg, '', 'incoming', tim, False, '')))
event = gajim.events.create_event('chat', (msg, '', 'incoming', tim,
False, '', None))
gajim.events.add_event(self.account, fjid, event)
autopopup = gajim.config.get('autopopup')
autopopupaway = gajim.config.get('autopopupaway')
@ -474,8 +471,6 @@ class GroupchatControl(ChatControlBase):
self.room_jid, icon_name = 'message')
image = state_images['message']
model[iter][C_IMG] = image
if gajim.interface.systray_capabilities:
gajim.interface.systray.add_jid(fjid, self.account, 'pm')
self.parent_win.show_title()
else:
self._start_private_message(nick)
@ -697,7 +692,7 @@ class GroupchatControl(ChatControlBase):
model = self.list_treeview.get_model()
gc_contact = gajim.contacts.get_gc_contact(self.account, self.room_jid, nick)
state_images = gajim.interface.roster.jabber_state_images['16']
if gajim.awaiting_events[self.account].has_key(self.room_jid + '/' + nick):
if len(gajim.events.get_events(self.account, self.room_jid + '/' + nick)):
image = state_images['message']
else:
image = state_images[gc_contact.show]
@ -801,7 +796,8 @@ class GroupchatControl(ChatControlBase):
os.rename(old_file, files[old_file])
self.print_conversation(s, 'info')
if not gajim.awaiting_events[self.account].has_key(self.room_jid + '/' + nick):
if len(gajim.events.get_events(self.account,
self.room_jid + '/' + nick)) == 0:
self.remove_contact(nick)
else:
c = gajim.contacts.get_gc_contact(self.account, self.room_jid, nick)
@ -1291,9 +1287,8 @@ class GroupchatControl(ChatControlBase):
nb = 0
for nick in gajim.contacts.get_nick_list(self.account, self.room_jid):
fjid = self.room_jid + '/' + nick
if gajim.awaiting_events[self.account].has_key(fjid):
# gc can only have messages as event
nb += len(gajim.awaiting_events[self.account][fjid])
nb += len(gajim.events.get_events(self.account, fjid))
# gc can only have messages as event
return nb
def _on_change_subject_menuitem_activate(self, widget):

View File

@ -39,7 +39,6 @@ class MessageControl:
self.account = account
self.hide_chat_buttons_always = False
self.hide_chat_buttons_current = False
self.nb_unread = 0
self.resource = resource
gajim.last_message_time[self.account][self.get_full_jid()] = 0
@ -117,10 +116,7 @@ class MessageControl:
pass
def get_specific_unread(self):
n = 0
if gajim.awaiting_events[self.account].has_key(self.contact.jid):
n = len(gajim.awaiting_events[self.account][self.contact.jid])
return n
return len(gajim.events.get_events(self.account, self.contact.jid))
def send_message(self, message, keyID = '', type = 'chat',
chatstate = None, msg_id = None, composing_jep = None, resource = None,

View File

@ -224,7 +224,7 @@ class MessageWindow:
gajim.config.get('notify_on_all_muc_messages') and not \
ctrl.attention_flag:
continue
unread += ctrl.nb_unread
unread += ctrl.get_nb_unread()
unread_str = ''
if unread > 1:
@ -280,9 +280,8 @@ class MessageWindow:
ctrl.shutdown()
# Update external state
if gajim.interface.systray_capabilities:
gajim.interface.systray.remove_jid(ctrl.get_full_jid(), ctrl.account,
ctrl.type_id)
gajim.events.remove_events(ctrl.account, ctrl.get_full_jid,
types = ['printed_msg', 'chat', 'gc_msg'])
del gajim.last_message_time[ctrl.account][ctrl.get_full_jid()]
self.disconnect_tab_dnd(ctrl.widget)
@ -432,7 +431,7 @@ class MessageWindow:
if ind < 0:
ind = self.notebook.get_n_pages() - 1
ctrl = self.get_control(ind, None)
if ctrl.nb_unread > 0:
if ctrl.get_nb_unread() > 0:
found = True
break # found
elif gajim.config.get('ctrl_tab_go_to_next_composing') : # Search for a composing contact

View File

@ -32,7 +32,37 @@ if dbus_support.supported:
import dbus.glib
import dbus.service
def get_show_in_roster(event, account, contact):
'''Return True if this event must be shown in roster, else False'''
num = get_advanced_notification(event, account, contact)
if num != None:
if gajim.config.get_per('notifications', str(num), 'roster') == 'yes':
return True
if gajim.config.get_per('notifications', str(num), 'roster') == 'no':
return False
if event == 'message_received':
chat_control = helpers.get_chat_control(account, contact)
if not chat_control:
return True
elif event == 'ft_request':
return True
return False
def get_show_in_systray(event, account, contact):
'''Return True if this event must be shown in roster, else False'''
num = get_advanced_notification(event, account, contact)
if num != None:
if gajim.config.get_per('notifications', str(num), 'systray') == 'yes':
return True
if gajim.config.get_per('notifications', str(num), 'systray') == 'no':
return False
if event in ('message_received', 'ft_request', 'gc_msg_highlight',
'ft_request'):
return True
return False
def get_advanced_notification(event, account, contact):
'''Returns the number of the first advanced notification or None'''
num = 0
notif = gajim.config.get_per('notifications', str(num))
while notif:
@ -68,26 +98,7 @@ def get_advanced_notification(event, account, contact):
if tab_opened == 'both':
tab_opened_ok = True
else:
chat_control = False
full_jid_with_resource = contact.jid
if contact.resource:
full_jid_with_resource += '/' + contact.resource
highest_contact = gajim.contacts.get_contact_with_highest_priority(
account, contact.jid)
# Look for a chat control that has the given resource, or default to
# one without resource
if gajim.interface.msg_win_mgr.get_control(full_jid_with_resource,
account):
chat_control = True
elif not highest_contact or not highest_contact.resource:
# unknow contact or offline message
if gajim.interface.msg_win_mgr.get_control(contact.jid, account):
chat_control = True
elif highest_contact and contact.resource != \
highest_contact.resource:
chat_control = False
elif gajim.interface.msg_win_mgr.get_control(contact.jid, account):
chat_control = True
chat_control = helper.get_chat_control(account, contact)
if (chat_control and tab_opened == 'yes') or (not chat_control and \
tab_opened == 'no'):
tab_opened_ok = True

View File

@ -596,7 +596,7 @@ class SignalObject(DbusPrototype):
return contact_dict
def get_unread_msgs_number(self, *args):
return str(gajim.interface.roster.nb_unread)
return str(gajim.events.get_nb_events)
def start_chat(self, *args):
[account] = self._get_real_arguments(args, 1)

View File

@ -29,6 +29,7 @@ import gtkgui_helpers
import cell_renderer_image
import tooltips
import message_control
import notify
from common import gajim
from common import helpers
@ -263,7 +264,7 @@ class RosterWindow:
if big_brother_jid != jid or big_brother_account != account:
# We are adding a child contact
if contact.show in ('offline', 'error') and \
not showOffline and not gajim.awaiting_events[account].has_key(jid):
not showOffline and len(gajim.events.get_events(account, jid)) == 0:
return
parent_iters = self.get_contact_iter(big_brother_jid,
big_brother_account)
@ -281,7 +282,7 @@ class RosterWindow:
if (contact.show in ('offline', 'error') or hide) and \
not showOffline and (not _('Transports') in contact.groups or \
gajim.connections[account].connected < 2) and \
not gajim.awaiting_events[account].has_key(jid) and \
len(gajim.events.get_events(account, jid)) == 0 and \
not _('Not in Roster') in contact.groups:
return
@ -355,7 +356,7 @@ class RosterWindow:
return
showOffline = gajim.config.get('showoffline')
if (contact.show in ('offline', 'error')) and not showOffline and \
not gajim.awaiting_events[account].has_key(jid):
len(gajim.events.get_events(account, jid)) == 0:
return
model = self.tree.get_model()
@ -396,7 +397,7 @@ class RosterWindow:
if (contact.show in ('offline', 'error') or hide) and \
not showOffline and (not _('Transports') in contact.groups or \
gajim.connections[account].connected < 2) and \
not gajim.awaiting_events[account].has_key(contact.jid):
len(gajim.events.get_events(account, contact.jid)) == 0:
self.remove_contact(contact, account)
else:
self.draw_contact(contact.jid, account)
@ -506,7 +507,7 @@ class RosterWindow:
iter = iters[0] # choose the icon with the first iter
icon_name = helpers.get_icon_name_to_show(contact, account)
# look if anotherresource has awaiting events
# look if another resource has awaiting events
for c in contact_instances:
c_icon_name = helpers.get_icon_name_to_show(c, account)
if c_icon_name == 'message':
@ -530,7 +531,7 @@ class RosterWindow:
# a child has awaiting messages ?
child_jid = model[child_iter][C_JID].decode('utf-8')
child_account = model[child_iter][C_ACCOUNT].decode('utf-8')
if gajim.awaiting_events[child_account].has_key(child_jid):
if len(gajim.events.get_events(child_account, child_jid)):
icon_name = 'message'
break
child_iter = model.iter_next(child_iter)
@ -1061,7 +1062,7 @@ class RosterWindow:
contact.show = show
contact.status = status
if show in ('offline', 'error') and \
not gajim.awaiting_events[account].has_key(contact.jid):
len(gajim.events.get_events(account, contact.jid)) == 0:
if len(contact_instances) > 1:
# if multiple resources
gajim.contacts.remove_contact(account, contact)
@ -2077,7 +2078,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
contact.sub = 'from'
gajim.contacts.add_contact(account, contact)
self.add_contact_to_roster(contact.jid, account)
elif gajim.awaiting_events[account].has_key(contact.jid):
elif len(gajim.events.get_events(account, contact.jid)):
need_readd = True
elif gajim.interface.msg_win_mgr.has_window(contact.jid, account):
if _('Not in Roster') in contact.groups:
@ -2397,7 +2398,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
mw.new_tab(chat_control)
if gajim.awaiting_events[account].has_key(fjid):
if len(gajim.events.get_events(account, fjid)):
# We call this here to avoid race conditions with widget validation
chat_control.read_queue()
@ -2493,10 +2494,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
resource_for_chat = None
# Do we have a queue?
qs = gajim.awaiting_events[account]
no_queue = True
if qs.has_key(fjid):
no_queue = False
no_queue = len(gajim.events.get_events(account, fjid)) == 0
popup = helpers.allow_popup_window(account, advanced_notif_num)
@ -2518,14 +2516,17 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
return
# We save it in a queue
if no_queue:
qs[fjid] = []
kind = 'chat'
type_ = 'chat'
if msg_type == 'normal':
kind = 'normal'
qs[fjid].append((kind, (msg, subject, msg_type, tim, encrypted,
resource, msg_id)))
self.nb_unread += 1
type_ = 'normal'
show_in_roster = notify.get_show_in_roster('message_received', account,
contact)
show_in_systray = notify.get_show_in_systray('message_received', account,
contact)
event = gajim.events.create_event(type_, (msg, subject, msg_type, tim,
encrypted, resource, msg_id), show_in_roster = show_in_roster,
show_in_systray = show_in_systray)
gajim.events.add_event(account, fjid, event)
if popup:
if not ctrl:
self.new_chat(contact, account, resource = resource_for_chat)
@ -2555,8 +2556,6 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
self.tree.expand_row(path[0:2], False)
self.tree.scroll_to_cell(path)
self.tree.set_cursor(path)
if gajim.interface.systray_capabilities:
gajim.interface.systray.add_jid(fjid, account, kind, advanced_notif_num)
def on_preferences_menuitem_activate(self, widget):
if gajim.interface.instances.has_key('preferences'):
@ -2721,14 +2720,14 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
# check if we have unread or recent mesages
unread = False
recent = False
if self.nb_unread > 0:
if gajim.events.get_nb_events() > 0:
unread = True
for win in gajim.interface.msg_win_mgr.windows():
unrd = 0
for ctrl in win.controls():
if ctrl.type_id == message_control.TYPE_GC:
if gajim.config.get('notify_on_all_muc_messages'):
unrd += ctrl.nb_unread
unrd += ctrl.get_nb_unread()
else:
if ctrl.attention_flag:
unrd += 1
@ -2765,33 +2764,30 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
def open_event(self, account, jid, event):
'''If an event was handled, return True, else return False'''
if not event:
return False
typ = event[0]
data = event[1]
data = event.parameters
ft = gajim.interface.instances['file_transfers']
if typ == 'normal':
if event.type_ == 'normal':
dialogs.SingleMessageWindow(account, jid,
action = 'receive', from_whom = jid, subject = data[1],
message = data[0], resource = data[5])
gajim.interface.remove_first_event(account, jid, typ)
gajim.interface.remove_first_event(account, jid, event.type_)
return True
elif typ == 'file-request':
elif event.type_ == 'file-request':
contact = gajim.contacts.get_contact_with_highest_priority(account,
jid)
gajim.interface.remove_first_event(account, jid, typ)
gajim.interface.remove_first_event(account, jid, event.type_)
ft.show_file_request(account, contact, data)
return True
elif typ in ('file-request-error', 'file-send-error'):
gajim.interface.remove_first_event(account, jid, typ)
elif event.type_ in ('file-request-error', 'file-send-error'):
gajim.interface.remove_first_event(account, jid, event.type_)
ft.show_send_error(data)
return True
elif typ in ('file-error', 'file-stopped'):
gajim.interface.remove_first_event(account, jid, typ)
elif event.type_ in ('file-error', 'file-stopped'):
gajim.interface.remove_first_event(account, jid, event.type_)
ft.show_stopped(jid, data)
return True
elif typ == 'file-completed':
gajim.interface.remove_first_event(account, jid, typ)
elif event.type_ == 'file-completed':
gajim.interface.remove_first_event(account, jid, event.type_)
ft.show_completed(jid, data)
return True
return False
@ -2825,12 +2821,12 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
else:
self.tree.expand_row(path, False)
else:
first_ev = gajim.get_first_event(account, jid)
first_ev = gajim.events.get_first_event(account, jid)
if not first_ev:
# look in other resources
for c in gajim.contacts.get_contact(account, jid):
fjid = c.get_full_jid()
first_ev = gajim.get_first_event(account, fjid)
first_ev = gajim.events.get_first_event(account, fjid)
if first_ev:
resource = c.resource
break
@ -2838,7 +2834,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
child_iter = model.iter_children(iter)
while not first_ev and child_iter:
child_jid = model[child_iter][C_JID].decode('utf-8')
first_ev = gajim.get_first_event(account, child_jid)
first_ev = gajim.events.get_first_event(account, child_jid)
if first_ev:
jid = child_jid
else:
@ -3088,8 +3084,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
model[iter][1] = self.jabber_state_images['16'][model[iter][2]]
iter = model.iter_next(iter)
# Update the systray
if gajim.interface.systray_enabled:
gajim.interface.systray.set_img()
gajim.interface.systray.set_img()
for win in gajim.interface.msg_win_mgr.windows():
for ctrl in win.controls():
@ -3565,13 +3560,14 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
change_title_allowed = gajim.config.get('change_roster_title')
if change_title_allowed:
start = ''
if self.nb_unread > 1:
start = '[' + str(self.nb_unread) + '] '
elif self.nb_unread == 1:
nb_unread = gajim.events.get_nb_events()
if nb_unread > 1:
start = '[' + str(nb_unread) + '] '
elif nb_unread == 1:
start = '* '
self.window.set_title(start + 'Gajim')
gtkgui_helpers.set_unset_urgency_hint(self.window, self.nb_unread)
gtkgui_helpers.set_unset_urgency_hint(self.window, nb_unread)
def iter_is_separator(self, model, iter):
if model[iter][0] == 'SEPARATOR':
@ -3640,7 +3636,6 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
self.transports_state_images = {'16': {}, '32': {}, 'opened': {},
'closed': {}}
self.nb_unread = 0 # number of unread messages
self.last_save_dir = None
self.editing_path = None # path of row with cell in edit mode
self.add_new_contact_handler_id = False

View File

@ -47,7 +47,6 @@ class Systray:
for trayicon in GNU/Linux'''
def __init__(self):
self.jids = [] # Contain things like [account, jid, type_of_msg]
self.single_message_handler_id = None
self.new_chat_handler_id = None
self.t = None
@ -58,14 +57,10 @@ class Systray:
self.xml.signal_autoconnect(self)
self.popup_menus = []
def set_img(self, advanced_notif_num = None):
def set_img(self):
if not gajim.interface.systray_enabled:
return
if advanced_notif_num:
if gajim.config.get_per('notifications', str(advanced_notif_num),
'systray') == 'no':
return
if len(self.jids) > 0:
if gajim.events.get_nb_systray_events():
state = 'message'
else:
state = self.status
@ -75,19 +70,6 @@ class Systray:
elif image.get_storage_type() == gtk.IMAGE_PIXBUF:
self.img_tray.set_from_pixbuf(image.get_pixbuf())
def add_jid(self, jid, account, typ, advanced_notif_num = None):
l = [account, jid, typ]
# We can keep several single message because we open them one by one
if not l in self.jids or typ == 'normal':
self.jids.append(l)
self.set_img(advanced_notif_num)
def remove_jid(self, jid, account, typ):
l = [account, jid, typ]
if l in self.jids:
self.jids.remove(l)
self.set_img()
def change_status(self, global_status):
''' set tray image to 'global_status' '''
# change image and status, only if it is different
@ -244,8 +226,11 @@ class Systray:
self.systray_context_menu.show_all()
def on_show_all_events_menuitem_activate(self, widget):
for i in range(len(self.jids)):
self.handle_first_event()
events = gajim.events.get_systray_events()
for account in events:
for jid in events[account]:
for event in events[account][jid]:
gajim.interface.handle_event(account, jid, event.type_)
def on_show_roster_menuitem_activate(self, widget):
win = gajim.interface.roster.window
@ -262,7 +247,7 @@ class Systray:
def on_left_click(self):
win = gajim.interface.roster.window
if len(self.jids) == 0:
if len(gajim.events.get_systray_events()) == 0:
# no pending events, so toggle visible/hidden for roster window
if win.get_property('visible'): # visible in ANY virtual desktop?
win.hide() # we hide it from VD that was visible in
@ -276,10 +261,8 @@ class Systray:
self.handle_first_event()
def handle_first_event(self):
account = self.jids[0][0]
jid = self.jids[0][1]
typ = self.jids[0][2]
gajim.interface.handle_event(account, jid, typ)
account, jid, event = gajim.events.get_first_systray_event()
gajim.interface.handle_event(account, jid, event.type_)
def on_middle_click(self):
'''middle click raises window to have complete focus (fe. get kbd events)

View File

@ -245,45 +245,6 @@ class SystrayWin32(systray.Systray):
elif lparam == win32con.WM_LBUTTONUP: # Left click
self.on_left_click()
def add_jid(self, jid, account, typ):
systray.Systray.add_jid(self, jid, account, typ)
nb = gajim.interface.roster.nb_unread
for acct in gajim.connections:
# in chat / groupchat windows
for kind in ('chats', 'gc'):
jids = gajim.interface.instances[acct][kind]
for jid in jids:
if jid != 'tabbed':
nb += jids[jid].nb_unread[jid]
text = i18n.ngettext(
'Gajim - %d unread message',
'Gajim - %d unread messages',
nb, nb, nb)
self.systray_winapi.notify_icon.set_tooltip(text)
def remove_jid(self, jid, account, typ):
systray.Systray.remove_jid(self, jid, account, typ)
nb = gajim.interface.roster.nb_unread
for acct in gajim.connections:
# in chat / groupchat windows
for kind in ('chats', 'gc'):
for jid in gajim.interface.instances[acct][kind]:
if jid != 'tabbed':
nb += gajim.interface.instances[acct][kind][jid].nb_unread[jid]
if nb > 0:
text = i18n.ngettext(
'Gajim - %d unread message',
'Gajim - %d unread messages',
nb, nb, nb)
else:
text = 'Gajim'
self.systray_winapi.notify_icon.set_tooltip(text)
def set_img(self):
self.tray_ico_imgs = self.load_icos() #FIXME: do not do this here
# see gajim.interface.roster.reload_jabber_state_images() to merge
@ -301,6 +262,17 @@ class SystrayWin32(systray.Systray):
'Gajim')
self.systray_winapi.notify_icon.menu = self.systray_context_menu
nb = gajim.events.get_nb_systray_events()
if nb > 0:
text = i18n.ngettext(
'Gajim - %d unread message',
'Gajim - %d unread messages',
nb, nb, nb)
else:
text = 'Gajim'
self.systray_winapi.notify_icon.set_tooltip(text)
def load_icos(self):
'''load .ico files and return them to a dic of SHOW --> img_obj'''
iconset = str(gajim.config.get('iconset'))

View File

@ -282,34 +282,14 @@ class NotificationAreaTooltip(BaseTooltip, StatusTable):
self.table.set_property('column-spacing', 1)
text, single_line = '', ''
unread_chat = gajim.interface.roster.nb_unread
unread_single_chat = 0
unread_gc = 0
unread_pm = 0
unread_chat = gajim.events.get_nb_events(types = ['printed_chat', 'chat'])
unread_single_chat = gajim.events.get_nb_events(types = ['normal'])
unread_gc = gajim.events.get_nb_events(types = ['printed_gc_msg',
'gc_msg'])
unread_pm = gajim.events.get_nb_events(types = ['printed_pm', 'pm'])
accounts = self.get_accounts_info()
for acct in gajim.connections:
# Count unread chat messages
chat_t = message_control.TYPE_CHAT
for ctrl in gajim.interface.msg_win_mgr.get_controls(chat_t, acct):
unread_chat += ctrl.nb_unread
# Count unread PM messages for which we have a control
chat_t = message_control.TYPE_PM
for ctrl in gajim.interface.msg_win_mgr.get_controls(chat_t, acct):
unread_pm += ctrl.nb_unread
# we count unread gc/pm messages
chat_t = message_control.TYPE_GC
for ctrl in gajim.interface.msg_win_mgr.get_controls(chat_t, acct):
# These are PMs for which the PrivateChatControl has not yet been
# created
pm_msgs = ctrl.get_specific_unread()
unread_gc += ctrl.nb_unread
unread_gc -= pm_msgs
unread_pm += pm_msgs
if unread_chat or unread_single_chat or unread_gc or unread_pm:
text = 'Gajim '
awaiting_events = unread_chat + unread_single_chat + unread_gc + unread_pm
@ -508,8 +488,9 @@ class RosterTooltip(NotificationAreaTooltip):
properties = []
jid_markup = '<span weight="bold">' + prim_contact.jid + '</span>'
properties.append((jid_markup, None))
properties.append((_('Name: '), gtkgui_helpers.escape_for_pango_markup(
prim_contact.get_shown_name())))
prim_contact.get_shown_name())))
if prim_contact.sub:
properties.append(( _('Subscription: '),
gtkgui_helpers.escape_for_pango_markup(helpers.get_uf_sub(prim_contact.sub))))
@ -533,9 +514,10 @@ class RosterTooltip(NotificationAreaTooltip):
else:
contacts_dict[contact.priority] = [contact]
if num_resources== 1 and contact.resource:
properties.append((_('Resource: '), gtkgui_helpers.escape_for_pango_markup(
contact.resource) + ' (' + unicode(contact.priority) + ')'))
if num_resources == 1 and contact.resource:
properties.append((_('Resource: '),
gtkgui_helpers.escape_for_pango_markup(contact.resource) + ' (' + \
unicode(contact.priority) + ')'))
if num_resources > 1:
properties.append((_('Status: '), ' '))
contact_keys = contacts_dict.keys()