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

00034 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_gdk=text_color)
        highlight = self._textview.get_style().bg[gtk.STATE_SELECTED]
        self._buffer.create_tag('highlight', foreground_gdk=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