Revision 023f6f1e src/gr/ebs/gss/client/FileList.java

b/src/gr/ebs/gss/client/FileList.java
1
/*
2
 * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
3
 *
4
 * This file is part of GSS.
5
 *
6
 * GSS is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * GSS is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
package gr.ebs.gss.client;
20

  
21
import gr.ebs.gss.client.dnd.DnDSimpleFocusPanel;
22
import gr.ebs.gss.client.dnd.DnDTreeItem;
23
import gr.ebs.gss.client.rest.GetCommand;
24
import gr.ebs.gss.client.rest.MultipleHeadCommand;
25
import gr.ebs.gss.client.rest.RestCommand;
26
import gr.ebs.gss.client.rest.RestException;
27
import gr.ebs.gss.client.rest.resource.FileResource;
28
import gr.ebs.gss.client.rest.resource.FolderResource;
29
import gr.ebs.gss.client.rest.resource.OtherUserResource;
30
import gr.ebs.gss.client.rest.resource.SharedResource;
31
import gr.ebs.gss.client.rest.resource.TrashResource;
32
import gr.ebs.gss.client.rest.resource.UserResource;
33

  
34
import java.util.ArrayList;
35
import java.util.Collections;
36
import java.util.Comparator;
37
import java.util.List;
38

  
39
import com.google.gwt.core.client.GWT;
40
import com.google.gwt.dom.client.NativeEvent;
41
import com.google.gwt.event.dom.client.ClickEvent;
42
import com.google.gwt.event.dom.client.ClickHandler;
43
import com.google.gwt.http.client.URL;
44
import com.google.gwt.i18n.client.DateTimeFormat;
45
import com.google.gwt.resources.client.ClientBundle;
46
import com.google.gwt.resources.client.ImageResource;
47
import com.google.gwt.user.client.DOM;
48
import com.google.gwt.user.client.DeferredCommand;
49
import com.google.gwt.user.client.Event;
50
import com.google.gwt.user.client.IncrementalCommand;
51
import com.google.gwt.user.client.Window;
52
import com.google.gwt.user.client.ui.AbstractImagePrototype;
53
import com.google.gwt.user.client.ui.Composite;
54
import com.google.gwt.user.client.ui.Grid;
55
import com.google.gwt.user.client.ui.HTML;
56
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
57
import com.google.gwt.user.client.ui.HorizontalPanel;
58
import com.google.gwt.user.client.ui.TreeItem;
59
import com.google.gwt.user.client.ui.Widget;
60
import com.google.gwt.user.client.ui.HTMLTable.Cell;
61

  
62
/**
63
 * A composite that displays the list of files in a particular folder.
64
 */
