mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
Merge remote-tracking branch 'origin/GP-4740_ghidra1_CompositeEditorUndoRedo--SQUASHED'
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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)");
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user