mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-22 20:22:44 +00:00
Merge remote-tracking branch 'origin/GP-4232-dragonmacher-option-error-on-undo'
This commit is contained in:
commit
22844881cc
@ -15,16 +15,14 @@
|
||||
*/
|
||||
package ghidra.framework.options;
|
||||
|
||||
// Support for a PropertyEditor that uses text.
|
||||
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.beans.*;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
import javax.swing.JCheckBox;
|
||||
|
||||
/**
|
||||
* An implementation of PropertyComponent that is represented as a text field.
|
||||
* A basic editor for booleans.
|
||||
*/
|
||||
public class PropertyBoolean extends JCheckBox implements ItemListener {
|
||||
|
||||
@ -32,46 +30,32 @@ public class PropertyBoolean extends JCheckBox implements ItemListener {
|
||||
private boolean notifyEditorOfChanges = true;
|
||||
|
||||
/**
|
||||
* Constructor new PropertyText.
|
||||
* @param pe bean property editor that is used to get the value
|
||||
* to show in the text field
|
||||
* Constructor
|
||||
* @param pe bean property editor that is used to get the value to show in the text field
|
||||
*/
|
||||
public PropertyBoolean(PropertyEditor pe) {
|
||||
super();
|
||||
setSelected((Boolean) pe.getValue());
|
||||
|
||||
editor = pe;
|
||||
setSelected((Boolean) pe.getValue());
|
||||
addItemListener(this);
|
||||
|
||||
editor.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
Object value = editor.getValue();
|
||||
if ((value instanceof Boolean) && !value.equals(getText())) {
|
||||
notifyEditorOfChanges = false;
|
||||
try {
|
||||
setSelected((Boolean) value);
|
||||
}
|
||||
finally {
|
||||
notifyEditorOfChanges = true;
|
||||
}
|
||||
editor.addPropertyChangeListener(evt -> {
|
||||
Object value = editor.getValue();
|
||||
if ((value instanceof Boolean) && !value.equals(getText())) {
|
||||
notifyEditorOfChanges = false;
|
||||
try {
|
||||
setSelected((Boolean) value);
|
||||
}
|
||||
finally {
|
||||
notifyEditorOfChanges = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Change listener methods.
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (notifyEditorOfChanges) {
|
||||
try {
|
||||
editor.setValue(isSelected() ? Boolean.TRUE : Boolean.FALSE);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// Quietly ignore.
|
||||
}
|
||||
editor.setValue(isSelected() ? Boolean.TRUE : Boolean.FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package ghidra.framework.data;
|
||||
import java.beans.PropertyEditor;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import db.*;
|
||||
import ghidra.framework.options.*;
|
||||
@ -173,9 +174,18 @@ class OptionsDB extends AbstractOptions {
|
||||
}
|
||||
|
||||
synchronized void clearCache() {
|
||||
for (Option option : valueMap.values()) {
|
||||
DBOption dbOption = (DBOption) option;
|
||||
|
||||
Set<Entry<String, Option>> entries = valueMap.entrySet();
|
||||
Iterator<Entry<String, Option>> it = entries.iterator();
|
||||
while (it.hasNext()) {
|
||||
Entry<String, Option> entry = it.next();
|
||||
DBOption dbOption = (DBOption) entry.getValue();
|
||||
dbOption.clearCache();
|
||||
|
||||
// remove any options that have disappeared during an undo operation
|
||||
if (!dbOption.isValid()) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,6 +205,7 @@ class OptionsDB extends AbstractOptions {
|
||||
catch (IOException e) {
|
||||
domainObj.dbError(e);
|
||||
}
|
||||
|
||||
List<String> optionNames = new ArrayList<>(names);
|
||||
Collections.sort(optionNames);
|
||||
return optionNames;
|
||||
@ -256,13 +267,32 @@ class OptionsDB extends AbstractOptions {
|
||||
private Object value = null;
|
||||
private boolean isCached = false;
|
||||
|
||||
// Once an option has its value set, it becomes 'registered'. This seems conceptually
|
||||
// more like a 'has been used' concept, but it is the way things are currently coded. See
|
||||
// Option.setCurrentValue(). This class is special in that undo/redo operations may cause
|
||||
// option values to come and go from the database. If we leave an option around that has
|
||||
// been removed, it causes errors in the option UI when the value cannot be read. We use
|
||||
// this flag to know when an option was never registered. In that case, if the db record
|
||||
// goes away, then we will remove this options when our cache is cleared.
|
||||
private boolean isRegisteredOriginally;
|
||||
|
||||
protected DBOption(String name, OptionType type, String description, HelpLocation help,
|
||||
Object defaultValue, boolean isRegistered, PropertyEditor editor) {
|
||||
super(name, type, description, help, defaultValue, isRegistered, editor);
|
||||
|
||||
isRegisteredOriginally = isRegistered;
|
||||
getCurrentValue(); // initialize our defaults
|
||||
}
|
||||
|
||||
boolean isValid() {
|
||||
// all options registered by clients should stick around (see note above)
|
||||
if (isRegisteredOriginally) {
|
||||
return true;
|
||||
}
|
||||
DBRecord rec = getPropertyRecord(getName());
|
||||
return rec != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCurrentValue() {
|
||||
if (!isCached) {
|
||||
@ -280,7 +310,8 @@ class OptionsDB extends AbstractOptions {
|
||||
value = optionType.convertStringToObject(rec.getString(VALUE_COL));
|
||||
}
|
||||
else {
|
||||
Msg.info(this, "The type for '" + this.getName() + "' has changed! Using default value.");
|
||||
Msg.info(this, "The type for '" + this.getName() +
|
||||
"' has changed! Using default value.");
|
||||
value = getDefaultValue();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user