/* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. * * Copyright @ 2015 Atlassian Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.java.sip.communicator.impl.gui.main.chat; import java.awt.*; import java.awt.event.*; import javax.swing.*; import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.utils.*; import net.java.sip.communicator.plugin.desktoputil.*; import net.java.sip.communicator.plugin.desktoputil.chat.*; import net.java.sip.communicator.service.muc.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.skin.*; /** * The <tt>ChatContactRightButtonMenu</tt> is the menu, opened when user clicks * with the right mouse button on a contact in the list of contacts in the chat * window. * * @author Yana Stamcheva * @author Valentin Martinet * @author Adam Netocny * @author Ingo Bauersachs * @author Boris Grozev */ public class ChatContactRightButtonMenu extends SIPCommPopupMenu implements ActionListener, Skinnable { private static final long serialVersionUID = -4069653895234333083L; private Logger logger = Logger.getLogger(ChatContactRightButtonMenu.class); private final JMenuItem kickItem = new JMenuItem(GuiActivator.getResources().getI18NString( "service.gui.KICK")); private final JMenuItem banItem = new JMenuItem(GuiActivator.getResources().getI18NString( "service.gui.BAN")); private final JMenuItem changeRoomSubjectItem = new JMenuItem(GuiActivator.getResources().getI18NString( "service.gui.CHANGE_ROOM_SUBJECT")); private final JMenuItem changeNicknameItem = new JMenuItem(GuiActivator.getResources().getI18NString( "service.gui.CHANGE_NICKNAME")); private final JMenuItem grantOwnershipItem = new JMenuItem(GuiActivator.getResources().getI18NString( "service.gui.GRANT_OWNERSHIP")); private final JMenuItem grantAdminItem = new JMenuItem(GuiActivator.getResources().getI18NString( "service.gui.GRANT_ADMIN")); private final JMenuItem grantMembershipItem = new JMenuItem(GuiActivator.getResources().getI18NString( "service.gui.GRANT_MEMBERSHIP")); private final JMenuItem grantModeratorItem = new JMenuItem(GuiActivator.getResources().getI18NString( "service.gui.GRANT_MODERATOR")); private final JMenuItem grantVoiceItem = new JMenuItem(GuiActivator.getResources().getI18NString( "service.gui.GRANT_VOICE")); private final JMenuItem revokeOwnershipItem = new JMenuItem(GuiActivator.getResources().getI18NString( "service.gui.REVOKE_OWNERSHIP")); private final JMenuItem revokeAdminItem = new JMenuItem(GuiActivator.getResources().getI18NString( "service.gui.REVOKE_ADMIN")); private final JMenuItem revokeMembershipItem = new JMenuItem(GuiActivator.getResources().getI18NString( "service.gui.REVOKE_MEMBERSHIP")); private final JMenuItem revokeModeratorItem = new JMenuItem(GuiActivator.getResources().getI18NString( "service.gui.REVOKE_MODERATOR")); private final JMenuItem revokeVoiceItem = new JMenuItem(GuiActivator.getResources().getI18NString( "service.gui.REVOKE_VOICE")); private final JMenuItem sendPrivateMessageItem = new JMenuItem(GuiActivator.getResources().getI18NString( "service.gui.SEND_PRIVATE_MESSAGE")); private final ChatPanel chatPanel; /** * The contact associated with this menu */ private final ChatContact<?> chatContact; /** * The Chatroom in which the chatContact is currently participating. */ private ChatRoom room; /** * Creates an instance of <tt>ChatRoomsListRightButtonMenu</tt>. * @param chatPanel the chat panel containing this menu * @param chatContact the contact */ public ChatContactRightButtonMenu( ChatPanel chatPanel, ChatContact<?> chatContact) { this.chatPanel = chatPanel; this.chatContact = chatContact; Object descriptor = chatPanel.getChatSession().getDescriptor(); if (descriptor instanceof ChatRoomWrapper) this.room = ((ChatRoomWrapper) descriptor).getChatRoom(); this.setLocation(getLocation()); this.init(); } /** * Initializes the menu, by adding all containing menu items. */ private void init() { this.kickItem.setMnemonic( GuiActivator.getResources().getI18nMnemonic("service.gui.KICK")); this.banItem.setMnemonic( GuiActivator.getResources().getI18nMnemonic("service.gui.BAN")); this.grantAdminItem.setMnemonic( GuiActivator.getResources().getI18nMnemonic( "service.gui.GRANT_ADMIN")); this.grantMembershipItem.setMnemonic( GuiActivator.getResources().getI18nMnemonic( "service.gui.GRANT_MEMBERSHIP")); this.grantModeratorItem.setMnemonic( GuiActivator.getResources().getI18nMnemonic( "service.gui.GRANT_MODERATOR")); this.grantOwnershipItem.setMnemonic( GuiActivator.getResources().getI18nMnemonic( "service.gui.GRANT_OWNERSHIP")); this.grantVoiceItem.setMnemonic( GuiActivator.getResources().getI18nMnemonic( "service.gui.GRANT_VOICE")); this.revokeAdminItem.setMnemonic( GuiActivator.getResources().getI18nMnemonic( "service.gui.REVOKE_ADMIN")); this.revokeMembershipItem.setMnemonic( GuiActivator.getResources().getI18nMnemonic( "service.gui.REVOKE_MEMBERSHIP")); this.revokeModeratorItem.setMnemonic( GuiActivator.getResources().getI18nMnemonic( "service.gui.REVOKE_MODERATOR")); this.revokeOwnershipItem.setMnemonic( GuiActivator.getResources().getI18nMnemonic( "service.gui.REVOKE_OWNERSHIP")); this.revokeVoiceItem.setMnemonic( GuiActivator.getResources().getI18nMnemonic( "service.gui.REVOKE_VOICE")); this.changeNicknameItem.setMnemonic( GuiActivator.getResources().getI18nMnemonic( "service.gui.CHANGE_NICKNAME")); this.changeRoomSubjectItem.setMnemonic( GuiActivator.getResources().getI18nMnemonic( "service.gui.CHANGE_ROOM_SUBJECT")); this.sendPrivateMessageItem.setMnemonic( GuiActivator.getResources().getI18nMnemonic( "service.gui.SEND_PRIVATE_MESSAGE")); this.kickItem.addActionListener(this); this.banItem.addActionListener(this); this.changeNicknameItem.addActionListener(this); this.changeRoomSubjectItem.addActionListener(this); this.grantAdminItem.addActionListener(this); this.grantMembershipItem.addActionListener(this); this.grantModeratorItem.addActionListener(this); this.grantOwnershipItem.addActionListener(this); this.grantVoiceItem.addActionListener(this); this.revokeAdminItem.addActionListener(this); this.revokeMembershipItem.addActionListener(this); this.revokeModeratorItem.addActionListener(this); this.revokeOwnershipItem.addActionListener(this); this.revokeVoiceItem.addActionListener(this); this.sendPrivateMessageItem.addActionListener(this); this.kickItem.setName("kickItem"); this.banItem.setName("banItem"); this.changeNicknameItem.setName("changeNicknameItem"); this.changeRoomSubjectItem.setName("changeRoomSubjectItem"); this.grantAdminItem.setName("grantAdminItem"); this.grantMembershipItem.setName("grantMembershipItem"); this.grantModeratorItem.setName("grantModeratorItem"); this.grantOwnershipItem.setName("grantOwnershipItem"); this.grantVoiceItem.setName("grantVoiceItem"); this.revokeAdminItem.setName("revokeAdminItem"); this.revokeMembershipItem.setName("revokeMembershipItem"); this.revokeModeratorItem.setName("revokeModeratorItem"); this.revokeOwnershipItem.setName("revokeOwnershipItem"); this.revokeVoiceItem.setName("revokeVoiceItem"); this.sendPrivateMessageItem.setName("sendPrivateMessageItem"); loadSkin(); ChatRoomMemberRole role = chatContact.getName().equals(room.getUserNickname()) ? room.getUserRole() : ((ChatRoomMember) chatContact.getDescriptor()).getRole(); int roleIndex = role.getRoleIndex(); String roleName = role.getLocalizedRoleName(); JLabel jl_username = new JLabel(" " + chatContact.getName() + " (" + GuiActivator.getResources().getI18NString(roleName) + ") "); jl_username.setFont(jl_username.getFont().deriveFont(Font.BOLD)); this.add(jl_username); this.addSeparator(); // Here we build the menu when the local user cell renderer is clicked: if(chatContact.getName().equals(room.getUserNickname())) { if(roleIndex >= 50) { // It means we are at least a moderator, so we can change room's // subject: this.add(this.changeRoomSubjectItem); } this.add(this.changeNicknameItem); } else { if(!ConfigurationUtils.isPrivateMessagingInChatRoomDisabled()) this.add(this.sendPrivateMessageItem); if(room.getUserRole().getRoleIndex() >= 50) { if(roleIndex <= 40) { this.add(this.kickItem); // Admins and owners can ban members: if(room.getUserRole().getRoleIndex() >= 60 && roleIndex < 50) { this.add(this.banItem); } this.addSeparator(); } // we must at least be a moderator for managing voice rights if(roleIndex <= 20) this.add(this.grantVoiceItem); else if(roleIndex == 40 || roleIndex == 30) this.add(this.revokeVoiceItem); } if(room.getUserRole().getRoleIndex() >= 60) { // we must at least be an admin to manage membership if(roleIndex < 40) this.add(this.grantMembershipItem); // else if(roleIndex == 40) // this.add(this.revokeMembershipItem); if(roleIndex < 50) // room admins can edit moderators list this.add(this.grantModeratorItem); else if(roleIndex == 50) this.add(this.revokeModeratorItem); } // only room owners can edit admins list // if(room.getUserRole().getRoleIndex() == 70) // { // if(roleIndex != 60 && roleIndex >= 30) // // room owners can grant members or unaffiliated users as admins // this.add(this.grantAdminItem); // else if(roleIndex == 60) // this.add(this.revokeAdminItem); // // // room owners can edit owners list // if(roleIndex != 70 && roleIndex >= 40) // this.add(this.grantOwnershipItem); // else if(roleIndex == 70) // this.add(this.revokeOwnershipItem); // } } } /** * Handles the <tt>ActionEvent</tt>. Determines which menu item was * selected and makes the appropriate operations. * * @param e the <tt>ActionEvent</tt> that notified us */ public void actionPerformed(ActionEvent e) { String menuItemName = ((JMenuItem) e.getSource()).getName(); if (menuItemName.equals("kickItem")) { ChatOperationReasonDialog reasonDialog = new ChatOperationReasonDialog(); int result = new ChatOperationReasonDialog().showDialog(); if (result == MessageDialog.OK_RETURN_CODE) new KickParticipantThread( room, reasonDialog.getReason()).start(); } else if (menuItemName.equals("banItem")) { ChatOperationReasonDialog reasonDialog = new ChatOperationReasonDialog(); int result = reasonDialog.showDialog(); if (result == MessageDialog.OK_RETURN_CODE) new BanParticipantThread( room, reasonDialog.getReason()).start(); } else if (menuItemName.equals("changeRoomSubjectItem")) { ChatOperationReasonDialog reasonDialog = new ChatOperationReasonDialog( chatPanel.getChatContainer().getFrame(), GuiActivator.getResources().getI18NString( "service.gui.CHANGE_ROOM_SUBJECT"), GuiActivator.getResources().getI18NString( "service.gui.CHANGE_ROOM_SUBJECT_LABEL"), "Ok", false); //reasonDialog.setIconImage( //ImageLoader.getImage(ImageLoader.CHANGE_ROOM_SUBJECT_ICON_16x16)); reasonDialog.setReasonFieldText(room.getSubject()); int result = reasonDialog.showDialog(); if (result == MessageDialog.OK_RETURN_CODE) { try { room.setSubject(reasonDialog.getReason().trim()); } catch (OperationFailedException ex) { ex.printStackTrace(); } } } else if (menuItemName.equals("changeNicknameItem")) { ChatOperationReasonDialog reasonDialog = new ChatOperationReasonDialog( chatPanel.getChatContainer().getFrame(), GuiActivator.getResources().getI18NString( "service.gui.CHANGE_NICKNAME"), GuiActivator.getResources().getI18NString( "service.gui.CHANGE_NICKNAME_LABEL"), "Ok", false, true); reasonDialog.setIconImage(ImageLoader.getImage( ImageLoader.CHANGE_NICKNAME_ICON)); reasonDialog.setReasonFieldText(chatContact.getName()); int result = reasonDialog.showDialog(); if (result == MessageDialog.OK_RETURN_CODE) { String nickname = reasonDialog.getReason().trim(); try { room.setUserNickname(nickname); ConfigurationUtils.updateChatRoomProperty( room.getParentProvider(), room.getIdentifier(), "userNickName", nickname); } catch (OperationFailedException ex) { String errorMessage = null; if(ex.getErrorCode() == OperationFailedException.IDENTIFICATION_CONFLICT) { errorMessage = GuiActivator.getResources() .getI18NString( "service.gui.CHANGE_NICKNAME_CONFLICT_ERROR"); } else { errorMessage = ex.getLocalizedMessage(); } chatPanel.addErrorMessage( nickname, GuiActivator.getResources().getI18NString( "service.gui.CHANGE_NICKNAME_ERROR"), errorMessage); } } } else if (menuItemName.equals("grantVoiceItem")) { room.grantVoice(chatContact.getName()); ((ChatRoomMember)chatContact.getDescriptor()).setRole( ChatRoomMemberRole.MEMBER); } else if (menuItemName.equals("grantMembershipItem")) { room.grantMembership(((ChatRoomMember) chatContact.getDescriptor()).getContactAddress()); ((ChatRoomMember)chatContact.getDescriptor()).setRole( ChatRoomMemberRole.MEMBER); } else if(menuItemName.equals("grantModeratorItem")) { room.grantModerator(chatContact.getName()); ((ChatRoomMember)chatContact.getDescriptor()).setRole( ChatRoomMemberRole.MODERATOR); } else if(menuItemName.equals("grantAdminItem")) { room.grantAdmin(((ChatRoomMember) chatContact .getDescriptor()).getContactAddress()); ((ChatRoomMember)chatContact.getDescriptor()).setRole( ChatRoomMemberRole.ADMINISTRATOR); } else if(menuItemName.equals("grantOwnershipItem")) { room.grantOwnership(((ChatRoomMember) chatContact.getDescriptor()).getContactAddress()); ((ChatRoomMember)chatContact.getDescriptor()).setRole( ChatRoomMemberRole.OWNER); } else if(menuItemName.equals("revokeOwnershipItem")) { room.revokeOwnership(((ChatRoomMember) chatContact.getDescriptor()).getContactAddress()); ((ChatRoomMember)chatContact.getDescriptor()).setRole( ChatRoomMemberRole.ADMINISTRATOR); } else if(menuItemName.equals("revokeAdminItem")) { room.revokeAdmin(((ChatRoomMember) chatContact.getDescriptor()).getContactAddress()); ((ChatRoomMember)chatContact.getDescriptor()).setRole( ChatRoomMemberRole.MEMBER); } else if(menuItemName.equals("revokeModeratorItem")) { room.revokeModerator(chatContact.getName()); ((ChatRoomMember)chatContact.getDescriptor()).setRole( ChatRoomMemberRole.MEMBER); } else if(menuItemName.equals("revokeMembershipItem")) { room.revokeMembership(((ChatRoomMember) chatContact.getDescriptor()).getContactAddress()); ((ChatRoomMember)chatContact.getDescriptor()).setRole( ChatRoomMemberRole.GUEST); } else if(menuItemName.equals("revokeVoiceItem")) { room.revokeVoice(chatContact.getName()); ((ChatRoomMember)chatContact.getDescriptor()).setRole( ChatRoomMemberRole.SILENT_MEMBER); } else if(menuItemName.equals("sendPrivateMessageItem")) { ChatWindowManager chatWindowManager = GuiActivator.getUIService() .getChatWindowManager(); chatWindowManager.openPrivateChatForChatRoomMember(room, chatContact.getName()); } } /** * Kicks the the selected chat room participant or shows a message to the * user that he/she has not enough permissions to do a ban. */ private class KickParticipantThread extends Thread { private final ChatRoom chatRoom; private final String reason; KickParticipantThread(ChatRoom chatRoom, String reason) { this.chatRoom = chatRoom; this.reason = reason; } @Override public void run() { try { chatRoom.kickParticipant( (ChatRoomMember) chatContact.getDescriptor(), reason); } catch (OperationFailedException e) { logger.error("Failed to kick participant.", e); if (e.getErrorCode() == OperationFailedException.NOT_ENOUGH_PRIVILEGES) { ErrorDialog errorDialog = new ErrorDialog( chatPanel.getChatContainer().getFrame(), GuiActivator.getResources() .getI18NString("service.gui.KICK_FAILED"), GuiActivator.getResources().getI18NString( "service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS", new String[]{chatContact.getName()}), e); errorDialog.showDialog(); } else if (e.getErrorCode() == OperationFailedException.FORBIDDEN) { new ErrorDialog( chatPanel.getChatContainer().getFrame(), GuiActivator.getResources() .getI18NString("service.gui.KICK_FAILED"), GuiActivator.getResources() .getI18NString("service.gui.KICK_FAILED_NOT_ALLOWED", new String[]{chatContact.getName()}), e).showDialog(); } else { new ErrorDialog( chatPanel.getChatContainer().getFrame(), GuiActivator.getResources() .getI18NString("service.gui.KICK_FAILED"), GuiActivator.getResources() .getI18NString("service.gui.KICK_FAILED_GENERAL_ERROR", new String[]{chatContact.getName()}), e).showDialog(); } } } } /** * Bans the the selected chat room participant or shows a message to the * user that he/she has not enough permissions to do a ban. */ private class BanParticipantThread extends Thread { private final ChatRoom chatRoom; private final String reason; BanParticipantThread(ChatRoom chatRoom, String reason) { this.chatRoom = chatRoom; this.reason = reason; } @Override public void run() { try { chatRoom.banParticipant( (ChatRoomMember) chatContact.getDescriptor(), reason); } catch (OperationFailedException e) { logger.error("Failed to ban participant.", e); String errorTitle = GuiActivator.getResources() .getI18NString("service.gui.BAN_FAILED"); String errorMessageKey; switch (e.getErrorCode()) { case OperationFailedException.NOT_ENOUGH_PRIVILEGES: errorMessageKey = "service.gui.BAN_FAILED_NOT_ENOUGH_PERMISSIONS"; break; case OperationFailedException.FORBIDDEN: errorMessageKey = "service.gui.BAN_FAILED_NOT_ALLOWED"; break; default: errorMessageKey = "service.gui.BAN_FAILED_GENERAL_ERROR"; break; } new ErrorDialog( chatPanel.getChatContainer().getFrame(), errorTitle, GuiActivator.getResources().getI18NString( errorMessageKey, new String[]{chatContact.getName()}), e).showDialog(); } } } /** * Reloads icons for all menu items. */ public void loadSkin() { this.grantOwnershipItem.setIcon(ImageUtils.getScaledRoundedIcon( ImageLoader.getImage(ImageLoader.CHATROOM_MEMBER_OWNER), 16, 16)); this.grantAdminItem.setIcon(ImageUtils.getScaledRoundedIcon( ImageLoader.getImage(ImageLoader.CHATROOM_MEMBER_ADMIN), 16, 16)); this.grantMembershipItem.setIcon(ImageUtils.getScaledRoundedIcon( ImageLoader.getImage(ImageLoader.CHATROOM_MEMBER_STANDARD), 16, 16)); this.grantModeratorItem.setIcon(ImageUtils.getScaledRoundedIcon( ImageLoader.getImage( ImageLoader.CHATROOM_MEMBER_MODERATOR), 16, 16)); this.grantVoiceItem.setIcon(ImageUtils.getScaledRoundedIcon( ImageLoader.getImage(ImageLoader.CHATROOM_MEMBER_STANDARD), 16, 16)); this.revokeAdminItem.setIcon(ImageUtils.getScaledRoundedIcon( ImageLoader.getImage(ImageLoader.CHATROOM_MEMBER_STANDARD), 16, 16)); this.revokeMembershipItem.setIcon(ImageUtils.getScaledRoundedIcon( ImageLoader.getImage(ImageLoader.CHATROOM_MEMBER_GUEST), 16, 16)); this.revokeModeratorItem.setIcon(ImageUtils.getScaledRoundedIcon( ImageLoader.getImage(ImageLoader.CHATROOM_MEMBER_STANDARD), 16, 16)); this.revokeOwnershipItem.setIcon(ImageUtils.getScaledRoundedIcon( ImageLoader.getImage(ImageLoader.CHATROOM_MEMBER_ADMIN), 16, 16)); this.revokeVoiceItem.setIcon(ImageUtils.getScaledRoundedIcon( ImageLoader.getImage(ImageLoader.CHAT_ROOM_REVOKE_VOICE), 16, 16)); this.kickItem.setIcon(new ImageIcon(ImageLoader.getImage( ImageLoader.KICK_ICON_16x16))); this.banItem.setIcon(new ImageIcon(ImageLoader.getImage( ImageLoader.BAN_ICON_16x16))); this.changeNicknameItem.setIcon(new ImageIcon(ImageLoader.getImage( ImageLoader.CHANGE_NICKNAME_ICON_16x16))); this.changeRoomSubjectItem.setIcon(new ImageIcon(ImageLoader.getImage( ImageLoader.CHANGE_ROOM_SUBJECT_ICON_16x16))); } }