65
public class FileList extends Composite implements ClickHandler {
66

  
67
	private HTML prevButton = new HTML("<a href='javascript:;'>&lt; Previous</a>", true);
68

  
69
	private HTML nextButton = new HTML("<a href='javascript:;'>Next &gt;</a>", true);
70

  
71
	private String showingStats = "";
72

  
73
	private int startIndex = 0;
74

  
75
	/**
76
	 * A constant that denotes the completion of an IncrementalCommand.
77
	 */
78
	public static final boolean DONE = false;
79

  
80
	private boolean clickControl = false;
81

  
82
	private boolean clickShift = false;
83

  
84
	private int firstShift = -1;
85

  
86
	private ArrayList<Integer> selectedRows = new ArrayList<Integer>();
87

  
88
	/**
89
	 * The context menu for the selected file.
90
	 */
91
	final DnDSimpleFocusPanel contextMenu;
92

  
93
	/**
94
	 * Specifies that the images available for this composite will be the ones
95
	 * available in FileContextMenu.
96
	 */
97
	public interface Images extends ClientBundle,FileContextMenu.Images, Folders.Images {
98

  
99
		@Source("gr/ebs/gss/resources/blank.gif")
100
		ImageResource blank();
101

  
102
		@Source("gr/ebs/gss/resources/asc.png")
103
		ImageResource asc();
104

  
105
		@Source("gr/ebs/gss/resources/desc.png")
106
		ImageResource desc();
107

  
108
		@Source("gr/ebs/gss/resources/mimetypes/document_shared.png")
109
		ImageResource documentShared();
110

  
111
		@Source("gr/ebs/gss/resources/mimetypes/kcmfontinst.png")
112
		ImageResource wordprocessor();
113

  
114
		@Source("gr/ebs/gss/resources/mimetypes/log.png")
115
		ImageResource spreadsheet();
116

  
117
		@Source("gr/ebs/gss/resources/mimetypes/kpresenter_kpr.png")
118
		ImageResource presentation();
119

  
120
		@Source("gr/ebs/gss/resources/mimetypes/acroread.png")
121
		ImageResource pdf();
122

  
123
		@Source("gr/ebs/gss/resources/mimetypes/image.png")
124
		ImageResource image();
125

  
126
		@Source("gr/ebs/gss/resources/mimetypes/video2.png")
127
		ImageResource video();
128

  
129
		@Source("gr/ebs/gss/resources/mimetypes/knotify.png")
130
		ImageResource audio();
131

  
132
		@Source("gr/ebs/gss/resources/mimetypes/html.png")
133
		ImageResource html();
134

  
135
		@Source("gr/ebs/gss/resources/mimetypes/txt.png")
136
		ImageResource txt();
137

  
138
		@Source("gr/ebs/gss/resources/mimetypes/ark2.png")
139
		ImageResource zip();
140

  
141
		@Source("gr/ebs/gss/resources/mimetypes/kcmfontinst_shared.png")
142
		ImageResource wordprocessorShared();
143

  
144
		@Source("gr/ebs/gss/resources/mimetypes/log_shared.png")
145
		ImageResource spreadsheetShared();
146

  
147
		@Source("gr/ebs/gss/resources/mimetypes/kpresenter_kpr_shared.png")
148
		ImageResource presentationShared();
149

  
150
		@Source("gr/ebs/gss/resources/mimetypes/acroread_shared.png")
151
		ImageResource pdfShared();
152

  
153
		@Source("gr/ebs/gss/resources/mimetypes/image_shared.png")
154
		ImageResource imageShared();
155

  
156
		@Source("gr/ebs/gss/resources/mimetypes/video2_shared.png")
157
		ImageResource videoShared();
158

  
159
		@Source("gr/ebs/gss/resources/mimetypes/knotify_shared.png")
160
		ImageResource audioShared();
161

  
162
		@Source("gr/ebs/gss/resources/mimetypes/html_shared.png")
163
		ImageResource htmlShared();
164

  
165
		@Source("gr/ebs/gss/resources/mimetypes/txt_shared.png")
166
		ImageResource txtShared();
167

  
168
		@Source("gr/ebs/gss/resources/mimetypes/ark2_shared.png")
169
		ImageResource zipShared();
170

  
171
	}
172

  
173
	/**
174
	 * A label with the number of files in this folder.
175
	 */
176
	private HTML countLabel = new HTML();
177

  
178
	/**
179
	 * The table widget with the file list.
180
	 */
181
	private FileTable table = new FileTable(GSS.VISIBLE_FILE_COUNT + 1, 8);
182

  
183
	/**
184
	 * The navigation bar for paginating the results.
185
	 */
186
	private HorizontalPanel navBar = new HorizontalPanel();
187

  
188
	/**
189
	 * The number of files in this folder.
190
	 */
191
	int folderFileCount;
192

  
193
	/**
194
	 * Total folder size
195
	 */
196
	long folderTotalSize;
197

  
198
	/**
199
	 * A cache of the files in the list.
200
	 */
201
	private List<FileResource> files;
202

  
203
	/**
204
	 * The widget's image bundle.
205
	 */
206
	private final Images images;
207

  
208
	private String sortingProperty = "name";
209

  
210
	private boolean sortingType = true;
211

  
212
	private HTML nameLabel;
213

  
214
	private HTML versionLabel;
215

  
216
	private HTML sizeLabel;
217

  
218
	private HTML dateLabel;
219

  
220
	private HTML ownerLabel;
221

  
222
	private HTML pathLabel;
223

  
224
	/**
225
	 * Construct the file list widget. This entails setting up the widget
226
	 * layout, fetching the number of files in the current folder from the
227
	 * server and filling the local file cache of displayed files with data from
228
	 * the server, as well.
229
	 *
230
	 * @param _images
231
	 */
232
	public FileList(Images _images) {
233
		images = _images;
234

  
235
		prevButton.addClickHandler(this);
236
		nextButton.addClickHandler(this);
237

  
238
		contextMenu = new DnDSimpleFocusPanel(new HTML(AbstractImagePrototype.create(images.fileContextMenu()).getHTML()));
239
		GSS.get().getDragController().makeDraggable(contextMenu);
240

  
241
		// Setup the table.
242
		table.setCellSpacing(0);
243
		table.setCellPadding(2);
244
		table.setWidth("100%");
245
		table.addClickHandler(new ClickHandler() {
246

  
247
			@Override
248
			public void onClick(ClickEvent event) {
249
				Cell cell = table.getCellForEvent(event);
250
				GWT.log("row clicked:"+cell.getRowIndex(), null);
251
				onRowClicked(cell.getRowIndex(), true);
252
			}
253
		});
254
		// Create the 'navigation' bar at the upper-right.
255
		HorizontalPanel innerNavBar = new HorizontalPanel();
256
		innerNavBar.setStyleName("gss-ListNavBar");
257
		innerNavBar.setSpacing(8);
258
		innerNavBar.add(prevButton);
259
		innerNavBar.add(countLabel);
260
		innerNavBar.add(nextButton);
261
		navBar.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
262
		navBar.add(innerNavBar);
263
		navBar.setWidth("100%");
264

  
265
		initWidget(table);
266
		setStyleName("gss-List");
267

  
268
		initTable();
269
		DeferredCommand.addCommand(new IncrementalCommand() {
270

  
271
			public boolean execute() {
272
				return fetchRootFolder();
273
			}
274
		});
275
		sinkEvents(Event.ONCONTEXTMENU);
276
		sinkEvents(Event.ONMOUSEUP);
277
		sinkEvents(Event.ONMOUSEDOWN);
278
		sinkEvents(Event.ONCLICK);
279
		sinkEvents(Event.ONKEYDOWN);
280
		sinkEvents(Event.ONDBLCLICK);
281
		GSS.preventIESelection();
282
	}
283

  
284
	@Override
285
	public void onClick(ClickEvent event) {
286
		 if(event.getSource() == nextButton){
287
			// Move forward a page.
288
			clearSelectedRows();
289
			startIndex += GSS.VISIBLE_FILE_COUNT;
290
			if (startIndex >= folderFileCount)
291
				startIndex -= GSS.VISIBLE_FILE_COUNT;
292
			else
293
				update(false);
294
		} else if (event.getSource() == prevButton) {
295
			clearSelectedRows();
296
			// Move back a page.
297
			startIndex -= GSS.VISIBLE_FILE_COUNT;
298
			if (startIndex < 0)
299
				startIndex = 0;
300
			else
301
				update(false);
302
		}
303
	}
304

  
305

  
306
	@Override
307
	public void onBrowserEvent(Event event) {
308
		if (DOM.eventGetType(event) == Event.ONMOUSEDOWN && DOM.eventGetButton(event) == NativeEvent.BUTTON_RIGHT){
309
			if (DOM.eventGetCtrlKey(event))
310
				clickControl = true;
311
			else
312
				clickControl = false;
313
			if (DOM.eventGetShiftKey(event)) {
314
				clickShift = true;
315
				if (selectedRows.size() == 1)
316
					firstShift = selectedRows.get(0) - startIndex;
317
				//event.preventDefault();
318
			} else {
319
				clickShift = false;
320
				firstShift = -1;
321
				//event.preventDefault();
322
			}
323
			int ri = table.getRowForEvent2(event);
324
			if(ri != -1)
325
				if(!selectedRows.contains(ri-1))
326
					onRowClicked(ri, false);
327
		}
328

  
329
		if (files == null || files.size() == 0) {
330
			if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && selectedRows.size() == 0) {
331
				FileContextMenu fm = new FileContextMenu(images, false, true);
332
				fm.onEmptyEvent(event);
333
			}
334
			return;
335
		}
336
		if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && selectedRows.size() != 0) {
337
			FileContextMenu fm = new FileContextMenu(images, false, false);
338
			fm.onEvent(event);
339
		} else if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && selectedRows.size() == 0) {
340
			FileContextMenu fm = new FileContextMenu(images, false, true);
341
			fm.onEmptyEvent(event);
342
		} else if (DOM.eventGetType(event) == Event.ONDBLCLICK)
343
			if (getSelectedFiles().size() == 1) {
344
				GSS app = GSS.get();
345
				FileResource file = getSelectedFiles().get(0);
346
				String dateString = RestCommand.getDate();
347
				String resource = file.getUri().substring(app.getApiPath().length() - 1, file.getUri().length());
348
				String sig = app.getCurrentUserResource().getUsername() + " " +
349
						RestCommand.calculateSig("GET", dateString, resource,
350
						RestCommand.base64decode(app.getToken()));
351
				Window.open(file.getUri() + "?Authorization=" + URL.encodeComponent(sig) + "&Date=" + URL.encodeComponent(dateString), "_blank", "");
352
				event.preventDefault();
353
				return;
354
			}
355
		if (DOM.eventGetType(event) == Event.ONCLICK) {
356
			if (DOM.eventGetCtrlKey(event))
357
				clickControl = true;
358
			else
359
				clickControl = false;
360
			if (DOM.eventGetShiftKey(event)) {
361
				clickShift = true;
362
				if (selectedRows.size() == 1)
363
					firstShift = selectedRows.get(0) - startIndex;
364
				//event.preventDefault();
365
			} else {
366
				clickShift = false;
367
				firstShift = -1;
368
				//event.preventDefault();
369
			}
370
		}
371
		super.onBrowserEvent(event);
372
	}
373

  
374
	/**
375
	 * Retrieve the root folder for the current user.
376
	 *
377
	 * @return true if the retrieval was successful
378
	 */
379
	protected boolean fetchRootFolder() {
380
		UserResource user = GSS.get().getCurrentUserResource();
381
		if (user == null)
382
			return !DONE;
383
		// Update cache and clear selection.
384
		updateFileCache(true);
385
		return DONE;
386
	}
