Logo Search packages:      
Sourcecode: lernid version File versions  Download package

NativeChatroom.py

#!/usr/bin/python
# -*- coding: utf-8 -*-
### BEGIN LICENSE
# Copyright (C) 2009 Jono Bacon <jono@ubuntu.com>
# Copyright (C) 2010 Michael Budde <mbudde@gmail.com>
#
#This program is free software: you can redistribute it and/or modify it
#under the terms of the GNU General Public License version 3, as published
#by the Free Software Foundation.
#
#This program is distributed in the hope that it will be useful, but
#WITHOUT ANY WARRANTY; without even the implied warranties of
#MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
#PURPOSE.  See the GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License along
#with this program.  If not, see <http://www.gnu.org/licenses/>.
### END LICENSE

import gtk
import gobject
import gtkmozembed
import urlparse
import logging
import pango
import time

from lernid.CouchDBPreferences import Preferences
from lernid.widgets.IrcWidget import IrcWidget

from lernid import IrcBackend

class Chatroom(IrcWidget):

    __gtype_name__ = 'LernidNativeChatroom'

    __gsignals__ = {
        'members-changed': (
            gobject.SIGNAL_RUN_LAST, None, (object,)
        ),
    }

    def __init__(self):
        IrcWidget.__init__(self, 'chatroom')
        self.set_property('can-focus', True)

        builder = self.builder_with_file('ChatWidget.ui')

        scroll = builder.get_object('scroll')
        self._adjust = scroll.get_vadjustment()

        self.add(builder.get_object('vbox1'))
        self._textview = builder.get_object('textview')
        self._textview.modify_font(pango.FontDescription('Monospace'))
        self._textview.connect('size-allocate', self._scroll)
        self._at_bottom = None

        self._buffer = self._textview.get_buffer()
        text_color = self._textview.get_style().text[gtk.STATE_INSENSITIVE]
        self._buffer.create_tag('gray', foreground=text_color)
        highlight = self._textview.get_style().bg[gtk.STATE_SELECTED]
        self._buffer.create_tag('highlight', foreground=highlight)

        self._input = builder.get_object('input')
        self._input.connect('icon-press', self._send_text)
        self._input.connect('activate', self._send_text)
        self._input.connect('key-press-event', self._key_pressed)
        self._input.modify_font(pango.FontDescription('Monospace'))

        self._questionbutton = builder.get_object('questionbutton')
        self._questionbutton.connect('toggled', self._questionbutton_toggled)

        self._init_hyperlinks()

    def do_event_connect(self, eventman, event):
        IrcWidget.do_event_connect(self, eventman, event)
        self._server = IrcBackend.Server.get_server('irc.freenode.net', event.nick)
        self._nick = event.nick
        self._chatchan = self._server.get_channel(event.chat)
        def joined(server):
            logging.debug('connected to chatroom')
            self._input.set_sensitive(True)
            self._questionbutton.set_sensitive(True)
        self.event_connect_signal(self._chatchan, 'joined', joined)
        self.event_connect_signal(self._chatchan, 'message-received', self._message_received)
        self.event_connect_signal(self._chatchan, 'message-sent', self._message_sent)
        def members_changed(chan, members):
            self.emit('members-changed', members)
        self.event_connect_signal(self._chatchan, 'members-changed', members_changed)

    def do_event_disconnect(self, eventman, event):
        self._input.set_sensitive(False)
        self._questionbutton.set_sensitive(False)
        istart, iend = self._buffer.get_bounds()
        self._buffer.delete(istart, iend)
        self._server.disconnect()
        self.event_disconnect_signals()

    def get_input_widget(self):
        return self._input

    def _key_pressed(self, widget, event):
        if (event.keyval == gtk.keysyms.Tab):
            self._try_autocomplete()
            return True
        else:
            return False

    def _try_autocomplete(self):
        text = self._input.get_text()
        pos = self._input.get_position()

        if pos == 0 or text[pos-1] == ' ':
            return

        if len(text) > pos and text[pos] == ' ':
            space = False
        else:
            space = True

        partial_nick = text[:pos].split(' ')[-1]

        members = self._chatchan.get_members()
        nicks = filter(lambda x: partial_nick in x[:len(partial_nick)], members)

        if len(nicks) == 1:
            completion = nicks[0][len(partial_nick):]

            completion += ':'
            if space:
                completion += ' '

        elif len(nicks) > 1:
            iend = self._buffer.get_end_iter()
            nicks.sort()
            self._buffer.insert_with_tags_by_name(iend, "\n" + ' '.join(nicks), 'gray')

            self._at_bottom = (self._adjust.value == self._adjust.upper -
                               self._adjust.page_size)

            # sort by length
            nicks.sort(lambda x,y: cmp(len(x), len(y)))

            completion = ''
            for i in range(len(partial_nick), len(nicks[0])):
                # filter nicknames with the same next character
                filtered_nicks = filter(lambda x: nicks[0][i] == x[i], nicks)
                if len(nicks) == len(filtered_nicks):
                    completion += nicks[0][i]
                else:
                    break
        else: # no match
            return

        self._input.insert_text(completion, pos)
        self._input.set_position(pos + len(completion))

    def _send_text(self, *args):
        text = self._input.get_text()
        if text == '':
            return
        if text.startswith('/'):
            self._append_to_buffer(_('IRC commands are not yet supported.'))
        elif self._questionbutton.get_active():
            self._questionbutton.set_active(False)
            self._chatchan.send_message('QUESTION:' + ' ' + text)
        else:
            self._chatchan.send_message(text)
        self._input.set_text('')

    def _message_received(self, chan, sender, text, msgtype):
        self._append_to_buffer(text, sender, msgtype)

    def _message_sent(self, chan, text):
        self._adjust.value = self._adjust.upper - self._adjust.page_size
        self._append_to_buffer(text, self._nick)

    def _scroll(self, textview, alloc):
        if self._at_bottom is None:
            self._at_bottom = True
        if self._at_bottom:
            self._adjust.value = self._adjust.upper - self._adjust.page_size

    def _questionbutton_toggled(self, *args):
        self._input.grab_focus()


Generated by  Doxygen 1.6.0   Back to index