Ejemplo n.º 1
0
class CategoryManager(Frame):
    """Category manager for the sticky notes."""

    def __init__(self, master, app, **kwargs):
        Frame.__init__(self, master, **kwargs)
        self.columnconfigure(0, weight=1)

        self.app = app

        self.style = Style(self)
        self.style.theme_use("clam")

        self.im_plus = PhotoImage(file=IM_PLUS)
        self.im_moins = PhotoImage(file=IM_MOINS)

        # --- Default category
        self.frame_def_cat = Frame(self)
        self.default_category = StringVar(self.frame_def_cat,
                                          CONFIG.get("General",
                                                     "default_category").capitalize())
        Label(self.frame_def_cat, text=_("Default category ")).grid(row=0, column=0,
                                                                    sticky="e",
                                                                    padx=(4, 0))
        self.categories = CONFIG.options("Categories")
        self.categories.sort()
        categories = [cat.capitalize() for cat in self.categories]
        self.def_cat_menu = OptionMenu(self.frame_def_cat, self.default_category,
                                       CONFIG.get("General",
                                                  "default_category").capitalize(),
                                       *categories)
        optionmenu_patch(self.def_cat_menu, self.default_category)
        self.def_cat_menu.grid(row=0, column=1, sticky="w", padx=4, pady=4)

        # --- Category colors, names ...
        self.frame_cat = Frame(self)
        self.colors = list(COLORS.keys())
        self.colors.sort()
        self.images = []
        for key in self.colors:
            self.images.append(PhotoImage(key, master=self, width=16, height=16))
            fill(self.images[-1], COLORS[key])
        self.cat_colors = {}
        self.cat_labels = {}
        self.cat_menus = {}
        self.cat_buttons = {}
        for i, cat in enumerate(self.categories):
            self.cat_labels[cat] = Label(self.frame_cat,
                                         text="%s" % cat.capitalize(),
                                         anchor='e')
            self.cat_labels[cat].grid(row=i + 2, column=0, sticky="ew", padx=2)
            self.cat_labels[cat].bind('<Double-Button-1>', self.change_name)
            self.cat_colors[cat] = StringVar(self)
            color = CONFIG.get("Categories", cat)
            self.cat_menus[cat] = OptionMenu(self.frame_cat, self.cat_colors[cat],
                                             INV_COLORS[color], *self.colors,
                                             command=lambda color, c=cat: self.change_menubutton_color(color, c),
                                             style="%s.TMenubutton" % cat)
            optionmenu_patch(self.cat_menus[cat], self.cat_colors[cat])
            self.style.configure("%s.TMenubutton" % cat, background=color)
            self.cat_menus[cat].grid(row=i + 2, column=1, sticky="w", padx=4, pady=4)
            self.cat_buttons[cat] = Button(self.frame_cat, image=self.im_moins,
                                           command=lambda c=cat: self.del_cat(c))
            self.cat_buttons[cat].grid(row=i + 2, column=2, padx=4, pady=4)

        self.add_cat_button = Button(self.frame_cat, image=self.im_plus,
                                     command=self.add_cat)
        self.add_cat_button.grid(row=i + 3, column=0, pady=(0, 4))

        if len(self.categories) == 1:
            self.cat_buttons[self.categories[0]].configure(state="disabled")

        # --- placement
        self.frame_def_cat.grid(row=0, column=0, sticky="eswn")
        Separator(self, orient="horizontal").grid(row=1, columnspan=3,
                                                  pady=10, sticky="ew")
        self.frame_cat.grid(row=2, column=0, sticky="eswn")

    def change_name(self, event):
        def ok(event):
            cats = [l.cget('text').lower() for l in self.cat_labels.values()]
            cat = name.get().strip().lower()
            if cat and cat not in cats:
                label.configure(text=cat.capitalize())
                if old_cat == self.default_category.get():
                    self.default_category.set(cat.capitalize())
                self.update_def_cat_menu()

            name.destroy()
        label = event.widget
        old_cat = label.cget('text')
        name = Entry(self, justify='center')
        name.insert(0, label.cget('text'))
        name.place(in_=label, relx=0, rely=0, anchor='nw', relwidth=1, relheight=1)
        name.bind('<FocusOut>', lambda e: name.destroy())
        name.bind('<Escape>', lambda e: name.destroy())
        name.bind('<Return>', ok)
        name.selection_range(0, 'end')
        name.focus_set()

    def get_color(self, category):
        return self.cat_colors[category].get()

    def get_name(self, category):
        return self.cat_labels[category].cget('text').lower()

    def change_menubutton_color(self, color, cat):
        """ change the color of the menubutton of the category cat when its
            default color is changed """
        self.style.configure("%s.TMenubutton" % cat, background=COLORS[color])

    def del_cat(self, category):
        rep = askyesnocancel(_("Question"),
                             _("Do you want to delete all notes belonging to \
the category %(category)s? If you answer 'No', the category will be deleted but \
the notes will belong to the default category. Be careful, the change will take \
effect immediately and cannot be undone." % {"category": category}))
        if rep is not None:
            del(self.cat_colors[category])
            self.cat_buttons[category].grid_forget()
            del(self.cat_buttons[category])
            self.cat_labels[category].grid_forget()
            cat = self.cat_labels[category].cget('text')
            del(self.cat_labels[category])
            self.cat_menus[category].grid_forget()
            del(self.cat_menus[category])
            self.categories.remove(category)
            CONFIG.remove_option("Categories", category)
            if self.default_category.get() == cat:
                default = list(self.cat_labels.values())[0].cget('text')
                self.default_category.set(default)
                CONFIG.set("General", "default_category", default.lower())
                self.update_def_cat_menu()
            if len(self.categories) == 1:
                self.cat_buttons[self.categories[0]].configure(state="disabled")
            if rep:
                self.app.delete_cat(category)
            self.app.update_notes()
            self.app.update_menu()
            save_config()

    def update_def_cat_menu(self):
        self.def_cat_menu.destroy()
        categories = [l.cget('text') for l in self.cat_labels.values()]
        self.def_cat_menu = OptionMenu(self.frame_def_cat, self.default_category,
                                       None, *categories)
        optionmenu_patch(self.def_cat_menu, self.default_category)
        self.def_cat_menu.grid(row=0, column=1, sticky="w", padx=4, pady=4)

    def add_cat(self):
        top = Toplevel(self)
        top.transient(self)
        top.grab_set()
        top.resizable(False, False)
        top.title(_("New Category"))

        def valide(event=None):
            cats = [l.cget('text').lower() for l in self.cat_labels.values()]
            cat = name.get().strip().lower()
            if cat and cat not in cats:
                i = self.add_cat_button.grid_info()['row']
                self.add_cat_button.grid_configure(row=i + 1)
                self.cat_labels[cat] = Label(self.frame_cat,
                                             text="%s " % cat.capitalize())
                self.cat_labels[cat].grid(row=i, column=0, sticky="e")
                self.cat_colors[cat] = StringVar(self, _("Yellow"))
                self.cat_menus[cat] = OptionMenu(self.frame_cat, self.cat_colors[cat],
                                                 _("Yellow"), *self.colors,
                                                 command=lambda color, c=cat: self.change_menubutton_color(color, c),
                                                 style="%s.TMenubutton" % cat)
                self.style.configure("%s.TMenubutton" % cat, background=COLORS[_("Yellow")])
                optionmenu_patch(self.cat_menus[cat], self.cat_colors[cat])
                self.cat_menus[cat].grid(row=i, column=1, padx=4, pady=4)
                self.cat_buttons[cat] = Button(self.frame_cat, image=self.im_moins,
                                               command=lambda c=cat: self.del_cat(c))
                self.cat_buttons[cat].grid(row=i, column=2, padx=4, pady=4)
                self.cat_buttons[self.categories[0]].configure(state="normal")
                self.categories.append(cat)
                self.categories.sort()
                self.update_def_cat_menu()
                top.destroy()

        name = Entry(top, justify="center")
        name.grid(row=0, column=0, columnspan=2, sticky="ew")
        name.bind("<Return>", valide)
        name.focus_set()
        Button(top, text="Ok", command=valide).grid(row=1, column=0, sticky="nswe")
        Button(top, text=_("Cancel"),
               command=top.destroy).grid(row=1, column=1, sticky="nswe")