387

  
388
	private void onRowClicked(int row, boolean toggleSelection) {
389
		// Select the row that was clicked (-1 to account for header row).
390
		if (row > folderFileCount)
391
			return;
392
		if (clickShift) {
393
			GWT.log("Row is: " + row + " fs: " + firstShift, null);
394
			if (firstShift == -1)
395
				firstShift = row;
396
			else if (row > firstShift) {
397
				clearSelectedRows();
398
				for (int i = firstShift; i < row; i++) {
399
					selectedRows.add(startIndex + i);
400
					styleRow(i, true);
401
				}
402
				GSS.get().setCurrentSelection(getSelectedFiles());
403
				contextMenu.setFiles(getSelectedFiles());
404
				makeRowDraggable(row);
405
			} else if (row != -1 && row == firstShift) {
406
				selectedRows.add(row - 1);
407
				styleRow(row, true);
408
				styleRow(row - 1, true);
409
				GSS.get().setCurrentSelection(getSelectedFiles());
410
				contextMenu.setFiles(getSelectedFiles());
411
				makeRowDraggable(row);
412
			} else if (row < firstShift) {
413
				GWT.log("Row is:" + row + " fs:" + firstShift, null);
414
				clearSelectedRows();
415

  
416
				for (int i = firstShift; i >= row - 1; i--) {
417
					selectedRows.add(startIndex + i);
418
					styleRow(i, true);
419
				}
420
				GSS.get().setCurrentSelection(getSelectedFiles());
421
				makeRowDraggable(row);
422
				contextMenu.setFiles(getSelectedFiles());
423
			}
424
		} else if (row > 0)
425
			selectRow(row - 1, toggleSelection);
426
	}
427

  
428
	/**
429
	 * Initializes the table so that it contains enough rows for a full page of
430
	 * files.
431
	 */
