ChatCommands: Add Clipboard Support (#1040)
* Add Chat Input Clipboard Support Add CTRL+V and CTRL+C support to the in-game chatbox. Fixes an issue with errors being thrown when shortcuts were used when not currently logged in. Extracts clipboard logic (a couple places already had a sort of "copy" functionality) to a simple clipboard util. * Checkstyle fix
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Connor <contact@connor-parks.email>
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user