Ejemplo n.º 1
0
    def to_readable_string(self):
        """ Return nice representation of date.

        Fuzzy dates => localized version
        Close dates => Today, Tomorrow, In X days
        Other => with locale dateformat, stripping year for this year
        """
        if self._fuzzy is not None:
            return STRINGS[self._fuzzy]

        days_left = self.days_left()
        if days_left == 0:
            return _('Today')
        elif days_left < 0:
            abs_days = abs(days_left)
            return ngettext('Yesterday', '%(days)d days ago', abs_days) % \
                {'days': abs_days}
        elif days_left > 0 and days_left <= 15:
            return ngettext('Tomorrow', 'In %(days)d days', days_left) % \
                {'days': days_left}
        else:
            locale_format = locale.nl_langinfo(locale.D_FMT)
            if calendar.isleap(datetime.date.today().year):
                year_len = 366
            else:
                year_len = 365
            if float(days_left) / year_len < 1.0:
                # if it's in less than a year, don't show the year field
                locale_format = locale_format.replace('/%Y', '')
                locale_format = locale_format.replace('.%Y', '.')
            return self._real_date.strftime(locale_format)
Ejemplo n.º 2
0
Archivo: dates.py Proyecto: huxuan/gtg
    def to_readable_string(self):
        """ Return nice representation of date.

        Fuzzy dates => localized version
        Close dates => Today, Tomorrow, In X days
        Other => with locale dateformat, stripping year for this year
        """
        if self._fuzzy is not None:
            return STRINGS[self._fuzzy]

        days_left = self.days_left()
        if days_left == 0:
            return _('Today')
        elif days_left < 0:
            abs_days = abs(days_left)
            return ngettext('Yesterday', '%(days)d days ago', abs_days) % \
                {'days': abs_days}
        elif days_left > 0 and days_left <= 15:
            return ngettext('Tomorrow', 'In %(days)d days', days_left) % \
                {'days': days_left}
        else:
            locale_format = locale.nl_langinfo(locale.D_FMT)
            if calendar.isleap(datetime.date.today().year):
                year_len = 366
            else:
                year_len = 365
            if float(days_left) / year_len < 1.0:
                # if it's in less than a year, don't show the year field
                locale_format = locale_format.replace('/%Y', '')
                locale_format = locale_format.replace('.%Y', '.')
            return self._real_date.strftime(locale_format)
Ejemplo n.º 3
0
    def delete_tags(self, tags=None):
        self.tags_todelete = tags or self.tags_todelete

        if not self.tags_todelete:
            # We must at least have something to delete !
            return []

        # Prepare labels
        singular = len(self.tags_todelete)
        cancel_text = ngettext("Keep selected tag", "Keep selected tags",
                               singular)

        delete_text = ngettext("Permanently remove tag",
                               "Permanently remove tags", singular)

        label_text = ngettext(
            "Deleting a tag cannot be undone, "
            "and will delete the following tag: ",
            "Deleting a tag cannot be undone, "
            "and will delete the following tag: ", singular)

        label_text = label_text[0:label_text.find(":") + 1]

        # we don't want to end with just one task that doesn't fit the
        # screen and a line saying "And one more task", so we go a
        # little over our limit
        tags_count = len(self.tags_todelete)
        missing_tags_count = tags_count - self.MAXIMUM_TAGS_TO_SHOW
        if missing_tags_count >= 2:
            tagslist = self.tags_todelete[:self.MAXIMUM_TAGS_TO_SHOW]
            titles_suffix = _("\nAnd %d more tags") % missing_tags_count
        else:
            tagslist = self.tags_todelete
            titles_suffix = ""

        titles = "".join("\n• " + tag for tag in tagslist)

        # Build and run dialog
        dialog = Gtk.MessageDialog(transient_for=self.browser, modal=True)
        dialog.add_button(cancel_text, Gtk.ResponseType.CANCEL)

        delete_btn = dialog.add_button(delete_text, Gtk.ResponseType.YES)
        delete_btn.get_style_context().add_class("destructive-action")

        dialog.props.use_markup = True
        dialog.props.text = "<span weight=\"bold\">" + label_text + "</span>"

        dialog.props.secondary_text = titles + titles_suffix

        response = dialog.run()
        dialog.destroy()

        if response == Gtk.ResponseType.YES:
            self.on_delete_confirm()
        elif response == Gtk.ResponseType.REJECT:
            tagslist = []

        return tagslist
