diff options
Diffstat (limited to 'model.py')
-rw-r--r-- | model.py | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/model.py b/model.py new file mode 100644 index 0000000..75ad6a8 --- /dev/null +++ b/model.py @@ -0,0 +1,210 @@ +# 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 + +import gobject +import gtk +import cjson + +from sugar import dispatch + +class MindMapModel(gtk.GenericTreeModel): + + _COLUMN_TYPES = (str, str, long, long) + + def __init__(self): + gobject.GObject.__init__(self) + + self._next_thought_id = 0 + self._thoughts_by_id = {} + self._thoughts = [] + + def create_new_thought(self): + thought = Thought(self._next_thought_id) + self._add_thought(thought) + + def _add_thought(self, thought): + thought.changed.connect(self.__thought_changed_cb) + self._thoughts.append(thought) + self._thoughts_by_id[thought.id] = thought + self._next_thought_id += 1 + + path = (thought.id,) + self.row_inserted(path, self.get_iter(path)) + + def get_thought(self, thought_id): + return self._thoughts_by_id[int(thought_id)] + + def __thought_changed_cb(self, **kwargs): + thought = kwargs['sender'] + path = (thought.id,) + self.row_changed(path, self.get_iter(path)) + + def get_thoughts(self): + return self._thoughts + + def serialize(self): + thoughts = [] + for thought in self._thoughts: + thought_dict = {} + thought_dict['id'] = thought.id + thought_dict['name'] = thought.name + thought_dict['x'] = thought.x + thought_dict['y'] = thought.y + thoughts.append(thought_dict) + + return cjson.encode({'thoughts': thoughts}) + + def unserialize(self, data): + thoughts = cjson.decode(data)['thoughts'] + for thought_dict in thoughts: + thought = Thought(thought_dict['id']) + thought.name = thought_dict['name'] + thought.x = thought_dict['x'] + thought.y = thought_dict['y'] + self._add_thought(thought) + + # gtk.GenericTreeModel methods + # paths and rowrefs are the thought ids + def on_get_flags(self): + return gtk.TREE_MODEL_ITERS_PERSIST + + def on_get_n_columns(self): + return len(self._COLUMN_TYPES) + + def on_get_column_type(self, n): + return self._COLUMN_TYPES[n] + + def on_get_iter(self, path): + logging.debug('on_get_iter %r %r' % (type(path), path)) + if path[0] in self._thoughts_by_id: + return path[0] + else: + return None + + def on_get_path(self, rowref): + logging.debug('on_get_path %r' % rowref) + return (rowref,) + + def on_get_value(self, rowref, column): + #logging.debug('on_get_value %r %r' % (rowref, column)) + if rowref >= len(self._thoughts): + return None + thought = self._thoughts[rowref] + value_tuple = thought.get_tuple() + return value_tuple[column] + + def on_iter_next(self, rowref): + #logging.debug('on_iter_next %r' % rowref) + if rowref not in self._thoughts_by_id: + return None + thought = self._thoughts_by_id[rowref] + + index = self._thoughts.index(thought) + if index + 1 >= len(self._thoughts): + return None + next_thought = self._thoughts[index + 1] + #logging.debug('on_iter_next returning %r' % next_thought.id) + return next_thought.id + + def on_iter_children(self, rowref): + logging.debug('on_iter_children %r' % rowref) + if rowref: + return None + if self._thoughts: + return self._thoughts[0].id + else: + return None + + def on_iter_has_child(self, rowref): + return False + + def on_iter_n_children(self, rowref): + logging.debug('on_iter_n_children %r' % rowref) + if rowref: + return 0 + return len(self._thoughts) + + def on_iter_nth_child(self, rowref, n): + logging.debug('on_iter_nth_child %r %r' % (rowref, n)) + if rowref is not None: + return None + if n < len(self._thoughts): + return self._thoughts[n].id + + def on_iter_parent(child): + return None + +class Thought(object): + + def __init__(self, thought_id, name=None, x=0, y=0): + if thought_id is None: + raise ValueError('thought_id cannot be None') + self._id = thought_id + self._name = name + self._x = x + self._y = y + + self.changed = dispatch.Signal() + + def get_tuple(self): + return (self.id, self.name, self.x, self.y) + + def set_id(self, new_id): + if self._id == new_id: + return + self._id = new_id + self.changed.send(self) + + def get_id(self): + return self._id + + id = property(get_id, set_id) + + def set_name(self, new_name): + if self._name == new_name: + return + self._name = new_name + self.changed.send(self) + + def get_name(self): + return self._name + + name = property(get_name, set_name) + + def set_x(self, new_x): + if self._x == new_x: + return + self._x = new_x + self.changed.send(self) + + def get_x(self): + return self._x + + x = property(get_x, set_x) + + def set_y(self, new_y): + if self._y == new_y: + return + self._y = new_y + self.changed.send(self) + + def get_y(self): + return self._y + + y = property(get_y, set_y) + |