Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@member.fsf.org>2010-01-26 02:40:17 (GMT)
committer Aleksey Lim <alsroot@member.fsf.org>2010-01-26 02:40:17 (GMT)
commitdd0b987ba644d0585cab41fe56db044870d47c18 (patch)
tree5c2ff2f597a6ca0d4d8545ad237ebb8921437e72
parentd7c829a6807c1da42dae12676dae1f1c1437f2fd (diff)
Add DND support
-rw-r--r--src/jarabe/journal/Makefile.am38
-rw-r--r--src/jarabe/journal/homogeneview.py13
-rw-r--r--src/jarabe/journal/listview.py4
-rw-r--r--src/jarabe/journal/thumbsview.py13
-rw-r--r--src/jarabe/journal/widgets.py170
5 files changed, 154 insertions, 84 deletions
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