From 334be3331bf967d9b6c60f9d55e27d2374ecc94e Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Thu, 11 Jan 2007 22:57:06 +0000 Subject: Some more usability fixes for the clipboard. --- diff --git a/services/clipboard/clipboardobject.py b/services/clipboard/clipboardobject.py index 09aa771..5fe18b7 100644 --- a/services/clipboard/clipboardobject.py +++ b/services/clipboard/clipboardobject.py @@ -26,6 +26,9 @@ class ClipboardObject: def get_preview(self): return self._get_type_info().get_preview() + + def get_activity(self): + return self._get_type_info().get_activity() def get_percent(self): return self._percent diff --git a/services/clipboard/clipboardservice.py b/services/clipboard/clipboardservice.py index d9da8cc..5a7e42a 100644 --- a/services/clipboard/clipboardservice.py +++ b/services/clipboard/clipboardservice.py @@ -26,6 +26,7 @@ NAME_KEY = 'NAME' PERCENT_KEY = 'PERCENT' ICON_KEY = 'ICON' PREVIEW_KEY = 'PREVIEW' +ACTIVITY_KEY = 'ACTIVITY' FORMATS_KEY = 'FORMATS' class ClipboardDBusServiceHelper(dbus.service.Object): @@ -63,7 +64,8 @@ class ClipboardDBusServiceHelper(dbus.service.Object): self.object_state_changed(object_id, {NAME_KEY: cb_object.get_name(), PERCENT_KEY: cb_object.get_percent(), ICON_KEY: cb_object.get_icon(), - PREVIEW_KEY: cb_object.get_preview()}) + PREVIEW_KEY: cb_object.get_preview(), + ACTIVITY_KEY: cb_object.get_activity()}) @dbus.service.method(_CLIPBOARD_DBUS_INTERFACE, in_signature="s", out_signature="") @@ -80,7 +82,8 @@ class ClipboardDBusServiceHelper(dbus.service.Object): self.object_state_changed(object_id, {NAME_KEY: cb_object.get_name(), PERCENT_KEY: percent, ICON_KEY: cb_object.get_icon(), - PREVIEW_KEY: cb_object.get_preview()}) + PREVIEW_KEY: cb_object.get_preview(), + ACTIVITY_KEY: cb_object.get_activity()}) logging.debug('Changed object with object_id ' + object_id + ' with percent ' + str(percent)) @@ -99,6 +102,7 @@ class ClipboardDBusServiceHelper(dbus.service.Object): PERCENT_KEY: cb_object.get_percent(), ICON_KEY: cb_object.get_icon(), PREVIEW_KEY: cb_object.get_preview(), + ACTIVITY_KEY: cb_object.get_activity(), FORMATS_KEY: format_types} return result_dict diff --git a/services/clipboard/typeregistry.py b/services/clipboard/typeregistry.py index 0a1aaa2..ea37dba 100644 --- a/services/clipboard/typeregistry.py +++ b/services/clipboard/typeregistry.py @@ -13,6 +13,9 @@ class FileType: def get_preview(self): raise NotImplementedError + + def get_activity(self): + raise NotImplementedError def matches_mime_type(cls, mime_type): raise NotImplementedError @@ -38,6 +41,9 @@ class TextFileType(FileType): return text[0:49] + "..." return '' + + def get_activity(self): + return '' def matches_mime_type(cls, mime_type): return mime_type in cls._types @@ -55,6 +61,9 @@ class ImageFileType(FileType): def get_preview(self): return '' + + def get_activity(self): + return '' def matches_mime_type(cls, mime_type): return mime_type in cls._types @@ -78,7 +87,10 @@ class UriFileType(FileType): return title return '' - + + def get_activity(self): + return '' + def matches_mime_type(cls, mime_type): return mime_type in cls._types matches_mime_type = classmethod(matches_mime_type) @@ -95,6 +107,9 @@ class PdfFileType(FileType): def get_preview(self): return '' + + def get_activity(self): + return 'org.laptop.sugar.Xbook' def matches_mime_type(cls, mime_type): return mime_type in cls._types @@ -112,6 +127,9 @@ class MsWordFileType(FileType): def get_preview(self): return '' + + def get_activity(self): + return 'org.laptop.AbiWordActivity' def matches_mime_type(cls, mime_type): return mime_type in cls._types @@ -129,6 +147,29 @@ class RtfFileType(FileType): def get_preview(self): return '' + + def get_activity(self): + return 'org.laptop.AbiWordActivity' + + def matches_mime_type(cls, mime_type): + return mime_type in cls._types + matches_mime_type = classmethod(matches_mime_type) + +class OOTextFileType(FileType): + + _types = set(['application/vnd.oasis.opendocument.text']) + + def get_name(self): + return _('OpenOffice text file') + + def get_icon(self): + return 'activity-abiword' + + def get_preview(self): + return '' + + def get_activity(self): + return 'org.laptop.AbiWordActivity' def matches_mime_type(cls, mime_type): return mime_type in cls._types @@ -143,6 +184,9 @@ class UnknownFileType(FileType): def get_preview(self): return '' + + def get_activity(self): + return '' def matches_mime_type(cls, mime_type): return true @@ -154,6 +198,7 @@ class TypeRegistry: self._types.append(PdfFileType) self._types.append(MsWordFileType) self._types.append(RtfFileType) + self._types.append(OOTextFileType) self._types.append(UriFileType) self._types.append(ImageFileType) self._types.append(TextFileType) diff --git a/shell/view/clipboardicon.py b/shell/view/clipboardicon.py index 42c5453..ad74c1b 100644 --- a/shell/view/clipboardicon.py +++ b/shell/view/clipboardicon.py @@ -2,6 +2,7 @@ import logging from sugar.graphics.menuicon import MenuIcon from view.clipboardmenu import ClipboardMenu +from sugar.graphics.iconcolor import IconColor from sugar.activity import ActivityFactory from sugar.clipboard import clipboardservice from sugar import util @@ -14,32 +15,30 @@ class ClipboardIcon(MenuIcon): self._name = name self._percent = 0 self._preview = None + self._activity = None self.connect('activated', self._icon_activated_cb) self._menu = None def create_menu(self): - self._menu = ClipboardMenu(self._name, self._percent, self._preview) + self._menu = ClipboardMenu(self._name, self._percent, self._preview, + self._activity) self._menu.connect('action', self._popup_action_cb) return self._menu - def set_state(self, name, percent, icon_name, preview): + def set_state(self, name, percent, icon_name, preview, activity): self._name = name self._percent = percent self._preview = preview - self.set_icon_name(icon_name) + self._activity = activity + self.set_property("icon_name", icon_name) if self._menu: - self._menu.set_state(name, percent, preview) + self._menu.set_state(name, percent, preview, activity) - def _get_activity_for_mime_type(self, mime_type): - # FIXME: We should use some kind of registry that could be extended by - # newly installed activities. - if mime_type == "application/pdf": - return "org.laptop.sugar.Xbook" - elif mime_type in ["application/msword", "text/rtf", "application/rtf"]: - return "org.laptop.AbiWordActivity" + if activity and percent < 100: + self.set_property('color', IconColor("#000000,#424242")) else: - return None - + self.set_property('color', IconColor("#000000,#FFFFFF")) + def _activity_create_success_cb(self, handler, activity): activity.start(util.unique_id()) activity.execute("open_document", [self._object_id]) @@ -47,26 +46,20 @@ class ClipboardIcon(MenuIcon): def _activity_create_error_cb(self, handler, err): pass - def _icon_activated_cb(self, icon): - if self._percent < 100: - return - - cb_service = clipboardservice.get_instance() - (name, percent, icon, preview, format_types) = \ - cb_service.get_object(self._object_id) - if not format_types: + def _open_file(self): + if self._percent < 100 or not self._activity: return logging.debug("_icon_activated_cb: " + self._object_id) - activity_type = self._get_activity_for_mime_type(format_types[0]) - if not activity_type: - return # Launch the activity to handle this item - handler = ActivityFactory.create(activity_type) + handler = ActivityFactory.create(self._activity) handler.connect('success', self._activity_create_success_cb) handler.connect('error', self._activity_create_error_cb) - + + def _icon_activated_cb(self, icon): + self._open_file() + def _popup_action_cb(self, popup, action): self.popdown() @@ -75,6 +68,8 @@ class ClipboardIcon(MenuIcon): elif action == ClipboardMenu.ACTION_DELETE: cb_service = clipboardservice.get_instance() cb_service.delete_object(self._object_id) - + elif action == ClipboardMenu.ACTION_OPEN: + self._open_file() + def get_object_id(self): return self._object_id diff --git a/shell/view/clipboardmenu.py b/shell/view/clipboardmenu.py index 031a49a..178edef 100644 --- a/shell/view/clipboardmenu.py +++ b/shell/view/clipboardmenu.py @@ -1,3 +1,4 @@ +import logging import gtk import gobject import hippo @@ -10,16 +11,28 @@ from sugar.graphics import style class ClipboardMenuItem(ClipboardBubble): def __init__(self, percent = 0, stylesheet="clipboard.Bubble"): - ClipboardBubble.__init__(self, percent = percent) + self._text_item = None + ClipboardBubble.__init__(self, percent=percent) style.apply_stylesheet(self, stylesheet) + + self._text_item = hippo.CanvasText(text=str(percent) + ' %') + style.apply_stylesheet(self._text_item, 'clipboard.MenuItem.Title') + self.append(self._text_item) + + def do_set_property(self, pspec, value): + if pspec.name == 'percent': + if self._text_item: + self._text_item.set_property('text', str(value) + ' %') + ClipboardBubble.do_set_property(self, pspec, value) + class ClipboardMenu(Menu): ACTION_DELETE = 0 - ACTION_SHARE = 1 + ACTION_OPEN = 1 ACTION_STOP_DOWNLOAD = 2 - def __init__(self, name, percent, preview): + def __init__(self, name, percent, preview, activity): Menu.__init__(self, name) if percent < 100: @@ -29,21 +42,39 @@ class ClipboardMenu(Menu): self._progress_bar = None self._remove_icon = None + self._open_icon = None self._stop_icon = None self.add_item(preview, wrap=True) - self._update_icons(percent) + self._update_icons(percent, activity) - def _update_icons(self, percent): - if percent == 100: + def _update_icons(self, percent, activity): + + if percent == 100 and activity: if not self._remove_icon: self._remove_icon = CanvasIcon(icon_name='stock-remove') self.add_action(self._remove_icon, ClipboardMenu.ACTION_DELETE) - + + if not self._open_icon: + self._open_icon = CanvasIcon(icon_name='stock-keep') + self.add_action(self._open_icon, ClipboardMenu.ACTION_OPEN) + if self._stop_icon: self.remove_action(self._stop_icon) self._stop_icon = None + elif percent == 100 and not activity: + if not self._remove_icon: + self._remove_icon = CanvasIcon(icon_name='stock-remove') + self.add_action(self._remove_icon, ClipboardMenu.ACTION_DELETE) + + if self._open_icon: + self.remove_action(self._open_icon) + self._open_icon = None + + if self._stop_icon: + self.remove_action(self._stop_icon) + self._stop_icon = None else: if not self._stop_icon: self._stop_icon = CanvasIcon(icon_name='stock-close') @@ -52,9 +83,13 @@ class ClipboardMenu(Menu): if self._remove_icon: self.remove_action(self._remove_icon) self._remove_icon = None - - def set_state(self, name, percent, preview): + + if self._open_icon: + self.remove_action(self._open_icon) + self._open_icon = None + + def set_state(self, name, percent, preview, activity): self.set_title(name) if self._progress_bar: self._progress_bar.set_property('percent', percent) - self._update_icons(percent) + self._update_icons(percent, activity) diff --git a/shell/view/frame/Frame.py b/shell/view/frame/Frame.py index 38e6d0e..f41477c 100644 --- a/shell/view/frame/Frame.py +++ b/shell/view/frame/Frame.py @@ -53,18 +53,18 @@ class EventFrame(gobject.GObject): self._hover = EventFrame.HOVER_NONE self._active = False - invisible = self._create_invisible(0, 0, gtk.gdk.screen_width(), 1) + invisible = self._create_invisible(0, 0, gtk.gdk.screen_width(), 6) self._windows.append(invisible) - invisible = self._create_invisible(0, 0, 1, gtk.gdk.screen_height()) + invisible = self._create_invisible(0, 0, 6, gtk.gdk.screen_height()) self._windows.append(invisible) - invisible = self._create_invisible(gtk.gdk.screen_width() - 1, 0, + invisible = self._create_invisible(gtk.gdk.screen_width() - 6, 0, gtk.gdk.screen_width(), gtk.gdk.screen_height()) self._windows.append(invisible) - invisible = self._create_invisible(0, gtk.gdk.screen_height() - 1, + invisible = self._create_invisible(0, gtk.gdk.screen_height() - 6, gtk.gdk.screen_width(), gtk.gdk.screen_height()) self._windows.append(invisible) diff --git a/shell/view/frame/clipboardbox.py b/shell/view/frame/clipboardbox.py index ac6798e..5a902f9 100644 --- a/shell/view/frame/clipboardbox.py +++ b/shell/view/frame/clipboardbox.py @@ -89,9 +89,9 @@ class ClipboardBox(hippo.CanvasBox): logging.debug('ClipboardBox: ' + object_id + ' was deleted.') def _object_state_changed_cb(self, cb_service, object_id, name, percent, - icon_name, preview): + icon_name, preview, activity): icon = self._icons[object_id] - icon.set_state(name, percent, icon_name, preview) + icon.set_state(name, percent, icon_name, preview, activity) logging.debug('ClipboardBox: ' + object_id + ' state was changed.') def drag_motion_cb(self, widget, context, x, y, time): @@ -188,7 +188,7 @@ class ClipboardBox(hippo.CanvasBox): def _get_targets_for_dnd(self, object_id): cb_service = clipboardservice.get_instance() - (name, percent, icon, preview, format_types) = \ + (name, percent, icon, preview, activity, format_types) = \ cb_service.get_object(object_id) targets = [] diff --git a/shell/view/stylesheet.py b/shell/view/stylesheet.py index 5b1c4c6..031716b 100644 --- a/shell/view/stylesheet.py +++ b/shell/view/stylesheet.py @@ -70,7 +70,7 @@ clipboard_bubble = { } clipboard_menu_item_title = { - 'xalign': hippo.ALIGNMENT_START, + 'xalign': hippo.ALIGNMENT_CENTER, 'padding-left': 5, 'color' : 0xFFFFFFFF, 'font' : style.get_font_description('Bold', 1.2) diff --git a/sugar/clipboard/clipboardservice.py b/sugar/clipboard/clipboardservice.py index 8455751..7809c07 100644 --- a/sugar/clipboard/clipboardservice.py +++ b/sugar/clipboard/clipboardservice.py @@ -6,6 +6,7 @@ NAME_KEY = 'NAME' PERCENT_KEY = 'PERCENT' ICON_KEY = 'ICON' PREVIEW_KEY = 'PREVIEW' +ACTIVITY_KEY = 'ACTIVITY' FORMATS_KEY = 'FORMATS' DBUS_SERVICE = "org.laptop.Clipboard" @@ -20,7 +21,7 @@ class ClipboardService(gobject.GObject): 'object-deleted': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([str])), 'object-state-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, - ([str, str, int, str, str])), + ([str, str, int, str, str, str])), } def __init__(self): @@ -64,7 +65,8 @@ class ClipboardService(gobject.GObject): def _object_state_changed_cb(self, object_id, values): self.emit('object-state-changed', object_id, values[NAME_KEY], - values[PERCENT_KEY], values[ICON_KEY], values[PREVIEW_KEY]) + values[PERCENT_KEY], values[ICON_KEY], values[PREVIEW_KEY], + values[ACTIVITY_KEY]) def add_object(self, object_id, name): self._dbus_service.add_object(object_id, name) @@ -86,7 +88,7 @@ class ClipboardService(gobject.GObject): return (result_dict[NAME_KEY], result_dict[PERCENT_KEY], result_dict[ICON_KEY], result_dict[PREVIEW_KEY], - result_dict[FORMATS_KEY]) + result_dict[ACTIVITY_KEY], result_dict[FORMATS_KEY]) def get_object_data(self, object_id, formatType): return self._dbus_service.get_object_data(object_id, formatType, diff --git a/sugar/graphics/ClipboardBubble.py b/sugar/graphics/ClipboardBubble.py index 1947fd5..acabb15 100644 --- a/sugar/graphics/ClipboardBubble.py +++ b/sugar/graphics/ClipboardBubble.py @@ -86,14 +86,27 @@ class ClipboardBubble(hippo.CanvasBox, hippo.CanvasItem): width -= line_width * 2 height -= line_width * 2 - self._paint_ellipse(cr, x, y, width, height, self._fill_color) + cr.move_to(x + self._radius, y); + cr.arc(x + width - self._radius, y + self._radius, + self._radius, math.pi * 1.5, math.pi * 2); + cr.arc(x + width - self._radius, x + height - self._radius, + self._radius, 0, math.pi * 0.5); + cr.arc(x + self._radius, y + height - self._radius, + self._radius, math.pi * 0.5, math.pi); + cr.arc(x + self._radius, y + self._radius, self._radius, + math.pi, math.pi * 1.5); + + color = self._int_to_rgb(self._fill_color) + cr.set_source_rgb(*color) + cr.fill_preserve(); color = self._int_to_rgb(self._stroke_color) cr.set_source_rgb(*color) cr.set_line_width(line_width) cr.stroke(); - self._paint_progress_bar(cr, x, y, width, height, line_width) + if self._percent > 0: + self._paint_progress_bar(cr, x, y, width, height, line_width) def _paint_progress_bar(self, cr, x, y, width, height, line_width): prog_x = x + line_width @@ -101,31 +114,21 @@ class ClipboardBubble(hippo.CanvasBox, hippo.CanvasItem): prog_width = (width - (line_width * 2)) * (self._percent / 100.0) prog_height = (height - (line_width * 2)) - self._paint_ellipse(cr, prog_x, prog_y, width, height, self._progress_color) - - def _paint_ellipse(self, cr, x, y, width, height, fill_color): - cr.move_to(x + self._radius, y) - cr.arc(x + width - self._radius, - y + self._radius, - self._radius, - math.pi * 1.5, - math.pi * 2) - cr.arc(x + width - self._radius, - x + height - self._radius, - self._radius, - 0, - math.pi * 0.5) - cr.arc(x + self._radius, - y + height - self._radius, - self._radius, - math.pi * 0.5, - math.pi) - cr.arc(x + self._radius, - y + self._radius, - self._radius, - math.pi, - math.pi * 1.5); - - color = self._int_to_rgb(fill_color) + x = prog_x + y = prog_y + width = prog_width + height = prog_height + + cr.move_to(x + self._radius, y); + cr.arc(x + width - self._radius, y + self._radius, + self._radius, math.pi * 1.5, math.pi * 2); + cr.arc(x + width - self._radius, x + height - self._radius, + self._radius, 0, math.pi * 0.5); + cr.arc(x + self._radius, y + height - self._radius, + self._radius, math.pi * 0.5, math.pi); + cr.arc(x + self._radius, y + self._radius, self._radius, + math.pi, math.pi * 1.5); + + color = self._int_to_rgb(self._progress_color) cr.set_source_rgb(*color) cr.fill_preserve(); diff --git a/sugar/graphics/canvasicon.py b/sugar/graphics/canvasicon.py index 071a745..125ddf9 100644 --- a/sugar/graphics/canvasicon.py +++ b/sugar/graphics/canvasicon.py @@ -54,6 +54,9 @@ class _IconCache: def get_handle(self, name, color, size): info = self._theme.lookup_icon(name, int(size), 0) + if not info: + raise "Icon '" + name + "' not found." + if color: key = (info.get_filename(), color.to_string()) else: @@ -160,8 +163,3 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem): def _button_press_event_cb(self, item, event): item.emit_activated() - - def set_icon_name(self, icon_name): - self._icon_name = icon_name - self._buffer = None - self.emit_paint_needed(0, 0, -1, -1) diff --git a/sugar/graphics/menu.py b/sugar/graphics/menu.py index f453b16..2cc892a 100644 --- a/sugar/graphics/menu.py +++ b/sugar/graphics/menu.py @@ -110,4 +110,4 @@ class Menu(gtk.Window): self.emit('action', action) def set_title(self, title): - self._title_item.set_text(title) + self._title_item.set_property('text', title) -- cgit v0.9.1