Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/jarabe/journal/listview.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/jarabe/journal/listview.py')
-rw-r--r--src/jarabe/journal/listview.py310
1 files changed, 59 insertions, 251 deletions
diff --git a/src/jarabe/journal/listview.py b/src/jarabe/journal/listview.py
index 251388d..36cd06a 100644
--- a/src/jarabe/journal/listview.py
+++ b/src/jarabe/journal/listview.py
@@ -20,12 +20,11 @@ import time
import gobject
import gtk
-import hippo
import gconf
import pango
from sugar.graphics import style
-from sugar.graphics.icon import CanvasIcon, Icon, CellRendererIcon
+from sugar.graphics.icon import CellRendererIcon
from sugar.graphics.xocolor import XoColor
from sugar import util
@@ -61,32 +60,14 @@ class BaseListView(gtk.Bin):
__gtype_name__ = 'JournalBaseListView'
__gsignals__ = {
- 'clear-clicked': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([]))
+ 'detail-clicked': (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE,
+ ([object]))
}
def __init__(self):
- self._query = {}
- self._model = None
- self._progress_bar = None
- self._last_progress_bar_pulse = None
-
- gobject.GObject.__init__(self)
-
- self.connect('destroy', self.__destroy_cb)
-
- self._scrolled_window = gtk.ScrolledWindow()
- self._scrolled_window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- self.add(self._scrolled_window)
- self._scrolled_window.show()
-
- self.tree_view = TreeView()
- self.tree_view.props.fixed_height_mode = True
- self.tree_view.modify_base(gtk.STATE_NORMAL,
- style.COLOR_WHITE.get_gdk_color())
- self._scrolled_window.add(self.tree_view)
- self.tree_view.show()
+ gtk.TreeView.__init__(self)
+ self.props.fixed_height_mode = True
self.cell_title = None
self.cell_icon = None
@@ -94,32 +75,45 @@ class BaseListView(gtk.Bin):
self.date_column = None
self._add_columns()
- self.tree_view.enable_model_drag_source(gtk.gdk.BUTTON1_MASK,
- [('text/uri-list', 0, 0),
- ('journal-object-id', 0, 0)],
- gtk.gdk.ACTION_COPY)
+ self.enable_model_drag_source(gtk.gdk.BUTTON1_MASK,
+ [('text/uri-list', 0, 0), ('journal-object-id', 0, 0)],
+ gtk.gdk.ACTION_COPY)
+
+ self.cell_title.props.editable = True
+ self.cell_title.connect('edited', self.__cell_title_edited_cb)
- # Auto-update stuff
- self._fully_obscured = True
- self._dirty = False
- self._refresh_idle_handler = None
- self._update_dates_timer = None
+ self.cell_icon.connect('clicked', self.__icon_clicked_cb)
+ self.cell_icon.connect('detail-clicked', self.__detail_clicked_cb)
- model.created.connect(self.__model_created_cb)
- model.updated.connect(self.__model_updated_cb)
- model.deleted.connect(self.__model_deleted_cb)
+ cell_detail = CellRendererDetail(self)
+ cell_detail.connect('clicked', self.__detail_cell_clicked_cb)
- def __model_created_cb(self, sender, **kwargs):
- self._set_dirty()
+ column = gtk.TreeViewColumn('')
+ column.props.sizing = gtk.TREE_VIEW_COLUMN_FIXED
+ column.props.fixed_width = cell_detail.props.width
+ column.pack_start(cell_detail)
+ self.append_column(column)
- def __model_updated_cb(self, sender, **kwargs):
- self._set_dirty()
+ self.connect('notify::hover-selection',
+ self.__notify_hover_selection_cb)
- def __model_deleted_cb(self, sender, **kwargs):
- self._set_dirty()
+ def __notify_hover_selection_cb(self, widget, pspec):
+ self.cell_icon.props.show_palette = not self.props.hover_selection
+
+ def do_size_request(self, requisition):
+ # HACK: We tell the model that the view is just resizing so it can avoid
+ # hitting both D-Bus and disk.
+ model = self.get_model()
+ if model is not None:
+ model.view_is_resizing = True
+ try:
+ gtk.TreeView.do_size_request(self, requisition)
+ finally:
+ if model is not None:
+ model.view_is_resizing = False
def _add_columns(self):
- cell_favorite = CellRendererFavorite(self.tree_view)
+ cell_favorite = CellRendererFavorite(self)
cell_favorite.connect('clicked', self.__favorite_clicked_cb)
column = gtk.TreeViewColumn('')
@@ -127,9 +121,9 @@ class BaseListView(gtk.Bin):
column.props.fixed_width = cell_favorite.props.width
column.pack_start(cell_favorite)
column.set_cell_data_func(cell_favorite, self.__favorite_set_data_cb)
- self.tree_view.append_column(column)
+ self.append_column(column)
- self.cell_icon = CellRendererActivityIcon(self.tree_view)
+ self.cell_icon = CellRendererActivityIcon(self)
column = gtk.TreeViewColumn('')
column.props.sizing = gtk.TREE_VIEW_COLUMN_FIXED
@@ -137,8 +131,8 @@ class BaseListView(gtk.Bin):
column.pack_start(self.cell_icon)
column.add_attribute(self.cell_icon, 'file-name', ListModel.COLUMN_ICON)
column.add_attribute(self.cell_icon, 'xo-color',
- ListModel.COLUMN_ICON_COLOR)
- self.tree_view.append_column(column)
+ ListModel.COLUMN_ICON_COLOR)
+ self.append_column(column)
self.cell_title = gtk.CellRendererText()
self.cell_title.props.ellipsize = pango.ELLIPSIZE_MIDDLE
@@ -152,15 +146,15 @@ class BaseListView(gtk.Bin):
self._title_column.add_attribute(self.cell_title, 'markup',
ListModel.COLUMN_TITLE)
self._title_column.connect('clicked', self.__header_clicked_cb)
- self.tree_view.append_column(self._title_column)
+ self.append_column(self._title_column)
buddies_column = gtk.TreeViewColumn('')
buddies_column.props.sizing = gtk.TREE_VIEW_COLUMN_FIXED
- self.tree_view.append_column(buddies_column)
+ self.append_column(buddies_column)
for column_index in [ListModel.COLUMN_BUDDY_1, ListModel.COLUMN_BUDDY_2,
ListModel.COLUMN_BUDDY_3]:
- cell_icon = CellRendererBuddy(self.tree_view,
+ cell_icon = CellRendererBuddy(self,
column_index=column_index)
buddies_column.pack_start(cell_icon)
buddies_column.props.fixed_width += cell_icon.props.width
@@ -186,7 +180,7 @@ class BaseListView(gtk.Bin):
self.date_column.pack_start(cell_text)
self.date_column.add_attribute(cell_text, 'text', ListModel.COLUMN_DATE)
self.date_column.connect('clicked', self.__header_clicked_cb)
- self.tree_view.append_column(self.date_column)
+ self.append_column(self.date_column)
def __header_clicked_cb(self, column_clicked):
if column_clicked == self._title_column:
@@ -206,7 +200,7 @@ class BaseListView(gtk.Bin):
else:
self._query['order_by'] = ['+timestamp']
- self.refresh()
+ self._refresh()
# Need to update the column indicators after the model has been reset
if self._query['order_by'] == ['-timestamp']:
@@ -237,19 +231,8 @@ class BaseListView(gtk.Bin):
width, height_ = layout.get_size()
return pango.PIXELS(width)
- def do_size_allocate(self, allocation):
- self.allocation = allocation
- self.child.size_allocate(allocation)
-
- def do_size_request(self, requisition):
- requisition.width, requisition.height = self.child.size_request()
-
- def __destroy_cb(self, widget):
- if self._model is not None:
- self._model.stop()
-
def __favorite_set_data_cb(self, column, cell, tree_model, tree_iter):
- favorite = self._model[tree_iter][ListModel.COLUMN_FAVORITE]
+ favorite = self.get_model()[tree_iter][ListModel.COLUMN_FAVORITE]
if favorite:
client = gconf.client_get_default()
color = XoColor(client.get_string('/desktop/sugar/user/color'))
@@ -259,7 +242,7 @@ class BaseListView(gtk.Bin):
cell.props.fill_color = style.COLOR_WHITE.get_svg()
def __favorite_clicked_cb(self, cell, path):
- row = self._model[path]
+ row = self.get_model()[path]
metadata = model.get(row[ListModel.COLUMN_UID])
if metadata['keep'] == '1':
metadata['keep'] = '0'
@@ -267,212 +250,37 @@ class BaseListView(gtk.Bin):
metadata['keep'] = '1'
model.write(metadata, update_mtime=False)
- def update_with_query(self, query_dict):
- logging.debug('ListView.update_with_query')
- self._query = query_dict
-
- if 'order_by' not in self._query:
- self._query['order_by'] = ['+timestamp']
-
- self.refresh()
-
- def refresh(self):
- logging.debug('ListView.refresh query %r', self._query)
- self._stop_progress_bar()
- self._start_progress_bar()
-
- if self._model is not None:
- self._model.stop()
-
- self._model = ListModel(self._query)
- self._model.connect('ready', self.__model_ready_cb)
- self._model.connect('progress', self.__model_progress_cb)
- self._model.setup()
-
- def __model_ready_cb(self, tree_model):
- self._stop_progress_bar()
-
- # Cannot set it up earlier because will try to access the model and it
- # needs to be ready.
- self.tree_view.set_model(self._model)
-
- if len(tree_model) == 0:
- if self._is_query_empty():
- self._show_message(MESSAGE_EMPTY_JOURNAL)
- else:
- self._show_message(MESSAGE_NO_MATCH)
- else:
- self._clear_message()
-
- def _is_query_empty(self):
- # FIXME: This is a hack, we shouldn't have to update this every time
- # a new search term is added.
- if self._query.get('query', '') or self._query.get('mime_type', '') or \
- self._query.get('keep', '') or self._query.get('mtime', '') or \
- self._query.get('activity', ''):
- return False
- else:
- return True
-
- def __model_progress_cb(self, tree_model):
- if time.time() - self._last_progress_bar_pulse > 0.05:
- if self._progress_bar is not None:
- self._progress_bar.pulse()
- self._last_progress_bar_pulse = time.time()
-
- def _start_progress_bar(self):
- alignment = gtk.Alignment(xalign=0.5, yalign=0.5, xscale=0.5)
- self.remove(self.child)
- self.add(alignment)
- alignment.show()
-
- self._progress_bar = gtk.ProgressBar()
- self._progress_bar.props.pulse_step = 0.01
- self._last_progress_bar_pulse = time.time()
- alignment.add(self._progress_bar)
- self._progress_bar.show()
-
- def _stop_progress_bar(self):
- if self.child != self._progress_bar:
- return
- self.remove(self.child)
- self.add(self._scrolled_window)
-
- def _show_message(self, message):
- canvas = hippo.Canvas()
- self.remove(self.child)
- self.add(canvas)
- canvas.show()
-
- box = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL,
- background_color=style.COLOR_WHITE.get_int(),
- yalign=hippo.ALIGNMENT_CENTER,
- spacing=style.DEFAULT_SPACING,
- padding_bottom=style.GRID_CELL_SIZE)
- canvas.set_root(box)
-
- icon = CanvasIcon(size=style.LARGE_ICON_SIZE,
- icon_name='activity-journal',
- stroke_color = style.COLOR_BUTTON_GREY.get_svg(),
- fill_color = style.COLOR_TRANSPARENT.get_svg())
- box.append(icon)
-
- if message == MESSAGE_EMPTY_JOURNAL:
- text = _('Your Journal is empty')
- elif message == MESSAGE_NO_MATCH:
- text = _('No matching entries')
- else:
- raise ValueError('Invalid message')
-
- text = hippo.CanvasText(text=text,
- xalign=hippo.ALIGNMENT_CENTER,
- font_desc=style.FONT_BOLD.get_pango_desc(),
- color = style.COLOR_BUTTON_GREY.get_int())
- box.append(text)
-
- if message == MESSAGE_NO_MATCH:
- button = gtk.Button(label=_('Clear search'))
- button.connect('clicked', self.__clear_button_clicked_cb)
- button.props.image = Icon(icon_name='dialog-cancel',
- icon_size=gtk.ICON_SIZE_BUTTON)
- canvas_button = hippo.CanvasWidget(widget=button,
- xalign=hippo.ALIGNMENT_CENTER)
- box.append(canvas_button)
-
- def __clear_button_clicked_cb(self, button):
- self.emit('clear-clicked')
-
- def _clear_message(self):
- self.remove(self.child)
- self.add(self._scrolled_window)
- self._scrolled_window.show()
-
def update_dates(self):
logging.debug('ListView.update_dates')
- visible_range = self.tree_view.get_visible_range()
+ visible_range = self.get_visible_range()
if visible_range is None:
return
path, end_path = visible_range
while True:
- x, y, width, height = self.tree_view.get_cell_area(path,
- self.date_column)
- x, y = self.tree_view.convert_tree_to_widget_coords(x, y)
- self.tree_view.queue_draw_area(x, y, width, height)
+ x, y, width, height = self.get_cell_area(path, self.date_column)
+ x, y = self.convert_tree_to_widget_coords(x, y)
+ self.queue_draw_area(x, y, width, height)
if path == end_path:
break
else:
- next_iter = self._model.iter_next(self._model.get_iter(path))
- path = self._model.get_path(next_iter)
-
- def _set_dirty(self):
- if self._fully_obscured:
- self._dirty = True
- else:
- self.refresh()
-
- def set_is_visible(self, visible):
- logging.debug('canvas_visibility_notify_event_cb %r', visible)
- if visible:
- self._fully_obscured = False
- if self._dirty:
- self.refresh()
- if self._update_dates_timer is None:
- logging.debug('Adding date updating timer')
- self._update_dates_timer = \
- gobject.timeout_add_seconds(UPDATE_INTERVAL,
- self.__update_dates_timer_cb)
- else:
- self._fully_obscured = True
- if self._update_dates_timer is not None:
- logging.debug('Remove date updating timer')
- gobject.source_remove(self._update_dates_timer)
- self._update_dates_timer = None
-
- def __update_dates_timer_cb(self):
- self.update_dates()
- return True
-
-class ListView(BaseListView):
- __gtype_name__ = 'JournalListView'
-
- __gsignals__ = {
- 'detail-clicked': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([object]))
- }
-
- def __init__(self):
- BaseListView.__init__(self)
-
- self.cell_title.props.editable = True
- self.cell_title.connect('edited', self.__cell_title_edited_cb)
-
- self.cell_icon.connect('clicked', self.__icon_clicked_cb)
- self.cell_icon.connect('detail-clicked', self.__detail_clicked_cb)
-
- cell_detail = CellRendererDetail(self.tree_view)
- cell_detail.connect('clicked', self.__detail_cell_clicked_cb)
-
- column = gtk.TreeViewColumn('')
- column.props.sizing = gtk.TREE_VIEW_COLUMN_FIXED
- column.props.fixed_width = cell_detail.props.width
- column.pack_start(cell_detail)
- self.tree_view.append_column(column)
+ next_iter = self.get_model().iter_next(
+ self.get_model().get_iter(path))
+ path = self.get_model().get_path(next_iter)
def __detail_cell_clicked_cb(self, cell, path):
- row = self.tree_view.get_model()[path]
+ row = self.get_model()[path]
self.emit('detail-clicked', row[ListModel.COLUMN_UID])
def __detail_clicked_cb(self, cell, uid):
self.emit('detail-clicked', uid)
def __icon_clicked_cb(self, cell, path):
- row = self.tree_view.get_model()[path]
+ row = self.get_model()[path]
metadata = model.get(row[ListModel.COLUMN_UID])
misc.resume(metadata)
def __cell_title_edited_cb(self, cell, path, new_text):
- row = self._model[path]
+ row = self.get_model()[path]
metadata = model.get(row[ListModel.COLUMN_UID])
metadata['title'] = new_text
model.write(metadata, update_mtime=False)