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() + "&nbsp;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() + "&nbsp;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() + "&nbsp;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() + "&nbsp;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() + "&nbsp;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() + "&nbsp;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() + "&nbsp;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() + "&nbsp;" + 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

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff