/** * $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.assistants; import java.awt.BorderLayout; 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.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.Map; import javax.swing.Icon; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.JToolBar; import org.jivesoftware.fastpath.FastpathPlugin; import org.jivesoftware.fastpath.FpRes; import org.jivesoftware.fastpath.resources.FastpathRes; import org.jivesoftware.fastpath.workspace.panes.BackgroundPane; import org.jivesoftware.fastpath.workspace.util.RequestUtils; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smackx.MessageEventManager; import org.jivesoftware.smackx.workgroup.util.ModelUtil; import org.jivesoftware.spark.ChatManager; import org.jivesoftware.spark.SparkManager; import org.jivesoftware.spark.component.RolloverButton; import org.jivesoftware.spark.component.browser.BrowserFactory; import org.jivesoftware.spark.component.browser.BrowserListener; import org.jivesoftware.spark.component.browser.BrowserViewer; import org.jivesoftware.spark.ui.ChatRoom; import org.jivesoftware.spark.ui.rooms.GroupChatRoom; import org.jivesoftware.spark.util.GraphicUtils; import org.jivesoftware.spark.util.log.Log; /** * Creates a new CoBrowser component. The CoBrowser is ChatRoom specific and is used * to control the end users browser. Using the CoBrowser allows you to assist end customers * by directing them to the appropriate site. */ public class CoBrowser extends JPanel implements ActionListener, BrowserListener { private static final long serialVersionUID = 1115198448380589259L; private boolean isShowing; private ChatRoom chatRoom; private final JTextField pushField = new JTextField(); private JCheckBox followMeButton; private RolloverButton goButton; private RolloverButton pushCurrentPageButton; private RolloverButton backButton; private String lastLink; private boolean hasLoaded; private BrowserViewer browser; private JTextField urlField; private String sessionID; // Define Constants private final static String PUBLIC_TOOLTIP = FpRes.getString("tooltip.allow.cobrowsing"); private final static String PRIVATE_TOOLTIP = FpRes.getString("tooltip.hide.cobrowsing"); /** * Creates a new CoBrowser object to be used with the specifid ChatRoom. */ public CoBrowser(String sessionID, ChatRoom chatRoom) { this.sessionID = sessionID; this.chatRoom = chatRoom; tabSelected(); } public void showDialog() { JFrame frame = new JFrame(FpRes.getString("title.cobrowsing.for", sessionID)); frame.setIconImage(SparkManager.getMainWindow().getIconImage()); frame.getContentPane().setLayout(new BorderLayout()); frame.getContentPane().add(this); frame.pack(); frame.setSize(600, 400); frame.setLocationRelativeTo(SparkManager.getChatManager().getChatContainer().getChatFrame()); frame.setVisible(true); } private void showSpecifiedPage() { String url = urlField.getText(); if (ModelUtil.hasLength(url)) { startFollowMeSession(url); } } /** * Loads a URL page( probably an html page ). * * @param url the url to load(ex.http://www.yahoo.com) */ private void load(String url) { if (url.startsWith("www")) { url = "http://" + url; } if (!url.startsWith("http")) { url = "http://" + url; } browser.loadURL(url); hasLoaded = true; } private void buildUI() { if (!isShowing) { update(getGraphics()); isShowing = true; final JToolBar toolbar = new JToolBar(); toolbar.setFloatable(false); toolbar.add(backButton); toolbar.add(urlField); toolbar.add(goButton); toolbar.setOpaque(false); final BackgroundPane titlePanel = new BackgroundPane(); titlePanel.setLayout(new GridBagLayout()); JLabel cobrowsingLabel = new JLabel(); cobrowsingLabel.setText(FpRes.getString("cobrowsing.session")); cobrowsingLabel.setFont(new Font("Dialog", Font.BOLD, 11)); titlePanel.add(cobrowsingLabel, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 0), 0, 0)); titlePanel.add(pushCurrentPageButton, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 5, 5), 0, 0)); titlePanel.add(followMeButton, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 5, 5), 0, 0)); titlePanel.add(toolbar, new GridBagConstraints(0, 1, 3, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 0, 5, 0), 0, 0)); add(titlePanel, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); updateLinkLabel(getStartLocation()); goButton.addActionListener(this); backButton.addActionListener(this); pushCurrentPageButton.addActionListener(this); } } public void actionPerformed(ActionEvent e) { if (e.getSource() == goButton) { showSpecifiedPage(); } else if (e.getSource() == pushCurrentPageButton) { if (ModelUtil.hasLength(urlField.getText())) { pushPage(urlField.getText()); followMeButton.setSelected(true); } } else if (e.getSource() == backButton) { if (ModelUtil.hasLength(lastLink)) { browser.goBack(); } } else if (e.getSource() == followMeButton) { boolean isSelected = followMeButton.isSelected(); if (!isSelected) { //followMeButton.setIcon(lockIcon); followMeButton.setToolTipText(PRIVATE_TOOLTIP); } else { //followMeButton.setIcon(unlockIcon); followMeButton.setToolTipText(PUBLIC_TOOLTIP); } } } private void startFollowMeSession(String url) { updateLinkLabel(url); // If the disable box is selected, only goto new page. // Do not update customer. if (!followMeButton.isSelected()) { load(url); return; } // If the disable box is not selected, update customer with // page push. /* final Message mes = new Message(); mes.setProperty("PUSH_URL", link); mes.setBody("Start a Co-Browsing session with [b]" + link + "[/b]"); // Update to insert into room chatRoom.getChatWindow().insertNotificationMessage("Sent a Co-Browsing invitation with page [b]" + link + "[/b]"); chatRoom.sendMessage(mes); */ pushField.setText(""); load(url); } private void pushPage(String link) { updateLinkLabel(link); // If the disable box is not selected, update customer with // page push. final Message mes = new Message(); mes.setProperty("PUSH_URL", link); mes.setBody(FpRes.getString("message.start.cobrowsing", link)); chatRoom.getTranscriptWindow().insertNotificationMessage(FpRes.getString("message.send.cobrowsing.message", link), ChatManager.NOTIFICATION_COLOR); send(mes); pushField.setText(""); load(link); } private void updateLinkLabel(String text) { lastLink = urlField.getText(); urlField.setText(text); urlField.setToolTipText(GraphicUtils.createToolTip(text)); } /** * Loads a page without notifiying of a change. * * @param url the url to load(ex.http://www.yahoo.com) */ public void loadWithoutNotification(String url) { hasLoaded = false; load(url); } private void navigateUser(String href) { if (followMeButton.isSelected() && hasLoaded) { final Message mes = new Message(); mes.setProperty("PUSH_URL", href); mes.setBody(""); send(mes); updateLinkLabel(href); hasLoaded = false; } else { updateLinkLabel(href); } hasLoaded = true; } public void tabSelected() { goButton = new RolloverButton(FastpathRes.getImageIcon(FastpathRes.PUSH_URL_16x16)); pushCurrentPageButton = new RolloverButton(FastpathRes.getImageIcon(FastpathRes.DOWNLOAD_16x16)); followMeButton = new JCheckBox(FpRes.getString("checkbox.allow.user.to.follow"), false); followMeButton.setToolTipText(GraphicUtils.createToolTip(PUBLIC_TOOLTIP)); followMeButton.addActionListener(this); final JPanel mainPanel = new JPanel(); browser = BrowserFactory.getBrowser(); browser.addBrowserListener(this); mainPanel.setLayout(new BorderLayout()); mainPanel.add(browser, BorderLayout.CENTER); urlField = new JTextField(); setLayout(new GridBagLayout()); backButton = new RolloverButton(FastpathRes.getImageIcon(FastpathRes.SMALL_PIN_BLUE)); backButton.setText(FpRes.getString("back")); backButton.setToolTipText(GraphicUtils.createToolTip(FpRes.getString("tooltip.back.one.page"))); goButton.setToolTipText(GraphicUtils.createToolTip(FpRes.getString("tooltip.push.url"))); goButton.setText(FpRes.getString("go")); pushCurrentPageButton.setToolTipText(GraphicUtils.createToolTip(FpRes.getString("tooltip.push.current.page"))); pushCurrentPageButton.setText(FpRes.getString("button.start.cobrowsing.session")); load(getStartLocation()); buildUI(); add(mainPanel, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); urlField.addKeyListener(new KeyListener() { public void keyPressed(KeyEvent e) { if (e.getKeyChar() == KeyEvent.VK_ENTER) { showSpecifiedPage(); } } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } }); followMeButton.setOpaque(false); } public String getTabTitle() { return FastpathRes.getString(FastpathRes.CO_BROWSER_TAB_TITLE); } public Icon getTabIcon() { return FastpathRes.getImageIcon(FastpathRes.EARTH_VIEW_16x16); } public String getTabToolTip() { return FastpathRes.getString(FastpathRes.CO_BROWSER_TAB_TITLE); } public JComponent getGUI() { return this; } /** * Let's make sure that the panel doesn't strech past the * scrollpane view pane. * * @return the preferred dimension */ public Dimension getPreferredSize() { final Dimension size = super.getPreferredSize(); size.width = 0; return size; } public void documentLoaded(String documentURL) { urlField.setText(documentURL); navigateUser(documentURL); } private String getStartLocation() { Map metadata = FastpathPlugin.getLitWorkspace().getMetadata(sessionID); RequestUtils utils = new RequestUtils(metadata); String location = utils.getRequestLocation(); if (location == null) { location = ""; } return location; } private void send(Message message) { GroupChatRoom groupChatRoom = (GroupChatRoom)chatRoom; try { message.setTo(groupChatRoom.getRoomname()); message.setType(Message.Type.groupchat); MessageEventManager.addNotificationsRequests(message, true, true, true, true); groupChatRoom.getMultiUserChat().sendMessage(message); } catch (XMPPException ex) { Log.error("Unable to send message in conference chat.", ex); } } }