Merged revisions 5017-5020,5022-5029 via svnmerge from

svn://svn.gajim.org/gajim/trunk

........
r5017 | asterix | 2006-01-06 01:55:51 -0700 (Fri, 06 Jan 2006) | 2 lines

use escape for pango markup

........
r5018 | asterix | 2006-01-06 02:21:39 -0700 (Fri, 06 Jan 2006) | 2 lines

missing new contacts function

........
r5019 | asterix | 2006-01-06 11:03:07 -0700 (Fri, 06 Jan 2006) | 2 lines

handle the click on toggle_gpg_encryption menuitem

........
r5020 | asterix | 2006-01-06 11:14:14 -0700 (Fri, 06 Jan 2006) | 2 lines

use the saved size even if a chat window is already opened

........
r5022 | asterix | 2006-01-07 03:43:47 -0700 (Sat, 07 Jan 2006) | 2 lines

we can now resume filetransfert

........
r5023 | asterix | 2006-01-07 03:56:31 -0700 (Sat, 07 Jan 2006) | 2 lines

[Knuckles] Google E-Mail Notification

........
r5024 | asterix | 2006-01-07 04:02:16 -0700 (Sat, 07 Jan 2006) | 2 lines

better string

........
r5025 | asterix | 2006-01-07 04:14:32 -0700 (Sat, 07 Jan 2006) | 2 lines

fix a TB

........
r5026 | asterix | 2006-01-07 05:36:55 -0700 (Sat, 07 Jan 2006) | 2 lines

we can now drag a file on a contact in the roster to send him a file

........
r5027 | asterix | 2006-01-07 06:26:28 -0700 (Sat, 07 Jan 2006) | 2 lines

contact.groups is always a list, even if emtpy

........
r5028 | asterix | 2006-01-07 06:54:30 -0700 (Sat, 07 Jan 2006) | 2 lines

make all buttons insensitive on a category row in disco

........
r5029 | asterix | 2006-01-07 07:19:25 -0700 (Sat, 07 Jan 2006) | 2 lines

auto open groupchat configuration window when we create a new room

........
This commit is contained in:
Travis Shirk 2006-01-07 17:25:35 +00:00
parent c0c30f961f
commit f52afdcbe8
17 changed files with 183 additions and 18 deletions

View File

@ -289,7 +289,7 @@ class Chat:
close_button.hide()
nickname.set_max_width_chars(10)
lbl = self.names[jid]
lbl = gtkgui_helpers.escape_for_pango_markup(self.names[jid])
if num_unread: # if unread, text in the label becomes bold
lbl = '<b>' + unread + lbl + '</b>'
nickname.set_markup(lbl)

View File

@ -661,7 +661,6 @@ class ChatControl(ChatControlBase):
self._schedule_activity_timers()
# Hook up signals
# FIXME: This does not seem to be working
self.parent_win.window.connect('motion-notify-event',
self._on_window_motion_notify)
message_tv_buffer = self.msg_textview.get_buffer()
@ -673,6 +672,8 @@ class ChatControl(ChatControlBase):
self._on_banner_eventbox_button_press_event)
xm = gtk.glade.XML(GTKGUI_GLADE, 'avatar_eventbox', APP)
xm.signal_autoconnect(self)
xm = gtk.glade.XML(GTKGUI_GLADE, 'gpg_togglebutton', APP)
xm.signal_autoconnect(self)
if self.contact.jid in gajim.encrypted_chats[self.account]:
self.xml.get_widget('gpg_togglebutton').set_active(True)
@ -833,8 +834,8 @@ class ChatControl(ChatControlBase):
else:
tb.set_sensitive(False)
#we talk about a contact here
tt = _('%s has not broadcasted an OpenPGP key nor you have '\
'assigned one') % self.contact.name
tt = _('%s has not broadcast an OpenPGP key, nor has one been assigned') %\
self.contact.name
gtk.Tooltips().set_tip(self.xml.get_widget('gpg_eventbox'), tt)
def send_message(self, message, keyID = '', chatstate = None):
@ -1013,7 +1014,7 @@ class ChatControl(ChatControlBase):
if self.parent_win.get_active_control() != self:
color = self.lighten_color(color)
label_str = self.contact.name
label_str = gtkgui_helpers.escape_for_pango_markup(self.contact.name)
if num_unread: # if unread, text in the label becomes bold
label_str = '<b>' + unread + label_str + '</b>'
return (label_str, color)
@ -1400,3 +1401,8 @@ class ChatControl(ChatControlBase):
def _on_contact_information_menuitem_clicked(self, widget):
gajim.interface.roster.on_info(widget, self.contact, self.account)
def on_toggle_gpg_menuitem_activate(self, widget):
print "toggling"
jid = self.get_active_jid()
tb = self.xml.get_widget('gpg_togglebutton')
tb.set_active(not tb.get_active())