Ejemplo n.º 4
0
    def delete_tags(self, tags=None):
        if tags:
            self.tags_todelete = tags
        # We must at least have something to delete !
        if len(self.tags_todelete) > 0:

            # We fill the text and the buttons' labels according to the number
            # of tags to delete
            label = self.builder.get_object("label1")
            label_text = label.get_text()
            cdlabel2 = self.builder.get_object("cd-label2")
            cdlabel3 = self.builder.get_object("cd-label3")
            cdlabel4 = self.builder.get_object("cd-label4")
            singular = len(self.tags_todelete)
            label_text = ngettext(
                "Deleting a tag cannot be undone, "
                "and will delete the following tag: ",
                "Deleting a tag cannot be undone, "
                "and will delete the following tag: ", singular)
            cdlabel2.set_label(
                ngettext("Are you sure you want to delete this"
                         " tag?", "Are you sure you want to delete "
                         "these tags?", singular))

            cdlabel3.set_label(
                ngettext("Keep selected tag", "Keep selected tags", singular))
            cdlabel4.set_label(
                ngettext("Permanently remove tag", "Permanently remove tags",
                         singular))
            label_text = label_text[0:label_text.find(":") + 1]

            # we don't want to end with just one task that doesn't fit the
            # screen and a line saying "And one more task", so we go a
            # little over our limit
            tags_count = len(self.tags_todelete)
            missing_tags_count = tags_count - self.MAXIMUM_TAGS_TO_SHOW
            if missing_tags_count >= 2:
                tagslist = self.tags_todelete[:self.MAXIMUM_TAGS_TO_SHOW]
                titles_suffix = _("\nAnd %d more tags") % missing_tags_count
            else:
                tagslist = self.tags_todelete
                titles_suffix = ""

            titles = "".join("\n - " + tag for tag in tagslist)
            label.set_text(label_text + titles + titles_suffix)
            delete_dialog = self.builder.get_object("confirm_delete_tag")
            delete_dialog.resize(1, 1)
            cancel_button = self.builder.get_object("cancel")
            cancel_button.grab_focus()
            if delete_dialog.run() != 1:
                self.tags_todelete = []
            delete_dialog.hide()
            return tagslist
        else:
            return []
Ejemplo n.º 5
0
    def refresh_day_left(self):
        # If the task is marked as done, we display the delay between the
        # due date and the actual closing date. If the task isn't marked
        # as done, we display the number of days left.
        status = self.task.get_status()
        if status in [Task.STA_DISMISSED, Task.STA_DONE]:
            delay = self.task.get_days_late()
            if delay is None:
                txt = ""
            elif delay == 0:
                txt = "Completed on time"
            elif delay >= 1:
                txt = ngettext("Completed %(days)d day late",
                               "Completed %(days)d days late", delay) % \
                    {'days': delay}
            elif delay <= -1:
                abs_delay = abs(delay)
                txt = ngettext("Completed %(days)d day early",
                               "Completed %(days)d days early", abs_delay) % \
                    {'days': abs_delay}
        else:
            due_date = self.task.get_due_date()
            result = due_date.days_left()
            if due_date.is_fuzzy():
                txt = ""
            elif result > 0:
                txt = ngettext("Due tomorrow!", "%(days)d days left", result)\
                    % {'days': result}
            elif result == 0:
                txt = _("Due today!")
            elif result < 0:
                abs_result = abs(result)
                txt = ngettext("Due yesterday!", "Was %(days)d days ago",
                               abs_result) % {
                                   'days': abs_result
                               }

        style_context = self.window.get_style_context()
        color = style_context.get_color(Gtk.StateFlags.INSENSITIVE).to_color()
        self.dayleft_label.set_markup(
            f"<span color='{color.to_string()}'>{txt}</span>")
