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 #print len(self.children)
150 #print self.children[path[0]].id
151 return self
.children
[path
[0]].get_by_path(path
[:-1])
155 def on_unread_count_changed(self
, obj
, old_value
, delta
):
158 class Category(Node
):
160 Represents a category - a node that can have child nodes.
163 persistent_properties
= [ "id", "name" ]
164 persistent_table
= "categories"
169 GObject
.__init
__(self
)
170 Node
.__gobject
_init
__(self
)
177 def do_get_property(self
, property):
178 if property.name
== "title":
181 return Node
.do_get_property(self
, property)
183 def do_set_property(self
, property, value
):
184 if property.name
== "title":
187 Node
.do_set_property(self
, property, value
)
189 def on_unread_count_changed(self
, obj
, old_value
, delta
):
190 self
.props
.unread_count
+= delta
194 Represents a feed - a node that can contain items. Feeds cannot have
198 persistent_properties
= [ "id", "title", "location", "link" ]
199 persistent_table
= "feeds"
204 "title": (str, "title", "title", "", gobject
.PARAM_READWRITE
),
205 "location": (str, "location", "location", "", gobject
.PARAM_READWRITE
),
206 "status": (int, "status", "status", 0, 9999, 0, gobject
.PARAM_READWRITE
),
210 GObject
.__init
__(self
)
211 Node
.__gobject
_init
__(self
)
218 def add_child(self
, node
, norder
= None, allow_append
= True):
219 debug("tried to add child to a feed %d!" % self
.id)
221 def do_get_property(self
, property):
222 if property.name
== "title":
224 elif property.name
== "location":
226 elif property.name
== "status":
229 return Node
.do_get_property(self
, property)
231 def do_set_property(self
, property, value
):
232 if property.name
== "title":
234 elif property.name
== "location":
235 self
.location
= value
236 elif property.name
== "status":
239 Node
.do_set_property(self
, property, value
)
241 def on_unread_count_changed(self
, obj
, old_value
, delta
):
244 def add_item(self
, item
):
245 self
.items
.append(item
)
247 def on_is_read_changed(self
, obj
, is_read
):
249 self
.props
.unread_count
-= 1
251 self
.props
.unread_count
+= 1
254 persistent_properties
= [ "id", "title", "feed_id", "is_read", "link", "pub_date", "description" ]
255 persistent_table
= "items"
259 "title": (str, "title", "title", "", gobject
.PARAM_READWRITE
),
260 "location": (str, "location", "location", "", gobject
.PARAM_READWRITE
),
261 "is-read": (gobject
.TYPE_BOOLEAN
, "is-read", "is-read", False, gobject
.PARAM_READWRITE
)
265 "is-read-changed": (gobject
.SIGNAL_RUN_LAST
, gobject
.TYPE_NONE
, (gobject
.TYPE_PYOBJECT
,))
269 GObject
.__init
__(self
)
277 self
.description
= "description"
280 self
.guidislink
= False
282 self
.publication_name
= "publication_name"
283 self
.publication_volume
= "publication_volume"
284 self
.publication_number
= "publication_number"
285 self
.publication_section
= "publication_section"
286 self
.publication_starting_page
= "publication_starting_page"
288 self
.fm_license
= "fm_license"
289 self
.fm_changes
= "fm_changes"
291 self
.creator
= "creator"
293 self
.contributors
= []
295 self
.license_urls
= []
297 def do_get_property(self
, property):
298 if property.name
== "title":
300 elif property.name
== "is-read":
303 raise AttributeError, "unknown property %s" % property.name
305 def do_set_property(self
, property, value
):
306 if property.name
== "title":
308 elif property.name
== "is-read":
309 old_value
= bool(self
.is_read
)
311 if old_value
!= value
:
312 self
.emit("is-read-changed", int(value
))
314 raise AttributeError, "unknown property %s" % property.name