def __init__(self, parent, editor, replace): Toplevel.__init__(self, parent) self.title(SSTE_NAME) self.replace = replace self.editor = editor # make modal self.transient(parent) self.grab_set() self._search = StringVar() d = ttk.Label(self, text=_('Find text:')) d.grid(column=0, row=0, sticky=W, padx=2, pady=2) t = ttk.Entry(self, width=20, textvariable=self._search) t.grid(column=0, row=1, sticky=(W, E), padx=2, pady=2) t.focus() if replace: self._replace = StringVar() d = ttk.Label(self, text=_('Replace with:')) d.grid(column=0, row=2, sticky=W, padx=2, pady=2) t = ttk.Entry(self, width=20, textvariable=self._replace) t.grid(column=0, row=3, sticky=(W, E), padx=2, pady=2) self.bind('<Return>', self.onSearch) self.bind('<Escape>', self.onQuit)
def __init__(self, parent, confirm): Toplevel.__init__(self, parent) self.title(SSTE_NAME) self._confirm = confirm # make modal self.transient(parent) self.grab_set() self._passwd = StringVar() self._passwdconf = StringVar() self.password = '' d = ttk.Label(self, text=_('Password:'******'*') p.grid(column=0, row=1, sticky=(W, E), padx=2, pady=2) if self._confirm: d = ttk.Label(self, text=_('Confirm:')) d.grid(column=0, row=2, sticky=W, padx=2, pady=2) c = ttk.Entry(self, textvariable=self._passwdconf, show='*') c.grid(column=0, row=3, sticky=(W, E), padx=2, pady=2) p.focus() self.bind('<Return>', self.onClose) self.bind('<Escape>', self.onQuit)
def openFile(self): '''Open and decrypt file. ''' passwd = self.getPassword(confirm=False) if passwd: try: text = open(self.filename, 'rb').read() except: self.error(_('Could not open file.')) self.filename = DEFAULT_FILENAME return try: text = decrypt(self.config['gnupg'], text, passwd) except BadPassword: self.error(_('Wrong password.')) return except GnuPGError as e: self.error(_('GnuPG error:\n{}').format(str(e))) return except Exception as e: self.error(e) return self.text.delete('1.0', 'end') self.text.insert('1.0', text) self.text.mark_set('insert', '1.0') self.text.see('insert') self.text.edit_modified(0)
def onClose(self, *args): if not self._confirm or self._passwd.get() == self._passwdconf.get(): self.password = self._passwd.get() self.destroy() else: messagebox.showinfo(parent=self, title=SSTE_NAME, message=_('Error:'), detail=_("Entered passwords don't match."), icon='error')
def __init__(self, parent, message): Toplevel.__init__(self, parent) self.title(SSTE_NAME) # make modal self.transient(parent) self.grab_set() t = Text(self, wrap='none') t.insert('1.0', message) vscroll = ttk.Scrollbar(self, orient=VERTICAL, command=t.yview) hscroll = ttk.Scrollbar(self, orient=HORIZONTAL, command=t.xview) t.configure(yscrollcommand=vscroll.set, xscrollcommand=hscroll.set, state=DISABLED) t.grid(column=0, row=0, sticky=(W, N, E, S)) vscroll.grid(column=1, row=0, sticky=(N, S)) hscroll.grid(column=0, row=1, sticky=(W, E)) self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) close = ttk.Button(self, text=_("Close"), command=self.onClose) close.grid(column=0, row=2, padx=2, pady=5) close.focus() self.bind('<Return>', self.onClose)
def error(self, message): '''Show error message. ''' messagebox.showinfo(parent=self.win, title=SSTE_NAME, message=_('Error'), detail=message, icon='error')
def onGnuPG(self, *args): '''Choose GnuPG path. ''' p = filedialog.askopenfilename(title=_('GnuPG path'), initialfile=self.config['gnupg']) if p: self.config['gnupg'] = p self._gnupg.set(self.config['gnupg'])
def onBGColor(self, *args): '''Choose background color. ''' c = colorchooser.askcolor(title=_('Background color'), initialcolor=self.config['bgcolor']) if c[1]: self.config['bgcolor'] = c[1] self._bgcolor.set(self.config['bgcolor']) self.editor['background'] = self.config['bgcolor']
def onFGColor(self, *args): '''Choose text color. ''' c = colorchooser.askcolor(title=_('Text color'), initialcolor=self.config['fgcolor']) if c[1]: self.config['fgcolor'] = c[1] self._fgcolor.set(self.config['fgcolor']) self.editor['foreground'] = self.config['fgcolor'] self.editor['insertbackground'] = self.config['fgcolor']
def bindAccelerators(self): '''Bind all keyboard shortcuts. ''' # File menu self.win.bind(_('<Control-n>'), self.onNew) self.win.bind(_('<Control-o>'), self.onOpen) self.win.bind(_('<Control-s>'), self.onSave) self.win.bind(_('<Control-S>'), self.onSaveAs) self.win.bind(_('<Control-q>'), self.onQuit) # Edit menu self.win.bind(_('<Control-f>'), self.onFind) self.win.bind(_('<Control-r>'), self.onReplace) self.win.bind(_('<Control-a>'), self.onSelectAll) # Help menu self.win.bind(_('<F1>'), self.onManual)
def safeToCloseDoc(self): '''Show safe to close dialog. ''' if self.text.edit_modified(): if messagebox.askyesno( message=('Close document'), detail=_('File has changed. Do you want to save it?'), title=SSTE_NAME, icon='question'): return self.onSave() return True
def __init__(self, parent, editor, config): Toplevel.__init__(self, parent) self.title(SSTE_NAME) self.editor = editor self.settings = config # keep original configuration self.config = config.copy() # local configuration copy # make modal self.transient(parent) self.grab_set() self._fgcolor = StringVar() self._fgcolor.set(self.config['fgcolor']) self._bgcolor = StringVar() self._bgcolor.set(self.config['bgcolor']) self._gnupg = StringVar() self._gnupg.set(self.config['gnupg']) d = ttk.Label(self, text=_('Text color:')) d.grid(column=0, row=0, sticky=W, padx=2, pady=2) b = ttk.Button(self, width=25, textvariable=self._fgcolor, command=self.onFGColor) b.grid(column=1, row=0, sticky=(W,E), padx=2, pady=2) b.focus() d = ttk.Label(self, text=_('Background color:')) d.grid(column=0, row=1, sticky=W, padx=2, pady=2) b = ttk.Button(self, width=25, textvariable=self._bgcolor, command=self.onBGColor) b.grid(column=1, row=1, sticky=(W,E), padx=2, pady=2) d = ttk.Label(self, text=_('GnuPG path:')) d.grid(column=0, row=2, sticky=W, padx=2, pady=2) b = ttk.Button(self, width=25, textvariable=self._gnupg, command=self.onGnuPG) b.grid(column=1, row=2, sticky=(W,E), padx=2, pady=2) self.bind('<Return>', self.onOk) self.bind('<Escape>', self.onCancel)
def saveFile(self): '''Encrypt and save file. ''' passwd = self.getPassword(confirm=True) if passwd: try: text = encrypt(self.config['gnupg'], self.text.get('1.0', 'end'), passwd) except GnuPGError as e: self.error(_('GnuPG error:\n{}').format(str(e))) return except Exception as e: self.error(e) return try: open(self.filename, 'wb').write(text) except: self.error(_('Could not write to file.')) self.filename = DEFAULT_FILENAME return self.text.edit_modified(0)
def onSearch(self, *args): '''Search text in editor text widget.''' # unselect any currently selected text self.editor.tag_remove('sel', '1.0', 'end') countVar = StringVar() start = self.editor.search(self._search.get(), 'insert', nocase=True, stopindex='end', count=countVar) if start: end = '{}+{}c'.format(start, countVar.get()) self.editor.see(start) self.editor.tag_add('sel', start, end) if self.replace: if messagebox.askyesno(title=SSTE_NAME, message=_('Replace text'), detail=_('Replace current selection?'), icon='question'): self.editor.delete(start, end) self.editor.insert(start, self._replace.get()) end = '{}+{}c'.format(start, len(self._replace.get())) else: self.editor.tag_remove(start, end) self.editor.mark_set('insert', end) else: if messagebox.askyesno(title=SSTE_NAME, message=_('Text not found.'), detail=_('Go to top of document?'), icon='question'): # unselect currently selected text self.editor.tag_remove('sel', '1.0', 'end') self.editor.mark_set('insert', '1.0') self.editor.see('1.0') else: self.destroy()
def _execute(gpg, text, passwd, cmd): '''Execute GnuPG with command 'cmd' and return answer. ''' try: proc = Popen((gpg, cmd, '--batch', '--quiet', '--passphrase', passwd), stdin=PIPE, stdout=PIPE, stderr=PIPE) text, err = proc.communicate(text) except: raise Exception(_('Could not execute GnuPG.')) if err: err = err.decode(encoding='utf-8') if 'Bad session key' in err: raise BadPassword raise GnuPGError(e) return text
def buildMenu(self): '''Build and insert all menus. ''' menubar = Menu(self.win) self.win['menu'] = menubar # File menu fileMenu = Menu(menubar) lbl, pos = labelUnderline(_('_File')) menubar.add_cascade(menu=fileMenu, label=lbl, underline=pos) lbl, pos = labelUnderline(_('_New')) fileMenu.add_command(label=lbl, underline=pos, accelerator=_('Ctrl+N'), command=self.onNew) lbl, pos = labelUnderline(_('_Open...')) fileMenu.add_command(label=lbl, underline=pos, accelerator=_('Ctrl+O'), command=self.onOpen) lbl, pos = labelUnderline(_('_Save')) fileMenu.add_command(label=lbl, underline=pos, accelerator=_('Ctrl+S'), command=self.onSave) lbl, pos = labelUnderline(_('Save _As...')) fileMenu.add_command(label=lbl, underline=pos, accelerator=_('Ctrl+Shift+S'), command=self.onSaveAs) fileMenu.add_separator() lbl, pos = labelUnderline(_('_Quit')) fileMenu.add_command(label=lbl, underline=pos, accelerator=_('Ctrl+Q'), command=self.onQuit) # Edit Menu editMenu = Menu(menubar) lbl, pos = labelUnderline(_('_Edit')) menubar.add_cascade(menu=editMenu, label=lbl, underline=pos) lbl, pos = labelUnderline(_('_Undo')) editMenu.add_command(label=lbl, underline=pos, accelerator=_('Ctrl+Z'), command=self.text.edit_undo) lbl, pos = labelUnderline(_('Re_do')) editMenu.add_command(label=lbl, underline=pos, accelerator=_('Ctrl+Shift+Z'), command=self.text.edit_redo) editMenu.add_separator() lbl, pos = labelUnderline(_('Cu_t')) editMenu.add_command( label=lbl, underline=pos, accelerator=_('Ctrl+X'), command=lambda: self.text.event_generate('<<Cut>>')) lbl, pos = labelUnderline(_('_Copy')) editMenu.add_command( label=lbl, underline=pos, accelerator=_('Ctrl+C'), command=lambda: self.text.event_generate('<<Copy>>')) lbl, pos = labelUnderline(_('_Paste')) editMenu.add_command( label=lbl, underline=pos, accelerator=_('Ctrl+V'), command=lambda: self.text.event_generate('<<Paste>>')) editMenu.add_separator() lbl, pos = labelUnderline(_('_Find...')) editMenu.add_command(label=lbl, underline=pos, accelerator=_('Ctrl+F'), command=self.onFind) lbl, pos = labelUnderline(_('_Replace...')) editMenu.add_command(label=lbl, underline=pos, accelerator=_('Ctrl+R'), command=self.onReplace) editMenu.add_separator() lbl, pos = labelUnderline(_('Select _All')) editMenu.add_command(label=lbl, underline=pos, accelerator=_('Ctrl+A'), command=self.onSelectAll) editMenu.add_separator() lbl, pos = labelUnderline(_('_Settings...')) editMenu.add_command(label=lbl, underline=pos, command=self.onSettings) # Help Menu helpMenu = Menu(menubar) lbl, pos = labelUnderline(_('_Help')) menubar.add_cascade(menu=helpMenu, label=lbl, underline=pos) lbl, pos = labelUnderline(_('_Manual')) helpMenu.add_command(label=lbl, underline=pos, accelerator=_('F1'), command=self.onManual) helpMenu.add_separator() lbl, pos = labelUnderline(_('_About')) helpMenu.add_command(label=lbl, underline=pos, command=self.onAbout) lbl, pos = labelUnderline(_('_Copyright')) helpMenu.add_command(label=lbl, underline=pos, command=self.onCopyright) lbl, pos = labelUnderline(_('_Warranty')) helpMenu.add_command(label=lbl, underline=pos, command=self.onWarranty)
if os.path.exists(i): break CONFIG_FILE = i DEFAULT_CONFIG = {'gnupg': '', 'fgcolor': 'black', 'bgcolor': 'white'} #------------------------------------------------------------------------------ # process arguments and show information or start GUI parser = argparse.ArgumentParser(description=SSTE_NAME + ' ' + SSTE_VERSION) parser.add_argument("filename", type=str, nargs='?', default='', help=_('file to open')) parser.add_argument( "--gnupg", type=str, default='', help=_('GnuPG command, including complete path if not on PATH')) parser.add_argument("-c", "--copyright", action="store_true", help=_('show copyright information.')) parser.add_argument("-w", "--warranty", action="store_true",