Merge remote-tracking branch 'origin/GP-3521_ghidragon_allow_user_to_see_and_pick_older_undos_or_redos--SQUASHED'

This commit is contained in:
Ryan Kurtz 2023-06-14 07:49:31 -04:00
commit d98ae48110
14 changed files with 303 additions and 115 deletions

View file

@ -16,6 +16,7 @@
package ghidra.framework.data;
import java.io.IOException;
import java.util.List;
import db.TerminatedTransactionException;
import ghidra.framework.model.*;
@ -222,14 +223,44 @@ abstract class AbstractTransactionManager {
*/
abstract int getUndoStackDepth();
/**
* Returns true if there is at least one redo transaction to be redone.
* @return true if there is at least one redo transaction to be redone
*/
abstract boolean canRedo();
/**
* Returns true if there is at least one undo transaction to be undone.
* @return true if there is at least one undo transaction to be undone
*/
abstract boolean canUndo();
/**
* Returns the name of the next undo transaction (The most recent change).
* @return the name of the next undo transaction (The most recent change)
*/
abstract String getRedoName();
/**
* Returns the name of the next redo transaction (The most recent undo).
* @return the name of the next redo transaction (The most recent undo)
*/
abstract String getUndoName();
/**
* Returns the names of all undoable transactions in reverse chronological order. In other
* words the transaction at the top of the list must be undone first.
* @return the names of all undoable transactions in reverse chronological order
*/
abstract List<String> getAllUndoNames();
/**
* Returns the names of all redoable transactions in chronological order. In other words
* the transaction at the top of the list must be redone first.
* @return the names of all redoable transactions in chronological order
*/
abstract List<String> getAllRedoNames();
abstract TransactionInfo getCurrentTransactionInfo();
final void redo() throws IOException {

View file

@ -427,6 +427,16 @@ public abstract class DomainObjectAdapterDB extends DomainObjectAdapter
return transactionMgr.getUndoName();
}
@Override
public List<String> getAllUndoNames() {
return transactionMgr.getAllUndoNames();
}
@Override
public List<String> getAllRedoNames() {
return transactionMgr.getAllRedoNames();
}
@Override
public TransactionInfo getCurrentTransactionInfo() {
return transactionMgr.getCurrentTransactionInfo();

View file

@ -121,9 +121,6 @@ class DomainObjectDBTransaction implements TransactionInfo {
return hasDBTransaction;
}
/* (non-Javadoc)
* @see ghidra.framework.data.XTransaction#getID()
*/
@Override
public long getID() {
return id;
@ -148,8 +145,8 @@ class DomainObjectDBTransaction implements TransactionInfo {
throw new IllegalStateException("Transaction not found");
}
if (entry.status != Status.NOT_DONE) {
throw new IllegalStateException("Attempted to end Transaction " + "more that once: " +
entry.description);
throw new IllegalStateException(
"Attempted to end Transaction " + "more that once: " + entry.description);
}
entry.status = commit ? Status.COMMITTED : Status.ABORTED;
if (!commit) {
@ -196,28 +193,20 @@ class DomainObjectDBTransaction implements TransactionInfo {
}
}
/* (non-Javadoc)
* @see ghidra.framework.data.XTransaction#getDescription()
*/
@Override
public String getDescription() {
if (list.isEmpty()) {
return "";
}
String description = "";
for (TransactionEntry entry : list) {
description = entry.description;
String description = entry.description;
if (description != null && description.length() != 0) {
description = domainObject.getDomainFile().getName() + ": " + description;
break;
return description;
}
}
return description;
return "";
}
/* (non-Javadoc)
* @see ghidra.framework.data.XTransaction#getOpenSubTransactions()
*/
@Override
public ArrayList<String> getOpenSubTransactions() {
ArrayList<String> subTxList = new ArrayList<String>();

View file

@ -16,7 +16,7 @@
package ghidra.framework.data;
import java.io.IOException;
import java.util.LinkedList;
import java.util.*;
import ghidra.framework.model.*;
import ghidra.framework.model.TransactionInfo.Status;
@ -27,10 +27,8 @@ import ghidra.util.datastruct.WeakSet;
class DomainObjectTransactionManager extends AbstractTransactionManager {
private LinkedList<DomainObjectDBTransaction> undoList =
new LinkedList<>();
private LinkedList<DomainObjectDBTransaction> redoList =
new LinkedList<>();
private LinkedList<DomainObjectDBTransaction> undoList = new LinkedList<>();
private LinkedList<DomainObjectDBTransaction> redoList = new LinkedList<>();
private WeakSet<TransactionListener> transactionListeners =
WeakDataStructureFactory.createCopyOnWriteWeakSet();
@ -241,6 +239,25 @@ class DomainObjectTransactionManager extends AbstractTransactionManager {
return "";
}
@Override
List<String> getAllUndoNames() {
return getDescriptions(undoList);
}
@Override
List<String> getAllRedoNames() {
return getDescriptions(redoList);
}
private List<String> getDescriptions(List<DomainObjectDBTransaction> list) {
List<String> descriptions = new ArrayList<>();
for (DomainObjectDBTransaction tx : list) {
descriptions.add(tx.getDescription());
}
Collections.reverse(descriptions);
return descriptions;
}
@Override
TransactionInfo getCurrentTransactionInfo() {
return transaction;

View file

@ -16,7 +16,7 @@
package ghidra.framework.data;
import java.io.IOException;
import java.util.LinkedList;
import java.util.*;
import ghidra.framework.model.*;
import ghidra.framework.model.TransactionInfo.Status;
@ -88,8 +88,8 @@ class SynchronizedTransactionManager extends AbstractTransactionManager {
synchronized void removeDomainObject(DomainObjectAdapterDB domainObj) throws LockException {
if (getCurrentTransactionInfo() != null) {
throw new LockException(
"domain object has open transaction: " + getCurrentTransactionInfo().getDescription());
throw new LockException("domain object has open transaction: " +
getCurrentTransactionInfo().getDescription());
}
if (isLocked()) {
throw new LockException("domain object is locked!");
@ -265,6 +265,26 @@ class SynchronizedTransactionManager extends AbstractTransactionManager {
return "";
}
@Override
List<String> getAllUndoNames() {
List<String> descriptions = new ArrayList<>();
for (SynchronizedTransaction tx : undoList) {
descriptions.add(tx.getDescription());
}
Collections.reverse(descriptions);
return descriptions;
}
@Override
List<String> getAllRedoNames() {
List<String> descriptions = new ArrayList<>();
for (SynchronizedTransaction tx : redoList) {
descriptions.add(tx.getDescription());
}
Collections.reverse(descriptions);
return descriptions;
}
@Override
TransactionInfo getCurrentTransactionInfo() {
return transaction;

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,8 +15,8 @@
*/
package ghidra.framework.model;
import java.io.IOException;
import java.util.List;
/**
* Objects that implement Undoable have the ability to "remember" some number
@ -59,14 +58,28 @@ public interface Undoable {
void redo() throws IOException;
/**
* Returns a description of the chanage that would be "undone".
* Returns a description of the change that would be "undone".
* @return a description of the change that would be "undone".
*/
String getUndoName();
public String getUndoName();
/**
* Returns a description of the change that would be "redone".
* @return a description of the change that would be "redone".
*/
String getRedoName();
public String getRedoName();
/**
* Returns a list of the names of all current undo transactions
* @return a list of the names of all current undo transactions
*/
public List<String> getAllUndoNames();
/**
* Returns a list of the names of all current redo transactions
* @return a list of the names of all current redo transactions
*/
public List<String> getAllRedoNames();
/**
* Adds the given transaction listener to this domain object