Statistics
| Branch: | Tag: | Revision:

root / src / gr / ebs / gss / client / FileList.java @ 16b54aa8

History | View | Annotate | Download (35.4 kB)

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
import gr.ebs.gss.client.commands.GetUserCommand;
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
                        @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
        }
305

    
306

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

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

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

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

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

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

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

    
441
                        }
442

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
649
                        });
650
                }
651

    
652

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

    
667
                        //add view image link for image files
668
                        String contentType = file.getContentType();
669
                        if (contentType.endsWith("png") || contentType.endsWith("gif") || contentType.endsWith("jpeg") )
670
                                table.setHTML(i, 1, file.getName() + " <a href='" +
671
                                                GSS.get().getTopPanel().getFileMenu().getDownloadURL(file) +
672
                                                "' title='" + file.getName() + "' rel='lytebox[p]' " +
673
                                                "onclick='myLytebox.start(this, false, false);return false;'>" +
674
                                                "(view)" + "</a>");
675
                        else
676
                                table.setHTML(i, 1, file.getName());
677

    
678
                        if(GSS.get().findUserFullName(file.getOwner()) == null){
679
                                GetUserCommand guc = new GetUserCommand(file.getOwner());
680
                                guc.execute();
681
                                GSS.get().putUserToMap(file.getOwner(), file.getOwner());
682
                        }
683
                        table.setText(i, 2, GSS.get().getUserFullName(file.getOwner()));
684
                        table.setText(i, 3, file.getPath());
685
                        table.setText(i, 4, String.valueOf(file.getVersion()));
686
                        table.setText(i, 5, String.valueOf(file.getFileSizeAsString()));
687
                        final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");
688
                        table.setText(i, 6, formatter.format(file.getModificationDate()));
689
                        folderTotalSize += file.getContentLength();
690
                }
691

    
692
                // Clear any remaining slots.
693
                for (; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {
694
                        table.setHTML(i, 0, "&nbsp;");
695
                        table.setHTML(i, 1, "&nbsp;");
696
                        table.setHTML(i, 2, "&nbsp;");
697
                        table.setHTML(i, 3, "&nbsp;");
698
                        table.setHTML(i, 4, "&nbsp;");
699
                        table.setHTML(i, 5, "&nbsp;");
700
                        table.setHTML(i, 6, "&nbsp;");
701
                        table.setHTML(i, 7, "&nbsp;");
702
                }
703

    
704
                if (folderFileCount == 0) {
705
                        showingStats = "no files";
706
                        prevButton.setVisible(false);
707
                        nextButton.setVisible(false);
708
                } else if (folderFileCount < GSS.VISIBLE_FILE_COUNT) {
709
                        if (folderFileCount == 1)
710
                                showingStats = "1 file";
711
                        else
712
                                showingStats = folderFileCount + " files";
713
                        showingStats += " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
714
                        prevButton.setVisible(false);
715
                        nextButton.setVisible(false);
716
                } else {
717
                        showingStats = "" + (startIndex + 1) + " - " + max + " of " + count + " files" + " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
718
                        prevButton.setVisible(startIndex != 0);
719
                        nextButton.setVisible(startIndex + GSS.VISIBLE_FILE_COUNT < count);
720
                }
721
                updateCurrentlyShowingStats();
722

    
723
        }
724

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

    
779
        /**
780
         * Update status panel with currently showing file stats.
781
         */
782
        public void updateCurrentlyShowingStats() {
783
                GSS.get().getStatusPanel().updateCurrentlyShowing(showingStats);
784
        }
785

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

    
806
        public void updateFileCache(boolean updateSelectedFolder, final boolean clearSelection) {
807
                updateFileCache(updateSelectedFolder, clearSelection, null);
808
        }
