# HG changeset patch # User Erik Grinaker # Date 1091447582 0 # Node ID b181693cfdc75cbe6814327c31b2a44e488925ff # Parent a877d43f09876152f64340bf52aaa1ed15101a6b small changes like cleanups and bugfixes diff -r a877d43f09876152f64340bf52aaa1ed15101a6b -r b181693cfdc75cbe6814327c31b2a44e488925ff AUTHORS --- a/AUTHORS Thu Jul 29 14:20:09 2004 +0000 +++ b/AUTHORS Mon Aug 02 11:53:02 2004 +0000 @@ -1,4 +1,4 @@ Revelation was written by: -Erik Grinaker +Erik Grinaker diff -r a877d43f09876152f64340bf52aaa1ed15101a6b -r b181693cfdc75cbe6814327c31b2a44e488925ff ChangeLog --- a/ChangeLog Thu Jul 29 14:20:09 2004 +0000 +++ b/ChangeLog Mon Aug 02 11:53:02 2004 +0000 @@ -2,6 +2,14 @@ ---------------[ xxxx-xx-xx : 0.3.1 ]--------------- +2004-08-02 Erik Grinaker + + * added access keys to popup menus + + * code cleanups + + * updated some of the text files + 2004-07-29 Erik Grinaker * moved data about the current file into the EntryStore class diff -r a877d43f09876152f64340bf52aaa1ed15101a6b -r b181693cfdc75cbe6814327c31b2a44e488925ff INSTALL --- a/INSTALL Thu Jul 29 14:20:09 2004 +0000 +++ b/INSTALL Mon Aug 02 11:53:02 2004 +0000 @@ -7,11 +7,7 @@ python setup.py build python setup.py install +Note: if you are reinstalling or upgrading Revelation you may need to use +"python setup.py install --force", otherwise the old files will not be +replaced. -You may need to restart gconfd-2 after installing for the first time, -as gconf doesn't sense changes to the central database. Run -'gconftool-2 --shutdown' as your normal user, or send it a SIGHUP. - -If you are reinstalling or upgrading Revelation you may need to use -the --force argument to install, otherwise the old files will not be -replaced. diff -r a877d43f09876152f64340bf52aaa1ed15101a6b -r b181693cfdc75cbe6814327c31b2a44e488925ff README --- a/README Thu Jul 29 14:20:09 2004 +0000 +++ b/README Mon Aug 02 11:53:02 2004 +0000 @@ -1,5 +1,7 @@ -Revelation is a password manager for the GNOME 2 desktop. It organizes -accounts in a tree structure, and stores them as AES-encrypted XML. +Revelation is a password manager for the GNOME 2 desktop, released +under the GNU GPL license. It stores accounts and passwords in a single, +secure place, and gives access to them through a user-friendly graphical +interface. -The project website is located at http://oss.wired-networks.net/revelation/ +The project website is located at http://oss.codepoet.no/revelation/ diff -r a877d43f09876152f64340bf52aaa1ed15101a6b -r b181693cfdc75cbe6814327c31b2a44e488925ff TODO --- a/TODO Thu Jul 29 14:20:09 2004 +0000 +++ b/TODO Mon Aug 02 11:53:02 2004 +0000 @@ -8,6 +8,9 @@ - program-launchers for misc account types (announce on rvl-list when done in svn) - export to XHTML/CSS files +- add a "changed" signal to the EntryStore - requires all methods to + be atomic (can't call add_entry() etc directly, since it triggers + the signal repeatedly) 0.4.x: - will introduce a gnome 2.6 dependency diff -r a877d43f09876152f64340bf52aaa1ed15101a6b -r b181693cfdc75cbe6814327c31b2a44e488925ff setup.py --- a/setup.py Thu Jul 29 14:20:09 2004 +0000 +++ b/setup.py Mon Aug 02 11:53:02 2004 +0000 @@ -9,7 +9,7 @@ version = '0.3.0', description = 'Password manager for GNOME 2', author = 'Erik Grinaker', - author_email = 'erikg@wired-networks.net', + author_email = 'erikg@codepoet.no', url = 'http://oss.codepoet.no/revelation/', packages = [ 'revelation', 'revelation.datahandler' ], diff -r a877d43f09876152f64340bf52aaa1ed15101a6b -r b181693cfdc75cbe6814327c31b2a44e488925ff src/lib/data.py --- a/src/lib/data.py Thu Jul 29 14:20:09 2004 +0000 +++ b/src/lib/data.py Mon Aug 02 11:53:02 2004 +0000 @@ -171,6 +171,7 @@ try: self.get("view/window-width") self.get("file/autoload_file") + self.get("file/autosave") except ConfigError: return gtk.FALSE @@ -279,7 +280,11 @@ def find(self, offset, direction = SEARCH_NEXT): "Search for an entry, starting at the given offset" - iter = offset.copy() + if offset is None: + iter = None + + else: + iter = offset.copy() while 1: @@ -370,12 +375,12 @@ def __cb_file_changed(self, widget, file = None): "Callback for when the file changes" - self.changed = gtk.FALSE - if file is None: self.password = None self.filepassword = None + self.changed = gtk.FALSE + def add_entry(self, parent, entry = None, sibling = None): "Adds an entry" @@ -403,10 +408,8 @@ revelation.widget.TreeStore.clear(self) - self.file = None - self.password = None - self.filepassword = None - self.changed = gtk.FALSE + self.set_file(None, None, None) + self.changed = gtk.FALSE self.emit("cleared") @@ -443,7 +446,7 @@ entries = [] - for iter in iters + for iter in iters: entries.append(self.get_entry(iter)) return entries @@ -480,12 +483,23 @@ def replace_entrystore(self, source): "Replaces the current entrystore data with those of a different entrystore" - self.data.clear() - self.data.import_entrystore(source) + self.clear() + self.import_entrystore(source) + self.set_file(source.file, source.password, source.filepassword) - self.file = source.file - self.password = source.password - self.filepassword = source.filepassword + + def set_file(self, file, password, filepassword = None): + "Sets the current file for the data" + + self.password = password + + if filepassword is not None: + self.filepassword = filepassword + + else: + self.filepassword = password + + self.file = file def set_folder_state(self, iter, open): diff -r a877d43f09876152f64340bf52aaa1ed15101a6b -r b181693cfdc75cbe6814327c31b2a44e488925ff src/lib/datahandler/rvl.py --- a/src/lib/datahandler/rvl.py Thu Jul 29 14:20:09 2004 +0000 +++ b/src/lib/datahandler/rvl.py Mon Aug 02 11:53:02 2004 +0000 @@ -232,17 +232,16 @@ "Checks if the passed data is valid" try: - headerdata = self.__parse_header(data[0:12]) + dataversion, version = self.__parse_header(data[0:12]) + + if dataversion > revelation.DATAVERSION: + raise base.VersionError # ignore version 0 data files (deprecated, remove in future version) except base.FormatError: return - if headerdata[0] > revelation.DATAVERSION: - raise base.VersionError - - def detect_type(self, data): "Checks if the handler can handle the data type" diff -r a877d43f09876152f64340bf52aaa1ed15101a6b -r b181693cfdc75cbe6814327c31b2a44e488925ff src/lib/widget.py --- a/src/lib/widget.py Thu Jul 29 14:20:09 2004 +0000 +++ b/src/lib/widget.py Mon Aug 02 11:53:02 2004 +0000 @@ -205,7 +205,7 @@ items = self.menu.get_children() - if index > len(items): + if index < len(items): return items[index] else: @@ -409,6 +409,26 @@ self.toggle_expanded(iter) self.emit("doubleclick", iter) + # display popup on right-click + if data.button == 3: + path = self.get_path_at_pos(int(data.x), int(data.y)) + + if path is None: + self.unselect_all() + + elif self.selection.iter_is_selected(self.model.get_iter(path[0])) == gtk.FALSE: + self.set_cursor(path[0], path[1], gtk.FALSE) + + # create the menu + menuitems = [] + self.emit("popup", menuitems) + + # (kind of ugly, but it works) + window = self.get_toplevel() + window.popup(menuitems, int(data.x_root), int(data.y_root), data.button, data.get_time()) + + return gtk.TRUE + def __cb_keypress(self, object, data): "Callback for handling key presses" @@ -510,6 +530,7 @@ gobject.signal_new("doubleclick", TreeView, gobject.SIGNAL_ACTION, gobject.TYPE_BOOLEAN, (gobject.TYPE_PYOBJECT, )) +gobject.signal_new("popup", TreeView, gobject.SIGNAL_ACTION, gobject.TYPE_BOOLEAN, (gobject.TYPE_PYOBJECT, )) @@ -795,7 +816,10 @@ class MenuFactory(gtk.ItemFactory): "A factory for menus" - def __init__(self, widget, accelgroup): + def __init__(self, widget, accelgroup = None): + if accelgroup == None: + accelgroup = gtk.AccelGroup() + gtk.ItemFactory.__init__(self, widget, "
", accelgroup) diff -r a877d43f09876152f64340bf52aaa1ed15101a6b -r b181693cfdc75cbe6814327c31b2a44e488925ff src/revelation --- a/src/revelation Thu Jul 29 14:20:09 2004 +0000 +++ b/src/revelation Mon Aug 02 11:53:02 2004 +0000 @@ -2,7 +2,7 @@ # # Revelation 0.3.0 - a password manager for GNOME 2 -# http://oss.wired-networks.net/revelation/ +# http://oss.codepoet.no/revelation/ # $Id$ # # Copyright (c) 2003-2004 Erik Grinaker @@ -48,10 +48,8 @@ self.__init_mainarea() self.__init_states() - self.connect("delete_event", lambda w,d: gtk.TRUE ^ self.quit()) - - # private init methods + # init methods def __init_facilities(self): "Sets up various application facilities" @@ -87,7 +85,7 @@ "Sets up the main application area" self.tree = revelation.ui.Tree(self.data) - self.tree.connect("button_press_event", self.__cb_popup_tree) + self.tree.connect("popup", self.__cb_popup_tree) self.tree.connect("doubleclick", lambda w,d: self.entry_edit()) self.tree.selection.connect("changed", lambda w: self.dataview.display_entry(self.data.get_entry(self.tree.get_active()))) self.tree.selection.connect("changed", self.__cb_state_entry) @@ -159,6 +157,8 @@ "Sets the initial application state" self.set_default_size(self.config.get("view/window-width"), self.config.get("view/window-height")) + self.connect("delete_event", lambda w,d: gtk.TRUE ^ self.quit()) + self.tree.select(None) self.dataview.display_info() @@ -290,54 +290,36 @@ # other, normal callbacks - def __cb_popup_tree(self, widget, data = None): - "Displays a popup-menu for the treeview" - - if data.button != 3: - return - - path = self.tree.get_path_at_pos(int(data.x), int(data.y)) - - if path is None: - self.tree.unselect_all() - - elif self.tree.selection.iter_is_selected(self.data.get_iter(path[0])) == gtk.FALSE: - self.tree.set_cursor(path[0], path[1], gtk.FALSE) + def __cb_popup_tree(self, widget, menuitems): + "Create a popup-menu for the treeview" # create the popup menu iters = self.tree.get_selected() - menuitems = [] + + if len(iters) == 0 or (len(iters) == 1 and self.data.get_entry(iters[0]).type == revelation.entry.ENTRY_FOLDER): + menuitems.append(("/_Add Entry...", None, "Create a new entry", lambda w,d: self.entry_add(), 0, "", revelation.stock.STOCK_ADD)) if len(iters) == 1: - menuitems.append(("/Edit", None, "Edit the selected entry", lambda w,d: self.entry_edit(), 0, "", revelation.stock.STOCK_EDIT)) + menuitems.append(("/_Edit", None, "Edit the selected entry", lambda w,d: self.entry_edit(), 0, "", revelation.stock.STOCK_EDIT)) if len(iters) > 0: - menuitems.append(("/Remove", None, "Remove the selected entry", lambda w,d: self.entry_remove(), 0, "", revelation.stock.STOCK_REMOVE)) - - if len(iters) < 2: - menuitems.append(("/Add Entry...", None, "Create a new entry", lambda w,d: self.entry_add(), 0, "", revelation.stock.STOCK_ADD)) + menuitems.append(("/Re_move", None, "Remove the selected entry", lambda w,d: self.entry_remove(), 0, "", revelation.stock.STOCK_REMOVE)) clipboardmenu = [] if len(iters) > 0: - clipboardmenu.append(("/Cut", "", "Cut the selected entry to the clipboard", lambda w,d: self.clip_cut(), 0, "", gtk.STOCK_CUT)) - clipboardmenu.append(("/Copy", "", "Copy the selected entry to the keyboard", lambda w,d: self.clip_copy(), 0, "", gtk.STOCK_COPY)) + clipboardmenu.append(("/Cu_t", "", "Cut the selected entry to the clipboard", lambda w,d: self.clip_cut(), 0, "", gtk.STOCK_CUT)) + clipboardmenu.append(("/_Copy", "", "Copy the selected entry to the keyboard", lambda w,d: self.clip_copy(), 0, "", gtk.STOCK_COPY)) if len(iters) < 2 and self.clipboard.has_contents(): - clipboardmenu.append(("/Paste", "", "Paste entry from clipboard", lambda w,d: self.clip_paste(), 0, "", gtk.STOCK_PASTE)) + clipboardmenu.append(("/_Paste", "", "Paste entry from clipboard", lambda w,d: self.clip_paste(), 0, "", gtk.STOCK_PASTE)) if len(clipboardmenu) > 0: menuitems.append(("/sep1", None, None, None, 0, "")) menuitems.extend(clipboardmenu) - print data.get_time(), data.button - - self.popup(menuitems, int(data.x_root), int(data.y_root), data.button, data.get_time()) - - return gtk.TRUE - # various private methods @@ -379,7 +361,6 @@ datafile.check_file() dialog = revelation.dialog.PasswordLoad(self, datafile.file) - entrystore = None while 1: @@ -443,7 +424,7 @@ except revelation.CancelError: dialog.destroy() - raise revelation.CancelError + raise else: return entrystore @@ -506,8 +487,8 @@ "Changes the password of the current data file" try: - dialog = revelation.dialog.PasswordChange(self, self.password) - self.password = dialog.run() + dialog = revelation.dialog.PasswordChange(self, self.data.password) + self.data.password = dialog.run() self.__file_autosave() self.statusbar.set_status("Password changed") @@ -531,6 +512,7 @@ iters = self.data.filter_parents(self.tree.get_selected()) self.undoqueue.add_action(revelation.data.UNDO_ACTION_CUT, iters) self.clipboard.cut(self.data, iters) + self.__file_autosave() self.tree.unselect_all() @@ -542,6 +524,7 @@ iters = self.clipboard.paste(self.data, self.tree.get_active()) self.undoqueue.add_action(revelation.data.UNDO_ACTION_PASTE, iters) + self.__file_autosave() self.tree.select(iters[0]) @@ -554,6 +537,7 @@ self.undoqueue.add_action(revelation.data.UNDO_ACTION_ADD, iter) self.__file_autosave() + self.tree.select(iter) self.statusbar.set_status("Added entry '" + entry.name + "'") @@ -579,6 +563,7 @@ newentry = dialog.run() self.data.update_entry(iter, newentry) self.undoqueue.add_action(revelation.data.UNDO_ACTION_EDIT, iter, entry) + self.__file_autosave() self.tree.select(iter) self.statusbar.set_status("Updated entry '" + newentry.name + "'") @@ -685,7 +670,7 @@ def file_lock(self): "Locks the current data file" - if self.password is None: + if self.data.password is None: return iter = self.tree.get_active() @@ -696,7 +681,7 @@ dialog = revelation.dialog.PasswordLock(self) while 1: - if dialog.run() == self.password: + if dialog.run() == self.data.password: break else: @@ -769,9 +754,7 @@ datafile = revelation.io.DataFile(file, revelation.datahandler.Revelation, password) if self.__file_save(datafile) == gtk.TRUE: - self.data.file = file - self.data.password = password - self.data.filepassword = password + self.data.set_file(file, password) self.statusbar.set_status("Data saved to file " + file) return gtk.TRUE @@ -808,17 +791,19 @@ if len(iters) > 0: self.tree.select(iters[0]) + else: self.tree.unselect_all() + self.__file_autosave() self.statusbar.set_status(action.name.capitalize() + " redone") - def run(self, file = None): + def run(self): "Run the application" - if file is not None: - self.file_open(file) + if len(sys.argv) > 1: + self.file_open(os.path.abspath(sys.argv[1])) elif self.config.get("file/autoload") and self.config.get("file/autoload_file") != "": self.file_open(self.config.get("file/autoload_file")) @@ -837,17 +822,15 @@ if len(iters) > 0: self.tree.select(iters[0]) + else: self.tree.unselect_all() + self.__file_autosave() self.statusbar.set_status(action.name.capitalize() + " undone") if __name__ == "__main__": - file = None - if len(sys.argv) > 1: - file = os.path.abspath(sys.argv[1]) + Revelation().run() - Revelation().run(file) -