/>
<replaceregexp file="${gwt.www.dir}/${gwt.module}/index.html"
match="authCookie: (.*)"
- replace="authCookie: "${authCookie}""
+ replace="authCookie: "${authCookie}","
+ byline="true"
+ />
+ <replaceregexp file="${gwt.www.dir}/${gwt.module}/index.html"
+ match="version: (.*)"
+ replace="version: "${version}""
byline="true"
/>
</target>
-loginUrl = {{ settings.LOGIN_URL }}
-authCookie = {{ settings.AUTH_COOKIE_NAME }}
-feedbackUrl = {{ settings.FEEDBACK_URL }}
+#!!!!!ATTENTION!!!!! loginUrl MUST end at "next=". You should not give the value of the next parameter. It will be determined automatically
+loginUrl={{ settings.LOGIN_URL }}
+CLOUDBAR_ACTIVE_SERVICE = {{ settings.CLOUDBAR_ACTIVE }}
+CLOUDBAR_LOCATION = {{ settings.CLOUDBAR_LOCATION }}
+CLOUDBAR_SERVICES = {{ settings.CLOUDBAR_SERVICES_URL }}
+CLOUDBAR_MENU = {{ settings.CLOUDBAR_MENU_URL }}
+authCookie={{ settings.AUTH_COOKIE_NAME }}
+feedbackUrl={{ settings.FEEDBACK_URL }}
+version=0.9.0
\ No newline at end of file
import com.google.gwt.event.dom.client.KeyDownEvent;\r
import com.google.gwt.http.client.Response;\r
import com.google.gwt.http.client.URL;\r
+import com.google.gwt.regexp.shared.RegExp;\r
import com.google.gwt.user.client.Event.NativePreviewEvent;\r
import com.google.gwt.user.client.ui.Anchor;\r
import com.google.gwt.user.client.ui.Button;\r
String name = userName.getText().trim();\r
if (name.length() == 0)\r
return;\r
+ RegExp emailValidator = RegExp.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+[.][A-Z]{2,4}$", "i");\r
+ if (!emailValidator.test(name)) {\r
+ app.displayWarning("Username must be a valid email address");\r
+ return;\r
+ }\r
+ \r
group.addMember(name);\r
String path = "?update=";\r
PostRequest updateGroup = new PostRequest(app.getApiPath(), app.getUsername(), path) {\r
@DefaultStringValue("/v1/")
String apiPath();
- /**
- * @return the version string
- */
- @DefaultStringValue("")
- String version();
-
@DefaultStringValue("X-Auth-Token")
String authTokenCookie();
cookieSeparator=|
apiPath=/v1/
-version=0.8.4
authTokenCookie=X-Auth-Token
shibSessionCookiePrefix=_shibsession_
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.dom.client.TextAreaElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
Dictionary otherProperties = Dictionary.getDictionary("otherProperties");
+ Pithos app;
+
+ String appData;
+
+ TextArea msg;
+
/**
* The widget constructor.
*/
- public FeedbackDialog(final Pithos app, final String appData) {
+ public FeedbackDialog(final Pithos _app, final String _appData) {
+ app = _app;
+ appData = _appData;
+
// Set the dialog's caption.
Anchor close = new Anchor("close");
close.addStyleName("close");
inner.add(text);
FlexTable table = new FlexTable();
table.setText(0, 0, "Please describe your problem here, provide as many details as possible");
- final TextArea msg = new TextArea();
+ msg = new TextArea();
msg.setWidth("100%");
msg.setHeight("100px");
table.setWidget(1, 0, msg);
Button confirm = new Button("Submit feedback", new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
- PostRequest sendFeedback = new PostRequest("", "", otherProperties.get("feedbackUrl"), "feedback-msg=" + msg.getText() + "&feedback-data=" + appData) {
-
- @Override
- protected void onUnauthorized(Response response) {
- app.sessionExpired();
- }
-
- @Override
- public void onSuccess(Resource result) {
- app.displayInformation("Feedback sent");
- }
-
- @Override
- public void onError(Throwable t) {
- GWT.log("", t);
- }
- };
- sendFeedback.setHeader("X-Auth-Token", app.getToken());
- Scheduler.get().scheduleDeferred(sendFeedback);
+ sendFeedback();
hide();
}
});
protected void onPreviewNativeEvent(NativePreviewEvent preview) {
super.onPreviewNativeEvent(preview);
NativeEvent evt = preview.getNativeEvent();
- if (evt.getType().equals("keydown"))
+ if (evt.getType().equals("keydown")) {
// Use the popup's key preview hooks to close the dialog when
// either enter or escape is pressed.
switch (evt.getKeyCode()) {
case KeyCodes.KEY_ENTER:
+ sendFeedback();
+ hide();
+ break;
case KeyCodes.KEY_ESCAPE:
hide();
break;
}
+ }
+ }
+
+ /**
+ */
+ void sendFeedback() {
+ PostRequest sendFeedback = new PostRequest("", "", otherProperties.get("feedbackUrl"), "feedback_msg=" + msg.getText() + "&feedback_data=" + appData + "&auth=" + app.getToken()) {
+
+ @Override
+ protected void onUnauthorized(Response response) {
+ app.sessionExpired();
+ }
+
+ @Override
+ public void onSuccess(Resource result) {
+ app.displayInformation("Feedback sent");
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ }
+ };
+ Scheduler.get().scheduleDeferred(sendFeedback);
}
}
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import com.google.gwt.cell.client.Cell.Context;
import com.google.gwt.cell.client.ImageResourceCell;
else if (callback != null)
callback.execute();
}
+
+ public void selectByUrl(List<String> selectedUrls) {
+ Set<File> previous = selectionModel.getSelectedSet();
+ for (File f : previous)
+ selectionModel.setSelected(f, false);
+
+ int i = 0;
+ boolean scrolled = false;
+ for (File f : files) {
+ if (selectedUrls.contains(app.getApiPath() + f.getOwner() + f.getUri())) {
+ selectionModel.setSelected(f, true);
+ if (!scrolled) {
+ celltable.getRowElement(i).getCells().getItem(0).scrollIntoView();
+ scrolled = true;
+ }
+ }
+ i++;
+ }
+ }
}
import gr.grnet.pithos.web.client.rest.PostRequest;\r
import gr.grnet.pithos.web.client.rest.PutRequest;\r
\r
+import java.util.Arrays;\r
import java.util.HashMap;\r
import java.util.Map;\r
\r
PutRequest updateFile = new PutRequest(app.getApiPath(), app.getUsername(), path) {\r
@Override\r
public void onSuccess(Resource result) {\r
- updateMetaData(app.getApiPath(), file.getOwner(), path + "?update=", newMeta);\r
+ updateMetaData(app.getApiPath(), file.getOwner(), path, newMeta);\r
}\r
\r
@Override\r
Scheduler.get().scheduleDeferred(updateFile);\r
}\r
else\r
- updateMetaData(app.getApiPath(), app.getUsername(), file.getUri() + "?update=", newMeta);\r
+ updateMetaData(app.getApiPath(), app.getUsername(), file.getUri(), newMeta);\r
return true;\r
}\r
\r
- protected void updateMetaData(String api, String owner, String path, Map<String, String> newMeta) {\r
+ protected void updateMetaData(final String api, final String owner, final String path, Map<String, String> newMeta) {\r
if (newMeta != null) {\r
- PostRequest updateFile = new PostRequest(api, owner, path) {\r
+ PostRequest updateFile = new PostRequest(api, owner, path + "?update=") {\r
@Override\r
public void onSuccess(Resource result) {\r
if (!app.isMySharedSelected())\r
\r
@Override\r
public void execute() {\r
+ app.getFileList().selectByUrl(Arrays.asList(api + owner + path));\r
app.updateMySharedRoot();\r
}\r
}, true);\r
- else\r
- app.updateSharedFolder(file.getParent(), true);\r
+ else {\r
+ app.updateSharedFolder(file.getParent(), true, new Command() {\r
+ \r
+ @Override\r
+ public void execute() {\r
+ app.getFileList().selectByUrl(Arrays.asList(api + owner + path));\r
+ }\r
+ });\r
+ }\r
}\r
\r
@Override\r
\r
@Override\r
public void execute() {\r
+ app.getFileList().selectByUrl(Arrays.asList(api + owner + path));\r
if (file.isSharedOrPublished())\r
app.updateMySharedRoot();\r
}\r
}, true);\r
- else\r
+ else {\r
+ app.getFileList().selectByUrl(Arrays.asList(api + owner + path));\r
app.updateSharedFolder(file.getParent(), true);\r
+ }\r
}\r
}\r
import gr.grnet.pithos.web.client.foldertree.Folder;
+import com.google.gwt.core.client.Scheduler;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
public static final boolean DONE = true;
+ Anchor close;
+
/**
* The Form element that performs the file upload.
*/
protected Folder folder;
protected Pithos app;
+
+ private boolean inProgress = false;
/**
* The widget's constructor.
*/
public FileUploadDialog(Pithos _app) {
app = _app;
- Anchor close = new Anchor("close");
+ close = new Anchor("close");
close.addStyleName("close");
close.addClickHandler(new ClickHandler() {
// Set the dialog's caption.
setText("File upload");
setAnimationEnabled(true);
- setGlassEnabled(true);
+// setGlassEnabled(true);
setStyleName("pithos-DialogBox");
setVisible(false);
panel.setCellHorizontalAlignment(inner, HasHorizontalAlignment.ALIGN_CENTER);
setWidget(form);
+
+ Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
+
+ @Override
+ public void execute() {
+ center();
+ close();
+ }
+ });
}
private void refreshFolder() {
}
}, true);
else
- app.updateOtherSharedFolder(folder, true);
+ app.updateOtherSharedFolder(folder, true, null);
}
- native void setupUpload(FileUploadDialog dlg, String path, String token) /*-{
+ native void setupUpload(FileUploadDialog dlg, Pithos app, String token) /*-{
var uploader = $wnd.$('#uploader').pluploadQueue();
var createUploader = function() {
$wnd.$("#uploader").pluploadQueue({
init: {
FilesAdded: function(up, files) {
+ var api = app.@gr.grnet.pithos.web.client.Pithos::getApiPath()();
+ var folder = app.@gr.grnet.pithos.web.client.Pithos::getUploadFolder()();
+ var owner = folder.@gr.grnet.pithos.web.client.foldertree.Folder::getOwner()();
+ var uri = folder.@gr.grnet.pithos.web.client.foldertree.Folder::getUri()();
+ var path = api + owner + uri;
for (var j=0; j<files.length; j++)
- files[j].url = up.path + "/" + files[j].name + "?X-Auth-Token=" + encodeURIComponent(token);
+ files[j].url = path + "/" + files[j].name;
+ dlg.@gr.grnet.pithos.web.client.FileUploadDialog::setInProgress(Z)(true);
+ if (up.state == $wnd.plupload.STOPPED)
+ up.start();
+ app.@gr.grnet.pithos.web.client.Pithos::showUploadIndicator()();
+ if (!dlg.@gr.grnet.pithos.web.client.FileUploadDialog::isVisible()())
+ app.@gr.grnet.pithos.web.client.Pithos::showUploadAlert(I)(up.files.length);
+ },
+
+ FilesRemoved: function(up, files) {
+ if (up.files.length == 0)
+ dlg.@gr.grnet.pithos.web.client.FileUploadDialog::setInProgress(Z)(false);
+ else
+ dlg.@gr.grnet.pithos.web.client.FileUploadDialog::setInProgress(Z)(true);
},
BeforeUpload: function(up, file) {
if ($wnd.console && $wnd.console.log)
$wnd.console.log('About to upload ' + file.url);
- up.settings.url = file.url;
+ up.settings.url = file.url + + "?X-Auth-Token=" + encodeURIComponent(token);
+ },
+
+ UploadProgress: function(up, file) {
+ $wnd.$('#upload_alert_progress_bar').css('width', up.total.percent + '%');
+ $wnd.$('#upload_alert_percent').html(up.total.percent + '%');
},
FileUploaded: function(up, file, response) {
$wnd.console.log('File ' + file.name + ' uploaded');
$wnd.console.log('Response: ' + response);
}
+ var folder = app.@gr.grnet.pithos.web.client.Pithos::getUploadFolder()();
+ if (folder == file.folder)
+ app.@gr.grnet.pithos.web.client.Pithos::updateUploadFolder()();
},
UploadComplete: function(up, files) {
- if ($wnd.console && $wnd.console.log)
+ if ($wnd.console && $wnd.console.log) {
$wnd.console.log('All files finished');
+ }
+ dlg.@gr.grnet.pithos.web.client.FileUploadDialog::setInProgress(Z)(false);
dlg.@gr.grnet.pithos.web.client.FileUploadDialog::hideUploadIndicator()();
- dlg.@gr.grnet.pithos.web.client.FileUploadDialog::refreshFolder()();
+ app.@gr.grnet.pithos.web.client.Pithos::hideUploadAlert()();
+ var uris = [];
+ if (!dlg.@gr.grnet.pithos.web.client.FileUploadDialog::isVisible()())
+ while (files.length > 0) {
+ uris.push(files[0].url);
+ up.removeFile(files[0]);
+ }
+ else
+ for (var i=0; i<files.length; i++)
+ uris.push(files[i].url);
+ app.@gr.grnet.pithos.web.client.Pithos::updateUploadFolder(Lcom/google/gwt/core/client/JsArrayString;)(uris);
},
Error: function(up, error) {
uploader = createUploader();
}
else {
+ var dropElm = $wnd.document.getElementById('rightPanel');
+ $wnd.plupload.removeAllEvents(dropElm, uploader.id);
var removeAll = true;
var files = uploader.files;
if ($wnd.console && $wnd.console.log)
uploader = createUploader();
if ($wnd.console && $wnd.console.log)
$wnd.console.log(uploader);
+ dlg.@gr.grnet.pithos.web.client.FileUploadDialog::setInProgress(Z)(false);
+ }
+ else {
+ dlg.@gr.grnet.pithos.web.client.FileUploadDialog::setInProgress(Z)(true);
}
}
- uploader.path = path;
}-*/;
native boolean isUploading()/*-{
setVisible(true);
setModal(true);
super.center();
- String path = app.getApiPath() + folder.getOwner() + folder.getUri();
- setupUpload(this, path, app.getToken());
+ setupUpload(this, app, app.getToken());
super.center();
}
void close() {
setVisible(false);
setModal(false);
+ clearUploader();
if (isUploading())
app.showUploadIndicator();
+ setGlobalDropArea();
+ }
+
+ private native void clearUploader() /*-{
+ var uploader = $wnd.$("#uploader").pluploadQueue();
+ var files = uploader.files;
+ while (files.length > 0)
+ uploader.removeFile(files[0]);
+ }-*/;
+
+ native void setGlobalDropArea() /*-{
+ var uploader = $wnd.$("#uploader").pluploadQueue();
+ if (uploader.runtime == 'html5') {
+ uploader.settings.drop_element = 'rightPanel';
+ uploader.trigger('PostInit');
+ }
+ }-*/;
+
+ private void setInProgress(boolean _inProgress) {
+ inProgress = _inProgress;
+ if (inProgress)
+ close.setText("hide");
+ else
+ close.setText("close");
}
}
import com.google.gwt.event.dom.client.ClickHandler;\r
import com.google.gwt.resources.client.ClientBundle;\r
import com.google.gwt.resources.client.ImageResource;\r
+import com.google.gwt.user.client.Window;\r
import com.google.gwt.user.client.ui.AbstractImagePrototype;\r
import com.google.gwt.user.client.ui.Composite;\r
import com.google.gwt.user.client.ui.HTML;\r
* A link to send feedBack about the error.\r
*/\r
private HTML feedbackLink;\r
+ \r
+ Pithos app;\r
+ \r
/**\r
* The widget's constructor.\r
*\r
* @param newImages a bundle that provides the images for this widget\r
*/\r
- public MessagePanel(final Pithos app, final Images newImages) {\r
+ public MessagePanel(Pithos _app, final Images newImages) {\r
+ app = _app;\r
images = newImages;\r
simplePanel = new SimplePanel();\r
simplePanel.setStyleName("effectPanel");\r
public void hideMessage() {\r
message = new HTML(" ");\r
this.setVisible(false);\r
+ app.onWindowResized(Window.getClientHeight());\r
}\r
-\r
}\r
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.regexp.shared.RegExp;
import com.google.gwt.user.client.Event.NativePreviewEvent;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
protected void addPermission() {
String selected = null;
if (userAdd) {
- selected = userBox.getText();
+ selected = userBox.getText().trim();
+ RegExp emailValidator = RegExp.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+[.][A-Z]{2,4}$", "i");
+ if (!emailValidator.test(selected)) {
+ app.displayWarning("Username must be a valid email address");
+ return;
+ }
} else if (groupBox.getSelectedIndex() > -1) {
String groupName = groupBox.getValue(groupBox.getSelectedIndex());
selected = app.getUsername() + ":" + groupName;
return;
}
if (selected == null || selected.length() == 0 || selected.equals(app.getUsername() + ":")) {
- app.displayError("You have to select o username or group");
+ app.displayWarning("You have to select a username or group");
return;
}
+
boolean readValue = read.getValue();
boolean writeValue = write.getValue();
permTable.setHTML(i, 0, "<span>" + AbstractImagePrototype.create(images.permUser()).getHTML() + " " + user + "</span>");
else
permTable.setHTML(i, 0, "<span>" + AbstractImagePrototype.create(images.permGroup()).getHTML() + " " + user.split(":")[1].trim() + "</span>");
- permTable.getFlexCellFormatter().setStyleName(i, 0, "props-labels");
+ permTable.getFlexCellFormatter().setStyleName(i, 0, "props-values");
Boolean[] userPerms = permissions.get(user);
Boolean readP = userPerms[0];
color: #4085A5;
text-decoration: underline;
}
+
+.statistics {
+ color: black;
+ padding-top: 10px;
+ padding-bottom: 10px;
+}
+
+@external gwt-HTML;
+
+.statistics .gwt-HTML {
+ font-size: 80%;
+}
+
+.uploadAlert {
+ background-color: #4085a5;
+ border: none;
+ width: 350px;
+}
+
+.uploadAlertLink {
+ text-decoration: underline;
+ position: absolute;
+ left: 200px;
+ top: 2px;
+}
+
+.uploadAlertClose {
+ cursor: pointer;
+ position: absolute;
+ right: 1px;
+ top: 2px;
+}
+
+.uploadAlertProgress {
+ display: block;
+ float: left;
+}
+
+.uploadAlertPercent {
+ position: absolute;
+ left: 90px;
+}
\ No newline at end of file
*/
package gr.grnet.pithos.web.client;
-import gr.grnet.pithos.web.client.PithosDisclosurePanel.Style;
import gr.grnet.pithos.web.client.commands.UploadFileCommand;
import gr.grnet.pithos.web.client.foldertree.AccountResource;
import gr.grnet.pithos.web.client.foldertree.File;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.i18n.client.Dictionary;
-import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.ImageResource;
-import com.google.gwt.resources.client.ClientBundle.Source;
import com.google.gwt.resources.client.ImageResource.ImageOptions;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.HorizontalSplitPanel;
+import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.SelectionChangeEvent;
public interface Style extends CssResource {
String commandAnchor();
+
+ String statistics();
+
+ @ClassName("gwt-HTML")
+ String html();
+
+ String uploadAlert();
+
+ String uploadAlertLink();
+
+ String uploadAlertProgress();
+
+ String uploadAlertPercent();
+
+ String uploadAlertClose();
}
public interface Resources extends ClientBundle {
@Source("Pithos.css")
Style pithosCss();
+
+ @Source("gr/grnet/pithos/resources/close-popup.png")
+ ImageResource closePopup();
}
public static Resources resources = GWT.create(Resources.class);
updateSharedFolder(f, showfiles, null);
}
- public void updateOtherSharedFolder(Folder f, boolean showfiles) {
- otherSharedTreeView.updateFolder(f, showfiles);
+ public void updateOtherSharedFolder(Folder f, boolean showfiles, Command callback) {
+ otherSharedTreeView.updateFolder(f, showfiles, callback);
}
public MysharedTreeView getMySharedTreeView() {
/**
* The bottom panel that contains the status bar.
*/
- private StatusPanel statusPanel = null;
+ StatusPanel statusPanel = null;
/**
* The file list widget.
@SuppressWarnings("rawtypes") List<SingleSelectionModel> selectionModels = new ArrayList<SingleSelectionModel>();
- Button upload;
+ public Button upload;
private HTML numOfFiles;
private Toolbar toolbar;
- private FileUploadDialog fileUploadDialog;
-
+ private FileUploadDialog fileUploadDialog = new FileUploadDialog(this);
+
+ UploadAlert uploadAlert;
+
@Override
public void onModuleLoad() {
if (parseUserCredentials())
header.setCellWidth(folderStatistics, "40px");
outer.add(header);
outer.setCellHorizontalAlignment(header, HasHorizontalAlignment.ALIGN_CENTER);
- // Inner contains the various lists.nner
+ // Inner contains the various lists
inner.sinkEvents(Event.ONCONTEXTMENU);
inner.setWidth("100%");
// Add the left and right panels to the split panel.
splitPanel.setLeftWidget(trees);
- splitPanel.setRightWidget(inner);
+ FlowPanel right = new FlowPanel();
+ right.getElement().setId("rightPanel");
+ right.add(inner);
+ splitPanel.setRightWidget(right);
splitPanel.setSplitPosition("219px");
splitPanel.setSize("100%", "100%");
splitPanel.addStyleName("pithos-splitPanel");
// 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.
- Scheduler.get().scheduleDeferred(new ScheduledCommand() {
-
- @Override
- public void execute() {
+ Scheduler.get().scheduleIncremental(new RepeatingCommand() {
+
+ @Override
+ public boolean execute() {
+ if (!isCloudbarReady())
+ return true;
onWindowResized(Window.getClientHeight());
- }
- });
-
+ return false;
+ }
+ });
+
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
public void applyPermissions(Folder f) {
if (f != null) {
- if (f.isInTrash())
+ if (f.isInTrash()) {
upload.setEnabled(false);
+ disableUploadArea();
+ }
else {
Boolean[] perms = f.getPermissions().get(username);
if (f.getOwner().equals(username) || (perms != null && perms[1] != null && perms[1])) {
upload.setEnabled(true);
+ enableUploadArea();
}
- else
+ else {
upload.setEnabled(false);
+ disableUploadArea();
+ }
}
}
- else
+ else {
upload.setEnabled(false);
+ disableUploadArea();
+ }
}
@SuppressWarnings({ "rawtypes", "unchecked" })
Window.Location.assign(otherProperties.get("loginUrl") + Window.Location.getHref());
}
- protected void fetchAccount(final Command callback) {
+ public void fetchAccount(final Command callback) {
String path = "?format=json";
GetRequest<AccountResource> getAccount = new GetRequest<AccountResource>(AccountResource.class, getApiPath(), username, path) {
protected void onWindowResized(int height) {
// Adjust the split panel to take up the available room in the window.
- int newHeight = height - splitPanel.getAbsoluteTop();
+ int newHeight = height - splitPanel.getAbsoluteTop() - 153;
if (newHeight < 1)
newHeight = 1;
splitPanel.setHeight("" + newHeight);
inner.setHeight("" + newHeight);
}
-
+
+ native boolean isCloudbarReady()/*-{
+ if ($wnd.$("div.servicesbar") && $wnd.$("div.servicesbar").height() > 0)
+ return true;
+ return false;
+ }-*/;
+
@Override
public void onResize(ResizeEvent event) {
int height = event.getHeight();
*/
public void displayError(String msg) {
messagePanel.displayError(msg);
+ onWindowResized(Window.getClientHeight());
}
/**
*/
public void displayWarning(String msg) {
messagePanel.displayWarning(msg);
+ onWindowResized(Window.getClientHeight());
}
/**
*/
public void displayInformation(String msg) {
messagePanel.displayInformation(msg);
+ onWindowResized(Window.getClientHeight());
}
/**
if (mysharedTreeSelectionModel.getSelectedObject() != null) {
deselectOthers(mysharedTreeView, mysharedTreeSelectionModel);
upload.setEnabled(false);
+ disableUploadArea();
updateSharedFolder(mysharedTreeSelectionModel.getSelectedObject(), true);
showRelevantToolbarButtons();
}
if (otherSharedTreeSelectionModel.getSelectedObject() != null) {
deselectOthers(otherSharedTreeView, otherSharedTreeSelectionModel);
applyPermissions(otherSharedTreeSelectionModel.getSelectedObject());
- updateOtherSharedFolder(otherSharedTreeSelectionModel.getSelectedObject(), true);
+ updateOtherSharedFolder(otherSharedTreeSelectionModel.getSelectedObject(), true, null);
showRelevantToolbarButtons();
}
else {
public boolean isMySharedSelected() {
return getSelectedTree().equals(getMySharedTreeView());
}
+
+ private Folder getUploadFolder() {
+ if (folderTreeView.equals(getSelectedTree()) || otherSharedTreeView.equals(getSelectedTree())) {
+ return getSelection();
+ }
+ return null;
+ }
+
+ private void updateUploadFolder() {
+ updateUploadFolder(null);
+ }
+
+ private void updateUploadFolder(final JsArrayString urls) {
+ if (folderTreeView.equals(getSelectedTree()) || otherSharedTreeView.equals(getSelectedTree())) {
+ Folder f = getSelection();
+ if (getSelectedTree().equals(getFolderTreeView()))
+ updateFolder(f, true, new Command() {
+
+ @Override
+ public void execute() {
+ updateStatistics();
+ if (urls != null)
+ selectUploadedFiles(urls);
+ }
+ }, false);
+ else
+ updateOtherSharedFolder(f, true, null);
+ }
+ }
+
+ public native void disableUploadArea() /*-{
+ var uploader = $wnd.$("#uploader").pluploadQueue();
+ var dropElm = $wnd.document.getElementById('rightPanel');
+ $wnd.plupload.removeAllEvents(dropElm, uploader.id);
+ }-*/;
+
+ public native void enableUploadArea() /*-{
+ var uploader = $wnd.$("#uploader").pluploadQueue();
+ var dropElm = $wnd.document.getElementById('rightPanel');
+ $wnd.plupload.removeAllEvents(dropElm, uploader.id);
+ if (uploader.runtime == 'html5') {
+ uploader.settings.drop_element = 'rightPanel';
+ uploader.trigger('PostInit');
+ }
+ }-*/;
+
+ public void showUploadAlert(int nOfFiles) {
+ if (uploadAlert == null)
+ uploadAlert = new UploadAlert(this, nOfFiles);
+ if (!uploadAlert.isShowing())
+ uploadAlert.setPopupPositionAndShow(new PopupPanel.PositionCallback() {
+
+ @Override
+ public void setPosition(int offsetWidth, int offsetHeight) {
+ uploadAlert.setPopupPosition((Window.getClientWidth() - offsetWidth)/2, statusPanel.getAbsoluteTop() - offsetHeight);
+ }
+ });
+ uploadAlert.setNumOfFiles(nOfFiles);
+ }
+
+ public void hideUploadAlert() {
+ if (uploadAlert != null && uploadAlert.isShowing())
+ uploadAlert.hide();
+ }
+
+ public void selectUploadedFiles(JsArrayString urls) {
+ List<String> selectedUrls = new ArrayList<String>();
+ for (int i=0; i<urls.length(); i++)
+ selectedUrls.add(urls.get(i));
+ fileList.selectByUrl(selectedUrls);
+ }
}
package gr.grnet.pithos.web.client;
import com.google.gwt.core.client.GWT;
+import com.google.gwt.i18n.client.Dictionary;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
* The constructor of the status panel.
*/
public StatusPanel() {
- Configuration conf = GWT.create(Configuration.class);
+ Dictionary otherProperties = Dictionary.getDictionary("otherProperties");
+
HorizontalPanel outer = new HorizontalPanel();
outer.setWidth("100%");
outer.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
inner.add(firstLine);
HorizontalPanel secondLine = new HorizontalPanel();
- secondLine.add(new HTML("Pithos Web Client v" + conf.version() + " <a class='grnet-sign' href='http://www.grnet.gr'>Copyright (C) 2011-2012 Greek Research and Technology Network</a>"));
+ secondLine.add(new HTML("Pithos Web Client v" + otherProperties.get("version") + " <a class='grnet-sign' href='http://www.grnet.gr'>Copyright (C) 2011-2012 Greek Research and Technology Network</a>"));
secondLine.addStyleName("grnet-sign");
inner.add(secondLine);
outer.add(inner);
--- /dev/null
+/*
+ * Copyright 2011-2012 GRNET S.A. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and
+ * documentation are those of the authors and should not be
+ * interpreted as representing official policies, either expressed
+ * or implied, of GRNET S.A.
+ */
+package gr.grnet.pithos.web.client;
+
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.user.client.ui.Anchor;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Image;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+/**
+ * The 'Folder Context' menu implementation.
+ */
+public class UploadAlert extends PopupPanel {
+
+ private HTML label = new HTML();
+
+ /**
+ * The widget's constructor.
+ */
+ public UploadAlert(final Pithos app, int _numOfFiles) {
+ // The popup's constructor's argument is a boolean specifying that it
+ // auto-close itself when the user clicks outside of it.
+ super(false);
+ setAnimationEnabled(true);
+ addStyleName(Pithos.resources.pithosCss().uploadAlert());
+ FlowPanel content = new FlowPanel();
+ setNumOfFiles(_numOfFiles);
+ content.add(label);
+ Anchor a = new Anchor("Click for details");
+ a.addStyleName(Pithos.resources.pithosCss().uploadAlertLink());
+ a.addClickHandler(new ClickHandler() {
+
+ @Override
+ public void onClick(ClickEvent event) {
+ app.getFileUploadDialog().center();
+ }
+ });
+ content.add(a);
+ Image close = new Image(Pithos.resources.closePopup());
+ close.addClickHandler(new ClickHandler() {
+
+ @Override
+ public void onClick(ClickEvent event) {
+ hide();
+ }
+ });
+ close.addStyleName(Pithos.resources.pithosCss().uploadAlertClose());
+ content.add(close);
+
+ FlowPanel progress = new FlowPanel();
+ progress.addStyleName("plupload_progress");
+ progress.addStyleName(Pithos.resources.pithosCss().uploadAlertProgress());
+ FlowPanel progress_container = new FlowPanel();
+ progress_container.addStyleName("plupload_progress_container");
+ progress.add(progress_container);
+ FlowPanel progress_bar = new FlowPanel();
+ progress_bar.getElement().setId("upload_alert_progress_bar");
+ progress_bar.addStyleName("plupload_progress_bar");
+ progress_container.add(progress_bar);
+ content.add(progress);
+
+ HTML percent = new HTML();
+ percent.getElement().setId("upload_alert_percent");
+ percent.addStyleName(Pithos.resources.pithosCss().uploadAlertPercent());
+ content.add(percent);
+
+ add(content);
+ }
+
+ public void setNumOfFiles(int n) {
+ label.setText(String.valueOf(n) + " " + (n > 1 ? "files are" : "file is") + " being uploaded");
+ }
+}
public void execute() {
if (containerPanel != null)
containerPanel.hide();
- final Group group = user.getGroup();
+ final String groupName = user.getGroup();
+ final Group group = app.getAccount().getGroup(groupName);
+ if (group == null)
+ return;
group.removeMember(user.getName());
String path = "?update=";
PostRequest updateGroup = new PostRequest(app.getApiPath(), app.getUsername(), path) {
@Override
public void onSuccess(Resource result) {
- app.updateGroupNode(group);
+ app.fetchAccount(new Command() {
+
+ @Override
+ public void execute() {
+ Group updatedGroup2 = app.getAccount().getGroup(groupName);
+ if (updatedGroup2 != null)
+ app.updateGroupNode(updatedGroup2);
+ else {
+ app.updateGroupNode(null);
+ }
+ }
+ });
}
@Override
return f;
return null;
}
+
+ public Group getGroup(String groupName) {
+ for (Group g : groups)
+ if (g.getName().equalsIgnoreCase(groupName))
+ return g;
+ return null;
+ }
}
public boolean equals(Object other) {
if (other instanceof Folder) {
Folder o = (Folder) other;
- return getUri().equals(o.getUri());
+ return owner.equals(o.getOwner()) && getUri().equals(o.getUri());
}
return false;
}
package gr.grnet.pithos.web.client.foldertree;
import gr.grnet.pithos.web.client.FolderContextMenu;
+import gr.grnet.pithos.web.client.Pithos;
import gr.grnet.pithos.web.client.PithosDisclosurePanel;
import gr.grnet.pithos.web.client.TreeView;
content.add(tree);
HorizontalPanel statistics = new HorizontalPanel();
- statistics.addStyleName("pithos-statistics");
+ statistics.addStyleName(Pithos.resources.pithosCss().statistics());
statistics.add(new HTML("Used: "));
usedBytes = new HTML();
statistics.add(usedBytes);
if (selected != null) {
app.deselectOthers(app.getGroupTreeView(), groupSelectionModel);
app.showFiles(new HashSet<File>());
+ app.disableUploadArea();
+ app.upload.setEnabled(false);
app.showRelevantToolbarButtons();
if (selected.equals(createGroup)) {
new CreateGroupCommand(app, null).execute();
final ListDataProvider<User> dataProvider = userDataProviderMap.get(g);
dataProvider.getList().clear();
for (String u : g.getMembers())
- dataProvider.getList().add(new User(u, g));
+ dataProvider.getList().add(new User(u, g.getName()));
return new DefaultNodeInfo<User>(dataProvider, userCell, userSelectionModel, null);
}
final ListDataProvider<User> dataProvider = userDataProviderMap.get(group);
dataProvider.getList().clear();
for (String u : group.getMembers())
- dataProvider.getList().add(new User(u, group));
+ dataProvider.getList().add(new User(u, group.getName()));
}
}
public class User {
private String name;
- private Group group;
+ private String group;
- public User(String _name, Group _group) {
+ public User(String _name, String _group) {
name = _name;
group = _group;
}
return name;
}
- public Group getGroup() {
+ public String getGroup() {
return group;
}
}
}
private void fetchSharedContainers(final Command callback) {
- String path = "?format=json&shared=";
+ String path = "?format=json&shared=&public=";
GetRequest<AccountResource> getAccount = new GetRequest<AccountResource>(AccountResource.class, app.getApiPath(), app.getUsername(), path) {
@Override
public void onSuccess(final AccountResource _result) {
if (iter.hasNext()) {
final Folder f = iter.next();
- String path = "/" + f.getContainer() + "?format=json&shared=&delimiter=/&prefix=" + URL.encodeQueryString(f.getPrefix());
+ String path = "/" + f.getContainer() + "?format=json&shared=&public=&delimiter=/&prefix=" + URL.encodeQueryString(f.getPrefix());
GetRequest<Folder> getFolder = new GetRequest<Folder>(Folder.class, app.getApiPath(), f.getOwner(), path, f) {
@Override
public void onSuccess(Folder _result) {
}
public void fetchFolder(final Folder f, final boolean showfiles, final Command callback) {
- String path = "/" + f.getContainer() + "?format=json&shared=" + URL.encodeQueryString(f.getPrefix());
+ String path = "/" + f.getContainer() + "?format=json&shared=&public=" + URL.encodeQueryString(f.getPrefix());
GetRequest<Folder> getFolder = new GetRequest<Folder>(Folder.class, app.getApiPath(), f.getOwner(), path, f) {
@Override
public void onSuccess(final Folder _result) {
import com.google.gwt.user.cellview.client.CellTree;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.TreeNode;
+import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Tree;
return model.getSelection();
}
- public void updateFolder(Folder folder, boolean showfiles) {
- model.updateFolder(folder, showfiles);
+ public void updateFolder(Folder folder, boolean showfiles, Command callback) {
+ model.updateFolder(folder, showfiles, callback);
}
}
dataProviderMap.put(f, new ListDataProvider<Folder>());
}
final ListDataProvider<Folder> dataProvider = dataProviderMap.get(f);
- fetchFolder(f, dataProvider, false);
+ fetchFolder(f, dataProvider, false, null);
return new DefaultNodeInfo<Folder>(dataProvider, folderCell, selectionModel, null);
}
}
return selectionModel.getSelectedObject();
}
- public void updateFolder(Folder folder, boolean showfiles) {
+ public void updateFolder(Folder folder, boolean showfiles, Command callback) {
if (dataProviderMap.get(folder) == null) {
dataProviderMap.put(folder, new ListDataProvider<Folder>());
}
final ListDataProvider<Folder> dataProvider = dataProviderMap.get(folder);
- fetchFolder(folder, dataProvider, showfiles);
+ fetchFolder(folder, dataProvider, showfiles, callback);
}
- public void fetchFolder(final Folder f, final ListDataProvider<Folder> dataProvider, final boolean showfiles) {
+ public void fetchFolder(final Folder f, final ListDataProvider<Folder> dataProvider, final boolean showfiles, final Command callback) {
String path = "/" + f.getContainer() + "?format=json&delimiter=/&prefix=" + URL.encodeQueryString(f.getPrefix());
GetRequest<Folder> getFolder = new GetRequest<Folder>(Folder.class, app.getApiPath(), f.getOwner(), path, f) {
@Override
dataProvider.getList().clear();
dataProvider.getList().addAll(_result.getSubfolders());
app.getOtherSharedTreeView().updateChildren(f);
+ if (callback != null)
+ callback.execute();
}
});
}
try {
if (response.getStatusCode() == HTTP_OK || (okcode !=-1 && response.getStatusCode() == okcode))
onSuccess(deserialize(response));
- else if (response.getStatusCode() == Response.SC_UNAUTHORIZED)
+ else if (response.getStatusCode() == Response.SC_UNAUTHORIZED) {
+ log(request, response);
onUnauthorized(response);
+ }
else {
String statusText = "";
String text = "";
}
}
+ private native void log(Request req, Response resp)/*-{
+ if ($wnd.console && $wnd.console.log) {
+ $wnd.console.log(req.@com.google.gwt.http.client.Request::toString()());
+ $wnd.console.log(resp.@com.google.gwt.http.client.Response::toString()());
+ $wnd.console.log(resp.@com.google.gwt.http.client.Response::getStatusCode()());
+ $wnd.console.log(resp.@com.google.gwt.http.client.Response::getStatusText()());
+ $wnd.console.log(resp.@com.google.gwt.http.client.Response::getStatusCode()());
+ $wnd.console.log(resp.@com.google.gwt.http.client.Response::getText()());
+ $wnd.console.log(resp.@com.google.gwt.http.client.Response::getHeadersAsString()());
+ }
+ }-*/;
+
public abstract void onSuccess(T result);
public abstract T deserialize(Response response);
<script>
var otherProperties = {
loginUrl: "/im/login?next=",
- feedbackUrl: "/im/feedback",
- authCookie: "_pithos2_a"
+ feedbackUrl: "/feedback",
+ authCookie: "_pithos2_a",
+ version: ""
}
</script>
</head>
padding-left: 4;
}
-.pithos-statistics {
- color: black;
- padding-top: 10px;
- padding-bottom: 10px;
-}
-
-.pithos-statistics .gwt-HTML {
- font-size: 85%;
-}
-
.pithos-statisticsSeparator {
background: url(images/separator.png) no-repeat;
width: 100%;
.pithos-uploadButton-loading {
background: url(images/ajax-loader.gif) no-repeat;
- background-position: 110px 0px;
+ background-position: 100px 0px;
background-color: #ff7f2a;
}
background-color: #0A0;\r
}\r
\r
+.plupload_start {\r
+ display: none;\r
+}\r
+\r
.plupload_wrapper {\r
font-family: Verdana, 'PT Sans', sans-serif;\r
font-size: 100%;\r