package org.chartsy.chatsy.chat.ui; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Image; import java.awt.Insets; import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.swing.DefaultComboBoxModel; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingConstants; import org.jivesoftware.smack.Roster; import org.jivesoftware.smack.RosterEntry; import org.jivesoftware.smack.RosterGroup; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smackx.Form; import org.jivesoftware.smackx.muc.MultiUserChat; import org.chartsy.chatsy.chat.ChatManager; import org.chartsy.chatsy.chat.ChatsyManager; import org.chartsy.chatsy.chat.Workspace; import org.chartsy.chatsy.chat.ui.rooms.GroupChatRoom; import org.chartsy.chatsy.chat.util.SwingWorker; import org.chartsy.chatsy.chatimpl.search.users.UserSearchService; import org.openide.DialogDescriptor; import org.openide.DialogDisplayer; import org.openide.util.ImageUtilities; import org.openide.util.NbPreferences; public class CommandPanel extends JPanel implements ActionListener { private static final String COMMAND_BUTTON_BG = "org/chartsy/chatsy/resources/command-btn.png"; private static final String ADD_ICON = "org/chartsy/chatsy/resources/add-icon.png"; private static final String CHAT_ICON = "org/chartsy/chatsy/resources/chat-icon.png"; private static final String SEARCH_ICON = "org/chartsy/chatsy/resources/search-icon.png"; private static Image buttonBackground; private static String[] addButtonTooltips = { "Create conference room", "Add a contact" }; private static String[] chatButtonTooltips = { "Join conference", "Start chat" }; private int selectedTab = 0; private CommandButton addButton; private CommandButton chatButton; private CommandButton searchButton; public CommandPanel() { setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5)); setOpaque(true); setBackground(Color.decode("0xbdbebd")); buttonBackground = ImageUtilities.loadImage(COMMAND_BUTTON_BG, true); addButton = new CommandButton(ADD_ICON, addButtonTooltips[0]); chatButton = new CommandButton(CHAT_ICON, chatButtonTooltips[0]); searchButton = new CommandButton(SEARCH_ICON, "Search for buddies"); add(addButton); add(chatButton); add(searchButton); addButton.addActionListener((ActionListener)this); chatButton.addActionListener((ActionListener)this); searchButton.addActionListener((ActionListener)this); } public void setSelectedTab(int index) { if (selectedTab != index) { selectedTab = index; updateAddButtonTooltip(); updateChatButtonTooltip(); } } public void updateAddButtonTooltip() { addButton.setToolTipText(addButtonTooltips[selectedTab]); } public void updateChatButtonTooltip() { chatButton.setToolTipText(chatButtonTooltips[selectedTab]); } public void addButtonClick() { addButton.doClick(); } public void chatButtonClick() { chatButton.doClick(); } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == addButton) { AddPanel addPanel = new AddPanel(selectedTab); DialogDescriptor descriptor = new DialogDescriptor(addPanel, "Add a contact", true, null); descriptor.setMessageType(DialogDescriptor.PLAIN_MESSAGE); descriptor.setOptions(new Object[] { DialogDescriptor.OK_OPTION, DialogDescriptor.CANCEL_OPTION }); Object ret = DialogDisplayer.getDefault().notify(descriptor); if (ret.equals(DialogDescriptor.OK_OPTION)) { switch (selectedTab) { case 0: addPanel.createGroupChat(); break; case 1: addPanel.addRosterEntry(); break; } } } else if (e.getSource() == chatButton) { switch (selectedTab) { case 0: break; case 1: List<ContactItem> selectedContacts = new ArrayList<ContactItem>(ChatsyManager.getChatManager().getSelectedContactItems()); if (selectedContacts.isEmpty()) return; if (selectedContacts.size() == 1) { ContactItem item = selectedContacts.get(0); ChatManager chatManager = ChatsyManager.getChatManager(); boolean handled = chatManager.fireContactItemDoubleClicked(item); if (!handled) chatManager.activateChat(item.getJID(), item.getDisplayName()); } else { String nickname = NbPreferences.root().node("/org/chartsy/chat").get("nickname", ""); String serviceName = "conference.chat.mrswing.com"; String message = nickname + " invites you to conference."; String roomName = nickname + " Conference"; String roomJID = nickname + "_conference@" + serviceName; List<String> jids = new ArrayList<String>(); for (ContactItem item : selectedContacts) jids.add(item.getJID()); createPrivateConference(message, roomName, roomJID, jids); } break; } } else if (e.getSource() == searchButton) { UserSearchService searchService = new UserSearchService(); searchService.search(""); } } private void createPrivateConference(String message, String roomName, String roomJID, Collection<String> jids) { final MultiUserChat multiUserChat = new MultiUserChat(ChatsyManager.getConnection(), roomJID); final GroupChatRoom room = new GroupChatRoom(multiUserChat); room.setTabTitle(roomName); try { multiUserChat.create(NbPreferences.root().node("/org/chartsy/chat").get("nickname", "")); } catch (XMPPException ex) { } try { Form submitForm = multiUserChat.getConfigurationForm().createAnswerForm(); submitForm.setAnswer("muc#roomconfig_publicroom", false); submitForm.setAnswer("muc#roomconfig_roomname", roomName); submitForm.setAnswer("muc#roomconfig_maxusers", 200); final List<String> owners = new ArrayList<String>(); owners.add(ChatsyManager.getSessionManager().getBareAddress()); submitForm.setAnswer("muc#roomconfig_roomowners", owners); multiUserChat.sendConfigurationForm(submitForm); } catch (XMPPException ex) { } ChatManager chatManager = ChatsyManager.getChatManager(); ChatRoom chatRoom = chatManager.getChatContainer().getChatRoom(room.getRoomname()); if (chatRoom == null) { chatManager.getChatContainer().addChatRoom(room); chatManager.getChatContainer().activateChatRoom(room); } for (String jid : jids) { multiUserChat.invite(jid, message); room.getTranscriptWindow().insertNotificationMessage( "Waiting for " + jid + " to join the conference.", ChatManager.NOTIFICATION_COLOR); } } private static class CommandButton extends JButton { private CommandButton(String iconPath, String tooltip) { if (iconPath != null) setIcon(ImageUtilities.loadImageIcon(iconPath, true)); setOpaque(false); setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); setHorizontalAlignment(SwingConstants.CENTER); setHorizontalTextPosition(SwingConstants.CENTER); setVerticalAlignment(SwingConstants.CENTER); setVerticalTextPosition(SwingConstants.CENTER); setFocusable(false); setBorderPainted(false); setFocusPainted(false); setRolloverEnabled(false); setContentAreaFilled(false); if (tooltip != null) setToolTipText(tooltip); setPreferredSize(new Dimension(35, 36)); } @Override protected void paintComponent(Graphics g) { Graphics2D graphics2D = (Graphics2D) g; graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); graphics2D.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); graphics2D.drawImage(buttonBackground, 0, 0, this); super.paintComponent(g); } } private static class AddPanel extends JPanel implements ActionListener { /* UI for conference */ private JLabel roomNameLabel; private JLabel topicLabel; private JTextField roomNameField; private JTextField topicField; /* UI for contact */ private JLabel usernameLabel; private JLabel nicknameLabel; private JLabel groupLabel; private JTextField usernameField; private JTextField nicknameField; private JComboBox groupBox; private JButton newGroupButton; private DefaultComboBoxModel groupModel; private AddPanel(int index) { setLayout(new GridBagLayout()); setOpaque(false); switch (index) { case 0: // conferences roomNameLabel = new JLabel("Room Name:"); roomNameField = new JTextField(); topicLabel = new JLabel("Topic:"); topicField = new JTextField(); add(roomNameLabel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0)); add(roomNameField, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); add(topicLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 5, 0)); add(topicField, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); roomNameLabel.setOpaque(false); topicLabel.setOpaque(false); break; case 1: // contacts usernameLabel = new JLabel("Username:"); usernameField = new JTextField(); nicknameLabel = new JLabel("Nickname:"); nicknameField = new JTextField(); groupLabel = new JLabel("Group:"); groupBox = new JComboBox(groupModel = new DefaultComboBoxModel()); newGroupButton = new JButton("New Group"); add(usernameLabel, new GridBagConstraints(0, 0, 1, 1, 0.0D, 0.0D, 17, 2, new Insets(5, 5, 5, 5), 0, 0)); add(usernameField, new GridBagConstraints(1, 0, 1, 1, 1.0D, 0.0D, 17, 2, new Insets(5, 5, 5, 5), 0, 0)); add(nicknameLabel, new GridBagConstraints(0, 1, 1, 1, 0.0D, 0.0D, 17, 2, new Insets(5, 5, 5, 5), 0, 0)); add(nicknameField, new GridBagConstraints(1, 1, 1, 1, 1.0D, 0.0D, 17, 2, new Insets(5, 5, 5, 5), 0, 0)); add(groupLabel, new GridBagConstraints(0, 4, 1, 1, 0.0D, 0.0D, 17, 2, new Insets(5, 5, 5, 5), 0, 0)); add(groupBox, new GridBagConstraints(1, 4, 1, 1, 1.0D, 0.0D, 17, 2, new Insets(5, 5, 5, 5), 0, 0)); add(newGroupButton, new GridBagConstraints(2, 4, 1, 1, 0.0D, 0.0D, 17, 2, new Insets(5, 5, 5, 5), 0, 0)); usernameLabel.setOpaque(false); nicknameLabel.setOpaque(false); groupLabel.setOpaque(false); newGroupButton.addActionListener((ActionListener)this); for (ContactGroup contactGroup : Workspace.getInstance().getContactList().getContactGroups()) groupModel.addElement(contactGroup.getName()); groupBox.setEditable(true); if (groupModel.getSize() == 0) groupBox.addItem("Friends"); if (groupModel.getSize() > 0) groupBox.setSelectedIndex(0); break; } } @Override public Dimension getPreferredSize() { final Dimension dimension = super.getPreferredSize(); dimension.width = 350; return dimension; } public String getJID() { String contact = usernameField.getText(); if (contact.indexOf("@") == -1) contact = contact + "@" + ChatsyManager.getConnection().getServiceName(); else if (contact.split("@", 2)[1].equals(ChatsyManager.getConnection().getServiceName())) contact = contact.split("@", 2)[0] + "@" + ChatsyManager.getConnection().getServiceName(); return contact; } public String getNickname() { if (!nicknameField.getText().isEmpty()) return nicknameField.getText(); else return getJID().split("@", 2)[0]; } public String getGroupName() { return (String) groupBox.getSelectedItem(); } public String getRoomName() { return roomNameField.getText(); } public String getTopic() { return topicField.getText(); } public void addRosterEntry() { final SwingWorker rosterEntryThread = new SwingWorker() { public Object construct() { return addEntry(getJID(), getNickname(), getGroupName()); } public void finished() { } }; rosterEntryThread.start(); } private RosterEntry addEntry(String jid, String nickname, String group) { String[] groups = {group}; Roster roster = ChatsyManager.getConnection().getRoster(); RosterEntry userEntry = roster.getEntry(jid); boolean isSubscribed = true; if (userEntry != null) isSubscribed = userEntry.getGroups().isEmpty(); if (isSubscribed) { try { roster.createEntry(jid, nickname, groups); } catch (XMPPException ex) { } return roster.getEntry(jid); } try { RosterGroup rosterGroup = roster.getGroup(group); if (rosterGroup == null) rosterGroup = roster.createGroup(group); if (userEntry == null) { roster.createEntry(jid, nickname, groups); userEntry = roster.getEntry(jid); } else { userEntry.setName(nickname); rosterGroup.addEntry(userEntry); } userEntry = roster.getEntry(jid); } catch (XMPPException ex) { } return userEntry; } public void createGroupChat() { String roomName = getRoomName(); String roomJID = roomName.replaceAll(" ", "_") + "@conference.chat.mrswing.com"; final MultiUserChat multiUserChat = new MultiUserChat(ChatsyManager.getConnection(), roomJID); final GroupChatRoom room = new GroupChatRoom(multiUserChat); room.setTabTitle(roomName); try { multiUserChat.create(NbPreferences.root().node("/org/chartsy/chat").get("nickname", "")); } catch (XMPPException ex) { } try { Form submitForm = multiUserChat.getConfigurationForm().createAnswerForm(); submitForm.setAnswer("muc#roomconfig_publicroom", true); submitForm.setAnswer("muc#roomconfig_roomname", roomName); submitForm.setAnswer("muc#roomconfig_passwordprotectedroom", false); submitForm.setAnswer("muc#roomconfig_moderatedroom", false); submitForm.setAnswer("muc#roomconfig_persistentroom", false); final List<String> owners = new ArrayList<String>(); owners.add(ChatsyManager.getSessionManager().getBareAddress()); submitForm.setAnswer("muc#roomconfig_roomowners", owners); multiUserChat.sendConfigurationForm(submitForm); } catch (XMPPException ex) { } ChatManager chatManager = ChatsyManager.getChatManager(); ChatRoom chatRoom = chatManager.getChatContainer().getChatRoom(roomName); if (chatRoom == null) { chatManager.getChatContainer().addChatRoom(room); chatManager.getChatContainer().activateChatRoom(room); } } @Override public void actionPerformed(ActionEvent e) { } } }