809

    
810
        public void updateFileCache(boolean updateSelectedFolder, final boolean clearSelection, final String newFilename) {
811
                if (!updateSelectedFolder && !GSS.get().getFolders().getTrashItem().equals(GSS.get().getFolders().getCurrent()))
812
                        updateFileCache(clearSelection);
813
                else if (GSS.get().getFolders().getCurrent() != null) {
814
                        final DnDTreeItem folderItem = (DnDTreeItem) GSS.get().getFolders().getCurrent();
815
                        if( folderItem.getFolderResource()!= null){
816
                                if(GSS.get().getFolders().isFileItem(folderItem) || GSS.get().getFolders().isMySharedItem(folderItem)  || GSS.get().getFolders().isOthersSharedItem(folderItem) ){
817
                                        update(true);
818
                                        GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, folderItem.getFolderResource().getUri(),folderItem.getFolderResource()) {
819

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

    
840
                                                        @Override
841
                                                        public void onError(Throwable t) {
842
                                                                GWT.log("", t);
843
                                                                GSS.get().displayError("Unable to fetch folder " + folderItem.getFolderResource().getName());
844
                                                        }
845
                                                };
846
                                                DeferredCommand.addCommand(gf);
847
                                }
848
                        }
849
                        else if (folderItem.getTrashResource() != null) {
850
                                GetCommand<TrashResource> gt = new GetCommand<TrashResource>(TrashResource.class, folderItem.getTrashResource().getUri(), null) {
851

    
852
                                        @Override
853
                                        public void onComplete() {
854
                                                folderItem.setUserObject(getResult());
855
                                                updateFileCache(clearSelection);
856
                                        }
857

    
858
                                        @Override
859
                                        public void onError(Throwable t) {
860
                                                if (t instanceof RestException && (((RestException) t).getHttpStatusCode() == 204 || ((RestException) t).getHttpStatusCode() == 1223)) {
861
                                                        folderItem.setUserObject(new TrashResource(folderItem.getTrashResource().getUri()));
862
                                                        updateFileCache(clearSelection);
863
                                                } else {
864
                                                        GWT.log("", t);
865
                                                        GSS.get().displayError("Unable to fetch trash resource");
866
                                                }
867
                                        }
868
                                };
869
                                DeferredCommand.addCommand(gt);
870
                        } else if (folderItem.getSharedResource() != null) {
871
                                GetCommand<SharedResource> gt = new GetCommand<SharedResource>(SharedResource.class, folderItem.getSharedResource().getUri(), null) {
872

    
873
                                        @Override
874
                                        public void onComplete() {
875
                                                folderItem.setUserObject(getResult());
876
                                                for(FileResource r : folderItem.getSharedResource().getFiles()){
877
                                                        String p = r.getUri();
878
                                                        int indexOfQuestionMark = p.lastIndexOf('?');
879
                                                        if(indexOfQuestionMark>0)
880
                                                                r.setUri(p.substring(0, indexOfQuestionMark));
881
                                                        GWT.log("FETCHED:"+r.getLastModifiedSince(), null);
882
                                                }
883
                                                folderItem.getSharedResource().setFilesExpanded(true);
884
                                                updateFileCache(clearSelection, newFilename);
885
                                                
886
                                        }
887

    
888
                                        @Override
889
                                        public void onError(Throwable t) {
890
                                                GWT.log("", t);
891
                                                GSS.get().displayError("Unable to fetch My Shares resource");
892
                                        }
893
                                };
894
                                DeferredCommand.addCommand(gt);
895
                        } else if (folderItem.getOtherUserResource() != null) {
896
                                GetCommand<OtherUserResource> gt = new GetCommand<OtherUserResource>(OtherUserResource.class, folderItem.getOtherUserResource().getUri(), null) {
897

    
898
                                        @Override
899
                                        public void onComplete() {
900
                                                folderItem.setUserObject(getResult());
901
                                                //updateFileCache(clearSelection, newFilename);
902
                                                for(FileResource r : folderItem.getOtherUserResource().getFiles()){
903
                                                        String p = r.getUri();
904
                                                        int indexOfQuestionMark = p.lastIndexOf('?');
905
                                                        if(indexOfQuestionMark>0)
906
                                                                r.setUri(p.substring(0, indexOfQuestionMark));
907
                                                        GWT.log("FETCHED:"+r.getLastModifiedSince(), null);
908
                                                }
909
                                                folderItem.getOtherUserResource().setFilesExpanded(true);
910
                                                updateFileCache(clearSelection, newFilename);
911
                                                
912
                                        }
913

    
914
                                        @Override
915
                                        public void onError(Throwable t) {
916
                                                GWT.log("", t);
917
                                                GSS.get().displayError("Unable to fetch My Shares resource");
918
                                        }
919
                                };
920
                                DeferredCommand.addCommand(gt);
921
                        }
922
                } else
923
                        updateFileCache(clearSelection);
924
        }
925

    
926
        private void updateFileCache(boolean clearSelection) {
927
                updateFileCache(clearSelection, null);
928
        }
929

    
930
        /**
931
         * Update the file cache with data from the server.
932
         *
933
         * @param userId the ID of the current user
934
         * @param newFilename the new name of the previously selected file,
935
         *                         if a rename operation has taken place
936
         */
