From 9326b8412347501072aec82b18e5c1db91f0e1c9 Mon Sep 17 00:00:00 2001 From: Christos Stathis Date: Fri, 27 Jan 2012 13:17:47 +0200 Subject: [PATCH] FilePropertiesDialog is broken into three dialogs --- .../web/client/AbstractPropertiesDialog.java | 10 +- .../grnet/pithos/web/client/FileContextMenu.java | 7 +- .../pithos/web/client/FilePermissionsDialog.java | 322 ++++++++++++++++++++ .../pithos/web/client/FilePropertiesDialog.java | 234 +------------- .../pithos/web/client/FileVersionsDialog.java | 210 +++++++++++++ .../pithos/web/client/FilesPropertiesDialog.java | 8 +- .../pithos/web/client/FolderPropertiesDialog.java | 2 +- .../grnet/pithos/web/client/PermissionsList.java | 6 +- src/gr/grnet/pithos/web/client/Pithos.java | 2 +- src/gr/grnet/pithos/web/client/ToolsMenu.java | 14 +- src/gr/grnet/pithos/web/client/TopPanel.java | 2 +- src/gr/grnet/pithos/web/client/VersionsList.java | 6 +- .../web/client/commands/PropertiesCommand.java | 28 +- 13 files changed, 592 insertions(+), 259 deletions(-) create mode 100644 src/gr/grnet/pithos/web/client/FilePermissionsDialog.java create mode 100644 src/gr/grnet/pithos/web/client/FileVersionsDialog.java diff --git a/src/gr/grnet/pithos/web/client/AbstractPropertiesDialog.java b/src/gr/grnet/pithos/web/client/AbstractPropertiesDialog.java index 4920b56..150e92e 100644 --- a/src/gr/grnet/pithos/web/client/AbstractPropertiesDialog.java +++ b/src/gr/grnet/pithos/web/client/AbstractPropertiesDialog.java @@ -41,6 +41,7 @@ import com.google.gwt.user.client.ui.DialogBox; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.TabPanel; import com.google.gwt.user.client.ui.TextBox; +import com.google.gwt.user.client.ui.VerticalPanel; /** * Abstract class, parent of all 'File properties' dialog boxes. @@ -50,7 +51,7 @@ public abstract class AbstractPropertiesDialog extends DialogBox { protected static final String MULTIPLE_VALUES_TEXT = "(Multiple values)"; - protected TabPanel inner = null; + protected VerticalPanel inner = null; protected Pithos app; @@ -91,13 +92,6 @@ public abstract class AbstractPropertiesDialog extends DialogBox { } } - - - public void selectTab(int _tab) { - inner.selectTab(_tab); - } - - /** * Enables IE selection prevention and hides the dialog * (we disable the prevention on creation of the dialog) diff --git a/src/gr/grnet/pithos/web/client/FileContextMenu.java b/src/gr/grnet/pithos/web/client/FileContextMenu.java index ef157b4..33702a3 100644 --- a/src/gr/grnet/pithos/web/client/FileContextMenu.java +++ b/src/gr/grnet/pithos/web/client/FileContextMenu.java @@ -237,8 +237,11 @@ public class FileContextMenu extends PopupPanel { } if (selectedFolder != null && !selectedFolder.isInTrash()) { - if (isFolderTreeSelected && selectedFiles.size() == 1) - contextMenu.addItem(new MenuItem("" + AbstractImagePrototype.create(newImages.viewText()).getHTML() + " Properties", true, new PropertiesCommand(app, this, selectedFiles, 0))); + if (isFolderTreeSelected && selectedFiles.size() == 1) { + contextMenu.addItem(new MenuItem("" + AbstractImagePrototype.create(newImages.viewText()).getHTML() + " Properties", true, new PropertiesCommand(app, this, selectedFiles, PropertiesCommand.PROPERTIES))); + contextMenu.addItem(new MenuItem("" + AbstractImagePrototype.create(newImages.sharing()).getHTML() + " Sharing", true, new PropertiesCommand(app, this, selectedFiles, PropertiesCommand.PERMISSIONS))); + contextMenu.addItem(new MenuItem("" + AbstractImagePrototype.create(newImages.versions()).getHTML() + " Versions", true, new PropertiesCommand(app, this, selectedFiles, PropertiesCommand.VERSIONS))); + } } contextMenu.addItem(new MenuItem("" + AbstractImagePrototype.create(newImages.download()).getHTML() + " Download", true, new Command() { diff --git a/src/gr/grnet/pithos/web/client/FilePermissionsDialog.java b/src/gr/grnet/pithos/web/client/FilePermissionsDialog.java new file mode 100644 index 0000000..8af002d --- /dev/null +++ b/src/gr/grnet/pithos/web/client/FilePermissionsDialog.java @@ -0,0 +1,322 @@ +/* + * Copyright 2011 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 gr.grnet.pithos.web.client.foldertree.File; +import gr.grnet.pithos.web.client.foldertree.Resource; +import gr.grnet.pithos.web.client.rest.PostRequest; + +import java.util.Map; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.core.client.Scheduler; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.http.client.Response; +import com.google.gwt.http.client.URL; +import com.google.gwt.resources.client.ImageResource; +import com.google.gwt.user.client.Command; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.Anchor; +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.FocusPanel; +import com.google.gwt.user.client.ui.HasHorizontalAlignment; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.TextBox; +import com.google.gwt.user.client.ui.VerticalPanel; + +/** + * The 'File properties' dialog box implementation. + * + */ +public class FilePermissionsDialog extends AbstractPropertiesDialog { + + protected PermissionsList permList; + + protected CheckBox readForAll; + + /** + * An image bundle for this widgets images. + */ + public interface Images extends MessagePanel.Images { + + @Source("gr/grnet/pithos/resources/edit_user.png") + ImageResource permUser(); + + @Source("gr/grnet/pithos/resources/groups22.png") + ImageResource permGroup(); + + @Source("gr/grnet/pithos/resources/editdelete.png") + ImageResource delete(); + } + + final File file; + + Images images = GWT.create(Images.class); + + /** + * The widget's constructor. + */ + public FilePermissionsDialog(Pithos _app, File _file) { + super(_app); + file = _file; + + Anchor close = new Anchor(); + close.addStyleName("close"); + close.addClickHandler(new ClickHandler() { + + @Override + public void onClick(@SuppressWarnings("unused") ClickEvent event) { + hide(); + } + }); + // Set the dialog's caption. + setText("File permissions"); + setAnimationEnabled(true); + setGlassEnabled(true); + setStyleName("pithos-DialogBox"); + + // Outer contains inner and buttons. + final VerticalPanel outer = new VerticalPanel(); + outer.add(close); + final FocusPanel focusPanel = new FocusPanel(outer); + // Inner contains generalPanel and permPanel. + inner = new VerticalPanel(); + inner.addStyleName("inner"); +// inner.getDeckPanel().addStyleName("pithos-TabPanelBottom"); + + inner.add(createSharingPanel()); + + outer.add(inner); + + // Create the 'OK' button, along with a listener that hides the dialog + // when the button is clicked. + final Button ok = new Button("OK", new ClickHandler() { + @Override + public void onClick(@SuppressWarnings("unused") ClickEvent event) { + accept(); + closeDialog(); + } + }); + ok.addStyleName("button"); + + outer.add(ok); + outer.setCellHorizontalAlignment(inner, HasHorizontalAlignment.ALIGN_CENTER); + + focusPanel.setFocus(true); + setWidget(outer); + } + + private VerticalPanel createSharingPanel() { + VerticalPanel permPanel = new VerticalPanel(); + + permList = new PermissionsList(images, file.getPermissions(), file.getOwner(), file.getInheritedPermissionsFrom() != null); + permPanel.add(permList); + + if (file.getInheritedPermissionsFrom() == null) { + HorizontalPanel permButtons = new HorizontalPanel(); + Button add = new Button("Add Group", new ClickHandler() { + @Override + public void onClick(@SuppressWarnings("unused") ClickEvent event) { + PermissionsAddDialog dlg = new PermissionsAddDialog(app, app.getAccount().getGroups(), permList, false); + dlg.center(); + permList.updatePermissionTable(); + } + }); + add.addStyleName("button"); + permButtons.add(add); + permButtons.setCellHorizontalAlignment(add, HasHorizontalAlignment.ALIGN_CENTER); + + final Button addUser = new Button("Add User", new ClickHandler() { + @Override + public void onClick(@SuppressWarnings("unused") ClickEvent event) { + PermissionsAddDialog dlg = new PermissionsAddDialog(app, app.getAccount().getGroups(), permList, true); + dlg.center(); + permList.updatePermissionTable(); + } + }); + addUser.addStyleName("button"); + permButtons.add(addUser); + permButtons.setCellHorizontalAlignment(addUser, HasHorizontalAlignment.ALIGN_CENTER); + + permButtons.setSpacing(8); + permButtons.addStyleName("pithos-TabPanelBottom"); + permPanel.add(permButtons); + } + + final Label readForAllNote = new Label("When this option is enabled, the file will be readable" + + " by everyone. By checking this option, you are certifying that you have the right to " + + "distribute this file and that it does not violate the Terms of Use.", true); + readForAllNote.setVisible(false); + readForAllNote.setStylePrimaryName("pithos-readForAllNote"); + + readForAll = new CheckBox(); + readForAll.setValue(file.isPublished()); + readForAll.addClickHandler(new ClickHandler() { + @Override + public void onClick(@SuppressWarnings("unused") ClickEvent event) { + readForAllNote.setVisible(readForAll.getValue()); + } + }); + + // Only show the read for all permission if the user is the owner. + if (file.getOwner().equals(app.getUsername())) { + final HorizontalPanel permForAll = new HorizontalPanel(); + permForAll.add(new Label("Public")); + permForAll.add(readForAll); + permForAll.setSpacing(8); + permForAll.addStyleName("pithos-TabPanelBottom"); + permForAll.add(readForAllNote); + permPanel.add(permForAll); + } + + if (file.isPublished()) { + final HorizontalPanel pathPanel = new HorizontalPanel(); + pathPanel.setWidth("100%"); + pathPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT); + pathPanel.add(new Label("Link")); + pathPanel.setSpacing(8); + pathPanel.addStyleName("pithos-TabPanelBottom"); + + TextBox path = new TextBox(); + path.setWidth("100%"); + path.addClickHandler(new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + Pithos.enableIESelection(); + ((TextBox) event.getSource()).selectAll(); + Pithos.preventIESelection(); + } + }); + path.setText(Window.Location.getHost() + file.getPublicUri()); + path.setTitle("Use this link for sharing the file via e-mail, IM, etc. (crtl-C/cmd-C to copy to system clipboard)"); + path.setWidth("100%"); + path.setReadOnly(true); + pathPanel.add(path); + permPanel.add(pathPanel); + } + + return permPanel; + } + + /** + * Accepts any change and updates the file + * + */ + @Override + protected void accept() { + final Map perms = (permList.hasChanges() ? permList.getPermissions() : null); + + //only update the read for all perm if the user is the owner + Boolean published = null; + if (readForAll.getValue() != file.isPublished()) + if (file.getOwner().equals(app.getUsername())) + published = readForAll.getValue(); + final Boolean finalPublished = published; + + updateMetaData(app.getApiPath(), app.getUsername(), file.getUri() + "?update=", finalPublished, perms); + } + + protected void updateMetaData(String api, String owner, String path, final Boolean published, final Map newPermissions) { + if (published != null || newPermissions != null) { + PostRequest updateFile = new PostRequest(api, owner, path) { + @Override + public void onSuccess(@SuppressWarnings("unused") Resource result) { + app.updateFolder(file.getParent(), true, new Command() { + + @Override + public void execute() { + app.updateMySharedRoot(); + } + }); + } + + @Override + public void onError(Throwable t) { + GWT.log("", t); + app.setError(t); + app.displayError("System error modifying file:" + t.getMessage()); + } + + @Override + protected void onUnauthorized(@SuppressWarnings("unused") Response response) { + app.sessionExpired(); + } + }; + updateFile.setHeader("X-Auth-Token", app.getToken()); + + if (published != null) + updateFile.setHeader("X-Object-Public", published.toString()); + if (newPermissions != null) { + String readPermHeader = "read="; + String writePermHeader = "write="; + for (String u : newPermissions.keySet()) { + Boolean[] p = newPermissions.get(u); + if (p[0] != null && p[0]) + readPermHeader += u + ","; + if (p[1] != null && p[1]) + writePermHeader += u + ","; + } + if (readPermHeader.endsWith("=")) + readPermHeader = ""; + else if (readPermHeader.endsWith(",")) + readPermHeader = readPermHeader.substring(0, readPermHeader.length() - 1); + if (writePermHeader.endsWith("=")) + writePermHeader = ""; + else if (writePermHeader.endsWith(",")) + writePermHeader = writePermHeader.substring(0, writePermHeader.length() - 1); + String permHeader = readPermHeader + ((readPermHeader.length() > 0 && writePermHeader.length() > 0) ? ";" : "") + writePermHeader; + if (permHeader.length() == 0) + permHeader="~"; + else + permHeader = URL.encodePathSegment(permHeader); + updateFile.setHeader("X-Object-Sharing", permHeader); + } + Scheduler.get().scheduleDeferred(updateFile); + } + else + app.updateFolder(file.getParent(), true, new Command() { + + @Override + public void execute() { + if (file.isShared()) + app.updateMySharedRoot(); + } + }); + } +} diff --git a/src/gr/grnet/pithos/web/client/FilePropertiesDialog.java b/src/gr/grnet/pithos/web/client/FilePropertiesDialog.java index 89e1f67..6943468 100644 --- a/src/gr/grnet/pithos/web/client/FilePropertiesDialog.java +++ b/src/gr/grnet/pithos/web/client/FilePropertiesDialog.java @@ -35,16 +35,11 @@ package gr.grnet.pithos.web.client; import gr.grnet.pithos.web.client.foldertree.File; -import gr.grnet.pithos.web.client.foldertree.FileVersions; import gr.grnet.pithos.web.client.foldertree.Resource; -import gr.grnet.pithos.web.client.foldertree.Version; -import gr.grnet.pithos.web.client.rest.GetRequest; import gr.grnet.pithos.web.client.rest.PostRequest; import gr.grnet.pithos.web.client.rest.PutRequest; -import gr.grnet.pithos.web.client.rest.RestException; import java.util.HashMap; -import java.util.List; import java.util.Map; import com.google.gwt.core.client.GWT; @@ -54,12 +49,9 @@ import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.http.client.Response; import com.google.gwt.http.client.URL; import com.google.gwt.i18n.client.DateTimeFormat; -import com.google.gwt.resources.client.ImageResource; import com.google.gwt.user.client.Command; -import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Anchor; 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.FlexTable; import com.google.gwt.user.client.ui.FocusPanel; @@ -76,31 +68,6 @@ import com.google.gwt.user.client.ui.VerticalPanel; */ public class FilePropertiesDialog extends AbstractPropertiesDialog { - protected PermissionsList permList; - - protected CheckBox readForAll; - - /** - * An image bundle for this widgets images. - */ - public interface Images extends MessagePanel.Images { - - @Source("gr/grnet/pithos/resources/edit_user.png") - ImageResource permUser(); - - @Source("gr/grnet/pithos/resources/groups22.png") - ImageResource permGroup(); - - @Source("gr/grnet/pithos/resources/editdelete.png") - ImageResource delete(); - - @Source("gr/grnet/pithos/resources/db_update.png") - ImageResource restore(); - - @Source("gr/grnet/pithos/resources/folder_inbox.png") - ImageResource download(); - } - /** * The widget that holds the name of the file. */ @@ -108,8 +75,6 @@ public class FilePropertiesDialog extends AbstractPropertiesDialog { final File file; - Images images = GWT.create(Images.class); - FlexTable metaTable; /** * The widget's constructor. @@ -136,21 +101,13 @@ public class FilePropertiesDialog extends AbstractPropertiesDialog { // Outer contains inner and buttons. final VerticalPanel outer = new VerticalPanel(); outer.add(close); - final FocusPanel focusPanel = new FocusPanel(outer); // Inner contains generalPanel and permPanel. - inner = new DecoratedTabPanel(); - inner.setAnimationEnabled(true); + inner = new VerticalPanel(); inner.addStyleName("inner"); - inner.getDeckPanel().addStyleName("pithos-TabPanelBottom"); - +// inner.getDeckPanel().addStyleName("pithos-TabPanelBottom"); - inner.add(createGeneralPanel(), "General"); - inner.add(createSharingPanel(), "Sharing"); - - fetchVersions(); - - inner.selectTab(0); + inner.add(createGeneralPanel()); outer.add(inner); @@ -168,39 +125,9 @@ public class FilePropertiesDialog extends AbstractPropertiesDialog { outer.add(ok); outer.setCellHorizontalAlignment(inner, HasHorizontalAlignment.ALIGN_CENTER); - focusPanel.setFocus(true); setWidget(outer); } - protected void fetchVersions() { - String path = file.getUri() + "?format=json&version=list"; - GetRequest getVersions = new GetRequest(FileVersions.class, app.getApiPath(), file.getOwner(), path) { - - @Override - public void onSuccess(FileVersions _result) { - inner.add(createVersionPanel(_result.getVersions()), "Versions"); - } - - @Override - public void onError(Throwable t) { - GWT.log("", t); - app.setError(t); - if (t instanceof RestException) { - app.displayError("Unable to fetch versions: " + ((RestException) t).getHttpStatusText()); - } - else - app.displayError("System error unable to fetch versions: "+t.getMessage()); - } - - @Override - protected void onUnauthorized(@SuppressWarnings("unused") Response response) { - app.sessionExpired(); - } - }; - getVersions.setHeader("X-Auth-Token", app.getToken()); - Scheduler.get().scheduleDeferred(getVersions); - } - private VerticalPanel createGeneralPanel() { final VerticalPanel generalPanel = new VerticalPanel(); final FlexTable generalTable = new FlexTable(); @@ -298,105 +225,6 @@ public class FilePropertiesDialog extends AbstractPropertiesDialog { table.setWidget(row, 2, delete); } - private VerticalPanel createSharingPanel() { - VerticalPanel permPanel = new VerticalPanel(); - - permList = new PermissionsList(images, file.getPermissions(), file.getOwner(), file.getInheritedPermissionsFrom() != null); - permPanel.add(permList); - - if (file.getInheritedPermissionsFrom() == null) { - HorizontalPanel permButtons = new HorizontalPanel(); - Button add = new Button("Add Group", new ClickHandler() { - @Override - public void onClick(@SuppressWarnings("unused") ClickEvent event) { - PermissionsAddDialog dlg = new PermissionsAddDialog(app, app.getAccount().getGroups(), permList, false); - dlg.center(); - permList.updatePermissionTable(); - } - }); - add.addStyleName("button"); - permButtons.add(add); - permButtons.setCellHorizontalAlignment(add, HasHorizontalAlignment.ALIGN_CENTER); - - final Button addUser = new Button("Add User", new ClickHandler() { - @Override - public void onClick(@SuppressWarnings("unused") ClickEvent event) { - PermissionsAddDialog dlg = new PermissionsAddDialog(app, app.getAccount().getGroups(), permList, true); - dlg.center(); - permList.updatePermissionTable(); - } - }); - addUser.addStyleName("button"); - permButtons.add(addUser); - permButtons.setCellHorizontalAlignment(addUser, HasHorizontalAlignment.ALIGN_CENTER); - - permButtons.setSpacing(8); - permButtons.addStyleName("pithos-TabPanelBottom"); - permPanel.add(permButtons); - } - - final Label readForAllNote = new Label("When this option is enabled, the file will be readable" + - " by everyone. By checking this option, you are certifying that you have the right to " + - "distribute this file and that it does not violate the Terms of Use.", true); - readForAllNote.setVisible(false); - readForAllNote.setStylePrimaryName("pithos-readForAllNote"); - - readForAll = new CheckBox(); - readForAll.setValue(file.isPublished()); - readForAll.addClickHandler(new ClickHandler() { - @Override - public void onClick(@SuppressWarnings("unused") ClickEvent event) { - readForAllNote.setVisible(readForAll.getValue()); - } - }); - - // Only show the read for all permission if the user is the owner. - if (file.getOwner().equals(app.getUsername())) { - final HorizontalPanel permForAll = new HorizontalPanel(); - permForAll.add(new Label("Public")); - permForAll.add(readForAll); - permForAll.setSpacing(8); - permForAll.addStyleName("pithos-TabPanelBottom"); - permForAll.add(readForAllNote); - permPanel.add(permForAll); - } - - if (file.isPublished()) { - final HorizontalPanel pathPanel = new HorizontalPanel(); - pathPanel.setWidth("100%"); - pathPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT); - pathPanel.add(new Label("Link")); - pathPanel.setSpacing(8); - pathPanel.addStyleName("pithos-TabPanelBottom"); - - TextBox path = new TextBox(); - path.setWidth("100%"); - path.addClickHandler(new ClickHandler() { - @Override - public void onClick(ClickEvent event) { - Pithos.enableIESelection(); - ((TextBox) event.getSource()).selectAll(); - Pithos.preventIESelection(); - } - }); - path.setText(Window.Location.getHost() + file.getPublicUri()); - path.setTitle("Use this link for sharing the file via e-mail, IM, etc. (crtl-C/cmd-C to copy to system clipboard)"); - path.setWidth("100%"); - path.setReadOnly(true); - pathPanel.add(path); - permPanel.add(pathPanel); - } - - return permPanel; - } - - VerticalPanel createVersionPanel(List versions) { - VerticalPanel versionPanel = new VerticalPanel(); - VersionsList verList = new VersionsList(app, this, images, file, versions); - versionPanel.add(verList); - return versionPanel; - } - /** * Accepts any change and updates the file * @@ -405,19 +233,10 @@ public class FilePropertiesDialog extends AbstractPropertiesDialog { protected void accept() { String newFilename = null; - final Map perms = (permList.hasChanges() ? permList.getPermissions() : null); - if (!name.getText().trim().equals(file.getName())) { newFilename = name.getText().trim(); } - //only update the read for all perm if the user is the owner - Boolean published = null; - if (readForAll.getValue() != file.isPublished()) - if (file.getOwner().equals(app.getUsername())) - published = readForAll.getValue(); - final Boolean finalPublished = published; - final Map newMeta = new HashMap(); for (int row = 1; row < metaTable.getRowCount(); row++) { String key = ((TextBox) metaTable.getWidget(row, 0)).getText().trim(); @@ -431,7 +250,7 @@ public class FilePropertiesDialog extends AbstractPropertiesDialog { PutRequest updateFile = new PutRequest(app.getApiPath(), app.getUsername(), path) { @Override public void onSuccess(@SuppressWarnings("unused") Resource result) { - updateMetaData(app.getApiPath(), file.getOwner(), path + "?update=", newMeta, finalPublished, perms); + updateMetaData(app.getApiPath(), file.getOwner(), path + "?update=", newMeta); } @Override @@ -480,11 +299,11 @@ public class FilePropertiesDialog extends AbstractPropertiesDialog { Scheduler.get().scheduleDeferred(updateFile); } else - updateMetaData(app.getApiPath(), app.getUsername(), file.getUri() + "?update=", newMeta, finalPublished, perms); + updateMetaData(app.getApiPath(), app.getUsername(), file.getUri() + "?update=", newMeta); } - protected void updateMetaData(String api, String owner, String path, Map newMeta, final Boolean published, final Map newPermissions) { - if (newMeta != null || published != null || newPermissions != null) { + protected void updateMetaData(String api, String owner, String path, Map newMeta) { + if (newMeta != null) { PostRequest updateFile = new PostRequest(api, owner, path) { @Override public void onSuccess(@SuppressWarnings("unused") Resource result) { @@ -511,42 +330,13 @@ public class FilePropertiesDialog extends AbstractPropertiesDialog { }; updateFile.setHeader("X-Auth-Token", app.getToken()); - if (newMeta != null) { - for (String t : file.getMeta().keySet()) { - updateFile.setHeader("X-Object-Meta-" + URL.encodePathSegment(t.trim()), "~"); - } - - for (String key : newMeta.keySet()) - updateFile.setHeader("X-Object-Meta-" + URL.encodePathSegment(key.trim()), URL.encodePathSegment(newMeta.get(key))); + for (String t : file.getMeta().keySet()) { + updateFile.setHeader("X-Object-Meta-" + URL.encodePathSegment(t.trim()), "~"); } - if (published != null) - updateFile.setHeader("X-Object-Public", published.toString()); - if (newPermissions != null) { - String readPermHeader = "read="; - String writePermHeader = "write="; - for (String u : newPermissions.keySet()) { - Boolean[] p = newPermissions.get(u); - if (p[0] != null && p[0]) - readPermHeader += u + ","; - if (p[1] != null && p[1]) - writePermHeader += u + ","; - } - if (readPermHeader.endsWith("=")) - readPermHeader = ""; - else if (readPermHeader.endsWith(",")) - readPermHeader = readPermHeader.substring(0, readPermHeader.length() - 1); - if (writePermHeader.endsWith("=")) - writePermHeader = ""; - else if (writePermHeader.endsWith(",")) - writePermHeader = writePermHeader.substring(0, writePermHeader.length() - 1); - String permHeader = readPermHeader + ((readPermHeader.length() > 0 && writePermHeader.length() > 0) ? ";" : "") + writePermHeader; - if (permHeader.length() == 0) - permHeader="~"; - else - permHeader = URL.encodePathSegment(permHeader); - updateFile.setHeader("X-Object-Sharing", permHeader); - } + for (String key : newMeta.keySet()) + updateFile.setHeader("X-Object-Meta-" + URL.encodePathSegment(key.trim()), URL.encodePathSegment(newMeta.get(key))); + Scheduler.get().scheduleDeferred(updateFile); } else diff --git a/src/gr/grnet/pithos/web/client/FileVersionsDialog.java b/src/gr/grnet/pithos/web/client/FileVersionsDialog.java new file mode 100644 index 0000000..e3bc655 --- /dev/null +++ b/src/gr/grnet/pithos/web/client/FileVersionsDialog.java @@ -0,0 +1,210 @@ +/* + * Copyright 2011 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 gr.grnet.pithos.web.client.foldertree.File; +import gr.grnet.pithos.web.client.foldertree.FileVersions; +import gr.grnet.pithos.web.client.foldertree.Resource; +import gr.grnet.pithos.web.client.foldertree.Version; +import gr.grnet.pithos.web.client.rest.GetRequest; +import gr.grnet.pithos.web.client.rest.PostRequest; +import gr.grnet.pithos.web.client.rest.PutRequest; +import gr.grnet.pithos.web.client.rest.RestException; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.core.client.Scheduler; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.http.client.Response; +import com.google.gwt.http.client.URL; +import com.google.gwt.resources.client.ImageResource; +import com.google.gwt.user.client.Command; +import com.google.gwt.user.client.ui.Anchor; +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.FocusPanel; +import com.google.gwt.user.client.ui.HasHorizontalAlignment; +import com.google.gwt.user.client.ui.TextBox; +import com.google.gwt.user.client.ui.VerticalPanel; + +/** + * The 'File properties' dialog box implementation. + * + */ +public class FileVersionsDialog extends AbstractPropertiesDialog { + + protected PermissionsList permList; + + protected CheckBox readForAll; + + /** + * An image bundle for this widgets images. + */ + public interface Images extends MessagePanel.Images { + + @Source("gr/grnet/pithos/resources/edit_user.png") + ImageResource permUser(); + + @Source("gr/grnet/pithos/resources/groups22.png") + ImageResource permGroup(); + + @Source("gr/grnet/pithos/resources/editdelete.png") + ImageResource delete(); + + @Source("gr/grnet/pithos/resources/db_update.png") + ImageResource restore(); + + @Source("gr/grnet/pithos/resources/folder_inbox.png") + ImageResource download(); + } + + final File file; + + Images images = GWT.create(Images.class); + + /** + * The widget's constructor. + */ + public FileVersionsDialog(Pithos _app, File _file) { + super(_app); + file = _file; + + Anchor close = new Anchor(); + close.addStyleName("close"); + close.addClickHandler(new ClickHandler() { + + @Override + public void onClick(@SuppressWarnings("unused") ClickEvent event) { + hide(); + } + }); + // Set the dialog's caption. + setText("File versions"); + setAnimationEnabled(true); + setGlassEnabled(true); + setStyleName("pithos-DialogBox"); + + // Outer contains inner and buttons. + final VerticalPanel outer = new VerticalPanel(); + outer.add(close); + final FocusPanel focusPanel = new FocusPanel(outer); + // Inner contains generalPanel and permPanel. + inner = new VerticalPanel(); + inner.addStyleName("inner"); +// inner.getDeckPanel().addStyleName("pithos-TabPanelBottom"); + + fetchVersions(); + + outer.add(inner); + + // Create the 'OK' button, along with a listener that hides the dialog + // when the button is clicked. + final Button ok = new Button("OK", new ClickHandler() { + @Override + public void onClick(@SuppressWarnings("unused") ClickEvent event) { + accept(); + closeDialog(); + } + }); + ok.addStyleName("button"); + + outer.add(ok); + outer.setCellHorizontalAlignment(inner, HasHorizontalAlignment.ALIGN_CENTER); + + focusPanel.setFocus(true); + setWidget(outer); + } + + protected void fetchVersions() { + String path = file.getUri() + "?format=json&version=list"; + GetRequest getVersions = new GetRequest(FileVersions.class, app.getApiPath(), file.getOwner(), path) { + + @Override + public void onSuccess(FileVersions _result) { + inner.add(createVersionPanel(_result.getVersions())); + } + + @Override + public void onError(Throwable t) { + GWT.log("", t); + app.setError(t); + if (t instanceof RestException) { + app.displayError("Unable to fetch versions: " + ((RestException) t).getHttpStatusText()); + } + else + app.displayError("System error unable to fetch versions: "+t.getMessage()); + } + + @Override + protected void onUnauthorized(@SuppressWarnings("unused") Response response) { + app.sessionExpired(); + } + }; + getVersions.setHeader("X-Auth-Token", app.getToken()); + Scheduler.get().scheduleDeferred(getVersions); + } + + VerticalPanel createVersionPanel(List versions) { + VerticalPanel versionPanel = new VerticalPanel(); + VersionsList verList = new VersionsList(app, this, images, file, versions); + versionPanel.add(verList); + return versionPanel; + } + + /** + * Accepts any change and updates the file + * + */ + @Override + protected void accept() { + updateMetaData(app.getApiPath(), app.getUsername(), file.getUri() + "?update="); + } + + protected void updateMetaData(String api, String owner, String path) { + app.updateFolder(file.getParent(), true, new Command() { + + @Override + public void execute() { + if (file.isShared()) + app.updateMySharedRoot(); + } + }); + } +} diff --git a/src/gr/grnet/pithos/web/client/FilesPropertiesDialog.java b/src/gr/grnet/pithos/web/client/FilesPropertiesDialog.java index 536d540..db99434 100644 --- a/src/gr/grnet/pithos/web/client/FilesPropertiesDialog.java +++ b/src/gr/grnet/pithos/web/client/FilesPropertiesDialog.java @@ -57,8 +57,6 @@ import com.google.gwt.user.client.ui.VerticalPanel; */ public class FilesPropertiesDialog extends AbstractPropertiesDialog { -// private final TristateCheckBox versionedCheck; - private final List files; /** @@ -78,12 +76,10 @@ public class FilesPropertiesDialog extends AbstractPropertiesDialog { final VerticalPanel outer = new VerticalPanel(); final FocusPanel focusPanel = new FocusPanel(outer); // Inner contains generalPanel and permPanel. - inner = new DecoratedTabPanel(); - inner.setAnimationEnabled(true); + inner = new VerticalPanel(); - inner.add(createGeneralPanel(), "General"); + inner.add(createGeneralPanel()); - inner.selectTab(0); outer.add(inner); final HorizontalPanel buttons = new HorizontalPanel(); diff --git a/src/gr/grnet/pithos/web/client/FolderPropertiesDialog.java b/src/gr/grnet/pithos/web/client/FolderPropertiesDialog.java index 041609d..c97fbd1 100644 --- a/src/gr/grnet/pithos/web/client/FolderPropertiesDialog.java +++ b/src/gr/grnet/pithos/web/client/FolderPropertiesDialog.java @@ -171,7 +171,7 @@ public class FolderPropertiesDialog extends DialogBox { inner.add(generalPanel, "General"); VerticalPanel permPanel = new VerticalPanel(); - FilePropertiesDialog.Images images = GWT.create(FilePropertiesDialog.Images.class); + FilePermissionsDialog.Images images = GWT.create(FilePermissionsDialog.Images.class); boolean permsReadonly = folder.getInheritedPermissionsFrom() != null || folder.existChildrenPermissions(); permList = new PermissionsList(images, folder.getPermissions(), folder.getOwner(), permsReadonly); permPanel.add(permList); diff --git a/src/gr/grnet/pithos/web/client/PermissionsList.java b/src/gr/grnet/pithos/web/client/PermissionsList.java index 45ab6c7..3ce05a5 100644 --- a/src/gr/grnet/pithos/web/client/PermissionsList.java +++ b/src/gr/grnet/pithos/web/client/PermissionsList.java @@ -34,15 +34,15 @@ */ package gr.grnet.pithos.web.client; -import com.google.gwt.event.logical.shared.ValueChangeEvent; -import com.google.gwt.event.logical.shared.ValueChangeHandler; -import gr.grnet.pithos.web.client.FilePropertiesDialog.Images; +import gr.grnet.pithos.web.client.FilePermissionsDialog.Images; import java.util.HashMap; import java.util.Map; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.logical.shared.ValueChangeEvent; +import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.user.client.ui.AbstractImagePrototype; import com.google.gwt.user.client.ui.CheckBox; import com.google.gwt.user.client.ui.Composite; diff --git a/src/gr/grnet/pithos/web/client/Pithos.java b/src/gr/grnet/pithos/web/client/Pithos.java index c8e8b47..64358db 100644 --- a/src/gr/grnet/pithos/web/client/Pithos.java +++ b/src/gr/grnet/pithos/web/client/Pithos.java @@ -362,7 +362,7 @@ public class Pithos implements EntryPoint, ResizeHandler { boolean isFolderTreeSelected = selectedTree.equals(getFolderTreeView()); if (!folder.isInTrash() && canWrite && isFolderTreeSelected && !folder.isContainer()) - new PropertiesCommand(Pithos.this, null, folder, 1).execute(); + new PropertiesCommand(Pithos.this, null, folder, PropertiesCommand.PERMISSIONS).execute(); } } }); diff --git a/src/gr/grnet/pithos/web/client/ToolsMenu.java b/src/gr/grnet/pithos/web/client/ToolsMenu.java index 428bd06..6d2076a 100644 --- a/src/gr/grnet/pithos/web/client/ToolsMenu.java +++ b/src/gr/grnet/pithos/web/client/ToolsMenu.java @@ -56,6 +56,8 @@ import gr.grnet.pithos.web.client.grouptree.User; import java.util.List; +import com.google.gwt.resources.client.ImageResource; +import com.google.gwt.resources.client.ClientBundle.Source; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.AbstractImagePrototype; @@ -166,13 +168,13 @@ public class ToolsMenu extends PopupPanel { if (delete != null) contextMenu.addItem(delete); - MenuItem properties = null; - if (files != null && files.size() == 1) - properties = new MenuItem("" + AbstractImagePrototype.create(newImages.viewText()).getHTML() + " File properties", true, new PropertiesCommand(app, this, files, 0)); + if (files != null && files.size() == 1) { + contextMenu.addItem(new MenuItem("" + AbstractImagePrototype.create(newImages.viewText()).getHTML() + " File properties", true, new PropertiesCommand(app, this, files, PropertiesCommand.PROPERTIES))); + contextMenu.addItem(new MenuItem("" + AbstractImagePrototype.create(newImages.group()).getHTML() + " Sharing", true, new PropertiesCommand(app, this, files, PropertiesCommand.PERMISSIONS))); + contextMenu.addItem(new MenuItem("" + AbstractImagePrototype.create(newImages.versions()).getHTML() + " Versions", true, new PropertiesCommand(app, this, files, PropertiesCommand.VERSIONS))); + } else if (!folder.isContainer()) - properties = new MenuItem("" + AbstractImagePrototype.create(newImages.viewText()).getHTML() + " Folder properties", true, new PropertiesCommand(app, this, folder, 0)); - if (properties != null) - contextMenu.addItem(properties); + contextMenu.addItem(new MenuItem("" + AbstractImagePrototype.create(newImages.viewText()).getHTML() + " Folder properties", true, new PropertiesCommand(app, this, folder, 0))); } if (files != null && !files.isEmpty()) { contextMenu.addItem(new MenuItem("" + AbstractImagePrototype.create(newImages.download()).getHTML() + " Download", true, new Command() { diff --git a/src/gr/grnet/pithos/web/client/TopPanel.java b/src/gr/grnet/pithos/web/client/TopPanel.java index bf9290f..3c89d60 100644 --- a/src/gr/grnet/pithos/web/client/TopPanel.java +++ b/src/gr/grnet/pithos/web/client/TopPanel.java @@ -72,7 +72,7 @@ public class TopPanel extends Composite { /** * An image bundle for this widgets images. */ - public interface Images extends FilePropertiesDialog.Images { + public interface Images extends FilePermissionsDialog.Images { @Source("gr/grnet/pithos/resources/pithos2-logo.png") ImageResource pithosLogo(); diff --git a/src/gr/grnet/pithos/web/client/VersionsList.java b/src/gr/grnet/pithos/web/client/VersionsList.java index 17ff860..7f6b6a9 100644 --- a/src/gr/grnet/pithos/web/client/VersionsList.java +++ b/src/gr/grnet/pithos/web/client/VersionsList.java @@ -34,7 +34,7 @@ */ package gr.grnet.pithos.web.client; -import gr.grnet.pithos.web.client.FilePropertiesDialog.Images; +import gr.grnet.pithos.web.client.FileVersionsDialog.Images; import gr.grnet.pithos.web.client.foldertree.File; import gr.grnet.pithos.web.client.foldertree.Resource; import gr.grnet.pithos.web.client.foldertree.Version; @@ -71,9 +71,9 @@ public class VersionsList extends Composite { private FlexTable permTable = new FlexTable(); - FilePropertiesDialog container; + FileVersionsDialog container; - public VersionsList(Pithos _app, FilePropertiesDialog aContainer, final Images theImages, File _file, List theVersions) { + public VersionsList(Pithos _app, FileVersionsDialog aContainer, final Images theImages, File _file, List theVersions) { app = _app; images = theImages; container = aContainer; diff --git a/src/gr/grnet/pithos/web/client/commands/PropertiesCommand.java b/src/gr/grnet/pithos/web/client/commands/PropertiesCommand.java index c42abcc..a24944c 100644 --- a/src/gr/grnet/pithos/web/client/commands/PropertiesCommand.java +++ b/src/gr/grnet/pithos/web/client/commands/PropertiesCommand.java @@ -34,8 +34,9 @@ */ package gr.grnet.pithos.web.client.commands; -import gr.grnet.pithos.web.client.FileContextMenu; +import gr.grnet.pithos.web.client.FilePermissionsDialog; import gr.grnet.pithos.web.client.FilePropertiesDialog; +import gr.grnet.pithos.web.client.FileVersionsDialog; import gr.grnet.pithos.web.client.FilesPropertiesDialog; import gr.grnet.pithos.web.client.FolderPropertiesDialog; import gr.grnet.pithos.web.client.Pithos; @@ -54,6 +55,10 @@ import com.google.gwt.user.client.ui.PopupPanel; */ public class PropertiesCommand implements Command { + public static final int PROPERTIES = 0; + public static final int PERMISSIONS = 1; + public static final int VERSIONS = 2; + private PopupPanel containerPanel; private int tabToShow = 0; @@ -64,7 +69,6 @@ public class PropertiesCommand implements Command { /** * @param _containerPanel - * @param _newImages the images of all the possible delete dialogs * @param _tab the tab to switch to */ public PropertiesCommand(Pithos _app, PopupPanel _containerPanel, Object _resource, int _tab) { @@ -90,13 +94,25 @@ public class PropertiesCommand implements Command { List files = (List) resource; if (files.size() > 1) { FilesPropertiesDialog dlg = new FilesPropertiesDialog(app, files); - dlg.selectTab(tabToShow); dlg.center(); } else { - FilePropertiesDialog dlg = new FilePropertiesDialog(app, files.get(0)); - dlg.selectTab(tabToShow); - dlg.center(); + switch (tabToShow) { + case PROPERTIES: + FilePropertiesDialog dlg = new FilePropertiesDialog(app, files.get(0)); + dlg.center(); + break; + case PERMISSIONS: + FilePermissionsDialog dlg1 = new FilePermissionsDialog(app, files.get(0)); + dlg1.center(); + break; + case VERSIONS: + FileVersionsDialog dlg2 = new FileVersionsDialog(app, files.get(0)); + dlg2.center(); + break; + default: + break; + } } } } -- 1.7.10.4