diff options
Diffstat (limited to 'src/jarabe/journal/browse')
-rw-r--r-- | src/jarabe/journal/browse/__init__.py | 15 | ||||
-rw-r--r-- | src/jarabe/journal/browse/lazymodel.py | 420 | ||||
-rw-r--r-- | src/jarabe/journal/browse/smoothtable.py | 346 | ||||
-rw-r--r-- | src/jarabe/journal/browse/tableview.py | 175 | ||||
-rw-r--r-- | src/jarabe/journal/browse/treeview.py | 182 |
5 files changed, 0 insertions, 1138 deletions
diff --git a/src/jarabe/journal/browse/__init__.py b/src/jarabe/journal/browse/__init__.py deleted file mode 100644 index 307e9c3..0000000 --- a/src/jarabe/journal/browse/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (C) 2009, Aleksey Lim -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/src/jarabe/journal/browse/lazymodel.py b/src/jarabe/journal/browse/lazymodel.py deleted file mode 100644 index d590fbc..0000000 --- a/src/jarabe/journal/browse/lazymodel.py +++ /dev/null @@ -1,420 +0,0 @@ -# Copyright (C) 2009, Aleksey Lim -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import gtk -import logging -from gobject import GObject, SIGNAL_RUN_FIRST, TYPE_PYOBJECT - - -class Source(GObject): - - __gsignals__ = { - 'objects-updated': (SIGNAL_RUN_FIRST, None, []), - 'row-delayed-fetch': (SIGNAL_RUN_FIRST, None, 2 * [TYPE_PYOBJECT]), - } - - def get_count(self): - """ Returns number of objects """ - pass - - def get_row(self, offset): - """ Get object - - Returns: - objects in dict {field_name: value, ...} - False can't fint object - None wait for reply signal - - """ - pass - - def get_order(self): - """ Get current order, returns (field_name, gtk.SortType) """ - pass - - def set_order(self, field_name, sort_type): - """ Set current order """ - pass - - -class LazyModel(gtk.GenericTreeModel): - - def __init__(self, columns, calc_columns=None): - """ columns/calc_columns = {field_name: (column_num, column_type)} """ - gtk.GenericTreeModel.__init__(self) - - self.columns_by_name = {} - self.columns_by_num = {} - self.columns_types = {} - - for name, i in columns.items(): - self.columns_by_name[name] = i[0] - self.columns_by_num[i[0]] = name - self.columns_types[i[0]] = i[1] - - if calc_columns is not None: - for name, i in calc_columns.items(): - self.columns_types[i[0]] = i[1] - - self._n_columns = max(self.columns_types.keys()) + 1 - - self._source = None - self._closing = False - self._view = None - self._last_count = 0 - self._cache = {} - self._frame = (0, -1) - self._in_process = {} - self._postponed = [] - - self.set_source(None, force=True) - self.set_view(None, force=True) - - def on_calc_value(self, row, column): - # stub - pass - - def get_source(self): - return self._source - - def set_source(self, source, force=False): - if self._source == source and not force: - return - - if self._source is not None: - self._source.disconnect_by_func(self.refresh) - self._source.disconnect_by_func(self.__delayed_fetch_cb) - - self._source = source - if self._source is not None: - self._source.connect('objects-updated', self.refresh) - self._source.connect('row-delayed-fetch', self.__delayed_fetch_cb) - - self.refresh() - - source = property(get_source, set_source) - - def get_view(self): - return self._view - - def set_view(self, view, force=False): - if self._view == view and not force: - return - - cursor = None - - if self._view is not None: - cursor = self._view.get_cursor() - try: - self._closing = True - self._view.set_model(None) - finally: - self._closing = False - - self._view = view - self._cache = {} - self._frame = (0, -1) - self._in_process = {} - self._postponed = [] - self._last_count = self._source and self._source.get_count() or 0 - - if self._source is not None and view is not None: - self._update_columns() - view.set_model(self) - if cursor is not None: - view.set_cursor(*cursor) - - view = property(get_view, set_view) - - def get_order(self): - if self._source is None: - return None - order = self._source.get_order() - if order is None: - return None - return (self.columns_by_name[order[0]], order[1]) - - def set_order(self, column, order): - if self._source is None: - return - self._source.set_order(self.columns_by_num[column], order) - self._update_columns() - - def refresh(self, sender=None): - if self._source is None or self._view is None: - return - - if self._last_count == 0: - self.set_view(self._view, force=True) - - self._update_columns() - - count = self._source.get_count() - - # TODO how to handle large update, - # commented for now since in TableView - # it works fine w/o these updates - #for i in range(self._last_count, count): - # self.emit('row-inserted', (i, ), self.get_iter((i, ))) - #for i in reversed(range(count, self._last_count)): - # self.emit('row-deleted', (i, )) - if self._last_count != count: - self.emit('rows-reordered', (0, ), self.get_iter((0, )), None) - - if self._frame[0] >= count: - self._frame = (0, -1) - elif self._frame[1] >= count: - for i in range(count, self._frame[1]): - if i in self._cache: - del self._cache[i] - self._frame = (self._frame[0], count-1) - - self._cache = {} - - if self._last_count == count: - for i in range(self._frame[0], self._frame[1]+1): - self.emit('row-changed', (i, ), self.get_iter((i, ))) - - self._last_count = count - - def recalc(self, fields): - for i, row in self._cache.items(): - for field in fields: - if field in row: - del row[field] - self.emit('row-changed', (i, ), self.get_iter((i, ))) - - def get_row(self, pos, frame=None): - if self._source is None: - return False - if not isinstance(pos, tuple): - pos = self.get_path(pos) - return self._get_row(pos[0], frame or (pos, pos)) - - def __delayed_fetch_cb(self, source, offset, metadata): - if not offset in self._in_process: - logging.debug('__delayed_fetch_cb: no offset=%s' % offset) - return - - logging.debug('__delayed_fetch_cb: get %s' % offset) - - path = (offset, ) - iterator = self.get_iter(path) - row = Row(self, path, iterator, metadata) - - if self.in_frame(offset): - self._cache[offset] = row - - del self._in_process[offset] - self.emit('row-changed', path, iterator) - if self._in_process: - return - - while self._postponed: - offset, force = self._postponed.pop() - if not force and not self.in_frame(offset): - continue - row = self.get_row((offset, )) - if row is not None and row != False: - self.emit('row-changed', row.path, row.iterator) - else: - break - - def _get_row(self, offset, frame): - - def fetch(): - row = self._source.get_row(offset) - - if row is None or row == False: - if row is not None: - logging.debug('_get_row: can not find row for %s' % offset) - return False - logging.debug('_get_row: wait for reply for %s' % offset) - self._in_process[offset] = True - return None - - row = Row(self, (offset, ), self.get_iter(offset), row) - self._cache[offset] = row - return row - - out = self._cache.get(offset) - if out is not None: - return out - - if frame[0] >= frame[1]: - # just return requested single row and do not change cache - # if requested frame has <= 1 rows - if self._in_process: - self._postponed.append((offset, True)) - return None - else: - return fetch() - - if frame != self._frame: - # switch to new frame - intersect_min = max(frame[0], self._frame[0]) - intersect_max = min(frame[1], self._frame[1]) - if intersect_min > intersect_max: - self._cache = {} - else: - for i in range(self._frame[0], intersect_min): - if i in self._cache: - del self._cache[i] - for i in range(intersect_max+1, self._frame[1]+1): - if i in self._cache: - del self._cache[i] - self._frame = frame - - if self._in_process: - self._postponed.append((offset, False)) - return None - - return fetch() - - def _update_columns(self): - order = self.get_order() - if order is None or not hasattr(self._view, 'get_columns'): - return - - for column in self._view.get_columns(): - if column.get_sort_column_id() == order[0]: - column.props.sort_indicator = True - column.props.sort_order = order[1] - else: - column.props.sort_indicator = False - - def in_frame(self, offset): - return offset >= self._frame[0] and offset <= self._frame[1] - - def on_get_n_columns(self): - return self._n_columns - - def on_get_column_type(self, index): - return self.columns_types.get(index, bool) - - def on_iter_n_children(self, iterator): - if iterator is None and not self._closing: - return self._source.get_count() - else: - return 0 - - def on_get_value(self, offset, column): - if self._view is None or offset >= self._source.get_count(): - return None - - # return value only if iterator came from visible range - # (on setting model, gtk.TreeView scans all items) - vrange = self._view.get_visible_range() - if vrange and offset >= vrange[0][0] and offset <= vrange[1][0]: - row = self._get_row(offset, (vrange[0][0], vrange[1][0])) - return row is not None and row != False and row[column] - - return None - - def on_iter_nth_child(self, iterator, n): - return n - - def on_get_path(self, iterator): - return iterator - - def on_get_iter(self, path): - if self._source.get_count() and not self._closing: - return path[0] - else: - return False - - def on_iter_next(self, iterator): - if iterator is not None: - if iterator >= self._source.get_count() - 1 or self._closing: - return None - return iterator + 1 - return None - - def on_get_flags(self): - return gtk.TREE_MODEL_ITERS_PERSIST | gtk.TREE_MODEL_LIST_ONLY - - def on_iter_children(self, iterator): - return None - - def on_iter_has_child(self, iterator): - return False - - def on_iter_parent(self, iterator): - return None - - -class Row: - - def __init__(self, model, path, iterator, metadata): - self.model = model - self.iterator = iterator - self.path = path - self.metadata = metadata - self.row = [None] * len(model.columns_by_name) - self._calced_row = {} - - for name, value in metadata.items(): - column = model.columns_by_name.get(str(name), -1) - if column != -1: - self.row[column] = value - - def __getitem__(self, key): - if isinstance(key, int): - if key < len(self.row): - return self.row[key] - else: - if key in self._calced_row: - return self._calced_row[key] - else: - value = self.model.on_calc_value(self, key) - if value is not None: - self._calced_row[key] = value - return value - else: - return self.metadata[key] - - def __setitem__(self, key, value): - if isinstance(key, int): - if key < len(self.row): - self.row[key] = value - else: - self._calced_row[key] = value - else: - self.metadata[key] = value - - def __delitem__(self, key): - if isinstance(key, int): - if key < len(self.row): - del self.row[key] - else: - del self._calced_row[key] - else: - del self.metadata[key] - - def __contains__(self, key): - if isinstance(key, int): - return key < len(self.row) or key in self._calced_row - else: - return self.metadata.__contains__(key) - - def has_key(self, key): - return self.__contains__(key) - - def get(self, key, default=None): - if key in self: - return self.__getitem__(key) - else: - return default diff --git a/src/jarabe/journal/browse/smoothtable.py b/src/jarabe/journal/browse/smoothtable.py deleted file mode 100644 index 9f6af15..0000000 --- a/src/jarabe/journal/browse/smoothtable.py +++ /dev/null @@ -1,346 +0,0 @@ -# Copyright (C) 2009, Aleksey Lim -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import gtk -import gobject -import math -import bisect -import logging - - -class SmoothTable(gtk.Container): - - __gsignals__ = { - 'set-scroll-adjustments': (gobject.SIGNAL_RUN_FIRST, None, - [gtk.Adjustment, gtk.Adjustment]), - } - - def __init__(self, rows, columns, new_cell, fill_in): - assert(rows and columns) - - self._rows = [] - self._adj = None - self._adj_value_changed_id = None - self._bin_window = None - self._bin_rows = 0 - self._cell_height = 0 - self._reordered = None - self._last_allocation = None - self._fill_in = fill_in - self._visible_rows = {} - - gtk.Container.__init__(self) - - for i in range(rows + 2): - row = [] - for j in range(columns): - cell = new_cell() - cell.show() - cell.set_parent(self) - cell.size_allocate(gtk.gdk.Rectangle(-1, -1)) - row.append(cell) - self._rows.append(row) - - self.connect('key-press-event', self.__key_press_event_cb) - - def get_columns(self): - return len(self._rows[0]) - - columns = property(get_columns) - - def get_rows(self): - return len(self._rows) - 2 - - rows = property(get_rows) - - def get_frame(self): - if self._adj is None or self._cell_height == 0: - return (0, 0) - top = int(self._adj.value / self._cell_height) - bottom = int(math.ceil(self._adj.value + self._adj.page_size) / \ - self._cell_height) - return (top * self.columns, bottom * self.columns + (self.columns - 1)) - - frame = property(get_frame) - - def get_bin_rows(self): - return self._bin_rows - - def set_bin_rows(self, bin_rows): - self._bin_rows = max(self.rows, bin_rows) - - if self._adj is None: - return - - for row in self._rows: - for cell in row: - cell.size_allocate(gtk.gdk.Rectangle(-1, -1, 0, 0)) - - self._setup_adjustment(force=True) - - bin_rows = property(get_bin_rows, set_bin_rows) - - def get_visible_cell(self, y, x): - if x >= self.columns: - return None - row = self._visible_rows.get(y) - if row is None: - return None - return row[x] - - def goto(self, row): - if self._adj is None: - return - self._adj.props.value = row * self._cell_height - self._adj.value_changed() - - def do_realize(self): - self.set_flags(gtk.REALIZED) - - self.window = gtk.gdk.Window( - self.get_parent_window(), - window_type=gtk.gdk.WINDOW_CHILD, - x=self.allocation.x, - y=self.allocation.y, - width=self.allocation.width, - height=self.allocation.height, - wclass=gtk.gdk.INPUT_OUTPUT, - colormap=self.get_colormap(), - event_mask=gtk.gdk.VISIBILITY_NOTIFY_MASK) - self.window.set_user_data(self) - - self._bin_window = gtk.gdk.Window( - self.window, - window_type=gtk.gdk.WINDOW_CHILD, - x=0, - y=int(-self._adj.value), - width=self.allocation.width, - height=int(self._adj.upper), - colormap=self.get_colormap(), - wclass=gtk.gdk.INPUT_OUTPUT, - event_mask=(self.get_events() | gtk.gdk.EXPOSURE_MASK | - gtk.gdk.SCROLL_MASK)) - self._bin_window.set_user_data(self) - - self.set_style(self.style.attach(self.window)) - self.style.set_background(self.window, gtk.STATE_NORMAL) - self.style.set_background(self._bin_window, gtk.STATE_NORMAL) - - for row in self._rows: - for cell in row: - cell.set_parent_window(self._bin_window) - - self.queue_resize() - - def do_size_allocate(self, allocation): - if self._reordered is not None: - if allocation == self._reordered: - self._reordered = None - return - self._reordered = None - - self.allocation = allocation - self._cell_height = allocation.height / self.rows - - self._setup_adjustment(force=True) - - if self.flags() & gtk.REALIZED: - self.window.move_resize(*allocation) - self._bin_window.resize(allocation.width, int(self._adj.upper)) - - def do_unrealize(self): - self._bin_window.set_user_data(None) - self._bin_window.destroy() - self._bin_window = None - gtk.Container.do_unrealize(self) - - def do_style_set(self, style): - gtk.Widget.do_style_set(self, style) - if self.flags() & gtk.REALIZED: - self.style.set_background(self._bin_window, gtk.STATE_NORMAL) - - def do_expose_event(self, event): - if event.window != self._bin_window: - return False - gtk.Container.do_expose_event(self, event) - return False - - def do_map(self): - self.set_flags(gtk.MAPPED) - - for row in self._rows: - for cell in row: - cell.map() - - self._bin_window.show() - self.window.show() - - def do_size_request(self, req): - req.width = 0 - req.height = 0 - - for row in self._rows: - for cell in row: - cell.size_request() - - def do_forall(self, include_internals, callback, data): - for row in self._rows: - for cell in row: - callback(cell, data) - - def do_add(self, widget): - pass - - def do_remove(self, widget): - pass - - def do_set_scroll_adjustments(self, hadjustment, vadjustment): - if vadjustment is None or vadjustment == self._adj: - return - - if self._adj is not None: - self._adj.disconnect(self._adj_value_changed_id) - - self._adj = vadjustment - self._setup_adjustment() - - self._adj_value_changed_id = vadjustment.connect('value-changed', - self.__adjustment_value_changed_cb) - - def _setup_adjustment(self, force=False): - self._adj.lower = 0 - self._adj.upper = self._bin_rows * self._cell_height - self._adj.page_size = self.allocation.height - self._adj.changed() - - max_value = max(0, self._adj.upper - self._adj.page_size) - if self._adj.value > max_value: - self._adj.value = max_value - self._adj.value_changed() - elif force: - self._adj.value_changed() - - def _allocate_row(self, row, cell_y): - cell_x = 0 - cell_no = cell_y / self._cell_height * self.columns - cell_row = cell_y / self._cell_height - - for cell_column, cell in enumerate(row): - self._fill_in(cell, cell_row, cell_column) - - callocation = gtk.gdk.Rectangle(cell_x, cell_y) - callocation.width = self.allocation.width / self.columns - callocation.height = self._cell_height - cell.size_allocate(callocation) - - cell_x += callocation.width - cell_no += 1 - - def _get_head(self): - if self._adj is None: - return 0 - return int(self._adj.value) - int(self._adj.value) % self._cell_height - - def __adjustment_value_changed_cb(self, sender=None): - if not self.flags() & gtk.REALIZED or self._cell_height == 0 or \ - self._adj.value < 0 or self._adj.value > self._adj.upper - \ - (self.rows * self._cell_height): - return - - spare_rows = [] - visible_rows = [] - page_end = int(self._adj.value + self._adj.page_size) - - if self._last_allocation != self.allocation: - self._last_allocation = self.allocation - spare_rows = [] + self._rows - else: - - class IndexedRow: - - def __init__(self, row): - self.row = row - - def __lt__(self, other): - return self.row[0].allocation.y < other.row[0].allocation.y - - for row in self._rows: - if row[0].allocation.y < 0 or \ - row[0].allocation.y > page_end or \ - (row[0].allocation.y + self._cell_height) < \ - self._adj.value: - spare_rows.append(row) - else: - bisect.insort_right(visible_rows, IndexedRow(row)) - - if not visible_rows or len(visible_rows) < self.rows + \ - (self._get_head() != visible_rows[0]): - self._reordered = self.allocation - self._visible_rows = {} - - def insert_spare_row(cell_y, end_y): - while cell_y < end_y: - if not spare_rows: - logging.error('spare_rows should not be empty') - return - row = spare_rows.pop() - self._allocate_row(row, cell_y) - self._visible_rows[cell_y / self._cell_height] = row - cell_y = cell_y + self._cell_height - - cell_y = self._get_head() - for i in visible_rows: - cell = i.row[0].allocation - insert_spare_row(cell_y, cell.y) - self._visible_rows[cell.y / self._cell_height] = i.row - cell_y = cell.y + cell.height - insert_spare_row(cell_y, page_end) - - self._bin_window.move(0, int(-self._adj.value)) - self.window.process_updates(True) - - def __key_press_event_cb(self, widget, event): - if self._adj is None or self._cell_height == 0: - return - - page = self.rows * self._cell_height - uplimit = self._adj.upper - page - - if event.keyval == gtk.keysyms.Up: - self._adj.value -= self._cell_height - - elif event.keyval == gtk.keysyms.Down: - self._adj.value += min(uplimit - self._adj.value, - self._cell_height) - - elif event.keyval in (gtk.keysyms.Page_Up, gtk.keysyms.KP_Page_Up): - self._adj.value -= min(self._adj.value, page) - - elif event.keyval in (gtk.keysyms.Page_Down, gtk.keysyms.KP_Page_Down): - self._adj.value += min(uplimit - self._adj.value, page) - - elif event.keyval in (gtk.keysyms.Home, gtk.keysyms.KP_Home): - self._adj.value = 0 - - elif event.keyval in (gtk.keysyms.End, gtk.keysyms.KP_End): - self._adj.value = uplimit - - else: - return False - - return True - -SmoothTable.set_set_scroll_adjustments_signal('set-scroll-adjustments') diff --git a/src/jarabe/journal/browse/tableview.py b/src/jarabe/journal/browse/tableview.py deleted file mode 100644 index 024d212..0000000 --- a/src/jarabe/journal/browse/tableview.py +++ /dev/null @@ -1,175 +0,0 @@ -# Copyright (C) 2009, Aleksey Lim -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import gtk -import math -import hippo -import gobject - -from sugar.graphics import style -from sugar.graphics.roundbox import CanvasRoundBox -from jarabe.journal.browse.smoothtable import SmoothTable - -COLOR_BACKGROUND = style.COLOR_WHITE -COLOR_SELECTED = style.COLOR_TEXT_FIELD_GREY - - -class TableCell: - - def __init__(self): - self.row = None - self.tree = None - - def do_fill_in(self): - pass - - -class TableView(SmoothTable): - - def __init__(self, cell_class, rows, columns): - SmoothTable.__init__(self, rows, columns, - lambda: self._create_cell(cell_class), self._do_fill_in) - - self._model = None - self._hover_selection = False - self._selected_cell = None - - def get_cursor(self): - return (self.frame[0], ) - - def set_cursor(self, cursor): - self.goto(cursor) - - def get_model(self): - return self._model - - def set_model(self, model): - if self._model == model: - return - - if self._model is not None: - self._model.disconnect_by_func(self.__row_changed_cb) - self._model.disconnect_by_func(self.__table_resized_cb) - - self._model = model - - if model is not None: - self._model.connect('row-changed', self.__row_changed_cb) - self._model.connect('rows-reordered', self.__table_resized_cb) - - self._resize() - - model = gobject.property(type=object, - getter=get_model, setter=set_model) - - def get_hover_selection(self): - return self._hover_selection - - def set_hover_selection(self, value): - self._hover_selection = value - - hover_selection = gobject.property(type=object, - getter=get_hover_selection, setter=set_hover_selection) - - def get_visible_range(self): - return ((self.frame[0], ), (self.frame[1], )) - - def _create_cell(self, cell_class): - canvas = hippo.Canvas() - canvas.show() - canvas.modify_bg(gtk.STATE_NORMAL, COLOR_BACKGROUND.get_gdk_color()) - - sel_box = CanvasRoundBox() - sel_box.props.border_color = COLOR_BACKGROUND.get_int() - canvas.set_root(sel_box) - - cell = cell_class() - cell.tree = self - sel_box.append(cell, hippo.PACK_EXPAND) - - canvas.connect('enter-notify-event', - self.__enter_notify_event_cb, cell) - canvas.connect('leave-notify-event', self.__leave_notify_event_cb) - - canvas.table_view_cell_sel_box = sel_box - canvas.table_view_cell = cell - - return canvas - - def _resize(self): - rows = int(math.ceil(float(self._model.iter_n_children(None)) / \ - self.columns)) - self.bin_rows = rows - - def _do_fill_in(self, canvas, y, x, prepared_row=None): - - cell = canvas.table_view_cell - sel_box = canvas.table_view_cell_sel_box - - if self._selected_cell == cell and cell.get_visible(): - bg_color = COLOR_SELECTED - else: - bg_color = COLOR_BACKGROUND - sel_box.props.background_color = bg_color.get_int() - - cell.row = prepared_row - - if cell.row is None: - cell_num = y * self.columns + x - - if cell_num < self._model.iter_n_children(None): - row = self._model.get_row((cell_num, ), self.frame) - if row is not None and row != False: - cell.row = row - - if cell.row is None: - cell.set_visible(False) - else: - cell.do_fill_in() - cell.set_visible(True) - - def __enter_notify_event_cb(self, canvas, event, cell): - if not self.hover_selection: - return - - if cell.get_visible(): - sel_box = canvas.table_view_cell_sel_box - sel_box.props.background_color = COLOR_SELECTED.get_int() - - self._selected_cell = cell - - def __leave_notify_event_cb(self, canvas, event): - if not self.hover_selection: - return - - sel_box = canvas.table_view_cell_sel_box - sel_box.props.background_color = COLOR_BACKGROUND.get_int() - - self._selected_cell = None - - def __row_changed_cb(self, model, path, iterator): - y = path[0] / self.columns - x = path[0] % self.columns - - canvas = self.get_visible_cell(y, x) - if canvas is None: - return - - row = self._model.get_row(path) - self._do_fill_in(canvas, y, x, row) - - def __table_resized_cb(self, model=None, path=None, iterator=None, a=None): - self._resize() diff --git a/src/jarabe/journal/browse/treeview.py b/src/jarabe/journal/browse/treeview.py deleted file mode 100644 index b103e9a..0000000 --- a/src/jarabe/journal/browse/treeview.py +++ /dev/null @@ -1,182 +0,0 @@ -# Copyright (C) 2009, Aleksey Lim -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import gtk -import gobject -import logging - -from sugar.graphics.palette import Invoker - -_SHOW_PALETTE_TIMEOUT = 200 - - -class TreeView(gtk.TreeView): - - def __init__(self): - gtk.TreeView.__init__(self) - self._invoker = _TreeInvoker(self) - - def set_cursor(self, path, column, edit=False): - if path is not None: - gtk.TreeView.set_cursor(self, path, column, edit) - - def append_column(self, column): - if isinstance(column, TreeViewColumn): - column.view = self - return gtk.TreeView.append_column(self, column) - - def create_palette(self): - return self._invoker.cell_palette - - -class TreeViewColumn(gtk.TreeViewColumn): - - def __init__(self, title=None, cell=None, **kwargs): - gtk.TreeViewColumn.__init__(self, title, cell, **kwargs) - self.view = None - self._order_by = None - self.palette_cb = None - self.connect('clicked', self._clicked_cb) - - def set_sort_column_id(self, field): - self.props.clickable = True - self._order_by = field - - def get_sort_column_id(self): - return self._order_by - - def _clicked_cb(self, column): - if self.view is None: - return - - if self.props.sort_indicator: - if self.props.sort_order == gtk.SORT_DESCENDING: - new_order = gtk.SORT_ASCENDING - else: - new_order = gtk.SORT_DESCENDING - else: - new_order = gtk.SORT_ASCENDING - - self.view.get_model().set_order(self._order_by, new_order) - - -class _TreeInvoker(Invoker): - - def __init__(self, tree=None): - Invoker.__init__(self) - self._position_hint = self.AT_CURSOR - - self._tree = None - self.cell_palette = None - self._palette_pos = None - self._enter_timeout = None - - self._enter_hid = None - self._motion_hid = None - self._leave_hid = None - self._button_hid = None - - if tree is not None: - self.attach(tree) - - def get_toplevel(self): - return self._tree.get_toplevel() - - def attach(self, tree): - self._tree = tree - self._enter_hid = tree.connect('enter-notify-event', self._enter_cb) - self._motion_hid = tree.connect('motion-notify-event', self._enter_cb) - self._leave_hid = tree.connect('leave-notify-event', self._leave_cb) - self._button_hid = tree.connect('button-release-event', - self._button_cb) - Invoker.attach(self, tree) - - def detach(self): - Invoker.detach(self) - self._tree.disconnect(self._enter_hid) - self._tree.disconnect(self._motion_hid) - self._tree.disconnect(self._leave_hid) - self._tree.disconnect(self._button_cb) - - def _close_palette(self): - if self._enter_timeout: - gobject.source_remove(self._enter_timeout) - self._enter_timeout = None - self.cell_palette = None - self._palette_pos = None - - def _open_palette(self, notify, force): - if self._enter_timeout: - gobject.source_remove(self._enter_timeout) - self._enter_timeout = None - - coords = self._tree.convert_widget_to_bin_window_coords( - *self._tree.get_pointer()) - - pos = self._tree.get_path_at_pos(*coords) - if not pos: - self._close_palette() - return False - - path, column, x, y = pos - if not hasattr(column, 'palette_cb') or not column.palette_cb: - self._close_palette() - return False - - row = self._tree.props.model.get_row(path) - if row is None: - logging.debug('_open_palette: wait for row %s' % path) - self._enter_timeout = gobject.timeout_add(500, self._open_palette, - self.notify_mouse_enter, False) - return False - - palette = column.palette_cb(self._tree.props.model, row, x, y) - if palette is None: - self._close_palette() - return False - - if self._palette_pos != (path, column) or self.cell_palette != palette: - if self.palette is not None: - self.palette.popdown(True) - self.palette = None - - self._palette_pos = (path, column) - self.cell_palette = palette - notify() - - return False - - def notify_popup(self): - Invoker.notify_popup(self) - - def notify_popdown(self): - Invoker.notify_popdown(self) - - def _enter_cb(self, widget, event): - if self._enter_timeout: - gobject.source_remove(self._enter_timeout) - self._enter_timeout = gobject.timeout_add(_SHOW_PALETTE_TIMEOUT, - self._open_palette, self.notify_mouse_enter, False) - - def _leave_cb(self, widget, event): - self.notify_mouse_leave() - self._close_palette() - - def _button_cb(self, widget, event): - if event.button == 3: - return self._open_palette(self.notify_right_click, True) - else: - return False |