/** * $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.Color; 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.ActionListener; 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 java.util.Map; import java.util.TimerTask; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; import org.jivesoftware.fastpath.FastpathPlugin; import org.jivesoftware.fastpath.FpRes; import org.jivesoftware.fastpath.resources.FastpathRes; import org.jivesoftware.fastpath.workspace.Workpane; import org.jivesoftware.fastpath.workspace.assistants.RoomInformation; import org.jivesoftware.fastpath.workspace.util.RequestUtils; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smackx.Form; import org.jivesoftware.smackx.muc.Affiliate; import org.jivesoftware.smackx.muc.MultiUserChat; import org.jivesoftware.smackx.workgroup.agent.Offer; import org.jivesoftware.smackx.workgroup.agent.TransferRequest; import org.jivesoftware.spark.ChatManager; import org.jivesoftware.spark.ChatNotFoundException; import org.jivesoftware.spark.SparkManager; import org.jivesoftware.spark.component.LinkLabel; import org.jivesoftware.spark.component.RolloverButton; import org.jivesoftware.spark.component.WrappedLabel; import org.jivesoftware.spark.ui.ChatContainer; import org.jivesoftware.spark.ui.conferences.ConferenceUtils; import org.jivesoftware.spark.ui.rooms.GroupChatRoom; import org.jivesoftware.spark.util.ModelUtil; import org.jivesoftware.spark.util.ResourceUtils; import org.jivesoftware.spark.util.SwingTimerTask; import org.jivesoftware.spark.util.SwingWorker; import org.jivesoftware.spark.util.TaskEngine; import org.jivesoftware.spark.util.log.Log; import org.jivesoftware.sparkimpl.plugin.alerts.SparkToaster; /** * Handles invitations and transfers of Fastpath Requests. */ public class UserInvitationPane { private Map metadata; private AcceptListener listener; private Offer offer; private JProgressBar progressBar; private SparkToaster toasterManager; public UserInvitationPane(final Offer offer, final RequestUtils request, final String fullRoomJID, final String inviter, String reason) { // Add to Chat window ChatManager chatManager = SparkManager.getChatManager(); try { GroupChatRoom chatRoom = chatManager.getGroupChat(fullRoomJID); if (chatRoom.isActive()) { offer.reject(); return; } } catch (ChatNotFoundException e) { } final JPanel transcriptAlert = new JPanel(); transcriptAlert.setBackground(Color.white); transcriptAlert.setLayout(new GridBagLayout()); this.offer = offer; progressBar = new JProgressBar(); progressBar.setFont(new Font("Dialog", Font.BOLD, 11)); final JPanel topPanel = new JPanel(); topPanel.setBackground(Color.white); topPanel.setLayout(new GridBagLayout()); JLabel userImage = new JLabel(FastpathRes.getImageIcon(FastpathRes.FASTPATH_IMAGE_16x16)); userImage.setHorizontalAlignment(JLabel.LEFT); String title = FpRes.getString("title.fastpath.invitation"); if (offer.getContent() instanceof TransferRequest) { title = FpRes.getString("title.fastpath.transfer"); } userImage.setText(title); topPanel.add(userImage, new GridBagConstraints(0, 0, 4, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0)); userImage.setFont(new Font("Dialog", Font.BOLD, 12)); final JLabel inviterLabel = new JLabel(FpRes.getString("from") + ":"); inviterLabel.setFont(new Font("Dialog", Font.BOLD, 11)); final WrappedLabel inviterValueLabel = new WrappedLabel(); inviterValueLabel.setBackground(Color.white); String nickname = SparkManager.getUserManager().getUserNicknameFromJID(inviter); inviterValueLabel.setText(nickname); topPanel.add(inviterLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0)); topPanel.add(inviterValueLabel, new GridBagConstraints(1, 1, 3, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0)); final JLabel nameLabel = new JLabel(FpRes.getString("room") + ":"); nameLabel.setFont(new Font("Dialog", Font.BOLD, 11)); final WrappedLabel valueLabel = new WrappedLabel(); valueLabel.setBackground(Color.white); valueLabel.setText(fullRoomJID); topPanel.add(nameLabel, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0)); topPanel.add(valueLabel, new GridBagConstraints(1, 2, 3, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0)); final JLabel messageLabel = new JLabel(FpRes.getString("message") + ":"); messageLabel.setFont(new Font("Dialog", Font.BOLD, 11)); final WrappedLabel messageValueLabel = new WrappedLabel(); messageValueLabel.setBackground(Color.white); messageValueLabel.setText(reason); topPanel.add(messageLabel, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0)); topPanel.add(messageValueLabel, new GridBagConstraints(1, 3, 3, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0)); // Add accept button and reject button. RolloverButton acceptButton = new RolloverButton("Accept", FastpathRes.getImageIcon(FastpathRes.CIRCLE_CHECK_IMAGE)); RolloverButton rejectButton = new RolloverButton("Decline", FastpathRes.getImageIcon(FastpathRes.SMALL_DELETE)); ResourceUtils.resButton(acceptButton, FpRes.getString("button.accept")); ResourceUtils.resButton(rejectButton, FpRes.getString("button.reject")); LinkLabel infoButton = new LinkLabel(FpRes.getString("message.view.more.information"), null, Color.blue, Color.red); transcriptAlert.add(topPanel, new GridBagConstraints(0, 3, 2, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0)); transcriptAlert.add(progressBar, new GridBagConstraints(0, 4, 3, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(15, 2, 2, 2), 0, 0)); transcriptAlert.add(infoButton, new GridBagConstraints(0, 5, 1, 1, 0.0, 1.0, GridBagConstraints.SOUTH, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0)); transcriptAlert.add(acceptButton, new GridBagConstraints(1, 5, 1, 1, 1.0, 1.0, GridBagConstraints.SOUTH, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0)); transcriptAlert.add(rejectButton, new GridBagConstraints(2, 5, 1, 1, 0.0, 1.0, GridBagConstraints.SOUTH, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0)); metadata = offer.getMetaData(); infoButton.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { RoomInformation roomInformation = new RoomInformation(); if (metadata != null) { roomInformation.showAllInformation(metadata); roomInformation.showRoomInformation(); } } }); acceptButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { final TimerTask loadRoomTask = new SwingTimerTask() { public void doRun() { offer.accept(); closeToaster(); startFastpathChat(fullRoomJID, request.getUsername()); } }; TaskEngine.getInstance().schedule(loadRoomTask, 100); } }); rejectButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { rejectOffer(); } }); // Start progress bart final Date endTime = offer.getExpiresDate(); Date now = new Date(); long mill = endTime.getTime() - now.getTime(); int seconds = (int)(mill / 1000); progressBar.setMaximum(seconds); progressBar.setValue(seconds); SwingWorker worker = new SwingWorker() { public Object construct() { while (true) { Date now = new Date(); if (now.getTime() >= endTime.getTime()) { break; } try { Thread.sleep(1000); } catch (InterruptedException e) { Log.error(e); } progressBar.setValue(progressBar.getValue() - 1); progressBar.setStringPainted(true); int seconds = (int)(endTime.getTime() - now.getTime()) / 1000; if (seconds <= 60) { String timeString = seconds + " " + FpRes.getString("seconds"); progressBar.setString(timeString); } else { long difference = endTime.getTime() - now.getTime(); String timeString = ModelUtil.getTimeFromLong(difference); progressBar.setString(timeString); } } return progressBar; } }; worker.start(); toasterManager = new SparkToaster(); toasterManager.setHidable(false); toasterManager.setToasterHeight((int)transcriptAlert.getPreferredSize().getHeight() + 40); toasterManager.setToasterWidth(300); toasterManager.setDisplayTime(500000000); toasterManager.showToaster("Incoming Fastpath Request", transcriptAlert); toasterManager.hideTitle(); } /** * Reject the current offer. */ public void rejectOffer() { offer.reject(); if (listener != null) { listener.noOption(); listener = null; } closeToaster(); } public void dispose() { if (listener != null) { listener.noOption(); listener = null; } closeToaster(); } /** * Removes oneself as an owner of the room. * * @param muc the <code>MultiUserChat</code> of the chat room. */ private void removeOwner(MultiUserChat muc) { if (muc.isJoined()) { // Try and remove myself as an owner if I am one. Collection<Affiliate> owners = null; try { owners = muc.getOwners(); } catch (XMPPException e1) { return; } if (owners == null) { return; } Iterator<Affiliate> iter = owners.iterator(); List<String> list = new ArrayList<String>(); while (iter.hasNext()) { Affiliate affilitate = iter.next(); String jid = affilitate.getJid(); if (!jid.equals(SparkManager.getSessionManager().getBareAddress())) { list.add(jid); } } if (list.size() > 0) { try { Form form = muc.getConfigurationForm().createAnswerForm(); form.setAnswer("muc#roomconfig_roomowners", list); // new DataFormDialog(groupChat, form); muc.sendConfigurationForm(form); } catch (XMPPException e) { Log.error(e); } } } } /** * Sets the AcceptListener to use with this dialog instance. * * @param listener the <code>AcceptListener</code> to use with this instance. */ public void setAcceptListener(AcceptListener listener) { this.listener = listener; } /** * Used to handle yes/no selection in dialog. You would use this simply to * be notified when a user has either clicked on the yes or no dialog. */ public interface AcceptListener { /** * Fired when the Yes button has been clicked. */ void yesOption(); /** * Fired when the No button has been clicked. */ void noOption(); } private void closeToaster() { toasterManager.close(); } private void startFastpathChat(String fullRoomJID, String roomName) { // Add to Chat window ChatManager chatManager = SparkManager.getChatManager(); GroupChatRoom chatRoom; try { chatRoom = chatManager.getGroupChat(fullRoomJID); if (!chatRoom.isActive()) { // Remove old room, add new room. chatManager.removeChat(chatRoom); MultiUserChat chat = new MultiUserChat(SparkManager.getConnection(), fullRoomJID); chatRoom = new GroupChatRoom(chat); } else { // Already in the room, do not process invitation offer.reject(); return; } } catch (ChatNotFoundException e) { MultiUserChat chat = new MultiUserChat(SparkManager.getConnection(), fullRoomJID); chatRoom = new GroupChatRoom(chat); } chatRoom.getSplitPane().setDividerSize(5); chatRoom.getSplitPane().getRightComponent().setVisible(true); chatRoom.getBottomPanel().setVisible(true); chatRoom.getScrollPaneForTranscriptWindow().setVisible(true); chatRoom.getEditorBar().setVisible(true); chatRoom.getChatInputEditor().setEnabled(true); chatRoom.getToolBar().setVisible(true); chatRoom.getVerticalSlipPane().setDividerLocation(0.8); chatRoom.getSplitPane().setDividerLocation(0.6); try { chatRoom.setTabTitle(roomName); chatRoom.getConferenceRoomInfo().setNicknameChangeAllowed(false); chatRoom.getToolBar().setVisible(true); chatRoom.getEditorBar().setVisible(true); chatRoom.getChatInputEditor().setEnabled(true); ChatContainer chatContainer = SparkManager.getChatManager().getChatContainer(); chatContainer.addChatRoom(chatRoom); FastpathPlugin.getLitWorkspace().addFastpathChatRoom(chatRoom, Workpane.RoomState.activeRoom); chatContainer.setChatRoomTitle(chatRoom, roomName); if (chatContainer.getActiveChatRoom() == chatRoom) { chatContainer.getChatFrame().setTitle(roomName); } } catch (Exception e) { Log.error(e); } ConferenceUtils.enterRoomOnSameThread(roomName, fullRoomJID, null); removeOwner(chatRoom.getMultiUserChat()); FastpathPlugin.getLitWorkspace().checkForDecoration(chatRoom, offer.getSessionID()); if (listener != null) { listener.yesOption(); listener = null; } } }