summaryrefslogtreecommitdiff
path: root/enigma-swing
diff options
context:
space:
mode:
Diffstat (limited to 'enigma-swing')
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/panels/EditorPanel.java43
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/panels/IdentifierPanel.java29
2 files changed, 48 insertions, 24 deletions
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/EditorPanel.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/EditorPanel.java
index 92d1bd7f..377f63c6 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/EditorPanel.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/EditorPanel.java
@@ -1,11 +1,13 @@
1package cuchaz.enigma.gui.panels; 1package cuchaz.enigma.gui.panels;
2 2
3import java.awt.AWTKeyStroke;
3import java.awt.Color; 4import java.awt.Color;
4import java.awt.Component; 5import java.awt.Component;
5import java.awt.Font; 6import java.awt.Font;
6import java.awt.GridBagConstraints; 7import java.awt.GridBagConstraints;
7import java.awt.GridBagLayout; 8import java.awt.GridBagLayout;
8import java.awt.GridLayout; 9import java.awt.GridLayout;
10import java.awt.KeyboardFocusManager;
9import java.awt.Rectangle; 11import java.awt.Rectangle;
10import java.awt.event.ActionEvent; 12import java.awt.event.ActionEvent;
11import java.awt.event.ActionListener; 13import java.awt.event.ActionListener;
@@ -16,8 +18,11 @@ import java.awt.event.MouseEvent;
16import java.util.ArrayList; 18import java.util.ArrayList;
17import java.util.Collection; 19import java.util.Collection;
18import java.util.Comparator; 20import java.util.Comparator;
21import java.util.HashSet;
19import java.util.List; 22import java.util.List;
20import java.util.Map; 23import java.util.Map;
24import java.util.NavigableSet;
25import java.util.Set;
21 26
22import javax.swing.JButton; 27import javax.swing.JButton;
23import javax.swing.JComponent; 28import javax.swing.JComponent;
@@ -120,6 +125,11 @@ public class EditorPanel {
120 customizeEditor(this.editor); 125 customizeEditor(this.editor);
121 this.editor.addCaretListener(event -> onCaretMove(event.getDot(), this.mouseIsPressed)); 126 this.editor.addCaretListener(event -> onCaretMove(event.getDot(), this.mouseIsPressed));
122 127
128 // Remove the tab key from focus traversal keys (we give it a different meaning)
129 Set<AWTKeyStroke> focusTraversalKeys = new HashSet<>(this.editor.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
130 focusTraversalKeys.removeIf(key -> key.getKeyCode() == KeyEvent.VK_TAB);
131 this.editor.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, focusTraversalKeys);
132
123 // set unit increment to height of one line, the amount scrolled per 133 // set unit increment to height of one line, the amount scrolled per
124 // mouse wheel rotation is then controlled by OS settings 134 // mouse wheel rotation is then controlled by OS settings
125 this.editorScrollPane.getVerticalScrollBar().setUnitIncrement(this.editor.getFontMetrics(this.editor.getFont()).getHeight()); 135 this.editorScrollPane.getVerticalScrollBar().setUnitIncrement(this.editor.getFontMetrics(this.editor.getFont()).getHeight());
@@ -199,6 +209,9 @@ public class EditorPanel {
199 EditorPanel.this.shouldNavigateOnClick = true; // CTRL 209 EditorPanel.this.shouldNavigateOnClick = true; // CTRL
200 break; 210 break;
201 } 211 }
212 } else if (event.getKeyCode() == KeyEvent.VK_TAB) {
213 EditorPanel.this.navigateToNextObfuscatedToken();
214 event.consume();
202 } 215 }
203 } 216 }
204 217
@@ -668,6 +681,36 @@ public class EditorPanel {
668 } 681 }
669 } 682 }
670 683
684 /**
685 * Navigate to the next obfuscated token that can be renamed.
686 *
687 * <p>If the tokens are damaged, then this method should not be called
688 * synchronously. Instead, the call should be wrapped in a
689 * {@link SwingUtilities#invokeLater(Runnable)}. Failing to do so
690 * will induce invalid token highlighting regions.
691 */
692 public void navigateToNextObfuscatedToken() {
693 int caretPos = this.getEditor().getCaretPosition();
694 Token token = this.getToken(this.getEditor().getCaretPosition());
695 NavigableSet<Token> obfuscatedTokens = this.getSource().getTokenStore().getByType().get(RenamableTokenType.OBFUSCATED);
696 Token next;
697
698 if (token == null) {
699 next = obfuscatedTokens.higher(new Token(caretPos, caretPos, null));
700 } else {
701 next = obfuscatedTokens.higher(token);
702 }
703
704 if (next == null) {
705 // Wrap to start of document
706 next = obfuscatedTokens.pollFirst();
707 }
708
709 if (next != null) {
710 this.navigateToToken(next);
711 }
712 }
713
671 public void navigateToToken(Token token) { 714 public void navigateToToken(Token token) {
672 if (token == null) { 715 if (token == null) {
673 throw new IllegalArgumentException("Token cannot be null!"); 716 throw new IllegalArgumentException("Token cannot be null!");
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/IdentifierPanel.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/IdentifierPanel.java
index 6a8d7347..cf336e00 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/IdentifierPanel.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/IdentifierPanel.java
@@ -23,8 +23,6 @@ import cuchaz.enigma.gui.events.ConvertingTextFieldListener;
23import cuchaz.enigma.gui.util.GridBagConstraintsBuilder; 23import cuchaz.enigma.gui.util.GridBagConstraintsBuilder;
24import cuchaz.enigma.gui.util.GuiUtil; 24import cuchaz.enigma.gui.util.GuiUtil;
25import cuchaz.enigma.gui.util.ScaleUtil; 25import cuchaz.enigma.gui.util.ScaleUtil;
26import cuchaz.enigma.source.RenamableTokenType;
27import cuchaz.enigma.source.Token;
28import cuchaz.enigma.translation.mapping.AccessModifier; 26import cuchaz.enigma.translation.mapping.AccessModifier;
29import cuchaz.enigma.translation.mapping.EntryChange; 27import cuchaz.enigma.translation.mapping.EntryChange;
30import cuchaz.enigma.translation.mapping.EntryMapping; 28import cuchaz.enigma.translation.mapping.EntryMapping;
@@ -197,36 +195,19 @@ public class IdentifierPanel {
197 195
198 @Override 196 @Override
199 public void onStopEditing(ConvertingTextField field, StopEditingCause cause) { 197 public void onStopEditing(ConvertingTextField field, StopEditingCause cause) {
198 EditorPanel e = gui.getActiveEditor();
199
200 if (cause != StopEditingCause.ABORT) { 200 if (cause != StopEditingCause.ABORT) {
201 vc.reset(); 201 vc.reset();
202 vc.setActiveElement(field); 202 vc.setActiveElement(field);
203 doRename(field.getText()); 203 doRename(field.getText());
204 204
205 if (cause == StopEditingCause.TAB) { 205 if (cause == StopEditingCause.TAB && e != null) {
206 EditorPanel editor = gui.getActiveEditor(); 206 // invokeLater as per the method's javadocs
207 207 SwingUtilities.invokeLater(e::navigateToNextObfuscatedToken);
208 if (editor == null) {
209 return;
210 }
211
212 Token token = editor.getToken(editor.getEditor().getCaretPosition());
213
214 SwingUtilities.invokeLater(() -> {
215 Token next = editor.getSource().getTokenStore().getByType().get(RenamableTokenType.OBFUSCATED).higher(token);
216
217 if (next == null) {
218 editor.getEditor().requestFocusInWindow();
219 } else {
220 editor.navigateToToken(next);
221 }
222 });
223
224 return;
225 } 208 }
226 } 209 }
227 210
228 EditorPanel e = gui.getActiveEditor();
229
230 if (e != null) { 211 if (e != null) {
231 e.getEditor().requestFocusInWindow(); 212 e.getEditor().requestFocusInWindow();
232 } 213 }