Merge remote-tracking branch 'origin/GP-4740_ghidra1_CompositeEditorUndoRedo--SQUASHED'

This commit is contained in:
ghidra1
2024-08-20 13:13:26 -04:00
97 changed files with 3861 additions and 3522 deletions

View File

@@ -10,10 +10,6 @@ color.bg.version.tracking.dual.listing.highlight.markup.failed = color.palette.r
color.bg.version.tracking.dual.listing.highlight.markup.no.address = color.palette.lavender
color.bg.version.tracking.dual.listing.highlight.markup.same = color.palette.lightskyblue
color.bg.version.tracking.dual.listing.highlight.markup.conflict = color.palette.gold
color.bg.version.tracking.filter.formatted.field.error = color.palette.lightgray
color.bg.version.tracking.filter.formatted.field.editing = color.bg.filterfield
color.fg.version.tracking.filter.formatted.field.editing = color.fg.filterfield
color.bg.version.tracking.match.table.locked.out = color.palette.aliceblue
color.bg.version.tracking.match.table.markup.status.applied = color.palette.limegreen
@@ -83,7 +79,6 @@ icon.version.tracking.tag.status.deleted = tag_blue_delete.png
icon.version.tracking.tag.status.existing = tag_blue.png
icon.version.tracking.tag.button.undo = undo-apply.png
icon.version.tracking.filter.status.changed = bullet_black.png
icon.version.tracking.filter.status.invalid = no_small.png
icon.version.tracking.filter.status.applied = bullet_green.png

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -29,7 +29,9 @@ import docking.widgets.checkbox.GCheckBox;
import docking.widgets.combobox.GhidraComboBox;
import docking.widgets.label.GDLabel;
import docking.widgets.label.GHtmlLabel;
import docking.widgets.textfield.HexIntegerFormatter;
import docking.widgets.numberformat.HexIntegerFormatter;
import docking.widgets.numberformat.IntegerFormatterFactory;
import docking.widgets.textfield.*;
import generic.theme.GColor;
import ghidra.feature.vt.api.main.VTAssociation;
import ghidra.feature.vt.gui.provider.matchtable.NumberRangeProducer;
@@ -59,8 +61,8 @@ public abstract class AbstractAddressRangeFilter<T> extends AncillaryFilter<T>
private static final Long MAX_ADDRESS_VALUE = Long.MAX_VALUE;
private JComponent component;
private FilterFormattedTextField lowerAddressRangeTextField;
private FilterFormattedTextField upperAddressRangeTextField;
private GFormattedTextField lowerAddressRangeTextField;
private GFormattedTextField upperAddressRangeTextField;
private JComboBox<String> lowerRangeComboBox;
private JComboBox<String> upperRangeComboBox;
@@ -90,14 +92,14 @@ public abstract class AbstractAddressRangeFilter<T> extends AncillaryFilter<T>
enablePanel.add(enableCheckBox, BorderLayout.NORTH);
// begin address field (long input field with hex)
lowerAddressRangeTextField = new FilterFormattedTextField(
lowerAddressRangeTextField = new GFormattedTextField(
new IntegerFormatterFactory(new HexIntegerFormatter(), false), MIN_ADDRESS_VALUE);
lowerAddressRangeTextField.setName("Lower Address Range Text Field"); // for tracking state
lowerAddressRangeTextField.setColumns(15);
lowerAddressRangeTextField.setMinimumSize(lowerAddressRangeTextField.getPreferredSize());
// end address field (long input field with hex)
upperAddressRangeTextField = new FilterFormattedTextField(
upperAddressRangeTextField = new GFormattedTextField(
new IntegerFormatterFactory(new HexIntegerFormatter(), false), MAX_ADDRESS_VALUE);
upperAddressRangeTextField.setName("Upper Address Range Text Field"); // for tracking state
upperAddressRangeTextField.setColumns(15);
@@ -169,17 +171,20 @@ public abstract class AbstractAddressRangeFilter<T> extends AncillaryFilter<T>
}
};
FilterStatusListener notificationListener = status -> fireStatusChanged(status);
TextEntryStatusListener notificationListener = s -> {
FilterEditingStatus status = FilterEditingStatus.getFilterStatus(s);
fireStatusChanged(status);
};
StatusLabel lowerScoreStatusLabel =
new StatusLabel(lowerAddressRangeTextField, MIN_ADDRESS_VALUE);
lowerAddressRangeTextField.addFilterStatusListener(lowerScoreStatusLabel);
lowerAddressRangeTextField.addFilterStatusListener(notificationListener);
lowerAddressRangeTextField.addTextEntryStatusListener(lowerScoreStatusLabel);
lowerAddressRangeTextField.addTextEntryStatusListener(notificationListener);
StatusLabel upperScoreStatusLabel =
new StatusLabel(upperAddressRangeTextField, MAX_ADDRESS_VALUE);
upperAddressRangeTextField.addFilterStatusListener(upperScoreStatusLabel);
upperAddressRangeTextField.addFilterStatusListener(notificationListener);
upperAddressRangeTextField.addTextEntryStatusListener(upperScoreStatusLabel);
upperAddressRangeTextField.addTextEntryStatusListener(notificationListener);
disabledScreen = createDisabledScreen(layeredPane);
@@ -246,7 +251,7 @@ public abstract class AbstractAddressRangeFilter<T> extends AncillaryFilter<T>
component.validate();
}
private JComboBox<String> createComboBox(FilterFormattedTextField field, Long defaultValue,
private JComboBox<String> createComboBox(GFormattedTextField field, Long defaultValue,
String prototypeString) {
GhidraComboBox<String> comboBox = new GhidraComboBox<>(new LimitedHistoryComboBoxModel()) {
// overridden to paint seamlessly with out color changing text field
@@ -287,14 +292,22 @@ public abstract class AbstractAddressRangeFilter<T> extends AncillaryFilter<T>
return component;
}
private FilterEditingStatus getLowerAddressRangeStatus() {
return FilterEditingStatus.getFilterStatus(lowerAddressRangeTextField);
}
private FilterEditingStatus getUpperAddressRangeStatus() {
return FilterEditingStatus.getFilterStatus(upperAddressRangeTextField);
}
@Override
public FilterEditingStatus getFilterStatus() {
if (!isEnabled) {
return FilterEditingStatus.NONE;
}
FilterEditingStatus lowerStatus = lowerAddressRangeTextField.getFilterStatus();
FilterEditingStatus upperStatus = upperAddressRangeTextField.getFilterStatus();
FilterEditingStatus lowerStatus = getLowerAddressRangeStatus();
FilterEditingStatus upperStatus = getUpperAddressRangeStatus();
if (lowerStatus == FilterEditingStatus.ERROR || upperStatus == FilterEditingStatus.ERROR) {
return FilterEditingStatus.ERROR;
@@ -339,8 +352,8 @@ public abstract class AbstractAddressRangeFilter<T> extends AncillaryFilter<T>
return true;
}
if (lowerAddressRangeTextField.getFilterStatus() == FilterEditingStatus.ERROR ||
upperAddressRangeTextField.getFilterStatus() == FilterEditingStatus.ERROR) {
if (getLowerAddressRangeStatus() == FilterEditingStatus.ERROR ||
getUpperAddressRangeStatus() == FilterEditingStatus.ERROR) {
return true; // for an invalid filter state, we let all values through
}
@@ -572,10 +585,10 @@ public abstract class AbstractAddressRangeFilter<T> extends AncillaryFilter<T>
private class FormattedFieldComboBoxEditor implements ComboBoxEditor {
private EventListenerList listeners = new EventListenerList();
private final FilterFormattedTextField textField;
private final GFormattedTextField textField;
private final Object defaultValue;
FormattedFieldComboBoxEditor(FilterFormattedTextField textField) {
FormattedFieldComboBoxEditor(GFormattedTextField textField) {
this.textField = textField;
defaultValue = textField.getValue();
}

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,6 +22,7 @@ import java.util.Set;
import javax.swing.Icon;
import javax.swing.JComponent;
import docking.widgets.textfield.GFormattedTextField;
import generic.theme.GIcon;
import ghidra.framework.options.SaveState;
import ghidra.util.exception.AssertException;
@@ -72,8 +73,6 @@ public abstract class Filter<T> {
public enum FilterEditingStatus {
NONE("", null),
DIRTY("Filter contents have changed, but are not yet applied", new GIcon(
"icon.version.tracking.filter.status.changed")),
ERROR("Filter contents are not valid", new GIcon(
"icon.version.tracking.filter.status.invalid")),
APPLIED("Filter applied", new GIcon("icon.version.tracking.filter.status.applied"));
@@ -93,6 +92,17 @@ public abstract class Filter<T> {
Icon getIcon() {
return icon;
}
public static FilterEditingStatus getFilterStatus(GFormattedTextField textEntryField) {
switch (textEntryField.getTextEntryStatus()) {
case INVALID:
return FilterEditingStatus.ERROR;
case CHANGED:
return FilterEditingStatus.APPLIED;
default:
return FilterEditingStatus.NONE;
}
}
}
/**

View File

@@ -1,219 +0,0 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.feature.vt.gui.filters;
import static ghidra.feature.vt.gui.filters.Filter.FilterEditingStatus.*;
import java.awt.Color;
import java.awt.event.FocusEvent;
import java.text.ParseException;
import java.util.HashSet;
import java.util.Set;
import javax.swing.InputVerifier;
import javax.swing.JFormattedTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors;
import ghidra.feature.vt.gui.filters.Filter.FilterEditingStatus;
import ghidra.util.SystemUtilities;
public class FilterFormattedTextField extends JFormattedTextField {
private static final Color ERROR_BACKGROUND_COLOR =
new GColor("color.bg.version.tracking.filter.formatted.field.error");
private static final Color EDITING_BACKGROUND_COLOR =
new GColor("color.bg.version.tracking.filter.formatted.field.editing");
private static final Color EDITING_FOREGROUND_COLOR =
new GColor("color.fg.version.tracking.filter.formatted.field.editing");
private Set<FilterStatusListener> listeners = new HashSet<>();
private FilterEditingStatus currentStatus = NONE;
private final Object defaultValue;
private final String defaultText;
private boolean isError;
private boolean ignoreFocusEditChanges;
/** A flag to let us know when we can ignore focus updates */
private boolean isProcessingFocusEvent;
public FilterFormattedTextField(AbstractFormatterFactory factory, Object defaultValue) {
super(factory);
setValue(defaultValue);
this.defaultValue = defaultValue;
this.defaultText = getText(); // get the formatted text
this.currentStatus = NONE;
getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
updateText();
}
@Override
public void insertUpdate(DocumentEvent e) {
updateText();
}
@Override
public void changedUpdate(DocumentEvent e) {
updateText();
}
});
addPropertyChangeListener("value", evt -> editingFinished());
update();
}
public void disableFocusEventProcessing() {
ignoreFocusEditChanges = true;
}
@Override
public int getFocusLostBehavior() {
if (ignoreFocusEditChanges) {
return -1; // force us to ignore the focus event
}
return super.getFocusLostBehavior();
}
@Override
protected void processFocusEvent(FocusEvent e) {
isProcessingFocusEvent = true;
super.processFocusEvent(e);
isProcessingFocusEvent = false;
}
public FilterEditingStatus getFilterStatus() {
return currentStatus;
}
public void addFilterStatusListener(FilterStatusListener listener) {
listeners.add(listener);
}
private void filterStatusChanged(FilterEditingStatus status) {
currentStatus = status;
if (listeners == null) {
return; // happens during construction
}
for (FilterStatusListener listener : listeners) {
listener.filterStatusChanged(status);
}
}
private void updateText() {
if (isProcessingFocusEvent) {
return; // ignore transient events
}
InputVerifier verifier = getInputVerifier();
if (verifier != null) {
setIsError(!verifier.verify(this));
}
update();
}
@Override
public void setText(String t) {
if (SystemUtilities.isEqual(getText(), t)) {
return;
}
super.setText(t);
update();
}
public void setIsError(boolean isError) {
// if ( isError && !this.isError ) {
// warn(); // only warn if we were not already in an error situation
// }
this.isError = isError;
update();
}
public void editingFinished() {
update();
}
private boolean hasNonDefaultValue() {
if (defaultText == null) {
return false; // not yet initialized
}
AbstractFormatter formatter = getFormatter();
if (formatter == null) {
return hasNonDefaultText(); // no formatter implies a text only field
}
try {
Object value = formatter.stringToValue(getText());
if (value == null) {
return true; // assume empty string or invalid text
}
return !value.equals(defaultValue);
}
catch (ParseException e) {
return true;
}
}
private boolean hasNonDefaultText() {
return !getText().equals(defaultText);
}
private void update() {
updateStatus();
if (isError) {
setForeground(Colors.FOREGROUND);
setBackground(ERROR_BACKGROUND_COLOR);
}
else if (hasNonDefaultValue()) {
setForeground(EDITING_FOREGROUND_COLOR);
setBackground(EDITING_BACKGROUND_COLOR);
}
else { // default
setForeground(Colors.FOREGROUND);
setBackground(Colors.BACKGROUND);
}
filterStatusChanged(currentStatus);
}
private void updateStatus() {
FilterEditingStatus oldStatus = currentStatus;
if (isError) {
currentStatus = FilterEditingStatus.ERROR;
}
else if (hasNonDefaultValue()) {
currentStatus = APPLIED;
}
else {
currentStatus = NONE;
}
if (oldStatus != currentStatus) {
filterStatusChanged(currentStatus);
}
}
}

View File

@@ -1,45 +0,0 @@
/* ###
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.feature.vt.gui.filters;
import javax.swing.JFormattedTextField;
import javax.swing.JFormattedTextField.AbstractFormatter;
import javax.swing.text.DefaultFormatterFactory;
import docking.widgets.textfield.IntegerFormatter;
public class IntegerFormatterFactory extends DefaultFormatterFactory {
private AbstractFormatter formatter = new IntegerFormatter();
public IntegerFormatterFactory(boolean allowsNegativeInput) {
this(new IntegerFormatter(), allowsNegativeInput);
}
public IntegerFormatterFactory(IntegerFormatter formatter, boolean allowsNegativeInput) {
this.formatter = formatter;
if (allowsNegativeInput) {
formatter.setAllowsInvalid(true);
}
}
@Override
public AbstractFormatter getFormatter(JFormattedTextField tf) {
return formatter;
}
}

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,9 +21,11 @@ import java.awt.event.*;
import javax.swing.*;
import docking.widgets.label.GDLabel;
import docking.widgets.textfield.GFormattedTextField;
import docking.widgets.textfield.TextEntryStatusListener;
import ghidra.feature.vt.gui.filters.Filter.FilterEditingStatus;
public class StatusLabel extends GDLabel implements FilterStatusListener {
public class StatusLabel extends GDLabel implements TextEntryStatusListener {
private final JFormattedTextField textField;
@@ -82,7 +84,8 @@ public class StatusLabel extends GDLabel implements FilterStatusListener {
}
@Override
public void filterStatusChanged(FilterEditingStatus status) {
public void statusChanged(GFormattedTextField textEntryField) {
FilterEditingStatus status = FilterEditingStatus.getFilterStatus(textEntryField);
resetBounds();
setIcon(status.getIcon());
setToolTipText(status.getDescription() + " (click to reset)");

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -26,6 +26,8 @@ import org.apache.commons.lang3.StringUtils;
import docking.widgets.label.GDLabel;
import docking.widgets.numberformat.BoundedRangeDecimalFormatterFactory;
import docking.widgets.textfield.GFormattedTextField;
import docking.widgets.textfield.TextEntryStatusListener;
import ghidra.feature.vt.gui.filters.*;
import ghidra.framework.options.SaveState;
import ghidra.util.layout.HorizontalLayout;
@@ -41,8 +43,8 @@ public abstract class AbstractDoubleRangeFilter<T> extends Filter<T>
private final Double minValue;
private JComponent component;
private FilterFormattedTextField upperBoundField;
private FilterFormattedTextField lowerBoundField;
private GFormattedTextField upperBoundField;
private GFormattedTextField lowerBoundField;
private String filterName;
AbstractDoubleRangeFilter(String filterName, Double minValue, Double maxValue) {
@@ -54,7 +56,7 @@ public abstract class AbstractDoubleRangeFilter<T> extends Filter<T>
}
private void createLowerBoundField() {
lowerBoundField = new FilterFormattedTextField(
lowerBoundField = new GFormattedTextField(
new BoundedRangeDecimalFormatterFactory(maxValue, minValue, FORMAT), minValue);
lowerBoundField.setName("Lower " + filterName + " Filter Field"); // for debugging
lowerBoundField.setColumns(4);
@@ -63,7 +65,7 @@ public abstract class AbstractDoubleRangeFilter<T> extends Filter<T>
}
private void createUpperBoundField() {
upperBoundField = new FilterFormattedTextField(
upperBoundField = new GFormattedTextField(
new BoundedRangeDecimalFormatterFactory(maxValue, minValue, FORMAT), maxValue);
upperBoundField.setName("Upper " + filterName + " Filter Field"); // for debugging
upperBoundField.setColumns(4);
@@ -93,15 +95,18 @@ public abstract class AbstractDoubleRangeFilter<T> extends Filter<T>
panel.add(middleLabel);
panel.add(upperBoundField);
FilterStatusListener notificationListener = status -> fireStatusChanged(status);
TextEntryStatusListener notificationListener = s -> {
FilterEditingStatus status = FilterEditingStatus.getFilterStatus(s);
fireStatusChanged(status);
};
StatusLabel lowerBoundStatusLabel = new StatusLabel(lowerBoundField, minValue);
lowerBoundField.addFilterStatusListener(lowerBoundStatusLabel);
lowerBoundField.addFilterStatusListener(notificationListener);
lowerBoundField.addTextEntryStatusListener(lowerBoundStatusLabel);
lowerBoundField.addTextEntryStatusListener(notificationListener);
StatusLabel upperBoundStatusLabel = new StatusLabel(upperBoundField, maxValue);
upperBoundField.addFilterStatusListener(upperBoundStatusLabel);
upperBoundField.addFilterStatusListener(notificationListener);
upperBoundField.addTextEntryStatusListener(upperBoundStatusLabel);
upperBoundField.addTextEntryStatusListener(notificationListener);
JLayeredPane layeredPane = new JLayeredPane();
layeredPane.add(panel, BASE_COMPONENT_LAYER);
@@ -127,10 +132,18 @@ public abstract class AbstractDoubleRangeFilter<T> extends Filter<T>
return component;
}
private FilterEditingStatus getLowerBoundStatus() {
return FilterEditingStatus.getFilterStatus(lowerBoundField);
}
private FilterEditingStatus getUpperBoundStatus() {
return FilterEditingStatus.getFilterStatus(upperBoundField);
}
@Override
public FilterEditingStatus getFilterStatus() {
FilterEditingStatus lowerStatus = lowerBoundField.getFilterStatus();
FilterEditingStatus upperStatus = upperBoundField.getFilterStatus();
FilterEditingStatus lowerStatus = getLowerBoundStatus();
FilterEditingStatus upperStatus = getUpperBoundStatus();
if (lowerStatus == FilterEditingStatus.ERROR || upperStatus == FilterEditingStatus.ERROR) {
return FilterEditingStatus.ERROR;
@@ -146,8 +159,8 @@ public abstract class AbstractDoubleRangeFilter<T> extends Filter<T>
@Override
public boolean passesFilter(T t) {
if (lowerBoundField.getFilterStatus() == FilterEditingStatus.ERROR ||
upperBoundField.getFilterStatus() == FilterEditingStatus.ERROR) {
if (getLowerBoundStatus() == FilterEditingStatus.ERROR ||
getUpperBoundStatus() == FilterEditingStatus.ERROR) {
return true; // for an invalid filter state, we let all values through
}

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -27,6 +27,8 @@ import javax.swing.border.Border;
import org.apache.commons.lang3.StringUtils;
import docking.widgets.label.GDLabel;
import docking.widgets.numberformat.IntegerFormatterFactory;
import docking.widgets.textfield.GFormattedTextField;
import ghidra.feature.vt.api.main.VTMatch;
import ghidra.feature.vt.gui.filters.*;
import ghidra.framework.options.SaveState;
@@ -39,7 +41,7 @@ public class LengthFilter extends Filter<VTMatch> {
private static final Integer DEFAULT_FILTER_VALUE = 0;
private JComponent component;
private FilterFormattedTextField textField;
private GFormattedTextField textField;
public LengthFilter() {
component = createComponent();
@@ -49,7 +51,7 @@ public class LengthFilter extends Filter<VTMatch> {
final JLabel label = new GDLabel("Length Filter: ");
Integer defaultValue = DEFAULT_FILTER_VALUE;
textField = new FilterFormattedTextField(new IntegerFormatterFactory(false), defaultValue);
textField = new GFormattedTextField(new IntegerFormatterFactory(false), defaultValue);
textField.setName("Length Filter Field"); // for debugging
textField.setInputVerifier(new IntegerInputVerifier());
textField.setHorizontalAlignment(SwingConstants.RIGHT);
@@ -67,8 +69,11 @@ public class LengthFilter extends Filter<VTMatch> {
final JLayeredPane layeredPane = new JLayeredPane();
StatusLabel statusLabel = new StatusLabel(textField, defaultValue);
textField.addFilterStatusListener(statusLabel);
textField.addFilterStatusListener(status -> fireStatusChanged(status));
textField.addTextEntryStatusListener(statusLabel);
textField.addTextEntryStatusListener(s -> {
FilterEditingStatus status = FilterEditingStatus.getFilterStatus(s);
fireStatusChanged(status);
});
layeredPane.add(panel, BASE_COMPONENT_LAYER);
layeredPane.add(statusLabel, HOVER_COMPONENT_LAYER);
layeredPane.setPreferredSize(panel.getPreferredSize());
@@ -91,7 +96,7 @@ public class LengthFilter extends Filter<VTMatch> {
@Override
public FilterEditingStatus getFilterStatus() {
return textField.getFilterStatus();
return FilterEditingStatus.getFilterStatus(textField);
}
@Override

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -28,9 +28,11 @@ import javax.swing.text.DefaultFormatterFactory;
import docking.widgets.label.GDLabel;
import docking.widgets.table.GTable;
import docking.widgets.textfield.GFormattedTextField;
import ghidra.feature.vt.api.main.VTAssociation;
import ghidra.feature.vt.api.main.VTSession;
import ghidra.feature.vt.gui.filters.*;
import ghidra.feature.vt.gui.filters.Filter;
import ghidra.feature.vt.gui.filters.StatusLabel;
import ghidra.feature.vt.gui.plugin.VTController;
import ghidra.framework.options.SaveState;
import ghidra.program.model.address.Address;
@@ -44,7 +46,7 @@ public abstract class AbstractTextFilter<T> extends Filter<T> {
private static final Integer HOVER_COMPONENT_LAYER = 2;
private JComponent component;
private FilterFormattedTextField textField;
private GFormattedTextField textField;
private String defaultValue = "";
protected VTController controller;
protected final GTable table;
@@ -62,7 +64,7 @@ public abstract class AbstractTextFilter<T> extends Filter<T> {
panel.setBorder(BorderFactory.createCompoundBorder(outsideBorder, paddingBorder));
DefaultFormatterFactory factory = new DefaultFormatterFactory(new DefaultFormatter());
textField = new FilterFormattedTextField(factory, defaultValue);
textField = new GFormattedTextField(factory, defaultValue);
textField.setName(filterName + " Field"); // for debugging
textField.setColumns(20);
textField.setMinimumSize(textField.getPreferredSize());
@@ -76,8 +78,11 @@ public abstract class AbstractTextFilter<T> extends Filter<T> {
panel.add(textField, BorderLayout.CENTER);
StatusLabel nameFieldStatusLabel = new StatusLabel(textField, defaultValue);
textField.addFilterStatusListener(nameFieldStatusLabel);
textField.addFilterStatusListener(status -> fireStatusChanged(status));
textField.addTextEntryStatusListener(nameFieldStatusLabel);
textField.addTextEntryStatusListener(s -> {
FilterEditingStatus status = FilterEditingStatus.getFilterStatus(s);
fireStatusChanged(status);
});
final JLayeredPane layeredPane = new JLayeredPane();
layeredPane.add(panel, BASE_COMPONENT_LAYER);
@@ -127,7 +132,7 @@ public abstract class AbstractTextFilter<T> extends Filter<T> {
@Override
public FilterEditingStatus getFilterStatus() {
return textField.getFilterStatus();
return FilterEditingStatus.getFilterStatus(textField);
}
protected String getTextFieldText() {