package com.ts3client.ui; import com.ts3client.contacts.ContactType; import com.ts3client.net.ChannelNode; import com.ts3client.net.ClientEntry; import com.ts3client.net.Group; import com.ts3client.net.ServerModel; import javax.swing.JCheckBoxMenuItem; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import java.util.List; /** * The context menu for a client, shared by the server tree and the clickable * names in the chat log. */ final class ClientMenu { private ClientMenu() { } /** * @param fromTree whether this menu was opened from the server tree itself, as * opposed to a client link elsewhere (chat log, etc.) — "Find * Client in Channel Tree" is redundant in the former case. */ static JPopupMenu build(ClientEntry client, boolean self, boolean fromTree, ServerModel model, GroupIcons groupIcons, ServerTreePanel.Actions actions) { JPopupMenu menu = new JPopupMenu(); if (!self) { JMenuItem pm = new JMenuItem("Open text chat", Icons.of("PLAYER_CHAT")); pm.addActionListener(a -> actions.openPrivateChat(client)); menu.add(pm); JMenuItem poke = new JMenuItem("Poke", Icons.of("POKE")); poke.addActionListener(a -> actions.pokeClient(client)); menu.add(poke); menu.addSeparator(); JMenuItem kickChannel = new JMenuItem("Kick Client from Channel", Icons.of("KICK_FROM_CHANNEL")); kickChannel.addActionListener(a -> actions.kickClientFromChannel(client)); menu.add(kickChannel); JMenuItem kickServer = new JMenuItem("Kick Client from Server", Icons.of("KICK_FROM_SERVER")); kickServer.addActionListener(a -> actions.kickClientFromServer(client)); menu.add(kickServer); JMenuItem ban = new JMenuItem("Ban Client", Icons.of("BAN_CLIENT")); ban.addActionListener(a -> actions.banClient(client)); menu.add(ban); boolean muted = actions.isClientLocallyMuted(client.id); JMenuItem mute = new JMenuItem(muted ? "Unmute client" : "Mute client", Icons.of(muted ? "PLAYER_ON" : "INPUT_MUTED")); mute.addActionListener(a -> actions.toggleClientMute(client)); menu.add(mute); JMenuItem volume = new JMenuItem("Change Volume…", Icons.of("VOLUME")); volume.addActionListener(a -> actions.changeClientVolume(client)); menu.add(volume); menu.addSeparator(); addContactItems(menu, client, actions); } else { JMenuItem me = new JMenuItem("This is you", Icons.of("PLAYER_OFF")); me.setEnabled(false); menu.add(me); } menu.addSeparator(); menu.add(buildServerGroupMenu(client, model, groupIcons, actions)); menu.add(buildChannelGroupMenu(client, model, groupIcons, actions)); menu.addSeparator(); if (!fromTree) { JMenuItem findInTree = new JMenuItem("Find Client in Channel Tree", Icons.of("CHANNEL_SWITCH")); findInTree.setEnabled(model.isChannelVisible(client.channelId)); findInTree.addActionListener(a -> actions.findClientInTree(client)); menu.add(findInTree); } JMenuItem description = new JMenuItem("Change Description", Icons.of("EDIT")); description.addActionListener(a -> actions.changeClientDescription(client)); menu.add(description); if (!self && !client.avatarFlag.isEmpty() && actions.canDeleteOtherAvatars()) { JMenuItem avatar = new JMenuItem("Delete Avatar", Icons.of("DELETE_AVATAR_OTHER")); avatar.addActionListener(a -> actions.deleteClientAvatar(client)); menu.add(avatar); } JMenuItem info = new JMenuItem("Connection Info", Icons.of("INFO")); info.addActionListener(a -> actions.showConnectionInfo(client)); menu.add(info); if (!self) { menu.addSeparator(); JMenuItem joinChannel = new JMenuItem("Join Channel of Client", Icons.of("CHANNEL_SWITCH")); joinChannel.setEnabled(model.canJoinChannel(client.channelId)); joinChannel.addActionListener(a -> actions.joinChannel(client.channelId)); menu.add(joinChannel); JMenuItem moveHere = new JMenuItem("Move Client to own Channel", Icons.of("MOVE_CLIENT_TO_OWN_CHANNEL")); moveHere.addActionListener(a -> actions.moveClientToOwnChannel(client)); menu.add(moveHere); } return menu; } /** * The contact entries, as TeamSpeak offers them: a client not on the list can be * added as a friend or blocked; one on it can be edited or removed. */ private static void addContactItems(JPopupMenu menu, ClientEntry client, ServerTreePanel.Actions actions) { ContactType type = actions.contactTypeOf(client); if (type == null) { JMenuItem friend = new JMenuItem("Add as Friend", Icons.of("ADD_FRIEND")); friend.addActionListener(a -> actions.addContact(client, ContactType.FRIEND)); menu.add(friend); JMenuItem blocked = new JMenuItem("Add as Blocked", Icons.of("ADD_FOE")); blocked.addActionListener(a -> actions.addContact(client, ContactType.BLOCKED)); menu.add(blocked); return; } JMenuItem edit = new JMenuItem("Edit in Contacts", Icons.of("EDIT_FRIEND_FOE_STATUS")); edit.addActionListener(a -> actions.editContact(client)); menu.add(edit); JMenuItem remove = new JMenuItem("Remove from Contacts", Icons.of(type == ContactType.BLOCKED ? "REMOVE_FOE" : "REMOVE_FRIEND")); remove.addActionListener(a -> actions.removeContact(client)); menu.add(remove); } private static JMenu buildServerGroupMenu(ClientEntry client, ServerModel model, GroupIcons groupIcons, ServerTreePanel.Actions actions) { JMenu menu = new JMenu("Set Server Groups"); menu.setIcon(Icons.of("PERMISSIONS_SERVER_GROUPS")); JMenuItem dialog = new JMenuItem("Server Groups Dialog..."); dialog.addActionListener(a -> actions.showServerGroupsDialog(client)); menu.add(dialog); menu.addSeparator(); for (Group g : model.allServerGroups()) { boolean assigned = client.inServerGroup(g.id); if (!model.canToggleGroup(g, assigned)) continue; JCheckBoxMenuItem item = new JCheckBoxMenuItem(g.name, groupIcons.iconOf(g)); item.setSelected(assigned); item.addActionListener(a -> actions.setClientServerGroup(client, g, !assigned)); menu.add(item); } return menu; } private static JMenu buildChannelGroupMenu(ClientEntry client, ServerModel model, GroupIcons groupIcons, ServerTreePanel.Actions actions) { JMenu menu = new JMenu("Set Channel Group"); menu.setIcon(Icons.of("PERMISSIONS_CHANNEL_GROUPS")); int defaultGroupId = model.defaultChannelGroupId(); for (Group g : model.allChannelGroups()) { if (g.id == defaultGroupId) continue; boolean assigned = client.channelGroupId == g.id; if (!model.canToggleGroup(g, assigned)) continue; JCheckBoxMenuItem item = new JCheckBoxMenuItem(g.name, groupIcons.iconOf(g)); item.setSelected(assigned); item.addActionListener(a -> actions.setClientChannelGroup(client, g)); menu.add(item); } return menu; } }