Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/model.py
diff options
context:
space:
mode:
Diffstat (limited to 'model.py')
-rw-r--r--model.py210
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)
+