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

master
Tomeu Vizoso 17 years ago
parent bd9bd2d020
commit 3dc8505ec5

@ -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)

@ -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):
__gtype_name__ = 'SugarClipboardIcon'
from view.clipboardmenu import ClipboardMenu
from view.frame.frameinvoker import FrameWidgetInvoker
__gproperties__ = {
'selected' : (bool, None, None, False,
gobject.PARAM_READWRITE)
}
class ClipboardIcon(RadioToolButton):
__gtype_name__ = 'SugarClipboardIcon'
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)
self.child.connect('drag_data_get', self._drag_data_get_cb)
self.connect('notify::active', self._notify_active_cb)
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)
def get_object_id(self):
return self._object_id
def do_get_property(self, pspec):
if pspec.name == 'selected':
return self._selected
else:
return CanvasIcon.do_get_property(self, pspec)
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 _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 _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,32 +116,41 @@ 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
self._preview = preview
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")
else:
self.props.xo_color = XoColor(profile.get_color().to_string())
self.props.sensitive = (percent == 100)
def get_object_id(self):
return self._object_id
if self.props.active:
self._put_in_clipboard()
def prelight(self, enter):
if enter:
self._hover = True
self.props.background_color = style.COLOR_BLACK.get_int()
def _notify_active_cb(self, widget, pspec):
if self.props.active:
self._put_in_clipboard()
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()
self.owns_clipboard = False
def _get_targets(self):
cb_service = clipboardservice.get_instance()
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

@ -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

@ -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
icon = ClipboardIcon(object_id, name, group)
self._tray.add_item(icon, 0)
icon.show()
self.prepend(icon)
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

@ -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)
@ -45,20 +45,6 @@ class ClipboardPanelWindow(FrameWindow):
self.connect("drag_drop", self._clipboard_box.drag_drop_cb)
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")

Loading…
Cancel
Save