Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jarabe/journal/journalactivity.py1
-rw-r--r--src/jarabe/journal/journaltoolbox.py116
-rw-r--r--src/jarabe/journal/listview.py13
-rw-r--r--src/jarabe/journal/model.py2
-rw-r--r--src/jarabe/journal/palettes.py174
5 files changed, 230 insertions, 76 deletions
diff --git a/src/jarabe/journal/journalactivity.py b/src/jarabe/journal/journalactivity.py
index a33038a..bb1c7f6 100644
--- a/src/jarabe/journal/journalactivity.py
+++ b/src/jarabe/journal/journalactivity.py
@@ -171,6 +171,7 @@ class JournalActivity(JournalWindow):
self._list_view = ListView()
self._list_view.connect('detail-clicked', self.__detail_clicked_cb)
self._list_view.connect('clear-clicked', self.__clear_clicked_cb)
+ self._list_view.connect('volume-error', self.__volume_error_cb)
self._main_view.pack_start(self._list_view)
self._list_view.show()
diff --git a/src/jarabe/journal/journaltoolbox.py b/src/jarabe/journal/journaltoolbox.py
index d825bc9..77334b4 100644
--- a/src/jarabe/journal/journaltoolbox.py
+++ b/src/jarabe/journal/journaltoolbox.py
@@ -26,6 +26,7 @@ import gobject
import gio
import gtk
+from sugar.graphics.palette import Palette
from sugar.graphics.toolbox import Toolbox
from sugar.graphics.toolcombobox import ToolComboBox
from sugar.graphics.toolbutton import ToolButton
@@ -37,11 +38,12 @@ from sugar.graphics.xocolor import XoColor
from sugar.graphics import iconentry
from sugar.graphics import style
from sugar import mime
-from sugar import profile
from jarabe.model import bundleregistry
from jarabe.journal import misc
from jarabe.journal import model
+from jarabe.journal.palettes import ClipboardMenu
+from jarabe.journal.palettes import VolumeMenu
_AUTOSEARCH_TIMEOUT = 1000
@@ -370,19 +372,23 @@ class EntryToolbar(gtk.Toolbar):
self.add(self._resume)
self._resume.show()
- self._copy = ToolButton()
-
client = gconf.client_get_default()
color = XoColor(client.get_string('/desktop/sugar/user/color'))
+ self._copy = ToolButton()
icon = Icon(icon_name='edit-copy', xo_color=color)
self._copy.set_icon_widget(icon)
icon.show()
-
- self._copy.set_tooltip(_('Copy'))
+ self._copy.set_tooltip(_('Copy to'))
self._copy.connect('clicked', self._copy_clicked_cb)
self.add(self._copy)
self._copy.show()
+ self._duplicate = ToolButton()
+ icon = Icon(icon_name='edit-duplicate', xo_color=color)
+ self._copy.set_icon_widget(icon)
+ self._duplicate.set_tooltip(_('Duplicate'))
+ self.add(self._duplicate)
+
separator = gtk.SeparatorToolItem()
self.add(separator)
separator.show()
@@ -396,25 +402,24 @@ class EntryToolbar(gtk.Toolbar):
def set_metadata(self, metadata):
self._metadata = metadata
self._refresh_copy_palette()
+ self._refresh_duplicate_palette()
self._refresh_resume_palette()
def _resume_clicked_cb(self, button):
misc.resume(self._metadata)
def _copy_clicked_cb(self, button):
- clipboard = gtk.Clipboard()
- clipboard.set_with_data([('text/uri-list', 0, 0)],
- self.__clipboard_get_func_cb,
- self.__clipboard_clear_func_cb)
-
- def __clipboard_get_func_cb(self, clipboard, selection_data, info, data):
- # Get hold of a reference so the temp file doesn't get deleted
- self._temp_file_path = model.get_file(self._metadata['uid'])
- selection_data.set_uris(['file://' + self._temp_file_path])
-
- def __clipboard_clear_func_cb(self, clipboard, data):
- # Release and delete the temp file
- self._temp_file_path = None
+ button.palette.popup(immediate=True, state=Palette.SECONDARY)
+
+ def _duplicate_clicked_cb(self, button):
+ file_path = model.get_file(self._metadata['uid'])
+ try:
+ model.copy(self._metadata, '/')
+ except IOError, e:
+ logging.exception('Error while copying the entry.')
+ self.emit('volume-error',
+ _('Error while copying the entry. %s') % (e.strerror, ),
+ _('Error'))
def _erase_button_clicked_cb(self, button):
registry = bundleregistry.get_registry()
@@ -427,24 +432,6 @@ class EntryToolbar(gtk.Toolbar):
def _resume_menu_item_activate_cb(self, menu_item, service_name):
misc.resume(self._metadata, service_name)
- def _copy_menu_item_activate_cb(self, menu_item, mount_point):
- file_path = model.get_file(self._metadata['uid'])
-
- if not file_path or not os.path.exists(file_path):
- logging.warn('Entries without a file cannot be copied.')
- self.emit('volume-error',
- _('Entries without a file cannot be copied.'),
- _('Warning'))
- return
-
- try:
- model.copy(self._metadata, mount_point)
- except IOError, e:
- logging.exception('Error while copying the entry. %s', e.strerror)
- self.emit('volume-error',
- _('Error while copying the entry. %s') % e.strerror,
- _('Error'))
-
def _refresh_copy_palette(self):
palette = self._copy.get_palette()
@@ -452,35 +439,54 @@ class EntryToolbar(gtk.Toolbar):
palette.menu.remove(menu_item)
menu_item.destroy()
+ clipboard_menu = ClipboardMenu(self._metadata)
+ clipboard_menu.set_image(Icon(icon_name='toolbar-edit',
+ icon_size=gtk.ICON_SIZE_MENU))
+ clipboard_menu.connect('volume-error', self.__volume_error_cb)
+ palette.menu.append(clipboard_menu)
+ clipboard_menu.show()
+
if self._metadata['mountpoint'] != '/':
- journal_item = MenuItem(_('Journal'))
- journal_item.set_image(Icon(
- icon_name='activity-journal',
- xo_color=profile.get_color(),
- icon_size=gtk.ICON_SIZE_MENU))
- journal_item.connect('activate',
- self._copy_menu_item_activate_cb, '/')
- journal_item.show()
- palette.menu.append(journal_item)
+ client = gconf.client_get_default()
+ color = XoColor(client.get_string('/desktop/sugar/user/color'))
+ journal_menu = VolumeMenu(self._metadata, _('Journal'), '/')
+ journal_menu.set_image(Icon(icon_name='activity-journal',
+ xo_color=color,
+ icon_size=gtk.ICON_SIZE_MENU))
+ journal_menu.connect('volume-error', self.__volume_error_cb)
+ palette.menu.append(journal_menu)
+ journal_menu.show()
volume_monitor = gio.volume_monitor_get()
+ icon_theme = gtk.icon_theme_get_default()
for mount in volume_monitor.get_mounts():
if self._metadata['mountpoint'] == mount.get_root().get_path():
continue
- menu_item = MenuItem(mount.get_name())
-
- icon_theme = gtk.icon_theme_get_default()
+ volume_menu = VolumeMenu(self._metadata, mount.get_name(),
+ mount.get_root().get_path())
for name in mount.get_icon().props.names:
if icon_theme.has_icon(name):
- menu_item.set_image(Icon(icon_name=name,
- icon_size=gtk.ICON_SIZE_MENU))
+ volume_menu.set_image(Icon(icon_name=name,
+ icon_size=gtk.ICON_SIZE_MENU))
break
+ volume_menu.connect('volume-error', self.__volume_error_cb)
+ palette.menu.append(volume_menu)
+ volume_menu.show()
+
+ def _refresh_duplicate_palette(self):
+ color = misc.get_icon_color(self._metadata)
+ self._copy.get_icon_widget().props.xo_color = color
+ if self._metadata['mountpoint'] == '/':
+ self._duplicate.connect('clicked', self._duplicate_clicked_cb)
+ self._duplicate.show()
+ icon = self._duplicate.get_icon_widget()
+ icon.props.xo_color = color
+ icon.show()
+ else:
+ self._duplicate.hide()
- menu_item.connect('activate',
- self._copy_menu_item_activate_cb,
- mount.get_root().get_path())
- palette.menu.append(menu_item)
- menu_item.show()
+ def __volume_error_cb(self, menu_item, message, severity):
+ self.emit('volume-error', message, severity)
def _refresh_resume_palette(self):
if self._metadata.get('activity_id', ''):
diff --git a/src/jarabe/journal/listview.py b/src/jarabe/journal/listview.py
index 70ab701..a9f5a53 100644
--- a/src/jarabe/journal/listview.py
+++ b/src/jarabe/journal/listview.py
@@ -476,6 +476,8 @@ class ListView(BaseListView):
__gsignals__ = {
'detail-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([object])),
+ 'volume-error': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([str, str])),
}
def __init__(self):
@@ -491,6 +493,7 @@ class ListView(BaseListView):
self.cell_icon.connect('clicked', self.__icon_clicked_cb)
self.cell_icon.connect('detail-clicked', self.__detail_clicked_cb)
+ self.cell_icon.connect('volume-error', self.__volume_error_cb)
cell_detail = CellRendererDetail(self.tree_view)
cell_detail.connect('clicked', self.__detail_cell_clicked_cb)
@@ -532,6 +535,9 @@ class ListView(BaseListView):
def __detail_clicked_cb(self, cell, uid):
self.emit('detail-clicked', uid)
+ def __volume_error_cb(self, cell, message, severity):
+ self.emit('volume-error', message, severity)
+
def __icon_clicked_cb(self, cell, path):
row = self.tree_view.get_model()[path]
metadata = model.get(row[ListModel.COLUMN_UID])
@@ -586,6 +592,8 @@ class CellRendererActivityIcon(CellRendererIcon):
__gsignals__ = {
'detail-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([str])),
+ 'volume-error': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([str, str])),
}
def __init__(self, tree_view):
@@ -610,11 +618,16 @@ class CellRendererActivityIcon(CellRendererIcon):
palette = ObjectPalette(metadata, detail=True)
palette.connect('detail-clicked',
self.__detail_clicked_cb)
+ palette.connect('volume-error',
+ self.__volume_error_cb)
return palette
def __detail_clicked_cb(self, palette, uid):
self.emit('detail-clicked', uid)
+ def __volume_error_cb(self, palette, message, severity):
+ self.emit('volume-error', message, severity)
+
def set_show_palette(self, show_palette):
self._show_palette = show_palette
diff --git a/src/jarabe/journal/model.py b/src/jarabe/journal/model.py
index 4ea6b7e..ddf9c07 100644
--- a/src/jarabe/journal/model.py
+++ b/src/jarabe/journal/model.py
@@ -621,6 +621,8 @@ def copy(metadata, mount_point):
client = gconf.client_get_default()
metadata['icon-color'] = client.get_string('/desktop/sugar/user/color')
file_path = get_file(metadata['uid'])
+ if file_path is None:
+ file_path = ''
metadata['mountpoint'] = mount_point
del metadata['uid']
diff --git a/src/jarabe/journal/palettes.py b/src/jarabe/journal/palettes.py
index 7091378..0812475 100644
--- a/src/jarabe/journal/palettes.py
+++ b/src/jarabe/journal/palettes.py
@@ -21,6 +21,7 @@ import os
import gobject
import gtk
import gconf
+import gio
from sugar.graphics import style
from sugar.graphics.palette import Palette
@@ -43,16 +44,18 @@ class ObjectPalette(Palette):
__gsignals__ = {
'detail-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([str])),
+ 'volume-error': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([str, str])),
}
def __init__(self, metadata, detail=False):
self._metadata = metadata
- self._temp_file_path = None
activity_icon = Icon(icon_size=gtk.ICON_SIZE_LARGE_TOOLBAR)
activity_icon.props.file = misc.get_icon_name(metadata)
- activity_icon.props.xo_color = misc.get_icon_color(metadata)
+ color = misc.get_icon_color(metadata)
+ activity_icon.props.xo_color = color
if 'title' in metadata:
title = gobject.markup_escape_text(metadata['title'])
@@ -86,15 +89,24 @@ class ObjectPalette(Palette):
self.menu.append(menu_item)
menu_item.show()
- client = gconf.client_get_default()
- color = XoColor(client.get_string('/desktop/sugar/user/color'))
- menu_item = MenuItem(_('Copy'))
+ menu_item = MenuItem(_('Copy to'))
icon = Icon(icon_name='edit-copy', xo_color=color,
icon_size=gtk.ICON_SIZE_MENU)
menu_item.set_image(icon)
- menu_item.connect('activate', self.__copy_activate_cb)
self.menu.append(menu_item)
menu_item.show()
+ copy_menu = CopyMenu(metadata)
+ copy_menu.connect('volume-error', self.__volume_error_cb)
+ menu_item.set_submenu(copy_menu)
+
+ if self._metadata['mountpoint'] == '/':
+ menu_item = MenuItem(_('Duplicate'))
+ icon = Icon(icon_name='edit-duplicate', xo_color=color,
+ icon_size=gtk.ICON_SIZE_MENU)
+ menu_item.set_image(icon)
+ menu_item.connect('activate', self.__duplicate_activate_cb)
+ self.menu.append(menu_item)
+ menu_item.show()
menu_item = MenuItem(_('Send to'), 'document-send')
self.menu.append(menu_item)
@@ -118,21 +130,15 @@ class ObjectPalette(Palette):
def __start_activate_cb(self, menu_item):
misc.resume(self._metadata)
- def __copy_activate_cb(self, menu_item):
- clipboard = gtk.Clipboard()
- clipboard.set_with_data([('text/uri-list', 0, 0)],
- self.__clipboard_get_func_cb,
- self.__clipboard_clear_func_cb)
-
- def __clipboard_get_func_cb(self, clipboard, selection_data, info, data):
- # Get hold of a reference so the temp file doesn't get deleted
- self._temp_file_path = model.get_file(self._metadata['uid'])
- logging.debug('__clipboard_get_func_cb %r', self._temp_file_path)
- selection_data.set_uris(['file://' + self._temp_file_path])
-
- def __clipboard_clear_func_cb(self, clipboard, data):
- # Release and delete the temp file
- self._temp_file_path = None
+ def __duplicate_activate_cb(self, menu_item):
+ file_path = model.get_file(self._metadata['uid'])
+ try:
+ model.copy(self._metadata, '/')
+ except IOError, e:
+ logging.exception('Error while copying the entry. %s', e.strerror)
+ self.emit('volume-error',
+ _('Error while copying the entry. %s') % e.strerror,
+ _('Error'))
def __erase_activate_cb(self, menu_item):
model.delete(self._metadata['uid'])
@@ -140,6 +146,9 @@ class ObjectPalette(Palette):
def __detail_activate_cb(self, menu_item):
self.emit('detail-clicked', self._metadata['uid'])
+ def __volume_error_cb(self, menu_item, message, severity):
+ self.emit('volume-error', message, severity)
+
def __friend_selected_cb(self, menu_item, buddy):
logging.debug('__friend_selected_cb')
file_name = model.get_file(self._metadata['uid'])
@@ -162,6 +171,129 @@ class ObjectPalette(Palette):
mime_type)
+class CopyMenu(gtk.Menu):
+ __gtype_name__ = 'JournalCopyMenu'
+
+ __gsignals__ = {
+ 'volume-error': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([str, str])),
+ }
+
+ def __init__(self, metadata):
+ gobject.GObject.__init__(self)
+
+ self._metadata = metadata
+
+ clipboard_menu = ClipboardMenu(self._metadata)
+ clipboard_menu.set_image(Icon(icon_name='toolbar-edit',
+ icon_size=gtk.ICON_SIZE_MENU))
+ clipboard_menu.connect('volume-error', self.__volume_error_cb)
+ self.append(clipboard_menu)
+ clipboard_menu.show()
+
+ if self._metadata['mountpoint'] != '/':
+ client = gconf.client_get_default()
+ color = XoColor(client.get_string('/desktop/sugar/user/color'))
+ journal_menu = VolumeMenu(self._metadata, _('Journal'), '/')
+ journal_menu.set_image(Icon(icon_name='activity-journal',
+ xo_color=color,
+ icon_size=gtk.ICON_SIZE_MENU))
+ journal_menu.connect('volume-error', self.__volume_error_cb)
+ self.append(journal_menu)
+ journal_menu.show()
+
+ volume_monitor = gio.volume_monitor_get()
+ icon_theme = gtk.icon_theme_get_default()
+ for mount in volume_monitor.get_mounts():
+ if self._metadata['mountpoint'] == mount.get_root().get_path():
+ continue
+ volume_menu = VolumeMenu(self._metadata, mount.get_name(),
+ mount.get_root().get_path())
+ for name in mount.get_icon().props.names:
+ if icon_theme.has_icon(name):
+ volume_menu.set_image(Icon(icon_name=name,
+ icon_size=gtk.ICON_SIZE_MENU))
+ break
+ volume_menu.connect('volume-error', self.__volume_error_cb)
+ self.append(volume_menu)
+ volume_menu.show()
+
+ def __volume_error_cb(self, menu_item, message, severity):
+ self.emit('volume-error', message, severity)
+
+
+class VolumeMenu(MenuItem):
+ __gtype_name__ = 'JournalVolumeMenu'
+
+ __gsignals__ = {
+ 'volume-error': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([str, str])),
+ }
+
+ def __init__(self, metadata, label, mount_point):
+ MenuItem.__init__(self, label)
+ self._metadata = metadata
+ self.connect('activate', self.__copy_to_volume_cb, mount_point)
+
+ def __copy_to_volume_cb(self, menu_item, mount_point):
+ file_path = model.get_file(self._metadata['uid'])
+
+ if not file_path or not os.path.exists(file_path):
+ logging.warn('Entries without a file cannot be copied.')
+ self.emit('volume-error',
+ _('Entries without a file cannot be copied.'),
+ _('Warning'))
+ return
+
+ try:
+ model.copy(self._metadata, mount_point)
+ except IOError, e:
+ logging.exception('Error while copying the entry. %s', e.strerror)
+ self.emit('volume-error',
+ _('Error while copying the entry. %s') % e.strerror,
+ _('Error'))
+
+
+class ClipboardMenu(MenuItem):
+ __gtype_name__ = 'JournalClipboardMenu'
+
+ __gsignals__ = {
+ 'volume-error': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
+ ([str, str])),
+ }
+
+ def __init__(self, metadata):
+ MenuItem.__init__(self, _('Clipboard'))
+
+ self._temp_file_path = None
+ self._metadata = metadata
+ self.connect('activate', self.__copy_to_clipboard_cb)
+
+ def __copy_to_clipboard_cb(self, menu_item):
+ file_path = model.get_file(self._metadata['uid'])
+ if not file_path or not os.path.exists(file_path):
+ logging.warn('Entries without a file cannot be copied.')
+ self.emit('volume-error',
+ _('Entries without a file cannot be copied.'),
+ _('Warning'))
+ return
+
+ clipboard = gtk.Clipboard()
+ clipboard.set_with_data([('text/uri-list', 0, 0)],
+ self.__clipboard_get_func_cb,
+ self.__clipboard_clear_func_cb)
+
+ def __clipboard_get_func_cb(self, clipboard, selection_data, info, data):
+ # Get hold of a reference so the temp file doesn't get deleted
+ self._temp_file_path = model.get_file(self._metadata['uid'])
+ logging.debug('__clipboard_get_func_cb %r', self._temp_file_path)
+ selection_data.set_uris(['file://' + self._temp_file_path])
+
+ def __clipboard_clear_func_cb(self, clipboard, data):
+ # Release and delete the temp file
+ self._temp_file_path = None
+
+
class FriendsMenu(gtk.Menu):
__gtype_name__ = 'JournalFriendsMenu'