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 import_notes(self): fichier = askopenfilename(defaultextension=".backup", filetypes=[(_("Notes (.notes)"), "*.notes"), (_("All files"), "*")], initialdir=LOCAL_PATH, initialfile="", title=_('Import')) if fichier: try: with open(fichier, "rb") as fich: dp = pickle.Unpickler(fich) note_data = dp.load() for i, key in enumerate(note_data): data = note_data[key] note_id = "%i" % (i + self.nb) self.note_data[note_id] = data cat = data["category"] if not CONFIG.has_option("Categories", cat): CONFIG.set("Categories", cat, data["color"]) self.hidden_notes[cat] = {} if data["visible"]: self.notes[note_id] = Sticky(self, note_id, **data) self.nb = int(max(self.note_data.keys(), key=lambda x: int(x))) + 1 self.update_menu() self.update_notes() except Exception: message = _("The file {file} is not a valid .notes file." ).format(file=fichier) showerror(_("Error"), message, traceback.format_exc())
def restore(self, fichier=None, confirmation=True): """Restore notes from backup.""" if confirmation: rep = askokcancel( _("Warning"), _("Restoring a backup will erase the current notes."), icon="warning") else: rep = True if rep: if fichier is None: fichier = askopenfilename(defaultextension=".backup", filetypes=[], initialdir=LOCAL_PATH, initialfile="", title=_('Restore Backup')) if fichier: try: keys = list(self.note_data.keys()) for key in keys: self.delete_note(key) if not os.path.samefile(fichier, PATH_DATA): copy(fichier, PATH_DATA) with open(PATH_DATA, "rb") as myfich: dp = pickle.Unpickler(myfich) note_data = dp.load() for i, key in enumerate(note_data): data = note_data[key] note_id = "%i" % i self.note_data[note_id] = data cat = data["category"] if not CONFIG.has_option("Categories", cat): CONFIG.set("Categories", cat, data["color"]) if data["visible"]: self.notes[note_id] = Sticky(self, note_id, **data) self.nb = len(self.note_data) self.update_menu() self.update_notes() except FileNotFoundError: showerror( _("Error"), _("The file {filename} does not exists.").format( filename=fichier)) except Exception as e: showerror(_("Error"), str(e), traceback.format_exc(), True)
def quit(self): CONFIG.set("General", "check_update", str("selected" in self.ch.state())) save_config() self.destroy()
def __init__(self): Tk.__init__(self) self.withdraw() self.notes = {} self.img = PhotoImage(file=cst.IM_ICON) self.icon = PhotoImage(master=self, file=cst.IM_ICON_48) self.iconphoto(True, self.icon) self.ewmh = ewmh.EWMH() style = Style(self) style.theme_use("clam") self.close1 = PhotoImage("img_close", file=cst.IM_CLOSE) self.close2 = PhotoImage("img_closeactive", file=cst.IM_CLOSE_ACTIVE) self.roll1 = PhotoImage("img_roll", file=cst.IM_ROLL) self.roll2 = PhotoImage("img_rollactive", file=cst.IM_ROLL_ACTIVE) self.protocol("WM_DELETE_WINDOW", self.quit) self.icon = tktray.Icon(self, docked=True) # --- Menu self.menu_notes = Menu(self.icon.menu, tearoff=False) self.hidden_notes = {cat: {} for cat in CONFIG.options("Categories")} self.menu_show_cat = Menu(self.icon.menu, tearoff=False) self.menu_hide_cat = Menu(self.icon.menu, tearoff=False) self.icon.configure(image=self.img) self.icon.menu.add_command(label=_("New Note"), command=self.new) self.icon.menu.add_separator() self.icon.menu.add_command(label=_('Show All'), command=self.show_all) self.icon.menu.add_cascade(label=_('Show Category'), menu=self.menu_show_cat) self.icon.menu.add_cascade(label=_('Show Note'), menu=self.menu_notes, state="disabled") self.icon.menu.add_separator() self.icon.menu.add_command(label=_('Hide All'), command=self.hide_all) self.icon.menu.add_cascade(label=_('Hide Category'), menu=self.menu_hide_cat) self.icon.menu.add_separator() self.icon.menu.add_command(label=_("Preferences"), command=self.config) self.icon.menu.add_command(label=_("Note Manager"), command=self.manage) self.icon.menu.add_separator() self.icon.menu.add_command(label=_("Backup Notes"), command=self.backup) self.icon.menu.add_command(label=_("Restore Backup"), command=self.restore) self.icon.menu.add_separator() self.icon.menu.add_command(label=_("Export"), command=self.export_notes) self.icon.menu.add_command(label=_("Import"), command=self.import_notes) self.icon.menu.add_separator() self.icon.menu.add_command(label=_('Check for Updates'), command=lambda: UpdateChecker(self)) self.icon.menu.add_command(label=_('About'), command=lambda: About(self)) self.icon.menu.add_command(label=_('Quit'), command=self.quit) # --- Restore notes self.note_data = {} if os.path.exists(PATH_DATA): with open(PATH_DATA, "rb") as fich: dp = pickle.Unpickler(fich) note_data = dp.load() for i, key in enumerate(note_data): self.note_data["%i" % i] = note_data[key] backup() for key in self.note_data: data = self.note_data[key] cat = data["category"] if not CONFIG.has_option("Categories", cat): CONFIG.set("Categories", cat, data["color"]) if data["visible"]: self.notes[key] = Sticky(self, key, **data) else: self.add_note_to_menu(key, data["title"], cat) self.nb = len(self.note_data) self.update_menu() self.update_notes() self.make_notes_sticky() # --- class bindings # newline depending on mode self.bind_class("Text", "<Return>", self.insert_newline) # char deletion taking into account list type self.bind_class("Text", "<BackSpace>", self.delete_char) # change Ctrl+A to select all instead of go to the beginning of the line self.bind_class('Text', '<Control-a>', self.select_all_text) self.bind_class('TEntry', '<Control-a>', self.select_all_entry) # bind Ctrl+Y to redo self.bind_class('Text', '<Control-y>', self.redo_event) # unbind Ctrl+I and Ctrl+B self.bind_class('Text', '<Control-i>', lambda e: None) self.bind_class('Text', '<Control-b>', lambda e: None) # highlight checkboxes when inside text selection self.bind_class("Text", "<ButtonPress-1>", self.highlight_checkboxes, True) self.bind_class("Text", "<ButtonRelease-1>", self.highlight_checkboxes, True) self.bind_class("Text", "<B1-Motion>", self.highlight_checkboxes, True) evs = [ '<<SelectAll>>', '<<SelectLineEnd>>', '<<SelectLineStart>>', '<<SelectNextChar>>', '<<SelectNextLine>>', '<<SelectNextPara>>', '<<SelectNextWord>>', '<<SelectNone>>', '<<SelectPrevChar>>', '<<SelectPrevLine>>', '<<SelectPrevPara>>', '<<SelectPrevWord>>' ] for ev in evs: self.bind_class("Text", ev, self.highlight_checkboxes, True) # check for updates if CONFIG.getboolean("General", "check_update"): UpdateChecker(self)
def ok(self): family = self.font_family.get() if family not in self.fonts: l = [i for i in self.fonts if i[:len(family)] == family] if l: family = l[0] else: family = 'TkDefaultFont' size = self.font_size.get() familytitle = self.fonttitle_family.get() if familytitle not in self.fonts: l = [i for i in self.fonts if i[:len(familytitle)] == familytitle] if l: familytitle = l[0] else: familytitle = 'TkDefaultFont' sizetitle = self.fonttitle_size.get() opacity = "%i" % float(self.opacity_scale.get()) language = self.lang.get().lower()[:2] style = "" if self.is_bold.instate(("selected", )): style += "bold," if self.is_italic.instate(("selected", )): style += "italic," if self.is_underlined.instate(("selected", )): style += "underline," if style: style = style[:-1] symbols = [ l.strip() for l in self.symbols.get("1.0", "end").splitlines() ] CONFIG.set("General", "default_category", self.category_settings.default_category.get().lower()) CONFIG.set("General", "language", language) CONFIG.set("General", "opacity", opacity) CONFIG.set("General", "position", self.position.get()) CONFIG.set("General", "buttons_position", self.titlebar_disposition.get()) CONFIG.set("General", "symbols", "".join(symbols)) CONFIG.set("Font", "text_size", size) CONFIG.set("Font", "text_family", family) CONFIG.set("Font", "title_family", familytitle) CONFIG.set("Font", "title_size", sizetitle) CONFIG.set("Font", "title_style", style) col_changes = {} name_changes = {} for cat in self.category_settings.categories: new_name = self.category_settings.get_name(cat) if cat in CONFIG.options("Categories"): old_color = CONFIG.get("Categories", cat) new_color = COLORS[self.category_settings.get_color(cat)] if new_name != cat: name_changes[cat] = new_name CONFIG.remove_option("Categories", cat) CONFIG.set("Categories", new_name, new_color) if old_color != new_color: col_changes[new_name] = (old_color, new_color) CONFIG.set("Categories", new_name, new_color) else: CONFIG.set("Categories", new_name, COLORS[self.category_settings.get_color(cat)]) save_config() self.changes = col_changes, name_changes self.destroy()