937
        private void updateFileCache(boolean clearSelection, String newFilename) {
938
                if (clearSelection)
939
                        clearSelectedRows();
940
                clearLabels();
941
                startIndex = 0;
942
                final TreeItem folderItem = GSS.get().getFolders().getCurrent();
943
                // Validation.
944
                if (folderItem == null || GSS.get().getFolders().isOthersShared(folderItem)) {
945
                        setFiles(new ArrayList<FileResource>());
946
                        update(true);
947
                        return;
948
                }
949
                if (folderItem instanceof DnDTreeItem) {
950
                        DnDTreeItem dnd = (DnDTreeItem) folderItem;
951
                        if (dnd.getFolderResource() != null) {
952
                                if (GSS.get().getFolders().isTrashItem(dnd))
953
                                        setFiles(new ArrayList<FileResource>());
954
                                else
955
                                        setFiles(dnd.getFolderResource().getFiles());
956

    
957
                        } else if (dnd.getTrashResource() != null)
958
                                setFiles(dnd.getTrashResource().getFiles());
959
                        else if (dnd.getSharedResource() != null)
960
                                setFiles(dnd.getSharedResource().getFiles());
961
                        else if (dnd.getOtherUserResource() != null)
962
                                setFiles(dnd.getOtherUserResource().getFiles());
963
                        else
964
                                setFiles(dnd.getFolderResource().getFiles());
965
                        update(true);
966

    
967
                        if (!clearSelection && selectedRows.size()==1 && newFilename!=null) {
968
                                int row = -1;
969
                                for (int i=1; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {
970
                                        if (startIndex + i > folderFileCount)
971
                                                break;
972
                                        FileResource file = files.get(startIndex + i - 1);
973
                                        if (newFilename.equals(file.getName())) {
974
                                                row = i-1;
975
                                                break;
976
                                        }
977
                                }
978
                                clearSelectedRows();
979
                                if (row!=-1)
980
                                        selectRow(row, true);
981
                        }
982
                }
983
        }
984

    
985
        /**
986
         * Fill the file cache with data.
987
         */
988
        public void setFiles(final List<FileResource> _files) {
989
                if (_files.size() > 0 && !GSS.get().getFolders().isTrash(GSS.get().getFolders().getCurrent())) {
990
                        files = new ArrayList<FileResource>();
991
                        for (FileResource fres : _files)
992
                                if (!fres.isDeleted())
993
                                        files.add(fres);
994
                } else
995
                        files = _files;
996
                Collections.sort(files, new Comparator<FileResource>() {
997

    
998
                        @Override
999
                        public int compare(FileResource arg0, FileResource arg1) {
1000
                                return arg0.getName().compareTo(arg1.getName());
1001
                        }
1002

    
1003
                });
1004
                folderFileCount = files.size();
1005
        }
1006

    
1007
        private void sortFiles(final String sortProperty) {
1008
                if (sortProperty.equals(sortingProperty))
1009
                        sortingType = !sortingType;
1010
                else {
1011
                        sortingProperty = sortProperty;
1012
                        sortingType = true;
1013
                }
1014
                update(true);
1015
        }
1016

    
1017
        private void clearLabels() {
1018
                nameLabel.setText("Name");
1019
                versionLabel.setText("Version");
1020
                sizeLabel.setText("Size");
1021
                dateLabel.setText("Last modified");
1022
                ownerLabel.setText("Owner");
1023
                pathLabel.setText("Path");
1024
        }
1025

    
1026
        /**
1027
         * Retrieve the table.
1028
         *
1029
         * @return the table
1030
         */
1031
        Grid getTable() {
1032
                return table;
1033
        }
1034

    
1035
        /**
1036
         * Does the list contains the requested filename
1037
         *
1038
         * @param fileName
1039
         * @return true/false
1040
         */
1041
        public boolean contains(String fileName) {
1042
                for (int i = 0; i < files.size(); i++)
1043
                        if (files.get(i).getName().equals(fileName))
1044
                                return true;
1045
                return false;
1046
        }
1047

    
1048
        public void clearSelectedRows() {
1049
                for (int r : selectedRows) {
1050
                        int row = r - startIndex;
1051
                        styleRow(row, false);
1052
                }
1053
                selectedRows.clear();
1054
                Object sel = GSS.get().getCurrentSelection();
1055
                if (sel instanceof FileResource || sel instanceof List)
1056
                        GSS.get().setCurrentSelection(null);
1057
        }
1058

    
1059
        /**
1060
         *
1061
         */
1062
        public void selectAllRows() {
1063
                clearSelectedRows();
1064
                int count = folderFileCount;
1065
                if (count == 0)
1066
                        return;
1067
                int max = startIndex + GSS.VISIBLE_FILE_COUNT;
1068
                if (max > count)
1069
                        max = count;
1070
                int i = 1;
1071
                for (; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {
1072
                        // Don't read past the end.
1073
                        // if (i > folderFileCount)
1074
                        // break;
1075
                        if (startIndex + i > folderFileCount)
1076
                                break;
1077
                        selectedRows.add(startIndex + i - 1);
1078
                        styleRow(i - 1, true);
1079
                }
1080
                GSS.get().setCurrentSelection(getSelectedFiles());
1081
                contextMenu.setFiles(getSelectedFiles());
1082
                makeRowDraggable(i-1);
1083

    
1084
        }
1085

    
1086
        private void makeRowDraggable(int row){
1087
                int contextRow = getWidgetRow(contextMenu, table);
1088
                if (contextRow != -1)
1089
                        table.setWidget(contextRow, 0, getFileIcon(files.get(contextRow - 1)).createImage());
1090
                contextMenu.setWidget(new HTML(getFileIcon(files.get(row - 1)).getHTML()));
1091
                table.setWidget(row, 0, contextMenu);
1092
        }
1093

    
1094
        private int getWidgetRow(Widget widget, Grid grid) {
1095
                for (int row = 0; row < grid.getRowCount(); row++)
1096
                        for (int col = 0; col < grid.getCellCount(row); col++) {
1097
                                Widget w = table.getWidget(row, col);
1098
                                if (w == widget)
1099
                                        return row;
1100
                        }
1101
                return -1;
1102
        }
1103

    
1104

    
1105

    
1106
}