/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.gui.main.chat;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import net.java.sip.communicator.impl.gui.lookandfeel.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.swing.*;
/**
* The ChatTransportSelectorBox represents the send via menu in the
* chat window. The menu contains all protocol specific transports. In the case
* of meta contact these would be all contacts for the currently selected meta
* contact chat.
*
* @author Yana Stamcheva
*/
public class ChatTransportSelectorBox
extends SIPCommMenuBar
implements ActionListener
{
private static final Logger logger
= Logger.getLogger(ChatTransportSelectorBox.class);
private final Map transportMenuItems =
new Hashtable();
private final SIPCommMenu menu = new SIPCommMenu();
private final ChatSession chatSession;
/**
* @param chatPanel Currently not used
*/
public ChatTransportSelectorBox(ChatPanel chatPanel,
ChatSession chatSession,
ChatTransport selectedChatTransport)
{
this.chatSession = chatSession;
this.menu.setPreferredSize(new Dimension(28, 24));
this.menu.setUI(new SIPCommSelectorMenuUI());
this.add(menu);
// as a default disable the menu, it will be enabled as soon as we add
// a valid menu item
this.menu.setEnabled(false);
Iterator chatTransports = chatSession.getChatTransports();
while (chatTransports.hasNext())
this.addChatTransport(chatTransports.next());
if (this.menu.getItemCount() > 0 &&
selectedChatTransport.allowsInstantMessage())
{
this.setSelected(selectedChatTransport);
}
}
/*
* Sets the menu to enabled or disabled. The menu is enabled, as soon as it
* contains one or more items. If it is empty, it is disabled.
*/
private void updateEnableStatus()
{
this.menu.setEnabled(this.menu.getItemCount() > 0);
}
/**
* Adds the given chat transport to the "send via" menu.
* Only add those that support IM.
*
* @param chatTransport The chat transport to add.
*/
public void addChatTransport(ChatTransport chatTransport)
{
if (chatTransport.allowsInstantMessage())
{
Image img = createTransportStatusImage(chatTransport);
JMenuItem menuItem = new JMenuItem(
"From: " + chatTransport.getProtocolProvider()
.getAccountID().getAccountAddress()
+ " To: " + chatTransport.getName(),
new ImageIcon(img));
menuItem.addActionListener(this);
this.transportMenuItems.put(chatTransport, menuItem);
this.menu.add(menuItem);
updateEnableStatus();
}
}
/**
* Removes the given chat transport from the "send via" menu. This method is
* used to update the "send via" menu when a protocol contact is moved or
* removed from the contact list.
*
* @param chatTransport the chat transport to be removed
*/
public void removeChatTransport(ChatTransport chatTransport)
{
this.menu.remove(transportMenuItems.get(chatTransport));
this.transportMenuItems.remove(chatTransport);
updateEnableStatus();
}
/**
* The listener of the chat transport selector box.
*/
public void actionPerformed(ActionEvent e)
{
JMenuItem menuItem = (JMenuItem) e.getSource();
for (Map.Entry transportMenuItem
: transportMenuItems.entrySet())
{
ChatTransport chatTransport = transportMenuItem.getKey();
if (transportMenuItem.getValue().equals(menuItem))
{
this.setSelected(chatTransport, (ImageIcon) menuItem.getIcon());
return;
}
}
if (logger.isDebugEnabled())
logger.debug( "Could not find contact for menu item "
+ menuItem.getText() + ". contactsTable("
+ transportMenuItems.size()+") is : "
+ transportMenuItems);
}
/**
* Obtains the status icon for the given chat transport and
* adds to it the account index information.
*
* @param chatTransport The chat transport for which to create the image.
* @return The indexed status image.
*/
public Image createTransportStatusImage(ChatTransport chatTransport)
{
return
ImageLoader.badgeImageWithProtocolIndex(
ImageLoader.getBytesInImage(
chatTransport.getStatus().getStatusIcon()),
chatTransport.getProtocolProvider());
}
/**
* Updates the chat transport presence status.
*
* @param chatTransport The chat transport to update.
*/
public void updateTransportStatus(ChatTransport chatTransport)
{
JMenuItem menuItem;
Icon icon;
if (chatTransport.equals(chatSession.getCurrentChatTransport())
&& !chatTransport.getStatus().isOnline())
{
ChatTransport newChatTransport
= chatSession.getCurrentChatTransport();
if(newChatTransport.getStatus().isOnline())
this.setSelected(newChatTransport);
}
if (!containsOtherOnlineContacts(chatTransport)
&& chatTransport.getStatus().isOnline())
{
this.setSelected(chatTransport);
}
menuItem = transportMenuItems.get(chatTransport);
// sometimes it may happen that menuItem is null
// it was removed for some reason, this maybe due to other bug
// anyway detect it to avoid NPE
if(menuItem == null)
return;
icon = new ImageIcon(createTransportStatusImage(chatTransport));
menuItem.setIcon(icon);
if(menu.getSelectedObject().equals(chatTransport))
{
this.menu.setIcon(icon);
}
}
/**
* In the "send via" menu selects the given contact and sets the given icon
* to the "send via" menu button.
*
* @param chatTransport
* @param icon
*/
private void setSelected(ChatTransport chatTransport, ImageIcon icon)
{
this.chatSession.setCurrentChatTransport(chatTransport);
SelectedObject selectedObject = new SelectedObject(icon, chatTransport);
this.menu.setSelected(selectedObject);
String tooltipText = "From: " + chatTransport.getProtocolProvider()
.getAccountID().getAccountAddress() + " To: ";
if(!chatTransport.getDisplayName()
.equals(chatTransport.getName()))
tooltipText += chatTransport.getDisplayName()
+ " (" + chatTransport.getName() + ")";
else
tooltipText += chatTransport.getDisplayName();
this.menu.setToolTipText(tooltipText);
}
/**
* Sets the selected contact to the given proto contact.
* @param chatTransport the proto contact to select
*/
public void setSelected(ChatTransport chatTransport)
{
this.setSelected(chatTransport,
new ImageIcon(createTransportStatusImage(chatTransport)));
}
/**
* Returns the protocol menu.
*
* @return the protocol menu
*/
public SIPCommMenu getMenu()
{
return menu;
}
/**
* Searches online contacts in the send via combo box.
*
* @return TRUE if the send via combo box contains online contacts, otherwise
* returns FALSE.
*/
private boolean containsOtherOnlineContacts(ChatTransport chatTransport)
{
for (ChatTransport comboChatTransport : transportMenuItems.keySet())
{
if(!comboChatTransport.equals(chatTransport)
&& comboChatTransport.getStatus().isOnline())
return true;
}
return false;
}
}