View File

@ -116,6 +116,7 @@ class Config:
'before_nickname': [ opt_str, '' ],
'after_nickname': [ opt_str, ':' ],
'send_os_info': [ opt_bool, True ],
'notify_on_new_gmail_email': [ opt_bool, True ],
'usegpg': [ opt_bool, False ],
'use_gpg_agent': [ opt_bool, False ],
'change_roster_title': [ opt_bool, True, _('Add * and [n] in roster title?')],

View File

@ -316,6 +316,15 @@ class Connection:
else:
self.dispatch('VCARD', vcard)
def _gMailCB(self, con, gm):
"""Called when we get notified of new mail messages in gmail account"""
if not gm.getTag('new-mail'):
return
if gm.getTag('new-mail').getNamespace() == common.xmpp.NS_GMAILNOTIFY:
jid = gajim.get_jid_from_account(self.name)
gajim.log.debug(('Notifying user of new gmail e-mail on %s.') % (jid))
self.dispatch('GMAIL_NOTIFY', jid)
raise common.xmpp.NodeProcessed
def _messageCB(self, con, msg):
"""Called when we receive a message"""
@ -871,6 +880,17 @@ class Connection:
return
file_props['receiver'] = self.get_full_jid(iq_obj)
si = iq_obj.getTag('si')
file_tag = si.getTag('file')
range_tag = None
if file_tag:
range_tag = file_tag.getTag('range')
if range_tag:
offset = range_tag.getAttr('offset')
if offset:
file_props['offset'] = int(offset)
length = range_tag.getAttr('length')
if length:
file_props['length'] = int(length)
feature = si.setTag('feature')
if feature.getNamespace() != common.xmpp.NS_FEATURE:
return
@ -1054,6 +1074,9 @@ class Connection:
si.setNamespace(common.xmpp.NS_SI)
file_tag = si.setTag('file')
file_tag.setNamespace(common.xmpp.NS_FILE)
if file_props.has_key('offset') and file_props['offset']:
range_tag = file_tag.setTag('range')
range_tag.setAttr('offset', file_props['offset'])
feature = si.setTag('feature')
feature.setNamespace(common.xmpp.NS_FEATURE)
_feature = common.xmpp.DataForm(typ='submit')
@ -1694,6 +1717,8 @@ class Connection:
common.xmpp.NS_PRIVATE)
con.RegisterHandler('iq', self._HttpAuthCB, 'get',
common.xmpp.NS_HTTP_AUTH)
con.RegisterHandler('iq', self._gMailCB, 'set',
common.xmpp.NS_GMAILNOTIFY)
con.RegisterHandler('iq', self._ErrorCB, 'error')
con.RegisterHandler('iq', self._IqCB)
con.RegisterHandler('iq', self._StanzaArrivedCB)

View File

