mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-24 03:09:36 +08:00
Eliminate use of jcalendar. Replaced DateEditor with non-editable
display for Options use.
This commit is contained in:
-277
@@ -1,277 +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.util.bean.opteditor;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import com.toedter.calendar.JCalendar;
|
||||
|
||||
import docking.action.DockingActionIf;
|
||||
import docking.options.editor.*;
|
||||
import docking.widgets.tree.GTree;
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||
import ghidra.framework.options.Options;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.database.ProgramBuilder;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||
import ghidra.test.TestEnv;
|
||||
|
||||
public class DateEditorTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
|
||||
private static final String TEST_CATEGORY_NAME = "Test Editor";
|
||||
private static final String TEST_DATE_OPTION_NAME = "Time Option Name";
|
||||
private TestEnv env;
|
||||
private PluginTool tool;
|
||||
private Program program;
|
||||
private CodeBrowserPlugin plugin;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
program = buildProgram();
|
||||
|
||||
env = new TestEnv();
|
||||
tool = env.showTool(program);
|
||||
tool.addPlugin(CodeBrowserPlugin.class.getName());
|
||||
plugin = env.getPlugin(CodeBrowserPlugin.class);
|
||||
}
|
||||
|
||||
private Program buildProgram() throws Exception {
|
||||
ProgramBuilder builder = new ProgramBuilder("notepad", ProgramBuilder._TOY);
|
||||
builder.createMemory("test1", Long.toHexString(0x1001000), 0x2000);
|
||||
return builder.getProgram();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
env.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEditor() throws Exception {
|
||||
|
||||
Date initialDate = new Date(System.currentTimeMillis());
|
||||
DateEditor dateEditor = addDateProperty(initialDate);
|
||||
|
||||
showProgramOptions();
|
||||
|
||||
OptionsDialog optionsDialog = waitForDialogComponent(OptionsDialog.class);
|
||||
ScrollableOptionsEditor optionsEditor = selectionDateOptionCategory(optionsDialog);
|
||||
Component c = findPairedComponent(optionsEditor, TEST_DATE_OPTION_NAME);
|
||||
assertNotNull(c);
|
||||
|
||||
JTextField optionTextField = findComponent((Container) c, JTextField.class);
|
||||
assertNotNull(optionTextField);
|
||||
String testDateString = dateEditor.format(initialDate);
|
||||
assertEquals(testDateString, getText(optionTextField));
|
||||
|
||||
JDialog dateDialog = lauchDateEditorDialog(c);
|
||||
JCalendar calendar = findComponent(dateDialog, JCalendar.class);
|
||||
assertNotNull("Could not find JCalendar", calendar);
|
||||
|
||||
Calendar cal = calendar.getCalendar();
|
||||
int hours = runSwing(() -> cal.get(Calendar.HOUR_OF_DAY));
|
||||
int minutes = runSwing(() -> cal.get(Calendar.MINUTE));
|
||||
int seconds = runSwing(() -> cal.get(Calendar.SECOND));
|
||||
|
||||
JTextField hoursField = getTextField(dateDialog, "Hours");
|
||||
JTextField minutesField = getTextField(dateDialog, "Minutes");
|
||||
JTextField secondsField = getTextField(dateDialog, "Seconds");
|
||||
|
||||
assertEquals(hours, Integer.parseInt(getText(hoursField)));
|
||||
assertEquals(minutes, Integer.parseInt(getText(minutesField)));
|
||||
assertEquals(seconds, Integer.parseInt(getText(secondsField)));
|
||||
|
||||
JCalendar cd = calendar;
|
||||
Date currentDate = runSwing(() -> cd.getCalendar().getTime());
|
||||
assertDateLabelValue(dateDialog, currentDate);
|
||||
|
||||
// change the time
|
||||
setText(hoursField, "01");
|
||||
setText(minutesField, "21");
|
||||
setText(secondsField, "59");
|
||||
|
||||
Calendar c2 = (Calendar) cal.clone();
|
||||
runSwing(() -> {
|
||||
c2.set(Calendar.HOUR_OF_DAY, 1);
|
||||
c2.set(Calendar.MINUTE, 21);
|
||||
c2.set(Calendar.SECOND, 59);
|
||||
|
||||
cd.setCalendar(c2);
|
||||
});
|
||||
|
||||
Date newDate = runSwing(() -> c2.getTime());
|
||||
|
||||
pressOk(dateDialog);
|
||||
|
||||
// make sure the text field was updated
|
||||
testDateString = dateEditor.format(newDate);
|
||||
assertEquals(testDateString, getText(optionTextField));
|
||||
|
||||
pressApply(optionsDialog);
|
||||
|
||||
// make sure the property changed
|
||||
Options plist = program.getOptions(TEST_CATEGORY_NAME);
|
||||
Date actualDate = plist.getDate(TEST_DATE_OPTION_NAME, (Date) null);
|
||||
assertEquals(newDate, actualDate);
|
||||
|
||||
closeAllWindowsAndFrames();
|
||||
}
|
||||
|
||||
private void assertDateLabelValue(Container c, Date date) {
|
||||
|
||||
JLabel dateLabel = (JLabel) findComponentByName(c, "DateString");
|
||||
assertNotNull(dateLabel);
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("MMM dd, yyyy ");
|
||||
assertEquals(formatter.format(date), runSwing(() -> dateLabel.getText()));
|
||||
}
|
||||
|
||||
private JTextField getTextField(Container c, String name) {
|
||||
JTextField tf = (JTextField) findComponentByName(c, name);
|
||||
assertNotNull(tf);
|
||||
return tf;
|
||||
}
|
||||
|
||||
private ScrollableOptionsEditor selectionDateOptionCategory(OptionsDialog optionsDialog)
|
||||
throws Exception {
|
||||
|
||||
OptionsPanel optionsPanel = (OptionsPanel) getInstanceField("panel", optionsDialog);
|
||||
Container pane = optionsDialog.getComponent();
|
||||
GTree tree = findComponent(pane, GTree.class);
|
||||
|
||||
waitForTree(tree);
|
||||
|
||||
GTreeNode testNode = getGTreeNode(tree.getRootNode(), TEST_CATEGORY_NAME);
|
||||
selectNode(testNode);
|
||||
ScrollableOptionsEditor p =
|
||||
(ScrollableOptionsEditor) getEditorPanel(optionsPanel, testNode);
|
||||
assertNotNull(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
private void pressApply(OptionsDialog optionsDialog) {
|
||||
JButton applyButton = findButtonByText(optionsDialog.getComponent(), "Apply");
|
||||
pressButton(applyButton);
|
||||
waitForSwing();
|
||||
}
|
||||
|
||||
private void pressOk(JDialog dateDialog) {
|
||||
|
||||
JButton okButton = findButtonByText(dateDialog.getContentPane(), "OK");
|
||||
assertNotNull(okButton);
|
||||
pressButton(okButton);
|
||||
waitForSwing();
|
||||
}
|
||||
|
||||
private JDialog lauchDateEditorDialog(Component c) {
|
||||
JButton button = findButtonByIcon((Container) c, ButtonPanelFactory.BROWSE_ICON);
|
||||
assertNotNull(button);
|
||||
pressButton(button, false);
|
||||
waitForSwing();
|
||||
|
||||
JDialog dateDialog = waitForJDialog("Edit Date");
|
||||
assertNotNull(dateDialog);
|
||||
return dateDialog;
|
||||
}
|
||||
|
||||
private void showProgramOptions() {
|
||||
// TODO change to getAction("Program Options")
|
||||
Set<DockingActionIf> list = tool.getAllActions();
|
||||
for (DockingActionIf action : list) {
|
||||
if (action.getName().equals("Program Options")) {
|
||||
performAction(action, plugin.getProvider(), false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
waitForSwing();
|
||||
}
|
||||
|
||||
private Object getEditorPanel(OptionsPanel optionsPanel, Object testNode) {
|
||||
Map<?, ?> map = (Map<?, ?>) getInstanceField("editorMap", optionsPanel);
|
||||
return map.get(testNode);
|
||||
}
|
||||
|
||||
private void selectNode(GTreeNode node) throws Exception {
|
||||
TreePath path = node.getTreePath();
|
||||
GTree tree = node.getTree();
|
||||
tree.setSelectionPath(path);
|
||||
waitForTree(tree);
|
||||
}
|
||||
|
||||
private GTreeNode getGTreeNode(GTreeNode parent, String nodeName) throws Exception {
|
||||
|
||||
for (int i = 0; i < parent.getChildCount(); i++) {
|
||||
GTreeNode node = parent.getChild(i);
|
||||
if (node.getName().equals(nodeName)) {
|
||||
return node;
|
||||
}
|
||||
GTreeNode foundNode = getGTreeNode(node, nodeName);
|
||||
if (foundNode != null) {
|
||||
return foundNode;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private DateEditor addDateProperty(Date date) {
|
||||
Options list = program.getOptions(TEST_CATEGORY_NAME);
|
||||
list.registerOption(TEST_DATE_OPTION_NAME, new Date(0), null, "Test for the DateEditor");
|
||||
|
||||
int transactionID = program.startTransaction("My Test");
|
||||
try {
|
||||
list.setDate(TEST_DATE_OPTION_NAME, date);
|
||||
}
|
||||
finally {
|
||||
program.endTransaction(transactionID, true);
|
||||
}
|
||||
|
||||
return (DateEditor) runSwing(() -> list.getPropertyEditor(TEST_DATE_OPTION_NAME));
|
||||
}
|
||||
|
||||
private Component findPairedComponent(Container container, String labelText) {
|
||||
Component[] c = container.getComponents();
|
||||
for (int i = 0; i < c.length; i++) {
|
||||
if (c[i] instanceof JLabel) {
|
||||
if (((JLabel) c[i]).getText().equals(labelText)) {
|
||||
return c[i + 1];
|
||||
}
|
||||
}
|
||||
if (c[i] instanceof Container) {
|
||||
Component comp = findPairedComponent((Container) c[i], labelText);
|
||||
if (comp != null) {
|
||||
return comp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +1,2 @@
|
||||
MODULE FILE LICENSE: lib/timingframework-1.0.jar BSD
|
||||
MODULE FILE LICENSE: lib/jcalendar-1.4.jar LGPL 2.1
|
||||
MODULE FILE LICENSE: lib/javahelp-2.0.05.jar GPL 2 With Classpath Exception
|
||||
|
||||
@@ -9,8 +9,6 @@ eclipse.project.name = 'Framework Docking'
|
||||
dependencies {
|
||||
compile project(':Generic')
|
||||
compile 'net.java.dev.timingframework:timingframework:1.0'
|
||||
compile 'com.toedter:jcalendar:1.4'
|
||||
|
||||
|
||||
// Only include this debug version of the jh library if necessary.
|
||||
//compile name:'jh2.with.debug'
|
||||
|
||||
@@ -1,302 +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 docking.options.editor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Toolkit;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.text.*;
|
||||
|
||||
import com.toedter.calendar.JCalendar;
|
||||
|
||||
import docking.widgets.label.GDLabel;
|
||||
import docking.widgets.label.GLabel;
|
||||
import ghidra.util.layout.HorizontalLayout;
|
||||
|
||||
/**
|
||||
* A simple set of label and text fields to show the current time and allow for editing
|
||||
*/
|
||||
class Clock extends JPanel implements CaretListener {
|
||||
|
||||
private JLabel dateLabel = new GDLabel("Apr 18, 2006");
|
||||
private JTextField hoursField;
|
||||
private JTextField minutesField;
|
||||
private JTextField secondsField;
|
||||
private SimpleDateFormat formatter;
|
||||
private DocumentListener docListener;
|
||||
private boolean isEditing;
|
||||
private JTextField currentEditField;
|
||||
|
||||
private int min;
|
||||
private int max;
|
||||
private int value;
|
||||
private Color defaultBackgroundColor;
|
||||
private static Color CURRENT_BACKGROUND_COLOR = new Color(204, 204, 255);
|
||||
|
||||
private JCalendar jCalendar;
|
||||
|
||||
/**
|
||||
* Construct a new Clock.
|
||||
* @param calendar JCalendar component that has the Calendar object being edited.
|
||||
*/
|
||||
Clock(JCalendar calendar) {
|
||||
super(new HorizontalLayout(1));
|
||||
this.jCalendar = calendar;
|
||||
setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
|
||||
create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void caretUpdate(CaretEvent e) {
|
||||
|
||||
JTextField tf = (JTextField) e.getSource();
|
||||
Document doc = tf.getDocument();
|
||||
max = 59;
|
||||
if (hoursField.getDocument() == doc) {
|
||||
max = 23;
|
||||
currentEditField = hoursField;
|
||||
updateColors(minutesField);
|
||||
updateColors(secondsField);
|
||||
}
|
||||
else if (minutesField.getDocument() == doc) {
|
||||
currentEditField = minutesField;
|
||||
updateColors(hoursField);
|
||||
updateColors(secondsField);
|
||||
}
|
||||
else {
|
||||
currentEditField = secondsField;
|
||||
updateColors(hoursField);
|
||||
updateColors(minutesField);
|
||||
}
|
||||
currentEditField.setBackground(CURRENT_BACKGROUND_COLOR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the text fields that show the time.
|
||||
*/
|
||||
void update(Date date) {
|
||||
if (isEditing) {
|
||||
return;
|
||||
}
|
||||
removeDocumentListeners();
|
||||
try {
|
||||
String dateStr = formatter.format(date);
|
||||
|
||||
dateLabel.setText(getDate(dateStr) + " ");
|
||||
hoursField.setText(getHours(dateStr));
|
||||
minutesField.setText(getMinutes(dateStr));
|
||||
secondsField.setText(getSeconds(dateStr));
|
||||
}
|
||||
finally {
|
||||
addDocumentListeners();
|
||||
}
|
||||
if (currentEditField != null) {
|
||||
setValue(Integer.parseInt(currentEditField.getText()), false);
|
||||
}
|
||||
}
|
||||
|
||||
private void create() {
|
||||
hoursField = new JTextField(2);
|
||||
minutesField = new JTextField(2);
|
||||
secondsField = new JTextField(2);
|
||||
|
||||
hoursField.addCaretListener(this);
|
||||
minutesField.addCaretListener(this);
|
||||
secondsField.addCaretListener(this);
|
||||
|
||||
// junit access
|
||||
hoursField.setName("Hours");
|
||||
minutesField.setName("Minutes");
|
||||
secondsField.setName("Seconds");
|
||||
dateLabel.setName("DateString");
|
||||
|
||||
min = 0;
|
||||
max = 60;
|
||||
value = 0;
|
||||
|
||||
add(dateLabel);
|
||||
add(hoursField);
|
||||
add(new GLabel(":"));
|
||||
add(minutesField);
|
||||
add(new GLabel(":"));
|
||||
add(secondsField);
|
||||
|
||||
formatter = new SimpleDateFormat("HH:mm:ss MMM dd, yyyy");
|
||||
hoursField.setDocument(new TimeDocument(true));
|
||||
minutesField.setDocument(new TimeDocument(false));
|
||||
secondsField.setDocument(new TimeDocument(false));
|
||||
Calendar cal = Calendar.getInstance();
|
||||
Date date = cal.getTime();
|
||||
update(date);
|
||||
|
||||
docListener = new DocumentListener() {
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
checkInput(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
checkInput(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
checkInput(e);
|
||||
}
|
||||
|
||||
};
|
||||
addDocumentListeners();
|
||||
defaultBackgroundColor = hoursField.getBackground();
|
||||
}
|
||||
|
||||
private void addDocumentListeners() {
|
||||
hoursField.getDocument().addDocumentListener(docListener);
|
||||
minutesField.getDocument().addDocumentListener(docListener);
|
||||
secondsField.getDocument().addDocumentListener(docListener);
|
||||
}
|
||||
|
||||
private void removeDocumentListeners() {
|
||||
hoursField.getDocument().removeDocumentListener(docListener);
|
||||
minutesField.getDocument().removeDocumentListener(docListener);
|
||||
secondsField.getDocument().removeDocumentListener(docListener);
|
||||
|
||||
}
|
||||
|
||||
private void checkInput(DocumentEvent e) {
|
||||
isEditing = true;
|
||||
Calendar cal = jCalendar.getCalendar();
|
||||
try {
|
||||
int hourValue = Integer.parseInt(hoursField.getText());
|
||||
int minutesValue = Integer.parseInt(minutesField.getText());
|
||||
int secondsValue = Integer.parseInt(secondsField.getText());
|
||||
if (hourValue >= 0 && hourValue <= 23 && minutesValue >= 0 && minutesValue <= 59 &&
|
||||
secondsValue >= 0 && secondsValue <= 59) {
|
||||
cal.set(Calendar.HOUR_OF_DAY, hourValue);
|
||||
cal.set(Calendar.MINUTE, minutesValue);
|
||||
cal.set(Calendar.SECOND, secondsValue);
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException exc) {
|
||||
// this can happen for the empty string
|
||||
}
|
||||
finally {
|
||||
isEditing = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateColors(JTextField field) {
|
||||
field.setBackground(defaultBackgroundColor);
|
||||
}
|
||||
|
||||
private void setValue(int newValue, boolean updateTextField) {
|
||||
|
||||
if (newValue < min) {
|
||||
value = min;
|
||||
}
|
||||
else if (newValue > max) {
|
||||
value = max;
|
||||
}
|
||||
else {
|
||||
value = newValue;
|
||||
}
|
||||
|
||||
if (updateTextField) {
|
||||
String str = Integer.toString(value);
|
||||
if (str.length() < 2) {
|
||||
str = "0" + str;
|
||||
}
|
||||
currentEditField.setText(str);
|
||||
}
|
||||
}
|
||||
|
||||
private String getHours(String dateStr) {
|
||||
int pos = dateStr.indexOf(":");
|
||||
return dateStr.substring(0, pos);
|
||||
}
|
||||
|
||||
private String getMinutes(String dateStr) {
|
||||
return dateStr.substring(3, 5);
|
||||
}
|
||||
|
||||
private String getSeconds(String dateStr) {
|
||||
return dateStr.substring(6, 8);
|
||||
}
|
||||
|
||||
private String getDate(String dateStr) {
|
||||
int pos = dateStr.indexOf(" ");
|
||||
return dateStr.substring(pos + 1);
|
||||
}
|
||||
|
||||
private class TimeDocument extends PlainDocument {
|
||||
|
||||
private boolean isHours;
|
||||
|
||||
TimeDocument(boolean isHours) {
|
||||
super();
|
||||
this.isHours = isHours;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
|
||||
char[] source = str.toCharArray();
|
||||
char[] result = new char[source.length];
|
||||
int j = 0;
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
if (Character.isDigit(source[i]) && isValidDigit(source[i])) {
|
||||
result[j++] = source[i];
|
||||
}
|
||||
else {
|
||||
Toolkit.getDefaultToolkit().beep();
|
||||
}
|
||||
String s = this.getText(0, getLength());
|
||||
try {
|
||||
if (s.length() > 0) {
|
||||
if (offs == 0) {
|
||||
s = str + s;
|
||||
}
|
||||
else {
|
||||
s = s + str;
|
||||
}
|
||||
int numericValue = Integer.parseInt(s);
|
||||
if (s.length() > 2 ||
|
||||
(isHours && (numericValue < 0 || numericValue > 23)) ||
|
||||
(!isHours && (numericValue < 0 || numericValue >= 60))) {
|
||||
Toolkit.getDefaultToolkit().beep();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
Toolkit.getDefaultToolkit().beep();
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.insertString(offs, new String(result, 0, j), a);
|
||||
}
|
||||
|
||||
private boolean isValidDigit(char c) {
|
||||
return c >= 0x30 && c <= 0x39;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,23 +15,15 @@
|
||||
*/
|
||||
package docking.options.editor;
|
||||
|
||||
import java.awt.*;
|
||||
import java.beans.*;
|
||||
import java.awt.Component;
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.text.*;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import com.toedter.calendar.JCalendar;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.DockingWindowManager;
|
||||
|
||||
/**
|
||||
* Editor for date and time; creates a text field for the string version of the date, and
|
||||
* a browse button to pop up the editor panel that contains a JCalendar to edit the date,
|
||||
* and a separate component to edit the time.
|
||||
* Non-editable Editor for date and time; creates a text field for the string version of the date.
|
||||
*/
|
||||
public class DateEditor extends PropertyEditorSupport {
|
||||
|
||||
@@ -40,9 +32,7 @@ public class DateEditor extends PropertyEditorSupport {
|
||||
private final static int NUMBER_OF_COLUMNS = 20;
|
||||
|
||||
private Date date;
|
||||
private CalendarPanel calendarPanel;
|
||||
private JTextField textField;
|
||||
private EditDateDialog dialog;
|
||||
private DateFormat dateFormat = DEFAULT_DATE_FORMAT;
|
||||
|
||||
public void setDateFormat(DateFormat format) {
|
||||
@@ -81,10 +71,6 @@ public class DateEditor extends PropertyEditorSupport {
|
||||
|
||||
this.date = (Date) value;
|
||||
|
||||
if (calendarPanel != null) {
|
||||
calendarPanel.setDate(date);
|
||||
}
|
||||
|
||||
if (textField != null) {
|
||||
textField.setText(format(date));
|
||||
}
|
||||
@@ -101,19 +87,6 @@ public class DateEditor extends PropertyEditorSupport {
|
||||
}
|
||||
}
|
||||
|
||||
private void displayCalendarEditor(Component parent) {
|
||||
if (calendarPanel == null) {
|
||||
calendarPanel = new CalendarPanel();
|
||||
}
|
||||
if (date != null) {
|
||||
calendarPanel.setDate(date);
|
||||
}
|
||||
if (dialog == null) {
|
||||
dialog = new EditDateDialog(parent);
|
||||
}
|
||||
DockingWindowManager.showDialog(parent, dialog);
|
||||
}
|
||||
|
||||
private class DatePanel extends JPanel {
|
||||
private JButton browseButton;
|
||||
|
||||
@@ -123,101 +96,9 @@ public class DateEditor extends PropertyEditorSupport {
|
||||
textField = new JTextField(NUMBER_OF_COLUMNS);
|
||||
textField.setText(date != null ? format(date) : "");
|
||||
textField.setEditable(false);
|
||||
browseButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE);
|
||||
Font f = browseButton.getFont();
|
||||
f = new Font(f.getName(), Font.BOLD, f.getSize());
|
||||
browseButton.setFont(f);
|
||||
|
||||
add(textField);
|
||||
add(Box.createHorizontalStrut(5));
|
||||
add(browseButton);
|
||||
setBorder(BorderFactory.createEmptyBorder());
|
||||
|
||||
browseButton.addActionListener(e -> displayCalendarEditor(browseButton));
|
||||
}
|
||||
}
|
||||
|
||||
private class CalendarPanel extends JPanel implements PropertyChangeListener {
|
||||
private JCalendar jcal;
|
||||
private Clock clock;
|
||||
|
||||
// this formatter is just used for parsing dates for input into JCalendar
|
||||
private SimpleDateFormat formatter;
|
||||
|
||||
CalendarPanel() {
|
||||
super(new BorderLayout(0, 5));
|
||||
setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
|
||||
jcal = new JCalendar();
|
||||
jcal.addPropertyChangeListener(this);
|
||||
clock = new Clock(jcal);
|
||||
add(jcal, BorderLayout.CENTER);
|
||||
add(clock, BorderLayout.SOUTH);
|
||||
formatter = new SimpleDateFormat("MM dd yyyy");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
String propertyName = evt.getPropertyName();
|
||||
if (propertyName == null || propertyName.equals("calendar")) {
|
||||
Calendar newCal = (Calendar) evt.getNewValue();
|
||||
Date newDate = newCal.getTime();
|
||||
clock.update(newDate);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return super.getPreferredSize();
|
||||
}
|
||||
|
||||
void setDate(Date date) {
|
||||
Calendar calendar = jcal.getCalendar();
|
||||
Calendar c = (Calendar) calendar.clone();
|
||||
|
||||
//need the month,day, year from the date
|
||||
String dateString = formatter.format(date);
|
||||
|
||||
int month = Integer.parseInt(dateString.substring(0, 2));
|
||||
int day = Integer.parseInt(dateString.substring(3, 5));
|
||||
int year = Integer.parseInt(dateString.substring(6));
|
||||
|
||||
c.set(Calendar.MONTH, month);
|
||||
c.set(Calendar.DAY_OF_WEEK, day);
|
||||
c.set(Calendar.YEAR, year);
|
||||
c.setTime(date);
|
||||
jcal.setCalendar(c);
|
||||
|
||||
clock.update(date);
|
||||
}
|
||||
}
|
||||
|
||||
private class EditDateDialog extends DialogComponentProvider {
|
||||
|
||||
EditDateDialog(Component parent) {
|
||||
super("Edit Date", true);
|
||||
JPanel dialogPanel = new JPanel();
|
||||
dialogPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
|
||||
dialogPanel.setLayout(new BorderLayout());
|
||||
dialogPanel.add(calendarPanel, BorderLayout.CENTER);
|
||||
addWorkPanel(dialogPanel);
|
||||
addOKButton();
|
||||
addCancelButton();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets called when the user clicks on the OK Action for the dialog.
|
||||
*/
|
||||
@Override
|
||||
protected void okCallback() {
|
||||
Date newDate = calendarPanel.jcal.getCalendar().getTime();
|
||||
DateEditor.this.setValue(newDate);
|
||||
DateEditor.this.firePropertyChange();
|
||||
close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cancelCallback() {
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ public class EditorState implements PropertyChangeListener {
|
||||
private Object originalValue;
|
||||
private Object currentValue;
|
||||
private PropertyEditor editor;
|
||||
private Set<PropertyChangeListener> listeners = new HashSet<PropertyChangeListener>();
|
||||
private Set<PropertyChangeListener> listeners = new HashSet<>();
|
||||
private Options options;
|
||||
private String name;
|
||||
|
||||
@@ -37,10 +37,12 @@ public class EditorState implements PropertyChangeListener {
|
||||
this.currentValue = options.getObject(name, null);
|
||||
this.originalValue = currentValue;
|
||||
this.editor = options.getPropertyEditor(name);
|
||||
editor.setValue(currentValue);
|
||||
if (editor != null) {
|
||||
editor.setValue(currentValue);
|
||||
|
||||
editor.removePropertyChangeListener(this); // don't repeatedly add editors
|
||||
editor.addPropertyChangeListener(this);
|
||||
editor.removePropertyChangeListener(this); // don't repeatedly add editors
|
||||
editor.addPropertyChangeListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
void addListener(PropertyChangeListener listener) {
|
||||
@@ -143,9 +145,8 @@ public class EditorState implements PropertyChangeListener {
|
||||
}
|
||||
|
||||
editor.removePropertyChangeListener(this);
|
||||
editor =
|
||||
new ErrorPropertyEditor("Ghidra does not know how to use PropertyEditor: " +
|
||||
editor.getClass().getName(), null);
|
||||
editor = new ErrorPropertyEditor(
|
||||
"Ghidra does not know how to use PropertyEditor: " + editor.getClass().getName(), null);
|
||||
return editor.getCustomEditor();
|
||||
}
|
||||
|
||||
|
||||
@@ -180,13 +180,6 @@ task assembleDistribution (type: Copy) {
|
||||
include "Icons/**"
|
||||
include "licenses/**"
|
||||
into "GPL"
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// LGPL SOURCE INCLUSION
|
||||
//////////////////////////////
|
||||
from ("${rootProject.ext.BIN_REPO}/ExternalLibraries/libsSrc/jcalendar-1.3.3.zip" ) {
|
||||
into "GPL/librarySourceForLGPL"
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user