Global Hotkeys Cleanup
This commit is contained in:
parent
b99f6bf98a
commit
e2a8857499
5 changed files with 133 additions and 105 deletions
|
@ -354,7 +354,8 @@ public class BytecodeViewer
|
||||||
* @param name the file name
|
* @param name the file name
|
||||||
* @return the file contents as a byte[]
|
* @return the file contents as a byte[]
|
||||||
*/
|
*/
|
||||||
public static byte[] getFileContents(String name) {
|
public static byte[] getFileContents(String name)
|
||||||
|
{
|
||||||
for (FileContainer container : files)
|
for (FileContainer container : files)
|
||||||
if (container.files.containsKey(name))
|
if (container.files.containsKey(name))
|
||||||
return container.files.get(name);
|
return container.files.get(name);
|
||||||
|
@ -369,15 +370,15 @@ public class BytecodeViewer
|
||||||
* @return
|
* @return
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static byte[] getClassFile(Class<?> clazz) throws IOException {
|
public static byte[] getClassFile(Class<?> clazz) throws IOException
|
||||||
try (InputStream is = clazz.getResourceAsStream(
|
{
|
||||||
"/" + clazz.getName().replace('.', '/') + ".class");
|
try (InputStream is = clazz.getResourceAsStream("/" + clazz.getName().replace('.', '/') + ".class");
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
ByteArrayOutputStream baos = new ByteArrayOutputStream())
|
||||||
|
{
|
||||||
int r;
|
int r;
|
||||||
byte[] buffer = new byte[8192];
|
byte[] buffer = new byte[8192];
|
||||||
while ((r = Objects.requireNonNull(is).read(buffer)) >= 0) {
|
while ((r = Objects.requireNonNull(is).read(buffer)) >= 0)
|
||||||
baos.write(buffer, 0, r);
|
baos.write(buffer, 0, r);
|
||||||
}
|
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -390,10 +391,9 @@ public class BytecodeViewer
|
||||||
*/
|
*/
|
||||||
public static void updateNode(ClassNode oldNode, ClassNode newNode)
|
public static void updateNode(ClassNode oldNode, ClassNode newNode)
|
||||||
{
|
{
|
||||||
for (FileContainer container : files) {
|
for (FileContainer container : files)
|
||||||
if (container.classes.remove(oldNode))
|
if (container.classes.remove(oldNode))
|
||||||
container.classes.add(newNode);
|
container.classes.add(newNode);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -401,7 +401,8 @@ public class BytecodeViewer
|
||||||
*
|
*
|
||||||
* @return the loaded classes as an array list
|
* @return the loaded classes as an array list
|
||||||
*/
|
*/
|
||||||
public static ArrayList<ClassNode> getLoadedClasses() {
|
public static ArrayList<ClassNode> getLoadedClasses()
|
||||||
|
{
|
||||||
ArrayList<ClassNode> a = new ArrayList<>();
|
ArrayList<ClassNode> a = new ArrayList<>();
|
||||||
|
|
||||||
for (FileContainer container : files)
|
for (FileContainer container : files)
|
||||||
|
@ -433,7 +434,8 @@ public class BytecodeViewer
|
||||||
* @param message if it should send a message saying it's compiled sucessfully.
|
* @param message if it should send a message saying it's compiled sucessfully.
|
||||||
* @return true if no errors, false if it failed to compile.
|
* @return true if no errors, false if it failed to compile.
|
||||||
*/
|
*/
|
||||||
public static boolean compile(boolean message, boolean successAlert) {
|
public static boolean compile(boolean message, boolean successAlert)
|
||||||
|
{
|
||||||
BytecodeViewer.updateBusyStatus(true);
|
BytecodeViewer.updateBusyStatus(true);
|
||||||
boolean noErrors = true;
|
boolean noErrors = true;
|
||||||
boolean actuallyTried = false;
|
boolean actuallyTried = false;
|
||||||
|
@ -483,7 +485,8 @@ public class BytecodeViewer
|
||||||
* @param files the file(s) you wish to open
|
* @param files the file(s) you wish to open
|
||||||
* @param recentFiles if it should append to the recent files menu
|
* @param recentFiles if it should append to the recent files menu
|
||||||
*/
|
*/
|
||||||
public static void openFiles(final File[] files, boolean recentFiles) {
|
public static void openFiles(final File[] files, boolean recentFiles)
|
||||||
|
{
|
||||||
if (recentFiles)
|
if (recentFiles)
|
||||||
{
|
{
|
||||||
for (File f : files)
|
for (File f : files)
|
||||||
|
@ -504,7 +507,8 @@ public class BytecodeViewer
|
||||||
*
|
*
|
||||||
* @param file the file of the plugin
|
* @param file the file of the plugin
|
||||||
*/
|
*/
|
||||||
public static void startPlugin(File file) {
|
public static void startPlugin(File file)
|
||||||
|
{
|
||||||
if (!file.exists())
|
if (!file.exists())
|
||||||
{
|
{
|
||||||
BytecodeViewer.showMessage("The plugin file " + file.getAbsolutePath() + " could not be found.");
|
BytecodeViewer.showMessage("The plugin file " + file.getAbsolutePath() + " could not be found.");
|
||||||
|
@ -525,7 +529,8 @@ public class BytecodeViewer
|
||||||
*
|
*
|
||||||
* @param message the message you need to send
|
* @param message the message you need to send
|
||||||
*/
|
*/
|
||||||
public static void showMessage(String message) {
|
public static void showMessage(String message)
|
||||||
|
{
|
||||||
BetterJOptionPane.showMessageDialog(viewer, message);
|
BetterJOptionPane.showMessageDialog(viewer, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,6 +595,9 @@ public class BytecodeViewer
|
||||||
tempF.mkdir();
|
tempF.mkdir();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refreshes the title on all of the opened tabs
|
||||||
|
*/
|
||||||
public static void refreshAllTabTitles()
|
public static void refreshAllTabTitles()
|
||||||
{
|
{
|
||||||
for(int i = 0; i < BytecodeViewer.viewer.workPane.tabs.getTabCount(); i++)
|
for(int i = 0; i < BytecodeViewer.viewer.workPane.tabs.getTabCount(); i++)
|
||||||
|
@ -598,92 +606,4 @@ public class BytecodeViewer
|
||||||
viewer.refreshTitle();
|
viewer.refreshTitle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks the hotkeys
|
|
||||||
*
|
|
||||||
* @param e
|
|
||||||
*/
|
|
||||||
public static void checkHotKey(KeyEvent e) {
|
|
||||||
if (System.currentTimeMillis() - Configuration.lastHotKeyExecuted <= (4000))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ((e.getKeyCode() == KeyEvent.VK_O) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0))
|
|
||||||
{
|
|
||||||
Configuration.lastHotKeyExecuted = System.currentTimeMillis();
|
|
||||||
|
|
||||||
final File file = DialogueUtils.fileChooser("Select File or Folder to open in BCV",
|
|
||||||
"APKs, DEX, Class Files or Zip/Jar/War Archives",
|
|
||||||
Constants.SUPPORTED_FILE_EXTENSIONS);
|
|
||||||
|
|
||||||
if(file == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
BytecodeViewer.updateBusyStatus(true);
|
|
||||||
BytecodeViewer.openFiles(new File[]{file}, true);
|
|
||||||
BytecodeViewer.updateBusyStatus(false);
|
|
||||||
} else if ((e.getKeyCode() == KeyEvent.VK_N) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
|
|
||||||
Configuration.lastHotKeyExecuted = System.currentTimeMillis();
|
|
||||||
BytecodeViewer.resetWorkspace(true);
|
|
||||||
} else if ((e.getKeyCode() == KeyEvent.VK_T) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
|
|
||||||
Configuration.lastHotKeyExecuted = System.currentTimeMillis();
|
|
||||||
Thread t = new Thread(() -> BytecodeViewer.compile(true, false), "Compile");
|
|
||||||
t.start();
|
|
||||||
} else if ((e.getKeyCode() == KeyEvent.VK_R) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
|
|
||||||
Configuration.lastHotKeyExecuted = System.currentTimeMillis();
|
|
||||||
if (BytecodeViewer.getLoadedClasses().isEmpty()) {
|
|
||||||
BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
new RunOptions().setVisible(true);
|
|
||||||
} else if ((e.getKeyCode() == KeyEvent.VK_S) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
|
|
||||||
Configuration.lastHotKeyExecuted = System.currentTimeMillis();
|
|
||||||
|
|
||||||
if (BytecodeViewer.getLoadedClasses().isEmpty()) {
|
|
||||||
BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread resourceExport = new Thread(() ->
|
|
||||||
{
|
|
||||||
if (BytecodeViewer.autoCompileSuccessful())
|
|
||||||
return;
|
|
||||||
|
|
||||||
JFileChooser fc = new FileChooser(Configuration.getLastDirectory(),
|
|
||||||
"Select Zip Export",
|
|
||||||
"Zip Archives",
|
|
||||||
"zip");
|
|
||||||
|
|
||||||
int returnVal = fc.showSaveDialog(viewer);
|
|
||||||
if (returnVal == JFileChooser.APPROVE_OPTION)
|
|
||||||
{
|
|
||||||
Configuration.lastDirectory = fc.getSelectedFile().getAbsolutePath();
|
|
||||||
File file = fc.getSelectedFile();
|
|
||||||
|
|
||||||
if (!file.getAbsolutePath().endsWith(".zip"))
|
|
||||||
file = new File(file.getAbsolutePath() + ".zip");
|
|
||||||
|
|
||||||
if (!DialogueUtils.canOverwriteFile(file))
|
|
||||||
return;
|
|
||||||
|
|
||||||
final File file2 = file;
|
|
||||||
|
|
||||||
BytecodeViewer.updateBusyStatus(true);
|
|
||||||
Thread jarExport = new Thread(() -> {
|
|
||||||
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(),
|
|
||||||
file2.getAbsolutePath());
|
|
||||||
BytecodeViewer.updateBusyStatus(false);
|
|
||||||
}, "Jar Export");
|
|
||||||
jarExport.start();
|
|
||||||
}
|
|
||||||
}, "Resource Export");
|
|
||||||
resourceExport.start();
|
|
||||||
}
|
|
||||||
else if ((e.getKeyCode() == KeyEvent.VK_W) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0))
|
|
||||||
{
|
|
||||||
Configuration.lastHotKeyExecuted = System.currentTimeMillis();
|
|
||||||
if (viewer.workPane.getCurrentViewer() != null)
|
|
||||||
viewer.workPane.tabs.remove(viewer.workPane.getCurrentViewer());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
package the.bytecode.club.bytecodeviewer;
|
||||||
|
|
||||||
|
import the.bytecode.club.bytecodeviewer.gui.components.FileChooser;
|
||||||
|
import the.bytecode.club.bytecodeviewer.gui.components.RunOptions;
|
||||||
|
import the.bytecode.club.bytecodeviewer.util.DialogueUtils;
|
||||||
|
import the.bytecode.club.bytecodeviewer.util.JarUtils;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whenever a key is pressed on the swing UI it should get logged here
|
||||||
|
*
|
||||||
|
* @author Konloch
|
||||||
|
* @since 7/6/2021
|
||||||
|
*/
|
||||||
|
public class GlobalHotKeys
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Checks the hotkeys
|
||||||
|
*/
|
||||||
|
public static void keyPressed(KeyEvent e) {
|
||||||
|
if (System.currentTimeMillis() - Configuration.lastHotKeyExecuted <= (4000))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((e.getKeyCode() == KeyEvent.VK_O) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0))
|
||||||
|
{
|
||||||
|
Configuration.lastHotKeyExecuted = System.currentTimeMillis();
|
||||||
|
|
||||||
|
final File file = DialogueUtils.fileChooser("Select File or Folder to open in BCV",
|
||||||
|
"APKs, DEX, Class Files or Zip/Jar/War Archives",
|
||||||
|
Constants.SUPPORTED_FILE_EXTENSIONS);
|
||||||
|
|
||||||
|
if(file == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BytecodeViewer.updateBusyStatus(true);
|
||||||
|
BytecodeViewer.openFiles(new File[]{file}, true);
|
||||||
|
BytecodeViewer.updateBusyStatus(false);
|
||||||
|
} else if ((e.getKeyCode() == KeyEvent.VK_N) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
|
||||||
|
Configuration.lastHotKeyExecuted = System.currentTimeMillis();
|
||||||
|
BytecodeViewer.resetWorkspace(true);
|
||||||
|
} else if ((e.getKeyCode() == KeyEvent.VK_T) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
|
||||||
|
Configuration.lastHotKeyExecuted = System.currentTimeMillis();
|
||||||
|
Thread t = new Thread(() -> BytecodeViewer.compile(true, false), "Compile");
|
||||||
|
t.start();
|
||||||
|
} else if ((e.getKeyCode() == KeyEvent.VK_R) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
|
||||||
|
Configuration.lastHotKeyExecuted = System.currentTimeMillis();
|
||||||
|
if (BytecodeViewer.getLoadedClasses().isEmpty()) {
|
||||||
|
BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
new RunOptions().setVisible(true);
|
||||||
|
} else if ((e.getKeyCode() == KeyEvent.VK_S) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
|
||||||
|
Configuration.lastHotKeyExecuted = System.currentTimeMillis();
|
||||||
|
|
||||||
|
if (BytecodeViewer.getLoadedClasses().isEmpty()) {
|
||||||
|
BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread resourceExport = new Thread(() ->
|
||||||
|
{
|
||||||
|
if (BytecodeViewer.autoCompileSuccessful())
|
||||||
|
return;
|
||||||
|
|
||||||
|
JFileChooser fc = new FileChooser(Configuration.getLastDirectory(),
|
||||||
|
"Select Zip Export",
|
||||||
|
"Zip Archives",
|
||||||
|
"zip");
|
||||||
|
|
||||||
|
int returnVal = fc.showSaveDialog(BytecodeViewer.viewer);
|
||||||
|
if (returnVal == JFileChooser.APPROVE_OPTION)
|
||||||
|
{
|
||||||
|
Configuration.lastDirectory = fc.getSelectedFile().getAbsolutePath();
|
||||||
|
File file = fc.getSelectedFile();
|
||||||
|
|
||||||
|
if (!file.getAbsolutePath().endsWith(".zip"))
|
||||||
|
file = new File(file.getAbsolutePath() + ".zip");
|
||||||
|
|
||||||
|
if (!DialogueUtils.canOverwriteFile(file))
|
||||||
|
return;
|
||||||
|
|
||||||
|
final File file2 = file;
|
||||||
|
|
||||||
|
BytecodeViewer.updateBusyStatus(true);
|
||||||
|
Thread jarExport = new Thread(() -> {
|
||||||
|
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(),
|
||||||
|
file2.getAbsolutePath());
|
||||||
|
BytecodeViewer.updateBusyStatus(false);
|
||||||
|
}, "Jar Export");
|
||||||
|
jarExport.start();
|
||||||
|
}
|
||||||
|
}, "Resource Export");
|
||||||
|
resourceExport.start();
|
||||||
|
}
|
||||||
|
else if ((e.getKeyCode() == KeyEvent.VK_W) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0))
|
||||||
|
{
|
||||||
|
Configuration.lastHotKeyExecuted = System.currentTimeMillis();
|
||||||
|
if (BytecodeViewer.viewer.workPane.getCurrentViewer() != null)
|
||||||
|
BytecodeViewer.viewer.workPane.tabs.remove(BytecodeViewer.viewer.workPane.getCurrentViewer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package the.bytecode.club.bytecodeviewer.gui.components;
|
package the.bytecode.club.bytecodeviewer.gui.components;
|
||||||
|
|
||||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
|
import the.bytecode.club.bytecodeviewer.GlobalHotKeys;
|
||||||
import the.bytecode.club.bytecodeviewer.Resources;
|
import the.bytecode.club.bytecodeviewer.Resources;
|
||||||
import the.bytecode.club.bytecodeviewer.gui.components.listeners.PressKeyListener;
|
import the.bytecode.club.bytecodeviewer.gui.components.listeners.PressKeyListener;
|
||||||
import the.bytecode.club.bytecodeviewer.gui.components.listeners.ReleaseKeyListener;
|
import the.bytecode.club.bytecodeviewer.gui.components.listeners.ReleaseKeyListener;
|
||||||
|
@ -76,7 +77,7 @@ public class SearchableJTextArea extends JTextArea
|
||||||
if ((keyEvent.getKeyCode() == KeyEvent.VK_F) && ((keyEvent.getModifiers() & KeyEvent.CTRL_MASK) != 0))
|
if ((keyEvent.getKeyCode() == KeyEvent.VK_F) && ((keyEvent.getModifiers() & KeyEvent.CTRL_MASK) != 0))
|
||||||
searchInput.requestFocus();
|
searchInput.requestFocus();
|
||||||
|
|
||||||
BytecodeViewer.checkHotKey(keyEvent);
|
GlobalHotKeys.keyPressed(keyEvent);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||||
import org.fife.ui.rtextarea.RTextScrollPane;
|
import org.fife.ui.rtextarea.RTextScrollPane;
|
||||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
import the.bytecode.club.bytecodeviewer.Configuration;
|
import the.bytecode.club.bytecodeviewer.Configuration;
|
||||||
|
import the.bytecode.club.bytecodeviewer.GlobalHotKeys;
|
||||||
import the.bytecode.club.bytecodeviewer.Resources;
|
import the.bytecode.club.bytecodeviewer.Resources;
|
||||||
import the.bytecode.club.bytecodeviewer.gui.components.listeners.PressKeyListener;
|
import the.bytecode.club.bytecodeviewer.gui.components.listeners.PressKeyListener;
|
||||||
import the.bytecode.club.bytecodeviewer.gui.components.listeners.ReleaseKeyListener;
|
import the.bytecode.club.bytecodeviewer.gui.components.listeners.ReleaseKeyListener;
|
||||||
|
@ -98,7 +99,7 @@ public class SearchableRSyntaxTextArea extends RSyntaxTextArea
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BytecodeViewer.checkHotKey(keyEvent);
|
GlobalHotKeys.keyPressed(keyEvent);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package the.bytecode.club.bytecodeviewer.util;
|
package the.bytecode.club.bytecodeviewer.util;
|
||||||
|
|
||||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
|
import the.bytecode.club.bytecodeviewer.GlobalHotKeys;
|
||||||
import the.bytecode.club.bytecodeviewer.gui.components.SearchableRSyntaxTextArea;
|
import the.bytecode.club.bytecodeviewer.gui.components.SearchableRSyntaxTextArea;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
@ -23,7 +24,7 @@ public class KeyEventDispatch implements KeyEventDispatcher
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BytecodeViewer.checkHotKey(e);
|
GlobalHotKeys.keyPressed(e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue