diff --git a/gramps2/ChangeLog b/gramps2/ChangeLog index 2ee4c1902..aaf4d46a1 100644 --- a/gramps2/ChangeLog +++ b/gramps2/ChangeLog @@ -1,8 +1,10 @@ 2006-01-12 Richard Taylor - * src/ObjectSelector/_ObjectSelectorWindow.py: initial outline of ObjectSelector - * src/ObjectSelector/_PersonPreviewFrame.py: initial outline of ObjectSelector - * src/ObjectSelector/_PersonSearchCriteriaWidget.py: initial outline of ObjectSelector - + * src/ObjectSelector/_ObjectSelectorWindow.py: initial outline of + ObjectSelector + * src/ObjectSelector/_PersonPreviewFrame.py: initial outline of + ObjectSelector + * src/ObjectSelector/_PersonSearchCriteriaWidget.py: initial + outline of ObjectSelector 2006-01-12 Alex Roitman * src/ViewManager.py: Connect undo handler to the menu item. diff --git a/gramps2/src/GrampsDb/_GrampsBSDDB.py b/gramps2/src/GrampsDb/_GrampsBSDDB.py index 4e8b8c5b2..acc83edae 100644 --- a/gramps2/src/GrampsDb/_GrampsBSDDB.py +++ b/gramps2/src/GrampsDb/_GrampsBSDDB.py @@ -261,7 +261,8 @@ class GrampsBSDDB(GrampsDbBase): db.DB_INIT_MPOOL|db.DB_INIT_LOCK|\ db.DB_INIT_LOG|db.DB_INIT_TXN|db.DB_RECOVER - self.undolog = "%s.log" % name + self.undolog = "%s.undo" % name + self.redolog = "%s.redo" % name env_name = os.path.expanduser(const.bsddbenv_dir) if not os.path.isdir(env_name): os.mkdir(env_name) @@ -375,7 +376,8 @@ class GrampsBSDDB(GrampsDbBase): self.undodb = db.DB() self.undodb.open(self.undolog, db.DB_RECNO, db.DB_CREATE) - + self.redodb = db.DB() + self.redodb.open(self.redolog, db.DB_RECNO, db.DB_CREATE) callback(0.5) self.metadata = self.open_table(self.full_name, "meta", no_txn=True) @@ -664,9 +666,9 @@ class GrampsBSDDB(GrampsDbBase): preserving the change in the passed transaction. """ if not self.readonly: - data = self.reference_map.get(str(main_key),txn=self.txn) + old_data = self.reference_map.get(str(main_key),txn=self.txn) if not transaction.batch: - transaction.add(REFERENCE_KEY,str(key),cPickle.dumps(data)) + transaction.add(REFERENCE_KEY,str(key),old_data,None) transaction.reference_del.append(str(key)) def _add_reference(self,key,data,transaction): @@ -681,7 +683,7 @@ class GrampsBSDDB(GrampsDbBase): if transaction.batch: self.reference_map.put(str(key),data,txn=self.txn) else: - transaction.add(REFERENCE_KEY,str(key),None) + transaction.add(REFERENCE_KEY,str(key),None,data) transaction.reference_add.append(str(key),data) def reindex_reference_map(self): @@ -798,6 +800,15 @@ class GrampsBSDDB(GrampsDbBase): self.metadata = None self.db_is_open = False + def _do_remove_object(self,handle,trans,dmap,key,del_list): + self._delete_primary_from_reference_map(handle,trans) + if not self.readonly: + handle = str(handle) + if not trans.batch: + old_data = dmap.get(handle,txn=self.txn) + trans.add(key,handle,old_data,None) + del_list.append(handle) + def _del_person(self,handle): self.person_map.delete(str(handle),txn=self.txn) @@ -902,11 +913,12 @@ class GrampsBSDDB(GrampsDbBase): old_data = None else: old_data = data_map.get(handle,txn=self.txn) - transaction.add(key,handle,old_data) + new_data = obj.serialize() + transaction.add(key,handle,old_data,new_data) if old_data: - update_list.append((handle,obj.serialize())) + update_list.append((handle,new_data)) else: - add_list.append((handle,obj.serialize())) + add_list.append((handle,new_data)) return old_data def _do_commit(self,add_list,db_map): @@ -1050,17 +1062,24 @@ class GrampsBSDDB(GrampsDbBase): self.txn = None def undo(self): - print "Doing it" + print "Undoing it" self.txn = self.env.txn_begin() GrampsDbBase.undo(self) self.txn.commit() self.txn = None + def redo(self): + print "Redoing it" + self.txn = self.env.txn_begin() + GrampsDbBase.redo(self) + self.txn.commit() + self.txn = None + def undo_reference(self,data,handle): if data == None: self.reference_map.delete(handle,txn=self.txn) else: - self.reference_map.put(handl,data,txn=self.txn) + self.reference_map.put(handle,data,txn=self.txn) def undo_data(self,data,handle,db_map,signal_root): if data == None: diff --git a/gramps2/src/GrampsDb/_GrampsDbBase.py b/gramps2/src/GrampsDb/_GrampsDbBase.py index 595b15f37..b305f7b59 100644 --- a/gramps2/src/GrampsDb/_GrampsDbBase.py +++ b/gramps2/src/GrampsDb/_GrampsDbBase.py @@ -373,11 +373,12 @@ class GrampsDbBase(GrampsDBCallback): old_data = None else: old_data = data_map.get(handle) - transaction.add(key,handle,old_data) + new_data = obj.serialize() + transaction.add(key,handle,old_data,new_data) if old_data: - update_list.append((handle,obj.serialize())) + update_list.append((handle,new_data)) else: - add_list.append((handle,obj.serialize())) + add_list.append((handle,new_data)) return old_data def commit_person(self,person,transaction,change_time=None): @@ -1164,6 +1165,7 @@ class GrampsDbBase(GrampsDBCallback): """ if self.undoindex == -1 or self.readonly: return False + transaction = self.translist[self.undoindex] mapbase = (self.person_map, self.family_map, self.source_map, @@ -1173,18 +1175,53 @@ class GrampsDbBase(GrampsDBCallback): subitems = transaction.get_recnos() subitems.reverse() for record_id in subitems: - (key, handle, data) = transaction.get_record(record_id) + (key,handle,old_data,new_data) = transaction.get_record(record_id) if key == REFERENCE_KEY: - self.undo_reference(data,handle) + self.undo_reference(old_data,handle) else: - self.undo_data(data,handle,mapbase[key],_sigbase[key]) + self.undo_data(old_data,handle,mapbase[key],_sigbase[key]) if self.undo_callback: if self.undoindex == -1: self.undo_callback(None) else: - transaction = self.translist[self.undoindex] - self.undo_callback(_("_Undo %s") % transaction.get_description()) + new_transaction = self.translist[self.undoindex] + self.undo_callback(_("_Undo %s") + % new_transaction.get_description()) + + return True + + def redo(self): + """ + Accesses the last undone transaction, and reverts the data to + the state before the transaction was undone. + """ + if self.undoindex == _UNDO_SIZE or self.readonly: + return False + + self.undoindex +=1 + transaction = self.translist[self.undoindex] + if transaction == None: + return False + + mapbase = (self.person_map, self.family_map, self.source_map, + self.event_map, self.media_map, self.place_map) + + subitems = transaction.get_recnos() + for record_id in subitems: + (key,handle,old_data,new_data) = transaction.get_record(record_id) + if key == REFERENCE_KEY: + self.undo_reference(new_data,handle) + else: + self.undo_data(new_data,handle,mapbase[key],_sigbase[key]) + + if self.undo_callback: + if self.undoindex == _UNDO_SIZE: + self.undo_callback(None) + else: + self.undo_callback(_("_Undo %s") + % transaction.get_description()) + return True def undo_reference(self,data,handle): @@ -1321,16 +1358,16 @@ class GrampsDbBase(GrampsDBCallback): person = self.get_person_from_handle(handle) self.genderStats.uncount_person (person) if not transaction.batch: - transaction.add(PERSON_KEY,handle,person.serialize()) + transaction.add(PERSON_KEY,handle,person.serialize(),None) transaction.person_del.append(str(handle)) def _do_remove_object(self,handle,trans,dmap,key,del_list): - self._delete_primary_from_reference_map(handle,transaction) + self._delete_primary_from_reference_map(handle,trans) if not self.readonly: handle = str(handle) if not trans.batch: old_data = dmap.get(handle) - trans.add(key,handle,old_data) + trans.add(key,handle,old_data,None) del_list.append(handle) def remove_source(self,handle,transaction): @@ -1751,14 +1788,19 @@ class Transaction: """ self.msg = msg - def add(self, type, handle, data): + def add(self, type, handle, old_data, new_data): """ Adds a commit operation to the Transaction. The type is a constant that indicates what type of PrimaryObject is being added. The handle is the object's database handle, and the data is the tuple returned by the object's serialize method. """ - self.last = self.db.append(cPickle.dumps((type,handle,data),1)) + self.last = self.db.append(cPickle.dumps((type, + handle, + old_data, + new_data), + 1) + ) if self.first == None: self.first = self.last diff --git a/gramps2/src/ViewManager.py b/gramps2/src/ViewManager.py index ec2210ccb..e5b86ec25 100644 --- a/gramps2/src/ViewManager.py +++ b/gramps2/src/ViewManager.py @@ -93,6 +93,7 @@ uidefault = ''' + @@ -314,6 +315,7 @@ class ViewManager: ('Export', gtk.STOCK_SAVE_AS, '_Export', "e", None, self.export_data), ('Abandon', gtk.STOCK_REVERT_TO_SAVED, '_Abandon changes and quit'), ('Undo', gtk.STOCK_UNDO, '_Undo', 'z', None, self.undo), + ('Redo', gtk.STOCK_REDO, '_Redo', 'z', None, self.redo), ('CmpMerge', None, '_Compare and merge'), ('FastMerge', None, '_Fast merge'), ('ScratchPad', gtk.STOCK_PASTE, '_ScratchPad', None, None, self.scratchpad), @@ -824,6 +826,9 @@ class ViewManager: def undo(self,obj): self.state.db.undo() + def redo(self,obj): + self.state.db.redo() + def export_data(self,obj): import Exporter Exporter.Exporter(self.state,self.uistate)