#3045: Fix issues with the clipboard icons and palettes.

This commit is contained in:
Tomeu Vizoso 2007-08-31 14:53:59 +02:00
parent bd9bd2d020
commit 3dc8505ec5
5 changed files with 111 additions and 206 deletions

1
NEWS
View File

@ -1,3 +1,4 @@
* #3045: Fix issues with the clipboard icons and palettes. (tomeu)
* Get invites back to work in the UI. (marco)
* Get the title on activity palette in the mesh to work. (marco)

View File

@ -19,65 +19,95 @@ import logging
from gettext import gettext as _
import gobject
import gtk
from sugar.graphics.icon import CanvasIcon
from view.clipboardmenu import ClipboardMenu
from sugar.graphics.radiotoolbutton import RadioToolButton
from sugar.graphics.xocolor import XoColor
from sugar.graphics.icon import Icon
from sugar.graphics import style
from sugar.clipboard import clipboardservice
from sugar import util
from sugar import profile
class ClipboardIcon(CanvasIcon):
from view.clipboardmenu import ClipboardMenu
from view.frame.frameinvoker import FrameWidgetInvoker
class ClipboardIcon(RadioToolButton):
__gtype_name__ = 'SugarClipboardIcon'
__gproperties__ = {
'selected' : (bool, None, None, False,
gobject.PARAM_READWRITE)
}
def __init__(self, object_id, name):
CanvasIcon.__init__(self)
def __init__(self, object_id, name, group):
RadioToolButton.__init__(self, group=group)
self._object_id = object_id
self._name = name
self._percent = 0
self._preview = None
self._activity = None
self._selected = False
self._hover = False
self.props.size = style.STANDARD_ICON_SIZE
self.props.xo_color = XoColor(profile.get_color().to_string())
self.owns_clipboard = False
self._icon = Icon()
self._icon.props.xo_color = profile.get_color()
self.set_icon_widget(self._icon)
self._icon.show()
self.props.sensitive = False
cb_service = clipboardservice.get_instance()
cb_service.connect('object-state-changed', self._object_state_changed_cb)
obj = cb_service.get_object(self._object_id)
formats = obj['FORMATS']
self.palette = ClipboardMenu(self._object_id, self._name, self._percent,
self._preview, self._activity,
formats and formats[0] == 'application/vnd.olpc-sugar')
self.palette.props.invoker = FrameWidgetInvoker(self)
def do_set_property(self, pspec, value):
if pspec.name == 'selected':
self._set_selected(value)
self.emit_paint_needed(0, 0, -1, -1)
else:
CanvasIcon.do_set_property(self, pspec, value)
self.child.connect('drag_data_get', self._drag_data_get_cb)
self.connect('notify::active', self._notify_active_cb)
def do_get_property(self, pspec):
if pspec.name == 'selected':
return self._selected
else:
return CanvasIcon.do_get_property(self, pspec)
def get_object_id(self):
return self._object_id
def _set_selected(self, selected):
self._selected = selected
if selected:
if not self._hover:
self.props.background_color = style.COLOR_SELECTION_GREY.get_int()
else:
self.props.background_color = style.COLOR_PANEL_GREY.get_int()
def _drag_data_get_cb(self, widget, context, selection, targetType, eventTime):
logging.debug('_drag_data_get_cb: requested target ' + selection.target)
cb_service = clipboardservice.get_instance()
data = cb_service.get_object_data(self._object_id, selection.target)['DATA']
selection.set(selection.target, 8, data)
def _put_in_clipboard(self):
logging.debug('ClipboardIcon._put_in_clipboard')
targets = self._get_targets()
if targets:
clipboard = gtk.Clipboard()
if not clipboard.set_with_data(targets,
self._clipboard_data_get_cb,
self._clipboard_clear_cb,
targets):
logging.error('GtkClipboard.set_with_data failed!')
else:
self.owns_clipboard = True
def _clipboard_data_get_cb(self, clipboard, selection, info, targets):
if not selection.target in [target[0] for target in targets]:
logging.warning('ClipboardIcon._clipboard_data_get_cb: asked %s but' \
' only have %r.' % (selection.target, targets))
return
cb_service = clipboardservice.get_instance()
data = cb_service.get_object_data(self._object_id, selection.target)['DATA']
selection.set(selection.target, 8, data)
def _clipboard_clear_cb(self, clipboard, targets):
logging.debug('ClipboardIcon._clipboard_clear_cb')
self.owns_clipboard = False
def _object_state_changed_cb(self, cb_service, object_id, name, percent,
icon_name, preview, activity):
if object_id != self._object_id:
return
def set_state(self, name, percent, icon_name, preview, activity):
cb_service = clipboardservice.get_instance()
obj = cb_service.get_object(self._object_id)
if obj['FORMATS'] and obj['FORMATS'][0] == 'application/vnd.olpc-sugar':
@ -86,9 +116,14 @@ class ClipboardIcon(CanvasIcon):
installable = False
if icon_name:
self.props.icon_name = icon_name
self._icon.props.icon_name = icon_name
else:
self.props.icon_name = 'application-octet-stream'
self._icon.props.icon_name = 'application-octet-stream'
self.child.drag_source_set(gtk.gdk.BUTTON1_MASK,
self._get_targets(),
gtk.gdk.ACTION_COPY)
self.child.drag_source_set_icon_name(self._icon.props.icon_name)
self._name = name
self._percent = percent
@ -96,22 +131,26 @@ class ClipboardIcon(CanvasIcon):
self._activity = activity
self.palette.set_state(name, percent, preview, activity, installable)
if (activity or installable) and percent < 100:
self.props.xo_color = XoColor("#000000,#424242")
self.props.sensitive = (percent == 100)
if self.props.active:
self._put_in_clipboard()
def _notify_active_cb(self, widget, pspec):
if self.props.active:
self._put_in_clipboard()
else:
self.props.xo_color = XoColor(profile.get_color().to_string())
self.owns_clipboard = False
def get_object_id(self):
return self._object_id
def _get_targets(self):
cb_service = clipboardservice.get_instance()
def prelight(self, enter):
if enter:
self._hover = True
self.props.background_color = style.COLOR_BLACK.get_int()
else:
self._hover = False
if self._selected:
self.props.background_color = style.COLOR_SELECTION_GREY.get_int()
else:
self.props.background_color = style.COLOR_PANEL_GREY.get_int()
attrs = cb_service.get_object(self._object_id)
format_types = attrs[clipboardservice.FORMATS_KEY]
targets = []
for format_type in format_types:
targets.append((format_type, 0, 0))
return targets

