1 from bisect
import insort
2 from gobject
import GObject
3 from straw
.error
import debug
7 class AsyncGObject(gobject
.GObject
):
9 gobject
.GObject
.__init
__(self
)
11 def emit(self
, *args
):
12 gobject
.idle_add(gobject
.GObject
.emit
, self
, *args
)
14 class Node(gobject
.GObject
):
16 Represents a base of single node in the model tree. This class is meant
17 for subclassing only, Node instances should not be used.
20 persistent_properties
= [ "id", "parent_id", "type", "norder" ]
21 persistent_table
= "nodes"
25 "norder": (int, "parent_id", "norder", 0, 999999, 0, gobject
.PARAM_READWRITE
),
26 "parent": (gobject
.TYPE_PYOBJECT
, "parent", "parent", gobject
.PARAM_READWRITE
),
27 "unread-count": (int, "unread-count", "unread-count", 0, 999999, 0, gobject
.PARAM_READWRITE
)
31 "parent-changed": (gobject
.SIGNAL_RUN_LAST
, gobject
.TYPE_NONE
, (gobject
.TYPE_PYOBJECT
,)),
32 "norder-changed": (gobject
.SIGNAL_RUN_LAST
, gobject
.TYPE_NONE
, (gobject
.TYPE_PYOBJECT
,)),
33 "unread-count-changed": (gobject
.SIGNAL_RUN_LAST
, gobject
.TYPE_NONE
, (gobject
.TYPE_PYOBJECT
, gobject
.TYPE_PYOBJECT
))
37 GObject
.__init
__(self
)
43 self
.handler_ids_unread_changed
= {}
45 def __cmp__(self
, other
):
48 elif self
.norder
== other
.norder
:
50 elif self
.norder
< other
.norder
:
55 def do_get_property(self
, property):
56 if property.name
== "norder":
58 elif property.name
== "parent_id":
60 elif property.name
== "unread-count":
61 return self
.unread_count
63 def do_set_property(self
, property, value
):
64 if property.name
== "unread-count":
68 if self
.unread_count
!= value
:
69 delta
= value
- self
.unread_count
70 old_value
= self
.unread_count
71 self
.unread_count
= value
72 self
.emit("unread-count-changed", old_value
, delta
)
73 elif property.name
== "norder":
74 if self
.norder
!= value
:
75 old_value
= self
.norder
77 self
.emit("norder-changed", old_value
)
78 elif property.name
== "parent":
79 if self
.parent
.id != value
.id:
80 old_value
= self
.parent
82 self
.parent_id
= value
.id
83 self
.emit("parent-changed", old_value
)
85 def add_child(self
, node
, norder
= None, allow_append
= True, emit_changes
= True):
86 debug("adding %d to %d with node.norder = %d, norder = %s" % (node
.id, self
.id, node
.norder
, str(norder
)))
88 if norder
== None or norder
>= len(self
.children
):
89 norder
= len(self
.children
)
91 if node
.parent
== self
:
92 if norder
> len(self
.children
):
93 norder
= len(self
.children
)#raise AttributeError
96 norder
= len(self
.children
) - 1
99 norder
= len(self
.children
)
100 elif norder
> len(self
.children
):
101 norder
= len(self
.children
)
103 if norder
< len(self
.children
):
104 for child
in self
.children
[norder
:]:
105 child
.props
.norder
+= 1
107 debug("calculated norder = %d" % (norder
))
109 node
.props
.norder
= norder
111 self
.append_child(node
, emit_changes
= emit_changes
)
113 def append_child(self
, node
, emit_changes
= True):
114 debug("appending %d to %d with norder = %d" % (node
.id, self
.id, node
.norder
))
115 insort(self
.children
, node
)
116 self
.handler_ids_unread_changed
[node
.id] = node
.connect("unread-count-changed", self
.on_unread_count_changed
)
119 self
.props
.unread_count
+= node
.unread_count
121 def remove_child(self
, node
, emit_changes
= True):
122 debug("removing %d from %d with norder = %d" % (node
.id, self
.id, node
.norder
))
123 for child
in self
.children
[(node
.norder
+ 1):]:
124 child
.props
.norder
-= 1
126 self
.children
.remove(node
)
128 node
.disconnect(self
.handler_ids_unread_changed
[node
.id])
131 self
.props
.unread_count
-= node
.unread_count
133 def move(self
, new_parent
, new_norder
= None):
134 debug("moving %d to %d (new_norder = %d)" % (self
.id, new_parent
.id, new_norder
))
135 old_parent
= self
.parent
136 self
.parent
.remove_child(self
, emit_changes
= False)
137 new_parent
.add_child(self
, norder
= new_norder
, allow_append
= False, emit_changes
= False)
138 self
.props
.parent
= new_parent
139 debug("changing unread count (old_parent %d: %d -> %d)" % (old_parent
.id, old_parent
.unread_count
, old_parent
.unread_count
- self
.unread_count
))
140 debug("changing unread count (new_parent %d: %d -> %d)" % (new_parent
.id, new_parent
.unread_count
, new_parent
.unread_count
+ self
.unread_count
))
141 old_parent
.props
.unread_count
-= self
.unread_count
142 self
.parent
.props
.unread_count
+= self
.unread_count
144 def get_by_path(self
, path
):
145 print "sss %d | %s | %s" % (self
.id, str(path
), str(len(self
.children
)))
148 elif path
[0] < len(self
.children
):
149 return self
.children
[path
[0]].get_by_path(path
[1:])
153 def on_unread_count_changed(self
, obj
, old_value
, delta
):
156 class Category(Node
):
158 Represents a category - a node that can have child nodes.
161 persistent_properties
= [ "id", "name" ]
162 persistent_table
= "categories"
167 GObject
.__init
__(self
)
168 Node
.__gobject
_init
__(self
)
175 def do_get_property(self
, property):
176 if property.name
== "title":
179 return Node
.do_get_property(self
, property)
181 def do_set_property(self
, property, value
):
182 if property.name
== "title":
185 Node
.do_set_property(self
, property, value
)
187 def on_unread_count_changed(self
, obj
, old_value
, delta
):
188 self
.props
.unread_count
+= delta
192 Represents a feed - a node that can contain items. Feeds cannot have
196 persistent_properties
= [ "id", "title", "location", "link" ]
197 persistent_table
= "feeds"
202 "title": (str, "title", "title", "", gobject
.PARAM_READWRITE
),
203 "location": (str, "location", "location", "", gobject
.PARAM_READWRITE
),
204 "status": (int, "status", "status", 0, 9999, 0, gobject
.PARAM_READWRITE
),
208 GObject
.__init
__(self
)
209 Node
.__gobject
_init
__(self
)
216 def add_child(self
, node
, norder
= None, allow_append
= True):
217 debug("tried to add child to a feed %d!" % self
.id)
219 def do_get_property(self
, property):
220 if property.name
== "title":
222 elif property.name
== "location":
224 elif property.name
== "status":
227 return Node
.do_get_property(self
, property)
229 def do_set_property(self
, property, value
):
230 if property.name
== "title":
232 elif property.name
== "location":
233 self
.location
= value
234 elif property.name
== "status":
237 Node
.do_set_property(self
, property, value
)
239 def on_unread_count_changed(self
, obj
, old_value
, delta
):
242 def add_item(self
, item
):
243 self
.items
.append(item
)
245 def on_is_read_changed(self
, obj
, is_read
):
247 self
.props
.unread_count
-= 1
249 self
.props
.unread_count
+= 1
252 persistent_properties
= [ "id", "title", "feed_id", "is_read", "link", "pub_date", "description" ]
253 persistent_table
= "items"
257 "title": (str, "title", "title", "", gobject
.PARAM_READWRITE
),
258 "location": (str, "location", "location", "", gobject
.PARAM_READWRITE
),
259 "is-read": (gobject
.TYPE_BOOLEAN
, "is-read", "is-read", False, gobject
.PARAM_READWRITE
)
263 "is-read-changed": (gobject
.SIGNAL_RUN_LAST
, gobject
.TYPE_NONE
, (gobject
.TYPE_PYOBJECT
,))
267 GObject
.__init
__(self
)
275 self
.description
= "description"
278 self
.guidislink
= False
280 self
.publication_name
= "publication_name"
281 self
.publication_volume
= "publication_volume"
282 self
.publication_number
= "publication_number"
283 self
.publication_section
= "publication_section"
284 self
.publication_starting_page
= "publication_starting_page"
286 self
.fm_license
= "fm_license"
287 self
.fm_changes
= "fm_changes"
289 self
.creator
= "creator"
291 self
.contributors
= []
293 self
.license_urls
= []
295 def do_get_property(self
, property):
296 if property.name
== "title":
298 elif property.name
== "is-read":
301 raise AttributeError, "unknown property %s" % property.name
303 def do_set_property(self
, property, value
):
304 if property.name
== "title":
306 elif property.name
== "is-read":
307 old_value
= bool(self
.is_read
)
309 if old_value
!= value
:
310 self
.emit("is-read-changed", int(value
))
312 raise AttributeError, "unknown property %s" % property.name