def open_parent(self): """ Open (or create) the parent task, then close the child to avoid various window management issues and to prevent visible content divergence when the child title changes. """ parents = self.task.get_parents() self.save() if not parents: tags = [t.get_name() for t in self.task.get_tags()] parent = self.req.new_task(tags=tags, newtask=True) parent_id = parent.get_id() self.task.set_parent(parent_id) # TODO: New Core, remove old code when stable parent2 = Task2(title=_('New Task'), id=parent_id) parent2.tags = self.app.ds.tasks.get(self.task.tid).tags self.app.ds.tasks.add(parent2) self.app.ds.tasks.parent(self.task.tid, parent2.id) self.app.open_task(parent_id) # Prevent WM issues and risks of conflicting content changes: self.close() elif len(parents) == 1: self.app.open_task(parents[0]) # Prevent WM issues and risks of conflicting content changes: self.close() elif len(parents) > 1: self.show_multiple_parent_popover(parents)
def test_toggle_dismiss_children(self): task = Task2(id=uuid4(), title='A Task') task2 = Task2(id=uuid4(), title='A Child Task') task.children.append(task2) task2.parent = task task.toggle_dismiss() self.assertEqual(task.status, Status.DISMISSED) self.assertEqual(task.date_closed, Date.today()) self.assertEqual(task2.status, Status.DISMISSED) self.assertEqual(task2.date_closed, Date.today()) task.toggle_dismiss() self.assertEqual(task.status, Status.ACTIVE) self.assertEqual(task.date_closed, Date.no_date()) self.assertEqual(task2.status, Status.ACTIVE) self.assertEqual(task2.date_closed, Date.no_date())
def test_tags_children(self): task1 = Task2(id=uuid4(), title='A Parent Task') task2 = Task2(id=uuid4(), title='A Child Task') tag1 = Tag2(id=uuid4(), name='A Tag') tag2 = Tag2(id=uuid4(), name='Another Tag') task1.children.append(task2) task1.add_tag(tag1) self.assertEqual(len(task1.tags), 1) self.assertEqual(len(task2.tags), 0) task2.add_tag(tag2) self.assertEqual(len(task1.tags), 1) self.assertEqual(len(task2.tags), 1) self.assertEqual(task2.tags[0].name, 'Another Tag')
def test_toggle_dismiss_single(self): task = Task2(id=uuid4(), title='A Task') task.toggle_dismiss() self.assertEqual(task.status, Status.DISMISSED) self.assertEqual(task.date_closed, Date.today()) task.toggle_dismiss() self.assertEqual(task.status, Status.ACTIVE) self.assertEqual(task.date_closed, Date.no_date())
def test_toggle_active_single(self): task = Task2(id=uuid4(), title='A Task') self.assertEqual(task.status, Status.ACTIVE) task.toggle_active() self.assertEqual(task.status, Status.DONE) self.assertEqual(task.date_closed, Date.today()) task.toggle_active() self.assertEqual(task.status, Status.ACTIVE) self.assertEqual(task.date_closed, Date.no_date())
def test_excerpt(self): task = Task2(id=uuid4(), title='A Task') self.assertEqual(task.excerpt, '') task.content = ('This is a sample content with some @tags, and some ' 'extra text for padding. I could go on and on and on ' 'and on and on.') expected = ('This is a sample content with some @tags, and some ' 'extra text for padding. I cou…') self.assertEqual(task.excerpt, expected)
def test_tags(self): task = Task2(id=uuid4(), title='A Task') tag = Tag2(id=uuid4(), name='A Tag') task.add_tag(tag) self.assertEqual(len(task.tags), 1) with self.assertRaises(ValueError): task.add_tag('my super tag') self.assertEqual(len(task.tags), 1) task.add_tag(tag) self.assertEqual(len(task.tags), 1) task.remove_tag('A Tag') self.assertEqual(len(task.tags), 0)
def __init__(self, requester, app, task, thisisnew=False, clipboard=None): """ req is the requester app is the view manager thisisnew is True when a new task is created and opened """ self.req = requester self.app = app self.browser_config = self.req.get_config('browser') self.config = self.req.get_task_config(task.get_id()) self.time = None self.clipboard = clipboard self.builder = Gtk.Builder() self.builder.add_from_file(self.EDITOR_UI_FILE) self.editormenu = self.builder.get_object("editor_menu") self.donebutton = self.builder.get_object("mark_as_done") self.undonebutton = self.builder.get_object("mark_as_undone") self.add_subtask = self.builder.get_object("add_subtask") self.tag_store = self.builder.get_object("tag_store") self.parent_button = self.builder.get_object("parent") # Closed date self.closed_popover = self.builder.get_object("closed_popover") self.closed_entry = self.builder.get_object("closeddate_entry") self.closed_calendar = self.builder.get_object("calendar_closed") # Start date self.start_popover = self.builder.get_object("start_popover") self.start_entry = self.builder.get_object("startdate_entry") self.start_calendar = self.builder.get_object("calendar_start") # Due date self.due_popover = self.builder.get_object("due_popover") self.due_entry = self.builder.get_object("duedate_entry") self.due_calendar = self.builder.get_object("calendar_due") # Recurrence self.recurring_menu = RecurringMenu(self.req, task.tid, self.builder) # TODO: Remove old code when new core is stable # If new add to new DS if thisisnew and task.tid not in self.app.ds.tasks.lookup.keys(): new_task = Task2(task.tid, task.get_title()) self.app.ds.tasks.add(new_task) # Create our dictionary and connect it dic = { "on_tags_popover": self.open_tags_popover, "on_tag_toggled": self.on_tag_toggled, "on_move": self.on_move, "set_recurring_term_every_day": self.set_recurring_term_every_day, "set_recurring_term_every_otherday": self.set_recurring_term_every_otherday, "set_recurring_term_every_week": self.set_recurring_term_every_week, "set_recurring_term_every_month": self.set_recurring_term_every_month, "set_recurring_term_every_year": self.set_recurring_term_every_year, "set_recurring_term_week_day": self.set_recurring_term_week_day, "set_recurring_term_calender_month": self.set_recurring_term_month, "set_recurring_term_calender_year": self.set_recurring_term_year, "toggle_recurring_status": self.toggle_recurring_status, "on_repeat_icon_toggled": self.on_repeat_icon_toggled, "show_popover_start": self.show_popover_start, "startingdate_changed": lambda w: self.date_changed(w, GTGCalendar.DATE_KIND_START), "startdate_cleared": lambda w: self.on_date_cleared(w, GTGCalendar.DATE_KIND_START), "startdate_focus_out": lambda w, e: self.date_focus_out(w, e, GTGCalendar.DATE_KIND_START ), "show_popover_due": self.show_popover_due, "duedate_changed": lambda w: self.date_changed(w, GTGCalendar.DATE_KIND_DUE), "duedate_now_selected": lambda w: self.on_duedate_fuzzy(w, Date.now()), "duedate_soon_selected": lambda w: self.on_duedate_fuzzy(w, Date.soon()), "duedate_someday_selected": lambda w: self.on_duedate_fuzzy(w, Date.someday()), "duedate_cleared": lambda w: self.on_date_cleared(w, GTGCalendar.DATE_KIND_DUE), "duedate_focus_out": lambda w, e: self.date_focus_out(w, e, GTGCalendar.DATE_KIND_DUE), "show_popover_closed": self.show_popover_closed, "closeddate_changed": lambda w: self.date_changed(w, GTGCalendar.DATE_KIND_CLOSED), "closeddate_focus_out": lambda w, e: self.date_focus_out(w, e, GTGCalendar.DATE_KIND_CLOSED ), } self.window = self.builder.get_object("TaskEditor") self.builder.connect_signals(dic) self.window.set_application(app) if task.has_parent(): self.parent_button.set_label(_('Open Parent')) else: self.parent_button.set_label(_('Add Parent')) # Connect signals for the calendar self.start_handle = self.start_calendar.connect( 'day-selected', lambda c: self.on_date_selected(c, GTGCalendar.DATE_KIND_START)) self.due_handle = self.due_calendar.connect( 'day-selected', lambda c: self.on_date_selected(c, GTGCalendar.DATE_KIND_DUE)) self.closed_handle = self.closed_calendar.connect( 'day-selected', lambda c: self.on_date_selected(c, GTGCalendar.DATE_KIND_CLOSED)) # Removing the Normal textview to replace it by our own # So don't try to change anything with glade, this is a home-made # widget textview = self.builder.get_object("textview") scrolled = self.builder.get_object("scrolledtask") scrolled.remove(textview) self.textview = TaskView(self.req, self.clipboard) self.textview.set_vexpand(True) self.textview.show() scrolled.add(self.textview) conf_font_value = self.browser_config.get("font_name") if conf_font_value != "": self.textview.override_font(Pango.FontDescription(conf_font_value)) self.textview.browse_tag_cb = app.select_tag self.textview.new_subtask_cb = self.new_subtask self.textview.get_subtasks_cb = task.get_children self.textview.delete_subtask_cb = self.remove_subtask self.textview.rename_subtask_cb = self.rename_subtask self.textview.open_subtask_cb = self.open_subtask self.textview.save_cb = self.light_save self.textview.add_tasktag_cb = self.tag_added self.textview.remove_tasktag_cb = self.tag_removed self.textview.refresh_cb = self.refresh_editor self.textview.get_tagslist_cb = task.get_tags_name self.textview.tid = task.tid # Voila! it's done self.textview.connect('focus-in-event', self.on_textview_focus_in) self.textview.connect('focus-out-event', self.on_textview_focus_out) """ TODO(jakubbrindza): Once all the functionality in editor is back and working, bring back also the accelerators! Dayleft_label needs to be brought back, however its position is unsure. """ # self.dayleft_label = self.builder.get_object("dayleft") self.task = task tags = task.get_tags() text = self.task.get_text() title = self.task.get_title() # Insert text and tags as a non_undoable action, otherwise # the user can CTRL+Z even this inserts. self.textview.buffer.begin_not_undoable_action() self.textview.buffer.set_text(f"{title}\n") if text: self.textview.insert(text) # Insert any remaining tags if tags: tag_names = [t.get_name() for t in tags] self.textview.insert_tags(tag_names) else: # If not text, we insert tags if tags: tag_names = [t.get_name() for t in tags] self.textview.insert_tags(tag_names) start = self.textview.buffer.get_end_iter() self.textview.buffer.insert(start, '\n') # Insert subtasks if they weren't inserted in the text subtasks = task.get_children() for sub in subtasks: if sub not in self.textview.subtasks['tags']: self.textview.insert_existing_subtask(sub) if thisisnew: self.textview.select_title() else: self.task.set_to_keep() self.textview.buffer.end_not_undoable_action() self.window.connect("destroy", self.destruction) # Connect search field to tags popup self.tags_entry = self.builder.get_object("tags_entry") self.tags_tree = self.builder.get_object("tags_tree") self.tags_tree.set_search_entry(self.tags_entry) self.tags_tree.set_search_equal_func(self.search_function, None) # plugins self.pengine = PluginEngine() self.plugin_api = PluginAPI(self.req, self.app, self) self.pengine.register_api(self.plugin_api) self.pengine.onTaskLoad(self.plugin_api) # Putting the refresh callback at the end make the start a lot faster self.refresh_editor() self.textview.grab_focus() self.init_dimensions() self.window.insert_action_group('app', app) self.window.insert_action_group('win', app.browser) self.textview.set_editable(True) self.window.set_transient_for(self.app.browser) self.window.show()
def test_title(self): task = Task2(id=uuid4(), title='\tMy Title\n') self.assertEqual(task.title, 'My Title')
def test_due_date(self): task1 = Task2(id=uuid4(), title='A Parent Task') task2 = Task2(id=uuid4(), title='A Child Task') task3 = Task2(id=uuid4(), title='Another Child Task') task4 = Task2(id=uuid4(), title='Yet Another Child Task') task5 = Task2(id=uuid4(), title='So many Child Tasks') task6 = Task2(id=uuid4(), title='More childs') task1.children.append(task2) task1.children.append(task3) task3.children.append(task4) task4.children.append(task5) task4.children.append(task6) # Test changing parent's due random_date = Date('1996-2-3') random_date2 = Date('2010-7-10') task1.date_due = random_date self.assertEqual(task1.date_due, random_date) task2.date_due = random_date task3.date_due = random_date task4.date_due = random_date task5.date_due = random_date task6.date_due = random_date # Test changes in the parent - Fuzzy task1.date_due = Date.now() self.assertEqual(task1.date_due, Date.now()) self.assertEqual(task2.date_due, random_date) self.assertEqual(task3.date_due, random_date) self.assertEqual(task4.date_due, random_date) self.assertEqual(task5.date_due, random_date) self.assertEqual(task6.date_due, random_date) # Test changing child's due (after parent's) task3.date_due = random_date2 self.assertEqual(task3.date_due, random_date2) self.assertEqual(task4.date_due, random_date) self.assertEqual(task5.date_due, random_date) self.assertEqual(task6.date_due, random_date) # Test changing child's due (before parent's) task4.date_due = random_date2 task3.date_due = random_date self.assertEqual(task4.date_due, random_date) self.assertEqual(task5.date_due, random_date) self.assertEqual(task6.date_due, random_date) # Test changing parent's due (before child's) task4.date_due = random_date task3.date_due = random_date2 self.assertEqual(task3.date_due, random_date2) self.assertEqual(task4.date_due, random_date) # Test changing parent's due (None or nodate) task2.date_due = random_date task1.date_due = None self.assertEqual(task2.date_due, random_date)