Implemented #1260
This commit is contained in:
parent
41be225383
commit
eb27dbe61a
3 changed files with 151 additions and 65 deletions
|
@ -47,9 +47,7 @@ GTKGUI_GLADE = 'gtkgui.glade'
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
class ChatControlBase(MessageControl):
|
class ChatControlBase(MessageControl):
|
||||||
# FIXME
|
'''A base class containing a banner, ConversationTextview, MessageTextView
|
||||||
'''TODO
|
|
||||||
Contains a banner, ConversationTextview, MessageTextView
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def draw_widgets(self):
|
def draw_widgets(self):
|
||||||
|
@ -84,7 +82,7 @@ class ChatControlBase(MessageControl):
|
||||||
self.widget.connect('key_press_event', self._on_keypress_event)
|
self.widget.connect('key_press_event', self._on_keypress_event)
|
||||||
|
|
||||||
# Create textviews and connect signals
|
# Create textviews and connect signals
|
||||||
self.conv_textview = ConversationTextview(None) # FIXME: remove account arg
|
self.conv_textview = ConversationTextview(self.account)
|
||||||
self.conv_textview.show_all()
|
self.conv_textview.show_all()
|
||||||
self.conv_scrolledwindow = self.xml.get_widget('conversation_scrolledwindow')
|
self.conv_scrolledwindow = self.xml.get_widget('conversation_scrolledwindow')
|
||||||
self.conv_scrolledwindow.add(self.conv_textview)
|
self.conv_scrolledwindow.add(self.conv_textview)
|
||||||
|
@ -395,8 +393,7 @@ class ChatControlBase(MessageControl):
|
||||||
item.add(img)
|
item.add(img)
|
||||||
item.connect('activate', append_emoticon, image[0])
|
item.connect('activate', append_emoticon, image[0])
|
||||||
#FIXME: add tooltip with ascii
|
#FIXME: add tooltip with ascii
|
||||||
menu.attach(item,
|
menu.attach(item, counter % size, counter % size + 1,
|
||||||
counter % size, counter % size + 1,
|
|
||||||
counter / size, counter / size + 1)
|
counter / size, counter / size + 1)
|
||||||
counter += 1
|
counter += 1
|
||||||
menu.show_all()
|
menu.show_all()
|
||||||
|
@ -450,8 +447,6 @@ class ChatControlBase(MessageControl):
|
||||||
|
|
||||||
def on_history_menuitem_clicked(self, widget = None, jid = None):
|
def on_history_menuitem_clicked(self, widget = None, jid = None):
|
||||||
'''When history menuitem is pressed: call history window'''
|
'''When history menuitem is pressed: call history window'''
|
||||||
# FIXME for GC, jid is None
|
|
||||||
print widget, jid
|
|
||||||
if gajim.interface.instances['logs'].has_key(jid):
|
if gajim.interface.instances['logs'].has_key(jid):
|
||||||
gajim.interface.instances['logs'][jid].window.present()
|
gajim.interface.instances['logs'][jid].window.present()
|
||||||
else:
|
else:
|
||||||
|
@ -747,6 +742,7 @@ class ChatControl(ChatControlBase):
|
||||||
|
|
||||||
def _update_banner_state_image(self):
|
def _update_banner_state_image(self):
|
||||||
# FIXME: The cyling of contact_list ... is this necessary if I have the contact
|
# FIXME: The cyling of contact_list ... is this necessary if I have the contact
|
||||||
|
# This will need to be triumphant when sending directly to a resource
|
||||||
contact = self.contact
|
contact = self.contact
|
||||||
show = contact.show
|
show = contact.show
|
||||||
jid = contact.jid
|
jid = contact.jid
|
||||||
|
@ -900,7 +896,6 @@ class ChatControl(ChatControlBase):
|
||||||
message_buffer = self.msg_textview.get_buffer()
|
message_buffer = self.msg_textview.get_buffer()
|
||||||
if self.kbd_activity_in_last_5_secs and message_buffer.get_char_count():
|
if self.kbd_activity_in_last_5_secs and message_buffer.get_char_count():
|
||||||
# Only composing if the keyboard activity was in text entry
|
# Only composing if the keyboard activity was in text entry
|
||||||
# FIXME: Need send_chatstate
|
|
||||||
self.send_chatstate('composing')
|
self.send_chatstate('composing')
|
||||||
elif self.mouse_over_in_last_5_secs and\
|
elif self.mouse_over_in_last_5_secs and\
|
||||||
jid == self.parent_win.get_active_jid():
|
jid == self.parent_win.get_active_jid():
|
||||||
|
|
|
@ -41,6 +41,9 @@ opt_bool = [ 'boolean', 0 ]
|
||||||
opt_color = [ 'color', '^(#[0-9a-fA-F]{6})|()$' ]
|
opt_color = [ 'color', '^(#[0-9a-fA-F]{6})|()$' ]
|
||||||
opt_one_window_types = ['never', 'always', 'peracct', 'pertype']
|
opt_one_window_types = ['never', 'always', 'peracct', 'pertype']
|
||||||
|
|
||||||
|
DEFAULT_WINDOW_WIDTH = 480
|
||||||
|
DEFAULT_WINDOW_HEIGHT = 440
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
|
|
||||||
__options = {
|
__options = {
|
||||||
|
@ -97,10 +100,18 @@ class Config:
|
||||||
'gc-hpaned-position': [opt_int, 540],
|
'gc-hpaned-position': [opt_int, 540],
|
||||||
'gc_refer_to_nick_char': [opt_str, ','],
|
'gc_refer_to_nick_char': [opt_str, ','],
|
||||||
'gc_proposed_nick_char': [opt_str, '_'],
|
'gc_proposed_nick_char': [opt_str, '_'],
|
||||||
'msgwin-x-position': [opt_int, 0],
|
'msgwin-x-position': [opt_int, -1], # Default is to let the window manager decide
|
||||||
'msgwin-y-position': [opt_int, 0],
|
'msgwin-y-position': [opt_int, -1], # Default is to let the window manager decide
|
||||||
'msgwin-width': [opt_int, 480],
|
'msgwin-width': [opt_int, DEFAULT_WINDOW_WIDTH],
|
||||||
'msgwin-height': [opt_int, 440],
|
'msgwin-height': [opt_int, DEFAULT_WINDOW_HEIGHT],
|
||||||
|
'chat_msgwin-x-position': [opt_int, -1], # Default is to let the window manager decide
|
||||||
|
'chat_msgwin-y-position': [opt_int, -1], # Default is to let the window manager decide
|
||||||
|
'chat_msgwin-width': [opt_int, DEFAULT_WINDOW_WIDTH],
|
||||||
|
'chat_msgwin-height': [opt_int, DEFAULT_WINDOW_HEIGHT],
|
||||||
|
'gc_msgwin-x-position': [opt_int, -1], # Default is to let the window manager decide
|
||||||
|
'gc_msgwin-y-position': [opt_int, -1], # Default is to let the window manager decide
|
||||||
|
'gc_msgwin-width': [opt_int, DEFAULT_WINDOW_WIDTH],
|
||||||
|
'gc_msgwin-height': [opt_int, DEFAULT_WINDOW_HEIGHT],
|
||||||
'single_msg-x-position': [opt_int, 0],
|
'single_msg-x-position': [opt_int, 0],
|
||||||
'single_msg-y-position': [opt_int, 0],
|
'single_msg-y-position': [opt_int, 0],
|
||||||
'single_msg-width': [opt_int, 400],
|
'single_msg-width': [opt_int, 400],
|
||||||
|
@ -210,7 +221,11 @@ class Config:
|
||||||
'http_auth': [opt_str, 'ask'], # yes, no, ask
|
'http_auth': [opt_str, 'ask'], # yes, no, ask
|
||||||
# proxy65 for FT
|
# proxy65 for FT
|
||||||
'file_transfer_proxies': [opt_str,
|
'file_transfer_proxies': [opt_str,
|
||||||
'proxy.jabber.org, proxy65.jabber.autocom.pl, proxy.jabber.cd.chalmers.se, proxy.netlab.cz, proxy65.jabber.ccc.de, proxy65.unstable.nl']
|
'proxy.jabber.org, proxy65.jabber.autocom.pl, proxy.jabber.cd.chalmers.se, proxy.netlab.cz, proxy65.jabber.ccc.de, proxy65.unstable.nl'],
|
||||||
|
'msgwin-x-position': [opt_int, -1], # Default is to let the window manager decide
|
||||||
|
'msgwin-y-position': [opt_int, -1], # Default is to let the window manager decide
|
||||||
|
'msgwin-width': [opt_int, DEFAULT_WINDOW_WIDTH],
|
||||||
|
'msgwin-height': [opt_int, DEFAULT_WINDOW_HEIGHT],
|
||||||
}, {}),
|
}, {}),
|
||||||
'statusmsg': ({
|
'statusmsg': ({
|
||||||
'message': [ opt_str, '' ],
|
'message': [ opt_str, '' ],
|
||||||
|
|
|
@ -37,8 +37,12 @@ class MessageWindow:
|
||||||
'''Class for windows which contain message like things; chats,
|
'''Class for windows which contain message like things; chats,
|
||||||
groupchats, etc.'''
|
groupchats, etc.'''
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, acct, type):
|
||||||
self._controls = {}
|
self._controls = {}
|
||||||
|
# If None, the window is not tied to any specific account
|
||||||
|
self.account = acct
|
||||||
|
# If None, the window is not tied to any specific type
|
||||||
|
self.type = type
|
||||||
|
|
||||||
self.widget_name = 'message_window'
|
self.widget_name = 'message_window'
|
||||||
self.xml = gtk.glade.XML(GTKGUI_GLADE, self.widget_name, APP)
|
self.xml = gtk.glade.XML(GTKGUI_GLADE, self.widget_name, APP)
|
||||||
|
@ -178,7 +182,6 @@ class MessageWindow:
|
||||||
|
|
||||||
def show_title(self, urgent = True, control = None):
|
def show_title(self, urgent = True, control = None):
|
||||||
'''redraw the window's title'''
|
'''redraw the window's title'''
|
||||||
print "show_title"
|
|
||||||
unread = 0
|
unread = 0
|
||||||
for ctl in self._controls.values():
|
for ctl in self._controls.values():
|
||||||
unread += ctl.nb_unread
|
unread += ctl.nb_unread
|
||||||
|
@ -221,20 +224,20 @@ class MessageWindow:
|
||||||
ctl.type_id)
|
ctl.type_id)
|
||||||
del gajim.last_message_time[ctl.account][ctl.contact.jid]
|
del gajim.last_message_time[ctl.account][ctl.contact.jid]
|
||||||
|
|
||||||
if len(self._controls) == 1:
|
|
||||||
self.window.destroy()
|
|
||||||
return
|
|
||||||
|
|
||||||
self.notebook.remove_page(self.notebook.page_num(ctl.widget))
|
self.notebook.remove_page(self.notebook.page_num(ctl.widget))
|
||||||
|
|
||||||
del self._controls[contact.jid]
|
del self._controls[contact.jid]
|
||||||
if len(self._controls) == 1: # we now have only one tab
|
if len(self._controls) == 1: # we are going from two tabs to one
|
||||||
show_tabs_if_one_tab = gajim.config.get('tabs_always_visible')
|
show_tabs_if_one_tab = gajim.config.get('tabs_always_visible')
|
||||||
self.notebook.set_show_tabs(show_tabs_if_one_tab)
|
self.notebook.set_show_tabs(show_tabs_if_one_tab)
|
||||||
if not show_tabs_if_one_tab:
|
if not show_tabs_if_one_tab:
|
||||||
self.alignment.set_property('top-padding', 0)
|
self.alignment.set_property('top-padding', 0)
|
||||||
|
|
||||||
self.show_title()
|
self.show_title()
|
||||||
|
elif len(self._controls) == 0:
|
||||||
|
# FIXME: These are not called when the window is destroyed like this, fake it
|
||||||
|
gajim.interface.msg_win_mgr._on_window_delete(self.window, None)
|
||||||
|
gajim.interface.msg_win_mgr._on_window_destroy(self.window)
|
||||||
|
self.window.destroy()
|
||||||
|
|
||||||
def redraw_tab(self, contact, chatstate = None):
|
def redraw_tab(self, contact, chatstate = None):
|
||||||
ctl = self._controls[contact.jid]
|
ctl = self._controls[contact.jid]
|
||||||
|
@ -378,9 +381,9 @@ class MessageWindow:
|
||||||
def popup_menu(self, event):
|
def popup_menu(self, event):
|
||||||
menu = self.get_active_control().prepare_context_menu()
|
menu = self.get_active_control().prepare_context_menu()
|
||||||
# common menuitems (tab switches)
|
# common menuitems (tab switches)
|
||||||
if len(self._controls) > 1: # if there is more than one tab
|
if len(self.controls) > 1: # if there is more than one tab
|
||||||
menu.append(gtk.SeparatorMenuItem()) # seperator
|
menu.append(gtk.SeparatorMenuItem()) # seperator
|
||||||
for ctl in self._controls.values():
|
for ctl in self.controls.values():
|
||||||
jid = ctl.contact.jid
|
jid = ctl.contact.jid
|
||||||
if jid != self.get_active_jid():
|
if jid != self.get_active_jid():
|
||||||
item = gtk.ImageMenuItem(_('Switch to %s') %\
|
item = gtk.ImageMenuItem(_('Switch to %s') %\
|
||||||
|
@ -477,38 +480,19 @@ class MessageWindowMgr:
|
||||||
self.mode = common.config.opt_one_window_types.index(mode)
|
self.mode = common.config.opt_one_window_types.index(mode)
|
||||||
assert(self.mode != -1)
|
assert(self.mode != -1)
|
||||||
|
|
||||||
def _new_window(self):
|
def _new_window(self, acct, type):
|
||||||
win = MessageWindow()
|
win = MessageWindow(acct, type)
|
||||||
# we track the lifetime of this window
|
# we track the lifetime of this window
|
||||||
win.window.connect('delete-event', self._on_window_delete)
|
win.window.connect('delete-event', self._on_window_delete)
|
||||||
win.window.connect('destroy', self._on_window_destroy)
|
win.window.connect('destroy', self._on_window_destroy)
|
||||||
return win
|
return win
|
||||||
|
|
||||||
def _gtkWinToMsgWin(self, gtk_win):
|
def _gtk_win_to_msg_win(self, gtk_win):
|
||||||
for w in self._windows.values():
|
for w in self._windows.values():
|
||||||
if w.window == gtk_win:
|
if w.window == gtk_win:
|
||||||
return w
|
return w
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _on_window_delete(self, win, event):
|
|
||||||
# FIXME: Do based on type, main, never, peracct, pertype
|
|
||||||
if gajim.config.get('saveposition'):
|
|
||||||
# save the window size and position
|
|
||||||
x, y = win.get_position()
|
|
||||||
if self.mode != self.CONFIG_NEVER:
|
|
||||||
gajim.config.set('msgwin-x-position', x)
|
|
||||||
gajim.config.set('msgwin-y-position', y)
|
|
||||||
width, height = win.get_size()
|
|
||||||
gajim.config.set('msgwin-width', width)
|
|
||||||
gajim.config.set('msgwin-height', height)
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _on_window_destroy(self, win):
|
|
||||||
for k in self._windows.keys():
|
|
||||||
if self._windows[k].window == win:
|
|
||||||
del self._windows[k]
|
|
||||||
return
|
|
||||||
|
|
||||||
def get_window(self, jid):
|
def get_window(self, jid):
|
||||||
for win in self._windows.values():
|
for win in self._windows.values():
|
||||||
if win.get_control(jid):
|
if win.get_control(jid):
|
||||||
|
@ -517,8 +501,53 @@ class MessageWindowMgr:
|
||||||
def has_window(self, jid):
|
def has_window(self, jid):
|
||||||
return self.get_window(jid)
|
return self.get_window(jid)
|
||||||
|
|
||||||
def create_window(self, contact, acct, type):
|
def one_window_opened(self, contact, acct, type):
|
||||||
key = None
|
return self._windows[self._mode_to_key(contact, acct, type)] != None
|
||||||
|
|
||||||
|
def _size_window(self, win, acct, type):
|
||||||
|
'''Returns the size tuple: (width, height)'''
|
||||||
|
size = None
|
||||||
|
if not gajim.config.get('saveposition'):
|
||||||
|
size = (common.config.DEFAULT_WINDOW_WIDTH,
|
||||||
|
common.config.DEFAULT_WINDOW_HEIGHT)
|
||||||
|
else:
|
||||||
|
if self.mode == self.CONFIG_NEVER or self.mode == self.CONFIG_ALWAYS:
|
||||||
|
size = (gajim.config.get('msgwin-width'),
|
||||||
|
gajim.config.get('msgwin-height'))
|
||||||
|
elif self.mode == self.CONFIG_PERACCT:
|
||||||
|
size = (gajim.config.get_per('msgwin-width', acct),
|
||||||
|
gajim.config.get_per('msgwin-height', acct))
|
||||||
|
elif self.mode == self.CONFIG_PERTYPE:
|
||||||
|
if type == message_control.TYPE_PM:
|
||||||
|
type = message_control.TYPE_CHAT
|
||||||
|
opt_width = type + '-msgwin-width'
|
||||||
|
opt_height = type + '-msgwin-height'
|
||||||
|
size = (gajim.config.get(opt_width),
|
||||||
|
gajim.config.get(opt_height))
|
||||||
|
print "Window size:", size
|
||||||
|
gtkgui_helpers.resize_window(win.window, size[0], size[1])
|
||||||
|
|
||||||
|
def _position_window(self, win, acct, type):
|
||||||
|
'''Returns the position tuple: (x, y)'''
|
||||||
|
if not gajim.config.get('saveposition') or self.mode == self.CONFIG_NEVER:
|
||||||
|
return
|
||||||
|
|
||||||
|
pos = (-1, -1) # default is left up to the native window manager
|
||||||
|
if self.mode == self.CONFIG_ALWAYS:
|
||||||
|
pos = (gajim.config.get('msgwin-x-position'),
|
||||||
|
gajim.config.get('msgwin-y-position'))
|
||||||
|
elif self.mode == self.CONFIG_PERACCT:
|
||||||
|
pos = (gajim.config.get_per('msgwin-x-position', acct),
|
||||||
|
gajim.config.get_per('msgwin-y-position', acct))
|
||||||
|
elif self.mode == self.CONFIG_PERTYPE:
|
||||||
|
pos = (gajim.config.get(type + '-msgwin-x-position'),
|
||||||
|
gajim.config.get(type + '-msgwin-y-position'))
|
||||||
|
|
||||||
|
print "Window position:", pos
|
||||||
|
if pos[0] != -1 and pos[1] != -1:
|
||||||
|
gtkgui_helpers.move_window(win.window, pos[0], pos[1])
|
||||||
|
|
||||||
|
def _mode_to_key(self, contact, acct, type):
|
||||||
if self.mode == self.CONFIG_NEVER:
|
if self.mode == self.CONFIG_NEVER:
|
||||||
key = contact.jid
|
key = contact.jid
|
||||||
elif self.mode == self.CONFIG_ALWAYS:
|
elif self.mode == self.CONFIG_ALWAYS:
|
||||||
|
@ -528,32 +557,79 @@ class MessageWindowMgr:
|
||||||
elif self.mode == self.CONFIG_PERTYPE:
|
elif self.mode == self.CONFIG_PERTYPE:
|
||||||
key = type
|
key = type
|
||||||
|
|
||||||
|
def create_window(self, contact, acct, type):
|
||||||
|
key = None
|
||||||
|
win_acct = None
|
||||||
|
win_type = None
|
||||||
|
|
||||||
|
key = self._mode_to_key(contact, acct, type)
|
||||||
|
if self.mode == self.CONFIG_PERACCT:
|
||||||
|
win_acct = acct
|
||||||
|
elif self.mode == self.CONFIG_PERTYPE:
|
||||||
|
win_type = type
|
||||||
|
|
||||||
win = None
|
win = None
|
||||||
try:
|
try:
|
||||||
win = self._windows[key]
|
win = self._windows[key]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# FIXME
|
win = self._new_window(win_acct, win_type)
|
||||||
print "Creating tabbed chat window for '%s'" % str(key)
|
|
||||||
win = self._new_window()
|
|
||||||
self._windows[key] = win
|
self._windows[key] = win
|
||||||
|
|
||||||
# Postion and size window based on saved state and window mode
|
# Postion and size window based on saved state and window mode
|
||||||
if gajim.config.get('saveposition'):
|
self._position_window(win, acct, type)
|
||||||
# FIXME: Add a peracct and pertype positioning mode/config
|
self._size_window(win, acct, type)
|
||||||
print "x,y",gajim.config.get('msgwin-x-position'),gajim.config.get('msgwin-y-position')
|
|
||||||
print "width,height",gajim.config.get('msgwin-width'),gajim.config.get('msgwin-height')
|
|
||||||
|
|
||||||
if self.mode != self.CONFIG_NEVER:
|
|
||||||
gtkgui_helpers.move_window(win.window,
|
|
||||||
gajim.config.get('msgwin-x-position'),
|
|
||||||
gajim.config.get('msgwin-y-position'))
|
|
||||||
gtkgui_helpers.resize_window(win.window,
|
|
||||||
gajim.config.get('msgwin-width'),
|
|
||||||
gajim.config.get('msgwin-height'))
|
|
||||||
|
|
||||||
assert(win)
|
|
||||||
return win
|
return win
|
||||||
|
|
||||||
|
def _on_window_delete(self, win, event):
|
||||||
|
if not gajim.config.get('saveposition'):
|
||||||
|
return False
|
||||||
|
msg_win = self._gtk_win_to_msg_win(win)
|
||||||
|
|
||||||
|
# Save widnow size and postion
|
||||||
|
pos_x_key = 'msgwin-x-position'
|
||||||
|
pos_y_key = 'msgwin-y-position'
|
||||||
|
size_width_key = 'msgwin-width'
|
||||||
|
size_height_key = 'msgwin-height'
|
||||||
|
|
||||||
|
acct = None
|
||||||
|
x, y = win.get_position()
|
||||||
|
width, height = win.get_size()
|
||||||
|
|
||||||
|
if self.mode == self.CONFIG_NEVER:
|
||||||
|
x = y = -1
|
||||||
|
elif self.mode == self.CONFIG_PERACCT:
|
||||||
|
acct = msg_win.account
|
||||||
|
elif self.mode == self.CONFIG_PERTYPE:
|
||||||
|
type = msg_win.type_id
|
||||||
|
pos_x_key = type + "-msgwin-x-position"
|
||||||
|
pos_y_key = type + "-msgwin-y-position"
|
||||||
|
size_width_key = type + "-msgwin-width"
|
||||||
|
size_height_key = type + "-msgwin-height"
|
||||||
|
|
||||||
|
print "saving acct:", acct
|
||||||
|
print "saving %s=%d" % (pos_x_key, x)
|
||||||
|
print "saving %s=%d" % (pos_y_key, y)
|
||||||
|
print "saving %s=%d" % (size_width_key, width)
|
||||||
|
print "saving %s=%d" % (size_height_key, height)
|
||||||
|
if acct:
|
||||||
|
gajim.config.set_per(pos_x_key, x, acct)
|
||||||
|
gajim.config.set_per(pos_y_key, y, acct)
|
||||||
|
gajim.config.set_per(size_width_key, width, acct)
|
||||||
|
gajim.config.set_per(size_height_key, height, acct)
|
||||||
|
else:
|
||||||
|
gajim.config.set(pos_x_key, x)
|
||||||
|
gajim.config.set(pos_y_key, y)
|
||||||
|
gajim.config.set(size_width_key, width)
|
||||||
|
gajim.config.set(size_height_key, height)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _on_window_destroy(self, win):
|
||||||
|
for k in self._windows.keys():
|
||||||
|
if self._windows[k].window == win:
|
||||||
|
del self._windows[k]
|
||||||
|
return
|
||||||
|
|
||||||
def get_control(self, jid):
|
def get_control(self, jid):
|
||||||
'''Amongst all windows, return the MessageControl for jid'''
|
'''Amongst all windows, return the MessageControl for jid'''
|
||||||
win = self.get_window(jid)
|
win = self.get_window(jid)
|
||||||
|
|
Loading…
Add table
Reference in a new issue