Ejemplo n.º 6
0
    def on_combo_changed(self, widget=None):
        """
        Updates the backend description and icon.

        @param widget: just to make this function usable as a signal callback.
                       Not used.
        """
        backend_name = self.combo_types.get_selected()
        if backend_name is None:
            return
        backend = BackendFactory().get_backend(backend_name)
        self.label_description.set_markup(backend.Backend.get_description())

        markup = '<big><big><big><b>%s</b></big></big></big>' % \
            backend.Backend.get_human_default_name()
        self.label_name.set_markup(markup)
        authors = backend.Backend.get_authors()
        author_txt = '<b>%s</b>:\n   - %s' % \
            (ngettext("Author", "Authors", len(authors)),
             reduce(lambda a, b: a + "\n" + "   - " + b, authors))
        self.label_author.set_markup(author_txt)
        pixbuf = self.dialog.get_pixbuf_from_icon_name(backend_name, 128)
        self.image_icon.set_from_pixbuf(pixbuf)
        self.show_all()
Ejemplo n.º 7
0
    def on_combo_changed(self, widget=None):
        '''
        Updates the backend description and icon.

        @param widget: just to make this function usable as a signal callback.
                       Not used.
        '''
        backend_name = self.combo_types.get_selected()
        if backend_name is None:
            return
        backend = BackendFactory().get_backend(backend_name)
        self.label_description.set_markup(backend.Backend.get_description())

        markup = '<big><big><big><b>%s</b></big></big></big>' % \
            backend.Backend.get_human_default_name()
        self.label_name.set_markup(markup)
        authors = backend.Backend.get_authors()
        author_txt = '<b>%s</b>:\n   - %s' % \
            (ngettext("Author", "Authors", len(authors)),
             reduce(lambda a, b: a + "\n" + "   - " + b, authors))
        self.label_author.set_markup(author_txt)
        pixbuf = self.dialog.get_pixbuf_from_icon_name(backend_name, 128)
        self.image_icon.set_from_pixbuf(pixbuf)
        self.show_all()
Ejemplo n.º 8
0
 def update_minutes_label(self):
     adjustment = int(self.adjustment.get_value())
     self.minutes_label.set_markup(
         ngettext(" minute", " minutes", adjustment))
Ejemplo n.º 9
0
    def show(self, tids=None):
        self.tids_todelete = tids or self.tids_todelete

        if not self.tids_todelete:
            # We must at least have something to delete!
            return []

        # Get full task list to delete
        tasklist = []
        self.update_tags = []

        for tid in self.tids_todelete:
            task = self.req.get_task(tid)
            self.recursive_list_tasks(tasklist, task)

        # Prepare Labels
        singular = len(tasklist)
        cancel_text = ngettext("Keep selected task", "Keep selected tasks",
                               singular)

        delete_text = ngettext("Permanently remove task",
                               "Permanently remove tasks", singular)

        label_text = ngettext(
            "Deleting a task cannot be undone, "
            "and will delete the following task: ",
            "Deleting a task cannot be undone, "
            "and will delete the following tasks: ", singular)

        label_text = label_text[0:label_text.find(":") + 1]

        missing_titles_count = len(tasklist) - self.MAXIMUM_TIDS_TO_SHOW

        if missing_titles_count >= 2:
            tasks = tasklist[:self.MAXIMUM_TIDS_TO_SHOW]
            titles_suffix = _("\nAnd %d more tasks" % missing_titles_count)
        else:
            tasks = tasklist
            titles_suffix = ""

        titles = "".join("\n• " + task.get_title() for task in tasks)

        # Build and run dialog
        dialog = Gtk.MessageDialog(transient_for=self.window, modal=True)
        dialog.add_button(cancel_text, Gtk.ResponseType.CANCEL)

        delete_btn = dialog.add_button(delete_text, Gtk.ResponseType.YES)
        delete_btn.get_style_context().add_class("destructive-action")

        dialog.props.use_markup = True
        dialog.props.text = "<span weight=\"bold\">" + label_text + "</span>"

        dialog.props.secondary_text = titles + titles_suffix

        response = dialog.run()
        dialog.destroy()

        if response == Gtk.ResponseType.YES:
            self.on_delete_confirm()
        elif response == Gtk.ResponseType.REJECT:
            tasklist = []

        return tasklist