View File

@ -37,7 +37,6 @@ class ClipboardMenu(Palette):
def __init__(self, object_id, name, percent, preview, activities, installable):
Palette.__init__(self, name)
self.props.position = Palette.RIGHT
self._object_id = object_id
self._percent = percent
self._activities = activities

View File

@ -21,8 +21,10 @@ import hippo
import gtk
from sugar import util
from view.clipboardicon import ClipboardIcon
from sugar.clipboard import clipboardservice
from sugar.graphics.tray import VTray
from view.clipboardicon import ClipboardIcon
class _ContextMap:
"""Maps a drag context to the clipboard object involved in the dragging."""
@ -60,33 +62,20 @@ class ClipboardBox(hippo.CanvasBox):
self._icons = {}
self._context_map = _ContextMap()
self._selected_icon = None
self._owns_clipboard = False
self._pressed_button = None
self._press_start_x = None
self._press_start_y = None
self._tray = VTray()
self.append(hippo.CanvasWidget(widget=self._tray), hippo.PACK_EXPAND)
self._tray.show()
cb_service = clipboardservice.get_instance()
cb_service.connect('object-added', self._object_added_cb)
cb_service.connect('object-deleted', self._object_deleted_cb)
cb_service.connect('object-state-changed', self._object_state_changed_cb)
def owns_clipboard(self):
return self._owns_clipboard
def _get_icon_at_coords(self, x, y):
box_x, box_y = self.get_context().translate_to_widget(self)
x -= box_x
y -= box_y
for object_id, icon in self._icons.iteritems():
icon_x, icon_y = self.get_position(icon)
icon_width, icon_height = icon.get_allocation()
if (x >= icon_x ) and (x <= icon_x + icon_width) and \
(y >= icon_y ) and (y <= icon_y + icon_height):
return icon
return None
for icon in self._icons.values():
if icon.owns_clipboard:
return True
return False
def _add_selection(self, object_id, selection):
if not selection.data:
@ -111,73 +100,33 @@ class ClipboardBox(hippo.CanvasBox):
on_disk=False)
def _object_added_cb(self, cb_service, object_id, name):
icon = ClipboardIcon(object_id, name)
icon.connect('button-release-event', self._icon_button_release_event_cb)
self._set_icon_selected(icon)
if self._icons:
group = self._icons.values()[0]
else:
group = None
self.prepend(icon)
icon = ClipboardIcon(object_id, name, group)
self._tray.add_item(icon, 0)
icon.show()
self._set_icon_selected(icon)
self._icons[object_id] = icon
logging.debug('ClipboardBox: ' + object_id + ' was added.')
def _set_icon_selected(self, icon):
logging.debug('_set_icon_selected')
icon.props.selected = True
if self._selected_icon:
self._selected_icon.props.selected = False
icon.props.active = True
self._selected_icon = icon
def _put_in_clipboard(self, object_id):
logging.debug('ClipboardBox._put_in_clipboard')
targets = self._get_object_targets(object_id)
if targets:
clipboard = gtk.Clipboard()
if not clipboard.set_with_data(targets,
self._clipboard_data_get_cb,
self._clipboard_clear_cb,
targets):
logging.error('GtkClipboard.set_with_data failed!')
else:
self._owns_clipboard = True
def _clipboard_data_get_cb(self, clipboard, selection, info, targets):
if not selection.target in [target[0] for target in targets]:
logging.warning('ClipboardBox._clipboard_data_get_cb: asked %s but' \
' only have %r.' % (selection.target, targets))
return
object_id = self._selected_icon.get_object_id()
cb_service = clipboardservice.get_instance()
data = cb_service.get_object_data(object_id, selection.target)['DATA']
selection.set(selection.target, 8, data)
def _clipboard_clear_cb(self, clipboard, targets):
logging.debug('ClipboardBox._clipboard_clear_cb')
self._owns_clipboard = False
def _icon_button_release_event_cb(self, icon, event):
logging.debug('ClipboardBox._icon_button_release_event_cb: %r' % icon.props.selected)
if not icon.props.selected:
self._set_icon_selected(icon)
def _object_deleted_cb(self, cb_service, object_id):
icon = self._icons[object_id]
position = self.get_children().index(icon)
self.remove(icon)
if icon.props.selected and self.get_children():
self._set_icon_selected(self.get_children()[position])
del self._icons[object_id]
logging.debug('ClipboardBox: ' + object_id + ' was deleted.')
def _object_state_changed_cb(self, cb_service, object_id, name, percent,
icon_name, preview, activity):
icon = self._icons[object_id]
icon.set_state(name, percent, icon_name, preview, activity)
if icon.props.selected and percent == 100:
self._put_in_clipboard(object_id)
def drag_motion_cb(self, widget, context, x, y, time):
logging.debug('ClipboardBox._drag_motion_cb')
context.drag_status(gtk.gdk.ACTION_COPY, time)
@ -211,72 +160,3 @@ class ClipboardBox(hippo.CanvasBox):
if not self._context_map.has_context(context):
context.drop_finish(True, gtk.get_current_event_time())
def drag_data_get_cb(self, widget, context, selection, targetType, eventTime):
logging.debug("drag_data_get_cb: requested target " + selection.target)
object_id = self._last_clicked_icon.get_object_id()
cb_service = clipboardservice.get_instance()
data = cb_service.get_object_data(object_id, selection.target)['DATA']
selection.set(selection.target, 8, data)
def button_press_event_cb(self, widget, event):
logging.debug("button_press_event_cb")
if event.button == 1 and event.type == gtk.gdk.BUTTON_PRESS:
self._last_clicked_icon = self._get_icon_at_coords(event.x, event.y)
if self._last_clicked_icon:
self._pressed_button = event.button
self._press_start_x = event.x
self._press_start_y = event.y
return False
def motion_notify_event_cb(self, widget, event):
if not self._pressed_button:
return True
# if the mouse button is not pressed, no drag should occurr
if not event.state & gtk.gdk.BUTTON1_MASK:
self._pressed_button = None
return True
logging.debug("motion_notify_event_cb")
if event.is_hint:
x, y, state = event.window.get_pointer()
else:
x = event.x
y = event.y
state = event.state
if widget.drag_check_threshold(int(self._press_start_x),
int(self._press_start_y),
int(x),
int(y)):
targets = self._get_object_targets(
self._last_clicked_icon.get_object_id())
context = widget.drag_begin(targets,
gtk.gdk.ACTION_COPY,
1,
event);
return True
def drag_end_cb(self, widget, drag_context):
logging.debug("drag_end_cb")
self._pressed_button = None
def _get_object_targets(self, object_id):
cb_service = clipboardservice.get_instance()
attrs = cb_service.get_object(object_id)
format_types = attrs[clipboardservice.FORMATS_KEY]
targets = []
for format_type in format_types:
targets.append((format_type, 0, 0))
return targets

View File

@ -37,7 +37,7 @@ class ClipboardPanelWindow(FrameWindow):
self._clipboard.connect("owner-change", self._owner_change_cb)
self._clipboard_box = ClipboardBox()
self.append(self._clipboard_box)
self.append(self._clipboard_box, hippo.PACK_EXPAND)
# Receiving dnd drops
self.drag_dest_set(0, [], 0)
@ -46,20 +46,6 @@ class ClipboardPanelWindow(FrameWindow):
self.connect("drag_data_received",
self._clipboard_box.drag_data_received_cb)
# Offering dnd drags
self.drag_source_set(0, [], 0)
self.add_events(gtk.gdk.BUTTON_PRESS_MASK |
gtk.gdk.POINTER_MOTION_HINT_MASK)
self.connect("motion_notify_event",
self._clipboard_box.motion_notify_event_cb)
# FIXME I'm not sure we should expose the canvas in the Window API
self._canvas.connect("button_press_event",
self._clipboard_box.button_press_event_cb)
self.connect("drag_end", self._clipboard_box.drag_end_cb)
self.connect("drag_data_get", self._clipboard_box.drag_data_get_cb)
def _owner_change_cb(self, clipboard, event):
logging.debug("owner_change_cb")