/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
*
* 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 net.java.sip.communicator.impl.gui.main.chat;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.*;
import javax.imageio.*;
import javax.swing.*;
import javax.swing.text.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.plugin.desktoputil.*;
import net.java.sip.communicator.plugin.desktoputil.SwingWorker;
import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.replacement.directimage.*;
import net.java.sip.communicator.util.*;
public class ShowPreviewDialog
extends SIPCommDialog
implements ActionListener,
ChatLinkClickedListener
{
/**
* Serial version UID.
*/
private static final long serialVersionUID = 1L;
/**
* The <tt>Logger</tt> used by the <tt>ShowPreviewDialog</tt> class and
* its instances for logging output.
*/
private static final Logger logger
= Logger.getLogger(ShowPreviewDialog.class);
/**
* The Ok button.
*/
private final JButton okButton;
/**
* The cancel button.
*/
private final JButton cancelButton;
/**
* Checkbox that indicates whether or not to show this dialog next time.
*/
private final JCheckBox configureReplacement;
/**
* The <tt>ChatConversationPanel</tt> that this dialog is associated with.
*/
private final ChatConversationPanel chatPanel;
/**
* Mapping between messageID and the string representation of the chat
* message.
*/
private Map<String, String> msgIDToChatString
= new ConcurrentHashMap<String, String>();
/**
* Mapping between the pair (messageID, link position) and the actual link
* in the string representation of the chat message.
*/
private Map<String, String> msgIDandPositionToLink
= new ConcurrentHashMap<String, String>();
/**
* Mapping between link and replacement for this link that is acquired
* from it's corresponding <tt>ReplacementService</tt>.
*/
private Map<String, String> linkToReplacement
= new ConcurrentHashMap<String, String>();
/**
* The id of the message that is currently associated with this dialog.
*/
private String currentMessageID = "";
/**
* The position of the link in the current message.
*/
private String currentLinkPosition = "";
/**
* Creates an instance of <tt>ShowPreviewDialog</tt>
* @param chatPanel The <tt>ChatConversationPanel</tt> that is associated
* with this dialog.
*/
ShowPreviewDialog(final ChatConversationPanel chatPanel)
{
this.chatPanel = chatPanel;
this.setTitle(
GuiActivator.getResources().getI18NString(
"service.gui.SHOW_PREVIEW_DIALOG_TITLE"));
okButton = new JButton(
GuiActivator.getResources().getI18NString("service.gui.OK"));
cancelButton = new JButton(
GuiActivator.getResources().getI18NString("service.gui.CANCEL"));
JPanel mainPanel = new TransparentPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
//mainPanel.setPreferredSize(new Dimension(200, 150));
this.getContentPane().add(mainPanel);
JTextPane descriptionMsg = new JTextPane();
descriptionMsg.setEditable(false);
descriptionMsg.setOpaque(false);
descriptionMsg.setText(
GuiActivator.getResources().getI18NString(
"service.gui.SHOW_PREVIEW_WARNING_DESCRIPTION"));
Icon warningIcon = null;
try
{
warningIcon =
new ImageIcon(
ImageIO.read(GuiActivator.getResources().getImageURL(
"service.gui.icons.WARNING_ICON")));
}
catch (IOException e)
{
logger.debug("failed to load the warning icon");
}
JLabel warningSign = new JLabel(warningIcon);
JPanel warningPanel = new TransparentPanel();
warningPanel.setLayout(new BoxLayout(warningPanel, BoxLayout.X_AXIS));
warningPanel.add(warningSign);
warningPanel.add(Box.createHorizontalStrut(10));
warningPanel.add(descriptionMsg);
configureReplacement
= new SIPCommCheckBox(
GuiActivator.getResources().getI18NString(
"plugin.chatconfig.replacement.CONFIGURE_REPLACEMENT"));
JPanel checkBoxPanel = new TransparentPanel(
new FlowLayout(FlowLayout.CENTER));
checkBoxPanel.add(configureReplacement);
JPanel buttonsPanel
= new TransparentPanel(new FlowLayout(FlowLayout.CENTER));
buttonsPanel.add(okButton);
buttonsPanel.add(cancelButton);
mainPanel.add(warningPanel);
mainPanel.add(Box.createVerticalStrut(10));
mainPanel.add(checkBoxPanel);
mainPanel.add(buttonsPanel);
okButton.addActionListener(this);
cancelButton.addActionListener(this);
this.setPreferredSize(new Dimension(390, 230));
}
@Override
public void actionPerformed(ActionEvent arg0)
{
if (arg0.getSource().equals(okButton))
{
SwingWorker worker = new SwingWorker()
{
/**
* Called on the event dispatching thread
* (not on the worker thread) after the
* <code>construct</code> method has returned.
*/
@Override
public void finished()
{
String newChatString = (String)get();
if (newChatString != null)
{
try
{
Element elem =
chatPanel.document.getElement(currentMessageID);
chatPanel.document.setOuterHTML(
elem, newChatString);
msgIDToChatString.put(
currentMessageID, newChatString);
}
catch (BadLocationException ex)
{
logger.error("Could not replace chat message", ex);
}
catch (IOException ex)
{
logger.error("Could not replace chat message", ex);
}
}
}
@Override
protected Object construct() throws Exception
{
String newChatString
= msgIDToChatString.get(currentMessageID);
try
{
String originalLink = msgIDandPositionToLink.get
(currentMessageID + "#" + currentLinkPosition);
String replacementLink
= linkToReplacement.get(originalLink);
String replacement;
DirectImageReplacementService source
= GuiActivator.getDirectImageReplacementSource();
if (originalLink.equals(replacementLink) &&
(!source.isDirectImage(originalLink) ||
source.getImageSize(originalLink) == -1))
{
replacement = originalLink;
}
else
{
replacement =
"<IMG HEIGHT=\"90\" WIDTH=\"120\" SRC=\""
+ replacementLink + "\" BORDER=\"0\" ALT=\""
+ originalLink + "\"></IMG>";
}
String old = originalLink + "</A> <A href=\"jitsi://"
+ ShowPreviewDialog.this.getClass().getName()
+ "/SHOWPREVIEW?" + currentMessageID + "#"
+ currentLinkPosition + "\">"
+ GuiActivator.getResources().
getI18NString("service.gui.SHOW_PREVIEW");
newChatString = newChatString.replace(old, replacement);
}
catch (Exception ex)
{
logger.error("Could not replace chat message", ex);
}
return newChatString;
}
};
worker.start();
this.setVisible(false);
}
else if (arg0.getSource().equals(cancelButton))
{
this.setVisible(false);
}
// Shows chat config panel
if(configureReplacement.isSelected())
{
ConfigurationContainer configContainer
= GuiActivator.getUIService().getConfigurationContainer();
ConfigurationForm chatConfigForm =
ChatConversationPanel.getChatConfigForm();
if(chatConfigForm != null)
{
configContainer.setSelected(chatConfigForm);
configContainer.setVisible(true);
}
// reset for next dialog appearance
configureReplacement.setSelected(false);
}
}
@Override
public void chatLinkClicked(URI url)
{
String action = url.getPath();
if (action.equals("/SHOWPREVIEW"))
{
currentMessageID = url.getQuery();
currentLinkPosition = url.getFragment();
this.setVisible(true);
this.setLocationRelativeTo(chatPanel);
}
}
/**
* Returns mapping between messageID and the string representation of
* the chat message.
* @return mapping between messageID and chat string.
*/
Map<String, String> getMsgIDToChatString()
{
return msgIDToChatString;
}
/**
* Returns mapping between the pair (messageID, link position) and the
* actual link in the string representation of the chat message.
* @return mapping between (messageID, linkPosition) and link.
*/
Map<String, String> getMsgIDandPositionToLink()
{
return msgIDandPositionToLink;
}
/**
* Returns mapping between link and replacement for this link that was
* acquired from it's corresponding <tt>ReplacementService</tt>.
* @return mapping between link and it's corresponding replacement.
*/
Map<String, String> getLinkToReplacement()
{
return linkToReplacement;
}
/**
* All functions implemented in this method will be invoked when user
* presses the Escape key.
*
* @param escaped <tt>true</tt> if this frame has been closed by pressing
* the Esc key; otherwise, <tt>false</tt>
*/
protected void close(boolean escaped)
{
cancelButton.doClick();
}
}