Revision 9e8e14e4
b/web_client/build.xml | ||
---|---|---|
102 | 102 |
<!--move file="${gwt.www.dir}/${gwt.module}/${gwt.module.class}.html" tofile="${gwt.www.dir}/${gwt.module}/index.html"/--> |
103 | 103 |
</target> |
104 | 104 |
|
105 |
<target name="uploadToVM" depends="gwt-compile"> |
|
106 |
<scp todir="chstath@pithos.dev.grnet.gr:/var/www/pithos_web_client" keyfile="/home/chstath/.ssh/id_rsa" passphrase="r0bax45"> |
|
107 |
<fileset dir="${gwt.www.dir}/${gwt.module}"/> |
|
108 |
</scp> |
|
109 |
</target> |
|
110 |
|
|
105 | 111 |
<target name="clean" description="Delete all build artifacts"> |
106 | 112 |
<delete dir="${build.dir}"/> |
107 | 113 |
</target> |
... | ... | |
128 | 134 |
<jvmarg value="-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=55555"/> |
129 | 135 |
<arg value="-war"/> |
130 | 136 |
<arg value="${gwt.www.dir}/${gwt.module}"/> |
137 |
<arg value="-noserver"/> |
|
131 | 138 |
<arg value="-startupUrl"/> |
132 |
<arg value="GSS.html"/> |
|
139 |
<arg value="http://127.0.0.1:8080/client/GSS.html"/>
|
|
133 | 140 |
<arg value="${gwt.module}"/> |
134 | 141 |
</java> |
135 | 142 |
</target> |
b/web_client/src/gr/grnet/pithos/web/client/CellTreeView.java | ||
---|---|---|
375 | 375 |
@Override |
376 | 376 |
public void onComplete() { |
377 | 377 |
others = getResult(); |
378 |
GSS.get().removeGlassPanel(); |
|
379 | 378 |
} |
380 | 379 |
|
381 | 380 |
@Override |
b/web_client/src/gr/grnet/pithos/web/client/Configuration.java | ||
---|---|---|
46 | 46 |
/** |
47 | 47 |
* @return the relative path of the API root URL |
48 | 48 |
*/ |
49 |
@DefaultStringValue("rest/")
|
|
49 |
@DefaultStringValue("/v1/")
|
|
50 | 50 |
String apiPath(); |
51 | 51 |
|
52 | 52 |
/** |
b/web_client/src/gr/grnet/pithos/web/client/Configuration.properties | ||
---|---|---|
7 | 7 |
logoutUrl=/Shibboleth.sso/Logout |
8 | 8 |
authCookie=_pithos_a |
9 | 9 |
cookieSeparator=| |
10 |
apiPath=v1/ |
|
10 |
apiPath=/v1/
|
|
11 | 11 |
version=2.0 |
/dev/null | ||
---|---|---|
1 |
/* |
|
2 |
* Copyright (c) 2011 Greek Research and Technology Network |
|
3 |
*/ |
|
4 |
package gr.grnet.pithos.web.client; |
|
5 |
|
|
6 |
import gr.grnet.pithos.web.client.MessagePanel.Images; |
|
7 |
import gr.grnet.pithos.web.client.rest.DeleteCommand; |
|
8 |
import gr.grnet.pithos.web.client.rest.RestException; |
|
9 |
import gr.grnet.pithos.web.client.rest.resource.GroupResource; |
|
10 |
|
|
11 |
import com.google.gwt.core.client.GWT; |
|
12 |
import com.google.gwt.dom.client.NativeEvent; |
|
13 |
import com.google.gwt.event.dom.client.ClickEvent; |
|
14 |
import com.google.gwt.event.dom.client.ClickHandler; |
|
15 |
import com.google.gwt.event.dom.client.KeyCodes; |
|
16 |
import com.google.gwt.user.client.DeferredCommand; |
|
17 |
import com.google.gwt.user.client.Event.NativePreviewEvent; |
|
18 |
import com.google.gwt.user.client.ui.AbstractImagePrototype; |
|
19 |
import com.google.gwt.user.client.ui.Button; |
|
20 |
import com.google.gwt.user.client.ui.DialogBox; |
|
21 |
import com.google.gwt.user.client.ui.HTML; |
|
22 |
import com.google.gwt.user.client.ui.HasHorizontalAlignment; |
|
23 |
import com.google.gwt.user.client.ui.HorizontalPanel; |
|
24 |
import com.google.gwt.user.client.ui.TreeItem; |
|
25 |
import com.google.gwt.user.client.ui.VerticalPanel; |
|
26 |
|
|
27 |
/** |
|
28 |
* The 'delete group' dialog box. |
|
29 |
*/ |
|
30 |
public class DeleteGroupDialog extends DialogBox { |
|
31 |
|
|
32 |
/** |
|
33 |
* The widget's constructor. |
|
34 |
* @param images the supplied images |
|
35 |
*/ |
|
36 |
public DeleteGroupDialog(final Images images) { |
|
37 |
// Use this opportunity to set the dialog's caption. |
|
38 |
setText("Delete group"); |
|
39 |
setAnimationEnabled(true); |
|
40 |
final GroupResource group = (GroupResource) GSS.get().getCurrentSelection(); |
|
41 |
// Create a VerticalPanel to contain the 'about' label and the 'OK' |
|
42 |
// button. |
|
43 |
final VerticalPanel outer = new VerticalPanel(); |
|
44 |
final HorizontalPanel buttons = new HorizontalPanel(); |
|
45 |
|
|
46 |
// Create the 'about' text and set a style name so we can style it with |
|
47 |
// CSS. |
|
48 |
final HTML text = new HTML("<table><tr><td>" + AbstractImagePrototype.create(images.warn()).getHTML() + "</td><td>" + "Are you sure you want to delete group '" + group.getName() + "'?</td></tr></table>"); |
|
49 |
text.setStyleName("pithos-warnMessage"); |
|
50 |
outer.add(text); |
|
51 |
|
|
52 |
// Create the 'Quit' button, along with a listener that hides the dialog |
|
53 |
// when the button is clicked and quits the application. |
|
54 |
final Button ok = new Button("OK", new ClickHandler() { |
|
55 |
@Override |
|
56 |
public void onClick(ClickEvent event) { |
|
57 |
deleteGroup(); |
|
58 |
hide(); |
|
59 |
} |
|
60 |
}); |
|
61 |
ok.getElement().setId("deleteGroup.button.ok"); |
|
62 |
buttons.add(ok); |
|
63 |
buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER); |
|
64 |
// Create the 'Cancel' button, along with a listener that hides the |
|
65 |
// dialog |
|
66 |
// when the button is clicked. |
|
67 |
final Button cancel = new Button("Cancel", new ClickHandler() { |
|
68 |
@Override |
|
69 |
public void onClick(ClickEvent event) { |
|
70 |
hide(); |
|
71 |
} |
|
72 |
}); |
|
73 |
cancel.getElement().setId("deleteGroup.button.cancel"); |
|
74 |
buttons.add(cancel); |
|
75 |
buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER); |
|
76 |
buttons.setSpacing(8); |
|
77 |
buttons.setStyleName("pithos-warnMessage"); |
|
78 |
outer.setStyleName("pithos-warnMessage"); |
|
79 |
outer.add(buttons); |
|
80 |
outer.setCellHorizontalAlignment(text, HasHorizontalAlignment.ALIGN_CENTER); |
|
81 |
outer.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER); |
|
82 |
setWidget(outer); |
|
83 |
} |
|
84 |
|
|
85 |
/** |
|
86 |
* Generate an RPC request to delete a group. |
|
87 |
* |
|
88 |
* @param userId the ID of the current user |
|
89 |
*/ |
|
90 |
private void deleteGroup() { |
|
91 |
final TreeItem group = GSS.get().getGroups().getCurrent(); |
|
92 |
if (group == null) { |
|
93 |
GSS.get().displayError("No group was selected!"); |
|
94 |
return; |
|
95 |
} |
|
96 |
DeleteCommand dg = new DeleteCommand(((GroupResource)group.getUserObject()).getUri()){ |
|
97 |
@Override |
|
98 |
public void onComplete() { |
|
99 |
GSS.get().getGroups().updateGroups(); |
|
100 |
} |
|
101 |
|
|
102 |
@Override |
|
103 |
public void onError(Throwable t) { |
|
104 |
GWT.log("", t); |
|
105 |
if(t instanceof RestException){ |
|
106 |
int statusCode = ((RestException)t).getHttpStatusCode(); |
|
107 |
if(statusCode == 405) |
|
108 |
GSS.get().displayError("You don't have the necessary permissions"); |
|
109 |
else if(statusCode == 404) |
|
110 |
GSS.get().displayError("Group not found"); |
|
111 |
else |
|
112 |
GSS.get().displayError("Unable to delete group:"+((RestException)t).getHttpStatusText()); |
|
113 |
} |
|
114 |
else |
|
115 |
GSS.get().displayError("System error unable to delete group:"+t.getMessage()); |
|
116 |
} |
|
117 |
}; |
|
118 |
DeferredCommand.addCommand(dg); |
|
119 |
} |
|
120 |
|
|
121 |
|
|
122 |
@Override |
|
123 |
protected void onPreviewNativeEvent(NativePreviewEvent preview) { |
|
124 |
super.onPreviewNativeEvent(preview); |
|
125 |
|
|
126 |
NativeEvent evt = preview.getNativeEvent(); |
|
127 |
if (evt.getType().equals("keydown")) |
|
128 |
// Use the popup's key preview hooks to close the dialog when either |
|
129 |
// enter or escape is pressed. |
|
130 |
switch (evt.getKeyCode()) { |
|
131 |
case KeyCodes.KEY_ENTER: |
|
132 |
hide(); |
|
133 |
deleteGroup(); |
|
134 |
break; |
|
135 |
case KeyCodes.KEY_ESCAPE: |
|
136 |
hide(); |
|
137 |
break; |
|
138 |
} |
|
139 |
} |
|
140 |
|
|
141 |
} |
/dev/null | ||
---|---|---|
1 |
/* |
|
2 |
* Copyright (c) 2011 Greek Research and Technology Network |
|
3 |
*/ |
|
4 |
package gr.grnet.pithos.web.client; |
|
5 |
|
|
6 |
import gr.grnet.pithos.web.client.MessagePanel.Images; |
|
7 |
import gr.grnet.pithos.web.client.rest.DeleteCommand; |
|
8 |
import gr.grnet.pithos.web.client.rest.RestException; |
|
9 |
import gr.grnet.pithos.web.client.rest.resource.GroupUserResource; |
|
10 |
|
|
11 |
import com.google.gwt.core.client.GWT; |
|
12 |
import com.google.gwt.dom.client.NativeEvent; |
|
13 |
import com.google.gwt.event.dom.client.ClickEvent; |
|
14 |
import com.google.gwt.event.dom.client.ClickHandler; |
|
15 |
import com.google.gwt.event.dom.client.KeyCodes; |
|
16 |
import com.google.gwt.user.client.DeferredCommand; |
|
17 |
import com.google.gwt.user.client.Event.NativePreviewEvent; |
|
18 |
import com.google.gwt.user.client.ui.AbstractImagePrototype; |
|
19 |
import com.google.gwt.user.client.ui.Button; |
|
20 |
import com.google.gwt.user.client.ui.DialogBox; |
|
21 |
import com.google.gwt.user.client.ui.HTML; |
|
22 |
import com.google.gwt.user.client.ui.HasHorizontalAlignment; |
|
23 |
import com.google.gwt.user.client.ui.HorizontalPanel; |
|
24 |
import com.google.gwt.user.client.ui.TreeItem; |
|
25 |
import com.google.gwt.user.client.ui.VerticalPanel; |
|
26 |
|
|
27 |
|
|
28 |
public class DeleteUserDialog extends DialogBox { |
|
29 |
|
|
30 |
/** |
|
31 |
* The widget's constructor. |
|
32 |
* @param images the supplied images |
|
33 |
*/ |
|
34 |
public DeleteUserDialog(final Images images) { |
|
35 |
// Use this opportunity to set the dialog's caption. |
|
36 |
setText("Delete user"); |
|
37 |
setAnimationEnabled(true); |
|
38 |
final GroupUserResource group = (GroupUserResource) GSS.get().getCurrentSelection(); |
|
39 |
// Create a VerticalPanel to contain the 'about' label and the 'OK' |
|
40 |
// button. |
|
41 |
final VerticalPanel outer = new VerticalPanel(); |
|
42 |
final HorizontalPanel buttons = new HorizontalPanel(); |
|
43 |
|
|
44 |
// Create the 'about' text and set a style name so we can style it with |
|
45 |
// CSS. |
|
46 |
final HTML text = new HTML("<table><tr><td>" + AbstractImagePrototype.create(images.warn()).getHTML() + "</td><td>" + "Are you sure you want to remove user '" + group.getName() + "'?</td></tr></table>"); |
|
47 |
text.setStyleName("pithos-warnMessage"); |
|
48 |
outer.add(text); |
|
49 |
|
|
50 |
// Create the 'Quit' button, along with a listener that hides the dialog |
|
51 |
// when the button is clicked and quits the application. |
|
52 |
final Button ok = new Button("OK", new ClickHandler() { |
|
53 |
@Override |
|
54 |
public void onClick(ClickEvent event) { |
|
55 |
deleteUser(); |
|
56 |
hide(); |
|
57 |
} |
|
58 |
}); |
|
59 |
ok.getElement().setId("deleteUser.button.ok"); |
|
60 |
buttons.add(ok); |
|
61 |
buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER); |
|
62 |
// Create the 'Cancel' button, along with a listener that hides the |
|
63 |
// dialog |
|
64 |
// when the button is clicked. |
|
65 |
final Button cancel = new Button("Cancel", new ClickHandler() { |
|
66 |
@Override |
|
67 |
public void onClick(ClickEvent event) { |
|
68 |
hide(); |
|
69 |
} |
|
70 |
}); |
|
71 |
cancel.getElement().setId("confirmation.button.cancel"); |
|
72 |
buttons.add(cancel); |
|
73 |
buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER); |
|
74 |
buttons.setSpacing(8); |
|
75 |
buttons.setStyleName("pithos-warnMessage"); |
|
76 |
outer.setStyleName("pithos-warnMessage"); |
|
77 |
outer.add(buttons); |
|
78 |
outer.setCellHorizontalAlignment(text, HasHorizontalAlignment.ALIGN_CENTER); |
|
79 |
outer.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER); |
|
80 |
setWidget(outer); |
|
81 |
} |
|
82 |
|
|
83 |
/** |
|
84 |
* Generate an RPC request to delete a group. |
|
85 |
* |
|
86 |
* @param userId the ID of the current user |
|
87 |
*/ |
|
88 |
private void deleteUser() { |
|
89 |
final TreeItem user = GSS.get().getGroups().getCurrent(); |
|
90 |
final TreeItem group = user.getParentItem(); |
|
91 |
if (group == null) { |
|
92 |
GSS.get().displayError("No user was selected!"); |
|
93 |
return; |
|
94 |
} |
|
95 |
final GroupUserResource memberR = (GroupUserResource) user.getUserObject(); |
|
96 |
DeleteCommand du = new DeleteCommand(memberR.getUri()){ |
|
97 |
|
|
98 |
@Override |
|
99 |
public void onComplete() { |
|
100 |
GSS.get().getGroups().updateGroups(); |
|
101 |
} |
|
102 |
|
|
103 |
@Override |
|
104 |
public void onError(Throwable t) { |
|
105 |
GWT.log("", t); |
|
106 |
if(t instanceof RestException){ |
|
107 |
int statusCode = ((RestException)t).getHttpStatusCode(); |
|
108 |
if(statusCode == 405) |
|
109 |
GSS.get().displayError("You don't have the necessary permissions"); |
|
110 |
else if(statusCode == 404) |
|
111 |
GSS.get().displayError("User not found"); |
|
112 |
else |
|
113 |
GSS.get().displayError("Unable to delete user:"+((RestException)t).getHttpStatusText()); |
|
114 |
} |
|
115 |
else |
|
116 |
GSS.get().displayError("System error unable to delete user:"+t.getMessage()); |
|
117 |
} |
|
118 |
}; |
|
119 |
DeferredCommand.addCommand(du); |
|
120 |
|
|
121 |
} |
|
122 |
|
|
123 |
@Override |
|
124 |
protected void onPreviewNativeEvent(NativePreviewEvent preview) { |
|
125 |
super.onPreviewNativeEvent(preview); |
|
126 |
|
|
127 |
NativeEvent evt = preview.getNativeEvent(); |
|
128 |
if (evt.getType().equals("keydown")) |
|
129 |
// Use the popup's key preview hooks to close the dialog when either |
|
130 |
// enter or escape is pressed. |
|
131 |
switch (evt.getKeyCode()) { |
|
132 |
case KeyCodes.KEY_ENTER: |
|
133 |
hide(); |
|
134 |
deleteUser(); |
|
135 |
break; |
|
136 |
case KeyCodes.KEY_ESCAPE: |
|
137 |
hide(); |
|
138 |
break; |
|
139 |
} |
|
140 |
} |
|
141 |
|
|
142 |
} |
|
143 |
|
b/web_client/src/gr/grnet/pithos/web/client/EditMenu.java | ||
---|---|---|
133 | 133 |
hide(); |
134 | 134 |
if(GSS.get().isFileListShowing()) |
135 | 135 |
GSS.get().getFileList().selectAllRows(); |
136 |
else if(GSS.get().isSearchResultsShowing()) |
|
137 |
GSS.get().getSearchResults().selectAllRows(); |
|
138 | 136 |
} |
139 | 137 |
}; |
140 | 138 |
final Command unselectAllCommand = new Command() { |
... | ... | |
144 | 142 |
hide(); |
145 | 143 |
if(GSS.get().isFileListShowing()) |
146 | 144 |
GSS.get().getFileList().clearSelectedRows(); |
147 |
else if(GSS.get().isSearchResultsShowing()) |
|
148 |
GSS.get().getSearchResults().clearSelectedRows(); |
|
149 | 145 |
} |
150 | 146 |
}; |
151 | 147 |
|
b/web_client/src/gr/grnet/pithos/web/client/FileContextMenu.java | ||
---|---|---|
156 | 156 |
hide(); |
157 | 157 |
if(GSS.get().isFileListShowing()) |
158 | 158 |
GSS.get().getFileList().clearSelectedRows(); |
159 |
else if(GSS.get().isSearchResultsShowing()) |
|
160 |
GSS.get().getSearchResults().clearSelectedRows(); |
|
161 | 159 |
} |
162 | 160 |
}; |
163 | 161 |
cutItem = new MenuItem("<span id='fileContextMenu.cut'>" + AbstractImagePrototype.create(newImages.cut()).getHTML() + " Cut</span>", true, new CutCommand(this)); |
b/web_client/src/gr/grnet/pithos/web/client/GSS.java | ||
---|---|---|
3 | 3 |
*/ |
4 | 4 |
package gr.grnet.pithos.web.client; |
5 | 5 |
|
6 |
import com.google.gwt.core.client.Scheduler; |
|
7 |
import com.google.gwt.core.client.Scheduler.ScheduledCommand; |
|
8 |
import com.google.gwt.user.client.ui.DockPanel; |
|
9 |
import com.google.gwt.user.client.ui.HasVerticalAlignment; |
|
6 | 10 |
import gr.grnet.pithos.web.client.clipboard.Clipboard; |
7 | 11 |
import gr.grnet.pithos.web.client.commands.GetUserCommand; |
8 |
import gr.grnet.pithos.web.client.rest.GetCommand; |
|
12 |
import gr.grnet.pithos.web.client.foldertree.AccountResource; |
|
13 |
import gr.grnet.pithos.web.client.foldertree.FolderTreeView; |
|
14 |
import gr.grnet.pithos.web.client.rest.GetRequest; |
|
9 | 15 |
import gr.grnet.pithos.web.client.rest.RestException; |
10 | 16 |
import gr.grnet.pithos.web.client.rest.resource.FileResource; |
11 | 17 |
import gr.grnet.pithos.web.client.rest.resource.OtherUserResource; |
... | ... | |
27 | 33 |
import com.google.gwt.event.logical.shared.ResizeHandler; |
28 | 34 |
import com.google.gwt.event.logical.shared.SelectionEvent; |
29 | 35 |
import com.google.gwt.event.logical.shared.SelectionHandler; |
30 |
import com.google.gwt.event.logical.shared.ValueChangeEvent; |
|
31 |
import com.google.gwt.event.logical.shared.ValueChangeHandler; |
|
32 | 36 |
import com.google.gwt.http.client.URL; |
33 | 37 |
import com.google.gwt.i18n.client.DateTimeFormat; |
34 | 38 |
import com.google.gwt.resources.client.ClientBundle; |
... | ... | |
42 | 46 |
import com.google.gwt.user.client.Window; |
43 | 47 |
import com.google.gwt.user.client.ui.AbstractImagePrototype; |
44 | 48 |
import com.google.gwt.user.client.ui.DecoratedTabPanel; |
45 |
import com.google.gwt.user.client.ui.DockPanel; |
|
46 | 49 |
import com.google.gwt.user.client.ui.HasHorizontalAlignment; |
47 |
import com.google.gwt.user.client.ui.HasVerticalAlignment; |
|
48 | 50 |
import com.google.gwt.user.client.ui.HorizontalSplitPanel; |
49 | 51 |
import com.google.gwt.user.client.ui.RootPanel; |
50 | 52 |
import com.google.gwt.user.client.ui.TabPanel; |
51 | 53 |
import com.google.gwt.user.client.ui.VerticalPanel; |
54 |
|
|
52 | 55 |
/** |
53 | 56 |
* Entry point classes define <code>onModuleLoad()</code>. |
54 | 57 |
*/ |
... | ... | |
67 | 70 |
*/ |
68 | 71 |
private static Images images = (Images) GWT.create(Images.class); |
69 | 72 |
|
70 |
private GlassPanel glassPanel = new GlassPanel(); |
|
73 |
public String getUsername() { |
|
74 |
return username; |
|
75 |
} |
|
71 | 76 |
|
72 |
/**
|
|
77 |
/**
|
|
73 | 78 |
* An aggregate image bundle that pulls together all the images for this |
74 | 79 |
* application into a single bundle. |
75 | 80 |
*/ |
76 |
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, CellTreeView.Images {
|
|
81 |
public interface Images extends ClientBundle, TopPanel.Images, StatusPanel.Images, FileMenu.Images, EditMenu.Images, SettingsMenu.Images, FilePropertiesDialog.Images, MessagePanel.Images, FileList.Images, Search.Images, CellTreeView.Images {
|
|
77 | 82 |
|
78 | 83 |
@Source("gr/grnet/pithos/resources/document.png") |
79 | 84 |
ImageResource folders(); |
... | ... | |
134 | 139 |
private FileList fileList; |
135 | 140 |
|
136 | 141 |
/** |
137 |
* The group list widget. |
|
138 |
*/ |
|
139 |
private Groups groups = new Groups(images); |
|
140 |
|
|
141 |
/** |
|
142 |
* The search result widget. |
|
143 |
*/ |
|
144 |
private SearchResults searchResults; |
|
145 |
|
|
146 |
/** |
|
147 | 142 |
* The tab panel that occupies the right side of the screen. |
148 | 143 |
*/ |
149 | 144 |
private TabPanel inner = new DecoratedTabPanel(){ |
... | ... | |
153 | 148 |
if(isFileListShowing()){ |
154 | 149 |
getFileList().showContextMenu(event); |
155 | 150 |
} |
156 |
else if(isUserListVisible()){ |
|
157 |
getGroups().setCurrent(null); |
|
158 |
getGroups().showPopup(event.getClientX(),event.getClientY()); |
|
159 |
} |
|
160 | 151 |
} |
161 | 152 |
}; |
162 | 153 |
}; |
... | ... | |
187 | 178 |
*/ |
188 | 179 |
private Object currentSelection; |
189 | 180 |
|
190 |
/** |
|
191 |
* The authentication token of the current user. |
|
192 |
*/ |
|
193 |
private String token; |
|
194 | 181 |
|
195 | 182 |
/** |
196 | 183 |
* The WebDAV password of the current user |
197 | 184 |
*/ |
198 | 185 |
private String webDAVPassword; |
199 | 186 |
|
200 |
|
|
201 |
|
|
202 | 187 |
public HashMap<String, String> userFullNameMap = new HashMap<String, String>(); |
203 | 188 |
|
189 |
private String username = null; |
|
190 |
|
|
191 |
/** |
|
192 |
* The authentication token of the current user. |
|
193 |
*/ |
|
194 |
private String token; |
|
195 |
|
|
196 |
private FolderTreeView folderTreeView = new FolderTreeView(); |
|
197 |
|
|
204 | 198 |
@Override |
205 | 199 |
public void onModuleLoad() { |
206 | 200 |
// Initialize the singleton before calling the constructors of the |
207 | 201 |
// various widgets that might call GSS.get(). |
208 | 202 |
singleton = this; |
209 |
RootPanel.get().add(glassPanel, 0, 0); |
|
210 |
parseUserCredentials(); |
|
211 |
|
|
212 |
topPanel = new TopPanel(GSS.images); |
|
213 |
topPanel.setWidth("100%"); |
|
203 |
if (parseUserCredentials()) |
|
204 |
initialize(); |
|
205 |
} |
|
214 | 206 |
|
215 |
messagePanel.setWidth("100%"); |
|
216 |
messagePanel.setVisible(false); |
|
207 |
private void initialize() { |
|
208 |
topPanel = new TopPanel(GSS.images); |
|
209 |
topPanel.setWidth("100%"); |
|
210 |
|
|
211 |
messagePanel.setWidth("100%"); |
|
212 |
messagePanel.setVisible(false); |
|
217 | 213 |
|
218 | 214 |
search = new Search(images); |
219 | 215 |
searchStatus.add(search, DockPanel.WEST); |
... | ... | |
223 | 219 |
searchStatus.setCellVerticalAlignment(userDetailsPanel, HasVerticalAlignment.ALIGN_MIDDLE); |
224 | 220 |
searchStatus.setWidth("100%"); |
225 | 221 |
|
226 |
fileList = new FileList(images); |
|
227 |
|
|
228 |
searchResults = new SearchResults(images); |
|
229 |
|
|
230 |
// Inner contains the various lists. |
|
231 |
inner.sinkEvents(Event.ONCONTEXTMENU); |
|
232 |
inner.setAnimationEnabled(true); |
|
233 |
inner.getTabBar().addStyleName("pithos-MainTabBar"); |
|
234 |
inner.getDeckPanel().addStyleName("pithos-MainTabPanelBottom"); |
|
235 |
inner.add(fileList, createHeaderHTML(AbstractImagePrototype.create(images.folders()), "Files"), true); |
|
236 |
|
|
237 |
inner.add(groups, createHeaderHTML(AbstractImagePrototype.create(images.groups()), "Groups"), true); |
|
238 |
inner.add(searchResults, createHeaderHTML(AbstractImagePrototype.create(images.search()), "Search Results"), true); |
|
239 |
//inner.add(new CellTreeView(images), createHeaderHTML(AbstractImagePrototype.create(images.search()), "Cell tree sample"), true); |
|
240 |
inner.setWidth("100%"); |
|
241 |
inner.selectTab(0); |
|
242 |
|
|
243 |
inner.addSelectionHandler(new SelectionHandler<Integer>() { |
|
244 |
|
|
245 |
@Override |
|
246 |
public void onSelection(SelectionEvent<Integer> event) { |
|
247 |
int tabIndex = event.getSelectedItem(); |
|
248 |
// TreeItem treeItem = GSS.get().getFolders().getCurrent(); |
|
249 |
switch (tabIndex) { |
|
250 |
case 0: |
|
251 |
// Files tab selected |
|
252 |
//fileList.clearSelectedRows(); |
|
253 |
fileList.updateCurrentlyShowingStats(); |
|
254 |
break; |
|
255 |
case 1: |
|
256 |
// Groups tab selected |
|
257 |
groups.updateCurrentlyShowingStats(); |
|
258 |
updateHistory("Groups"); |
|
259 |
break; |
|
260 |
case 2: |
|
261 |
// Search tab selected |
|
262 |
searchResults.clearSelectedRows(); |
|
263 |
searchResults.updateCurrentlyShowingStats(); |
|
264 |
updateHistory("Search"); |
|
265 |
break; |
|
266 |
} |
|
267 |
} |
|
268 |
}); |
|
269 |
// If the application starts with no history token, redirect to a new "Files" state |
|
270 |
String initToken = History.getToken(); |
|
271 |
if(initToken.length() == 0) |
|
272 |
History.newItem("Files"); |
|
273 |
// Add history listener to handle any history events |
|
274 |
History.addValueChangeHandler(new ValueChangeHandler<String>() { |
|
275 |
@Override |
|
276 |
public void onValueChange(ValueChangeEvent<String> event) { |
|
277 |
String tokenInput = event.getValue(); |
|
278 |
String historyToken = handleSpecialFolderNames(tokenInput); |
|
279 |
try { |
|
280 |
if(historyToken.equals("Search")) |
|
281 |
inner.selectTab(2); |
|
282 |
else if(historyToken.equals("Groups")) |
|
283 |
inner.selectTab(1); |
|
284 |
else if(historyToken.equals("Files")|| historyToken.length()==0) |
|
285 |
inner.selectTab(0); |
|
286 |
else { |
|
287 |
/*TODO: CELLTREE |
|
288 |
PopupTree popupTree = GSS.get().getFolders().getPopupTree(); |
|
289 |
TreeItem treeObj = GSS.get().getFolders().getPopupTree().getTreeItem(historyToken); |
|
290 |
SelectionEvent.fire(popupTree, treeObj); |
|
291 |
*/ |
|
292 |
} |
|
293 |
} catch (IndexOutOfBoundsException e) { |
|
294 |
inner.selectTab(0); |
|
295 |
} |
|
296 |
} |
|
297 |
}); |
|
298 |
|
|
299 |
// Add the left and right panels to the split panel. |
|
300 |
splitPanel.setLeftWidget(treeView); |
|
301 |
splitPanel.setRightWidget(inner); |
|
302 |
splitPanel.setSplitPosition("25%"); |
|
303 |
splitPanel.setSize("100%", "100%"); |
|
304 |
splitPanel.addStyleName("pithos-splitPanel"); |
|
305 |
|
|
306 |
// Create a dock panel that will contain the menu bar at the top, |
|
307 |
// the shortcuts to the left, the status bar at the bottom and the |
|
308 |
// right panel taking the rest. |
|
309 |
VerticalPanel outer = new VerticalPanel(); |
|
310 |
outer.add(topPanel); |
|
222 |
fileList = new FileList(images); |
|
223 |
|
|
224 |
// Inner contains the various lists. |
|
225 |
inner.sinkEvents(Event.ONCONTEXTMENU); |
|
226 |
inner.setAnimationEnabled(true); |
|
227 |
inner.getTabBar().addStyleName("pithos-MainTabBar"); |
|
228 |
inner.getDeckPanel().addStyleName("pithos-MainTabPanelBottom"); |
|
229 |
inner.add(fileList, createHeaderHTML(AbstractImagePrototype.create(images.folders()), "Files"), true); |
|
230 |
|
|
231 |
inner.setWidth("100%"); |
|
232 |
inner.selectTab(0); |
|
233 |
|
|
234 |
inner.addSelectionHandler(new SelectionHandler<Integer>() { |
|
235 |
|
|
236 |
@Override |
|
237 |
public void onSelection(SelectionEvent<Integer> event) { |
|
238 |
int tabIndex = event.getSelectedItem(); |
|
239 |
switch (tabIndex) { |
|
240 |
case 0: |
|
241 |
fileList.updateCurrentlyShowingStats(); |
|
242 |
break; |
|
243 |
} |
|
244 |
} |
|
245 |
}); |
|
246 |
|
|
247 |
// Add the left and right panels to the split panel. |
|
248 |
splitPanel.setLeftWidget(folderTreeView); |
|
249 |
splitPanel.setRightWidget(inner); |
|
250 |
splitPanel.setSplitPosition("25%"); |
|
251 |
splitPanel.setSize("100%", "100%"); |
|
252 |
splitPanel.addStyleName("pithos-splitPanel"); |
|
253 |
|
|
254 |
// Create a dock panel that will contain the menu bar at the top, |
|
255 |
// the shortcuts to the left, the status bar at the bottom and the |
|
256 |
// right panel taking the rest. |
|
257 |
VerticalPanel outer = new VerticalPanel(); |
|
258 |
outer.add(topPanel); |
|
311 | 259 |
outer.add(searchStatus); |
312 |
outer.add(messagePanel); |
|
313 |
outer.add(splitPanel); |
|
314 |
outer.add(statusPanel); |
|
315 |
outer.setWidth("100%"); |
|
316 |
outer.setCellHorizontalAlignment(messagePanel, HasHorizontalAlignment.ALIGN_CENTER); |
|
317 |
|
|
318 |
outer.setSpacing(4); |
|
319 |
|
|
320 |
// Hook the window resize event, so that we can adjust the UI. |
|
321 |
Window.addResizeHandler(this); |
|
322 |
// Clear out the window's built-in margin, because we want to take |
|
323 |
// advantage of the entire client area. |
|
324 |
Window.setMargin("0px"); |
|
325 |
// Finally, add the outer panel to the RootPanel, so that it will be |
|
326 |
// displayed. |
|
327 |
RootPanel.get().add(outer); |
|
328 |
// Call the window resized handler to get the initial sizes setup. Doing |
|
329 |
// this in a deferred command causes it to occur after all widgets' |
|
330 |
// sizes have been computed by the browser. |
|
331 |
DeferredCommand.addCommand(new Command() { |
|
332 |
|
|
333 |
@Override |
|
334 |
public void execute() { |
|
335 |
onWindowResized(Window.getClientHeight()); |
|
336 |
} |
|
337 |
}); |
|
338 |
} |
|
339 |
|
|
340 |
/** |
|
341 |
* Fetches the User object for the specified username. |
|
342 |
* |
|
343 |
* @param username the username of the user |
|
344 |
*/ |
|
345 |
private void fetchUser(final String username) { |
|
346 |
String path = getApiPath() + username + "/"; |
|
347 |
GetCommand<UserResource> getUserCommand = new GetCommand<UserResource>(UserResource.class, username, path, null) { |
|
348 |
|
|
349 |
@Override |
|
350 |
public void onComplete() { |
|
351 |
|
|
352 |
currentUserResource = getResult(); |
|
353 |
} |
|
354 |
|
|
355 |
@Override |
|
356 |
public void onError(Throwable t) { |
|
357 |
GWT.log("Fetching user error", t); |
|
358 |
if (t instanceof RestException) |
|
359 |
GSS.get().displayError("No user found:" + ((RestException) t).getHttpStatusText()); |
|
360 |
else |
|
361 |
GSS.get().displayError("System error fetching user data:" + t.getMessage()); |
|
362 |
authenticateUser(); |
|
363 |
} |
|
364 |
}; |
|
365 |
DeferredCommand.addCommand(getUserCommand); |
|
366 |
} |
|
260 |
outer.add(messagePanel); |
|
261 |
outer.add(splitPanel); |
|
262 |
outer.add(statusPanel); |
|
263 |
outer.setWidth("100%"); |
|
264 |
outer.setCellHorizontalAlignment(messagePanel, HasHorizontalAlignment.ALIGN_CENTER); |
|
265 |
|
|
266 |
outer.setSpacing(4); |
|
267 |
|
|
268 |
// Hook the window resize event, so that we can adjust the UI. |
|
269 |
Window.addResizeHandler(this); |
|
270 |
// Clear out the window's built-in margin, because we want to take |
|
271 |
// advantage of the entire client area. |
|
272 |
Window.setMargin("0px"); |
|
273 |
// Finally, add the outer panel to the RootPanel, so that it will be |
|
274 |
// displayed. |
|
275 |
RootPanel.get().add(outer); |
|
276 |
// Call the window resized handler to get the initial sizes setup. Doing |
|
277 |
// this in a deferred command causes it to occur after all widgets' |
|
278 |
// sizes have been computed by the browser. |
|
279 |
DeferredCommand.addCommand(new Command() { |
|
280 |
|
|
281 |
@Override |
|
282 |
public void execute() { |
|
283 |
onWindowResized(Window.getClientHeight()); |
|
284 |
} |
|
285 |
}); |
|
286 |
} |
|
367 | 287 |
|
368 | 288 |
/** |
369 | 289 |
* Parse and store the user credentials to the appropriate fields. |
370 | 290 |
*/ |
371 |
private void parseUserCredentials() { |
|
372 |
// Configuration conf = (Configuration) GWT.create(Configuration.class); |
|
373 |
// String cookie = conf.authCookie(); |
|
374 |
// String auth = Cookies.getCookie(cookie); |
|
375 |
// if (auth == null) { |
|
376 |
// authenticateUser(); |
|
377 |
// // Redundant, but silences warnings about possible auth NPE, below. |
|
378 |
// return; |
|
379 |
// } |
|
380 |
// int sepIndex = auth.indexOf(conf.cookieSeparator()); |
|
381 |
// if (sepIndex == -1) |
|
382 |
// authenticateUser(); |
|
383 |
// token = auth.substring(sepIndex + 1); |
|
384 |
// final String username = auth.substring(0, sepIndex); |
|
385 |
// if (username == null) |
|
386 |
// authenticateUser(); |
|
387 |
// |
|
388 |
// refreshWebDAVPassword(); |
|
389 |
|
|
390 |
final String username = "test"; |
|
391 |
DeferredCommand.addCommand(new Command() { |
|
392 |
|
|
393 |
@Override |
|
394 |
public void execute() { |
|
395 |
fetchUser(username); |
|
396 |
} |
|
397 |
}); |
|
291 |
private boolean parseUserCredentials() { |
|
292 |
Configuration conf = (Configuration) GWT.create(Configuration.class); |
|
293 |
String cookie = conf.authCookie(); |
|
294 |
String auth = Cookies.getCookie(cookie); |
|
295 |
if (auth == null) { |
|
296 |
authenticateUser(); |
|
297 |
return false; |
|
298 |
} |
|
299 |
else { |
|
300 |
String[] authSplit = auth.split("\\" + conf.cookieSeparator(), 2); |
|
301 |
if (authSplit.length != 2) { |
|
302 |
authenticateUser(); |
|
303 |
return false; |
|
304 |
} |
|
305 |
else { |
|
306 |
username = authSplit[0]; |
|
307 |
token = authSplit[1]; |
|
308 |
return true; |
|
309 |
} |
|
310 |
} |
|
398 | 311 |
} |
399 | 312 |
|
400 |
/**
|
|
313 |
/**
|
|
401 | 314 |
* Redirect the user to the login page for authentication. |
402 | 315 |
*/ |
403 | 316 |
protected void authenticateUser() { |
404 |
// Configuration conf = (Configuration) GWT.create(Configuration.class); |
|
405 |
//IMPORTANT: Temporary circumvention of the Shiboleth login process for development and testing |
|
406 |
//Some time in the future the comment line will be restored |
|
407 |
|
|
317 |
Configuration conf = (Configuration) GWT.create(Configuration.class); |
|
318 |
|
|
408 | 319 |
// Window.Location.assign(GWT.getModuleBaseURL() + conf.loginUrl() + "?next=" + Window.Location.getHref()); |
409 |
// Cookies.setCookie(conf.authCookie(), "chstath@ebs.gr" + conf.cookieSeparator() + "triapoulakiakathontan");
|
|
410 |
// Window.Location.assign(GWT.getModuleBaseURL());
|
|
320 |
Cookies.setCookie(conf.authCookie(), "demo" + conf.cookieSeparator() + "0000");
|
|
321 |
Window.Location.assign(GWT.getModuleBaseURL() + "GSS.html");
|
|
411 | 322 |
} |
412 | 323 |
|
413 | 324 |
/** |
... | ... | |
447 | 358 |
newHeight = 1; |
448 | 359 |
splitPanel.setHeight("" + newHeight); |
449 | 360 |
inner.setHeight("" + newHeight); |
450 |
/*if(isFileListShowing()){ |
|
451 |
getFileList().setHeight("" + (newHeight-50)); |
|
452 |
}*/ |
|
453 | 361 |
} |
454 | 362 |
|
455 | 363 |
@Override |
... | ... | |
500 | 408 |
RestResource currentFolder = getTreeView().getSelection(); |
501 | 409 |
if(currentFolder!=null){ |
502 | 410 |
showFileList(currentFolder); |
503 |
} |
|
504 | 411 |
} |
505 |
|
|
412 |
} |
|
413 |
|
|
506 | 414 |
} |
507 | 415 |
|
508 | 416 |
public void showFileList(RestResource r) { |
... | ... | |
538 | 446 |
} |
539 | 447 |
|
540 | 448 |
/** |
541 |
* Make the search results visible. |
|
542 |
* |
|
543 |
* @param query the search query string |
|
544 |
*/ |
|
545 |
public void showSearchResults(String query) { |
|
546 |
searchResults.updateFileCache(query); |
|
547 |
searchResults.updateCurrentlyShowingStats(); |
|
548 |
inner.selectTab(2); |
|
549 |
} |
|
550 |
|
|
551 |
/** |
|
552 | 449 |
* Display the 'loading' indicator. |
553 | 450 |
*/ |
554 | 451 |
public void showLoadingIndicator(String message, String path) { |
... | ... | |
651 | 548 |
} |
652 | 549 |
|
653 | 550 |
/** |
654 |
* Retrieve the groups. |
|
655 |
* |
|
656 |
* @return the groups |
|
657 |
*/ |
|
658 |
public Groups getGroups() { |
|
659 |
return groups; |
|
660 |
} |
|
661 |
|
|
662 |
/** |
|
663 | 551 |
* Retrieve the fileList. |
664 | 552 |
* |
665 | 553 |
* @return the fileList |
... | ... | |
668 | 556 |
return fileList; |
669 | 557 |
} |
670 | 558 |
|
671 |
public SearchResults getSearchResults() { |
|
672 |
return searchResults; |
|
673 |
} |
|
674 |
|
|
675 | 559 |
/** |
676 | 560 |
* Retrieve the topPanel. |
677 | 561 |
* |
... | ... | |
713 | 597 |
return webDAVPassword; |
714 | 598 |
} |
715 | 599 |
|
716 |
public void removeGlassPanel() { |
|
717 |
glassPanel.removeFromParent(); |
|
718 |
} |
|
719 |
|
|
720 | 600 |
/** |
721 | 601 |
* Retrieve the currentUserResource. |
722 | 602 |
* |
... | ... | |
749 | 629 |
*/ |
750 | 630 |
public String getApiPath() { |
751 | 631 |
Configuration conf = (Configuration) GWT.create(Configuration.class); |
752 |
return GWT.getModuleBaseURL() + conf.apiPath();
|
|
632 |
return conf.apiPath(); |
|
753 | 633 |
} |
754 | 634 |
|
755 | 635 |
/** |
... | ... | |
846 | 726 |
} |
847 | 727 |
|
848 | 728 |
} |
849 |
|
|
850 |
|
|
851 | 729 |
} |
/dev/null | ||
---|---|---|
1 |
/* |
|
2 |
* Copyright (c) 2011 Greek Research and Technology Network |
|
3 |
*/ |
|
4 |
package gr.grnet.pithos.web.client; |
|
5 |
|
|
6 |
import gr.grnet.pithos.web.client.Groups.Images; |
|
7 |
import gr.grnet.pithos.web.client.commands.CopyCommand; |
|
8 |
import gr.grnet.pithos.web.client.commands.DeleteUserOrGroupCommand; |
|
9 |
import gr.grnet.pithos.web.client.commands.NewGroupCommand; |
|
10 |
import gr.grnet.pithos.web.client.commands.NewUserCommand; |
|
11 |
import gr.grnet.pithos.web.client.commands.PasteCommand; |
|
12 |
import gr.grnet.pithos.web.client.rest.resource.GroupResource; |
|
13 |
import gr.grnet.pithos.web.client.rest.resource.GroupUserResource; |
|
14 |
|
|
15 |
import com.google.gwt.user.client.ui.AbstractImagePrototype; |
|
16 |
import com.google.gwt.user.client.ui.MenuBar; |
|
17 |
import com.google.gwt.user.client.ui.MenuItem; |
|
18 |
import com.google.gwt.user.client.ui.PopupPanel; |
|
19 |
import com.google.gwt.user.client.ui.TreeItem; |
|
20 |
|
|
21 |
|
|
22 |
public class GroupContextMenu extends PopupPanel { |
|
23 |
|
|
24 |
/** |
|
25 |
* The widget's images. |
|
26 |
*/ |
|
27 |
private final Images images; |
|
28 |
private MenuItem copy; |
|
29 |
private MenuItem paste; |
|
30 |
private MenuItem newGroup; |
|
31 |
private MenuItem addUser; |
|
32 |
private MenuItem delete; |
|
33 |
public GroupContextMenu(final Images newImages) { |
|
34 |
// The popup's constructor's argument is a boolean specifying that it |
|
35 |
// auto-close itself when the user clicks outside of it. |
|
36 |
super(true); |
|
37 |
images=newImages; |
|
38 |
setAnimationEnabled(true); |
|
39 |
final MenuBar contextMenu = new MenuBar(true); |
|
40 |
newGroup = new MenuItem("<span>" + AbstractImagePrototype.create(newImages.groupNew()).getHTML() + " New Group</span>", true, new NewGroupCommand(this)); |
|
41 |
newGroup.getElement().setId("groupContextMenu.newGroup"); |
|
42 |
contextMenu.addItem(newGroup); |
|
43 |
|
|
44 |
addUser = new MenuItem("<span>" + AbstractImagePrototype.create(newImages.groupNew()).getHTML() + " Add User</span>", true, new NewUserCommand(this)); |
|
45 |
addUser.getElement().setId("groupContextMenu.addUser"); |
|
46 |
contextMenu.addItem(addUser); |
|
47 |
|
|
48 |
copy = new MenuItem("<span id=groupContextMenu.copyUser>" + AbstractImagePrototype.create(newImages.copy()).getHTML() + " Copy User</span>", true, new CopyCommand(this)); |
|
49 |
copy.getElement().setId("groupContextMenu.copyUser"); |
|
50 |
contextMenu.addItem(copy); |
|
51 |
|
|
52 |
paste = new MenuItem("<span id=groupContextMenu.pasteUser>" + AbstractImagePrototype.create(newImages.paste()).getHTML() + " Paste User</span>", true, new PasteCommand(this)); |
|
53 |
paste.getElement().setId("groupContextMenu.pasteUser"); |
|
54 |
contextMenu.addItem(paste); |
|
55 |
|
|
56 |
delete = new MenuItem("<span id=groupContextMenu.delete>" + AbstractImagePrototype.create(newImages.delete()).getHTML() + " Delete</span>", true, new DeleteUserOrGroupCommand(this,images)); |
|
57 |
delete.getElement().setId("groupContextMenu.delete"); |
|
58 |
contextMenu.addItem(delete); |
|
59 |
|
|
60 |
add(contextMenu); |
|
61 |
|
|
62 |
} |
|
63 |
|
|
64 |
/* (non-Javadoc) |
|
65 |
* @see com.google.gwt.user.client.ui.PopupPanel#show() |
|
66 |
*/ |
|
67 |
@Override |
|
68 |
public void show() { |
|
69 |
TreeItem current = GSS.get().getGroups().getCurrent(); |
|
70 |
if(current==null){ |
|
71 |
copy.setVisible(false); |
|
72 |
paste.setVisible(false); |
|
73 |
addUser.setVisible(false); |
|
74 |
delete.setVisible(false); |
|
75 |
} |
|
76 |
else{ |
|
77 |
newGroup.setVisible(false); |
|
78 |
if(current.getUserObject() instanceof GroupUserResource && GSS.get().getCurrentSelection() instanceof GroupUserResource) |
|
79 |
copy.setVisible(true); |
|
80 |
else |
|
81 |
copy.setVisible(false); |
|
82 |
if(current.getUserObject() instanceof GroupResource && GSS.get().getCurrentSelection() instanceof GroupResource && GSS.get().getClipboard().hasUserItem()) |
|
83 |
paste.setVisible(true); |
|
84 |
else |
|
85 |
paste.setVisible(false); |
|
86 |
} |
|
87 |
super.show(); |
|
88 |
} |
|
89 |
|
|
90 |
} |
/dev/null | ||
---|---|---|
1 |
/* |
|
2 |
* Copyright (c) 2011 Greek Research and Technology Network |
|
3 |
*/ |
|
4 |
package gr.grnet.pithos.web.client; |
|
5 |
|
|
6 |
import gr.grnet.pithos.web.client.commands.NewGroupCommand; |
|
7 |
|
|
8 |
import com.google.gwt.event.dom.client.ClickEvent; |
|
9 |
import com.google.gwt.event.dom.client.ClickHandler; |
|
10 |
import com.google.gwt.resources.client.ClientBundle; |
|
11 |
import com.google.gwt.resources.client.ImageResource; |
|
12 |
import com.google.gwt.user.client.ui.AbstractImagePrototype; |
|
13 |
import com.google.gwt.user.client.ui.MenuBar; |
|
14 |
import com.google.gwt.user.client.ui.MenuItem; |
|
15 |
import com.google.gwt.user.client.ui.PopupPanel; |
|
16 |
|
|
17 |
/** |
|
18 |
* The 'Group' menu implementation. |
|
19 |
*/ |
|
20 |
public class GroupMenu extends PopupPanel implements ClickHandler { |
|
21 |
/** |
|
22 |
* The widget's images. |
|
23 |
*/ |
|
24 |
private Images images; |
|
25 |
private final MenuBar contextMenu; |
|
26 |
|
|
27 |
/** |
|
28 |
* An image bundle for this widgets images. |
|
29 |
*/ |
|
30 |
public interface Images extends ClientBundle { |
|
31 |
@Source("gr/grnet/pithos/resources/groupevent.png") |
|
32 |
ImageResource groupNew(); |
|
33 |
|
|
34 |
@Source("gr/grnet/pithos/resources/view_text.png") |
|
35 |
ImageResource viewText(); |
|
36 |
|
|
37 |
} |
|
38 |
|
|
39 |
/** |
|
40 |
* The widget's constructor. |
|
41 |
* |
|
42 |
* @param newImages the image bundle passed on by the parent object |
|
43 |
*/ |
|
44 |
public GroupMenu(final Images newImages) { |
|
45 |
// The popup's constructor's argument is a boolean specifying that it |
|
46 |
// auto-close itself when the user clicks outside of it. |
|
47 |
super(true); |
|
48 |
setAnimationEnabled(true); |
|
49 |
images = newImages; |
|
50 |
|
|
51 |
contextMenu = new MenuBar(true); |
|
52 |
MenuItem newGroupItem = new MenuItem("<span>" + AbstractImagePrototype.create(newImages.groupNew()).getHTML() + " New Group</span>", true, new NewGroupCommand(this)); |
|
53 |
newGroupItem.getElement().setId("topMenu.group.newGroup"); |
|
54 |
contextMenu.addItem(newGroupItem); |
|
55 |
|
|
56 |
add(contextMenu); |
|
57 |
} |
|
58 |
|
|
59 |
@Override |
|
60 |
public void onClick(ClickEvent event) { |
|
61 |
GroupMenu menu = new GroupMenu(images); |
|
62 |
int left = event.getRelativeElement().getAbsoluteLeft(); |
|
63 |
int top = event.getRelativeElement().getAbsoluteTop() + event.getRelativeElement().getOffsetHeight(); |
|
64 |
menu.setPopupPosition(left, top); |
|
65 |
|
|
66 |
menu.show(); |
|
67 |
} |
|
68 |
|
|
69 |
/** |
|
70 |
* Retrieve the contextMenu. |
|
71 |
* |
|
72 |
* @return the contextMenu |
|
73 |
*/ |
|
74 |
public MenuBar getContextMenu() { |
|
75 |
contextMenu.setAutoOpen(false); |
|
76 |
return contextMenu; |
|
77 |
} |
|
78 |
|
|
79 |
} |
/dev/null | ||
---|---|---|
1 |
/* |
|
2 |
* Copyright (c) 2011 Greek Research and Technology Network |
|
3 |
*/ |
|
4 |
package gr.grnet.pithos.web.client; |
|
5 |
|
|
6 |
import gr.grnet.pithos.web.client.rest.PostCommand; |
|
7 |
import gr.grnet.pithos.web.client.rest.RestException; |
|
8 |
|
|
9 |
import com.google.gwt.core.client.GWT; |
|
10 |
import com.google.gwt.dom.client.NativeEvent; |
|
11 |
import com.google.gwt.event.dom.client.ClickEvent; |
|
12 |
import com.google.gwt.event.dom.client.ClickHandler; |
|
13 |
import com.google.gwt.event.dom.client.KeyCodes; |
|
14 |
import com.google.gwt.http.client.URL; |
|
15 |
import com.google.gwt.user.client.DeferredCommand; |
|
16 |
import com.google.gwt.user.client.Event.NativePreviewEvent; |
|
17 |
import com.google.gwt.user.client.ui.Button; |
|
18 |
import com.google.gwt.user.client.ui.DialogBox; |
|
19 |
import com.google.gwt.user.client.ui.Grid; |
|
20 |
import com.google.gwt.user.client.ui.HasHorizontalAlignment; |
|
21 |
import com.google.gwt.user.client.ui.HorizontalPanel; |
|
22 |
import com.google.gwt.user.client.ui.TextBox; |
|
23 |
import com.google.gwt.user.client.ui.VerticalPanel; |
|
24 |
|
|
25 |
public class GroupPropertiesDialog extends DialogBox { |
|
26 |
|
|
27 |
/** |
|
28 |
* The widget that holds the folderName of the folder. |
|
29 |
*/ |
|
30 |
private TextBox groupName = new TextBox(); |
|
31 |
|
|
32 |
/** |
|
33 |
* A flag that denotes whether the dialog will be used to create or modify a |
|
34 |
* folder. |
|
35 |
*/ |
|
36 |
private final boolean create; |
|
37 |
|
|
38 |
/** |
|
39 |
* The widget's constructor. |
|
40 |
* |
|
41 |
* @param _create true if the dialog is displayed for creating a new |
|
42 |
* sub-folder of the selected folder, false if it is displayed |
|
43 |
* for modifying the selected folder |
|
44 |
*/ |
|
45 |
public GroupPropertiesDialog(final boolean _create) { |
|
46 |
setAnimationEnabled(true); |
|
47 |
create = _create; |
|
48 |
// Use this opportunity to set the dialog's caption. |
|
49 |
if (create) |
|
50 |
setText("Create Group"); |
|
51 |
else |
|
52 |
setText("Group properties"); |
|
53 |
final VerticalPanel panel = new VerticalPanel(); |
|
54 |
setWidget(panel); |
|
55 |
groupName.getElement().setId("groupDialog.textBox.name"); |
|
56 |
final Grid generalTable = new Grid(1, 2); |
|
57 |
generalTable.setText(0, 0, "Group Name"); |
|
58 |
generalTable.setWidget(0, 1, groupName); |
|
59 |
generalTable.getCellFormatter().setStyleName(0, 0, "props-labels"); |
|
60 |
generalTable.getCellFormatter().setStyleName(0, 1, "props-values"); |
|
61 |
generalTable.setCellSpacing(4); |
|
62 |
|
|
63 |
panel.add(generalTable); |
|
64 |
final HorizontalPanel buttons = new HorizontalPanel(); |
|
65 |
final Button ok = new Button("OK", new ClickHandler() { |
|
66 |
@Override |
|
67 |
public void onClick(ClickEvent event) { |
|
68 |
createGroup(groupName.getText()); |
|
69 |
hide(); |
|
70 |
} |
|
71 |
}); |
|
72 |
ok.getElement().setId("groupDialog.button.ok"); |
|
73 |
buttons.add(ok); |
|
74 |
buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER); |
|
75 |
// Create the 'Cancel' button, along with a listener that hides the |
|
76 |
// dialog |
|
77 |
// when the button is clicked. |
|
78 |
final Button cancel = new Button("Cancel", new ClickHandler() { |
|
79 |
@Override |
|
80 |
public void onClick(ClickEvent event) { |
|
81 |
hide(); |
|
82 |
} |
|
83 |
}); |
|
84 |
cancel.getElement().setId("groupDialog.button.cancel"); |
|
85 |
buttons.add(cancel); |
|
86 |
buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER); |
|
87 |
buttons.setSpacing(8); |
|
88 |
buttons.addStyleName("pithos-TabPanelBottom"); |
|
89 |
panel.add(buttons); |
|
90 |
panel.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER); |
|
91 |
//panel.addStyleName("pithos-DialogBox"); |
|
92 |
panel.addStyleName("pithos-TabPanelBottom"); |
|
93 |
} |
|
94 |
@Override |
|
95 |
public void center() { |
|
96 |
super.center(); |
|
97 |
groupName.setFocus(true); |
|
98 |
} |
|
99 |
|
|
100 |
@Override |
|
101 |
protected void onPreviewNativeEvent(NativePreviewEvent preview) { |
|
102 |
super.onPreviewNativeEvent(preview); |
|
103 |
|
|
104 |
NativeEvent evt = preview.getNativeEvent(); |
|
105 |
if (evt.getType().equals("keydown")) |
|
106 |
// Use the popup's key preview hooks to close the dialog when either |
|
107 |
// enter or escape is pressed. |
|
108 |
switch (evt.getKeyCode()) { |
|
109 |
case KeyCodes.KEY_ENTER: |
|
110 |
hide(); |
|
111 |
createGroup( groupName.getText()); |
|
112 |
break; |
|
113 |
case KeyCodes.KEY_ESCAPE: |
|
114 |
hide(); |
|
115 |
break; |
|
116 |
} |
|
117 |
} |
|
118 |
|
|
119 |
|
|
120 |
/** |
|
121 |
* Generate an RPC request to create a new group. |
|
122 |
* |
|
123 |
* @param userId the ID of the user whose namespace will be searched for |
|
124 |
* groups |
|
125 |
* @param aGroupName the name of the group to create |
|
126 |
*/ |
|
127 |
private void createGroup(String aGroupName) { |
|
128 |
|
|
129 |
if (aGroupName == null || aGroupName.length() == 0) { |
|
130 |
GSS.get().displayError("Empty group name!"); |
|
131 |
return; |
|
132 |
} |
|
133 |
GWT.log("createGroup(" + aGroupName + ")", null); |
|
134 |
PostCommand cg = new PostCommand(GSS.get().getCurrentUserResource().getGroupsPath()+"?name="+URL.encodeComponent(aGroupName), "", 201){ |
|
135 |
|
|
136 |
@Override |
|
137 |
public void onComplete() { |
|
138 |
GSS.get().getGroups().updateGroups(); |
|
139 |
GSS.get().showUserList(); |
|
140 |
} |
|
141 |
|
|
142 |
@Override |
|
143 |
public void onError(Throwable t) { |
|
144 |
GWT.log("", t); |
|
145 |
if(t instanceof RestException){ |
|
146 |
int statusCode = ((RestException)t).getHttpStatusCode(); |
|
147 |
if(statusCode == 405) |
|
148 |
GSS.get().displayError("You don't have the necessary permissions"); |
|
149 |
else if(statusCode == 404) |
|
150 |
GSS.get().displayError("Resource does not exist"); |
|
151 |
else if(statusCode == 409) |
|
152 |
GSS.get().displayError("A group with the same name already exists"); |
|
153 |
else if(statusCode == 413) |
|
154 |
GSS.get().displayError("Your quota has been exceeded"); |
|
155 |
else |
|
156 |
GSS.get().displayError("Unable to create group:"+((RestException)t).getHttpStatusText()); |
|
157 |
} |
|
158 |
else |
|
159 |
GSS.get().displayError("System error creating group:"+t.getMessage()); |
|
160 |
} |
|
161 |
}; |
|
162 |
DeferredCommand.addCommand(cg); |
|
163 |
|
|
164 |
} |
|
165 |
} |
/dev/null | ||
---|---|---|
1 |
/* |
|
2 |
* Copyright (c) 2011 Greek Research and Technology Network |
|
3 |
*/ |
|
4 |
package gr.grnet.pithos.web.client; |
|
5 |
|
|
6 |
import gr.grnet.pithos.web.client.rest.GetCommand; |
|
7 |
import gr.grnet.pithos.web.client.rest.MultipleGetCommand; |
|
8 |
import gr.grnet.pithos.web.client.rest.resource.GroupResource; |
|
9 |
import gr.grnet.pithos.web.client.rest.resource.GroupUserResource; |
|
10 |
import gr.grnet.pithos.web.client.rest.resource.GroupsResource; |
|
11 |
|
|
12 |
import java.util.List; |
|
13 |
|
|
14 |
import com.google.gwt.core.client.GWT; |
|
15 |
import com.google.gwt.dom.client.NativeEvent; |
|
16 |
import com.google.gwt.event.dom.client.ContextMenuEvent; |
|
17 |
import com.google.gwt.event.dom.client.ContextMenuHandler; |
|
18 |
import com.google.gwt.event.logical.shared.OpenEvent; |
|
19 |
import com.google.gwt.event.logical.shared.OpenHandler; |
|
20 |
import com.google.gwt.event.logical.shared.SelectionEvent; |
|
21 |
import com.google.gwt.event.logical.shared.SelectionHandler; |
|
22 |
import com.google.gwt.resources.client.ClientBundle; |
|
23 |
import com.google.gwt.resources.client.ImageResource; |
|
24 |
import com.google.gwt.user.client.DOM; |
|
25 |
import com.google.gwt.user.client.DeferredCommand; |
|
26 |
import com.google.gwt.user.client.Event; |
|
27 |
import com.google.gwt.user.client.ui.AbstractImagePrototype; |
|
28 |
import com.google.gwt.user.client.ui.Composite; |
|
29 |
import com.google.gwt.user.client.ui.HTML; |
|
30 |
import com.google.gwt.user.client.ui.Tree; |
|
31 |
import com.google.gwt.user.client.ui.TreeItem; |
|
32 |
|
|
33 |
/** |
|
34 |
* A component that displays a list of the user's groups. |
|
35 |
*/ |
|
36 |
public class Groups extends Composite implements SelectionHandler, OpenHandler { |
|
37 |
|
|
38 |
/** |
|
39 |
* An image bundle for this widget. |
|
40 |
*/ |
|
41 |
public interface Images extends Tree.Resources, ClientBundle, FileMenu.Images, EditMenu.Images, GroupMenu.Images, MessagePanel.Images { |
|
42 |
|
|
43 |
/** |
|
44 |
* Will bundle the file 'groupevent.png' residing in the package |
|
45 |
* 'gr.grnet.pithos.web.resources'. |
|
46 |
* |
|
47 |
* @return the image prototype |
|
48 |
*/ |
|
49 |
@Source("gr/grnet/pithos/resources/groupevent.png") |
|
50 |
ImageResource groupImage(); |
|
51 |
|
|
52 |
@Override |
|
53 |
@Source("gr/grnet/pithos/resources/editdelete.png") |
|
54 |
ImageResource delete(); |
|
55 |
|
|
56 |
} |
|
57 |
|
|
58 |
/** |
|
59 |
* cached latest group selection (for selecting and expanding on refresh) |
|
60 |
*/ |
|
61 |
private String selectedGroup = null; |
|
62 |
|
|
63 |
/** |
|
64 |
* The tree widget that displays the groups. |
|
65 |
*/ |
|
66 |
private Tree tree; |
|
67 |
|
|
68 |
/** |
|
69 |
* A cached copy of the currently selected group widget. |
|
70 |
*/ |
|
71 |
private TreeItem current; |
|
72 |
|
|
73 |
/** |
|
74 |
* A cached copy of the previously selected group widget. |
|
75 |
*/ |
|
76 |
private TreeItem previous; |
|
77 |
|
|
78 |
/** |
|
79 |
* The widget's image bundle. |
|
80 |
*/ |
|
81 |
private final Images images; |
|
82 |
|
|
83 |
private GroupContextMenu menu; |
|
84 |
|
|
85 |
/** |
|
86 |
* Constructs a new groups widget with a bundle of images. |
|
87 |
* |
|
88 |
* @param newImages a bundle that provides the images for this widget |
|
89 |
*/ |
|
90 |
public Groups(final Images newImages) { |
|
91 |
|
|
92 |
images = newImages; |
|
93 |
menu = new GroupContextMenu(images); |
|
94 |
tree = new Tree(newImages); |
|
95 |
this.addHandler(new ContextMenuHandler() { |
|
96 |
|
|
97 |
@Override |
|
98 |
public void onContextMenu(ContextMenuEvent event) { |
|
99 |
if(current==null) return; |
|
100 |
int left = current.getAbsoluteLeft() + 40; |
|
101 |
int top = current.getAbsoluteTop() + 20; |
|
102 |
showPopup(left, top); |
|
103 |
|
|
104 |
} |
|
105 |
}, ContextMenuEvent.getType()); |
|
106 |
tree.getElement().setId("groupsList.tree"); |
|
107 |
tree.addSelectionHandler(this); |
|
108 |
tree.addOpenHandler(this); |
|
109 |
tree.setAnimationEnabled(true); |
|
110 |
initWidget(tree); |
|
111 |
this.getElement().setAttribute("id", "CreativeFilesPanel"); |
|
112 |
setStylePrimaryName("pithos-Groups"); |
|
113 |
sinkEvents(Event.ONCONTEXTMENU); |
|
114 |
sinkEvents(Event.ONMOUSEUP); |
|
115 |
sinkEvents(Event.ONDBLCLICK); |
|
116 |
sinkEvents(Event.KEYEVENTS); |
|
117 |
} |
|
118 |
|
|
119 |
|
|
120 |
/** |
|
121 |
* Make an RPC call to retrieve the groups that belong to the specified |
|
122 |
* user. |
|
123 |
*/ |
|
124 |
public void updateGroups() { |
|
125 |
GetCommand<GroupsResource> gg = new GetCommand<GroupsResource>(GroupsResource.class, GSS.get().getCurrentUserResource().getGroupsPath(),null){ |
|
126 |
|
|
127 |
@Override |
|
128 |
public void onComplete() { |
|
129 |
GroupsResource res = getResult(); |
|
130 |
MultipleGetCommand<GroupResource> ga = new MultipleGetCommand<GroupResource>(GroupResource.class, res.getGroupPaths().toArray(new String[]{}), null){ |
|
131 |
|
|
132 |
@Override |
|
133 |
public void onComplete() { |
|
134 |
List<GroupResource> groupList = getResult(); |
|
135 |
tree.clear(); |
|
136 |
for (int i = 0; i < groupList.size(); i++) { |
|
137 |
final TreeItem item = new TreeItem(); |
|
138 |
item.setWidget(imageItemHTML(images.groupImage(), groupList.get(i).getName(),item)); |
|
139 |
item.setUserObject(groupList.get(i)); |
|
140 |
tree.addItem(item); |
|
141 |
updateUsers(item); |
|
142 |
} |
|
143 |
} |
|
144 |
|
|
145 |
@Override |
|
146 |
public void onError(Throwable t) { |
|
147 |
GWT.log("", t); |
|
148 |
} |
|
149 |
|
|
150 |
@Override |
|
151 |
public void onError(String p, Throwable throwable) { |
|
152 |
GWT.log("Path:"+p, throwable); |
|
153 |
} |
|
154 |
}; |
|
155 |
DeferredCommand.addCommand(ga); |
|
156 |
} |
|
157 |
|
|
158 |
@Override |
|
159 |
public void onError(Throwable t) { |
|
160 |
|
|
161 |
} |
|
162 |
}; |
|
163 |
DeferredCommand.addCommand(gg); |
|
164 |
} |
|
165 |
|
|
166 |
/** |
|
167 |
* update status panel with currently showing file stats |
|
168 |
*/ |
|
169 |
public void updateCurrentlyShowingStats() { |
|
170 |
GSS.get().getStatusPanel().updateCurrentlyShowing(null); //clear stats - nothing to show for the groups tab |
|
171 |
} |
|
172 |
|
|
173 |
/** |
|
174 |
* A helper method to simplify adding tree items that have attached images. |
|
175 |
* |
|
176 |
* @param parent the tree item to which the new item will be added. |
|
177 |
* @param title the text associated with this item. |
|
178 |
* @param imageProto |
|
179 |
* @return the new tree item |
|
180 |
*/ |
|
181 |
private TreeItem addImageItem(final TreeItem parent, final String title, final ImageResource imageProto) { |
|
182 |
final TreeItem item = new TreeItem(); |
|
183 |
item.setWidget(imageItemHTML(imageProto, title,item)); |
|
184 |
parent.addItem(item); |
|
185 |
return item; |
|
186 |
} |
|
187 |
|
|
188 |
/** |
|
189 |
* Generates HTML for a tree item with an attached icon. |
|
190 |
* |
|
191 |
* @param imageProto the icon image |
|
192 |
* @param title the title of the item |
|
193 |
* @return the resultant HTML |
|
194 |
*/ |
|
195 |
private HTML imageItemHTML(final ImageResource imageProto, final String title,final TreeItem item) { |
|
196 |
final HTML link = new HTML("<a class='hidden-link' href='javascript:;'>" + "<span id='groupsList."+title+"'>" + AbstractImagePrototype.create(imageProto).getHTML() + " " + title + "</span>" + "</a>"){ |
|
197 |
@Override |
|
198 |
public void onBrowserEvent(Event event) { |
|
199 |
switch (DOM.eventGetType(event)) { |
|
200 |
case Event.ONMOUSEDOWN: |
|
201 |
if (DOM.eventGetButton(event) == NativeEvent.BUTTON_RIGHT || DOM.eventGetButton(event) == NativeEvent.BUTTON_LEFT) |
|
202 |
onSelection(item); |
|
203 |
break; |
|
204 |
case Event.ONCONTEXTMENU: |
|
205 |
showPopup(event.getClientX(), event.getClientY()); |
|
206 |
event.preventDefault(); |
|
207 |
event.stopPropagation(); |
|
208 |
break; |
|
209 |
} |
|
210 |
super.onBrowserEvent(event); |
|
211 |
|
|
212 |
} |
|
213 |
}; |
|
214 |
link.sinkEvents(Event.ONMOUSEDOWN); |
|
215 |
link.sinkEvents(Event.ONCONTEXTMENU); |
|
216 |
link.sinkEvents(Event.ONCLICK); |
|
217 |
link.sinkEvents(Event.ONKEYDOWN); |
|
218 |
return link; |
|
219 |
} |
|
220 |
|
|
221 |
|
|
222 |
|
Also available in: Unified diff