/** * $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.sparkimpl.plugin.alerts; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JDialog; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import org.jivesoftware.resource.Res; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.spark.SparkManager; import org.jivesoftware.spark.component.CheckNode; import org.jivesoftware.spark.component.CheckTree; import org.jivesoftware.spark.component.TitlePanel; import org.jivesoftware.spark.ui.ChatInputEditor; import org.jivesoftware.spark.ui.ContactGroup; import org.jivesoftware.spark.ui.ContactItem; import org.jivesoftware.spark.ui.ContactList; import org.jivesoftware.spark.util.ModelUtil; /** * Allows for better selective broadcasting. * * @author Derek DeMoro */ public class BroadcastDialog extends JPanel { private static final long serialVersionUID = -8998994627855985137L; private ChatInputEditor messageBox; private JCheckBox OfflineUsers = new JCheckBox(Res.getString("checkbox.broadcast.hide.offline.user")); private JRadioButton normalMessageButton; private ArrayList<ArrayList<Object>> NodesGroups = new ArrayList<ArrayList<Object>>(); private List<CheckNode> nodes = new ArrayList<CheckNode>(); private List<CheckNode> groupNodes = new ArrayList<CheckNode>(); private CheckNode rosterNode; private CheckTree checkTree; private Integer OfflineGroup; public BroadcastDialog() { setLayout(new GridBagLayout()); rosterNode = new CheckNode(Res.getString("title.roster")); checkTree = new CheckTree(rosterNode); final ContactList contactList = SparkManager.getWorkspace().getContactList(); // creates the List for the Online Users String groupName = Res.getString("status.online"); CheckNode groupNode = new CheckNode(groupName); groupNodes.add(groupNode); rosterNode.add(groupNode); List<String> onlineJIDs = new ArrayList<String>(); //ContactGroup groupp; for(ContactGroup group : contactList.getContactGroups()) for (ContactItem item : group.getContactItems()) { if(item.isAvailable() && !onlineJIDs.contains(item.getJID())) { CheckNode itemNode = new CheckNode(item.getDisplayName(), false, item.getIcon()); itemNode.setAssociatedObject(item.getJID()); groupNode.add(itemNode); nodes.add(itemNode); onlineJIDs.add(item.getJID()); } } // Build out from Roster for (ContactGroup group : contactList.getContactGroups()) { groupName = group.getGroupName(); if (!group.hasAvailableContacts()) { continue; } groupNode = new CheckNode(groupName); groupNodes.add(groupNode); rosterNode.add(groupNode); // Now add contact items from contact group. for (ContactItem item : group.getContactItems()) { CheckNode itemNode = new CheckNode(item.getDisplayName(), false, item.getIcon()); itemNode.setAssociatedObject(item.getJID()); groupNode.add(itemNode); nodes.add(itemNode); } final List<ContactItem> offlineContacts = new ArrayList<ContactItem>(group.getOfflineContacts()); Collections.sort(offlineContacts, ContactList.ContactItemComparator); for (ContactItem item : offlineContacts) { CheckNode itemNode = new CheckNode(item.getDisplayName(), false, item.getIcon()); itemNode.setAssociatedObject(item.getJID()); groupNode.add(itemNode); nodes.add(itemNode); } } messageBox = new ChatInputEditor(); normalMessageButton = new JRadioButton(Res.getString("message.normal")); JRadioButton alertMessageButton = new JRadioButton(Res.getString("message.alert.notify")); ButtonGroup group = new ButtonGroup(); group.add(normalMessageButton); group.add(alertMessageButton); final JScrollPane pane = new JScrollPane(messageBox); pane.setBorder(BorderFactory.createTitledBorder(Res.getString("label.message").replace("&", ""))); final JScrollPane treePane = new JScrollPane(checkTree); treePane.setBorder(BorderFactory.createTitledBorder(Res.getString("message.send.to.these.people"))); treePane.getVerticalScrollBar().setBlockIncrement(200); treePane.getVerticalScrollBar().setUnitIncrement(20); // Add to UI add(pane, new GridBagConstraints(0, 0, 1, 1, 0.5, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); add(normalMessageButton, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0)); add(alertMessageButton, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 5, 2, 5), 0, 0)); add(treePane, new GridBagConstraints(1, 0, 1, 3, 0.5, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(2, 5, 2, 5), 0, 0)); add(OfflineUsers, new GridBagConstraints(1, 3, 1, 0, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(2, 5, 2, 5), 0, 0)); OfflineUsers.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { hideOfflineUsers(); } }); normalMessageButton.setSelected(true); checkTree.expandTree(); // Iterate through selected users. for (ContactItem item : contactList.getSelectedUsers()) { for (CheckNode node : nodes) { if (node.getAssociatedObject().toString().equals(item.getJID())) { node.setSelected(true); } } } } public void invokeDialog(ContactGroup group) { for (CheckNode node : groupNodes) { if (node.getUserObject().toString().equals(group.getGroupName())) { node.setSelected(true); } } invokeDialog(); } /** * Displays the broadcast dialog. */ public void invokeDialog() { final JDialog dlg; TitlePanel titlePanel; // Create the title panel for this dialog titlePanel = new TitlePanel(Res.getString("title.broadcast.message"), Res.getString("message.enter.broadcast.message"), null, true); // Construct main panel w/ layout. final JPanel mainPanel = new JPanel(); mainPanel.setLayout(new BorderLayout()); mainPanel.add(titlePanel, BorderLayout.NORTH); // The user should only be able to close this dialog. JButton okButton = new JButton(Res.getString("ok")); JButton closeButton = new JButton(Res.getString("close")); mainPanel.add(this,BorderLayout.CENTER); JPanel buttonpanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); buttonpanel.add(okButton); buttonpanel.add(closeButton); mainPanel.add(buttonpanel,BorderLayout.SOUTH); dlg = new JDialog(SparkManager.getMainWindow(), Res.getString("broadcast")); dlg.setContentPane(mainPanel); dlg.pack(); dlg.setSize(800, 600); dlg.setResizable(false); dlg.setLocationRelativeTo(SparkManager.getMainWindow()); // Add listener okButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (sendBroadcasts(dlg)) { dlg.setVisible(false); } } }); closeButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { dlg.setVisible(false); } }); dlg.setVisible(true); dlg.toFront(); dlg.requestFocus(); messageBox.requestFocus(); } private void hideOfflineUsers() { int i = 0; if (OfflineUsers.isSelected()) { final ContactList contactList = SparkManager.getWorkspace() .getContactList(); i = 0; for (CheckNode node : nodes) { if (contactList.getContactItemByDisplayName(node.toString()) .getPresence().getType() == Presence.Type.unavailable) { if (node.getParent() != null) { TreeNode parent = node.getParent(); TreeNode[] path = ((DefaultTreeModel) checkTree .getTree().getModel()).getPathToRoot(parent); ((DefaultTreeModel) checkTree.getTree().getModel()) .removeNodeFromParent(node); checkTree.getTree() .setSelectionPath(new TreePath(path)); NodesGroups.add(new ArrayList<Object>()); NodesGroups.get(i).add(parent); NodesGroups.get(i).add(node); i++; } } } for (int x = 0; x < groupNodes.size(); x++) { if (groupNodes.get(x).toString() .equals(Res.getString("group.offline"))) { OfflineGroup = x; TreeNode parent = groupNodes.get(x).getParent(); TreeNode[] path = ((DefaultTreeModel) checkTree.getTree() .getModel()).getPathToRoot(parent); ((DefaultTreeModel) checkTree.getTree().getModel()) .removeNodeFromParent(groupNodes.get(x)); checkTree.getTree().setSelectionPath(new TreePath(path)); } } } else { i = 0; DefaultMutableTreeNode child = groupNodes.get(OfflineGroup); ((DefaultTreeModel) checkTree.getTree().getModel()).insertNodeInto( child, rosterNode, rosterNode.getChildCount()); TreeNode[] path = ((DefaultTreeModel) checkTree.getTree() .getModel()).getPathToRoot(rosterNode); checkTree.getTree().expandPath(new TreePath(path)); checkTree.expandTree(); for (CheckNode node : nodes) { if (node.getParent() == null) { child = (CheckNode) NodesGroups.get(i).get(1); ((DefaultTreeModel) checkTree.getTree().getModel()) .insertNodeInto(child, ((CheckNode) NodesGroups .get(i).get(0)), ((CheckNode) NodesGroups .get(i).get(0)).getChildCount()); path = ((DefaultTreeModel) checkTree.getTree().getModel()) .getPathToRoot(node); checkTree.getTree().expandPath(new TreePath(path)); checkTree.expandTree(); i++; } } } } /** * Sends a broadcast message to all users selected. * @param dlg */ private boolean sendBroadcasts(JDialog dlg) { final Set<String> jids = new HashSet<String>(); for (CheckNode node : nodes) { if (node.isSelected()) { String jid = (String)node.getAssociatedObject(); jids.add(jid); } } if(jids.size() == 0) { JOptionPane.showMessageDialog(dlg, Res.getString("message.broadcast.no.user.selected"), Res.getString("title.error"), JOptionPane.ERROR_MESSAGE); return false; } String text = messageBox.getText(); if (!ModelUtil.hasLength(text)) { JOptionPane.showMessageDialog(dlg, Res.getString("message.broadcast.no.text"), Res.getString("title.error"), JOptionPane.ERROR_MESSAGE); return false; } for (String jid : jids) { final Message message = new Message(); message.setTo(jid); message.setBody(text); if (normalMessageButton.isSelected()) { message.setType(Message.Type.normal); } else { message.setType(Message.Type.headline); } SparkManager.getConnection().sendPacket(message); } return true; } }