432
	private void initTable() {
433
		nameLabel = new HTML("Name");
434
		nameLabel.addClickHandler(new ClickHandler() {
435

  
436
			@Override
437
			public void onClick(ClickEvent event) {
438
				sortFiles("name");
439

  
440
			}
441

  
442
		});
443
		versionLabel = new HTML("Version");
444
		versionLabel.addClickHandler(new ClickHandler() {
445

  
446
			@Override
447
			public void onClick(ClickEvent event) {
448
				sortFiles("version");
449
			}
450

  
451
		});
452
		sizeLabel = new HTML("Size");
453
		sizeLabel.addClickHandler(new ClickHandler() {
454

  
455
			@Override
456
			public void onClick(ClickEvent event) {
457
				sortFiles("size");
458
			}
459

  
460
		});
461
		dateLabel = new HTML("Last modified");
462
		dateLabel.addClickHandler(new ClickHandler() {
463

  
464
			@Override
465
			public void onClick(ClickEvent event) {
466
				sortFiles("date");
467
			}
468

  
469
		});
470
		ownerLabel = new HTML("Owner");
471
		ownerLabel.addClickHandler(new ClickHandler() {
472

  
473
			@Override
474
			public void onClick(ClickEvent event) {
475
				sortFiles("owner");
476
			}
477

  
478
		});
479
		pathLabel = new HTML("Path");
480
		pathLabel.addClickHandler(new ClickHandler() {
481

  
482
			@Override
483
			public void onClick(ClickEvent event) {
484
				sortFiles("path");
485
			}
486

  
487
		});
488
		// Create the header row.
489
		table.setText(0, 0, "");
490
		table.setWidget(0, 1, nameLabel);
491
		table.setWidget(0, 2, ownerLabel);
492
		table.setWidget(0, 3, pathLabel);
493
		table.setWidget(0, 4, versionLabel);
494
		table.setWidget(0, 5, sizeLabel);
495
		table.setWidget(0, 6, dateLabel);
496
		table.setWidget(0, 7, navBar);
497
		table.getRowFormatter().setStyleName(0, "gss-ListHeader");
498

  
499
		// Initialize the rest of the rows.
500
		for (int i = 1; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {
501
			table.setText(i, 0, "");
502
			table.setText(i, 1, "");
503
			table.setText(i, 2, "");
504
			table.setText(i, 3, "");
505
			table.setText(i, 4, "");
506
			table.setText(i, 5, "");
507
			table.setText(i, 6, "");
508
			table.setText(i, 7, "");
509
			table.getCellFormatter().setWordWrap(i, 0, false);
510
			table.getCellFormatter().setWordWrap(i, 1, false);
511
			table.getCellFormatter().setWordWrap(i, 2, false);
512
			table.getCellFormatter().setWordWrap(i, 3, false);
513
			table.getCellFormatter().setWordWrap(i, 4, false);
514
			table.getCellFormatter().setWordWrap(i, 5, false);
515
			table.getCellFormatter().setWordWrap(i, 6, false);
516
			table.getCellFormatter().setWordWrap(i, 7, false);
517
			table.getCellFormatter().setHorizontalAlignment(i, 4, HasHorizontalAlignment.ALIGN_CENTER);
518
		}
519
		prevButton.setVisible(false);
520
		nextButton.setVisible(false);
521
	}
522

  
523
	/**
524
	 * Selects the given row (relative to the current page).
525
	 *
526
	 * @param row the row to be selected
527
	 */
528
	private void selectRow(final int row, boolean toggleSelection) {
529
		if (row < folderFileCount) {
530
			if (clickControl)
531
				if (selectedRows.contains(row) && toggleSelection) {
532
					int i = selectedRows.indexOf(startIndex + row);
533
					selectedRows.remove(i);
534
					styleRow(row, false);
535
				} else {
536
					selectedRows.add(startIndex + row);
537
					styleRow(row, true);
538
				}
539
			else if (selectedRows.size() == 1 && selectedRows.contains(row) && toggleSelection){
540
				clearSelectedRows();
541
				return;
542
			}
543
			else {
544
				clearSelectedRows();
545
				selectedRows.add(startIndex + row);
546
				styleRow(row, true);
547
			}
548
			if (selectedRows.size() == 1)
549
				GSS.get().setCurrentSelection(files.get(selectedRows.get(0)));
550
			else if(selectedRows.size() == 0)
551
				GSS.get().setCurrentSelection(null);
552
			else
553
				GSS.get().setCurrentSelection(getSelectedFiles());
554
			contextMenu.setFiles(getSelectedFiles());
555
			makeRowDraggable(row+1);
556
		}
557
	}
558

  
559
	public List<FileResource> getSelectedFiles() {
560
		List<FileResource> result = new ArrayList();
561
		for (int i : selectedRows)
562
			result.add(files.get(i));
563
		return result;
564
	}
565

  
566
	/**
567
	 * Make the specified row look like selected or not, according to the
568
	 * <code>selected</code> flag.
569
	 *
570
	 * @param row
571
	 * @param selected
572
	 */
573
	void styleRow(final int row, final boolean selected) {
574
		if (row != -1 && row >= 0)
575
			if (selected)
576
				table.getRowFormatter().addStyleName(row + 1, "gss-SelectedRow");
577
			else
578
				table.getRowFormatter().removeStyleName(row + 1, "gss-SelectedRow");
579
	}
580

  
581
	/**
582
	 * Update the display of the file list.
583
	 */
584
	void update(boolean sort) {
585
		int count = folderFileCount;
586
		int max = startIndex + GSS.VISIBLE_FILE_COUNT;
587
		if (max > count)
588
			max = count;
589
		folderTotalSize = 0;
590

  
591
		if (sort && files != null && files.size() != 0) {
592
			clearLabels();
593
			clearSelectedRows();
594

  
595
			Collections.sort(files, new Comparator<FileResource>() {
596

  
597
				public int compare(FileResource arg0, FileResource arg1) {
598
					AbstractImagePrototype descPrototype = AbstractImagePrototype.create(images.desc());
599
					AbstractImagePrototype ascPrototype = AbstractImagePrototype.create(images.asc());
600
					if (sortingType)
601
						if (sortingProperty.equals("version")) {
602
							versionLabel.setHTML("Version&nbsp;" + descPrototype.getHTML());
603
							return arg0.getVersion().compareTo(arg1.getVersion());
604
						} else if (sortingProperty.equals("owner")) {
605
							ownerLabel.setHTML("Owner&nbsp;" + descPrototype.getHTML());
606
							return arg0.getOwner().compareTo(arg1.getOwner());
607
						} else if (sortingProperty.equals("date")) {
608
							dateLabel.setHTML("Date modified&nbsp;" + descPrototype.getHTML());
609
							return arg0.getModificationDate().compareTo(arg1.getModificationDate());
610
						} else if (sortingProperty.equals("size")) {
611
							sizeLabel.setHTML("Size&nbsp;" + descPrototype.getHTML());
612
							return arg0.getContentLength().compareTo(arg1.getContentLength());
613
						} else if (sortingProperty.equals("name")) {
614
							nameLabel.setHTML("Name&nbsp;" + descPrototype.getHTML());
615
							return arg0.getName().compareTo(arg1.getName());
616
						} else if (sortingProperty.equals("path")) {
617
							pathLabel.setHTML("Path&nbsp;" + descPrototype.getHTML());
618
							return arg0.getUri().compareTo(arg1.getUri());
619
						} else {
620
							nameLabel.setHTML("Name&nbsp;" + descPrototype.getHTML());
621
							return arg0.getName().compareTo(arg1.getName());
622
						}
623
					else if (sortingProperty.equals("version")) {
624
						versionLabel.setHTML("Version&nbsp;" + ascPrototype.getHTML());
625
						return arg1.getVersion().compareTo(arg0.getVersion());
626
					} else if (sortingProperty.equals("owner")) {
627
						ownerLabel.setHTML("Owner&nbsp;" + ascPrototype.getHTML());
628
						return arg1.getOwner().compareTo(arg0.getOwner());
629
					} else if (sortingProperty.equals("date")) {
630
						dateLabel.setHTML("Date modified&nbsp;" + ascPrototype.getHTML());
631
						return arg1.getModificationDate().compareTo(arg0.getModificationDate());
632
					} else if (sortingProperty.equals("size")) {
633
						sizeLabel.setHTML("Size&nbsp;" + ascPrototype.getHTML());
634
						return arg1.getContentLength().compareTo(arg0.getContentLength());
635
					} else if (sortingProperty.equals("name")) {
636
						nameLabel.setHTML("Name&nbsp;" + ascPrototype.getHTML());
637
						return arg1.getName().compareTo(arg0.getName());
638
					} else if (sortingProperty.equals("path")) {
639
						pathLabel.setHTML("Path&nbsp;" + ascPrototype.getHTML());
640
						return arg1.getUri().compareTo(arg0.getUri());
641
					} else {
642
						nameLabel.setHTML("Name&nbsp;" + ascPrototype.getHTML());
643
						return arg1.getName().compareTo(arg0.getName());
644
					}
645
				}
646

  
647
			});
648
		}
649

  
650

  
651
		// Show the selected files.
652
		int i = 1;
653
		for (; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {
654
			// Don't read past the end.
655
			// if (i > folderFileCount)
656
			// break;
657
			if (startIndex + i > folderFileCount)
658
				break;
659
			// Add a new row to the table, then set each of its columns to the
660
			// proper values.
661
			FileResource file = files.get(startIndex + i - 1);
662
			table.setWidget(i, 0, getFileIcon(file).createImage());
663
			table.getRowFormatter().addStyleName(i, "gss-fileRow");
664

  
665
			//add view image link for image files
666
			String contentType = file.getContentType();
667
			if (contentType.endsWith("png") || contentType.endsWith("gif") || contentType.endsWith("jpeg") )
668
				table.setHTML(i, 1, file.getName() + " <a href='" +
669
						GSS.get().getTopPanel().getFileMenu().getDownloadURL(file) +
670
						"' title='" + file.getName() + "' rel='lytebox[p]' " +
671
						"onclick='myLytebox.start(this, false, false)'>" +
672
						"(view)" + "</a>");
673
			else
674
				table.setHTML(i, 1, file.getName());
675
			table.setText(i, 2, file.getOwner());
676
			table.setText(i, 3, file.getPath());
677
			table.setText(i, 4, String.valueOf(file.getVersion()));
678
			table.setText(i, 5, String.valueOf(file.getFileSizeAsString()));
679
			final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");
680
			table.setText(i, 6, formatter.format(file.getModificationDate()));
681
			folderTotalSize += file.getContentLength();
682
		}
683

  
684
		// Clear any remaining slots.
685
		for (; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {
686
			table.setHTML(i, 0, "&nbsp;");
687
			table.setHTML(i, 1, "&nbsp;");
688
			table.setHTML(i, 2, "&nbsp;");
689
			table.setHTML(i, 3, "&nbsp;");
690
			table.setHTML(i, 4, "&nbsp;");
691
			table.setHTML(i, 5, "&nbsp;");
692
			table.setHTML(i, 6, "&nbsp;");
693
			table.setHTML(i, 7, "&nbsp;");
694
		}
695

  
696
		if (folderFileCount == 0) {
697
			showingStats = "no files";
698
			prevButton.setVisible(false);
699
			nextButton.setVisible(false);
700
		} else if (folderFileCount < GSS.VISIBLE_FILE_COUNT) {
701
			if (folderFileCount == 1)
702
				showingStats = "1 file";
703
			else
704
				showingStats = folderFileCount + " files";
705
			showingStats += " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
706
			prevButton.setVisible(false);
707
			nextButton.setVisible(false);
708
		} else {
709
			showingStats = "" + (startIndex + 1) + " - " + max + " of " + count + " files" + " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
710
			prevButton.setVisible(startIndex != 0);
711
			nextButton.setVisible(startIndex + GSS.VISIBLE_FILE_COUNT < count);
712
		}
713
		updateCurrentlyShowingStats();
714

  
715
	}
716

  
717
	/**
718
	 * Return the proper icon based on the MIME type of the file.
719
	 *
720
	 * @param file
721
	 * @return the icon
722
	 */
723
	private AbstractImagePrototype getFileIcon(FileResource file) {
724
		String mimetype = file.getContentType();
725
		boolean shared=false;
726
		Folders folders = GSS.get().getFolders();
727
		if(folders.getCurrent() != null && folders.isOthersSharedItem(folders.getCurrent())){
728
			DnDTreeItem otherUser = (DnDTreeItem) folders.getUserOfSharedItem(folders.getCurrent());
729
			if(otherUser==null)
730
				shared = false;
731
			else{
732
				String uname = otherUser.getOtherUserResource().getUsername();
733
				if(uname==null)
734
					uname = ((DnDTreeItem)folders.getSharesItem()).getOthersResource().getUsernameOfUri(otherUser.getOtherUserResource().getUri());
735
				if(uname != null)
736
					shared = file.isShared();
737
			}
738
		}
739
		else
740
			shared = file.isShared();
741
		if (mimetype == null)
742
			return shared ? AbstractImagePrototype.create(images.documentShared()) : AbstractImagePrototype.create(images.document());
743
		mimetype = mimetype.toLowerCase();
744
		if (mimetype.startsWith("application/pdf"))
745
			return shared ? AbstractImagePrototype.create(images.pdfShared()) : AbstractImagePrototype.create(images.pdf());
746
		else if (mimetype.endsWith("excel"))
747
			return shared ? AbstractImagePrototype.create(images.spreadsheetShared()) : AbstractImagePrototype.create(images.spreadsheet());
748
		else if (mimetype.endsWith("msword"))
749
			return shared ? AbstractImagePrototype.create(images.wordprocessorShared()) : AbstractImagePrototype.create(images.wordprocessor());
750
		else if (mimetype.endsWith("powerpoint"))
751
			return shared ? AbstractImagePrototype.create(images.presentationShared()) : AbstractImagePrototype.create(images.presentation());
752
		else if (mimetype.startsWith("application/zip") ||
753
					mimetype.startsWith("application/gzip") ||
754
					mimetype.startsWith("application/x-gzip") ||
755
					mimetype.startsWith("application/x-tar") ||
756
					mimetype.startsWith("application/x-gtar"))
757
			return shared ? AbstractImagePrototype.create(images.zipShared()) : AbstractImagePrototype.create(images.zip());
758
		else if (mimetype.startsWith("text/html"))
759
			return shared ? AbstractImagePrototype.create(images.htmlShared()) : AbstractImagePrototype.create(images.html());
760
		else if (mimetype.startsWith("text/plain"))
761
			return shared ? AbstractImagePrototype.create(images.txtShared()) : AbstractImagePrototype.create(images.txt());
762
		else if (mimetype.startsWith("image/"))
763
			return shared ? AbstractImagePrototype.create(images.imageShared()) : AbstractImagePrototype.create(images.image());
764
		else if (mimetype.startsWith("video/"))
765
			return shared ? AbstractImagePrototype.create(images.videoShared()) : AbstractImagePrototype.create(images.video());
766
		else if (mimetype.startsWith("audio/"))
767
			return shared ? AbstractImagePrototype.create(images.audioShared()) : AbstractImagePrototype.create(images.audio());
768
		return shared ? AbstractImagePrototype.create(images.documentShared()) : AbstractImagePrototype.create(images.document());
769
	}
770

  
771
	/**
772
	 * Update status panel with currently showing file stats.
773
	 */
774
	public void updateCurrentlyShowingStats() {
775
		GSS.get().getStatusPanel().updateCurrentlyShowing(showingStats);
776
	}
777

  
778
	/**
779
	 * Adjust the height of the table by adding and removing rows as necessary.
780
	 *
781
	 * @param newHeight the new height to reach
782
	 */
783
	void resizeTableHeight(final int newHeight) {
784
		GWT.log("Panel: " + newHeight + ", parent: " + table.getParent().getOffsetHeight(), null);
785
		// Fill the rest with empty slots.
786
		if (newHeight > table.getOffsetHeight())
787
			while (newHeight > table.getOffsetHeight()) {
788
				table.resizeRows(table.getRowCount() + 1);
789
				GWT.log("Table: " + table.getOffsetHeight() + ", rows: " + table.getRowCount(), null);
790
			}
791
		else
792
			while (newHeight < table.getOffsetHeight()) {
793
				table.resizeRows(table.getRowCount() - 1);
794
				GWT.log("Table: " + table.getOffsetHeight() + ", rows: " + table.getRowCount(), null);
795
			}
796
	}
797

  
798
	public void updateFileCache(boolean updateSelectedFolder, final boolean clearSelection) {
799
		updateFileCache(updateSelectedFolder, clearSelection, null);
800
	}
801

  
802
	public void updateFileCache(boolean updateSelectedFolder, final boolean clearSelection, final String newFilename) {
803
		if (!updateSelectedFolder && !GSS.get().getFolders().getTrashItem().equals(GSS.get().getFolders().getCurrent()))
804
			updateFileCache(clearSelection);
805
		else if (GSS.get().getFolders().getCurrent() != null) {
806
			final DnDTreeItem folderItem = (DnDTreeItem) GSS.get().getFolders().getCurrent();
807
			if( folderItem.getFolderResource()!= null){
808
				if(GSS.get().getFolders().isFileItem(folderItem) || GSS.get().getFolders().isMySharedItem(folderItem)  || GSS.get().getFolders().isOthersSharedItem(folderItem) ){
809
					update(true);
810
					GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, folderItem.getFolderResource().getUri(),folderItem.getFolderResource()) {
811

  
812
							@Override
813
							public void onComplete() {
814
								folderItem.setUserObject(getResult());
815
								if(GSS.get().getFolders().isFileItem(folderItem)){
816
									String[] filePaths = new String[folderItem.getFolderResource().getFilePaths().size()];
817
									int c=0;
818
									for(String fpath : folderItem.getFolderResource().getFilePaths()){
819
										filePaths[c] = fpath + "?" + Math.random();
820
										c++;
821
									}
822
									MultipleHeadCommand<FileResource> getFiles = new MultipleHeadCommand<FileResource>(FileResource.class, filePaths, folderItem.getFolderResource().getFileCache()){
823

  
824
										@Override
825
										public void onComplete(){
826
											List<FileResource> result = getResult();
827
											//remove random from path
828
											for(FileResource r : result){
829
												String p = r.getUri();
830
												int indexOfQuestionMark = p.lastIndexOf('?');
831
												if(indexOfQuestionMark>0)
832
													r.setUri(p.substring(0, indexOfQuestionMark));
833
												GWT.log("FETCHED:"+r.getLastModifiedSince(), null);
834
											}
835
											folderItem.getFolderResource().setFiles(result);
836
											folderItem.getFolderResource().setFilesExpanded(true);
837
											updateFileCache(clearSelection, newFilename);
838
										}
839

  
840
										@Override
841
										public void onError(String p, Throwable throwable) {
842
											if(throwable instanceof RestException)
843
												GSS.get().displayError("Unable to retrieve file details:"+((RestException)throwable).getHttpStatusText());
844
										}
845

  
846
										@Override
847
										public void onError(Throwable t) {
848
											GWT.log("", t);
849
											GSS.get().displayError("Unable to fetch files for folder " + folderItem.getFolderResource().getName());
850
										}
851

  
852
									};
853
									DeferredCommand.addCommand(getFiles);
854
								}
855
								else
856
									updateFileCache(clearSelection, newFilename);
857
							}
858

  
859
							@Override
860
							public void onError(Throwable t) {
861
								GWT.log("", t);
862
								GSS.get().displayError("Unable to fetch folder " + folderItem.getFolderResource().getName());
863
							}
864
						};
865
						DeferredCommand.addCommand(gf);
866
				}
867
			}
868
			else if (folderItem.getTrashResource() != null) {
869
				GetCommand<TrashResource> gt = new GetCommand<TrashResource>(TrashResource.class, folderItem.getTrashResource().getUri(), null) {
870

  
871
					@Override
872
					public void onComplete() {
873
						folderItem.setUserObject(getResult());
874
						updateFileCache(clearSelection);
875
					}
876

  
877
					@Override
878
					public void onError(Throwable t) {
879
						if (t instanceof RestException && (((RestException) t).getHttpStatusCode() == 204 || ((RestException) t).getHttpStatusCode() == 1223)) {
880
							folderItem.setUserObject(new TrashResource(folderItem.getTrashResource().getUri()));
881
							updateFileCache(clearSelection);
882
						} else {
883
							GWT.log("", t);
884
							GSS.get().displayError("Unable to fetch trash resource");
885
						}
886
					}
887
				};
888
				DeferredCommand.addCommand(gt);
889
			} else if (folderItem.getSharedResource() != null) {
890
				GetCommand<SharedResource> gt = new GetCommand<SharedResource>(SharedResource.class, folderItem.getSharedResource().getUri(), null) {
891

  
892
					@Override
893
					public void onComplete() {
894
						folderItem.setUserObject(getResult());
895
						updateFileCache(clearSelection, newFilename);
896
						String[] filePaths = new String[folderItem.getSharedResource().getFilePaths().size()];
897
						int c=0;
898
						for(String fpath : folderItem.getSharedResource().getFilePaths()){
899
							filePaths[c] = fpath + "?" + Math.random();
900
							c++;
901
						}
902
						MultipleHeadCommand<FileResource> getFiles = new MultipleHeadCommand<FileResource>(FileResource.class, filePaths, folderItem.getSharedResource().getFileCache()){
903

  
904
							@Override
905
							public void onComplete(){
906
								List<FileResource> result = getResult();
907
								//remove random from path
908
								for(FileResource r : result){
909
									String p = r.getUri();
910
									int indexOfQuestionMark = p.lastIndexOf('?');
911
									if(indexOfQuestionMark>0)
912
										r.setUri(p.substring(0, indexOfQuestionMark));
913
									GWT.log("FETCHED:"+r.getLastModifiedSince(), null);
914
								}
915
								folderItem.getSharedResource().setFiles(result);
916
								folderItem.getSharedResource().setFilesExpanded(true);
917
								updateFileCache(clearSelection, newFilename);
918
							}
919

  
920
							@Override
921
							public void onError(String p, Throwable throwable) {
922
								if(throwable instanceof RestException)
923
									GSS.get().displayError("Unable to retrieve file details:"+((RestException)throwable).getHttpStatusText());
924
							}
925

  
926
							@Override
927
							public void onError(Throwable t) {
928
								GWT.log("", t);
929
								GSS.get().displayError("Unable to fetch files for folder " + folderItem.getFolderResource().getName());
930
							}
931

  
932
						};
933
						DeferredCommand.addCommand(getFiles);
934
					}
935

  
936
					@Override
937
					public void onError(Throwable t) {
938
						GWT.log("", t);
939
						GSS.get().displayError("Unable to fetch My Shares resource");
940
					}
941
				};
942
				DeferredCommand.addCommand(gt);
943
			} else if (folderItem.getOtherUserResource() != null) {
944
				GetCommand<OtherUserResource> gt = new GetCommand<OtherUserResource>(OtherUserResource.class, folderItem.getOtherUserResource().getUri(), null) {
945

  
946
					@Override
947
					public void onComplete() {
948
						folderItem.setUserObject(getResult());
949
						updateFileCache(clearSelection, newFilename);
950
						String[] filePaths = new String[folderItem.getOtherUserResource().getFilePaths().size()];
951
						int c=0;
952
						for(String fpath : folderItem.getOtherUserResource().getFilePaths()){
953
							filePaths[c] = fpath + "?" + Math.random();
954
							c++;
955
						}
956
						MultipleHeadCommand<FileResource> getFiles = new MultipleHeadCommand<FileResource>(FileResource.class, filePaths, folderItem.getOtherUserResource().getFileCache()){
957

  
958
							@Override
959
							public void onComplete(){
960
								List<FileResource> result = getResult();
961
								//remove random from path
962
								for(FileResource r : result){
963
									String p = r.getUri();
964
									int indexOfQuestionMark = p.lastIndexOf('?');
965
									if(indexOfQuestionMark>0)
966
										r.setUri(p.substring(0, indexOfQuestionMark));
967
									GWT.log("FETCHED:"+r.getLastModifiedSince(), null);
968
								}
969
								folderItem.getOtherUserResource().setFiles(result);
970
								folderItem.getOtherUserResource().setFilesExpanded(true);
971
								updateFileCache(clearSelection, newFilename);
972
							}
973

  
974
							@Override
975
							public void onError(String p, Throwable throwable) {
976
								if(throwable instanceof RestException)
977
									GSS.get().displayError("Unable to retrieve file details:"+((RestException)throwable).getHttpStatusText());
978
							}
979

  
980
							@Override
981
							public void onError(Throwable t) {
982
								GWT.log("", t);
983
								GSS.get().displayError("Unable to fetch files for folder " + folderItem.getFolderResource().getName());
984
							}
985

  
986
						};
987
						DeferredCommand.addCommand(getFiles);
988
					}
989

  
990
					@Override
991
					public void onError(Throwable t) {
992
						GWT.log("", t);
993
						GSS.get().displayError("Unable to fetch My Shares resource");
994
					}
995
				};
996
				DeferredCommand.addCommand(gt);
997
			}
998
		} else
999
			updateFileCache(clearSelection);
1000
	}
1001

  
1002
	private void updateFileCache(boolean clearSelection) {
1003
		updateFileCache(clearSelection, null);
1004
	}
1005

  
1006
	/**
1007
	 * Update the file cache with data from the server.
1008
	 *
1009
	 * @param userId the ID of the current user
1010
	 * @param newFilename the new name of the previously selected file,
1011
	 * 			if a rename operation has taken place
1012
	 */
1013
	private void updateFileCache(boolean clearSelection, String newFilename) {
1014
		if (clearSelection)
1015
			clearSelectedRows();
1016
		clearLabels();
1017
		startIndex = 0;
1018
		final TreeItem folderItem = GSS.get().getFolders().getCurrent();
1019
		// Validation.
1020
		if (folderItem == null || GSS.get().getFolders().isOthersShared(folderItem)) {
1021
			setFiles(new ArrayList<FileResource>());
1022
			update(true);
1023
			return;
1024
		}
1025
		if (folderItem instanceof DnDTreeItem) {
1026
			DnDTreeItem dnd = (DnDTreeItem) folderItem;
1027
			if (dnd.getFolderResource() != null) {
1028
				if (GSS.get().getFolders().isTrashItem(dnd))
1029
					setFiles(new ArrayList<FileResource>());
1030
				else
1031
					setFiles(dnd.getFolderResource().getFiles());
1032

  
1033
			} else if (dnd.getTrashResource() != null)
1034
				setFiles(dnd.getTrashResource().getFiles());
1035
			else if (dnd.getSharedResource() != null)
1036
				setFiles(dnd.getSharedResource().getFiles());
1037
			else if (dnd.getOtherUserResource() != null)
1038
				setFiles(dnd.getOtherUserResource().getFiles());
1039
			else
1040
				setFiles(dnd.getFolderResource().getFiles());
1041
			update(true);
1042

  
1043
			if (!clearSelection && selectedRows.size()==1 && newFilename!=null) {
1044
				int row = -1;
1045
				for (int i=1; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {
1046
					if (startIndex + i > folderFileCount)
1047
						break;
1048
					FileResource file = files.get(startIndex + i - 1);
1049
					if (newFilename.equals(file.getName())) {
1050
						row = i-1;
1051
						break;
1052
					}
1053
				}
1054
				clearSelectedRows();
1055
				if (row!=-1)
1056
					selectRow(row, true);
1057
			}
1058
		}
1059
	}
1060

  
1061
	/**
1062
	 * Fill the file cache with data.
1063
	 */
1064
	public void setFiles(final List<FileResource> _files) {
1065
		if (_files.size() > 0 && !GSS.get().getFolders().isTrash(GSS.get().getFolders().getCurrent())) {
1066
			files = new ArrayList<FileResource>();
1067
			for (FileResource fres : _files)
1068
				if (!fres.isDeleted())
1069
					files.add(fres);
1070
		} else
1071
			files = _files;
1072
		Collections.sort(files, new Comparator<FileResource>() {
1073

  
1074
			public int compare(FileResource arg0, FileResource arg1) {
1075
				return arg0.getName().compareTo(arg1.getName());
1076
			}
1077

  
1078
		});
1079
		folderFileCount = files.size();
1080
	}
1081

  
1082
	private void sortFiles(final String sortProperty) {
1083
		if (sortProperty.equals(sortingProperty))
1084
			sortingType = !sortingType;
1085
		else {
1086
			sortingProperty = sortProperty;
1087
			sortingType = true;
1088
		}
1089
		update(true);
1090
	}
1091

  
1092
	private void clearLabels() {
1093
		nameLabel.setText("Name");
1094
		versionLabel.setText("Version");
1095
		sizeLabel.setText("Size");
1096
		dateLabel.setText("Last modified");
1097
		ownerLabel.setText("Owner");
1098
		pathLabel.setText("Path");
1099
	}
1100

  
1101
	/**
1102
	 * Retrieve the table.
1103
	 *
1104
	 * @return the table
1105
	 */
1106
	Grid getTable() {
1107
		return table;
1108
	}
1109

  
1110
	/**
1111
	 * Does the list contains the requested filename
1112
	 *
1113
	 * @param fileName
1114
	 * @return true/false
1115
	 */
1116
	public boolean contains(String fileName) {
1117
		for (int i = 0; i < files.size(); i++)
1118
			if (files.get(i).getName().equals(fileName))
1119
				return true;
1120
		return false;
1121
	}
1122

  
1123
	public void clearSelectedRows() {
1124
		for (int r : selectedRows) {
1125
			int row = r - startIndex;
1126
			styleRow(row, false);
1127
		}
1128
		selectedRows.clear();
1129
		Object sel = GSS.get().getCurrentSelection();
1130
		if (sel instanceof FileResource || sel instanceof List)
1131
			GSS.get().setCurrentSelection(null);
1132
	}
1133

  
1134
	/**
1135
	 *
1136
	 */
1137
	public void selectAllRows() {
1138
		clearSelectedRows();
1139
		int count = folderFileCount;
1140
		if (count == 0)
1141
			return;
1142
		int max = startIndex + GSS.VISIBLE_FILE_COUNT;
1143
		if (max > count)
1144
			max = count;
1145
		int i = 1;
1146
		for (; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {
1147
			// Don't read past the end.
1148
			// if (i > folderFileCount)
1149
			// break;
1150
			if (startIndex + i > folderFileCount)
1151
				break;
1152
			selectedRows.add(startIndex + i - 1);
1153
			styleRow(i - 1, true);
1154
		}
1155
		GSS.get().setCurrentSelection(getSelectedFiles());
1156
		contextMenu.setFiles(getSelectedFiles());
1157
		makeRowDraggable(i-1);
1158

  
1159
	}
1160

  
1161
	private void makeRowDraggable(int row){
1162
		int contextRow = getWidgetRow(contextMenu, table);
1163
		if (contextRow != -1)
1164
			table.setWidget(contextRow, 0, getFileIcon(files.get(contextRow - 1)).createImage());
1165
		contextMenu.setWidget(new HTML(getFileIcon(files.get(row - 1)).getHTML()));
1166
		table.setWidget(row, 0, contextMenu);
1167
	}
1168

  
1169
	private int getWidgetRow(Widget widget, Grid grid) {
1170
		for (int row = 0; row < grid.getRowCount(); row++)
1171
			for (int col = 0; col < grid.getCellCount(row); col++) {
1172
				Widget w = table.getWidget(row, col);
1173
				if (w == widget)
1174
					return row;
1175
			}
1176
		return -1;
1177
	}
1178

  
1179

  
1180

  
1181
}
1
/*
2
 * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
3
 *
4
 * This file is part of GSS.
5
 *
6
 * GSS is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * GSS is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
package gr.ebs.gss.client;
20

  
21
import gr.ebs.gss.client.dnd.DnDSimpleFocusPanel;
22
import gr.ebs.gss.client.dnd.DnDTreeItem;
23
import gr.ebs.gss.client.rest.GetCommand;
24
import gr.ebs.gss.client.rest.MultipleHeadCommand;
25
import gr.ebs.gss.client.rest.RestCommand;
26
import gr.ebs.gss.client.rest.RestException;
27
import gr.ebs.gss.client.rest.resource.FileResource;
28
import gr.ebs.gss.client.rest.resource.FolderResource;
29
import gr.ebs.gss.client.rest.resource.OtherUserResource;
30
import gr.ebs.gss.client.rest.resource.SharedResource;
31
import gr.ebs.gss.client.rest.resource.TrashResource;
32
import gr.ebs.gss.client.rest.resource.UserResource;
33

  
34
import java.util.ArrayList;
35
import java.util.Collections;
36
import java.util.Comparator;
37
import java.util.List;
38

  
39
import com.google.gwt.core.client.GWT;
40
import com.google.gwt.dom.client.NativeEvent;
41
import com.google.gwt.event.dom.client.ClickEvent;
42
import com.google.gwt.event.dom.client.ClickHandler;
43
import com.google.gwt.http.client.URL;
44
import com.google.gwt.i18n.client.DateTimeFormat;
45
import com.google.gwt.resources.client.ClientBundle;
46
import com.google.gwt.resources.client.ImageResource;
47
import com.google.gwt.user.client.DOM;
48
import com.google.gwt.user.client.DeferredCommand;
49
import com.google.gwt.user.client.Event;
50
import com.google.gwt.user.client.IncrementalCommand;
51
import com.google.gwt.user.client.Window;
52
import com.google.gwt.user.client.ui.AbstractImagePrototype;
53
import com.google.gwt.user.client.ui.Composite;
54
import com.google.gwt.user.client.ui.Grid;
55
import com.google.gwt.user.client.ui.HTML;
56
import com.google.gwt.user.client.ui.HTMLTable.Cell;
57
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
58
import com.google.gwt.user.client.ui.HorizontalPanel;
59
import com.google.gwt.user.client.ui.TreeItem;
60
import com.google.gwt.user.client.ui.Widget;
61

  
62
/**
63
 * A composite that displays the list of files in a particular folder.
64
 */
65
public class FileList extends Composite implements ClickHandler {
66

  
67
	private HTML prevButton = new HTML("<a href='javascript:;'>&lt; Previous</a>", true);
68

  
69
	private HTML nextButton = new HTML("<a href='javascript:;'>Next &gt;</a>", true);
70

  
71
	private String showingStats = "";
72

  
73
	private int startIndex = 0;
74

  
75
	/**
76
	 * A constant that denotes the completion of an IncrementalCommand.
77
	 */
78
	public static final boolean DONE = false;
79

  
80
	private boolean clickControl = false;
81

  
82
	private boolean clickShift = false;
83

  
84
	private int firstShift = -1;
85

  
86
	private ArrayList<Integer> selectedRows = new ArrayList<Integer>();
87

  
88
	/**
89
	 * The context menu for the selected file.
90
	 */
91
	final DnDSimpleFocusPanel contextMenu;
92

  
93
	/**
94
	 * Specifies that the images available for this composite will be the ones
95
	 * available in FileContextMenu.
96
	 */
97
	public interface Images extends ClientBundle,FileContextMenu.Images, Folders.Images {
98

  
99
		@Source("gr/ebs/gss/resources/blank.gif")
100
		ImageResource blank();
101

  
102
		@Source("gr/ebs/gss/resources/asc.png")
103
		ImageResource asc();
104

  
105
		@Source("gr/ebs/gss/resources/desc.png")
106
		ImageResource desc();
107

  
108
		@Source("gr/ebs/gss/resources/mimetypes/document_shared.png")
109
		ImageResource documentShared();
110

  
111
		@Source("gr/ebs/gss/resources/mimetypes/kcmfontinst.png")
112
		ImageResource wordprocessor();
113

  
114
		@Source("gr/ebs/gss/resources/mimetypes/log.png")
115
		ImageResource spreadsheet();
116

  
117
		@Source("gr/ebs/gss/resources/mimetypes/kpresenter_kpr.png")
118
		ImageResource presentation();
119

  
120
		@Source("gr/ebs/gss/resources/mimetypes/acroread.png")
121
		ImageResource pdf();
122

  
123
		@Source("gr/ebs/gss/resources/mimetypes/image.png")
124
		ImageResource image();
125

  
126
		@Source("gr/ebs/gss/resources/mimetypes/video2.png")
127
		ImageResource video();
128

  
129
		@Source("gr/ebs/gss/resources/mimetypes/knotify.png")
130
		ImageResource audio();
131

  
132
		@Source("gr/ebs/gss/resources/mimetypes/html.png")
133
		ImageResource html();
134

  
135
		@Source("gr/ebs/gss/resources/mimetypes/txt.png")
136
		ImageResource txt();
137

  
138
		@Source("gr/ebs/gss/resources/mimetypes/ark2.png")
139
		ImageResource zip();
140

  
141
		@Source("gr/ebs/gss/resources/mimetypes/kcmfontinst_shared.png")
142
		ImageResource wordprocessorShared();
143

  
144
		@Source("gr/ebs/gss/resources/mimetypes/log_shared.png")
145
		ImageResource spreadsheetShared();
146

  
147
		@Source("gr/ebs/gss/resources/mimetypes/kpresenter_kpr_shared.png")
148
		ImageResource presentationShared();
149

  
150
		@Source("gr/ebs/gss/resources/mimetypes/acroread_shared.png")
151
		ImageResource pdfShared();
152

  
153
		@Source("gr/ebs/gss/resources/mimetypes/image_shared.png")
154
		ImageResource imageShared();
155

  
156
		@Source("gr/ebs/gss/resources/mimetypes/video2_shared.png")
157
		ImageResource videoShared();
158

  
159
		@Source("gr/ebs/gss/resources/mimetypes/knotify_shared.png")
160
		ImageResource audioShared();
161

  
162
		@Source("gr/ebs/gss/resources/mimetypes/html_shared.png")
163
		ImageResource htmlShared();
164

  
165
		@Source("gr/ebs/gss/resources/mimetypes/txt_shared.png")
166
		ImageResource txtShared();
167

  
168
		@Source("gr/ebs/gss/resources/mimetypes/ark2_shared.png")
169
		ImageResource zipShared();
170

  
171
	}
172

  
173
	/**
174
	 * A label with the number of files in this folder.
175
	 */
176
	private HTML countLabel = new HTML();
177

  
178
	/**
179
	 * The table widget with the file list.
180
	 */
181
	private FileTable table = new FileTable(GSS.VISIBLE_FILE_COUNT + 1, 8);
182

  
183
	/**
184
	 * The navigation bar for paginating the results.
185
	 */
186
	private HorizontalPanel navBar = new HorizontalPanel();
187

  
188
	/**
189
	 * The number of files in this folder.
190
	 */
191
	int folderFileCount;
192

  
193
	/**
194
	 * Total folder size
195
	 */
196
	long folderTotalSize;
197

  
198
	/**
199
	 * A cache of the files in the list.
200
	 */
201
	private List<FileResource> files;
202

  
203
	/**
204
	 * The widget's image bundle.
205
	 */
206
	private final Images images;
207

  
208
	private String sortingProperty = "name";
209

  
210
	private boolean sortingType = true;
211

  
212
	private HTML nameLabel;
213

  
214
	private HTML versionLabel;
215

  
216
	private HTML sizeLabel;
217

  
218
	private HTML dateLabel;
219

  
220
	private HTML ownerLabel;
221

  
222
	private HTML pathLabel;
223

  
224
	/**
225
	 * Construct the file list widget. This entails setting up the widget
226
	 * layout, fetching the number of files in the current folder from the
227
	 * server and filling the local file cache of displayed files with data from
228
	 * the server, as well.
229
	 *
230
	 * @param _images
231
	 */
232
	public FileList(Images _images) {
233
		images = _images;
234

  
235
		prevButton.addClickHandler(this);
236
		nextButton.addClickHandler(this);
237

  
238
		contextMenu = new DnDSimpleFocusPanel(new HTML(AbstractImagePrototype.create(images.fileContextMenu()).getHTML()));
239
		GSS.get().getDragController().makeDraggable(contextMenu);
240

  
241
		// Setup the table.
242
		table.setCellSpacing(0);
243
		table.setCellPadding(2);
244
		table.setWidth("100%");
245
		table.addClickHandler(new ClickHandler() {
246

  
247
			@Override
248
			public void onClick(ClickEvent event) {
249
				Cell cell = table.getCellForEvent(event);
250
				GWT.log("row clicked:"+cell.getRowIndex(), null);
251
				onRowClicked(cell.getRowIndex(), true);
252
			}
253
		});
254
		// Create the 'navigation' bar at the upper-right.
255
		HorizontalPanel innerNavBar = new HorizontalPanel();
256
		innerNavBar.setStyleName("gss-ListNavBar");
257
		innerNavBar.setSpacing(8);
258
		innerNavBar.add(prevButton);
259
		innerNavBar.add(countLabel);
260
		innerNavBar.add(nextButton);
261
		navBar.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
262
		navBar.add(innerNavBar);
263
		navBar.setWidth("100%");
264

  
265
		initWidget(table);
266
		setStyleName("gss-List");
267

  
268
		initTable();
269
		DeferredCommand.addCommand(new IncrementalCommand() {
270

  
271
			@Override
272
			public boolean execute() {
273
				return fetchRootFolder();
274
			}
275
		});
276
		sinkEvents(Event.ONCONTEXTMENU);
277
		sinkEvents(Event.ONMOUSEUP);
278
		sinkEvents(Event.ONMOUSEDOWN);
279
		sinkEvents(Event.ONCLICK);
280
		sinkEvents(Event.ONKEYDOWN);
281
		sinkEvents(Event.ONDBLCLICK);
282
		GSS.preventIESelection();
283
	}
284

  
285
	@Override
286
	public void onClick(ClickEvent event) {
287
		 if(event.getSource() == nextButton){
288
			// Move forward a page.
289
			clearSelectedRows();
290
			startIndex += GSS.VISIBLE_FILE_COUNT;
291
			if (startIndex >= folderFileCount)
292
				startIndex -= GSS.VISIBLE_FILE_COUNT;
293
			else
294
				update(false);
295
		} else if (event.getSource() == prevButton) {
296
			clearSelectedRows();
297
			// Move back a page.
298
			startIndex -= GSS.VISIBLE_FILE_COUNT;
299
			if (startIndex < 0)
300
				startIndex = 0;
301
			else
302
				update(false);
303
		}
304
	}
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff