/*
* 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.filetransfer;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.main.chat.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.plugin.desktoputil.*;
import net.java.sip.communicator.plugin.desktoputil.SwingWorker;
// Disambiguates SwingWorker on Java 6 in the presence of javax.swing.*
/**
* The <tt>ReceiveFileConversationComponent</tt> is the component shown in the
* conversation area of the chat window to display a incoming file transfer.
*
* @author Yana Stamcheva
*/
public class ReceiveFileConversationComponent
extends FileTransferConversationComponent
implements ActionListener,
FileTransferStatusListener,
FileTransferListener
{
private final Logger logger
= Logger.getLogger(ReceiveFileConversationComponent.class);
private final IncomingFileTransferRequest fileTransferRequest;
private final OperationSetFileTransfer fileTransferOpSet;
private final ChatPanel chatPanel;
private final Date date;
private final String dateString;
private File downloadFile;
/**
* Creates a <tt>ReceiveFileConversationComponent</tt>.
* @param chatPanel the chat panel
* @param opSet the <tt>OperationSetFileTransfer</tt>
* @param request the <tt>IncomingFileTransferRequest</tt>
* associated with this component
* @param date the date
*/
public ReceiveFileConversationComponent(
ChatPanel chatPanel,
final OperationSetFileTransfer opSet,
final IncomingFileTransferRequest request,
final Date date)
{
this.chatPanel = chatPanel;
this.fileTransferOpSet = opSet;
this.fileTransferRequest = request;
this.date = date;
this.dateString = getDateString(date);
fileTransferOpSet.addFileTransferListener(this);
byte[] thumbnail = request.getThumbnail();
if (thumbnail != null && thumbnail.length > 0)
{
ImageIcon thumbnailIcon = new ImageIcon(thumbnail);
if (thumbnailIcon.getIconWidth() > IMAGE_WIDTH
|| thumbnailIcon.getIconHeight() > IMAGE_HEIGHT)
{
thumbnailIcon
= ImageUtils.getScaledRoundedIcon(
thumbnail, IMAGE_WIDTH, IMAGE_WIDTH);
}
imageLabel.setIcon(thumbnailIcon);
}
titleLabel.setText(
dateString
+ resources.getI18NString(
"service.gui.FILE_TRANSFER_REQUEST_RECIEVED",
new String[]{fileTransferRequest.getSender().getDisplayName()}));
String fileName
= getFileLabel(request.getFileName(), request.getFileSize());
fileLabel.setText(fileName);
acceptButton.setVisible(true);
acceptButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
titleLabel.setText(
dateString
+ resources
.getI18NString("service.gui.FILE_TRANSFER_PREPARING",
new String[]{fileTransferRequest.getSender()
.getDisplayName()}));
acceptButton.setVisible(false);
rejectButton.setVisible(false);
cancelButton.setVisible(true);
progressBar.setVisible(true);
downloadFile = createFile(fileTransferRequest);
new AcceptFile(downloadFile).start();
}
});
rejectButton.setVisible(true);
rejectButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
fileTransferRequest.rejectFile();
acceptButton.setVisible(false);
rejectButton.setVisible(false);
setWarningStyle(true);
fileLabel.setText("");
titleLabel.setText(
dateString
+ resources.getI18NString(
"service.gui.FILE_TRANSFER_REFUSED"));
ReceiveFileConversationComponent.this.chatPanel
.removeActiveFileTransfer(fileTransferRequest.getID());
}
});
progressBar.setMaximum((int)fileTransferRequest.getFileSize());
}
/**
* Creates the file to download.
*
* @return the file to download.
*/
private File createFile(IncomingFileTransferRequest fileTransferRequest)
{
File downloadFile = null;
File downloadDir = null;
String incomingFileName = fileTransferRequest.getFileName();
// strip characters that are invalid on Windows and maybe other
// platforms too
incomingFileName = incomingFileName
.replaceAll("[\\\\/:*?\"<>|]", "_");
try
{
downloadDir = GuiActivator.getFileAccessService()
.getDefaultDownloadDirectory();
if (!downloadDir.exists())
{
if (!downloadDir.mkdirs())
{
logger.error("Could not create the download directory : "
+ downloadDir.getAbsolutePath());
}
if (logger.isDebugEnabled())
logger.debug("Download directory created : "
+ downloadDir.getAbsolutePath());
}
}
catch (IOException e)
{
if (logger.isDebugEnabled())
logger.debug("Unable to find download directory.", e);
}
downloadFile = new File(downloadDir, incomingFileName);
// If a file with the given name already exists, add an index to the
// file name.
int index = 0;
int filenameLenght = incomingFileName.lastIndexOf(".");
if(filenameLenght == -1)
{
filenameLenght = incomingFileName.length();
}
while (downloadFile.exists())
{
String newFileName
= incomingFileName.substring(0, filenameLenght)
+ "-" + ++index
+ incomingFileName.substring(filenameLenght);
downloadFile = new File(downloadDir, newFileName);
}
// Change the file name to the name we would use on the local file
// system.
if (!downloadFile.getName().equals(fileTransferRequest.getFileName()))
{
String fileName
= getFileLabel( downloadFile.getName(),
fileTransferRequest.getFileSize());
fileLabel.setText(fileName);
}
return downloadFile;
}
/**
* Handles status changes in file transfer.
*/
public void statusChanged(FileTransferStatusChangeEvent event)
{
FileTransfer fileTransfer = event.getFileTransfer();
int status = event.getNewStatus();
String fromContactName
= fileTransferRequest.getSender().getDisplayName();
if (status == FileTransferStatusChangeEvent.COMPLETED
|| status == FileTransferStatusChangeEvent.CANCELED
|| status == FileTransferStatusChangeEvent.FAILED
|| status == FileTransferStatusChangeEvent.REFUSED)
{
fileTransfer.removeStatusListener(this);
}
if (status == FileTransferStatusChangeEvent.PREPARING)
{
hideProgressRelatedComponents();
titleLabel.setText(
dateString
+ resources.getI18NString(
"service.gui.FILE_TRANSFER_PREPARING",
new String[]{fromContactName}));
}
else if (status == FileTransferStatusChangeEvent.FAILED)
{
hideProgressRelatedComponents();
cancelButton.setVisible(false);
titleLabel.setText(
dateString
+ resources.getI18NString(
"service.gui.FILE_RECEIVE_FAILED",
new String[]{fromContactName}));
setWarningStyle(true);
}
else if (status == FileTransferStatusChangeEvent.IN_PROGRESS)
{
titleLabel.setText(
dateString
+ resources.getI18NString(
"service.gui.FILE_RECEIVING_FROM",
new String[]{fromContactName}));
setWarningStyle(false);
if (!progressBar.isVisible())
{
progressBar.setVisible(true);
}
}
else if (status == FileTransferStatusChangeEvent.COMPLETED)
{
this.setCompletedDownloadFile(downloadFile);
hideProgressRelatedComponents();
cancelButton.setVisible(false);
openFileButton.setVisible(true);
openFolderButton.setVisible(true);
titleLabel.setText(
dateString
+ resources.getI18NString(
"service.gui.FILE_RECEIVE_COMPLETED",
new String[]{fromContactName}));
}
else if (status == FileTransferStatusChangeEvent.CANCELED)
{
hideProgressRelatedComponents();
cancelButton.setVisible(false);
titleLabel.setText(
dateString
+ resources.getI18NString(
"service.gui.FILE_TRANSFER_CANCELED"));
setWarningStyle(true);
}
else if (status == FileTransferStatusChangeEvent.REFUSED)
{
hideProgressRelatedComponents();
titleLabel.setText(
dateString
+ resources.getI18NString(
"service.gui.FILE_TRANSFER_REFUSED",
new String[]{fromContactName}));
cancelButton.setVisible(false);
openFileButton.setVisible(false);
openFolderButton.setVisible(false);
setWarningStyle(true);
}
}
/**
* Returns the date of the component event.
*
* @return the date of the component event
*/
@Override
public Date getDate()
{
return date;
}
/**
* Accepts the file in a new thread.
*/
private class AcceptFile extends SwingWorker
{
private FileTransfer fileTransfer;
private final File downloadFile;
public AcceptFile(File downloadFile)
{
this.downloadFile = downloadFile;
}
@Override
public Object construct()
{
fileTransfer = fileTransferRequest.acceptFile(downloadFile);
chatPanel.addActiveFileTransfer(fileTransfer.getID(), fileTransfer);
// Remove previously added listener, that notified us for request
// cancellations.
fileTransferOpSet.removeFileTransferListener(
ReceiveFileConversationComponent.this);
// Add the status listener that would notify us when the file
// transfer has been completed and should be removed from
// active components.
fileTransfer.addStatusListener(chatPanel);
fileTransfer.addStatusListener(
ReceiveFileConversationComponent.this);
return "";
}
@Override
public void finished()
{
if (fileTransfer != null)
{
setFileTransfer(fileTransfer, fileTransferRequest.getFileSize());
}
}
}
/**
* Returns the label to show on the progress bar.
*
* @param bytesString the bytes that have been transfered
* @return the label to show on the progress bar
*/
@Override
protected String getProgressLabel(String bytesString)
{
return resources.getI18NString("service.gui.RECEIVED",
new String[]{bytesString});
}
public void fileTransferCreated(FileTransferCreatedEvent event)
{}
public void fileTransferRequestCanceled(FileTransferRequestEvent event)
{
IncomingFileTransferRequest request = event.getRequest();
if (request.equals(fileTransferRequest))
{
acceptButton.setVisible(false);
rejectButton.setVisible(false);
titleLabel.setText(
dateString
+ resources.getI18NString(
"service.gui.FILE_TRANSFER_CANCELED"));
setWarningStyle(true);
}
}
public void fileTransferRequestReceived(FileTransferRequestEvent event)
{}
public void fileTransferRequestRejected(FileTransferRequestEvent event)
{}
}