127
127
self.on_select_tag()
128
128
self.browser_shown = False
130
#Update the title when a task change
130
# Update the title when a task change
131
131
self.activetree.register_cllbck('node-added-inview',
132
self._update_window_title)
132
self._update_window_title)
133
133
self.activetree.register_cllbck('node-deleted-inview',
134
self._update_window_title)
134
self._update_window_title)
135
135
self._update_window_title()
137
137
### INIT HELPER FUNCTIONS #####################################################
197
197
# The tags treeview
198
198
self.tagtree = self.req.get_tag_tree()
199
199
self.tagtreeview = self.tv_factory.tags_treeview(self.tagtree)
201
201
self.tagtreeview.get_selection().connect('changed',
203
203
self.tagtreeview.connect('button-press-event',
204
self.on_tag_treeview_button_press_event)
204
self.on_tag_treeview_button_press_event)
205
205
self.tagtreeview.connect('key-press-event',
206
self.on_tag_treeview_key_press_event)
206
self.on_tag_treeview_key_press_event)
207
207
self.tagtreeview.connect('node-expanded',
208
self.on_tag_expanded)
208
self.on_tag_expanded)
209
209
self.tagtreeview.connect('node-collapsed',
210
self.on_tag_collapsed)
210
self.on_tag_collapsed)
211
211
self.sidebar_container.add(self.tagtreeview)
213
213
for path_t in self.config.get("expanded_tags"):
214
#the tuple was stored as a string. we have to reconstruct it
214
# the tuple was stored as a string. we have to reconstruct it
216
216
for p in path_t[1:-1].split(","):
217
217
p = p.strip(" '")
259
260
SIGNAL_CONNECTIONS_DIC = {
262
263
"on_edit_active_task":
263
self.on_edit_active_task,
264
self.on_edit_active_task,
264
265
"on_edit_done_task":
265
self.on_edit_done_task,
266
self.on_edit_done_task,
266
267
"on_delete_task":
267
self.on_delete_tasks,
268
self.on_delete_tasks,
268
269
"on_modify_tags":
270
271
"on_mark_as_done":
271
self.on_mark_as_done,
272
self.on_mark_as_done,
272
273
"on_mark_as_started":
273
self.on_mark_as_started,
274
self.on_mark_as_started,
274
275
"on_start_for_tomorrow":
275
self.on_start_for_tomorrow,
276
self.on_start_for_tomorrow,
276
277
"on_start_for_next_week":
277
self.on_start_for_next_week,
278
self.on_start_for_next_week,
278
279
"on_start_for_next_month":
279
self.on_start_for_next_month,
280
self.on_start_for_next_month,
280
281
"on_start_for_next_year":
281
self.on_start_for_next_year,
282
self.on_start_for_next_year,
282
283
"on_start_clear":
284
285
"on_set_due_today":
285
self.on_set_due_today,
286
self.on_set_due_today,
286
287
"on_set_due_tomorrow":
287
self.on_set_due_tomorrow,
288
self.on_set_due_tomorrow,
288
289
"on_set_due_next_week":
289
self.on_set_due_next_week,
290
self.on_set_due_next_week,
290
291
"on_set_due_next_month":
291
self.on_set_due_next_month,
292
self.on_set_due_next_month,
292
293
"on_set_due_next_year":
293
self.on_set_due_next_year,
294
self.on_set_due_next_year,
294
295
"on_set_due_now":
296
297
"on_set_due_soon":
297
self.on_set_due_soon,
298
self.on_set_due_soon,
298
299
"on_set_due_someday":
299
self.on_set_due_someday,
300
self.on_set_due_someday,
300
301
"on_set_due_clear":
301
self.on_set_due_clear,
302
self.on_set_due_clear,
302
303
"on_dismiss_task":
303
self.on_dismiss_task,
304
self.on_dismiss_task,
306
307
"on_size_allocate":
307
self.on_size_allocate,
308
self.on_size_allocate,
310
311
"on_add_subtask":
312
313
"on_tagcontext_deactivate":
313
self.on_tagcontext_deactivate,
314
self.on_tagcontext_deactivate,
314
315
"on_workview_toggled":
315
self.on_workview_toggled,
316
self.on_workview_toggled,
316
317
"on_view_workview_toggled":
317
self.on_workview_toggled,
318
self.on_workview_toggled,
318
319
"on_view_closed_toggled":
319
self.on_closed_toggled,
320
self.on_closed_toggled,
320
321
"on_view_sidebar_toggled":
321
self.on_sidebar_toggled,
322
self.on_sidebar_toggled,
322
323
"on_quickadd_field_activate":
323
self.on_quickadd_activate,
324
self.on_quickadd_activate,
324
325
"on_quickadd_field_icon_press":
325
self.on_quickadd_iconpress,
326
self.on_quickadd_iconpress,
326
327
"on_quickadd_field_changed":
327
self.on_quickadd_changed,
328
self.on_quickadd_changed,
328
329
"on_quickadd_entrycompletion_action_activated":
329
self.on_entrycompletion_action_activated,
330
self.on_entrycompletion_action_activated,
330
331
"on_view_quickadd_toggled":
331
self.on_toggle_quickadd,
332
self.on_toggle_quickadd,
332
333
"on_view_toolbar_toggled":
333
self.on_toolbar_toggled,
334
self.on_toolbar_toggled,
334
335
"on_about_clicked":
335
self.on_about_clicked,
336
self.on_about_clicked,
336
337
"on_about_delete":
338
339
"on_about_close":
340
341
"on_documentation_clicked":
341
lambda w: openurl(info.HELP_URI),
342
lambda w: openurl(info.HELP_URI),
342
343
"on_translate_clicked":
343
lambda w: openurl(info.TRANSLATE_URL),
344
lambda w: openurl(info.TRANSLATE_URL),
344
345
"on_report_bug_clicked":
345
lambda w: openurl(info.REPORT_BUG_URL),
346
lambda w: openurl(info.REPORT_BUG_URL),
346
347
"on_preferences_activate":
347
self.open_preferences,
348
self.open_preferences,
348
349
"on_edit_plugins_activate":
350
351
"on_edit_backends_activate":
351
self.open_edit_backends,
352
self.open_edit_backends,
353
354
self.builder.connect_signals(SIGNAL_CONNECTIONS_DIC)
358
359
# Active tasks TreeView
359
360
self.vtree_panes['active'].connect('row-activated',
360
self.on_edit_active_task)
361
self.on_edit_active_task)
362
tsk_treeview_btn_press = self.on_task_treeview_button_press_event
361
363
self.vtree_panes['active'].connect('button-press-event',
362
self.on_task_treeview_button_press_event)
364
tsk_treeview_btn_press)
365
task_treeview_key_press = self.on_task_treeview_key_press_event
363
366
self.vtree_panes['active'].connect('key-press-event',
364
self.on_task_treeview_key_press_event)
367
task_treeview_key_press)
365
368
self.vtree_panes['active'].connect('node-expanded',
366
self.on_task_expanded)
369
self.on_task_expanded)
367
370
self.vtree_panes['active'].connect('node-collapsed',
368
self.on_task_collapsed)
371
self.on_task_collapsed)
370
373
b_signals = BackendSignals()
371
374
b_signals.connect(b_signals.BACKEND_FAILED, self.on_backend_failed)
395
398
self._add_accelerator_for_widget(agr, "edit_redo", "<Control>y")
396
399
self._add_accelerator_for_widget(agr, "new_task_mi", "<Control>n")
397
400
self._add_accelerator_for_widget(agr, "new_subtask_mi",
399
402
self._add_accelerator_for_widget(agr, "edit_mi", "Return")
400
403
self._add_accelerator_for_widget(agr, "done_mi", "<Control>d")
401
404
self._add_accelerator_for_widget(agr, "dismiss_mi", "<Control>i")
464
467
self.builder.get_object("view_sidebar").set_active(True)
465
468
if not self.tagtreeview:
466
469
self.init_tags_sidebar()
468
# for applying the last used tag
469
taglist = self.config.get("last_selected_tag")
470
model = self.tagtreeview.get_model()
471
for tag_name in taglist:
472
path = self.tagtree.get_paths_for_node(tag_name)[0]
473
tag_iter = model.my_get_iter(path)
475
selection = self.tagtreeview.get_selection()
476
selection.select_iter(tag_iter)
478
470
self.sidebar.show()
482
472
sidebar_width = self.config.get("sidebar_width")
483
473
self.builder.get_object("hpaned1").set_position(sidebar_width)
484
474
self.builder.get_object("hpaned1").connect('notify::position',
485
self.on_sidebar_width)
475
self.on_sidebar_width)
487
477
closed_task_pane = self.config.get("closed_task_pane")
488
478
if not closed_task_pane:
580
571
self.req.apply_global_filter(self.activetree, 'workview')
583
raise Exception('Cannot set the view %s' %viewname)
574
raise Exception('Cannot set the view %s' % viewname)
584
575
self.menu_view_workview.set_active(workview)
585
576
self.toggle_workview.set_active(workview)
586
#The config_set has to be after the toggle, else you will have a loop
577
# The config_set has to be after the toggle, else you will have a loop
587
578
self.config.set('view', viewname)
588
579
self.vtree_panes['active'].set_col_visible('startdate', not workview)
590
581
def _update_window_title(self, nid=None, path=None, state_id=None):
591
582
count = self.activetree.get_n_nodes()
592
#Set the title of the window:
583
# Set the title of the window:
595
586
parenthesis = _("no active tasks")
633
624
self.config.set('tasklist_sort_column', sort_column)
634
625
self.config.set('tasklist_sort_order', sort_order)
636
def on_move(self, widget = None, data = None):
627
def on_move(self, widget=None, data=None):
637
628
xpos, ypos = self.window.get_position()
638
629
self.config.set('x_pos', xpos)
639
630
self.config.set('y_pos', ypos)
641
def on_size_allocate(self, widget = None, data = None):
632
def on_size_allocate(self, widget=None, data=None):
642
633
width, height = self.window.get_size()
643
634
self.config.set('width', width)
644
635
self.config.set('height', height)
646
def on_bottom_pane_position(self, widget, data = None):
637
def on_bottom_pane_position(self, widget, data=None):
647
638
self.config.set('bottom_pane_position', widget.get_position())
649
def on_sidebar_width(self, widget, data = None):
640
def on_sidebar_width(self, widget, data=None):
650
641
self.config.set('sidebar_width', widget.get_position())
652
643
def on_about_clicked(self, widget):
697
688
if not 'closed' in self.vtree_panes:
698
689
ctree = self.__create_closed_tree()
699
690
self.vtree_panes['closed'] = \
700
self.tv_factory.closed_tasks_treeview(ctree)
691
self.tv_factory.closed_tasks_treeview(ctree)
701
692
# Closed tasks TreeView
702
693
self.vtree_panes['closed'].connect('row-activated',
703
self.on_edit_done_task)
694
self.on_edit_done_task)
695
# I did not want to break the variable and there was no other
696
# option except this name:(Nimit)
697
clsd_tsk_btn_prs = self.on_closed_task_treeview_button_press_event
704
698
self.vtree_panes['closed'].connect('button-press-event',
705
self.on_closed_task_treeview_button_press_event)
700
clsd_tsk_key_prs = self.on_closed_task_treeview_key_press_event
706
701
self.vtree_panes['closed'].connect('key-press-event',
707
self.on_closed_task_treeview_key_press_event)
709
704
self.closed_selection = self.vtree_panes['closed'].get_selection()
710
705
self.closed_selection.connect("changed",
711
self.on_taskdone_cursor_changed)
706
self.on_taskdone_cursor_changed)
712
707
ctree.apply_filter(self.get_selected_tags()[0], refresh=True)
713
708
if not self.closed_pane:
714
709
self.closed_pane = gtk.ScrolledWindow()
715
710
self.closed_pane.set_size_request(-1, 100)
716
711
self.closed_pane.set_policy(gtk.POLICY_AUTOMATIC,
717
gtk.POLICY_AUTOMATIC)
712
gtk.POLICY_AUTOMATIC)
718
713
self.closed_pane.add(self.vtree_panes['closed'])
720
715
elif self.accessory_notebook.page_num(self.closed_pane) != -1:
726
721
self.config.set('closed_task_pane', True)
728
723
def hide_closed_pane(self):
729
#If we destroy completely the vtree, we cannot display it anymore
730
#Check is to hide/show the closed task pane multiple times.
731
#I let this code commented for now because it might be useful
732
#for performance reason, to really destroy the view when we don't
733
#display it. (Lionel, 17092010)
724
# If we destroy completely the vtree, we cannot display it anymore
725
# Check is to hide/show the closed task pane multiple times.
726
# I let this code commented for now because it might be useful
727
# for performance reason, to really destroy the view when we don't
728
# display it. (Lionel, 17092010)
734
729
# if self.vtree_panes.has_key('closed'):
735
730
# self.vtree_panes['closed'].set_model(None)
736
731
# del self.vtree_panes['closed']
810
805
# select. So, we have to wait for the task to be created, and then
811
806
# wait for its tid to show up (invernizzi)
812
807
def select_next_added_task_in_browser(treemodelsort, path,
815
810
def selecter(treemodelsort, path, iter, self):
816
811
self.__last_quick_added_tid_event.wait()
817
812
treeview = self.vtree_panes['active']
818
813
tid = self.activetree.get_node_for_path(path)
819
814
if self.__last_quick_added_tid == tid:
820
#this is the correct task
815
# this is the correct task
821
816
treemodelsort.disconnect(
822
817
self.__quick_add_select_handle)
823
818
selection = treeview.get_selection()
824
819
selection.unselect_all()
825
820
selection.select_path(path)
827
#It cannot be another thread than the main gtk thread !
822
# It cannot be another thread than the main gtk thread !
828
823
gobject.idle_add(selecter, treemodelsort, path, iter, self)
829
#event that is set when the new task is created
824
# event that is set when the new task is created
830
825
self.__last_quick_added_tid_event = threading.Event()
831
826
self.__quick_add_select_handle = \
832
self.vtree_panes['active'].get_model().connect(
833
"row-inserted", select_next_added_task_in_browser,
827
self.vtree_panes['active'].get_model().connect(
828
"row-inserted", select_next_added_task_in_browser,
835
830
task = self.req.new_task(newtask=True)
836
831
self.__last_quick_added_tid = task.get_id()
837
832
self.__last_quick_added_tid_event.set()
838
833
task.set_complex_title(text, tags=tags)
839
834
self.quickadd_entry.set_text('')
841
#signal the event for the plugins to catch
836
# signal the event for the plugins to catch
842
837
gobject.idle_add(self.emit, "task-added-via-quick-add",
845
#if no text is selected, we open the currently selected task
840
# if no text is selected, we open the currently selected task
846
841
nids = self.vtree_panes['active'].get_selected_nodes()
848
843
self.vmanager.open_task(nid)
879
874
self.target_cursor = path, col
880
875
treeview.set_cursor(path, col, 0)
881
#the nospecial=True disable right clicking for special tags
876
# the nospecial=True disable right clicking for special tags
882
877
selected_tags = self.get_selected_tags(nospecial=True)
883
878
selected_search = self.get_selected_search()
884
#popup menu for searches
879
# popup menu for searches
885
880
if selected_search is not None:
886
881
my_tag = self.req.get_tag(selected_search)
887
882
self.tagpopup.set_tag(my_tag)
900
895
def on_tag_treeview_key_press_event(self, treeview, event):
901
896
keyname = gtk.gdk.keyval_name(event.keyval)
902
897
is_shift_f10 = (keyname == "F10" and
903
event.get_state() & gtk.gdk.SHIFT_MASK)
898
event.get_state() & gtk.gdk.SHIFT_MASK)
904
899
if is_shift_f10 or keyname == "Menu":
905
900
selected_tags = self.get_selected_tags(nospecial=True)
906
901
selected_search = self.get_selected_search()
907
#popup menu for searches
902
# popup menu for searches
908
903
if selected_search is not None:
909
904
self.searchpopup.popup(None, None, None, 0, event.time)
910
905
elif len(selected_tags) > 0:
1188
1182
"tooltip": GnomeConfig.MARK_UNDONE_TOOLTIP,
1189
1183
"icon-name": "gtg-task-undone"}
1190
1184
settings_dismiss = {"label": GnomeConfig.MARK_DISMISS,
1191
"tooltip": GnomeConfig.MARK_DISMISS_TOOLTIP,
1192
"icon-name": "gtg-task-dismiss"}
1185
"tooltip": GnomeConfig.MARK_DISMISS_TOOLTIP,
1186
"icon-name": "gtg-task-dismiss"}
1193
1187
settings_undismiss = {"label": GnomeConfig.MARK_UNDISMISS,
1194
1188
"tooltip": GnomeConfig.MARK_UNDISMISS_TOOLTIP,
1195
1189
"icon-name": "gtg-task-undismiss"}
1205
1199
menu_item.set_image(image)
1206
1200
menu_item.set_label(settings["label"])
1208
#We unselect all in the active task view
1209
#Only if something is selected in the closed task list
1210
#And we change the status of the Done/dismiss button
1202
# We unselect all in the active task view
1203
# Only if something is selected in the closed task list
1204
# And we change the status of the Done/dismiss button
1211
1205
update_button(self.donebutton, settings_done)
1212
1206
update_menu_item(self.done_mi, settings_done)
1213
1207
update_button(self.dismissbutton, settings_dismiss)
1521
1515
@param backend_id: the backend for which we're creating the infobar
1522
1516
@returns gtk.Infobar: the created infobar
1524
#remove old infobar related to backend_id, if any
1518
# remove old infobar related to backend_id, if any
1525
1519
if not self.vbox_toolbars:
1527
1521
self.vbox_toolbars.foreach(self.__remove_backend_infobar, backend_id)
1529
1523
infobar = CustomInfoBar(self.req, self, self.vmanager, backend_id)
1530
1524
self.vbox_toolbars.pack_start(infobar, True)