From dd0b987ba644d0585cab41fe56db044870d47c18 Mon Sep 17 00:00:00 2001 From: Aleksey Lim Date: Tue, 26 Jan 2010 02:40:17 +0000 Subject: Add DND support --- diff --git a/src/jarabe/journal/Makefile.am b/src/jarabe/journal/Makefile.am index f4bf273..d653725 100644 --- a/src/jarabe/journal/Makefile.am +++ b/src/jarabe/journal/Makefile.am @@ -1,17 +1,23 @@ sugardir = $(pythondir)/jarabe/journal -sugar_PYTHON = \ - __init__.py \ - detailview.py \ - expandedentry.py \ - journalactivity.py \ - journalentrybundle.py \ - journaltoolbox.py \ - keepicon.py \ - listmodel.py \ - listview.py \ - misc.py \ - modalalert.py \ - model.py \ - objectchooser.py \ - palettes.py \ - volumestoolbar.py +sugar_PYTHON = \ + __init__.py \ + controler.py \ + detailview.py \ + entry.py \ + expandedentry.py \ + homogenetable.py \ + homogeneview.py \ + journalactivity.py \ + journalentrybundle.py \ + journaltoolbox.py \ + listview.py \ + misc.py \ + modalalert.py \ + model.py \ + objectchooser.py \ + palettes.py \ + preview.py \ + thumbsview.py \ + view.py \ + volumestoolbar.py \ + widgets.py diff --git a/src/jarabe/journal/homogeneview.py b/src/jarabe/journal/homogeneview.py index 3176e76..2a79d3d 100644 --- a/src/jarabe/journal/homogeneview.py +++ b/src/jarabe/journal/homogeneview.py @@ -19,7 +19,6 @@ import gobject import logging from sugar.graphics import style -from sugar.graphics.roundbox import CanvasRoundBox from jarabe.journal.homogenetable import VHomogeneTable @@ -35,9 +34,8 @@ class Cell(gtk.EventBox): pass def do_fill_in(self, table, cell_index): - result_set = table.get_result_set() - result_set.seek(cell_index) - self.do_fill_in_cell_content(table, cell_index, result_set.read()) + metadata = table.get_metadata(cell_index) + self.do_fill_in_cell_content(table, cell_index, metadata) if table.hover_selection: self.select(table.cursor == cell_index) @@ -68,9 +66,6 @@ class HomogeneView(VHomogeneTable): self.connect('cursor-changed', self.__cursor_changed_cb) - def get_result_set(self): - return self._result_set - def set_result_set(self, result_set): if self._result_set is result_set: return @@ -83,6 +78,10 @@ class HomogeneView(VHomogeneTable): else: self.cell_count = result_set_length + def get_metadata(self, offset): + self._result_set.seek(offset) + return self._result_set.read() + def __cursor_changed_cb(self, table, old_cursor): if not self.hover_selection: return diff --git a/src/jarabe/journal/listview.py b/src/jarabe/journal/listview.py index d8ce421..7c6735d 100644 --- a/src/jarabe/journal/listview.py +++ b/src/jarabe/journal/listview.py @@ -38,7 +38,9 @@ class _Cell(Cell): self._keep = KeepIcon(box_width=style.GRID_CELL_SIZE) row.pack_start(self._keep, expand=False) - self._icon = ObjectIcon(size=style.STANDARD_ICON_SIZE) + self._icon = ObjectIcon( + paint_box=False, + pixel_size=style.STANDARD_ICON_SIZE) row.pack_start(self._icon, expand=False) self._title = Title() diff --git a/src/jarabe/journal/thumbsview.py b/src/jarabe/journal/thumbsview.py index aaed3d7..f3959ff 100644 --- a/src/jarabe/journal/thumbsview.py +++ b/src/jarabe/journal/thumbsview.py @@ -30,6 +30,7 @@ class _Cell(Cell): def __init__(self): Cell.__init__(self) + self._last_thumb_uid = None self._last_thumb_offset = None self._last_thumb_mtime = None @@ -53,14 +54,12 @@ class _Cell(Cell): main.props.spacing = style.DEFAULT_PADDING cell.pack_end(main) - self._icon = ObjectIcon( - border=style.LINE_WIDTH, - border_color=style.COLOR_PANEL_GREY.get_int(), - box_width=preview.THUMB_WIDTH, - box_height=preview.THUMB_HEIGHT) + self._icon = ObjectIcon(pixel_size=style.MEDIUM_ICON_SIZE) + self._icon.set_size_request(preview.THUMB_WIDTH, preview.THUMB_HEIGHT) self._icon.show() self._thumb = Thumb() + self._thumb.set_size_request(preview.THUMB_WIDTH, preview.THUMB_HEIGHT) self._thumb.show() self._thumb_box = gtk.HBox() @@ -84,9 +83,11 @@ class _Cell(Cell): self._thumb.fill_in(metadata) if self._last_thumb_offset != offset or \ + self._last_thumb_uid != metadata.get('uid') or \ self._last_thumb_mtime != metadata.get('timestamp'): self._set_thumb_widget(self._icon) self._last_thumb_offset = None + self._last_thumb_uid = metadata.get('uid') self._last_thumb_mtime = metadata.get('timestamp') preview.fetch(offset, metadata) else: @@ -94,7 +95,7 @@ class _Cell(Cell): def fill_pixbuf_in(self, offset, pixbuf): self._last_thumb_offset = offset - self._thumb.image.set_from_pixbuf(pixbuf) + self._thumb.set_from_pixbuf(pixbuf) self._set_thumb_widget(self._thumb) def _set_thumb_widget(self, widget): diff --git a/src/jarabe/journal/widgets.py b/src/jarabe/journal/widgets.py index a6386c3..5d82325 100644 --- a/src/jarabe/journal/widgets.py +++ b/src/jarabe/journal/widgets.py @@ -31,6 +31,7 @@ from sugar.graphics.icon import CanvasIcon from sugar.graphics.xocolor import XoColor from sugar.graphics.palette import Invoker from sugar.graphics.palette import WidgetInvoker +from sugar.graphics import icon from jarabe.journal.entry import Entry from jarabe.journal.palettes import BuddyPalette @@ -115,41 +116,123 @@ def KeepIcon(**kwargs): return _CanvasToWidget(KeepIconCanvas, **kwargs) -class _Launcher(object): +class _JournalObject(gtk.EventBox): + + def __init__(self, detail, paint_box): + gtk.EventBox.__init__(self) - def __init__(self, detail): self.metadata = None self._detail = detail + self._invoker = WidgetInvoker(self) + self._invoker._position_hint = Invoker.AT_CURSOR + + self.modify_fg(gtk.STATE_NORMAL, + style.COLOR_PANEL_GREY.get_gdk_color()) + self.modify_bg(gtk.STATE_NORMAL, + style.COLOR_WHITE.get_gdk_color()) + + self.add_events(gtk.gdk.BUTTON_PRESS_MASK | \ + gtk.gdk.BUTTON_RELEASE_MASK | \ + gtk.gdk.LEAVE_NOTIFY_MASK | \ + gtk.gdk.ENTER_NOTIFY_MASK) + self.connect_after('button-release-event', self.__button_release_event_cb) + self.connect('destroy', self.__destroy_cb) + if paint_box: + self.connect_after('expose-event', self.__expose_event_cb) + + # DND stuff + + self._drag = False + self._temp_drag_file_path = None + self.drag_source_set(gtk.gdk.BUTTON1_MASK, + [('text/uri-list', 0, 0), ('journal-object-id', 0, 0)], + gtk.gdk.ACTION_COPY) + self.connect('drag-begin', self.__drag_begin_cb) + self.connect('drag-data-get', self.__drag_data_get_cb) + self.connect('drag-end', self.__drag_end_cb) + + def fill_in(self, metadata): + self.metadata = metadata + self._invoker.palette = None + def create_palette(self): if self.metadata is not None: return ObjectPalette(self.metadata, detail=self._detail) + def __destroy_cb(self, icon): + if self._invoker is not None: + self._invoker.detach() + + def __expose_event_cb(self, widget, event): + __, __, width, height = self.allocation + fg = self.style.fg_gc[gtk.STATE_NORMAL] + self.window.draw_rectangle(fg, False, 0, 0, width - 1, height - 1) + + def __drag_begin_cb(self, widget, context): + self._drag = True + + if self._invoker.palette is not None: + self._invoker.palette.popdown(immediate=True) + + surface = icon.get_surface( + file_name=misc.get_icon_name(self.metadata), + xo_color=misc.get_icon_color(self.metadata)) + pixmap, bitmask = _surface_to_pixels(self.window, surface) + + context.set_icon_pixmap(self.get_colormap(), pixmap, bitmask, + surface.get_width() / 2, surface.get_height() / 2) + + def __drag_data_get_cb(self, widget, context, selection, target_type, + event_time): + if selection.target == 'text/uri-list': + # Get hold of a reference so the temp file doesn't get deleted + self._temp_drag_file_path = model.get_file(self.metadata) + logging.debug('putting %r in selection', self._temp_drag_file_path) + selection.set(selection.target, 8, self._temp_drag_file_path) + + elif selection.target == 'journal-object-id': + selection.set(selection.target, 8, self.metadata['uid']) + + def __drag_end_cb(self, widget, context): + self._drag = False + self._temp_drag_file_path = None + def __button_release_event_cb(self, button, event): - if self.metadata is not None: + if not self._drag and self.metadata is not None: misc.resume(self.metadata) return True -class ObjectIconCanvas(_Launcher, CanvasIcon): +class ObjectIcon(_JournalObject): + + def __init__(self, detail=True, paint_box=True, **kwargs): + _JournalObject.__init__(self, detail, paint_box) - def __init__(self, detail=True, **kwargs): - CanvasIcon.__init__(self, **kwargs) - _Launcher.__init__(self, detail) + self._icon = icon.Icon(**kwargs) + self._icon.show() + self.add(self._icon) def fill_in(self, metadata): - self.metadata = metadata - self.palette = None + _JournalObject.fill_in(self, metadata) + self._icon.props.file = misc.get_icon_name(metadata) + self._icon.props.xo_color = misc.get_icon_color(metadata) + + +class Thumb(_JournalObject): - self.props.file_name = misc.get_icon_name(metadata) - self.props.xo_color = misc.get_icon_color(metadata) + def __init__(self, detail=True, paint_box=True): + _JournalObject.__init__(self, detail, paint_box) + self._image = gtk.Image() + self._image.show() + self.add(self._image) -def ObjectIcon(**kwargs): - return _CanvasToWidget(ObjectIconCanvas, **kwargs) + def set_from_pixbuf(self, pixbuf): + self._image.set_from_pixbuf(pixbuf) class Title(Entry): @@ -278,47 +361,6 @@ def DetailsIcon(**kwargs): return _CanvasToWidget(DetailsIconCanvas, **kwargs) -class Thumb(_Launcher, gtk.EventBox): - - def __init__(self, detail=True): - gtk.EventBox.__init__(self) - _Launcher.__init__(self, detail) - - self.modify_fg(gtk.STATE_NORMAL, - style.COLOR_PANEL_GREY.get_gdk_color()) - self.modify_bg(gtk.STATE_NORMAL, - style.COLOR_WHITE.get_gdk_color()) - - self.add_events(gtk.gdk.BUTTON_PRESS_MASK | \ - gtk.gdk.BUTTON_RELEASE_MASK | \ - gtk.gdk.LEAVE_NOTIFY_MASK | \ - gtk.gdk.ENTER_NOTIFY_MASK) - self.set_size_request(preview.THUMB_WIDTH, preview.THUMB_HEIGHT) - - self.connect_after('expose-event', self.__expose_event_cb) - - self.image = gtk.Image() - self.image.show() - self.add(self.image) - - self._invoker = WidgetInvoker(self) - self._invoker._position_hint = Invoker.AT_CURSOR - self.connect('destroy', self.__destroy_cb) - - def __expose_event_cb(self, widget, event): - __, __, width, height = self.allocation - fg = self.style.fg_gc[gtk.STATE_NORMAL] - self.window.draw_rectangle(fg, False, 0, 0, width - 1, height - 1) - - def fill_in(self, metadata): - self.metadata = metadata - self._invoker.palette = None - - def __destroy_cb(self, icon): - if self._invoker is not None: - self._invoker.detach() - - class _BuddyIcon(CanvasIcon): def __init__(self): @@ -345,3 +387,23 @@ class _CanvasToWidget(hippo.Canvas): def fill_in(self, metadata): self.root.fill_in(metadata) + + +def _surface_to_pixels(drawable, surface): + width = surface.get_width() + height = surface.get_height() + + pixmap = gtk.gdk.Pixmap(drawable, width, height) + pixmap_context = pixmap.cairo_create() + pixmap_context.set_source_surface(surface) + pixmap_context.paint(); + + mask_row_size = (width + 7) / 8 + mask_size = height * mask_row_size + mask_data = '\x00' * mask_size + mask = gtk.gdk.bitmap_create_from_data(drawable, mask_data, width, height) + mask_context = mask.cairo_create() + mask_context.set_source_surface(surface) + mask_context.paint(); + + return pixmap, mask -- cgit v0.9.1