Ejemplo n.º 10
0
    def refresh_editor(self, title=None, refreshtext=False):
        if self.window is None:
            return
        to_save = False
        # title of the window
        if title:
            self.window.set_title(title)
            to_save = True
        else:
            self.window.set_title(self.task.get_title())

        status = self.task.get_status()
        dismiss_tooltip = GnomeConfig.MARK_DISMISS_TOOLTIP
        undismiss_tooltip = GnomeConfig.MARK_UNDISMISS_TOOLTIP
        if status == Task.STA_DISMISSED:
            self.donebutton.set_label(GnomeConfig.MARK_DONE)
            self.donebutton.set_tooltip_text(GnomeConfig.MARK_DONE_TOOLTIP)
            self.donebutton.set_stock_id(Gtk.STOCK_APPLY)
            self.dismissbutton.set_label(GnomeConfig.MARK_UNDISMISS)
            self.dismissbutton.set_tooltip_text(undismiss_tooltip)
            self.dismissbutton.set_stock_id(Gtk.STOCK_REFRESH)
        elif status == Task.STA_DONE:
            self.donebutton.set_label(GnomeConfig.MARK_UNDONE)
            self.donebutton.set_tooltip_text(GnomeConfig.MARK_UNDONE_TOOLTIP)
            self.donebutton.set_stock_id(Gtk.STOCK_REFRESH)
            self.dismissbutton.set_label(GnomeConfig.MARK_DISMISS)
            self.dismissbutton.set_tooltip_text(dismiss_tooltip)
            self.dismissbutton.set_stock_id(Gtk.STOCK_CLOSE)
        else:
            self.donebutton.set_label(GnomeConfig.MARK_DONE)
            self.donebutton.set_tooltip_text(GnomeConfig.MARK_DONE_TOOLTIP)
            self.donebutton.set_stock_id(Gtk.STOCK_APPLY)
            self.dismissbutton.set_label(GnomeConfig.MARK_DISMISS)
            self.dismissbutton.set_tooltip_text(dismiss_tooltip)
            self.dismissbutton.set_stock_id(Gtk.STOCK_CLOSE)
        self.donebutton.show()
        self.tasksidebar.show()

        # Refreshing the status bar labels and date boxes
        if status in [Task.STA_DISMISSED, Task.STA_DONE]:
            self.builder.get_object("label2").hide()
            self.builder.get_object("box1").hide()
            self.builder.get_object("label4").show()
            self.builder.get_object("box4").show()
        else:
            self.builder.get_object("label4").hide()
            self.builder.get_object("box4").hide()
            self.builder.get_object("label2").show()
            self.builder.get_object("box1").show()

        # refreshing the start date field
        startdate = self.task.get_start_date()
        try:
            prevdate = Date.parse(self.startdate_widget.get_text())
            update_date = startdate != prevdate
        except ValueError:
            update_date = True

        if update_date:
            self.startdate_widget.set_text(str(startdate))

        # refreshing the due date field
        duedate = self.task.get_due_date()
        try:
            prevdate = Date.parse(self.duedate_widget.get_text())
            update_date = duedate != prevdate
        except ValueError:
            update_date = True

        if update_date:
            self.duedate_widget.set_text(str(duedate))

        # refreshing the closed date field
        closeddate = self.task.get_closed_date()
        prevcldate = Date.parse(self.closeddate_widget.get_text())
        if closeddate != prevcldate:
            self.closeddate_widget.set_text(str(closeddate))

        # refreshing the day left label
        # If the task is marked as done, we display the delay between the
        # due date and the actual closing date. If the task isn't marked
        # as done, we display the number of days left.
        if status in [Task.STA_DISMISSED, Task.STA_DONE]:
            delay = self.task.get_days_late()
            if delay is None:
                txt = ""
            elif delay == 0:
                txt = "Completed on time"
            elif delay >= 1:
                txt = ngettext("Completed %(days)d day late",
                               "Completed %(days)d days late", delay) % \
                    {'days': delay}
            elif delay <= -1:
                abs_delay = abs(delay)
                txt = ngettext("Completed %(days)d day early",
                               "Completed %(days)d days early", abs_delay) % \
                    {'days': abs_delay}
        else:
            due_date = self.task.get_due_date()
            result = due_date.days_left()
            if due_date.is_fuzzy():
                txt = ""
            elif result > 0:
                txt = ngettext("Due tomorrow!", "%(days)d days left", result) \
                    % {'days': result}
            elif result == 0:
                txt = _("Due today!")
            elif result < 0:
                abs_result = abs(result)
                txt = ngettext("Due yesterday!", "Was %(days)d days ago",
                               abs_result) % {'days': abs_result}

        style_context = self.window.get_style_context()
        color = style_context.get_color(Gtk.StateFlags.INSENSITIVE).to_color()
        self.dayleft_label.set_markup(
            "<span color='%s'>%s</span>" % (color.to_string(), txt))

        # Refreshing the tag list in the insert tag button
        taglist = self.req.get_used_tags()
        menu = Gtk.Menu()
        tag_count = 0
        for tagname in taglist:
            tag_object = self.req.get_tag(tagname)
            if not tag_object.is_special() and \
                    not self.task.has_tags(tag_list=[tagname]):
                tag_count += 1
                mi = Gtk.MenuItem(label=tagname, use_underline=False)
                mi.connect("activate", self.inserttag, tagname)
                mi.show()
                menu.append(mi)
        if tag_count > 0:
            self.inserttag_button.set_menu(menu)

        # Refreshing the parent list in open_parent_button
        menu = Gtk.Menu()
        parents = self.task.get_parents()
        if len(parents) > 0:
            for parent in self.task.get_parents():
                task = self.req.get_task(parent)
                mi = Gtk.MenuItem(label=task.get_title(), use_underline=False)
                mi.connect("activate", self.open_parent, parent)
                mi.show()
                menu.append(mi)
            self.open_parents_button.set_menu(menu)
        else:
            self.open_parents_button.set_sensitive(False)

        if refreshtext:
            self.textview.modified(refresheditor=False)
        if to_save:
            self.light_save()
