# Copyright (C) 2009, Tomeu Vizoso # # 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 logging from gettext import gettext as _ import gobject import gtk from gaphas import GtkView, Canvas, state # We'd rather not depend on sugar in this class from sugar.graphics import style from thoughtview import ThoughtView class MindMapView(GtkView): __gtype_name__ = 'MindMapView' def __init__(self, model=None): self._model = None self._row_changed_sid = None self._row_deleted_sid = None self._selected_thought = None GtkView.__init__(self) self.canvas = Canvas() #self.dragging_started.connect(self.__dragging_started_cb) #self.dragging_finished.connect(self.__dragging_finished_cb) #self.connect('button-release-event', self.__button_release_event_cb) if model is not None: self.model = model state.observers.add(self.__state_changed_cb) def __state_changed_cb(self, event): func, args, dict_ = event if len(args) > 1 and isinstance(args[1], ThoughtView): thought_view = args[1] x, y = thought_view.get_position() row = self.model.find_by_id(thought_view.id) if row[2] != x or row[3] != y: self.model.set(row.iter, 2, x, 3, y) def __dragging_started_cb(self, **kwargs): x, y = kwargs['position'] logging.debug('__dragging_started_cb %r %r' % (x, y)) thought = kwargs['element'] thought.dragging = True self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND1)) def __dragging_finished_cb(self, **kwargs): self.window.set_cursor(None) x, y = kwargs['position'] thought = kwargs['element'] logging.debug('__dragging_finished_cb %r %r' % (x, y)) thought.dragging = False rect = self.get_allocation() thought_rect = thought.get_rect() if (x >= 0 and x + thought_rect.width <= rect.width) and \ (y >= 0 and y + thought_rect.height <= rect.height): row = self.model.find_by_id(thought.id) self.model.set(row.iter, 2, x, 3, y) def __button_release_event_cb(self, widget, event): logging.debug('button_release_event_cb') if self._selected_thought is not None: self._selected_thought.selected = False self._selected_thought = None thought = self.get_element_at(event.x, event.y) if thought is not None: thought.selected = True self._selected_thought = thought return True def set_model(self, new_model): logging.debug('set_model %r' % new_model) if self._model == new_model: return if self._model is not None: self._model.disconnect(self._row_changed_sid) self._model.disconnect(self._row_deleted_sid) self._model = new_model if self._model is not None: self._row_changed_sid = \ self._model.connect('row-changed', self.__row_changed_cb) self._row_deleted_sid = \ self._model.connect('row-deleted', self.__row_deleted_cb) for item in self.canvas.get_all_items(): self.canvas.remove(item) self._populate_from_model(self._model) def _populate_from_model(self, rows): for row in rows: thought_view = ThoughtView(row[0], row[1], row[2], row[3], row[4]) self._populate_from_model(row.iterchildren()) self.add_element(thought_view) def get_model(self): return self._model model = property(get_model, set_model) def __row_changed_cb(self, model, path, iter): #logging.debug('__row_changed_cb %r' % path) row = model[iter] thought_view = self._get_thought_by_id(row[0]) if thought_view is None: thought_view = ThoughtView(row[0], row[1], row[2], row[3], row[4]) self.canvas.add(thought_view) else: thought_view.name = row[1] thought_view.set_position(row[2], row[3]) thought_view.x = row[2] thought_view.y = row[3] thought_view.color = row[4] self.canvas.request_update(thought_view) def __row_deleted_cb(self, model, path): logging.debug('__row_deleted_cb %r' % path) raise NotImplementedError() thought_view = self._get_thought_by_id(path[0]) self.remove_element(thought_view) def _get_thought_by_id(self, thought_id): for item in self.canvas.get_all_items(): if isinstance(item, ThoughtView) and item.id == thought_id: return item return None