/*
* XNap
*
* A pure java file sharing client.
*
* See AUTHORS for copyright information.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package xnap.gui.menu;
import xnap.XNap;
import xnap.gui.UserActionManager;
import xnap.gui.XNapFrame;
import xnap.gui.event.UserSupport;
import xnap.net.IUser;
import xnap.util.LinkSpeed;
import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import org.apache.log4j.Logger;
public class UserMenu extends JMenu
{
//--- Constant(s) ---
//--- Data field(s) ---
private static Logger logger = Logger.getLogger(UserMenu.class);
private UserSupport us;
private LinkedList addedComponents = new LinkedList();
private boolean dynamic;
//--- Constructor(s) ---
public UserMenu(UserSupport us, boolean dynamic)
{
super(XNap.tr("Users"));
this.us = us;
this.dynamic = dynamic;
setIcon(XNapFrame.getIcon("users.png"));
setToolTipText(XNap.tr("User options"));
getPopupMenu().addPopupMenuListener(new PopupListener());
// add a dummy
addDummy();
}
public UserMenu(UserSupport us)
{
this(us, false);
}
//--- Method(s) ---
public void addActions(IUser[] users)
{
if (users == null || users.length == 0) {
addDummy();
return;
}
if (users.length == 1) {
addUser(this, users[0], !dynamic);
}
else {
// single users
HashSet s = new HashSet(Arrays.asList(users));
users = (IUser[])s.toArray(new IUser[0]);
Arrays.sort(users, new UserComparator());
HashMap menuByUser = createMenuByUser(users);
for (int i = 0; i < users.length; i++) {
Container parent = getMenuByUser(menuByUser, users[i]);
addUser(parent, users[i], true);
}
for (Iterator i = menuByUser.values().iterator(); i.hasNext();) {
Container jm = (Container)i.next();
int count = ((jm instanceof JMenu) ? ((JMenu)jm).getItemCount()
: jm.getComponentCount());
if (jm != this && count == 0) {
removeComponent(this, jm);
}
}
// all users sub menu
AbstractAction[] actions
= UserActionManager.getInstance().getActions(users);
if (actions.length > 0) {
JMenu jm = new JMenu(XNap.tr("All Users")
+ " (" + users.length + ")");
for (int i = 0; i < actions.length; i++) {
jm.add(actions[i]);
}
addComponent(this, new JPopupMenu.Separator());
addComponent(this, jm);
}
}
}
protected void addComponent(Container jm, Component c)
{
jm.add(c);
if (jm == this) {
addedComponents.add(c);
}
}
protected void addDummy()
{
addComponent
(this, new JMenuItem("(" + XNap.tr("No Users Selected") + ")"));
}
protected void addLabel(Container jm, String s)
{
addComponent(jm, new JLabel(s));
}
protected void addUser(Container parent, IUser u, boolean createSubMenu)
{
if (createSubMenu) {
JMenu jm = new JMenu(u.getName());
addComponent(parent, jm);
parent = jm;
}
AbstractAction[] actions
= UserActionManager.getInstance().getActions(u);
if (actions.length == 0) {
parent.setEnabled(false);
}
else {
for (int i = 0; i < actions.length; i++) {
addComponent(parent, new JMenuItem(actions[i]));
}
addUserInfo(parent, u);
}
}
public void addUserInfo(Container jm, IUser user)
{
if (user.getClientInfo() != null) {
addComponent(jm, new JPopupMenu.Separator());
addLabel(jm, " " + XNap.tr("Client") + ": " + user.getClientInfo());
if (user.getFileCount() != -1) {
addLabel(jm, " " + XNap.tr("File Count") + ": " + user.getFileCount());
}
LinkSpeed l = new LinkSpeed(user.getLinkSpeed());
addLabel(jm, " " + XNap.tr("Link Speed") + ": " + l.toString());
}
}
protected HashMap createMenuByUser(IUser[] users)
{
HashMap menuByUser = new HashMap();
if (users.length <= 10) {
menuByUser.put(null, this);
}
else {
int slice = Math.min(users.length / 10, 26);
char first = 'A';
for (int i = 1; i < slice && first <= 'Z'; i++) {
char last = (char)('A' + i * (26 / slice) - 1);
createMenu(menuByUser, first, last);
first = (char)(last + 1);
}
createMenu(menuByUser, first, 'Z');
JMenu jm = new JMenu(XNap.tr("Other"));
menuByUser.put(null, jm);
addComponent(this, jm);
}
return menuByUser;
}
protected void createMenu(HashMap map, char first, char last)
{
String title = first + ((first != last) ? " - " + last : "");
JMenu jm = new JMenu(title);
addComponent(this, jm);
for (char i = first; i <= last; i++) {
map.put((new Character(i)).toString(), jm);
}
}
protected Container getMenuByUser(HashMap map, IUser u)
{
String s = u.getName();
if (s.length() > 0) {
JMenu jm = (JMenu)map.get(s.substring(0, 1).toUpperCase());
if (jm != null) {
return jm;
}
}
// fall back
return (Container)map.get(null);
}
protected void removeComponent(Container jm, Component c)
{
jm.remove(c);
if (jm == this) {
addedComponents.remove(c);
}
}
protected class PopupListener implements PopupMenuListener {
public void popupMenuCanceled(PopupMenuEvent e)
{
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e)
{
}
public void popupMenuWillBecomeVisible(PopupMenuEvent e)
{
for (Iterator i = addedComponents.iterator(); i.hasNext(); ) {
remove((Component)i.next());
}
addedComponents.clear();
addActions(us.getUsers());
}
}
public class UserComparator implements Comparator
{
public int compare(Object o1, Object o2)
{
IUser u1 = (IUser)o1;
IUser u2 = (IUser)o2;
return u1.getName().compareToIgnoreCase(u2.getName());
}
}
}