Add option to copy chat message contents to clipboard
Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
This commit is contained in:
@@ -475,6 +475,8 @@ public class WidgetID
|
|||||||
static final int MESSAGES = 55;
|
static final int MESSAGES = 55;
|
||||||
static final int TRANSPARENT_BACKGROUND_LINES = 56;
|
static final int TRANSPARENT_BACKGROUND_LINES = 56;
|
||||||
static final int INPUT = 57;
|
static final int INPUT = 57;
|
||||||
|
static final int MESSAGE_LINES = 58;
|
||||||
|
static final int FIRST_MESSAGE = 59;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class Prayer
|
static class Prayer
|
||||||
|
|||||||
@@ -362,6 +362,8 @@ public enum WidgetInfo
|
|||||||
CHATBOX_INPUT(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.INPUT),
|
CHATBOX_INPUT(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.INPUT),
|
||||||
CHATBOX_TRANSPARENT_BACKGROUND(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.TRANSPARENT_BACKGROUND),
|
CHATBOX_TRANSPARENT_BACKGROUND(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.TRANSPARENT_BACKGROUND),
|
||||||
CHATBOX_TRANSPARENT_LINES(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.TRANSPARENT_BACKGROUND_LINES),
|
CHATBOX_TRANSPARENT_LINES(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.TRANSPARENT_BACKGROUND_LINES),
|
||||||
|
CHATBOX_MESSAGE_LINES(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.MESSAGE_LINES),
|
||||||
|
CHATBOX_FIRST_MESSAGE(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.FIRST_MESSAGE),
|
||||||
|
|
||||||
BA_HEAL_WAVE_TEXT(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.CURRENT_WAVE),
|
BA_HEAL_WAVE_TEXT(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.CURRENT_WAVE),
|
||||||
BA_HEAL_CALL_TEXT(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.TO_CALL),
|
BA_HEAL_CALL_TEXT(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.TO_CALL),
|
||||||
|
|||||||
+11
@@ -52,4 +52,15 @@ public interface ChatHistoryConfig extends Config
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "copyToClipboard",
|
||||||
|
name = "Copy to clipboard",
|
||||||
|
description = "Add option on chat messages to copy them to clipboard",
|
||||||
|
position = 2
|
||||||
|
)
|
||||||
|
default boolean copyToClipboard()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+82
@@ -24,8 +24,11 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.chathistory;
|
package net.runelite.client.plugins.chathistory;
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.EvictingQueue;
|
import com.google.common.collect.EvictingQueue;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.datatransfer.StringSelection;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
@@ -34,12 +37,19 @@ import java.util.Queue;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import net.runelite.api.ChatMessageType;
|
import net.runelite.api.ChatMessageType;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.MenuAction;
|
||||||
|
import net.runelite.api.MenuEntry;
|
||||||
import net.runelite.api.ScriptID;
|
import net.runelite.api.ScriptID;
|
||||||
import net.runelite.api.VarClientInt;
|
import net.runelite.api.VarClientInt;
|
||||||
import net.runelite.api.VarClientStr;
|
import net.runelite.api.VarClientStr;
|
||||||
import net.runelite.api.events.ChatMessage;
|
import net.runelite.api.events.ChatMessage;
|
||||||
|
import net.runelite.api.events.MenuOpened;
|
||||||
import net.runelite.api.events.MenuOptionClicked;
|
import net.runelite.api.events.MenuOptionClicked;
|
||||||
import net.runelite.api.vars.InputType;
|
import net.runelite.api.vars.InputType;
|
||||||
|
import net.runelite.api.widgets.Widget;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
import static net.runelite.api.widgets.WidgetInfo.TO_CHILD;
|
||||||
|
import static net.runelite.api.widgets.WidgetInfo.TO_GROUP;
|
||||||
import net.runelite.client.callback.ClientThread;
|
import net.runelite.client.callback.ClientThread;
|
||||||
import net.runelite.client.chat.ChatMessageManager;
|
import net.runelite.client.chat.ChatMessageManager;
|
||||||
import net.runelite.client.chat.QueuedMessage;
|
import net.runelite.client.chat.QueuedMessage;
|
||||||
@@ -50,6 +60,7 @@ import net.runelite.client.input.KeyManager;
|
|||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
import net.runelite.client.util.Text;
|
import net.runelite.client.util.Text;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
@PluginDescriptor(
|
@PluginDescriptor(
|
||||||
@@ -62,12 +73,15 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
|
|||||||
private static final String WELCOME_MESSAGE = "Welcome to Old School RuneScape";
|
private static final String WELCOME_MESSAGE = "Welcome to Old School RuneScape";
|
||||||
private static final String CLEAR_HISTORY = "Clear history";
|
private static final String CLEAR_HISTORY = "Clear history";
|
||||||
private static final String CLEAR_PRIVATE = "<col=ffff00>Private:";
|
private static final String CLEAR_PRIVATE = "<col=ffff00>Private:";
|
||||||
|
private static final String COPY_TO_CLIPBOARD = "Copy to clipboard";
|
||||||
private static final int CYCLE_HOTKEY = KeyEvent.VK_TAB;
|
private static final int CYCLE_HOTKEY = KeyEvent.VK_TAB;
|
||||||
private static final int FRIENDS_MAX_SIZE = 5;
|
private static final int FRIENDS_MAX_SIZE = 5;
|
||||||
|
|
||||||
private Queue<QueuedMessage> messageQueue;
|
private Queue<QueuedMessage> messageQueue;
|
||||||
private Deque<String> friends;
|
private Deque<String> friends;
|
||||||
|
|
||||||
|
private String currentMessage = null;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Client client;
|
private Client client;
|
||||||
|
|
||||||
@@ -104,6 +118,7 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
|
|||||||
messageQueue = null;
|
messageQueue = null;
|
||||||
friends.clear();
|
friends.clear();
|
||||||
friends = null;
|
friends = null;
|
||||||
|
currentMessage = null;
|
||||||
keyManager.unregisterKeyListener(this);
|
keyManager.unregisterKeyListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,6 +182,68 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onMenuOpened(MenuOpened event)
|
||||||
|
{
|
||||||
|
if (event.getMenuEntries().length < 2 || !config.copyToClipboard())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use second entry as first one can be walk here with transparent chatbox
|
||||||
|
final MenuEntry entry = event.getMenuEntries()[event.getMenuEntries().length - 2];
|
||||||
|
|
||||||
|
if (entry.getType() != MenuAction.CC_OP_LOW_PRIORITY.getId())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int groupId = TO_GROUP(entry.getParam1());
|
||||||
|
final int childId = TO_CHILD(entry.getParam1());
|
||||||
|
|
||||||
|
if (groupId != WidgetInfo.CHATBOX.getGroupId())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Widget widget = client.getWidget(groupId, childId);
|
||||||
|
final Widget parent = widget.getParent();
|
||||||
|
|
||||||
|
if (WidgetInfo.CHATBOX_MESSAGE_LINES.getId() != parent.getId())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get child id of first chat message static child so we can substract this offset to link to dynamic child
|
||||||
|
// later
|
||||||
|
final int first = WidgetInfo.CHATBOX_FIRST_MESSAGE.getChildId();
|
||||||
|
|
||||||
|
// Convert current message static widget id to dynamic widget id of message node with message contents
|
||||||
|
// When message is right clicked, we are actually right clicking static widget that contains only sender.
|
||||||
|
// The actual message contents are stored in dynamic widgets that follow same order as static widgets.
|
||||||
|
// Every first dynamic widget is message sender and every second one is message contents.
|
||||||
|
final int dynamicChildId = (childId - first) * 2 + 1;
|
||||||
|
|
||||||
|
// Extract and store message contents when menu is opened because dynamic children can change while right click
|
||||||
|
// menu is open and dynamicChildId will be outdated
|
||||||
|
final Widget messageContents = parent.getChild(dynamicChildId);
|
||||||
|
if (messageContents == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentMessage = messageContents.getText();
|
||||||
|
|
||||||
|
final MenuEntry menuEntry = new MenuEntry();
|
||||||
|
menuEntry.setOption(COPY_TO_CLIPBOARD);
|
||||||
|
menuEntry.setTarget(entry.getTarget());
|
||||||
|
menuEntry.setType(MenuAction.RUNELITE.getId());
|
||||||
|
menuEntry.setParam0(entry.getParam0());
|
||||||
|
menuEntry.setParam1(entry.getParam1());
|
||||||
|
menuEntry.setIdentifier(entry.getIdentifier());
|
||||||
|
client.setMenuEntries(ArrayUtils.insert(1, client.getMenuEntries(), menuEntry));
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||||
{
|
{
|
||||||
@@ -185,6 +262,11 @@ public class ChatHistoryPlugin extends Plugin implements KeyListener
|
|||||||
messageQueue.removeIf(e -> e.getType() == ChatMessageType.PUBLICCHAT || e.getType() == ChatMessageType.MODCHAT);
|
messageQueue.removeIf(e -> e.getType() == ChatMessageType.PUBLICCHAT || e.getType() == ChatMessageType.MODCHAT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (COPY_TO_CLIPBOARD.equals(menuOption) && !Strings.isNullOrEmpty(currentMessage))
|
||||||
|
{
|
||||||
|
final StringSelection stringSelection = new StringSelection(Text.removeTags(currentMessage));
|
||||||
|
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user