package edu.washington.cs.oneswarm.ui.gwt.client.filebrowser;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.gen2.table.client.FixedWidthFlexTable;
import com.google.gwt.gen2.table.client.FixedWidthGrid;
import com.google.gwt.gen2.table.client.ScrollTable;
import com.google.gwt.gen2.table.client.AbstractScrollTable.ResizePolicy;
import com.google.gwt.gen2.table.client.AbstractScrollTable.ScrollPolicy;
import com.google.gwt.gen2.table.client.AbstractScrollTable.SortPolicy;
import com.google.gwt.gen2.table.client.SelectionGrid.SelectionPolicy;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DecoratedTabPanel;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.SourcesTabEvents;
import com.google.gwt.user.client.ui.SourcesTableEvents;
import com.google.gwt.user.client.ui.TabListener;
import com.google.gwt.user.client.ui.TableListener;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel;
import edu.washington.cs.oneswarm.ui.gwt.client.OneSwarmDialogBox;
import edu.washington.cs.oneswarm.ui.gwt.client.OneSwarmGWT;
import edu.washington.cs.oneswarm.ui.gwt.client.OneSwarmRPCClient;
import edu.washington.cs.oneswarm.ui.gwt.client.ReportableErrorDialogBox;
import edu.washington.cs.oneswarm.ui.gwt.client.newui.EntireUIRoot;
import edu.washington.cs.oneswarm.ui.gwt.client.newui.OneSwarmCss;
import edu.washington.cs.oneswarm.ui.gwt.rpc.FileListLite;
import edu.washington.cs.oneswarm.ui.gwt.rpc.OneSwarmConstants;
import edu.washington.cs.oneswarm.ui.gwt.rpc.ReportableException;
import edu.washington.cs.oneswarm.ui.gwt.rpc.StringTools;
import edu.washington.cs.oneswarm.ui.gwt.rpc.TorrentInfo;
public class UpdateSkippedFilesDialog extends OneSwarmDialogBox {
public static final String CSS_F2F_TABS = "os-f2f_tabs";
private List<CheckBox> checkboxes = new ArrayList<CheckBox>();
private ScrollTable fileTable;
private Button okButton = new Button(msg.button_update());
private EntireUIRoot mRoot = null;
private OneSwarmDialogBox mToClose = this;
private boolean[] updated = null;
private Label statusLabel = new Label(msg.update_files_loading());
private FixedWidthGrid mFilesData = null;
private static int WIDTH = 400;
private DockPanel bottom = new DockPanel();
private TorrentInfo torrent;
private FileListLite[] files = null;
final CheckBox streamCheck = new CheckBox(msg.update_files_streaming_download());
boolean initialStream = false;
private boolean[] initial_checks;
public UpdateSkippedFilesDialog(EntireUIRoot inRoot, TorrentInfo inTorrent) {
super(false);
this.setText("Details: " + StringTools.truncate(inTorrent.getName(), 40, true));
mRoot = inRoot;
this.torrent = inTorrent;
updated = new boolean[torrent.getNumFiles()];
Arrays.fill(updated, false);
initUI();
OneSwarmRPCClient.getService().getFilesForDownloadingTorrentHash(
OneSwarmRPCClient.getSessionID(), inTorrent.getTorrentID(),
new AsyncCallback<FileListLite[]>() {
public void onFailure(Throwable caught) {
System.err.println(caught.toString());
statusLabel.setText(caught.toString());
}
public void onSuccess(FileListLite[] result) {
statusLabel.setText("");
files = result;
update();
}
});
}
private Button selectNoneButton = new Button(msg.button_select_none());
private Button selectAllButton = new Button(msg.button_select_all());
// private void completed() {
// selectNoneButton.addClickHandler(new ClickHandler() {
// public void onClick(ClickEvent event) {
// for (CheckBox c : checkboxes) {
// if (c.isEnabled()) {
// c.setValue(false);
// }
// }
// }
// });
//
// selectAllButton.addClickHandler(new ClickHandler() {
// public void onClick(ClickEvent event) {
// for (CheckBox c : checkboxes) {
// if (c.isEnabled()) {
// c.setValue(true);
// }
// }
// }
// });
//
// HorizontalPanel f = new HorizontalPanel();
// f.setSpacing(3);
// f.add(selectAllButton);
// f.add(selectNoneButton);
// bottom.add(f, DockPanel.WEST);
// bottom.setCellVerticalAlignment(f, DockPanel.ALIGN_MIDDLE);
// bottom.setCellHorizontalAlignment(f, DockPanel.ALIGN_LEFT);
//
// }
// public F2FTorrentDownloader(FileListLite[] files) {
// this.collection = files;
//
// initUI();
// update();
// }
private ClickHandler enableDisableDLButton = new ClickHandler() {
public void onClick(ClickEvent event) {
// if nothing is selected, we can't download
boolean good = false;
for (int cItr = 0; cItr < checkboxes.size(); cItr++) {
CheckBox c = checkboxes.get(cItr);
if (c.isEnabled()
&& ((c.getValue() == true && initial_checks[cItr] == false) || (c
.getValue() == false && initial_checks[cItr] == true))) {
good = true;
break;
}
}
if (good) {
okButton.setEnabled(true);
} else {
okButton.setEnabled(false);
}
if (streamCheck.getValue() != initialStream) {
okButton.setEnabled(true);
}
}
};
DecoratedTabPanel tabs = new DecoratedTabPanel();
private void initUI() {
String[] dl_cols = new String[] { "DL", msg.swarm_browser_sort_name(),
msg.swarm_browser_sort_size() };
FixedWidthFlexTable filesHeader = new FixedWidthFlexTable();
int[] widths = new int[] { 20, 300, 70 };
mFilesData = new FixedWidthGrid(0, dl_cols.length);
for (int i = 0; i < dl_cols.length; i++) {
filesHeader.setText(0, i, dl_cols[i]);
filesHeader.setColumnWidth(i, widths[i]);
mFilesData.setColumnWidth(i, widths[i]);
}
mFilesData.setSelectionPolicy(SelectionPolicy.MULTI_ROW);
fileTable = new ScrollTable(mFilesData, filesHeader);
fileTable.setScrollPolicy(ScrollPolicy.DISABLED);
fileTable.setResizePolicy(ScrollTable.ResizePolicy.FILL_WIDTH);
fileTable.setSortPolicy(SortPolicy.DISABLED);
mFilesData.addTableListener(new TableListener() {
public void onCellClicked(SourcesTableEvents sender, int row, int cell) {
CheckBox cb = (CheckBox) (mFilesData.getWidget(row, 0));
if (cb.isEnabled()) {
cb.setValue(!cb.getValue());
UpdateSkippedFilesDialog.this.enableDisableDLButton.onClick(null);
}
}
});
VerticalPanel mainPanel = new VerticalPanel();
VerticalPanel filesPanel = new VerticalPanel();
Label selectLabel = new Label(msg.update_files_banner());
selectLabel.addStyleName(CSS_DIALOG_HEADER);
selectLabel.setWidth(WIDTH + "px");
mainPanel.add(selectLabel);
filesPanel.add(fileTable);
filesPanel.add(streamCheck);
streamCheck.addClickHandler(enableDisableDLButton);
OneSwarmRPCClient.getService().isStreamingDownload(OneSwarmRPCClient.getSessionID(),
torrent.getTorrentID(), new AsyncCallback<Boolean>() {
public void onFailure(Throwable caught) {
}
public void onSuccess(Boolean result) {
if (result != null && result.booleanValue() == true) {
streamCheck.setValue(true);
}
initialStream = result;
}
});
HorizontalPanel buttonPanel = new HorizontalPanel();
buttonPanel.setSpacing(3);
Button cancelButton = new Button(msg.button_cancel());
cancelButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
hide();
}
});
// cancelButton.setWidth("100px");
buttonPanel.add(cancelButton);
// okButton.setWidth("100px");
okButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
okButton.setEnabled(false);
for (int i = 0; i < checkboxes.size(); i++) {
checkboxes.get(i).setEnabled(false);
files[i].setSkipped(!checkboxes.get(i).getValue());
}
statusLabel.setText(msg.update_files_updating());
OneSwarmRPCClient.getService().updateSkippedFiles(OneSwarmRPCClient.getSessionID(),
files, new AsyncCallback<ReportableException>() {
public void onFailure(Throwable caught) {
System.err.println(caught);
caught.printStackTrace();
}
public void onSuccess(ReportableException result) {
if (result != null) {
new ReportableErrorDialogBox(result, false);
} else {
mRoot.refreshSwarms();
mToClose.hide();
}
}
});
OneSwarmRPCClient.getService().setStreamingDownload(
OneSwarmRPCClient.getSessionID(), torrent.getTorrentID(),
streamCheck.getValue(), new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
}
public void onSuccess(Void result) {
}
});
}
});
okButton.setEnabled(false);
buttonPanel.add(okButton);
buttonPanel.setCellHorizontalAlignment(okButton, HorizontalPanel.ALIGN_RIGHT);
buttonPanel.setCellHorizontalAlignment(cancelButton, HorizontalPanel.ALIGN_RIGHT);
buttonPanel.setCellHorizontalAlignment(statusLabel, HorizontalPanel.ALIGN_LEFT);
bottom.setWidth("100%");
bottom.add(buttonPanel, DockPanel.EAST);
bottom.setCellHorizontalAlignment(buttonPanel, HorizontalPanel.ALIGN_RIGHT);
bottom.add(statusLabel, DockPanel.WEST);
bottom.setCellVerticalAlignment(statusLabel, VerticalPanel.ALIGN_MIDDLE);
bottom.setCellHorizontalAlignment(statusLabel, HorizontalPanel.ALIGN_LEFT);
VerticalPanel sourcesPanel = new VerticalPanel();
sourcesPanel.add(new Label(msg.torrent_download_sources_not_available()));
tabs.addStyleName(CSS_F2F_TABS);
tabs.add(filesPanel, msg.settings_tab_files());
tabs.add(sourcesPanel, msg.torrent_download_tab_sources());
tabs.setWidth(WIDTH + "px");
tabs.addTabListener(new TabListener() {
public boolean onBeforeTabSelected(SourcesTabEvents arg0, int tabIndex) {
return true;
}
public void onTabSelected(SourcesTabEvents arg0, int tabIndex) {
if (tabIndex == 0) {
selectAllButton.setVisible(true);
selectNoneButton.setVisible(true);
} else {
selectAllButton.setVisible(false);
selectNoneButton.setVisible(false);
}
}
});
mainPanel.add(tabs);
mainPanel.add(bottom);
mainPanel.setWidth(WIDTH + "px");
tabs.selectTab(0);
this.setWidget(mainPanel);
}
public void hide() {
OneSwarmGWT.log("removing from update task");
super.hide();
}
private void update() {
// OneSwarmGWT.log("running update");
// fileTable.setVisible(false);
mFilesData.clear();
checkboxes.clear();
initial_checks = new boolean[files.length];
if (mFilesData.getRowCount() != torrent.getNumFiles()) {
mFilesData.resize(torrent.getNumFiles(), 3);
}
for (int i = 0; i < torrent.getNumFiles(); i++) {
final CheckBox b = new CheckBox();
b.addClickHandler(enableDisableDLButton);
b.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
b.setValue(!b.getValue());
}
});
b.setValue(!files[i].isSkipped());
b.setEnabled(!files[i].isFinishedDL());
this.initial_checks[i] = !files[i].isSkipped();
checkboxes.add(b);
mFilesData.setWidget(i, 0, b);
mFilesData.setText(i, 1, files[i].getFileName());
mFilesData.setText(i, 2, StringTools.formatRate(files[i].getFileSize()));
// OneSwarmGWT.log("adding: " + f.toString());
}
MediaInfoPanel mediaInfo = new MediaInfoPanel();
tabs.add(mediaInfo, "File Info");
mediaInfo.update(files);
fileTable.redraw();
}
static class MediaInfoPanel extends VerticalPanel {
private final ScrollTable table;
final ListBox defaultActionMenu = new ListBox();
FileListLite[] files;
String[] header = new String[] { "Key", "Value" };
FixedWidthGrid dataTable;
Button viewFFMpegOutButton = new Button("Ffmpeg output");
public MediaInfoPanel() {
table = new ScrollTable(new FixedWidthGrid(1, 2), new FixedWidthFlexTable());
table.setScrollPolicy(ScrollPolicy.DISABLED);
table.setResizePolicy(ResizePolicy.FILL_WIDTH);
FixedWidthFlexTable headerTable = table.getHeaderTable();
dataTable = table.getDataTable();
for (int i = 0; i < header.length; i++) {
headerTable.setWidget(0, i, new Label(header[i]));
dataTable.setWidget(0, i, new Label("loading..."));
}
defaultActionMenu.addItem("loading...");
add(defaultActionMenu);
add(table);
add(viewFFMpegOutButton);
viewFFMpegOutButton.setVisible(false);
viewFFMpegOutButton.addStyleName(OneSwarmCss.SMALL_BUTTON);
viewFFMpegOutButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
OneSwarmDialogBox dlg = new OneSwarmDialogBox(true, true, true);
dlg.hide();
dlg.setText("FFMpeg debug output");
TextArea a = new TextArea();
a.setReadOnly(true);
a.addStyleName("os-add_friend_publickey_text");
a.setText(ffmpegOut);
dlg.setWidget(a);
a.setWidth("800px");
a.setHeight("600px");
dlg.center();
dlg.show();
}
});
defaultActionMenu.addChangeHandler(new ChangeHandler() {
public void onChange(ChangeEvent event) {
int selected = Integer.parseInt(defaultActionMenu.getValue(defaultActionMenu
.getSelectedIndex()));
FileListLite f = files[selected];
System.out.println("getting media info for: " + f.getCollectionId() + " "
+ f.getFileName());
dataTable.resizeRows(1);
for (int i = 0; i < header.length; i++) {
dataTable.setWidget(0, i, new Label("loading..."));
}
updateTable(f);
}
});
}
public void update(FileListLite[] files) {
this.files = files;
defaultActionMenu.clear();
for (int i = 0; i < files.length; i++) {
FileListLite fileListLite = files[i];
defaultActionMenu.addItem(fileListLite.getFileName(), i + "");
}
if (defaultActionMenu.getItemCount() > 0) {
defaultActionMenu.setSelectedIndex(0);
updateTable(files[0]);
}
}
String ffmpegOut;
public void updateTable(FileListLite file) {
OneSwarmRPCClient.getService().getFileInfo(
OneSwarmRPCClient.getSessionID(),
file,
file.isFinishedDL()
&& OneSwarmConstants.InOrderType.getType(file.getFileName()) != null,
new AsyncCallback<HashMap<String, String>>() {
public void onFailure(Throwable caught) {
System.err.println(caught);
caught.printStackTrace();
}
public void onSuccess(HashMap<String, String> result) {
ArrayList<String> keys = new ArrayList<String>();
ffmpegOut = null;
for (String k : result.keySet()) {
if (k.equals("ffmpegOut")) {
ffmpegOut = result.get(k);
} else {
keys.add(k);
}
}
Collections.sort(keys);
dataTable.resizeRows(keys.size());
for (int i = 0; i < keys.size(); i++) {
String k = keys.get(i);
dataTable.setWidget(i, 0, new Label(k));
final String hash = result.get(k);
dataTable.setWidget(i, 1, new Label(hash));
if (k.contains("sha1") || k.contains("ed2k")) {
final String searchString = k.replaceFirst("hash_", "").trim()
+ ";" + hash;
HTML h = new HTML("<a href=#"
+ EntireUIRoot.SEARCH_HISTORY_TOKEN + searchString
+ ">" + hash + "</a>");
h.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
EntireUIRoot.getRoot(MediaInfoPanel.this)
.displaySearch(searchString);
}
});
dataTable.setWidget(i, 1, h);
}
}
viewFFMpegOutButton.setVisible(ffmpegOut != null);
table.redraw();
}
});
}
}
}