Ejemplo n.º 11
0
    def delete_tasks(self, tids=None):
        if tids:
            self.tids_todelete = tids
        # We must at least have something to delete !
        if len(self.tids_todelete) > 0:
            tasklist = []
            self.update_tags = []
            for tid in self.tids_todelete:

                def recursive_list_tasks(task_list, root):
                    """Populate a list of all the subtasks and
                       their children, recursively.

                       Also collect the list of affected tags
                       which should be refreshed"""
                    if root not in task_list:
                        task_list.append(root)
                        for tagname in root.get_tags_name():
                            if tagname not in self.update_tags:
                                self.update_tags.append(tagname)
                        for i in root.get_subtasks():
                            if i not in task_list:
                                recursive_list_tasks(task_list, i)

                task = self.req.get_task(tid)
                recursive_list_tasks(tasklist, task)

            # We fill the text and the buttons' labels according to the number
            # of tasks to delete
            label = self.builder.get_object("label1")
            label_text = label.get_text()
            cdlabel2 = self.builder.get_object("cd_question_label")
            cdlabel3 = self.builder.get_object("cd_cancel_label")
            cdlabel4 = self.builder.get_object("cd_delete_label")
            singular = len(tasklist)
            label_text = ngettext(
                "Deleting a task cannot be undone, "
                "and will delete the following task: ",
                "Deleting a task cannot be undone, "
                "and will delete the following tasks: ", singular)
            cdlabel2.set_label(
                ngettext("Are you sure you want to delete this"
                         " task?", "Are you sure you want to delete "
                         "these tasks?", singular))

            cdlabel3.set_label(
                ngettext("Keep selected task", "Keep selected tasks",
                         singular))
            cdlabel4.set_label(
                ngettext("Permanently remove task", "Permanently remove tasks",
                         singular))
            label_text = label_text[0:label_text.find(":") + 1]

            # we don't want to end with just one task that doesn't fit the
            # screen and a line saying "And one more task", so we go a
            # little over our limit
            missing_titles_count = len(tasklist) - self.MAXIMUM_TIDS_TO_SHOW
            if missing_titles_count >= 2:
                tasks = tasklist[:self.MAXIMUM_TIDS_TO_SHOW]
                titles_suffix = _("\nAnd %d more tasks" % missing_titles_count)
            else:
                tasks = tasklist
                titles_suffix = ""

            titles = "".join("\n - " + task.get_title() for task in tasks)
            label.set_text(label_text + titles + titles_suffix)
            delete_dialog = self.builder.get_object("confirm_delete")
            delete_dialog.resize(1, 1)
            cancel_button = self.builder.get_object("cancel")
            cancel_button.grab_focus()
            if delete_dialog.run() != 1:
                tasklist = []
            delete_dialog.hide()
            return tasklist
        else:
            return []
