package edu.washington.cs.oneswarm.ui.gwt.client.newui;
import java.util.Date;
import java.util.HashMap;
import com.allen_sauer.gwt.dnd.client.DragEndEvent;
import com.allen_sauer.gwt.dnd.client.DragHandler;
import com.allen_sauer.gwt.dnd.client.DragStartEvent;
import com.allen_sauer.gwt.dnd.client.PickupDragController;
import com.allen_sauer.gwt.dnd.client.VetoDragException;
import com.allen_sauer.gwt.dnd.client.drop.DropController;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.DecoratedTabPanel;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.Frame;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
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.newui.TagEditorDialog.TreeItemDropController;
import edu.washington.cs.oneswarm.ui.gwt.client.newui.friends.wizard.FriendsImportCallback;
import edu.washington.cs.oneswarm.ui.gwt.client.newui.friends.wizard.FriendsImportWizard;
import edu.washington.cs.oneswarm.ui.gwt.client.newui.friends.wizard.InvitationRedeemPanel;
import edu.washington.cs.oneswarm.ui.gwt.rpc.CommunityRecord;
import edu.washington.cs.oneswarm.ui.gwt.rpc.FriendInfoLite;
import edu.washington.cs.oneswarm.ui.gwt.rpc.OneSwarmConstants;
import edu.washington.cs.oneswarm.ui.gwt.rpc.OneSwarmUIServiceAsync;
import edu.washington.cs.oneswarm.ui.gwt.rpc.StringTools;
import edu.washington.cs.oneswarm.ui.gwt.rpc.TorrentInfo;
public class EntireUIRoot extends DockPanel {
private final NavigationSidePanel navSidePanel;
SwarmsBrowser swarmFileBrowser = null;
private Header header;
long mLastAction = 0;
public final static String SEARCH_HISTORY_TOKEN = "search:";
public final static String ADD_COMMUNITY_SERVER_TOKEN = "addcserver:";
private static final String CSS_UI_ROOT = "os-ui_root";
private static final String CSS_SEARCH_TABS = "os-search_tabs";
private static final String CSS_SEARCH_TAB_ITEM = "os-search_tab_item";
public static final String CSS_BROWSER_WARNING = "os-browser_warning";
boolean hasShift = false;
boolean hasAlt = false;
private SimplePanel keyboardRecorder;
HTML warningHTML = new HTML("");
boolean mWarningVisible = false;
boolean sticky_warning = false;
private String uiVersion = null;
ValueChangeHandler<String> historyChangeListener = new ValueChangeHandler<String>() {
@Override
public void onValueChange(ValueChangeEvent<String> event) {
// String historyToken = event.getValue();
/**
* We can't use the value provided by the event because of a firefox
* decoding bug (we rely on encoded responses to make parsing
*/
String historyToken = getHistoryToken();
OneSwarmGWT.log("History value changed: " + historyToken);
if (historyToken.startsWith("cserver") == false
&& swarmFileBrowser.isAttached() == false) {
keyboardRecorder.clear();
keyboardRecorder.setWidget(swarmFileBrowser);
header.getFilterBar().setVisible(true);
}
actionOccurred();
System.out.println("got history changed event: " + historyToken);
boolean recognized = false;
for (FileTypeFilter filter : FileTypeFilter.values()) {
if (filter.history_state_name.equals(historyToken)) {
swarmFileBrowser.changeFilter(filter, false); // this will
// clear
// the search
// bar
// logically. we
// do this in
// the UI below
recognized = true;
}
}
if (historyToken.equals(NavigationSidePanel.HYPERLINK_LABEL_TRANSFERS)) {
System.out.println("show transfers");
swarmFileBrowser.showTransfers();
recognized = true;
} else if (historyToken.equals(NavigationSidePanel.HYPERLINK_LABEL_FRIENDS)) {
System.out.println("show friends");
swarmFileBrowser.showFriends();
recognized = true;
} else if (historyToken.startsWith("friend")) {
// internal file browser code will recognize that we have a
// friend
// selected, this code will remove transfers (if selected)
// and clear other state appropriate to the switch
swarmFileBrowser.pageZero();
swarmFileBrowser.changeFilter(FileTypeFilter.All, false);
/**
* Select browse files to see these since the intent is clearly
* to view them
*/
if (searchTabs != null) {
searchTabs.selectTab(0);
}
recognized = true;
} else if (historyToken.startsWith("cserver")) {
keyboardRecorder.clear();
header.getFilterBar().setVisible(false);
CommunityRecord selectedServer = navSidePanel.getCommunityServersPanel()
.getSelectedServer();
if (selectedServer == null) {
keyboardRecorder.add(new Label("No selected community server."));
} else {
String base = selectedServer.getBaseURLSkipSSL();
final Frame frame = new Frame(base + "/?osclient="
+ URL.encode(mFooter.getVersion()));
frame.setWidth("98%");
final int off = 75;
frame.setHeight((Window.getClientHeight() - off) + "px");
Window.addResizeHandler(new ResizeHandler() {
@Override
public void onResize(ResizeEvent event) {
frame.setHeight((Window.getClientHeight() - off) + "px");
}
});
keyboardRecorder.add(frame);
if (searchTabs != null) {
searchTabs.selectTab(0);
}
// HTML frame = new HTML("<iframe src=\"" +
// selectedServer.getBaseURL() +
// "\" width=\"100%\" height=\"100%\" frameborder=\"0\" vspace=\"0\" "
// +
// "hspace=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"yes\" noresize");
// keyboardRecorder.add(frame);
}
recognized = true;
}
if (historyToken.equals("addfriends")) {
OneSwarmDialogBox dlg = new FriendsImportWizard(new HashMap<String, Integer>());
dlg.show();
dlg.setVisible(false);
dlg.center();
dlg.setPopupPosition(dlg.getPopupLeft(), Math.max(40, dlg.getPopupTop() - 200));
dlg.setVisible(true);
}
if (historyToken.startsWith(OneSwarmConstants.FRIEND_INVITE_PREFIX)) {
handleInviteParameters(URL.decode(historyToken));
}
if (historyToken.startsWith(ADD_COMMUNITY_SERVER_TOKEN)) {
handleCommunityServerAdd(getHistoryToken());
}
if (historyToken.startsWith(SEARCH_HISTORY_TOKEN)) {
String searchString = historyToken.substring(SEARCH_HISTORY_TOKEN.length());
displaySearch(URL.decode(searchString));
}
if (recognized) {
header.getFilterBar().clearSearchFieldText();
}
}
};
public void setWarning(String html) {
warningHTML.setHTML(html);
mWarningVisible = true;
DOM.setStyleAttribute(warningHTML.getElement(), "visibility", "visible");
sticky_warning = false;
}
public void clearWarning() {
if (mWarningVisible && !sticky_warning) {
DOM.setStyleAttribute(warningHTML.getElement(), "visibility", "hidden");
mWarningVisible = false;
}
}
private static boolean supportsKeyboardShortcuts() {
// if (OneSwarmGWT.isIE()) {
// return false;
// }
if (OneSwarmGWT.isWebKit()) {
return false;
}
return true;
}
private final PickupDragController dragController;
public PickupDragController getDragController() {
return dragController;
}
public EntireUIRoot(boolean useDebug) {
if (OneSwarmGWT.isIE()) {
if (OneSwarmGWT.getIEVersion() < 8) {
setWarning("<b>Note:</b> Old versions of Internet Explorer does not render OneSwarm properly. Please consider <a href=\"http://oneswarm.cs.washington.edu/faq.html#q4\">upgrading your browser</a> for a better experience.");
sticky_warning = true;
} else {
setWarning("<b>Note:</b> OneSwarm support for Internet Explorer 8 is experimental, if you experience issues please consider <a href=\"http://oneswarm.cs.washington.edu/faq.html#q4\">switching browser.</a>");
sticky_warning = false;
}
}
// create a DragController to manage drag-n-drop actions
// note: This creates an implicit DropController for the boundary panel
dragController = new PickupDragController(RootPanel.get(), true);
dragController.setBehaviorDragProxy(true);
dragController.addDragHandler(new DragHandler() {
@Override
public void onPreviewDragStart(DragStartEvent event) throws VetoDragException {
}
@Override
public void onPreviewDragEnd(DragEndEvent event) throws VetoDragException {
DropController dropController = event.getContext().dropController;
if (dropController == null || !(dropController instanceof TreeItemDropController)) {
throw new VetoDragException();
}
}
@Override
public void onDragStart(DragStartEvent event) {
}
@Override
public void onDragEnd(DragEndEvent event) {
}
});
addStyleName(CSS_UI_ROOT);
swarmFileBrowser = new SwarmsBrowser(useDebug);
if (OneSwarmGWT.isRemoteAccess()) {
OneSwarmRPCClient.getService().getComputerName(OneSwarmRPCClient.getSessionID(),
new AsyncCallback<String>() {
@Override
public void onFailure(Throwable caught) {
}
@Override
public void onSuccess(String result) {
Window.setTitle("OneSwarm - " + result + " (remote access)");
}
});
} else {
OneSwarmRPCClient.getService().getComputerName(OneSwarmRPCClient.getSessionID(),
new AsyncCallback<String>() {
@Override
public void onFailure(Throwable caught) {
}
@Override
public void onSuccess(String result) {
Window.setTitle("OneSwarm - " + result);
}
});
}
navSidePanel = new NavigationSidePanel();
/**
* Compensate for ScrollTable resizing bug in FireFox. See:
* http://code.google
* .com/p/google-web-toolkit-incubator/issues/detail?id=43
*/
// ResizableWidgetCollection.get().setResizeCheckingEnabled(false);
Widget north = null;
String urlParams = History.getToken();
boolean focusSearchField = urlParams != null && urlParams.length() > 1;
header = new Header(useDebug, focusSearchField);
VerticalPanel notice = new VerticalPanel();
warningHTML.setWidth("600px");
warningHTML.addStyleName(CSS_BROWSER_WARNING);
notice.add(warningHTML);
notice.setCellHorizontalAlignment(warningHTML, HorizontalPanel.ALIGN_CENTER);
notice.setWidth("100%");
notice.add(header);
north = notice;
this.add(north, DockPanel.NORTH);
this.add(navSidePanel, DockPanel.WEST);
this.setCellWidth(navSidePanel, "200px");
/**
* This is a hack to get around the fact that keyboard state is not
* exposed to proper click listeners. I'm not sure if this worse than
* just never using click listeners when we care about getting shift
* events...
*
* Also, FocusPanel's in the current version of GWT cause problems with
* WebKit-based browsers, so no keyboard shortcuts for them.
*/
if (supportsKeyboardShortcuts()) {
System.out.println("adding keyboard recorder");
keyboardRecorder = new FocusPanel();
((FocusPanel) keyboardRecorder).addKeyPressHandler(new KeyPressHandler() {
@Override
public void onKeyPress(KeyPressEvent event) {
// for instance, when showing a community server
if (swarmFileBrowser.isAttached() == false) {
return;
}
hasShift = event.isShiftKeyDown();
hasAlt = event.isAltKeyDown();
System.out.println("key press: " + event.getCharCode() + " shift?: " + hasShift);
if (Character.toLowerCase(event.getCharCode()) == 'j') {
hasShift = false;
swarmFileBrowser.selectPreviousSwarm();
} else if (Character.toLowerCase(event.getCharCode()) == 'k') {
hasShift = false;
swarmFileBrowser.selectNextSwarm();
} else if (Character.toLowerCase(event.getCharCode()) == 'n') {
swarmFileBrowser.nextPage();
} else if (Character.toLowerCase(event.getCharCode()) == 'p') {
swarmFileBrowser.previousPage();
} else if (Character.toLowerCase(event.getCharCode()) == 'd') {
swarmFileBrowser.dispatchSwarmAction(Strings.SWARM_DELETE,
swarmFileBrowser.getSelectedSwarms());
} else if (event.getCharCode() == 13) { // enter
swarmFileBrowser.doubleClick();
} else if (event.getCharCode() == '/') {
header.focusSearch();
}
}
});
} else {
keyboardRecorder = new SimplePanel();
}
keyboardRecorder.setWidget(swarmFileBrowser);
this.add(keyboardRecorder, DockPanel.EAST);
// this.add(swarmFileBrowser, DockPanel.EAST);
if (supportsKeyboardShortcuts()) {
((FocusPanel) keyboardRecorder).setFocus(true);
}
/**
* compensate for the memory leaks typical of browsers by periodically
* refreshing (if nothing is playing)
*/
(new Timer() {
@Override
public void run() {
long now = (new Date()).getTime();
if (getPlayingVideo() == false && (mLastAction + 60 * 1000) < now) {
System.out.println("f5 refreshing... " + (new Date()));
// TODO: make the currently selected section persist across
// reloads (e.g., leaving open the transfers window seems
// like a common use case)
reload();
} else {
System.out.println("skipped f5 refresh due to playing or recent action "
+ (new Date()));
}
}
}).scheduleRepeating(120 * 60 * 1000);
(new Timer() {
@Override
public void run() {
OneSwarmRPCClient.getService().ping(OneSwarmRPCClient.getSessionID(), uiVersion,
new AsyncCallback<String>() {
@Override
public void onFailure(Throwable caught) {
if ("OneSwarm updated".equals(caught.getMessage())) {
reload();
} else {
setWarning("<b>Warning:</b> The OneSwarm client appears to have stopped. Please restart it.");
}
}
@Override
public void onSuccess(String result) {
uiVersion = result;
clearWarning();
}
});
}
}).scheduleRepeating(5 * 1000);
History.addValueChangeHandler(historyChangeListener);
// History.addHistoryListener(new HistoryListener() {
// public void onHistoryChanged(String historyToken) {
//
// System.out.println("history tok: " + historyToken);
//
// if (historyToken.equals("addfriends")) {
// OneSwarmDialogBox dlg = new FriendsImportWizard(new HashMap<String,
// Integer>());
// dlg.show();
// dlg.setVisible(false);
// dlg.center();
// dlg.setVisible(true);
// History.newItem("#");
// } else if( historyToken.startsWith("id:") ) {
// displaySearch(URL.decode(historyToken));
// }
// }
// });
}
protected void handleCommunityServerAdd(String historyToken) {
String str = historyToken.substring(ADD_COMMUNITY_SERVER_TOKEN.length());
CommunityRecord rec = new CommunityRecord(str);
OneSwarmDialogBox dlg = new FriendsImportWizard(rec);
dlg.show();
dlg.setVisible(false);
dlg.center();
dlg.setVisible(true);
}
private void handleInviteParameters(String historyToken) {
String values = historyToken.replaceAll(OneSwarmConstants.FRIEND_INVITE_PREFIX, "");
String[] split = values.split(":");
String code = "";
String nick = "";
for (String s : split) {
if (s.startsWith(OneSwarmConstants.FRIEND_INVITE_CODE_PREFIX)) {
code = s.substring((OneSwarmConstants.FRIEND_INVITE_CODE_PREFIX.length()));
} else if (s.startsWith(OneSwarmConstants.FRIEND_INVITE_NICK_PREFIX)) {
nick = s.substring(OneSwarmConstants.FRIEND_INVITE_NICK_PREFIX.length());
}
}
final OneSwarmDialogBox dlg = new OneSwarmDialogBox();
dlg.setWidget(new InvitationRedeemPanel(new FriendsImportCallback() {
@Override
public void back() {
dlg.hide();
}
@Override
public void cancel() {
dlg.hide();
}
@Override
public void connectSuccesful(FriendInfoLite[] changes, boolean showSkip) {
dlg.hide();
}
}, code, nick));
dlg.setText("Redeem Invitation");
dlg.show();
dlg.setVisible(false);
dlg.center();
dlg.setVisible(true);
}
private native void reload() /*-{
$wnd.location.reload();
}-*/;
/**
* We include this function from Google's RSH (reallysimplehistory) to work
* around a hash decoding bug in firefox. See:
* https://bugzilla.mozilla.org/show_bug.cgi?id=378962
* https://bugzilla.mozilla.org/show_bug.cgi?id=483304
*/
private native String getHistoryToken() /*-{
var r = $wnd.location.href;
var i = r.indexOf("#");
return (i >= 0
? r.substr(i+1)
: ""
);
}-*/;
// public void onHistoryChanged(String historyToken) {
//
// if (historyToken.equals("cserver") == false &&
// swarmFileBrowser.isAttached() == false) {
// keyboardRecorder.clear();
// keyboardRecorder.setWidget(swarmFileBrowser);
// header.getFilterBar().setVisible(true);
// }
//
// actionOccurred();
// System.out.println("got history changed event: " + historyToken);
// boolean recognized = false;
// for (FileTypeFilter filter : FileTypeFilter.values()) {
// if (filter.history_state_name.equals(historyToken)) {
// swarmFileBrowser.changeFilter(filter, false); // this will clear
// // the search
// // bar
// // logically. we
// // do this in
// // the UI below
// recognized = true;
// }
// }
//
// if (historyToken.equals(NavigationSidePanel.HYPERLINK_LABEL_TRANSFERS)) {
// System.out.println("show transfers");
// swarmFileBrowser.showTransfers();
// recognized = true;
// } else if
// (historyToken.equals(NavigationSidePanel.HYPERLINK_LABEL_FRIENDS)) {
// System.out.println("show friends");
// swarmFileBrowser.showFriends();
// recognized = true;
// } else if (historyToken.equals("friend")) {
// // internal file browser code will recognize that we have a friend
// // selected, this code will remove transfers (if selected)
// // and clear other state appropriate to the switch
// swarmFileBrowser.pageZero();
// swarmFileBrowser.changeFilter(FileTypeFilter.All, false);
//
// /**
// * Select browse files to see these since the intent is clearly to
// * view them
// */
// if (searchTabs != null) {
// searchTabs.selectTab(0);
// }
//
// recognized = true;
// } else if (historyToken.equals("cserver")) {
//
// keyboardRecorder.clear();
// header.getFilterBar().setVisible(false);
//
// CommunityRecord selectedServer =
// navSidePanel.getCommunityServersPanel().getSelectedServer();
// if (selectedServer == null) {
// keyboardRecorder.add(new Label("No selected community server."));
// } else {
//
// final Frame frame = new Frame(selectedServer.getBaseURL() + "?osclient="
// + URL.encode(mFooter.getVersion()));
// frame.setWidth("98%");
//
// final int off = 120;
//
// frame.setHeight((Window.getClientHeight() - off) + "px");
//
// Window.addResizeHandler(new ResizeHandler() {
// public void onResize(ResizeEvent event) {
// frame.setHeight((Window.getClientHeight() - off) + "px");
// }
// });
//
// keyboardRecorder.add(frame);
//
// // HTML frame = new HTML("<iframe src=\"" +
// // selectedServer.getBaseURL() +
// // "\" width=\"100%\" height=\"100%\" frameborder=\"0\" vspace=\"0\" "
// // +
// //
// "hspace=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"yes\" noresize");
// // keyboardRecorder.add(frame);
// }
//
// recognized = true;
// }
//
// if (historyToken.startsWith(OneSwarmConstants.FRIEND_INVITE_PREFIX)) {
// handleInviteParameters(URL.decode(historyToken));
// }
//
// if( historyToken.startsWith(ADD_COMMUNITY_SERVER_TOKEN) ) {
// handleCommunityServerAdd(historyToken);
// }
//
// if (historyToken.startsWith(SEARCH_HISTORY_TOKEN)) {
// String searchString =
// historyToken.substring(SEARCH_HISTORY_TOKEN.length());
// displaySearch(URL.decode(searchString));
// }
//
// if (recognized) {
// header.getFilterBar().clearSearchFieldText();
// }
// }
/**
* Indicates that something has changed on the back end that warrants
* refreshing the current swarm list
*
* TODO: might just signal the removals/additions explicitly instead of
* needing to refresh the back end in case these refreshes (of all swarms)
* start to take a long time. alternatively, we could do some paged-style
* presentation
*/
public void refreshSwarms() {
System.out.println("refreshSwarms()");
swarmFileBrowser.refreshActive(false);
}
public static EntireUIRoot getRoot(Widget inWidget) {
while (inWidget != null) {
if (inWidget instanceof EntireUIRoot) {
return (EntireUIRoot) inWidget;
}
inWidget = inWidget.getParent();
}
return null;
}
public void filterTextChanged(String text) {
swarmFileBrowser.refreshFromFilterText(text);
}
public void friendFilterChanged() {
FriendInfoLite selectedFriend = navSidePanel.getFriendPanel().getFriendListPanel()
.getSelectedFriend();
if (selectedFriend != null) {
navSidePanel.clearSelection();
navSidePanel.getCommunityServersPanel().clearSelectedServer();
History.newItem("friend-" + selectedFriend.getId());
} else {
// TODO: we should set the active filter to all files
}
}
public void serverFilterChanged() {
CommunityRecord selectedServer = navSidePanel.getCommunityServersPanel()
.getSelectedServer();
if (selectedServer != null) {
navSidePanel.clearSelection();
navSidePanel.getFriendPanel().getFriendListPanel().clearSelectedFriend();
History.newItem("cserver-" + selectedServer.getBaseURL().hashCode());
}
}
/**
* hack attack
*/
public FriendInfoLite getSelectedFriend() {
return navSidePanel.getFriendPanel().getFriendListPanel().getSelectedFriend();
}
public void clearNonLocalSelections() {
navSidePanel.getFriendPanel().getFriendListPanel().clearSelectedFriend();
navSidePanel.getCommunityServersPanel().clearSelectedServer();
}
public void pageZero() {
swarmFileBrowser.pageZero();
if (searchTabs != null) {
searchTabs.selectTab(0);
}
}
boolean mPlayingVideo = false;
public void setPlayingVideo(boolean inPlaying) {
mPlayingVideo = inPlaying;
}
public boolean getPlayingVideo() {
return mPlayingVideo;
}
public void actionOccurred() {
mLastAction = (new Date()).getTime();
// System.out.println("action: " + mLastAction);
}
DecoratedTabPanel searchTabs = null;
private final String CSS_SEARCH_RESULTS_PANEL = "os-search_results_panel";
public void displaySearch(final String keywords) {
// swarmFileBrowser.newSearch(text);
header.getFilterBar().clearSearchFieldText();
/**
* Two cases: either the tab bar is currently being shown or not. If
* not, create it.
*/
if (searchTabs == null) {
keyboardRecorder.removeFromParent();
searchTabs = new DecoratedTabPanel();
searchTabs.add(keyboardRecorder, "Swarms");
searchTabs.addStyleName(CSS_SEARCH_TABS);
searchTabs.setWidth("100%");
// searchTabs.setHeight("100%");
// this.setCellWidth(searchTabs, "100%");
// this.setCellHeight(searchTabs, "100%");
this.add(searchTabs, DockPanel.EAST);
}
final HorizontalPanel closable = new HorizontalPanel();
closable.addStyleName(CSS_SEARCH_TAB_ITEM);
final Label searchLabel = new Label(StringTools.truncate(keywords, 15, true) + " (0)");
Image closeImg = new Image(OneSwarmDialogBox.CLOSE_IMAGE_URL);
closable.add(searchLabel);
closable.setCellVerticalAlignment(searchLabel, VerticalPanel.ALIGN_MIDDLE);
Image spacerImg = new Image("images/spacer.png");
spacerImg.setWidth("5px");
spacerImg.setHeight("5px");
closable.add(spacerImg);
closable.add(closeImg);
closable.setCellVerticalAlignment(closeImg, VerticalPanel.ALIGN_MIDDLE);
final VerticalPanel resultsWidget = new VerticalPanel();
resultsWidget.addStyleName(CSS_SEARCH_RESULTS_PANEL);
final HTML resultsCount = new HTML("0 results");
resultsWidget.add(resultsCount);
resultsWidget.setCellHorizontalAlignment(resultsCount, HorizontalPanel.ALIGN_CENTER);
searchTabs.add(resultsWidget, closable);
searchTabs.selectTab(searchTabs.getWidgetIndex(resultsWidget));
closeImg.addClickListener(new ClickListener() {
@Override
public void onClick(Widget sender) {
if (searchTabs.getTabBar().getSelectedTab() == searchTabs
.getWidgetIndex(resultsWidget)) {
searchTabs.selectTab(searchTabs.getTabBar().getSelectedTab() - 1);
}
searchTabs.remove(resultsWidget);
/*
* Remove the tab bar if the only tab remaining is the files tab
*/
if (searchTabs.getTabBar().getTabCount() == 1) {
searchTabs.removeFromParent();
keyboardRecorder.removeFromParent();
EntireUIRoot.this.add(keyboardRecorder, DockPanel.EAST);
searchTabs = null;
}
}
});
/**
* Now that the UI is set up, do the actual search.
*/
String session = OneSwarmRPCClient.getSessionID();
OneSwarmUIServiceAsync service = OneSwarmRPCClient.getService();
AsyncCallback<Integer> callback = new AsyncCallback<Integer>() {
@Override
public void onSuccess(Integer result) {
OneSwarmGWT.log("sending search, id=" + result);
// resultsWidget.clear();
resultsWidget.insert(new F2FSearchQueryWithResults(keywords, EntireUIRoot.this,
result, resultsCount, new F2FSearchQueryWithResults.ResultsCallback() {
int oldCount = 0;
@Override
public void updateCount(int count) {
if (count != oldCount) {
searchLabel.setText(StringTools.truncate(keywords, 15, true)
+ " (" + count + ")");
oldCount = count;
}
}
}), 0);
}
@Override
public void onFailure(Throwable caught) {
// well, do nothing...
OneSwarmGWT.log("error " + caught.getMessage());
caught.printStackTrace();
resultsWidget.add(new Label("Error: " + caught.toString()));
// searchField.setText(caught.getMessage());
}
};
service.sendSearch(session, keywords, callback);
header.focusSearch();
}
public void startChat(final FriendInfoLite selectedFriend) {
if (selectedFriend != null) {
if (selectedFriend.isSupportsChat() == false
&& selectedFriend.getStatus() == FriendInfoLite.STATUS_ONLINE) {
Window.alert("This user's OneSwarm client does not support chat (or has disabled it).");
return;
}
if (selectedFriend.isAllowChat() == false
&& selectedFriend.getStatus() == FriendInfoLite.STATUS_ONLINE) {
Window.alert("You have disabled chat for this friend.");
return;
}
}
final FriendInfoLite[] allFriends = navSidePanel.getFriendPanel().getFriendListPanel()
.getAllFriends();
boolean openNewWindow = true;
if (ChatDialog.showing()) {
if (!ChatDialog.tryHide()) {
openNewWindow = false;
}
}
if (openNewWindow) {
ChatDialog dlg = new ChatDialog(allFriends,
selectedFriend != null ? selectedFriend.getPublicKey() : null, this);
}
}
public void setUnreadChatCount(int total) {
navSidePanel.setUnreadChatCount(total);
}
public TorrentInfo[] getSelectedSwarms() {
return swarmFileBrowser.getSelectedSwarms();
}
Footer mFooter = new Footer();
public Footer getFooter() {
return mFooter;
}
}