@ -366,6 +366,10 @@ class Socks5:
if self.fd == None:
try:
self.fd = open(self.file_props['file-name'],'rb')
if self.file_props.has_key('offset') and self.file_props['offset']:
self.size = self.file_props['offset']
self.fd.seek(self.size)
self.file_props['received-len'] = self.size
except IOError, e:
self.close_file()
raise IOError, e
@ -383,11 +387,16 @@ class Socks5:
if self.file_props.has_key('fd'):
fd = self.file_props['fd']
else:
fd = open(self.file_props['file-name'],'wb')
offset = 0
opt = 'wb'
if self.file_props.has_key('offset') and self.file_props['offset']:
offset = self.file_props['offset']
opt = 'ab'
fd = open(self.file_props['file-name'], opt)
self.file_props['fd'] = fd
self.file_props['elapsed-time'] = 0
self.file_props['last-time'] = time.time()
self.file_props['received-len'] = 0
self.file_props['received-len'] = offset
return fd
def rem_fd(self, fd):

View File

@ -63,6 +63,7 @@ NS_TIME ='jabber:iq:time'
NS_TLS ='urn:ietf:params:xml:ns:xmpp-tls'
NS_VACATION ='http://jabber.org/protocol/vacation'
NS_VCARD ='vcard-temp'
NS_GMAILNOTIFY ='google:mail:notify'
NS_VCARD_UPDATE =NS_VCARD+':x:update'
NS_VERSION ='jabber:iq:version'
NS_ENCRYPTED ='jabber:x:encrypted' # JEP-0027

View File

@ -416,6 +416,10 @@ class PreferencesWindow:
st = gajim.config.get('send_os_info')
self.xml.get_widget('send_os_info_checkbutton').set_active(st)
# Notify user of new gmail e-mail messages
st = gajim.config.get('notify_on_new_gmail_email')
self.xml.get_widget('notify_gmail_checkbutton').set_active(st)
self.xml.signal_autoconnect(self)
self.sound_tree.get_model().connect('row-changed',
@ -869,6 +873,9 @@ class PreferencesWindow:
def on_send_os_info_checkbutton_toggled(self, widget):
self.on_checkbutton_toggled(widget, 'send_os_info')
def on_notify_gmail_checkbutton_toggled(self, widget):
self.on_checkbutton_toggled(widget, 'notify_on_new_gmail_email')
def fill_msg_treeview(self):
self.xml.get_widget('delete_msg_button').set_sensitive(False)
model = self.msg_tree.get_model()

View File

@ -563,6 +563,29 @@ class ConfirmationDialogCheck(ConfirmationDialog):
''' Get active state of the checkbutton '''
return self.checkbutton.get_active()
class FTOverwriteConfirmationDialog(ConfirmationDialog):
'''HIG compliant confirmation dialog to overwrite or resume a file transfert'''
def __init__(self, pritext, sectext='', propose_resume=True):
HigDialog.__init__(self, None, gtk.MESSAGE_QUESTION, gtk.BUTTONS_CANCEL,
pritext, sectext)
if propose_resume:
b = gtk.Button('', gtk.STOCK_REFRESH)
align = b.get_children()[0]
hbox = align.get_children()[0]
label = hbox.get_children()[1]
label.set_text('_Resume')
label.set_use_underline(True)
self.add_action_widget(b, 100)
b = gtk.Button('', gtk.STOCK_SAVE_AS)
align = b.get_children()[0]
hbox = align.get_children()[0]
label = hbox.get_children()[1]
label.set_text('Re_place')
label.set_use_underline(True)
self.add_action_widget(b, 200)
class InputDialog:
'''Class for Input dialog'''
def __init__(self, title, label_str, input_str = None, is_modal = True,
@ -886,6 +909,12 @@ class PopupNotificationWindow:
else:
txt = ''
event_description_label.set_markup('<span foreground="black">%s</span>' % txt)
elif event_type == _('New E-mail'):
dodgerblue = gtk.gdk.color_parse('dodgerblue')
close_button.modify_bg(gtk.STATE_NORMAL, dodgerblue)
eventbox.modify_bg(gtk.STATE_NORMAL, dodgerblue)
txt = _('You have new E-mail on %s.') % (jid)
event_description_label.set_markup('<span foreground="black">%s</span>' % txt)
# position the window to bottom-right of screen
window_width, self.window_height = self.window.get_size()
gajim.interface.roster.popups_notification_height += self.window_height

View File

@ -1166,6 +1166,9 @@ class ToplevelAgentBrowser(AgentBrowser):
model, iter = self.window.services_treeview.get_selection().get_selected()
if not iter:
return
if not model[iter][0]:
# We're on a category row
return
if model[iter][4] != 0:
# We don't have the info (yet)
# It's either unknown or a transport, register button should be active

View File

@ -300,6 +300,24 @@ _('Connection with peer cannot be established.'))
gajim.connections[account].send_file_request(file_props)
return True
def confirm_overwrite_cb(self, dialog, file_props):
file_path = dialog.get_filename()
file_path = file_path.decode('utf-8')
if os.path.exists(file_path):
stat = os.stat(file_path)
dl_size = stat.st_size
file_size = file_props['size']
dl_finished = dl_size >= file_size
dialog = dialogs.FTOverwriteConfirmationDialog(
_('This file already exists'), _('What do you want to do?'),
not dl_finished)
response = dialog.get_response()
if response == gtk.RESPONSE_CANCEL:
return gtk.FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN
elif response == 100:
file_props['offset'] = dl_size
return gtk.FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME
def show_file_request(self, account, contact, file_props):
''' show dialog asking for comfirmation and store location of new
file requested by a contact'''
@ -326,6 +344,8 @@ _('Connection with peer cannot be established.'))
gtk28 = False
if gtk.gtk_version >= (2, 8, 0) and gtk.pygtk_version >= (2, 8, 0):
dialog.props.do_overwrite_confirmation = True
dialog.connect('confirm-overwrite', self.confirm_overwrite_cb,
file_props)
gtk28 = True
if last_save_dir and os.path.isdir(last_save_dir):
dialog.set_current_folder(last_save_dir)

