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

Slide.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 os
import gtk
import gobject
import poppler
import re
import logging
import urllib

from lernid.widgets.Widget import Widget
from lernid.lernidconfig import save_cache_path
from lernid.Statusbar import Statusbar

class Slide(Widget):

    __gtype_name__ = 'LernidSlide'

    __gsignals__ = {
        'slides-downloaded': (
            gobject.SIGNAL_RUN_LAST, None, ()
        ),
        'slide-changed': (
            gobject.SIGNAL_RUN_LAST, None, ()
        ),
    }

    SLIDE_START_SIZE = 300
    SLIDE_MIN_SIZE = 150

    def __init__(self, vertical=False):
        Widget.__init__(self, 'slide')
        self._vertical = vertical
        align = gtk.Alignment(0.5, 0.5, 1.0, 1.0)
        if vertical:
            align.set_padding(0, 5, 3, 3)
        else:
            align.set_padding(3, 5, 0, 4)
        self.add(align)
        frame = gtk.Frame()
        frame.set_shadow_type(gtk.SHADOW_IN)
        align.add(frame)
        self._scroll = gtk.ScrolledWindow()
        if vertical:
            self._scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_NEVER)
        else:
            self._scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
        self._image = gtk.Image()
        self._scroll.add_with_viewport(self._image)
        frame.add(self._scroll)
        viewport = self._scroll.get_child()
        viewport.set_shadow_type(gtk.SHADOW_NONE)
        self._master_slide = None
        self._session_slide_downloaded = False

        self.connect('expose-event', self._resize)
        self.set_no_show_all(False)
        self.hide()

    def do_event_connect(self, eventman, event):
        classroom = eventman.get_widget_by_name('classroom')
        self.event_connect_signal(classroom, 'message-received', self._classroom_msg_received)
        schedule = eventman.get_widget_by_name('schedule')
        self.event_connect_signal(schedule, 'session-changed', self._session_changed)
        self.event_connect_signal(schedule, 'session-ended', self._session_ended)

    def do_event_disconnect(self, eventman, event):
        self._image.clear()
        self.hide()
        Statusbar.pop_message('slidesession')
        self.event_disconnect_signals()

    def _classroom_msg_received(self, classroom, chan, sender, text):
        matches = re.search(r'\[SLIDE (\d+)\]', text)
        if matches and self._session_slide_downloaded:
            self._change_slide_page(int(matches.groups()[0]))

    def _change_slide_page(self, pagenumber):
        logging.debug('changing slide to page %d' % pagenumber)
        try:
            # FIXME
            slide_url = "file://%s/slides.pdf" % os.path.realpath(save_cache_path('lernid'))
            pdf = poppler.document_new_from_file(slide_url, None)
            if pagenumber < 0 or pagenumber > pdf.get_n_pages():
                return
            page = pdf.get_page(int(pagenumber) - 1)
            w, h = page.get_size()
            pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, int(w), int(h))
            page.render_to_pixbuf(0,0,8,11,1,0, pixbuf)
        except:
            Statusbar.push_message(_('An error was encountered while trying to load slide number {0}'.format(pagenumber)), duration=120)
            logging.debug("Something went wrong when loading slide %s" % pagenumber)
            return
        self._master_slide = pixbuf
        self.show()
        if self._vertical:
            length = self.allocation.height
        else:
            length = self.allocation.width
        if length < self.SLIDE_START_SIZE:
            if self._vertical:
                self.set_size_request(-1, self.SLIDE_START_SIZE)
            else:
                self.set_size_request(self.SLIDE_START_SIZE, -1)
            self.queue_resize()
        self._resize()
        self.emit('slide-changed')

    def _resize(self, widget=None, data=None):
        if self._master_slide is not None:
            mwidth, mheight = self._master_slide.get_width(), self._master_slide.get_height()
            width, height = self._scroll.allocation.width, self._scroll.allocation.height
            if self._vertical:
                height = max(self.SLIDE_MIN_SIZE, height)
                width = int(float(height)/float(mheight)*mwidth)
            else:
                width = max(self.SLIDE_MIN_SIZE, width)
                height = int(float(width)/float(mwidth)*mheight)
            newpb = gtk.gdk.Pixbuf.scale_simple(self._master_slide, width, height, gtk.gdk.INTERP_BILINEAR)
            self._image.clear()
            self._image.set_from_pixbuf(newpb)
            self._image.show()

    def _session_changed(self, schedule, session):
        Statusbar.pop_message('slidesession')
        path = os.path.join(save_cache_path('lernid'), 'slides.pdf')
        if session.slides:
            try:
                logging.debug('downloading slides from %s' % session.slides)
                urllib.urlretrieve(session.slides, path)
                Statusbar.push_message(_('Slides have been downloaded'), 'slidesession')
                self._session_slide_downloaded = True
                self.emit('slides-downloaded')
            except:
                Statusbar.push_message(_('An error was encountered while downloading slides'), 'slidesession')
                logging.debug('Error when downloading slides from %s' % session.slides)
        else:
            self._image.clear()
            self.hide()
            self._session_slides_downloaded = False
            Statusbar.push_message(_('This session does not use slides'), 'slidesession')

    def _session_ended(self, schedule):
        self._image.clear()
        self.hide()
        Statusbar.pop_message('slidesession')
        self._session_slide_downloaded = False

Generated by  Doxygen 1.6.0   Back to index