# Copyright (C) 2007, Red Hat, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY 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, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import gtk, gobject import dbus import hippo import logging from gettext import gettext as _ import os from ConfigParser import ConfigParser from sugar import env from sugar.graphics import units from sugar.graphics import font from sugar.graphics import color from sugar.graphics import iconbutton import colorpicker _VIDEO_WIDTH = units.points_to_pixels(160) _VIDEO_HEIGHT = units.points_to_pixels(120) class IntroImage(gtk.EventBox): __gtype_name__ = "IntroImage" def __init__(self, **kwargs): gtk.EventBox.__init__(self, **kwargs) self._image = gtk.Image() self.add(self._image) def set_pixbuf(self, pixbuf): if pixbuf: self._image.set_from_pixbuf(pixbuf) else: self._image.clear() class IntroFallbackVideo(gtk.EventBox): __gtype_name__ = "IntroFallbackVideo" __gsignals__ = { 'pixbuf': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])), } def __init__(self, **kwargs): gtk.EventBox.__init__(self, **kwargs) self._image = gtk.Image() self._image.set_from_stock(gtk.STOCK_OPEN, -1) self.add(self._image) self._image.show() self.connect('button-press-event', self._button_press_event_cb) def play(self): pass def stop(self): pass def _button_press_event_cb(self, widget, event): filt = gtk.FileFilter() filt.add_pixbuf_formats() chooser = gtk.FileChooserDialog(_("Pick a buddy picture"), \ buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) chooser.set_filter(filt) resp = chooser.run() if resp == gtk.RESPONSE_ACCEPT: fname = chooser.get_filename() self.load_image(fname) chooser.hide() chooser.destroy() return True def load_image(self, path): pixbuf = gtk.gdk.pixbuf_new_from_file(path) self.emit('pixbuf', pixbuf) class VideoBox(hippo.CanvasBox, hippo.CanvasItem): __gtype_name__ = "SugarVideoBox" def __init__(self, **kwargs): hippo.CanvasBox.__init__(self, **kwargs) self.props.orientation = hippo.ORIENTATION_HORIZONTAL self._pixbuf = None self._label = hippo.CanvasText(text=_("My Picture:"), xalign=hippo.ALIGNMENT_START, padding_right=units.grid_to_pixels(0.5)) self._label.props.color = color.LABEL_TEXT.get_int() self._label.props.font_desc = font.DEFAULT.get_pango_desc() self.append(self._label) # check for camera and if not generate a .jpg has_webcam = False try: sys_bus = dbus.SystemBus() hal_obj = sys_bus.get_object ('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager') hal = dbus.Interface (hal_obj, 'org.freedesktop.Hal.Manager') udis = hal.FindDeviceByCapability ('video4linux') # check for the olpc specific camera if not udis: udis = hal.FindDeviceStringMatch('info.linux.driver','cafe1000-ccic') if udis: has_webcam = True finally: if has_webcam: import glive self._video = glive.LiveVideoSlot(_VIDEO_WIDTH, _VIDEO_HEIGHT) else: self._video = IntroFallbackVideo() self._video.set_size_request(_VIDEO_WIDTH, _VIDEO_HEIGHT) self._video.connect('pixbuf', self._new_pixbuf_cb) self._video_widget = hippo.CanvasWidget() self._video_widget.props.widget = self._video self.append(self._video_widget) gobject.idle_add(self._video.play) self._img = IntroImage() self._img.set_size_request(_VIDEO_WIDTH, _VIDEO_HEIGHT) self._img.connect('button-press-event', self._clear_image_cb) self._img_widget = hippo.CanvasWidget() self._img_widget.props.widget = self._img if not has_webcam: path = os.path.join(os.path.dirname(__file__), 'default-picture.png') self._video.load_image(path) def _clear_image_cb(self, widget, event): del self._pixbuf self._pixbuf = None self.remove(self._img_widget) self._img.set_pixbuf(None) self.append(self._video_widget) self._video.play() def _new_pixbuf_cb(self, widget, pixbuf): if self._pixbuf: del self._pixbuf self._pixbuf = pixbuf self._video.stop() self.remove(self._video_widget) scaled = pixbuf.scale_simple(_VIDEO_WIDTH, _VIDEO_HEIGHT, gtk.gdk.INTERP_BILINEAR) self._img.set_pixbuf(scaled) self._img.show_all() self.append(self._img_widget) def get_pixbuf(self): return self._pixbuf class EntryBox(hippo.CanvasBox, hippo.CanvasItem): __gtype_name__ = "SugarEntryBox" def __init__(self, **kwargs): hippo.CanvasBox.__init__(self, **kwargs) self.props.orientation = hippo.ORIENTATION_HORIZONTAL self._label = hippo.CanvasText(text=_("My Name:"), xalign=hippo.ALIGNMENT_START, padding_right=units.grid_to_pixels(0.5)) self._label.props.color = color.LABEL_TEXT.get_int() self._label.props.font_desc = font.DEFAULT.get_pango_desc() self.append(self._label) self._entry = gtk.Entry() self._entry.set_max_length(45) entry_item = hippo.CanvasWidget(widget=self._entry) self.append(entry_item) def get_text(self): return self._entry.props.text class ColorBox(hippo.CanvasBox, hippo.CanvasItem): __gtype_name__ = "SugarColorBox" def __init__(self, **kwargs): hippo.CanvasBox.__init__(self, **kwargs) self.props.orientation = hippo.ORIENTATION_HORIZONTAL self._color = None self._label = hippo.CanvasText(text=_("My Color:"), xalign=hippo.ALIGNMENT_START, padding_right=units.grid_to_pixels(0.5)) self._label.props.color = color.LABEL_TEXT.get_int() self._label.props.font_desc = font.DEFAULT.get_pango_desc() self.append(self._label) self._cp = colorpicker.ColorPicker() self._cp.connect('color', self._new_color_cb) self.append(self._cp) self._color = self._cp.get_color() def _new_color_cb(self, widget, color): self._color = color def get_color(self): return self._color class IntroBox(hippo.CanvasBox, hippo.CanvasItem): __gtype_name__ = 'SugarIntroBox' __gsignals__ = { 'ok': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT])) } def __init__(self, **kwargs): hippo.CanvasBox.__init__(self, **kwargs) self._pixbuf = None #self._video_box = VideoBox(xalign=hippo.ALIGNMENT_CENTER, # yalign=hippo.ALIGNMENT_START, # padding_bottom=units.grid_to_pixels(0.5)) #self.append(self._video_box) self._entry_box = EntryBox(xalign=hippo.ALIGNMENT_CENTER, padding_bottom=units.grid_to_pixels(0.5)) self.append(self._entry_box) self._color_box = ColorBox(xalign=hippo.ALIGNMENT_CENTER, padding_bottom=units.grid_to_pixels(0.5)) self.append(self._color_box) self._ok = iconbutton.IconButton(icon_name="theme:go-next", padding_bottom=units.grid_to_pixels(0.5)) self._ok.connect('activated', self._ok_activated) self.append(self._ok) def _ok_activated(self, item): #pixbuf = self._video_box.get_pixbuf() path = os.path.join(os.path.dirname(__file__), 'default-picture.png') pixbuf = gtk.gdk.pixbuf_new_from_file(path) name = self._entry_box.get_text() color = self._color_box.get_color() if not pixbuf or not name or not color: print "not one of pixbuf(%r), name(%r), or color(%r)" return self.emit('ok', pixbuf, name, color) class IntroWindow(gtk.Window): def __init__(self): gtk.Window.__init__(self) self.set_default_size(gtk.gdk.screen_width(), gtk.gdk.screen_height()) self.realize() self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DESKTOP) self._canvas = hippo.Canvas() self._intro_box = IntroBox(background_color=0x000000ff, yalign=hippo.ALIGNMENT_START, padding_top=units.grid_to_pixels(2), padding_left=units.grid_to_pixels(3), padding_right=units.grid_to_pixels(3)) self._intro_box.connect('ok', self._ok_cb) self._canvas.set_root(self._intro_box) self.add(self._canvas) self._canvas.show_all() def _ok_cb(self, widget, pixbuf, name, color): self.hide() gobject.idle_add(self._create_profile, pixbuf, name, color) def _create_profile(self, pixbuf, name, color): # Save the buddy icon icon_path = os.path.join(env.get_profile_path(), "buddy-icon.jpg") scaled = pixbuf.scale_simple(200, 200, gtk.gdk.INTERP_BILINEAR) pixbuf.save(icon_path, "jpeg", {"quality":"85"}) cp = ConfigParser() section = 'Buddy' if not cp.has_section(section): cp.add_section(section) # encode nickname to ascii-safe characters cp.set(section, 'NickName', name.encode("utf-8")) cp.set(section, 'Color', color.to_string()) section = 'Server' if not cp.has_section(section): cp.add_section(section) cp.set(section, 'Server', 'olpc.collabora.co.uk') cp.set(section, 'Registered', 'False') config_path = os.path.join(env.get_profile_path(), 'config') f = open(config_path, 'w') cp.write(f) f.close() # Generate keypair import commands keypath = os.path.join(env.get_profile_path(), "owner.key") cmd = "ssh-keygen -q -t dsa -f %s -C '' -N ''" % keypath (s, o) = commands.getstatusoutput(cmd) if s != 0: logging.error("Could not generate key pair: %d" % s) gtk.main_quit() return False if __name__ == "__main__": w = IntroWindow() w.show_all() w.connect('destroy', gtk.main_quit) gtk.main()