| 121 |
132 |
| 122 #### |
133 #### |
| 123 # [[[ The list of feeds |
134 # [[[ The list of feeds |
| 124 ### |
135 ### |
| 125 |
136 |
| |
137 # 'Add Feed' dialog |
| |
138 add_feed_win = None |
| |
139 def add_feed_win_closed(win): |
| |
140 global add_feed_win |
| |
141 add_feed_win = None |
| |
142 |
| |
143 def add_new_feed(): |
| |
144 global add_feed_win |
| |
145 |
| |
146 if add_feed_win: |
| |
147 gnt.gnt_window_present(add_feed_win) |
| |
148 return |
| |
149 win = gnt.Window() |
| |
150 win.set_title("New Feed") |
| |
151 |
| |
152 box = gnt.Box(False, False) |
| |
153 label = gnt.Label("Link") |
| |
154 box.add_widget(label) |
| |
155 entry = gnt.Entry("") |
| |
156 entry.set_size(40, 1) |
| |
157 box.add_widget(entry) |
| |
158 |
| |
159 win.add_widget(box) |
| |
160 win.show() |
| |
161 add_feed_win = win |
| |
162 add_feed_win.connect("destroy", add_feed_win_closed) |
| |
163 |
| 126 # |
164 # |
| 127 # The active row in the feed-list has changed. Update the feed-item table. |
165 # The active row in the feed-list has changed. Update the feed-item table. |
| 128 def feed_active_changed(tree, old): |
166 def feed_active_changed(tree, old): |
| 129 items.remove_all() |
167 items.remove_all() |
| 130 if not tree.active: |
168 if not tree.active: |
| 131 return |
169 return |
| |
170 update_items_title() |
| 132 for item in tree.active.items: |
171 for item in tree.active.items: |
| 133 add_feed_item(item) |
172 add_feed_item(item) |
| 134 |
173 |
| 135 # |
174 # |
| 136 # Check for the action keys and decide how to deal with them. |
175 # Check for the action keys and decide how to deal with them. |
| 137 def feed_key_pressed(tree, text): |
176 def feed_key_pressed(tree, text): |
| |
177 if tree.is_searching(): |
| |
178 return |
| 138 if text == 'r': |
179 if text == 'r': |
| 139 feed = tree.get_selection_data() |
180 feed = tree.get_selection_data() |
| 140 tree.perform_action_key('j') |
181 tree.perform_action_key('j') |
| 141 #tree.perform_action('move-down') |
182 #tree.perform_action('move-down') |
| 142 feed.refresh() |
183 feed.refresh() |
| 143 elif text == 'R': |
184 elif text == 'R': |
| 144 feeds = tree.get_rows() |
185 feeds = tree.get_rows() |
| 145 for feed in feeds: |
186 for feed in feeds: |
| 146 feed.refresh() |
187 feed.refresh() |
| |
188 elif text == 'a': |
| |
189 add_new_feed() |
| 147 else: |
190 else: |
| 148 return False |
191 return False |
| 149 return True |
192 return True |
| 150 |
193 |
| 151 feeds = RssTree() |
194 feeds = RssTree() |
| 152 feeds.set_property('columns', 2) |
195 feeds.set_property('columns', 2) |
| 153 feeds.set_col_width(0, 20) |
196 feeds.set_col_width(0, 20) |
| 154 feeds.set_col_width(1, 4) |
197 feeds.set_col_width(1, 8) |
| 155 feeds.set_column_resizable(0, False) |
198 feeds.set_column_resizable(0, False) |
| 156 feeds.set_column_resizable(1, False) |
199 feeds.set_column_resizable(1, False) |
| 157 feeds.set_column_is_right_aligned(1, True) |
200 feeds.set_column_is_right_aligned(1, True) |
| 158 feeds.set_show_separator(False) |
201 feeds.set_show_separator(False) |
| |
202 feeds.set_column_title(0, "Feeds") |
| |
203 feeds.set_show_title(True) |
| 159 |
204 |
| 160 feeds.connect('active_changed', feed_active_changed) |
205 feeds.connect('active_changed', feed_active_changed) |
| 161 feeds.connect('key_pressed', feed_key_pressed) |
206 feeds.connect('key_pressed', feed_key_pressed) |
| |
207 gnt.unset_flag(feeds, 256) # Fix the width |
| 162 |
208 |
| 163 #### |
209 #### |
| 164 # ]]] The list of feeds |
210 # ]]] The list of feeds |
| 165 ### |
211 ### |
| 166 |
212 |
| 175 details.clear() |
221 details.clear() |
| 176 if not tree.active: |
222 if not tree.active: |
| 177 return |
223 return |
| 178 item = tree.active |
224 item = tree.active |
| 179 details.append_text_with_flags(str(item.title) + "\n", gnt.TEXT_FLAG_BOLD) |
225 details.append_text_with_flags(str(item.title) + "\n", gnt.TEXT_FLAG_BOLD) |
| 180 details.append_text_with_flags(str(item.summary), gnt.TEXT_FLAG_NORMAL) |
226 details.append_text_with_flags("Link: ", gnt.TEXT_FLAG_BOLD) |
| 181 details.scroll(0) |
227 details.append_text_with_flags(str(item.link) + "\n", gnt.TEXT_FLAG_UNDERLINE) |
| 182 if item.unread: |
228 details.append_text_with_flags("Date: ", gnt.TEXT_FLAG_BOLD) |
| 183 item.set_property('unread', False) |
229 details.append_text_with_flags(str(item.date) + "\n", gnt.TEXT_FLAG_NORMAL) |
| 184 if old and old.unread: |
230 |
| 185 old.set_property('unread', True) |
231 details.append_text_with_flags("\n" + str(item.summary), gnt.TEXT_FLAG_NORMAL) |
| |
232 item.mark_unread(False) |
| |
233 |
| |
234 if old and old.unread: # If the last selected item is marked 'unread', then make sure it's bold |
| |
235 items.set_row_flags(old, gnt.TEXT_FLAG_BOLD) |
| 186 |
236 |
| 187 # |
237 # |
| 188 # Look for action keys in the feed-item list. |
238 # Look for action keys in the feed-item list. |
| 189 def item_key_pressed(tree, text): |
239 def item_key_pressed(tree, text): |
| |
240 if tree.is_searching(): |
| |
241 return |
| 190 current = tree.get_selection_data() |
242 current = tree.get_selection_data() |
| 191 if text == 'M': # Mark all of the items 'read' |
243 if text == 'M': # Mark all of the items 'read' |
| 192 all = tree.get_rows() |
244 all = tree.get_rows() |
| 193 for item in all: |
245 for item in all: |
| 194 item.unread = False |
246 item.mark_unread(False) |
| 195 elif text == 'm': # Mark the current item 'read' |
247 elif text == 'm': # Mark the current item 'read' |
| 196 if current.unread: |
248 current.mark_unread(False) |
| 197 current.set_property('unread', False) |
|
| 198 tree.perform_action_key('j') |
249 tree.perform_action_key('j') |
| 199 elif text == 'U': # Mark the current item 'unread' |
250 elif text == 'U': # Mark the current item 'unread' |
| 200 if not current.unread: |
251 current.mark_unread(True) |
| 201 current.set_property('unread', True) |
|
| 202 elif text == 'd': |
252 elif text == 'd': |
| 203 current.remove() |
253 current.remove() |
| 204 tree.perform_action_key('j') |
254 tree.perform_action_key('j') |
| 205 else: |
255 else: |
| 206 return False |
256 return False |
| 207 return True |
257 return True |
| 208 |
258 |
| 209 items = RssTree() |
259 items = RssTree() |
| 210 items.set_property('columns', 1) |
260 items.set_property('columns', 1) |
| 211 items.set_col_width(0, 40) |
261 items.set_col_width(0, 40) |
| |
262 items.set_column_title(0, "Items") |
| |
263 items.set_show_title(True) |
| 212 items.connect('key_pressed', item_key_pressed) |
264 items.connect('key_pressed', item_key_pressed) |
| 213 items.connect('active_changed', item_active_changed) |
265 items.connect('active_changed', item_active_changed) |
| 214 |
266 |
| |
267 size = gnt.screen_size() |
| |
268 items.set_size(size[0], size[1]) |
| |
269 |
| 215 #### |
270 #### |
| 216 # ]]] The list of items in the feed |
271 # ]]] The list of items in the feed |
| 217 #### |
272 #### |
| 218 |
273 |
| |
274 # |
| |
275 # Update the title of the items list depending on the selection in the feed list |
| |
276 def update_items_title(): |
| |
277 feed = feeds.active |
| |
278 if feed: |
| |
279 items.set_column_title(0, str(feed.title) + ": " + str(feed.unread) + "(" + str(len(feed.items)) + ")") |
| |
280 else: |
| |
281 items.set_column_title(0, "Items") |
| |
282 items.draw() |
| |
283 |
| 219 # The container on the top |
284 # The container on the top |
| |
285 line = gnt.Line(vertical = False) |
| |
286 |
| |
287 # The textview to show the details of a feed |
| |
288 details = gnt.TextView() |
| |
289 details.set_take_focus(True) |
| |
290 details.set_flag(gnt.TEXT_VIEW_TOP_ALIGN) |
| |
291 details.attach_scroll_widget(details) |
| |
292 |
| |
293 # Category tree |
| |
294 cat = gnt.Tree() |
| |
295 cat.set_property('columns', 1) |
| |
296 cat.set_column_title(0, 'Category') |
| |
297 cat.set_show_title(True) |
| |
298 gnt.set_flag(cat, 8) # remove borders |
| |
299 |
| 220 box = gnt.Box(homo = False, vert = False) |
300 box = gnt.Box(homo = False, vert = False) |
| 221 box.set_pad(0) |
301 box.set_pad(0) |
| 222 box.add_widget(feeds) |
302 |
| 223 box.add_widget(items) |
303 vbox = gnt.Box(homo = False, vert = True) |
| |
304 vbox.set_pad(0) |
| |
305 vbox.add_widget(feeds) |
| |
306 vbox.add_widget(gnt.Line(False)) |
| |
307 vbox.add_widget(cat) |
| |
308 box.add_widget(vbox) |
| |
309 |
| |
310 box.add_widget(gnt.Line(True)) |
| |
311 |
| |
312 vbox = gnt.Box(homo = False, vert = True) |
| |
313 vbox.set_pad(0) |
| |
314 vbox.add_widget(items) |
| |
315 vbox.add_widget(gnt.Line(False)) |
| |
316 vbox.add_widget(details) |
| |
317 box.add_widget(vbox) |
| 224 |
318 |
| 225 win.add_widget(box) |
319 win.add_widget(box) |
| 226 |
|
| 227 line = gnt.Line(vertical = False) |
|
| 228 win.add_widget(line) |
|
| 229 |
|
| 230 # The textview to show the details of a feed |
|
| 231 details = gnt.TextView() |
|
| 232 |
|
| 233 win.add_widget(details) |
|
| 234 |
|
| 235 browser = gnt.Button("Open in Browser") |
|
| 236 win.add_widget(browser) |
|
| 237 details.attach_scroll_widget(browser) |
|
| 238 |
|
| 239 win.show() |
320 win.show() |
| 240 |
321 |
| 241 def update_feed_title(feed, property): |
322 def update_feed_title(feed, property): |
| 242 if property.name == 'title': |
323 if property.name == 'title': |
| 243 feeds.change_text(feed, 0, feed.title) |
324 feeds.change_text(feed, 0, feed.title) |
| 244 elif property.name == 'unread': |
325 elif property.name == 'unread': |
| 245 feeds.change_text(feed, 1, str(feed.unread)) |
326 feeds.change_text(feed, 1, str(feed.unread) + "(" + str(len(feed.items)) + ")") |
| |
327 if feeds.active == feed: |
| |
328 update_items_title() |
| 246 |
329 |
| 247 # populate everything |
330 # populate everything |
| 248 for feed in gntrss.feeds: |
331 for feed in gntrss.feeds: |
| 249 feed.refresh() |
332 feed.refresh() |
| 250 add_feed(feed) |
333 add_feed(feed) |