Ejemplo n.º 12
0
    def delete_tasks(self, tids=None):
        if tids:
            self.tids_todelete = tids
        # We must at least have something to delete !
        if len(self.tids_todelete) > 0:
            tasklist = []
            self.update_tags = []
            for tid in self.tids_todelete:

                def recursive_list_tasks(task_list, root):
                    """Populate a list of all the subtasks and
                       their children, recursively.

                       Also collect the list of affected tags
                       which should be refreshed"""
                    if root not in task_list:
                        task_list.append(root)
                        for tagname in root.get_tags_name():
                            if tagname not in self.update_tags:
                                self.update_tags.append(tagname)
                        for i in root.get_subtasks():
                            if i not in task_list:
                                recursive_list_tasks(task_list, i)

                task = self.req.get_task(tid)
                recursive_list_tasks(tasklist, task)

            # We fill the text and the buttons' labels according to the number
            # of tasks to delete
            label = self.builder.get_object("label1")
            label_text = label.get_text()
            cdlabel2 = self.builder.get_object("cd_question_label")
            cdlabel3 = self.builder.get_object("cd_cancel_label")
            cdlabel4 = self.builder.get_object("cd_delete_label")
            singular = len(tasklist)
            label_text = ngettext("Deleting a task cannot be undone, "
                                  "and will delete the following task: ",
                                  "Deleting a task cannot be undone, "
                                  "and will delete the following tasks: ",
                                  singular)
            cdlabel2.set_label(ngettext("Are you sure you want to delete this"
                                        " task?",
                                        "Are you sure you want to delete "
                                        "these tasks?",
                                        singular))

            cdlabel3.set_label(ngettext("Keep selected task",
                                        "Keep selected tasks",
                                        singular))
            cdlabel4.set_label(ngettext("Permanently remove task",
                                        "Permanently remove tasks",
                                        singular))
            label_text = label_text[0:label_text.find(":") + 1]

            # we don't want to end with just one task that doesn't fit the
            # screen and a line saying "And one more task", so we go a
            # little over our limit
            missing_titles_count = len(tasklist) - self.MAXIMUM_TIDS_TO_SHOW
            if missing_titles_count >= 2:
                tasks = tasklist[: self.MAXIMUM_TIDS_TO_SHOW]
                titles_suffix = _("\nAnd %d more tasks" % missing_titles_count)
            else:
                tasks = tasklist
                titles_suffix = ""

            titles = "".join("\n - " + task.get_title() for task in tasks)
            label.set_text(label_text + titles + titles_suffix)
            delete_dialog = self.builder.get_object("confirm_delete")
            delete_dialog.resize(1, 1)
            cancel_button = self.builder.get_object("cancel")
            cancel_button.grab_focus()
            if delete_dialog.run() != 1:
                tasklist = []
            delete_dialog.hide()
            return tasklist
        else:
            return []
Ejemplo n.º 13
0
 def update_minutes_label(self):
     adjustment = int(self.adjustment.get_value())
     self.minutes_label.set_markup(ngettext(" minute", " minutes",
                                            adjustment))