Ticket #215: 215.patch

File 215.patch, 12.8 KB (added by erikos, 15 years ago)

refine the alert to match the spec

  • src/sugar/activity/activity.py

    diff --git a/src/sugar/activity/activity.py b/src/sugar/activity/activity.py
    index f3ee5b8..38fd421 100644
    a b will need for a real activity. 
    3030STABLE.
    3131"""
    3232# Copyright (C) 2006-2007 Red Hat, Inc.
    33 # Copyright (C) 2007-2008 One Laptop Per Child
     33# Copyright (C) 2007-2008-2009 One Laptop Per Child
    3434#
    3535# This library is free software; you can redistribute it and/or
    3636# modify it under the terms of the GNU Lesser General Public
    from hashlib import sha1 
    5555import traceback
    5656import gconf
    5757
    58 import gtk, gobject
     58import gtk
     59import gobject
     60import hippo
    5961import dbus
    6062import dbus.service
    6163import cjson
    from sugar.graphics.toolbutton import ToolButton 
    7072from sugar.graphics.toolcombobox import ToolComboBox
    7173from sugar.graphics.alert import Alert
    7274from sugar.graphics.icon import Icon
     75from sugar.graphics.icon import CanvasIcon
     76from sugar.graphics.entry import CanvasEntry
    7377from sugar.graphics.xocolor import XoColor
    7478from sugar.datastore import datastore
    7579from sugar.session import XSMPClient
    7680from sugar import wm
    77 from sugar import _sugarext
     81
     82from jarabe.model import bundleregistry
     83from jarabe.view.canvastextview import CanvasTextView
    7884
    7985_ = lambda msg: gettext.dgettext('sugar-toolkit', msg)
    8086
    class _ActivitySession(gobject.GObject): 
    353359    def __sm_quit_cb(self, client):
    354360        self.emit('quit')
    355361
    356 class TitleAlert(gtk.Window):
    357     __gtype_name__ = 'SugarTitleAlert'
     362class NamingToolbar(gtk.Toolbar):
     363    """ Toolbar of the naming alert
     364    """
     365    __gtype_name__ = 'SugarNamingToolbar'
     366
     367    __gsignals__ = {
     368        'keep-clicked': (gobject.SIGNAL_RUN_FIRST,
     369                         gobject.TYPE_NONE,
     370                         ([]))
     371    }
     372    def __init__(self):
     373        gtk.Toolbar.__init__(self)
     374
     375        client = gconf.client_get_default()
     376        color = XoColor(client.get_string('/desktop/sugar/user/color'))
     377        icon = Icon()
     378        icon.set_from_icon_name('activity-journal',
     379                                gtk.ICON_SIZE_LARGE_TOOLBAR)
     380        icon.props.xo_color = color
     381        self._add_widget(icon)
     382
     383        self._add_separator()
     384
     385        self._title = gtk.Label(_('Name this entry'))
     386        self._add_widget(self._title)
     387       
     388        self._add_separator(True)
     389
     390        self._keep_button = ToolButton('dialog-ok')
     391        self._keep_button.set_tooltip(_('Keep'))
     392        self._keep_button.connect('clicked', self.__keep_button_clicked_cb)
     393        self.insert(self._keep_button, -1)
     394        self._keep_button.show()
     395
     396    def _add_separator(self, expand=False):
     397        separator = gtk.SeparatorToolItem()
     398        separator.props.draw = False
     399        if expand:
     400            separator.set_expand(True)
     401        else:
     402            separator.set_size_request(style.DEFAULT_SPACING, -1)
     403        self.insert(separator, -1)
     404        separator.show()
     405
     406    def _add_widget(self, widget, expand=False):
     407        tool_item = gtk.ToolItem()
     408        tool_item.set_expand(expand)
     409
     410        tool_item.add(widget)
     411        widget.show()
     412
     413        self.insert(tool_item, -1)
     414        tool_item.show()
     415
     416    def __keep_button_clicked_cb(self, widget, data=None):
     417        self.emit('keep-clicked')
     418
     419class FavoriteIcon(CanvasIcon):
     420    def __init__(self, favorite):
     421        CanvasIcon.__init__(self, icon_name='emblem-favorite',
     422                            box_width=style.GRID_CELL_SIZE*3/5,
     423                            size=style.SMALL_ICON_SIZE)
     424        self._favorite = None
     425        self.set_favorite(favorite)
     426        self.connect('button-release-event', self.__release_event_cb)
     427        self.connect('motion-notify-event', self.__motion_notify_event_cb)
     428
     429    def set_favorite(self, favorite):
     430        if favorite == self._favorite:
     431            return
     432
     433        self._favorite = favorite
     434        if favorite:
     435            client = gconf.client_get_default()
     436            color = XoColor(client.get_string('/desktop/sugar/user/color'))
     437            self.props.xo_color = color
     438        else:
     439            self.props.stroke_color = style.COLOR_BUTTON_GREY.get_svg()
     440            self.props.fill_color = style.COLOR_WHITE.get_svg()
     441
     442    def get_favorite(self):
     443        return self._favorite
    358444
    359     _BACKGROUND_COLOR = style.COLOR_BLACK.get_gdk_color()
     445    favorite = gobject.property(
     446        type=bool, default=False, getter=get_favorite, setter=set_favorite)
     447
     448    def __release_event_cb(self, icon, event):
     449        self.props.favorite = not self.props.favorite
     450
     451    def __motion_notify_event_cb(self, icon, event):
     452        if not self._favorite:
     453            if event.detail == hippo.MOTION_DETAIL_ENTER:
     454                icon.props.fill_color = style.COLOR_BUTTON_GREY.get_svg()
     455            elif event.detail == hippo.MOTION_DETAIL_LEAVE:
     456                icon.props.fill_color = style.COLOR_TRANSPARENT.get_svg()
     457
     458class NamingAlert(gtk.Window):
     459    __gtype_name__ = 'SugarNamingAlert'
    360460
    361461    def __init__(self, activity):
    362462        gtk.Window.__init__(self)
    363463
     464        self._favorite_icon = None
     465        self._title = None
     466        self._description = None
     467        self._tags = None
     468
    364469        self.set_border_width(style.LINE_WIDTH)
    365470        offset = style.GRID_CELL_SIZE
    366471        width = gtk.gdk.screen_width() - offset * 2
    class TitleAlert(gtk.Window): 
    374479
    375480        self._activity = activity
    376481
    377         alignment = gtk.Alignment(xalign=0.5, yalign=0.5)
    378         self.add(alignment)
    379         alignment.show()
    380 
    381482        vbox = gtk.VBox()
    382         vbox.set_spacing(style.DEFAULT_PADDING)
    383         alignment.add(vbox)
     483        self.add(vbox)
    384484        vbox.show()
    385485
    386         self._entry = gtk.Entry()
    387         self._entry.props.text=self._activity.metadata['title']
    388         self._entry.modify_bg(gtk.STATE_INSENSITIVE, self._BACKGROUND_COLOR)
    389         self._entry.modify_base(gtk.STATE_INSENSITIVE, self._BACKGROUND_COLOR)
    390         vbox.pack_start(self._entry)
    391         self._entry.show()
    392         self._entry.connect('activate', self.__activate_cb)
     486        toolbar = NamingToolbar()
     487        toolbar.connect('keep-clicked', self.__keep_cb)
     488        vbox.pack_start(toolbar, False)
     489        toolbar.show()
     490
     491        canvas = hippo.Canvas()
     492        self._root = hippo.CanvasBox()
     493        self._root.props.background_color = style.COLOR_WHITE.get_int()
     494        canvas.set_root(self._root)
     495        vbox.pack_start(canvas)
     496        canvas.show()
     497
     498        body = self._create_body()
     499        self._root.append(body, hippo.PACK_EXPAND)
     500
     501    def _create_body(self):
     502        body = hippo.CanvasBox()
     503        body.props.orientation = hippo.ORIENTATION_VERTICAL
     504        body.props.background_color = style.COLOR_WHITE.get_int()
     505        body.props.padding_top = style.DEFAULT_SPACING * 3
     506
     507        header = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL,
     508                                 padding=style.DEFAULT_PADDING,
     509                                 padding_right=style.GRID_CELL_SIZE,
     510                                 spacing=style.DEFAULT_SPACING)
     511        body.append(header)
     512
     513        descriptions = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL,
     514                               spacing=style.DEFAULT_SPACING * 3,
     515                               padding_left=style.GRID_CELL_SIZE,
     516                               padding_right=style.GRID_CELL_SIZE,
     517                               padding_top=style.DEFAULT_SPACING * 3)
     518
     519        body.append(descriptions, hippo.PACK_EXPAND)
     520
     521        first_column = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL,
     522                                       spacing=style.DEFAULT_SPACING)
     523        descriptions.append(first_column)
     524
     525        second_column = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL,
     526                                       spacing=style.DEFAULT_SPACING)
     527        descriptions.append(second_column, hippo.PACK_EXPAND)
     528
     529        self._favorite_icon = self._create_favorite_icon()
     530        header.append(self._favorite_icon)
     531       
     532        activity_icon = self._create_activity_icon()
     533        header.append(activity_icon)
     534       
     535        self._title = self._create_title()
     536        header.append(self._title, hippo.PACK_EXPAND)
     537       
     538        if gtk.widget_get_default_direction() == gtk.TEXT_DIR_RTL:
     539            header.reverse()
     540
     541        description_box, self._description = self._create_description()
     542        second_column.append(description_box)
     543
     544        tags_box, self._tags = self._create_tags()
     545        second_column.append(tags_box)
     546
     547        return body
     548
     549    def _create_favorite_icon(self):
     550        favorite_icon = FavoriteIcon(False)
     551        return favorite_icon
     552   
     553    def _create_activity_icon(self):
     554        bundle_id = self._activity.metadata.get('activity', '')
     555        activity_info = bundleregistry.get_registry().get_bundle(bundle_id)
     556        file_name = activity_info.get_icon()
     557        activity_icon = CanvasIcon(file_name=file_name)
     558        if self._activity.metadata.has_key('icon-color') and \
     559                self._activity.metadata['icon-color']:
     560            activity_icon.props.xo_color = XoColor( \
     561                self._activity.metadata['icon-color'])
     562        return activity_icon
     563   
     564    def _create_title(self):
     565        title = CanvasEntry()
     566        title.set_background(style.COLOR_WHITE.get_html())
     567        title.props.text = self._activity.metadata.get('title', _('Untitled'))
     568        return title
     569   
     570    def _create_description(self):
     571        vbox = hippo.CanvasBox()
     572        vbox.props.spacing = style.DEFAULT_SPACING
     573
     574        text = hippo.CanvasText(text=_('Description:'),
     575                                font_desc=style.FONT_NORMAL.get_pango_desc())
     576        text.props.color = style.COLOR_BUTTON_GREY.get_int()
     577
     578        if gtk.widget_get_default_direction() == gtk.TEXT_DIR_RTL:
     579            text.props.xalign = hippo.ALIGNMENT_END
     580        else:
     581            text.props.xalign = hippo.ALIGNMENT_START
     582
     583        vbox.append(text)
     584
     585        description = self._activity.metadata.get('description', '')
     586        text_view = CanvasTextView(description,
     587                                   box_height=style.GRID_CELL_SIZE * 2)
     588        vbox.append(text_view, hippo.PACK_EXPAND)
    393589
    394         button = gtk.Button(_('Keep'))
    395         vbox.pack_start(button)
    396         button.show()
    397         button.connect('clicked', self.__activate_cb)
     590        text_view.text_view_widget.props.accepts_tab = False
     591
     592        return vbox, text_view
     593
     594    def _create_tags(self):
     595        vbox = hippo.CanvasBox()
     596        vbox.props.spacing = style.DEFAULT_SPACING
     597       
     598        text = hippo.CanvasText(text=_('Tags:'),
     599                                font_desc=style.FONT_NORMAL.get_pango_desc())
     600        text.props.color = style.COLOR_BUTTON_GREY.get_int()
     601
     602        if gtk.widget_get_default_direction() == gtk.TEXT_DIR_RTL:
     603            text.props.xalign = hippo.ALIGNMENT_END
     604        else:
     605            text.props.xalign = hippo.ALIGNMENT_START
     606
     607        vbox.append(text)
     608       
     609        tags = self._activity.metadata.get('tags', '')
     610        text_view = CanvasTextView(tags, box_height=style.GRID_CELL_SIZE * 2)
     611        vbox.append(text_view, hippo.PACK_EXPAND)
     612
     613        text_view.text_view_widget.props.accepts_tab = False
     614
     615        return vbox, text_view
    398616
    399617    def __realize_cb(self, widget):
    400618        self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
    401619        self.window.set_accept_focus(True)
    402         self.modify_bg(gtk.STATE_NORMAL, self._BACKGROUND_COLOR)
    403620
    404     def __activate_cb(self, widget):
    405         self._activity.metadata['title'] = self._entry.props.text
     621    def __keep_cb(self, widget):
     622        is_favorite = self._favorite_icon.get_favorite()
     623        if is_favorite:
     624            self._activity.metadata['keep'] = 1
     625        else:
     626            self._activity.metadata['keep'] = 0
     627
     628        old_title = self._activity.metadata.get('title', None)
     629        if old_title != self._title.props.text:
     630            self._activity.metadata['title'] = self._title.props.text
     631
     632        old_tags = self._activity.metadata.get('tags', None)
     633        new_tags = self._tags.text_view_widget.props.buffer.props.text
     634        if old_tags != new_tags:
     635            self._activity.metadata['tags'] = new_tags
     636
     637        old_description = self._activity.metadata.get('description', None)
     638        new_description = \
     639                self._description.text_view_widget.props.buffer.props.text
     640        if old_description != new_description:
     641            self._activity.metadata['description'] = new_description
     642
    406643        self._activity.metadata['title_set_by_user'] = '1'
    407644        self._activity.close()
    408645
    class Activity(Window, gtk.Container): 
    10271264            if not self._updating_jobject:
    10281265                self._complete_close()
    10291266        else:
    1030             title_alert = TitleAlert(self)
     1267            title_alert = NamingAlert(self)
    10311268            title_alert.set_transient_for(self.get_toplevel())
    10321269            title_alert.show()
    10331270