diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsConfig.java index 835ccec71e..a7e4963bcc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsConfig.java @@ -129,4 +129,15 @@ public interface ChatCommandsConfig extends Config { return true; } + + @ConfigItem( + position = 5, + keyName = "clipboardShortcuts", + name = "Clipboard shortcuts", + description = "Enable clipboard shortcuts (ctrl+c and ctrl+v)" + ) + default boolean clipboardShortcuts() + { + return true; + } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatKeyboardListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatKeyboardListener.java index d32dab3fc1..cd2678e520 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatKeyboardListener.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatKeyboardListener.java @@ -29,9 +29,11 @@ import javax.inject.Inject; import javax.inject.Singleton; import net.runelite.api.Client; import net.runelite.api.ScriptID; +import net.runelite.api.GameState; import net.runelite.api.VarClientStr; import net.runelite.client.callback.ClientThread; import net.runelite.client.input.KeyListener; +import net.runelite.client.util.Clipboard; @Singleton class ChatKeyboardListener implements KeyListener @@ -54,15 +56,45 @@ class ChatKeyboardListener implements KeyListener @Override public void keyPressed(KeyEvent e) { - if (!e.isControlDown() || !chatCommandsConfig.clearShortcuts()) + if (!e.isControlDown() || client.getGameState() != GameState.LOGGED_IN) { return; } + String input = client.getVar(VarClientStr.CHATBOX_TYPED_TEXT); + switch (e.getKeyCode()) { + case KeyEvent.VK_C: + if (!chatCommandsConfig.clipboardShortcuts()) + { + break; + } + + Clipboard.store(input); + + break; + case KeyEvent.VK_V: + if (!chatCommandsConfig.clipboardShortcuts()) + { + break; + } + + final String clipboard = Clipboard.retrieve(); + if (clipboard != null && !clipboard.isEmpty()) + { + final String replacement = input + clipboard; + + clientThread.invoke(() -> client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, replacement)); + } + + break; case KeyEvent.VK_W: - String input = client.getVar(VarClientStr.CHATBOX_TYPED_TEXT); + if (!chatCommandsConfig.clearShortcuts()) + { + break; + } + if (input != null) { // remove trailing space @@ -96,6 +128,12 @@ class ChatKeyboardListener implements KeyListener client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, ""); client.runScript(ScriptID.CHAT_PROMPT_INIT); }); + if (!chatCommandsConfig.clearShortcuts()) + { + break; + } + + clientThread.invoke(() -> client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, "")); break; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java index 73991b48fa..421341e75f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java @@ -32,10 +32,7 @@ import com.google.inject.Provides; import java.awt.Desktop; import java.awt.Graphics; import java.awt.Image; -import java.awt.Toolkit; import java.awt.TrayIcon; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.StringSelection; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; @@ -103,6 +100,7 @@ import net.runelite.client.ui.ClientUI; import net.runelite.client.ui.DrawManager; import net.runelite.client.ui.NavigationButton; import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.util.Clipboard; import net.runelite.client.util.HotkeyListener; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.Text; @@ -247,7 +245,7 @@ public class ScreenshotPlugin extends Plugin { updateConfig(); addSubscriptions(); - + overlayManager.add(screenshotOverlay); SCREENSHOT_DIR.mkdirs(); keyManager.registerKeyListener(hotkeyListener); @@ -855,9 +853,7 @@ public class ScreenshotPlugin extends Plugin { String link = imageUploadResponse.getData().getLink(); - StringSelection selection = new StringSelection(link); - Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - clipboard.setContents(selection, selection); + Clipboard.store(link); if (notifyWhenTaken) { @@ -915,7 +911,7 @@ public class ScreenshotPlugin extends Plugin updateConfig(); } - + private void updateConfig() { this.includeFrame = config.includeFrame(); diff --git a/runelite-client/src/main/java/net/runelite/client/util/Clipboard.java b/runelite-client/src/main/java/net/runelite/client/util/Clipboard.java new file mode 100644 index 0000000000..58932ba5ed --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/util/Clipboard.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2018, Connor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package net.runelite.client.util; + +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.IOException; + +public class Clipboard +{ + public static String retrieve() + { + Transferable contents = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null); + + if (contents == null || ! contents.isDataFlavorSupported(DataFlavor.stringFlavor)) + { + return null; + } + + try + { + return (String) contents.getTransferData(DataFlavor.stringFlavor); + } + catch (UnsupportedFlavorException | IOException ex) + { + return null; + } + } + + public static void store(String contents) + { + final StringSelection selection = new StringSelection(contents); + + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, null); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/util/LinkBrowser.java b/runelite-client/src/main/java/net/runelite/client/util/LinkBrowser.java index 793ccaf8a0..094ae56102 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/LinkBrowser.java +++ b/runelite-client/src/main/java/net/runelite/client/util/LinkBrowser.java @@ -26,8 +26,6 @@ package net.runelite.client.util; import com.google.common.base.Strings; import java.awt.Desktop; -import java.awt.Toolkit; -import java.awt.datatransfer.StringSelection; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -144,8 +142,7 @@ public class LinkBrowser if (result == JOptionPane.OK_OPTION) { - final StringSelection stringSelection = new StringSelection(data); - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null); + Clipboard.store(data); } }); }