View File

@ -420,7 +420,7 @@ class Interface:
return
if gajim.config.get('ignore_unknown_contacts') and \
not gajim.contacts[account].has_key(jid):
not gajim.contacts.get_contact(account, jid):
return
# Handle chat states
@ -808,6 +808,10 @@ class Interface:
notify.notify(_('File Transfer Error'),
jid, account, 'file-send-error', file_props)
def handle_event_gmail_notify(self, account, jid):
if gajim.config.get('notify_on_new_gmail_email'):
notify.notify(_('New E-mail'), jid, account)
def add_event(self, account, jid, typ, args):
'''add an event to the awaiting_events var'''
# We add it to the awaiting_events queue
@ -1196,6 +1200,7 @@ class Interface:
'BOOKMARKS': self.handle_event_bookmarks,
'CON_TYPE': self.handle_event_con_type,
'FILE_REQUEST': self.handle_event_file_request,
'GMAIL_NOTIFY': self.handle_event_gmail_notify,
'FILE_REQUEST_ERROR': self.handle_event_file_request_error,
'FILE_SEND_ERROR': self.handle_event_file_send_error,
'STANZA_ARRIVED': self.handle_event_stanza_arrived,

View File

@ -668,6 +668,8 @@ class GroupchatControl(ChatControlBase):
if not iter:
iter = self.add_contact_to_roster(nick, show, role,
affiliation, status, jid)
if statusCode == '201': # We just created the room
gajim.connections[self.account].request_gc_config(room_jid)
else:
actual_role = self.get_role(nick)
if role != actual_role:

View File

@ -492,6 +492,9 @@ class GroupchatWindow(chat.Chat):
if not iter:
iter = self.add_contact_to_roster(room_jid, nick, show, role,
affiliation, status, jid)
if statusCode == '201': # We just created the room
gajim.connections[self.account].request_gc_config(room_jid)
else:
actual_role = self.get_role(room_jid, nick)
if role != actual_role:

View File

@ -6208,6 +6208,26 @@ Custom</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="notify_gmail_checkbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Notify on new _Gmail e-mail (GoogleTalk users)</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_notify_gmail_checkbutton_toggled" last_modification_time="Wed, 06 Apr 2005 14:43:56 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>

View File

