package eu.jucy.gui.downloadsview;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import helpers.IObservable;
import helpers.StatusObject;
import helpers.Observable.IObserver;
import helpers.StatusObject.ChangeType;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;
import uc.files.downloadqueue.AbstractDownloadQueueEntry;
import uc.files.downloadqueue.DownloadQueue;
import uc.files.transfer.IFileTransfer;
import uc.files.transfer.TransferChange;
import uc.protocols.client.ClientProtocol;
import uihelpers.DelayedTreeUpdater;
import uihelpers.SUIJob;
import uihelpers.TableViewerAdministrator;
import eu.jucy.gui.ApplicationWorkbenchWindowAdvisor;
import eu.jucy.gui.GUIPI;
import eu.jucy.gui.UCView;
import eu.jucy.gui.downloadsview.DownloadsColumns.FilesLeftCol;
import eu.jucy.gui.downloadsview.DownloadsColumns.StatusCol;
import eu.jucy.gui.downloadsview.DownloadsColumns.SizeLeftCol;
import eu.jucy.gui.downloadsview.DownloadsColumns.SpeedCol;
import eu.jucy.gui.downloadsview.DownloadsColumns.TimeLeftCol;
import eu.jucy.gui.downloadsview.DownloadsColumns.TotalSizeLeftCol;
import eu.jucy.gui.downloadsview.DownloadsColumns.TotalTimeLeftCol;
import eu.jucy.gui.downloadsview.DownloadsColumns.Transferrer;
import eu.jucy.gui.transferview.TransfersView;
public class DownloadsView extends UCView implements IObserver<StatusObject> {
public static final String VIEW_ID = "eu.jucy.gui.downloadsview";
private Tree tree;
private TreeViewer treeViewer;
private TableViewerAdministrator<Object> tva;
private DelayedTreeUpdater<Object> dtu;
private DownloadQueue dq;
private final CopyOnWriteArrayList<TransfersObserver> active =
new CopyOnWriteArrayList<TransfersObserver>();
private class TransfersObserver implements IObserver<TransferChange> {
private final IFileTransfer ift;
private final Object adqe;
public TransfersObserver(IFileTransfer ift,Object parent) {
this.ift = ift;
this.adqe = parent;
active.add(this);
}
public void update(final IObservable<TransferChange> o, TransferChange arg) {
dtu.change(((IFileTransfer)o).getClientProtocol(), adqe);
dtu.change(adqe, dq);
if (TransferChange.FINISHED == arg) {
dispose();
}
}
public void dispose() {
ift.deleteObserver(this);
active.remove(this);
}
@Override
public int hashCode() {
return getClass().hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
return getClass().equals(obj.getClass());
}
}
@Override
public void createPartControl(Composite parent) {
tree = new Tree(parent,SWT.BORDER | SWT.FULL_SELECTION);
tree.setHeaderVisible(true);
treeViewer = new TreeViewer(tree);
treeViewer.setAutoExpandLevel(2);
treeViewer.setContentProvider(new DownloadsContentProvider());
dtu = new DelayedTreeUpdater<Object>(treeViewer);
tva = new TableViewerAdministrator<Object>(treeViewer,
Arrays.asList(new Transferrer(),new StatusCol(), new SpeedCol(),
new TimeLeftCol(),new SizeLeftCol(),
new FilesLeftCol(),new TotalTimeLeftCol(),new TotalSizeLeftCol() ),GUIPI.downloadsViewTable,0);
tva.apply();
getSite().setSelectionProvider(treeViewer);
dq = ApplicationWorkbenchWindowAdvisor.get().getDownloadQueue();
DownloadProgressPainter.addPainter(treeViewer);
treeViewer.setInput(dq);
dq.addObserver(this);
setControlsForFontAndColour(tree);
createContextPopup(TransfersView.ID, treeViewer);
for (AbstractDownloadQueueEntry adqe : dq.getAllRunningDQE()) {
for (IFileTransfer ift: adqe.getRunningFileTransfers()) {
ift.addObserver(new TransfersObserver(ift, adqe));
}
}
}
@Override
public void dispose() {
super.dispose();
if (dq != null) {
dq.deleteObserver(this);
}
for (TransfersObserver to : active) {
to.dispose();
}
}
@Override
public void setFocus() {
tree.setFocus();
}
public void update(IObservable<StatusObject> o, StatusObject arg) {
if (arg.getType() == ChangeType.CHANGED) {
switch(arg.getDetail()) {
case DownloadQueue.DQE_FIRST_TRANSFER_STARTED:
dtu.add(arg.getValue(), dq);
new SUIJob(tree) {
@Override
public void run() {
treeViewer.expandAll();
}
}.schedule(1000);
break;
case DownloadQueue.DQE_LAST_TRANSFER_FINISHED:
dtu.remove(arg.getValue(), dq);
break;
case DownloadQueue.DQE_TRANSFER_STARTED:
IFileTransfer ft = (IFileTransfer)arg.getDetailObject();
dtu.add(ft.getClientProtocol(), arg.getValue());
ft.addObserver(new TransfersObserver(ft,arg.getValue()));
break;
case DownloadQueue.DQE_TRANSFER_FINISHED:
IFileTransfer ft2 = (IFileTransfer)arg.getDetailObject();
dtu.remove(ft2.getClientProtocol(), arg.getValue());
break;
case DownloadQueue.FILEDQE_BLOCKSTATUSCHANGED:
dtu.change(arg.getValue(),dq);
break;
}
}
}
/**
*
* standard content provider will fetch ClientProtocols
* and StateMachines
*
* @author Quicksilver
*
*/
public static class DownloadsContentProvider implements ITreeContentProvider {
public void dispose() {}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof AbstractDownloadQueueEntry) {
List<ClientProtocol> cps = new ArrayList<ClientProtocol>();
for (IFileTransfer ift: ((AbstractDownloadQueueEntry)parentElement).getRunningFileTransfers()) {
cps.add(ift.getClientProtocol());
}
return cps.toArray();
}
return new Object[]{};
}
public Object getParent(Object element) {
return null;
}
public boolean hasChildren(Object element) {
return element instanceof AbstractDownloadQueueEntry ||
element instanceof DownloadQueue;
}
public Object[] getElements(Object inputElement) {
return ((DownloadQueue)inputElement).getAllRunningDQE().toArray();
}
}
}