/*
* 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.muc;
import java.util.*;
import net.java.sip.communicator.plugin.desktoputil.chat.*;
import net.java.sip.communicator.service.contactsource.*;
import net.java.sip.communicator.service.customcontactactions.*;
import net.java.sip.communicator.service.muc.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.*;
import org.jitsi.service.resources.*;
/**
* Implements CustomContactActionsService for MUC contact source.
*
* @author Hristo Terezov
*/
public class MUCCustomContactActionService
implements CustomContactActionsService
{
/**
* List of custom menu items.
*/
private final List> mucActionMenuItems
= new LinkedList>();
/**
* List of custom actions.
*/
private final List> mucActions
= new LinkedList>();
/**
*
*/
private static final String OWNER_CANT_REMOVE_CHATROOM_PROPERTY
= "net.java.sip.communicator.impl.muc.OWNER_CANT_REMOVE_CHATROOM";
/**
* Array of names for the custom actions.
*/
private String[] actionsNames = {
"leave",
"join",
"autojoin",
"autojoin_pressed",
"destroy_chatroom"
};
/**
* Array of labels for the custom actions.
*/
private String[] actionsLabels = {
"service.gui.LEAVE",
"service.gui.JOIN",
"service.gui.JOIN_AUTOMATICALLY",
"service.gui.JOIN_AUTOMATICALLY",
"service.gui.DESTROY_CHATROOM"
};
/**
* Array of icons for the custom actions.
*/
private String[] actionsIcons = {
"service.gui.icons.LEAVE_ICON_BUTTON",
"service.gui.icons.JOIN_ICON_BUTTON",
"service.gui.icons.AUTOJOIN_ON_ICON_BUTTON",
"service.gui.icons.AUTOJOIN_OFF_ICON_BUTTON",
"service.gui.icons.DESTROY_ICON_BUTTON"
};
/**
* Array of rollover icons for the custom actions.
*/
private String[] actionsIconsRollover = {
"service.gui.icons.LEAVE_ICON_ROLLOVER_BUTTON",
"service.gui.icons.JOIN_ICON_ROLLOVER_BUTTON",
"service.gui.icons.AUTOJOIN_ON_ICON_ROLLOVER_BUTTON",
"service.gui.icons.AUTOJOIN_OFF_ICON_ROLLOVER_BUTTON",
"service.gui.icons.DESTROY_ICON_ROLLOVER_BUTTON"
};
/**
* Array of pressed icons for the custom actions.
*/
private String[] actionsIconsPressed = {
"service.gui.icons.LEAVE_ICON_PRESSED_BUTTON",
"service.gui.icons.JOIN_ICON_PRESSED_BUTTON",
"service.gui.icons.AUTOJOIN_ON_ICON_PRESSED_BUTTON",
"service.gui.icons.AUTOJOIN_OFF_ICON_PRESSED_BUTTON",
"service.gui.icons.DESTROY_ICON_PRESSED_BUTTON"
};
/**
* Array of names for the custom menu items.
*/
private String[] menuActionsNames = {
"open",
"join",
"join_as",
"leave",
"remove",
"change_nick",
"autojoin",
"autojoin_pressed",
"open_automatically",
"destroy_chatroom"
};
/**
* Array of labels for the custom menu items.
*/
private String[] menuActionsLabels = {
"service.gui.OPEN",
"service.gui.JOIN",
"service.gui.JOIN_AS",
"service.gui.LEAVE",
"service.gui.REMOVE",
"service.gui.CHANGE_NICK",
"service.gui.JOIN_AUTOMATICALLY",
"service.gui.DONT_JOIN_AUTOMATICALLY",
"service.gui.OPEN_AUTOMATICALLY",
"service.gui.DESTROY_CHATROOM"
};
/**
* Array of icons for the custom menu items.
*/
private String[] menuActionsIcons = {
"service.gui.icons.CHAT_ROOM_16x16_ICON",
"service.gui.icons.JOIN_ICON",
"service.gui.icons.JOIN_AS_ICON",
"service.gui.icons.LEAVE_ICON",
"service.gui.icons.REMOVE_CHAT_ICON",
"service.gui.icons.RENAME_16x16_ICON",
"service.gui.icons.AUTOJOIN",
"service.gui.icons.AUTOJOIN",
"service.gui.icons.OPEN_AUTOMATICALLY",
"service.gui.icons.DESTROY_CHATROOM"
};
/**
* A runnable that leaves the chat room.
*/
private MUCCustomActionRunnable leaveRunnable
= new MUCCustomActionRunnable()
{
@Override
public void run()
{
ChatRoomWrapper leavedRoomWrapped
= MUCActivator.getMUCService().leaveChatRoom(
chatRoomWrapper);
if(leavedRoomWrapped != null)
MUCActivator.getUIService().closeChatRoomWindow(
leavedRoomWrapped);
}
};
/**
* A runnable that joins the chat room.
*/
private MUCCustomActionRunnable joinRunnable
= new MUCCustomActionRunnable()
{
@Override
public void run()
{
String[] joinOptions;
String subject = null;
String nickName = null;
nickName =
ConfigurationUtils.getChatRoomProperty(
chatRoomWrapper.getParentProvider()
.getProtocolProvider(), chatRoomWrapper
.getChatRoomID(), "userNickName");
if(nickName == null)
{
joinOptions = ChatRoomJoinOptionsDialog.getJoinOptions(
chatRoomWrapper.getParentProvider()
.getProtocolProvider(),
chatRoomWrapper.getChatRoomID(),
MUCActivator.getGlobalDisplayDetailsService()
.getDisplayName(chatRoomWrapper.getParentProvider()
.getProtocolProvider()));
nickName = joinOptions[0];
subject = joinOptions[1];
}
if (nickName != null)
MUCActivator.getMUCService().joinChatRoom(chatRoomWrapper,
nickName, null, subject);
}
};
/**
* A runnable that sets / unsets auto join setting of the chat room.
*/
private MUCCustomActionRunnable autoJoinRunnable
= new MUCCustomActionRunnable()
{
@Override
public void run()
{
chatRoomWrapper.setAutoJoin(!chatRoomWrapper.isAutojoin());
}
};
/**
* A runnable that destroys the chat room.
*/
private MUCCustomActionRunnable destroyActionRunnable
= new MUCCustomActionRunnable()
{
@Override
public void run()
{
String destroyOptions[]
= ChatRoomDestroyReasonDialog.getDestroyOptions();
if(destroyOptions == null)
return;
MUCActivator.getMUCService().destroyChatRoom(chatRoomWrapper,
destroyOptions[0], destroyOptions[1]);
}
};
/**
* Array of MUCCustomActionRunnable objects for the custom menu
* items. They will be executed when the item is pressed.
*/
private MUCCustomActionRunnable[] actionsRunnable = {
leaveRunnable,
joinRunnable,
autoJoinRunnable,
autoJoinRunnable,
destroyActionRunnable
};
/**
* Array of MUCCustomActionRunnable objects for the custom menu
* items. They will be executed when the item is pressed.
*/
private MUCCustomActionRunnable[] menuActionsRunnable = {
new MUCCustomActionRunnable()
{
@Override
public void run()
{
MUCActivator.getMUCService().openChatRoom(chatRoomWrapper);
}
},
joinRunnable,
new MUCCustomActionRunnable()
{
@Override
public void run()
{
String[] joinOptions;
joinOptions = ChatRoomJoinOptionsDialog.getJoinOptions(
chatRoomWrapper.getParentProvider().getProtocolProvider(),
chatRoomWrapper.getChatRoomID(),
MUCActivator.getGlobalDisplayDetailsService()
.getDisplayName(chatRoomWrapper.getParentProvider()
.getProtocolProvider()));
if(joinOptions[0] == null)
return;
MUCActivator.getMUCService()
.joinChatRoom(chatRoomWrapper, joinOptions[0], null,
joinOptions[1]);
}
},
leaveRunnable,
new MUCCustomActionRunnable()
{
@Override
public void run()
{
ChatRoom chatRoom = chatRoomWrapper.getChatRoom();
if (chatRoom != null)
{
ChatRoomWrapper leavedRoomWrapped
= MUCActivator.getMUCService().leaveChatRoom(
chatRoomWrapper);
if(leavedRoomWrapped != null)
MUCActivator.getUIService().closeChatRoomWindow(
leavedRoomWrapped);
}
MUCActivator.getUIService().closeChatRoomWindow(chatRoomWrapper);
MUCActivator.getMUCService().removeChatRoom(chatRoomWrapper);
}
},
new MUCCustomActionRunnable()
{
@Override
public void run()
{
ChatRoomJoinOptionsDialog.getJoinOptions(true,
chatRoomWrapper.getParentProvider().getProtocolProvider(),
chatRoomWrapper.getChatRoomID(),
MUCActivator.getGlobalDisplayDetailsService()
.getDisplayName(chatRoomWrapper.getParentProvider()
.getProtocolProvider()));
}
},
autoJoinRunnable,
autoJoinRunnable,
new MUCCustomActionRunnable()
{
@Override
public void run()
{
MUCActivator.getUIService().showChatRoomAutoOpenConfigDialog(
chatRoomWrapper.getParentProvider().getProtocolProvider(),
chatRoomWrapper.getChatRoomID());
}
},
destroyActionRunnable
};
/**
* Array of EnableChecker objects for the custom menu items. They
* are used to check if the item is enabled or disabled.
*/
private EnableChecker[] actionsEnabledCheckers = {
null,
new JoinEnableChecker(),
new JoinEnableChecker(),
new LeaveEnableChecker(),
null,
null,
null,
null,
null,
null
};
/**
* The resource management service instance.
*/
ResourceManagementService resources = MUCActivator.getResources();
/**
* Constructs the custom actions.
*/
public MUCCustomContactActionService()
{
for(int i = 0; i < menuActionsLabels.length; i++)
{
MUCActionMenuItems item
= new MUCActionMenuItems(
menuActionsNames[i],
menuActionsLabels[i],
menuActionsIcons[i],
menuActionsRunnable[i]);
mucActionMenuItems.add(item);
if(actionsEnabledCheckers[i] != null)
item.setEnabled(actionsEnabledCheckers[i]);
}
for(int i = 0; i < actionsLabels.length; i++)
{
MUCAction item = new MUCAction(
actionsNames[i],
actionsLabels[i],
actionsIcons[i],
actionsIconsRollover[i],
actionsIconsPressed[i],
actionsRunnable[i]);
mucActions.add(item);
}
}
/**
* Returns the template class that this service has been initialized with
*
* @return the template class
*/
public Class getContactSourceClass()
{
return SourceContact.class;
}
@Override
public Iterator>
getCustomContactActionsMenuItems()
{
return mucActionMenuItems.iterator();
}
@Override
public Iterator> getCustomContactActions()
{
return mucActions.iterator();
}
/**
* Implements the MUC custom action.
*/
private class MUCAction
implements ContactAction
{
/**
* The text of the action.
*/
private String text;
/**
* The icon of the action
*/
private byte[] icon;
/**
* The icon that is shown when the action is pressed.
*/
private byte[] iconPressed;
/**
* The runnable that is executed when the action is pressed.
*/
private MUCCustomActionRunnable actionPerformed;
/**
* The icon that is shown when the mouse is over the action.
*/
private byte[] iconRollover;
/**
* The name of the action.
*/
private String name;
/**
* Constructs MUCAction instance.
*
* @param textKey the key used to retrieve the label for the action.
* @param iconKey the key used to retrieve the icon for the action.
* @param actionPerformed the action executed when the action is
* pressed.
* @param iconRolloverKey the key used to retrieve the rollover icon for
* the action.
* @param iconPressedKey the key used to retrieve the pressed icon for
* the action.
*/
public MUCAction(String name, String textKey, String iconKey,
String iconRolloverKey, String iconPressedKey,
MUCCustomActionRunnable actionPerformed)
{
this.name = name;
this.text = resources.getI18NString(textKey);
this.icon = resources.getImageInBytes(iconKey);
this.iconRollover = resources.getImageInBytes(iconRolloverKey);
this.iconPressed = resources.getImageInBytes(iconPressedKey);
this.actionPerformed = actionPerformed;
}
@Override
public void actionPerformed(SourceContact actionSource, int x, int y)
throws OperationFailedException
{
if(!(actionSource instanceof ChatRoomSourceContact))
return;
actionPerformed.setContact(actionSource);
new Thread(actionPerformed).start();
}
@Override
public byte[] getIcon()
{
return icon;
}
@Override
public byte[] getRolloverIcon()
{
return iconRollover;
}
@Override
public byte[] getPressedIcon()
{
return iconPressed;
}
@Override
public String getToolTipText()
{
return text;
}
@Override
public boolean isVisible(SourceContact actionSource)
{
if(actionSource instanceof ChatRoomSourceContact)
{
if(name.equals("leave"))
{
return actionsEnabledCheckers[3].check(actionSource);
}
else if(name.equals("join"))
{
return actionsEnabledCheckers[1].check(actionSource);
}
else if(name.equals("destroy_chatroom"))
{
ChatRoomSourceContact contact
= (ChatRoomSourceContact) actionSource;
ChatRoomWrapper room = MUCActivator.getMUCService()
.findChatRoomWrapperFromSourceContact(contact);
if(room == null || room.getChatRoom() == null)
return false;
if(room.getChatRoom().getUserRole().equals(ChatRoomMemberRole.OWNER))
return true;
return false;
}
else
{
ChatRoomSourceContact contact
= (ChatRoomSourceContact) actionSource;
ChatRoomWrapper room = MUCActivator.getMUCService()
.findChatRoomWrapperFromSourceContact(contact);
if(room == null)
return false;
if(name.equals("autojoin"))
return room.isAutojoin();
else if(name.equals("autojoin_pressed"))
return !room.isAutojoin();
}
}
return false;
}
}
/**
* Implements the MUC custom menu items.
*/
private class MUCActionMenuItems
implements ContactActionMenuItem
{
/**
* The label for the menu item.
*/
private String text;
/**
* The the icon for the menu item.
*/
private byte[] image;
/**
* The action executed when the menu item is pressed.
*/
private MUCCustomActionRunnable actionPerformed;
/**
* Object that is used to check if the item is enabled or disabled.
*/
private EnableChecker enabled;
/**
* The name of the custom action menu item.
*/
private String name;
/**
* The mnemonic for the action.
*/
private char mnemonics;
/**
* Constructs MUCActionMenuItems instance.
*
* @param textKey the key used to retrieve the label for the menu item.
* @param imageKey the key used to retrieve the icon for the menu item.
* @param actionPerformed the action executed when the menu item is
* pressed.
*/
public MUCActionMenuItems(String name, String textKey, String imageKey,
MUCCustomActionRunnable actionPerformed)
{
this.text = resources.getI18NString(textKey);
this.image = (imageKey == null)? null :
resources.getImageInBytes(imageKey);
this.actionPerformed = actionPerformed;
this.enabled = new EnableChecker();
this.name = name;
this.mnemonics = resources.getI18nMnemonic(textKey);
}
@Override
public void actionPerformed(SourceContact actionSource)
throws OperationFailedException
{
if(!(actionSource instanceof ChatRoomSourceContact))
return;
actionPerformed.setContact(actionSource);
new Thread(actionPerformed).start();
}
@Override
public byte[] getIcon()
{
return image;
}
@Override
public String getText(SourceContact actionSource)
{
if(!(actionSource instanceof ChatRoomSourceContact))
return "";
if(!name.equals("open_automatically"))
return text;
String openAutomaticallyValue
= MUCService.getChatRoomAutoOpenOption(
((ChatRoomSourceContact)actionSource).getProvider(),
((ChatRoomSourceContact)actionSource).getChatRoomID());
if(openAutomaticallyValue == null)
openAutomaticallyValue = MUCService.DEFAULT_AUTO_OPEN_BEHAVIOUR;
String openAutomaticallyKey = MUCService.autoOpenConfigValuesTexts
.get(openAutomaticallyValue);
return "" + text + "...
("
+ resources.getI18NString(openAutomaticallyKey)
+ ")";
}
@Override
public boolean isVisible(SourceContact actionSource)
{
if(!(actionSource instanceof ChatRoomSourceContact))
return false;
ChatRoomSourceContact contact
= (ChatRoomSourceContact) actionSource;
ChatRoomWrapper room = MUCActivator.getMUCService()
.findChatRoomWrapperFromSourceContact(contact);
if(name.equals("autojoin") || name.equals("autojoin_pressed"))
{
if(room == null)
return true;
if(name.equals("autojoin"))
return !room.isAutojoin();
if(name.equals("autojoin_pressed"))
return room.isAutojoin();
}
else if(name.equals("remove"))
{
if(room == null || room.getChatRoom() == null)
return true;
boolean ownerCannotRemoveRoom
= MUCActivator.getConfigurationService().getBoolean(
OWNER_CANT_REMOVE_CHATROOM_PROPERTY, false);
// when joined role will be owner or member
// when not joined and if we never has entered the room role
// will be guest, if we joined and left the room the role
// will be owner or member
if(room.getChatRoom().getUserRole().equals(
ChatRoomMemberRole.MEMBER))
{
return true;
}
else
{
if(ownerCannotRemoveRoom)
return false;
else
return true;
}
}
else if(name.equals("destroy_chatroom"))
{
if(room == null || room.getChatRoom() == null)
return false;
if(room.getChatRoom().getUserRole().equals(
ChatRoomMemberRole.OWNER))
return true;
return false;
}
return true;
}
@Override
public char getMnemonics()
{
return mnemonics;
}
@Override
public boolean isEnabled(SourceContact actionSource)
{
return enabled.check(actionSource);
}
/**
* Sets EnabledChecker instance that will be used to check if
* the item should be enabled or disabled.
*
* @param enabled the EnabledChecker instance.
*/
public void setEnabled(EnableChecker enabled)
{
this.enabled = enabled;
}
@Override
public boolean isCheckBox()
{
return false;
}
@Override
public boolean isSelected(SourceContact contact)
{
ChatRoomWrapper chatRoomWrapper = MUCActivator.getMUCService()
.findChatRoomWrapperFromSourceContact(contact);
if(chatRoomWrapper == null)
return false;
return chatRoomWrapper.isAutojoin();
}
}
/**
* Checks if the menu item should be enabled or disabled. This is default
* implementation. Always returns that the item should be enabled.
*/
private static class EnableChecker
{
/**
* Checks if the menu item should be enabled or disabled.
*
* @param contact the contact associated with the menu item.
* @return always true
*/
public boolean check(SourceContact contact)
{
return true;
}
}
/**
* Implements EnableChecker for the join menu items.
*/
private static class JoinEnableChecker
extends EnableChecker
{
/**
* Checks if the menu item should be enabled or disabled.
*
* @param contact the contact associated with the menu item.
* @return true if the item should be enabled and
* false if not.
*/
public boolean check(SourceContact contact)
{
ChatRoomWrapper chatRoomWrapper = MUCActivator.getMUCService()
.findChatRoomWrapperFromSourceContact(contact);
ChatRoom chatRoom = null;
if(chatRoomWrapper != null)
{
chatRoom = chatRoomWrapper.getChatRoom();
}
if((chatRoom != null) && chatRoom.isJoined())
return false;
return true;
}
}
/**
* Implements EnableChecker for the leave menu item.
*/
private static class LeaveEnableChecker
extends JoinEnableChecker
{
/**
* Checks if the menu item should be enabled or disabled.
*
* @param contact the contact associated with the menu item.
* @return true if the item should be enabled and
* false if not.
*/
public boolean check(SourceContact contact)
{
return !super.check(contact);
}
}
/**
* Implements base properties for the MUC menu items.These properties are
* used when the menu item is pressed.
*/
private abstract class MUCCustomActionRunnable
implements Runnable
{
/**
* The contact associated with the menu item.
*/
protected SourceContact contact;
/**
* The contact associated with the menu item.
*/
protected ChatRoomWrapper chatRoomWrapper;
/**
* Sets the source contact.
* @param contact the contact to set
*/
public void setContact(SourceContact contact)
{
this.contact = contact;
chatRoomWrapper = MUCActivator.getMUCService()
.findChatRoomWrapperFromSourceContact(contact);
}
}
}