Ejemplo n.º 2
0
class Manager(Toplevel):
    """Mailbox Manager."""
    def __init__(self, master, pwd):
        """Create the mailbox manager dialog."""
        Toplevel.__init__(self, master, class_="CheckMails")
        self.title(_("Mailbox Manager"))
        self.minsize(200, 10)
        self.pwd = pwd
        self.resizable(False, False)
        self.protocol("WM_DELETE_WINDOW", self.quit)
        self.im_add = PhotoImage(master=self, file=ADD)
        self.im_del = PhotoImage(master=self, file=DEL)
        self.im_edit = PhotoImage(master=self, file=EDIT)
        self.mailboxes = {}
        active = CONFIG.get("Mailboxes", "active").split(", ")
        inactive = CONFIG.get("Mailboxes", "inactive").split(", ")
        while "" in active:
            active.remove("")
        while "" in inactive:
            inactive.remove("")
        active.sort()
        inactive.sort()
        self.frame = Frame(self)
        self.columnconfigure(0, weight=1)
        self.frame.columnconfigure(1, weight=1)
        self.frame.grid(row=0, column=0, padx=10, pady=10, sticky="eswn")
        i = -1
        for i, box in enumerate(active):
            c = Checkbutton(self.frame)
            c.state(('selected',))
            c.grid(row=i, column=0, pady=4, padx=(4, 0))
            l = Label(self.frame, text=box)
            l.grid(row=i, column=1, padx=4, pady=4)
            b_edit = Button(self.frame, image=self.im_edit, width=1,
                            command=lambda m=box: self.mailbox_info(m))
            b_edit.grid(row=i, column=2, padx=4, pady=4)
            b_del = Button(self.frame, image=self.im_del, width=1,
                           command=lambda m=box: self.del_mailbox(m))
            b_del.grid(row=i, column=3, padx=4, pady=4)
            self.mailboxes[box] = [c, l, b_edit, b_del]
        for box in inactive:
            i += 1
            c = Checkbutton(self.frame)
            c.grid(row=i, column=0, pady=4, padx=(4, 0))
            l = Label(self.frame, text=box)
            l.grid(row=i, column=1, padx=4, pady=4)
            b_edit = Button(self.frame, image=self.im_edit, width=1,
                            command=lambda m=box: self.mailbox_info(m))
            b_edit.grid(row=i, column=2, padx=4, pady=4)
            b_del = Button(self.frame, image=self.im_del, width=1,
                           command=lambda m=box: self.del_mailbox(m))
            b_del.grid(row=i, column=3, padx=4, pady=4)
            self.mailboxes[box] = [c, l, b_edit, b_del]

        self.b_add = Button(self.frame, image=self.im_add, command=self.mailbox_info, width=1)
        self.b_add.grid(row=i + 1, column=0, columnspan=4, pady=4, padx=4, sticky='w')

    def quit(self):
        """Save configuration and destroy the dialog."""
        active = []
        inactive = []
        for box, (c, l, b1, b2) in self.mailboxes.items():
            if "selected" in c.state():
                active.append(box)
            else:
                inactive.append(box)
        CONFIG.set("Mailboxes", "active", ", ".join(active))
        CONFIG.set("Mailboxes", "inactive", ", ".join(inactive))
        save_config()
        self.destroy()

    def del_mailbox(self, mailbox):
        """Delete the mailbox."""
        try:
            os.remove(os.path.join(LOCAL_PATH, mailbox))
        except FileNotFoundError:
            pass
        c, l, b_edit, b_del = self.mailboxes[mailbox]
        del(self.mailboxes[mailbox])
        c.grid_forget()
        l.grid_forget()
        b_edit.grid_forget()
        b_del.grid_forget()

    def mailbox_info(self, mailbox=""):
        """GUI to add or modify a mailbox login information."""

        def on_click(event):
            event.widget.focus_set()
            event.widget.selection_range(0, 'end')
            event.widget.unbind('<1>')
            return "break"

        def save(event=None):
            name = name_entry.get().strip()
            if not mailbox:
                # new mailbox
                i = self.b_add.grid_info()['row']
                self.b_add.grid_configure(row=i + 1)
                c = Checkbutton(self.frame)
                c.state(('selected',))
                c.grid(row=i, column=0, pady=4, padx=(4, 0))
                l = Label(self.frame, text=name)
                l.grid(row=i, column=1, padx=4, pady=4)
                b_edit = Button(self.frame, image=self.im_edit, width=1,
                                command=lambda m=name: self.mailbox_info(m))
                b_edit.grid(row=i, column=2, padx=4, pady=4)
                b_del = Button(self.frame, image=self.im_del, width=1,
                               command=lambda m=name: self.del_mailbox(m))
                b_del.grid(row=i, column=3, padx=4, pady=4)
                self.mailboxes[name] = [c, l, b_edit, b_del]
            elif name != mailbox:
                # change name of mailbox
                os.remove(os.path.join(LOCAL_PATH, mailbox))
                c, l, b_edit, b_del = self.mailboxes[mailbox]
                del(self.mailboxes[mailbox])
                l.configure(text=name)
                b_edit.configure(command=lambda m=name: self.mailbox_info(m))
                b_del.configure(command=lambda m=name: self.del_mailbox(m))
                self.mailboxes[name] = [c, l, b_edit, b_del]

            encrypt(name, self.pwd, server_entry.get().strip(),
                    login_entry.get().strip(), password_entry.get().strip(),
                    folder_entry.get().strip())
            top.destroy()

        top = Toplevel(self, class_="CheckMails")
        top.title(_("Login information"))
        top.transient(self)
        top.resizable(False, False)
        name_entry = Entry(top, justify='center', width=32)
        server_entry = Entry(top, justify='center', width=32)
        login_entry = Entry(top, justify='center', width=32)
        password_entry = Entry(top, show='*', justify='center', width=32)
        folder_entry = Entry(top, justify='center', width=32)
        if mailbox:
            name_entry.insert(0, mailbox)
            server, login, password, folder = decrypt(mailbox, self.pwd)
            if server is None:
                top.destroy()
                self.del_mailbox(mailbox)
                return
            server_entry.insert(0, server)
            login_entry.insert(0, login)
            password_entry.insert(0, password)
            folder_entry.insert(0, folder)
        else:
            name_entry.insert(0, "Mailbox name")
            server_entry.insert(0, "IMAP.mailbox.com")
            login_entry.insert(0, "*****@*****.**")
            folder_entry.insert(0, "inbox")
            name_entry.bind("<1>", on_click)
            server_entry.bind("<1>", on_click)
            login_entry.bind("<1>", on_click)
            password_entry.bind("<1>", on_click)
            folder_entry.bind("<1>", on_click)

        Label(top, text=_("Mailbox name")).grid(row=0, column=0, sticky="e",
                                                pady=(10, 4), padx=(10, 1))
        Label(top, text=_("IMAP server")).grid(row=1, column=0, sticky="e",
                                               pady=4, padx=(10, 1))
        Label(top, text=_("Login")).grid(row=2, column=0, sticky="e",
                                         pady=4, padx=(10, 1))
        Label(top, text=_("Password")).grid(row=3, column=0, sticky="e",
                                            pady=4, padx=(10, 1))
        Label(top, text=_("Folder to check")).grid(row=4, column=0, sticky="e",
                                                   pady=4, padx=(10, 1))
        name_entry.grid(row=0, column=1, sticky="w", pady=4, padx=(1, 10))
        server_entry.grid(row=1, column=1, sticky="w", pady=4, padx=(1, 10))
        login_entry.grid(row=2, column=1, sticky="w", pady=4, padx=(1, 10))
        password_entry.grid(row=3, column=1, sticky="w", pady=4, padx=(1, 10))
        folder_entry.grid(row=4, column=1, sticky="w", pady=4, padx=(1, 10))
        frame = Frame(top)
        frame.grid(row=5, columnspan=2, pady=(0, 6))
        Button(frame, text="Ok", command=save).grid(row=0, column=0,
                                                    padx=(10, 4), pady=4)
        Button(frame, text=_("Cancel"), command=top.destroy).grid(row=0,
                                                                  column=1,
                                                                  pady=4,
                                                                  padx=(10, 4))
        top.grab_set()
        name_entry.bind("<Key-Return>", save)
        server_entry.bind("<Key-Return>", save)
        login_entry.bind("<Key-Return>", save)
        password_entry.bind("<Key-Return>", save)
        folder_entry.bind("<Key-Return>", save)
        name_entry.focus_set()