/****************************************************************************
* Copyright (c) 2007 Remy Suen and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Remy Suen <remy.suen@gmail.com> - initial API and implementation
*****************************************************************************/
package org.eclipse.ecf.filetransfer.ui;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import org.eclipse.ecf.filetransfer.*;
import org.eclipse.ecf.internal.filetransfer.ui.Messages;
import org.eclipse.jface.action.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.program.Program;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.*;
import org.eclipse.ui.part.ViewPart;
public class FileTransfersView extends ViewPart {
public static final Map transfers = new HashMap();
public static final String ID = "org.eclipse.ecf.filetransfer.ui.FileTransfersView"; //$NON-NLS-1$
private static final String[] COLUMNS = {Messages.getString("FileTransfersView_COLUMN_NAME"), Messages.getString("FileTransfersView_COLUMN_DOWNLOAD"), Messages.getString("FileTransfersView_COLUMN_UPLOAD"), Messages.getString("FileTransfersView_COLUMN_LOCAL_FILE"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
Messages.getString("FileTransfersView_COLUMN_DONE"), Messages.getString("FileTransfersView_COLUMN_START_TIME"), Messages.getString("FileTransfersView_COLUMN_END_TIME"), Messages.getString("FileTransfersView_COLUMN_RATE")}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
private static final int[] WIDTHS = {225, 70, 70, 325, 50, 90, 90, 75};
private static final String DATEFORMAT = "HH:mm:ss"; //$NON-NLS-1$
static final SimpleDateFormat SDF = new SimpleDateFormat(DATEFORMAT);
static final Object[] EMPTY_ARRAY = new Object[0];
private static final double GIGABYTE = Math.pow(2, 30);
private static final double MEGABYTE = Math.pow(2, 20);
private static final double KILOBYTE = Math.pow(2, 10);
private static final int NAME = 0;
private static final int DOWNLOADED = NAME + 1;
private static final int UPLOADED = DOWNLOADED + 1;
private static final int FILENAME = UPLOADED + 1;
private static final int DONE = FILENAME + 1;
private static final int STARTTIME = DONE + 1;
private static final int ENDTIME = STARTTIME + 1;
private static final int RATE = ENDTIME + 1;
static class FileTransferEntry {
IFileTransfer fileTransfer;
String localFileName;
long startTime;
public FileTransferEntry(IFileTransfer fileTransfer, String localFileName) {
this.fileTransfer = fileTransfer;
this.localFileName = localFileName;
this.startTime = System.currentTimeMillis();
}
public FileTransferEntry(IFileTransfer fileTransfer) {
this(fileTransfer, null);
}
public IFileTransfer getFileTransfer() {
return fileTransfer;
}
public String getLocalFileName() {
return localFileName;
}
public long getStartTime() {
return startTime;
}
}
public static FileTransfersView addTransfer(IFileTransfer transfer) {
FileTransferEntry entry = new FileTransferEntry(transfer, null);
transfers.put(transfer, entry);
if (instance != null) {
instance.add(entry);
}
return instance;
}
public static FileTransfersView addTransfer(IFileTransfer transfer, String localFileName) {
FileTransferEntry entry = new FileTransferEntry(transfer, localFileName);
transfers.put(transfer, entry);
if (instance != null) {
instance.add(entry);
}
return instance;
}
TableViewer viewer;
private Table table;
private Action resumeAction;
private Action pauseAction;
private Action removeAction;
private Action launchAction;
static String getTwoDigitNumber(long value) {
if (value > GIGABYTE) {
double num = value / GIGABYTE;
return Double.toString(Math.floor(num * 100) / 100) + " " + Messages.getString("FileTransfersView_GB"); //$NON-NLS-1$ //$NON-NLS-2$
} else if (value > MEGABYTE) {
double num = value / MEGABYTE;
return Double.toString(Math.floor(num * 100) / 100) + " " + Messages.getString("FileTransfersView_MB"); //$NON-NLS-1$ //$NON-NLS-2$
} else if (value > KILOBYTE) {
double num = value / KILOBYTE;
return Double.toString(Math.floor(num * 100) / 100) + " " + Messages.getString("FileTransfersView_KB"); //$NON-NLS-1$ //$NON-NLS-2$
}
return value + " " + Messages.getString("FileTransfersView_BYTES"); //$NON-NLS-1$ //$NON-NLS-2$
}
private static FileTransfersView instance;
public FileTransfersView() {
instance = this;
}
public void dispose() {
instance = null;
super.dispose();
}
public void createPartControl(Composite parent) {
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.VIRTUAL | SWT.FULL_SELECTION);
viewer.setContentProvider(new ViewContentProvider());
viewer.setLabelProvider(new ViewLabelProvider());
//viewer.setSorter(new ViewerSorter());
viewer.setInput(getViewSite());
table = viewer.getTable();
for (int i = 0; i < WIDTHS.length; i++) {
TableColumn col = new TableColumn(table, SWT.LEFT);
col.setText(COLUMNS[i]);
col.setAlignment(SWT.CENTER);
col.setWidth(WIDTHS[i]);
}
Iterator iterator = transfers.keySet().iterator();
while (iterator.hasNext()) {
IFileTransfer fileTransfer = (IFileTransfer) iterator.next();
add((FileTransferEntry) transfers.get(fileTransfer));
}
makeActions();
hookContextMenu();
table.setLinesVisible(true);
table.setHeaderVisible(true);
table.setLayoutData(new GridData(GridData.FILL_BOTH));
table.setSize(1000, 1000);
}
private void add(FileTransferEntry transferEntry) {
if (table != null && !table.isDisposed()) {
viewer.add(transferEntry);
}
}
public void update(IFileTransfer transfer) {
if (table != null && !table.isDisposed()) {
FileTransferEntry entry = (FileTransferEntry) transfers.get(transfer);
viewer.update(entry, COLUMNS);
}
}
private void hookContextMenu() {
MenuManager menuMgr = new MenuManager();
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
fillContextMenu(manager);
enableActions();
}
});
Menu menu = menuMgr.createContextMenu(viewer.getControl());
table.setMenu(menu);
getSite().registerContextMenu(menuMgr, viewer);
}
void fillContextMenu(IMenuManager manager) {
manager.add(launchAction);
manager.add(new Separator());
manager.add(resumeAction);
manager.add(pauseAction);
manager.add(removeAction);
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
private void makeActions() {
resumeAction = new Action() {
public void run() {
ISelection sel = viewer.getSelection();
if (!(sel instanceof IStructuredSelection)) {
return;
}
IStructuredSelection ssel = (IStructuredSelection) sel;
Object o = ssel.getFirstElement();
if (o instanceof FileTransferEntry) {
FileTransferEntry entry = (FileTransferEntry) o;
IFileTransfer transfer = entry.getFileTransfer();
IFileTransferPausable pausable = (IFileTransferPausable) transfer.getAdapter(IFileTransferPausable.class);
if (pausable != null) {
pausable.resume();
}
}
}
};
resumeAction.setId("resume"); //$NON-NLS-1$
resumeAction.setText(Messages.getString("FileTransfersView_MENU_RESUME_TEXT")); //$NON-NLS-1$
pauseAction = new Action() {
public void run() {
ISelection sel = viewer.getSelection();
if (!(sel instanceof IStructuredSelection)) {
return;
}
IStructuredSelection ssel = (IStructuredSelection) sel;
Object o = ssel.getFirstElement();
if (o instanceof FileTransferEntry) {
FileTransferEntry entry = (FileTransferEntry) o;
IFileTransfer transfer = entry.getFileTransfer();
IFileTransferPausable pausable = (IFileTransferPausable) transfer.getAdapter(IFileTransferPausable.class);
if (pausable != null) {
pausable.pause();
}
}
}
};
pauseAction.setText(Messages.getString("FileTransfersView_MENU_PAUSE_TEXT")); //$NON-NLS-1$
removeAction = new Action() {
public void run() {
ISelection sel = viewer.getSelection();
if (!(sel instanceof IStructuredSelection)) {
return;
}
IStructuredSelection ssel = (IStructuredSelection) sel;
Object o = ssel.getFirstElement();
if (o instanceof FileTransferEntry) {
FileTransferEntry entry = (FileTransferEntry) o;
IFileTransfer transfer = entry.getFileTransfer();
transfer.cancel();
viewer.remove(entry);
transfers.remove(entry);
}
}
};
removeAction.setText(Messages.getString("FileTransfersView_MENU_REMOVE_TEXT")); //$NON-NLS-1$
removeAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));
launchAction = new Action() {
public void run() {
ISelection sel = viewer.getSelection();
if (!(sel instanceof IStructuredSelection)) {
return;
}
IStructuredSelection ssel = (IStructuredSelection) sel;
Object o = ssel.getFirstElement();
if (o != null && o instanceof FileTransferEntry) {
FileTransferEntry entry = (FileTransferEntry) o;
String fileName = entry.getLocalFileName();
Program.launch(fileName);
}
}
};
launchAction.setText(Messages.getString("FileTransfersView_MENU_LAUNCH_TEXT")); //$NON-NLS-1$
}
void enableActions() {
ISelection is = viewer.getSelection();
resumeAction.setEnabled(false);
pauseAction.setEnabled(false);
if (is instanceof IStructuredSelection) {
IStructuredSelection iss = (IStructuredSelection) is;
removeAction.setEnabled(!iss.isEmpty());
// Enable for launch if first element is download, and is done
Object o = iss.getFirstElement();
if (o instanceof FileTransferEntry) {
FileTransferEntry entry = (FileTransferEntry) o;
IFileTransfer transfer = entry.getFileTransfer();
String localFileName = entry.getLocalFileName();
if (transfer instanceof IIncomingFileTransfer && transfer.isDone() && transfer.getException() == null && localFileName != null) {
launchAction.setEnabled(true);
}
IFileTransferPausable pausable = (IFileTransferPausable) transfer.getAdapter(IFileTransferPausable.class);
if (!transfer.isDone() && pausable != null) {
resumeAction.setEnabled(true);
pauseAction.setEnabled(true);
return;
}
}
}
}
public void setFocus() {
table.setFocus();
}
class ViewLabelProvider extends LabelProvider implements ITableLabelProvider {
String endTime = null;
public String getColumnText(Object obj, int index) {
if (!(obj instanceof FileTransferEntry)) {
return getText(obj);
}
FileTransferEntry entry = (FileTransferEntry) obj;
IFileTransfer transfer = entry.getFileTransfer();
switch (index) {
case NAME :
return transfer.getID().getName();
case DOWNLOADED :
if (transfer instanceof IIncomingFileTransfer)
return getTwoDigitNumber(((IIncomingFileTransfer) transfer).getBytesReceived());
return Messages.getString("FileTransfersView_NA"); //$NON-NLS-1$
case UPLOADED :
if (transfer instanceof IOutgoingFileTransfer)
return getTwoDigitNumber(((IOutgoingFileTransfer) transfer).getBytesSent());
return Messages.getString("FileTransfersView_NA"); //$NON-NLS-1$
case FILENAME :
String fileName = entry.getLocalFileName();
return (fileName == null) ? "" : fileName; //$NON-NLS-1$
case DONE :
if (transfer.isDone()) {
Exception e = transfer.getException();
return (e == null) ? Messages.getString("FileTransfersView_YES") : Messages.getString("FileTransfersView_ERROR"); //$NON-NLS-1$ //$NON-NLS-2$
}
double percentComplete = transfer.getPercentComplete();
return Double.toString(percentComplete + '%');
case STARTTIME :
return SDF.format(new Date(entry.getStartTime()));
case ENDTIME :
if (transfer.isDone()) {
if (endTime == null)
endTime = SDF.format(new Date());
return endTime;
}
return Messages.getString("FileTransfersView_IN_PROGRESS"); //$NON-NLS-1$
case RATE :
long fileLength = transfer.getFileLength();
if (fileLength == -1)
return Messages.getString("FileTransfersView_NA"); //$NON-NLS-1$
return showTransferRate(entry.getStartTime(), fileLength * transfer.getPercentComplete());
}
return getText(obj);
}
public Image getColumnImage(Object obj, int index) {
return null;
}
}
class ViewContentProvider implements IStructuredContentProvider {
public void inputChanged(Viewer v, Object oldInput, Object newInput) {
// nothing to do in this case
}
public void dispose() {
// nothing to do in this case
}
public Object[] getElements(Object inputElement) {
return EMPTY_ARRAY;
}
}
String showTransferRate(long startTime, double bytesReceived) {
double convertedSize;
String unit;
double size = (bytesReceived / ((System.currentTimeMillis() + 1 - startTime) / 1000.0));
if (size / (1024 * 1024 * 1024) >= 1) {
convertedSize = size / (1024 * 1024 * 1024);
unit = Messages.getString("FileTransfersView_GB"); //$NON-NLS-1$
} else if (size / (1024 * 1024) >= 1) {
convertedSize = size / (1024 * 1024);
unit = Messages.getString("FileTransfersView_MB"); //$NON-NLS-1$
} else if (size / 1024 >= 1) {
convertedSize = size / 1024;
unit = Messages.getString("FileTransfersView_KB"); //$NON-NLS-1$
} else {
convertedSize = size;
unit = Messages.getString("FileTransfersView_BYTES"); //$NON-NLS-1$
}
DecimalFormat df = new DecimalFormat(NLS.bind("0.00 {0}/s", unit)); //$NON-NLS-1$
return df.format(convertedSize);
}
}