/*
- * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
+ * Copyright 2007, 2008, 2009, 2010 Electronic Business Systems Ltd.
*
* This file is part of GSS.
*
import gr.ebs.gss.client.clipboard.Clipboard;
import gr.ebs.gss.client.dnd.DnDFocusPanel;
+import gr.ebs.gss.client.dnd.DnDSimpleFocusPanel;
import gr.ebs.gss.client.rest.GetCommand;
import gr.ebs.gss.client.rest.RestException;
import gr.ebs.gss.client.rest.resource.FileResource;
import gr.ebs.gss.client.rest.resource.TrashResource;
import gr.ebs.gss.client.rest.resource.UserResource;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
+import com.google.gwt.event.logical.shared.ValueChangeEvent;
+import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
+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.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
-
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
*/
public static final boolean DONE = false;
- public static final int VISIBLE_FILE_COUNT = 200;
+ public static final int VISIBLE_FILE_COUNT = 100;
/**
* Instantiate an application-level image bundle. This object will provide
* programmatic access to all the images needed by widgets.
*/
private static Images images = (Images) GWT.create(Images.class);
+
private GlassPanel glassPanel = new GlassPanel();
/**
* An aggregate image bundle that pulls together all the images for this
* application into a single bundle.
*/
- public interface Images extends ClientBundle,TopPanel.Images, StatusPanel.Images, FileMenu.Images, EditMenu.Images, SettingsMenu.Images, GroupMenu.Images, FilePropertiesDialog.Images, MessagePanel.Images, FileList.Images, SearchResults.Images, Search.Images, Groups.Images, Folders.Images {
+ public interface Images extends ClientBundle, TopPanel.Images, StatusPanel.Images, FileMenu.Images, EditMenu.Images, SettingsMenu.Images, GroupMenu.Images, FilePropertiesDialog.Images, MessagePanel.Images, FileList.Images, SearchResults.Images, Search.Images, Groups.Images, Folders.Images {
@Source("gr/ebs/gss/resources/document.png")
ImageResource folders();
/**
* The group list widget.
*/
- private Groups groups = new Groups(images);
+ private Groups groups = new Groups(images);
/**
* The search result widget.
private SearchResults searchResults;
/**
- * A widget that displays a message indicating that communication with the
- * server is underway.
- */
- private LoadingIndicator loading;
-
- /**
* The tab panel that occupies the right side of the screen.
*/
- private TabPanel inner = new TabPanel();
+ private TabPanel inner = new DecoratedTabPanel();
/**
* The split panel that will contain the left and right panels.
private PickupDragController dragController;
+ @Override
public void onModuleLoad() {
// Initialize the singleton before calling the constructors of the
// various widgets that might call GSS.get().
@Override
public void previewDragStart() throws VetoDragException {
- super.previewDragStart();
- if (context.selectedWidgets.isEmpty())
+ super.previewDragStart();
+ if (context.selectedWidgets.isEmpty())
throw new VetoDragException();
- if(context.draggable != null){
- DnDFocusPanel toDrop = (DnDFocusPanel) context.draggable;
- //prevent drag and drop for trashed files and for unselected tree items
- if(toDrop.getFiles() != null && folders.isTrashItem(folders.getCurrent()))
- throw new VetoDragException();
- else if(toDrop.getItem() != null && !toDrop.getItem().equals(folders.getCurrent()))
- throw new VetoDragException();
- else if(toDrop.getItem() != null && !toDrop.getItem().isDraggable())
- throw new VetoDragException();
-
- }
- }
+ if (context.draggable != null)
+ if (context.draggable instanceof DnDFocusPanel) {
+ DnDFocusPanel toDrop = (DnDFocusPanel) context.draggable;
+ // prevent drag and drop for trashed files and for
+ // unselected tree items
+ if (toDrop.getFiles() != null && folders.isTrashItem(folders.getCurrent()))
+ throw new VetoDragException();
+ else if (toDrop.getItem() != null && !toDrop.getItem().equals(folders.getCurrent()))
+ throw new VetoDragException();
+ else if (toDrop.getItem() != null && !toDrop.getItem().isDraggable())
+ throw new VetoDragException();
+
+ } else if (context.draggable instanceof DnDSimpleFocusPanel) {
+ DnDSimpleFocusPanel toDrop = (DnDSimpleFocusPanel) context.draggable;
+ // prevent drag and drop for trashed files and for
+ // unselected tree items
+ if (toDrop.getFiles() != null && folders.isTrashItem(folders.getCurrent()))
+ throw new VetoDragException();
+ }
+ }
@Override
protected Widget newDragProxy(DragContext aContext) {
AbsolutePanel container = new AbsolutePanel();
DOM.setStyleAttribute(container.getElement(), "overflow", "visible");
for (Iterator iterator = aContext.selectedWidgets.iterator(); iterator.hasNext();) {
+ HTML html = null;
Widget widget = (Widget) iterator.next();
- DnDFocusPanel book = (DnDFocusPanel) widget;
- HTML html = book.cloneHTML();
- if(html == null)
+ if (widget instanceof DnDFocusPanel) {
+ DnDFocusPanel book = (DnDFocusPanel) widget;
+ html = book.cloneHTML();
+ } else if (widget instanceof DnDSimpleFocusPanel) {
+ DnDSimpleFocusPanel book = (DnDSimpleFocusPanel) widget;
+ html = book.cloneHTML();
+ }
+ if (html == null)
container.add(new Label("Drag ME"));
else
container.add(html);
searchResults = new SearchResults(images);
// Inner contains the various lists.
- inner.getTabBar().setStyleName("gss-TabBar");
- inner.setStyleName("gss-TabPanel");
+ inner.setAnimationEnabled(true);
+ inner.getTabBar().addStyleName("gss-MainTabBar");
+ inner.getDeckPanel().addStyleName("gss-MainTabPanelBottom");
inner.add(fileList, createHeaderHTML(AbstractImagePrototype.create(images.folders()), "Files"), true);
inner.add(groups, createHeaderHTML(AbstractImagePrototype.create(images.groups()), "Groups"), true);
@Override
public void onSelection(SelectionEvent<Integer> event) {
- int tabIndex= event.getSelectedItem();
+ int tabIndex = event.getSelectedItem();
+// TreeItem treeItem = GSS.get().getFolders().getCurrent();
switch (tabIndex) {
- case 0:
- fileList.clearSelectedRows();
- fileList.updateCurrentlyShowingStats();
- break;
- case 1:
- groups.updateCurrentlyShowingStats();
- break;
- case 2:
- searchResults.clearSelectedRows();
- searchResults.updateCurrentlyShowingStats();
- break;
- }
+ case 0:
+// Files tab selected
+ fileList.clearSelectedRows();
+ fileList.updateCurrentlyShowingStats();
+ break;
+ case 1:
+// Groups tab selected
+ groups.updateCurrentlyShowingStats();
+ updateHistory("Groups");
+ break;
+ case 2:
+// Search tab selected
+ searchResults.clearSelectedRows();
+ searchResults.updateCurrentlyShowingStats();
+ updateHistory("Search");
+ break;
+ }
}
});
-
+// If the application starts with no history token, redirect to a new "Files" state
+ String initToken = History.getToken();
+ if(initToken.length() == 0)
+ History.newItem("Files");
+// Add history listener to handle any history events
+ History.addValueChangeHandler(new ValueChangeHandler<String>() {
+ @Override
+ public void onValueChange(ValueChangeEvent<String> event) {
+ String tokenInput = event.getValue();
+ String historyToken = handleSpecialFolderNames(tokenInput);
+ try {
+ if(historyToken.equals("Search"))
+ inner.selectTab(2);
+ else if(historyToken.equals("Groups"))
+ inner.selectTab(1);
+ else if(historyToken.equals("Files")|| historyToken.length()==0)
+ inner.selectTab(0);
+ else {
+ PopupTree popupTree = GSS.get().getFolders().getPopupTree();
+ TreeItem treeObj = GSS.get().getFolders().getPopupTree().getTreeItem(historyToken);
+ SelectionEvent.fire(popupTree, treeObj);
+ }
+ } catch (IndexOutOfBoundsException e) {
+ inner.selectTab(0);
+ }
+ }
+ });
// Add the left and right panels to the split panel.
splitPanel.setLeftWidget(folders);
splitPanel.setRightWidget(inner);
splitPanel.setSplitPosition("25%");
splitPanel.setSize("100%", "100%");
+ splitPanel.addStyleName("gss-splitPanel");
// Create a dock panel that will contain the menu bar at the top,
// the shortcuts to the left, the status bar at the bottom and the
outer.setSpacing(4);
- loading = new LoadingIndicator();
-
// Hook the window resize event, so that we can adjust the UI.
Window.addResizeHandler(this);
-
// Clear out the window's built-in margin, because we want to take
// advantage of the entire client area.
Window.setMargin("0px");
-
// Finally, add the outer panel to the RootPanel, so that it will be
// displayed.
RootPanel.get().add(outer);
-
// Call the window resized handler to get the initial sizes setup. Doing
// this in a deferred command causes it to occur after all widgets'
// sizes have been computed by the browser.
DeferredCommand.addCommand(new Command() {
+
+ @Override
public void execute() {
- onWindowResized(Window.getClientWidth());
+ onWindowResized(Window.getClientHeight());
}
});
}
*/
private void fetchUser(final String username) {
String path = getApiPath() + username + "/";
- GetCommand<UserResource> getUserCommand = new GetCommand<UserResource>(UserResource.class, username, path){
+ GetCommand<UserResource> getUserCommand = new GetCommand<UserResource>(UserResource.class, username, path, null) {
@Override
public void onComplete() {
final String announcement = currentUserResource.getAnnouncement();
if (announcement != null)
DeferredCommand.addCommand(new Command() {
+
+ @Override
public void execute() {
displayInformation(announcement);
}
@Override
public void onError(Throwable t) {
GWT.log("Fetching user error", t);
- if(t instanceof RestException)
- GSS.get().displayError("No user found:"+((RestException)t).getHttpStatusText());
+ if (t instanceof RestException)
+ GSS.get().displayError("No user found:" + ((RestException) t).getHttpStatusText());
else
- GSS.get().displayError("System error fetching user data:"+t.getMessage());
+ GSS.get().displayError("System error fetching user data:" + t.getMessage());
authenticateUser();
}
};
Configuration conf = (Configuration) GWT.create(Configuration.class);
String cookie = conf.authCookie();
String auth = Cookies.getCookie(cookie);
- String domain = Window.Location.getHostName();
- String path = Window.Location.getPath();
- Cookies.setCookie(cookie, "", null, domain, path, false);
if (auth == null) {
authenticateUser();
// Redundant, but silences warnings about possible auth NPE, below.
int sepIndex = auth.indexOf(conf.cookieSeparator());
if (sepIndex == -1)
authenticateUser();
- token = auth.substring(sepIndex + 1, auth.length());
+ token = auth.substring(sepIndex + 1);
final String username = auth.substring(0, sepIndex);
if (username == null)
authenticateUser();
refreshWebDAVPassword();
DeferredCommand.addCommand(new Command() {
+
+ @Override
public void execute() {
fetchUser(username);
}
}
/**
- * Redirect the user to the logout page.
+ * Clear the cookie and redirect the user to the logout page.
*/
void logout() {
Configuration conf = (Configuration) GWT.create(Configuration.class);
+ String cookie = conf.authCookie();
+ String domain = Window.Location.getHostName();
+ String path = Window.Location.getPath();
+ Cookies.setCookie(cookie, "", null, domain, path, false);
Window.Location.assign(conf.logoutUrl());
}
* @return the header HTML fragment
*/
private String createHeaderHTML(AbstractImagePrototype imageProto, String caption) {
- String captionHTML = "<table class='caption' cellpadding='0' " +
- "cellspacing='0'>" + "<tr><td class='lcaption'>" + imageProto.getHTML() +
- "</td><td class='rcaption'><b style='white-space:nowrap'> " +
- caption + "</b></td></tr></table>";
+ String captionHTML = "<table class='caption' cellpadding='0' " + "cellspacing='0'>" + "<tr><td class='lcaption'>" + imageProto.getHTML() + "</td><td class='rcaption'><b style='white-space:nowrap'> " + caption + "</b></td></tr></table>";
return captionHTML;
}
-
private void onWindowResized(int height) {
// Adjust the split panel to take up the available room in the window.
int newHeight = height - splitPanel.getAbsoluteTop() - 44;
@Override
public void onResize(ResizeEvent event) {
- int width=event.getWidth();
- onWindowResized(width);
+ int height = event.getHeight();
+ onWindowResized(height);
}
- public boolean isFileListShowing(){
+ public boolean isFileListShowing() {
int tab = inner.getTabBar().getSelectedTab();
- if(tab == 0) return true;
+ if (tab == 0)
+ return true;
return false;
}
- public boolean isSearchResultsShowing(){
+ public boolean isSearchResultsShowing() {
int tab = inner.getTabBar().getSelectedTab();
- if(tab == 2) return true;
+ if (tab == 2)
+ return true;
return false;
}
/**
* Make the file list visible.
+ *
* @param update
*/
public void showFileList(boolean update) {
/**
* Make the search results visible.
+ *
* @param query the search query string
*/
public void showSearchResults(String query) {
* Display the 'loading' indicator.
*/
public void showLoadingIndicator() {
- loading.center();
+ topPanel.getLoading().setVisible(true);
}
/**
* Hide the 'loading' indicator.
*/
public void hideLoadingIndicator() {
- loading.hide();
+ topPanel.getLoading().setVisible(false);
}
/**
* @param y the new height
*/
public static native void resizeTo(int x, int y) /*-{
- $wnd.resizeTo(x,y);
+ $wnd.resizeTo(x,y);
}-*/;
/**
return fileList;
}
- public SearchResults getSearchResults(){
+ public SearchResults getSearchResults() {
return searchResults;
}
return clipboard;
}
-
- public StatusPanel getStatusPanel(){
+ public StatusPanel getStatusPanel() {
return statusPanel;
}
-
/**
* Retrieve the userDetailsPanel.
*
return dragController;
}
- public String getToken(){
+ public String getToken() {
return token;
}
return webDAVPassword;
}
- public void removeGlassPanel(){
+ public void removeGlassPanel() {
glassPanel.removeFromParent();
}
}
public static native void preventIESelection() /*-{
- $doc.body.onselectstart = function () { return false; };
+ $doc.body.onselectstart = function () { return false; };
}-*/;
public static native void enableIESelection() /*-{
if ($doc.body.onselectstart != null)
- $doc.body.onselectstart = null;
+ $doc.body.onselectstart = null;
}-*/;
/**
Cookies.setCookie(cookie, "", null, domain, path, false);
}
+ /**
+ * History support for folder navigation
+ * adds a new browser history entry
+ *
+ * @param key
+ */
+ public void updateHistory(String key){
+// Replace any whitespace of the initial string to "+"
+// String result = key.replaceAll("\\s","+");
+// Add a new browser history entry.
+// History.newItem(result);
+ History.newItem(key);
+ }
+
+ /**
+ * This method examines the token input and add a "/" at the end in case it's omitted.
+ * This happens only in Files/trash/, Files/shared/, Files/others.
+ *
+ * @param tokenInput
+ * @return the formated token with a "/" at the end or the same tokenInput parameter
+ */
+
+ private String handleSpecialFolderNames(String tokenInput){
+ List<String> pathsToCheck = Arrays.asList("Files/trash", "Files/shared", "Files/others");
+ if(pathsToCheck.contains(tokenInput))
+ return tokenInput + "/";
+ return tokenInput;
+
+ }
+
+ /**
+ * Reject illegal resource names, like '.' or '..'.
+ */
+ static boolean isValidResourceName(String name) {
+ if (".".equals(name) || "..".equals(name))
+ return false;
+ return true;
+ }
}