@ -197,6 +197,9 @@ class DesktopNotification:
img = 'ft_stopped.png'
else:
txt = ''
elif event_type == _('New Email'):
txt = _('You have new E-mail on %s.') % (jid)
ntype = 'gmail.notify'
else:
# defaul failsafe values
img = 'chat_msg_recv.png' # img to display

View File

@ -1259,6 +1259,8 @@ class RosterWindow:
gajim.connections[account].request_subscription(jid, txt)
if group:
group = [group]
else:
group = []
contact = gajim.contacts.get_contact_with_highest_priority(account, jid)
if not contact:
keyID = ''
@ -2476,10 +2478,30 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
if position == gtk.TREE_VIEW_DROP_BEFORE and len(path_dest) == 2 \
and path_dest[1] == 0: # dropped before the first group
return
iter_dest = model.get_iter(path_dest)
if info == self.TARGET_TYPE_URI_LIST:
# User dropped a file on the roster
if len(path_dest) < 3:
return
account = model[iter_dest][C_ACCOUNT].decode('utf-8')
jid = model[iter_dest][C_JID].decode('utf-8')
type_dest = model[iter_dest][C_TYPE].decode('utf-8')
if type_dest != 'contact':
return
c = gajim.contacts.get_contact_with_highest_priority(account, jid)
uri = data.strip()
uri_splitted = uri.split() # we may have more than one file dropped
for uri in uri_splitted:
path = helpers.get_file_path_from_dnd_dropped_uri(uri)
if os.path.isfile(path): # is it file?
gajim.interface.instances['file_transfers'].send_file(account, c,
path)
return
if position == gtk.TREE_VIEW_DROP_BEFORE and len(path_dest) == 2:
# dropped before a group : we drop it in the previous group
path_dest = (path_dest[1], path_dest[1]-1)
iter_dest = model.get_iter(path_dest)
path_dest = (path_dest[0], path_dest[1]-1)
iter_source = treeview.get_selection().get_selected()[1]
path_source = model.get_path(iter_source)
if len(path_dest) == 1: # dropped on an account
@ -2730,10 +2752,13 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
self.tree.set_expander_column(col)
#signals
self.TARGET_TYPE_URI_LIST = 80
TARGETS = [('MY_TREE_MODEL_ROW', gtk.TARGET_SAME_WIDGET, 0)]
TARGETS2 = [('MY_TREE_MODEL_ROW', gtk.TARGET_SAME_WIDGET, 0),
('text/uri-list', 0, self.TARGET_TYPE_URI_LIST)]
self.tree.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, TARGETS,
gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_MOVE | gtk.gdk.ACTION_COPY)
self.tree.enable_model_drag_dest(TARGETS, gtk.gdk.ACTION_DEFAULT)
self.tree.enable_model_drag_dest(TARGETS2, gtk.gdk.ACTION_DEFAULT)
self.tree.connect('drag_data_get', self.drag_data_get_data)
self.tree.connect('drag_data_received', self.drag_data_received_data)
self.xml.signal_autoconnect(self)

View File

@ -84,11 +84,12 @@ class TabbedChatWindow(chat.Chat):
self.xml.signal_autoconnect(signal_dict)
if gajim.config.get('saveposition') and \
not gtkgui_helpers.one_window_opened('chats'):
if gajim.config.get('saveposition'):
if gtkgui_helpers.one_window_opened('chats'):
# get window position and size from config
gtkgui_helpers.move_window(self.window, gajim.config.get('chat-x-position'),
gajim.config.get('chat-y-position'))
# Even if one is already opened we can use the saved size
gtkgui_helpers.resize_window(self.window, gajim.config.get('chat-width'),
gajim.config.get('chat-height'))
@ -451,6 +452,11 @@ class TabbedChatWindow(chat.Chat):
# send the message
self.send_message(message)
def on_toggle_gpg_menuitem_activate(self, widget):
jid = self.get_active_jid()
tb = self.xmls[jid].get_widget('gpg_togglebutton')
tb.set_active(not tb.get_active())
def remove_tab(self, jid):
if time.time() - gajim.last_message_time[self.account][jid] < 2:
dialog = dialogs.ConfirmationDialog(