/**
* $RCSfile: ,v $
* $Revision: $
* $Date: $
*
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
*
* 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 org.jivesoftware.fastpath.workspace.panes;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import org.jivesoftware.fastpath.FastpathPlugin;
import org.jivesoftware.fastpath.FpRes;
import org.jivesoftware.fastpath.resources.FastpathRes;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.Form;
import org.jivesoftware.smackx.muc.Affiliate;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.workgroup.agent.AgentRoster;
import org.jivesoftware.smackx.workgroup.agent.AgentRosterListener;
import org.jivesoftware.smackx.workgroup.packet.AgentStatus;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.UserManager;
import org.jivesoftware.spark.ui.conferences.ConferenceUtils;
import org.jivesoftware.spark.util.ModelUtil;
import org.jivesoftware.spark.util.SwingWorker;
import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.settings.local.LocalPreferences;
import org.jivesoftware.sparkimpl.settings.local.SettingsManager;
/**
* UI to show all chats occuring.
*/
public final class CurrentActivity extends JPanel {
private static final long serialVersionUID = 1L;
private DefaultListModel model = new DefaultListModel();
private JList list = new JList(model);
private JFrame mainFrame;
private JLabel activeConversations;
private int counter = 0;
/**
* Add listeners and construct UI.
*/
public CurrentActivity() {
init();
}
private void init() {
this.setLayout(new BorderLayout());
final BackgroundPane titlePane = new BackgroundPane() {
private static final long serialVersionUID = 3127229816651522537L;
public Dimension getPreferredSize() {
final Dimension size = super.getPreferredSize();
size.width = 0;
return size;
}
};
titlePane.setLayout(new GridBagLayout());
titlePane.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.LIGHT_GRAY));
JLabel userImage = new JLabel(FastpathRes.getImageIcon(FastpathRes.FASTPATH_IMAGE_24x24));
userImage.setHorizontalAlignment(JLabel.LEFT);
userImage.setText(FpRes.getString("title.current.active.conversation"));
titlePane.add(userImage, new GridBagConstraints(0, 0, 4, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0));
userImage.setFont(new Font("Dialog", Font.BOLD, 12));
activeConversations = new JLabel("0");
titlePane.add(new JLabel(FpRes.getString("title.number.of.active.conversations") +":"), new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
titlePane.add(activeConversations, new GridBagConstraints(1, 1, 1, 3, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
this.add(titlePane, BorderLayout.NORTH);
this.add(list, BorderLayout.CENTER);
list.setCellRenderer(new HistoryItemRenderer());
// Add current chats
addCurrentChats();
list.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent mouseEvent) {
checkPopup(mouseEvent);
}
public void mousePressed(MouseEvent mouseEvent) {
checkPopup(mouseEvent);
}
});
}
public void addCurrentChats() {
SwingWorker agentWorker = new SwingWorker() {
AgentRoster agentRoster;
Collection agentSet;
public Object construct() {
agentRoster = FastpathPlugin.getAgentSession().getAgentRoster();
agentSet = agentRoster.getAgents();
return agentSet;
}
public void finished() {
agentRoster.addListener(new AgentRosterListener() {
public void agentAdded(String jid) {
}
public void agentRemoved(String jid) {
}
public void presenceChanged(Presence presence) {
String agentJID = StringUtils.parseBareAddress(presence.getFrom());
agentJID = UserManager.unescapeJID(agentJID);
AgentStatus agentStatus = (AgentStatus)presence.getExtension("agent-status", "http://jabber.org/protocol/workgroup");
String status = presence.getStatus();
if (status == null) {
status = "Available";
}
if (agentStatus != null) {
List list = agentStatus.getCurrentChats();
// Add new ones.
Iterator iter = list.iterator();
while (iter.hasNext()) {
AgentStatus.ChatInfo chatInfo = (AgentStatus.ChatInfo)iter.next();
Date startDate = chatInfo.getDate();
String username = chatInfo.getUserID();
String nickname = chatInfo.getUsername();
if (!ModelUtil.hasLength(nickname)) {
nickname = FpRes.getString("message.not.specified");
}
String question = chatInfo.getQuestion();
if (!ModelUtil.hasLength(question)) {
question = "No question asked";
}
String email = chatInfo.getEmail();
if (!ModelUtil.hasLength(email)) {
email = FpRes.getString("message.not.specified");
}
addAgentChat(agentJID, nickname, email, question, startDate, chatInfo.getSessionID());
}
}
}
});
}
};
agentWorker.start();
}
private void addAgentChat(String agent, String visitor, String email, String question, Date startDate, String session) {
// Update counter.
counter++;
activeConversations.setText(Integer.toString(counter));
// Conversation Item
ConversationItem item = new ConversationItem(agent, visitor, startDate, email, question, session);
model.addElement(item);
}
private void checkPopup(MouseEvent e) {
if (e.isPopupTrigger()) {
// Check if monitor
try {
boolean isMonitor = FastpathPlugin.getAgentSession().hasMonitorPrivileges(SparkManager.getConnection());
if (isMonitor) {
JPopupMenu menu = new JPopupMenu();
int location = list.locationToIndex(e.getPoint());
list.setSelectedIndex(location);
ConversationItem item = (ConversationItem)list.getSelectedValue();
final String sessionID = item.getSessionID();
Action joinAction = new AbstractAction() {
private static final long serialVersionUID = -3198414924157880065L;
public void actionPerformed(ActionEvent actionEvent) {
// Get Conference
try {
Collection col = MultiUserChat.getServiceNames(SparkManager.getConnection());
if (col.size() == 0) {
return;
}
String serviceName = (String)col.iterator().next();
String roomName = sessionID + "@" + serviceName;
final LocalPreferences pref = SettingsManager.getLocalPreferences();
final String nickname = pref.getNickname();
MultiUserChat muc = new MultiUserChat(SparkManager.getConnection(), roomName);
ConferenceUtils.enterRoom(muc, roomName, nickname, null);
if (muc.isJoined()) {
// Try and remove myself as an owner if I am one.
Collection owners = null;
try {
owners = muc.getOwners();
}
catch (XMPPException e1) {
return;
}
Iterator iter = owners.iterator();
List<String> list = new ArrayList<String>();
while (iter.hasNext()) {
Affiliate affilitate = (Affiliate)iter.next();
String jid = affilitate.getJid();
if (!jid.equals(SparkManager.getSessionManager().getBareAddress())) {
list.add(jid);
}
}
if (list.size() > 0) {
Form form = muc.getConfigurationForm().createAnswerForm();
form.setAnswer("muc#roomconfig_roomowners", list);
// new DataFormDialog(groupChat, form);
muc.sendConfigurationForm(form);
}
}
}
catch (Exception e1) {
Log.error(e1);
}
}
};
joinAction.putValue(Action.NAME, FpRes.getString("menuitem.join.chat"));
menu.add(joinAction);
Action monitorAction = new AbstractAction() {
private static final long serialVersionUID = 7292337790553806820L;
public void actionPerformed(ActionEvent actionEvent) {
// Make user an owner.
try {
FastpathPlugin.getAgentSession().makeRoomOwner(SparkManager.getConnection(), sessionID);
Collection<String> col = MultiUserChat.getServiceNames(SparkManager.getConnection());
if (col.size() == 0) {
return;
}
String serviceName = (String)col.iterator().next();
String roomName = sessionID + "@" + serviceName;
LocalPreferences pref = SettingsManager.getLocalPreferences();
final String nickname = pref.getNickname();
MultiUserChat muc = new MultiUserChat(SparkManager.getConnection(), roomName);
ConferenceUtils.enterRoom(muc, roomName, nickname, null);
}
catch (XMPPException e1) {
Log.error(e1);
}
}
};
monitorAction.putValue(Action.NAME, FpRes.getString("menuitem.monitor.chat"));
menu.add(monitorAction);
menu.show(list, e.getX(), e.getY());
}
}
catch (XMPPException e1) {
Log.error(e1);
return;
}
}
}
public void showDialog() {
if (mainFrame == null) {
mainFrame = new JFrame(FpRes.getString("title.current.conversations"));
}
if (mainFrame.isVisible()) {
return;
}
mainFrame.setIconImage(SparkManager.getMainWindow().getIconImage());
mainFrame.getContentPane().setLayout(new BorderLayout());
mainFrame.getContentPane().add(new JScrollPane(this));
mainFrame.pack();
mainFrame.setSize(400, 400);
mainFrame.setLocationRelativeTo(SparkManager.getMainWindow());
mainFrame.setVisible(true);
}
}