Statistics
| Branch: | Tag: | Revision:

root / src / gr / grnet / pithos / web / client / FileList.java @ 969a4d94

History | View | Annotate | Download (19.7 kB)

1
/*
2
 * Copyright 2011 GRNET S.A. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or
5
 * without modification, are permitted provided that the following
6
 * conditions are met:
7
 *
8
 *   1. Redistributions of source code must retain the above
9
 *      copyright notice, this list of conditions and the following
10
 *      disclaimer.
11
 *
12
 *   2. Redistributions in binary form must reproduce the above
13
 *      copyright notice, this list of conditions and the following
14
 *      disclaimer in the documentation and/or other materials
15
 *      provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
 * POSSIBILITY OF SUCH DAMAGE.
29
 *
30
 * The views and conclusions contained in the software and
31
 * documentation are those of the authors and should not be
32
 * interpreted as representing official policies, either expressed
33
 * or implied, of GRNET S.A.
34
 */
35

    
36
package gr.grnet.pithos.web.client;
37

    
38
import gr.grnet.pithos.web.client.foldertree.File;
39
import gr.grnet.pithos.web.client.foldertree.Folder;
40
import gr.grnet.pithos.web.client.foldertree.FolderTreeView;
41

    
42
import java.util.ArrayList;
43
import java.util.Collections;
44
import java.util.Comparator;
45
import java.util.Iterator;
46
import java.util.List;
47

    
48
import com.google.gwt.cell.client.ImageResourceCell;
49
import com.google.gwt.cell.client.SafeHtmlCell;
50
import com.google.gwt.cell.client.TextCell;
51
import com.google.gwt.cell.client.ValueUpdater;
52
import com.google.gwt.core.client.GWT;
53
import com.google.gwt.event.dom.client.ContextMenuEvent;
54
import com.google.gwt.event.dom.client.ContextMenuHandler;
55
import com.google.gwt.i18n.client.DateTimeFormat;
56
import com.google.gwt.resources.client.ImageResource;
57
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
58
import com.google.gwt.safehtml.client.SafeHtmlTemplates.Template;
59
import com.google.gwt.safehtml.shared.SafeHtml;
60
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
61
import com.google.gwt.user.cellview.client.CellTable;
62
import com.google.gwt.user.cellview.client.Column;
63
import com.google.gwt.user.client.Event;
64
import com.google.gwt.user.client.Window;
65
import com.google.gwt.user.client.ui.Composite;
66
import com.google.gwt.user.client.ui.VerticalPanel;
67
import com.google.gwt.view.client.ListDataProvider;
68
import com.google.gwt.view.client.MultiSelectionModel;
69
import com.google.gwt.view.client.ProvidesKey;
70

    
71
/**
72
 * A composite that displays the list of files in a particular folder.
73
 */
74
public class FileList extends Composite {
75

    
76
        ListDataProvider<File> provider = new ListDataProvider<File>();
77

    
78
    /**
79
       * The styles applied to the table.
80
       */
81
    interface TableStyle extends CellTable.Style {
82
    }
83

    
84
        interface TableResources extends CellTable.Resources {
85
            @Override
86
                @Source({CellTable.Style.DEFAULT_CSS, "PithosCellTable.css"})
87
            TableStyle cellTableStyle();
88
        }
89
        
90
        static interface Templates extends SafeHtmlTemplates {
91
            Templates INSTANCE = GWT.create(Templates.class);
92

    
93
            @Template("<div id='dragHelper' style='border:1px solid black; background-color:#ffffff; color:black; width:150px;z-index:100'></div>")
94
            SafeHtml outerHelper();
95

    
96
        @Template("<span id='{0}'>{0}</span>")
97
        public SafeHtml filenameSpan(String filename);
98

    
99
        @Template("<a href='{0}' title='{1}' rel='lytebox[mnf]' onclick='myLytebox.start(this, false, false); return false;'>(view)</a>")
100
        public SafeHtml viewLink(String link, String title);
101

    
102
        @Template("<table><tr><td rowspan='3'>{0}</td><td style='font-size:95%;' id='{1}'>{1}</td></tr><tr><td>{2}</td></tr></table>")
103
        public SafeHtml rendelContactCell(String imageHtml, String name, String fileSize);
104

    
105
        @Template("<span id='{0}' class='{1}'>{2}</span>")
106
        public SafeHtml spanWithIdAndClass(String id, String cssClass, String content);
107
        }
108

    
109
        protected final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");
110

    
111
        /**
112
         * Specifies that the images available for this composite will be the ones
113
         * available in FileContextMenu.
114
         */
115
        public interface Images extends FolderTreeView.Images {
116

    
117
                @Source("gr/grnet/pithos/resources/blank.gif")
118
                ImageResource blank();
119

    
120
                @Source("gr/grnet/pithos/resources/asc.png")
121
                ImageResource asc();
122

    
123
                @Source("gr/grnet/pithos/resources/desc.png")
124
                ImageResource desc();
125

    
126
                @Source("gr/grnet/pithos/resources/mimetypes/document_shared.png")
127
                ImageResource documentShared();
128

    
129
                @Source("gr/grnet/pithos/resources/mimetypes/kcmfontinst.png")
130
                ImageResource wordprocessor();
131

    
132
                @Source("gr/grnet/pithos/resources/mimetypes/log.png")
133
                ImageResource spreadsheet();
134

    
135
                @Source("gr/grnet/pithos/resources/mimetypes/kpresenter_kpr.png")
136
                ImageResource presentation();
137

    
138
                @Source("gr/grnet/pithos/resources/mimetypes/acroread.png")
139
                ImageResource pdf();
140

    
141
                @Source("gr/grnet/pithos/resources/mimetypes/image.png")
142
                ImageResource image();
143

    
144
                @Source("gr/grnet/pithos/resources/mimetypes/video2.png")
145
                ImageResource video();
146

    
147
                @Source("gr/grnet/pithos/resources/mimetypes/knotify.png")
148
                ImageResource audio();
149

    
150
                @Source("gr/grnet/pithos/resources/mimetypes/html.png")
151
                ImageResource html();
152

    
153
                @Source("gr/grnet/pithos/resources/mimetypes/txt.png")
154
                ImageResource txt();
155

    
156
                @Source("gr/grnet/pithos/resources/mimetypes/ark2.png")
157
                ImageResource zip();
158

    
159
                @Source("gr/grnet/pithos/resources/mimetypes/kcmfontinst_shared.png")
160
                ImageResource wordprocessorShared();
161

    
162
                @Source("gr/grnet/pithos/resources/mimetypes/log_shared.png")
163
                ImageResource spreadsheetShared();
164

    
165
                @Source("gr/grnet/pithos/resources/mimetypes/kpresenter_kpr_shared.png")
166
                ImageResource presentationShared();
167

    
168
                @Source("gr/grnet/pithos/resources/mimetypes/acroread_shared.png")
169
                ImageResource pdfShared();
170

    
171
                @Source("gr/grnet/pithos/resources/mimetypes/image_shared.png")
172
                ImageResource imageShared();
173

    
174
                @Source("gr/grnet/pithos/resources/mimetypes/video2_shared.png")
175
                ImageResource videoShared();
176

    
177
                @Source("gr/grnet/pithos/resources/mimetypes/knotify_shared.png")
178
                ImageResource audioShared();
179

    
180
                @Source("gr/grnet/pithos/resources/mimetypes/html_shared.png")
181
                ImageResource htmlShared();
182

    
183
                @Source("gr/grnet/pithos/resources/mimetypes/txt_shared.png")
184
                ImageResource txtShared();
185

    
186
                @Source("gr/grnet/pithos/resources/mimetypes/ark2_shared.png")
187
                ImageResource zipShared();
188

    
189
        }
190
        
191
        /**
192
         * The number of files in this folder.
193
         */
194
        int folderFileCount;
195

    
196
        /**
197
         * Total folder size
198
         */
199
        long folderTotalSize;
200

    
201
        /**
202
         * A cache of the files in the list.
203
         */
204
        private List<File> files;
205

    
206
        /**
207
         * The widget's image bundle.
208
         */
209
        protected final Images images;
210
        
211
        protected CellTable<File> celltable;
212

    
213
        private final MultiSelectionModel<File> selectionModel;
214

    
215
        protected final List<SortableHeader> allHeaders = new ArrayList<SortableHeader>();
216

    
217
        SortableHeader nameHeader;
218

    
219
    FolderTreeView treeView;
220

    
221
    protected Pithos app;
222

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

    
236
        CellTable.Resources resources = GWT.create(TableResources.class);
237

    
238
        ProvidesKey<File> keyProvider = new ProvidesKey<File>(){
239

    
240
                        @Override
241
                        public Object getKey(File item) {
242
                                return item.getUri();
243
                        }
244
                };
245

    
246
                celltable = new CellTable<File>(10, resources, keyProvider);
247
        celltable.setWidth("100%");
248
        celltable.setStyleName("pithos-List");
249

    
250
                Column<File, ImageResource> status = new Column<File, ImageResource>(new ImageResourceCell() {
251
                    @Override
252
                public boolean handlesSelection() {
253
                    return false;
254
                }
255
                })
256
        {
257
                 @Override
258
                 public ImageResource getValue(File entity) {
259
                     return getFileIcon(entity);
260
                 }
261
            };
262
            celltable.addColumn(status,"");
263

    
264
        final Column<File,SafeHtml> nameColumn = new Column<File,SafeHtml>(new SafeHtmlCell()) {
265

    
266
                        @Override
267
                        public SafeHtml getValue(File object) {
268
                                SafeHtmlBuilder sb = new SafeHtmlBuilder();
269
                sb.append(Templates.INSTANCE.filenameSpan(object.getName()));
270
                                if (object.getContentType().endsWith("png") || object.getContentType().endsWith("gif") || object.getContentType().endsWith("jpeg")) {
271
                                sb.appendHtmlConstant("&nbsp;")
272
                      .append(Templates.INSTANCE.viewLink(app.getApiPath() + object.getOwner() + object.getUri() + "?X-Auth-Token=" + app.getToken(), object.getName()));
273
                                }
274
                                
275
                                return sb.toSafeHtml();
276
                        }
277
                        
278
                };
279
        celltable.addColumn(nameColumn, nameHeader = new SortableHeader("Name"));
280
                allHeaders.add(nameHeader);
281
                nameHeader.setUpdater(new FileValueUpdater(nameHeader, "name"));
282

    
283
                celltable.redrawHeaders();
284
                
285
        Column<File,String> aColumn = new Column<File,String>(new TextCell()) {
286
                        @Override
287
                        public String getValue(File object) {
288
                                // TODO Auto-generated method stub
289
                                return object.getSizeAsString();
290
                        }
291
                };
292
        SortableHeader aheader = new SortableHeader("Size");
293
        celltable.addColumn(aColumn, aheader);
294
                allHeaders.add(aheader);
295
                aheader.setUpdater(new FileValueUpdater(aheader, "size"));
296

    
297
        aColumn = new Column<File,String>(new TextCell()) {
298
                        @Override
299
                        public String getValue(File object) {
300
                                return object.getLastModified() != null ? formatter.format(object.getLastModified()) : "";
301
                        }
302
                };
303
        aheader = new SortableHeader("Last Modified");
304
                celltable.addColumn(aColumn, aheader);
305
                allHeaders.add(aheader);
306
                aheader.setUpdater(new FileValueUpdater(aheader, "date"));
307
               
308
                provider.addDataDisplay(celltable);
309

    
310
                VerticalPanel vp = new VerticalPanel();
311
                vp.setWidth("100%");
312

    
313
        vp.add(celltable);
314

    
315
                vp.setCellWidth(celltable, "100%");
316
        vp.addHandler(new ContextMenuHandler() {
317
            @Override
318
            public void onContextMenu(ContextMenuEvent event) {
319
                    TreeView tree = app.getSelectedTree();
320
                    if (tree != null && (tree.equals(app.getFolderTreeView()) || tree.equals(app.getOtherSharedTreeView()))) {
321
                        Folder selectedFolder = app.getSelection();
322
                        FileContextMenu contextMenu = new FileContextMenu(app, images, tree, selectedFolder, getSelectedFiles());
323
                        int x = event.getNativeEvent().getClientX();
324
                        int y = event.getNativeEvent().getClientY();
325
                        contextMenu.setPopupPosition(x, y);
326
                        contextMenu.show();
327
                    }
328
            }
329
        }, ContextMenuEvent.getType());
330
                initWidget(vp);
331

    
332
                selectionModel = new MultiSelectionModel<File>(keyProvider);
333

    
334
                celltable.setSelectionModel(selectionModel, PithosSelectionEventManager.<File> createDefaultManager());
335
//                celltable.setPageSize(Pithos.VISIBLE_FILE_COUNT);
336
                
337
                sinkEvents(Event.ONCONTEXTMENU);
338
//                sinkEvents(Event.ONMOUSEUP);
339
//                sinkEvents(Event.ONMOUSEDOWN);
340
//                sinkEvents(Event.ONCLICK);
341
//                sinkEvents(Event.ONKEYDOWN);
342
//                sinkEvents(Event.ONDBLCLICK);
343
                Pithos.preventIESelection();
344
        }
345

    
346
        public List<File> getSelectedFiles() {
347
        return new ArrayList<File>(selectionModel.getSelectedSet());
348
        }
349
        
350
//        @Override
351
//        public void onBrowserEvent(Event event) {
352
//
353
//                if (files == null || files.size() == 0) {
354
//                        if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() == 0) {
355
//                                contextMenu = new FileContextMenu(images, false, true);
356
//                contextMenu.show();
357
//                                event.preventDefault();
358
//                                event.cancelBubble(true);
359
//                        }
360
//                        return;
361
//                }
362
//                if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() != 0) {
363
//                        GWT.log("*****GOING TO SHOW CONTEXT MENU ****", null);
364
//                        contextMenu =  new FileContextMenu(images, false, false);
365
//                        contextMenu = contextMenu.onEvent(event);
366
//                        event.cancelBubble(true);
367
//                        event.preventDefault();
368
//                } else if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() == 0) {
369
//                        contextMenu = new FileContextMenu(images, false, true);
370
//                        contextMenu = contextMenu.onEmptyEvent(event);
371
//                        event.cancelBubble(true);
372
//                        event.preventDefault();
373
//                } else if (DOM.eventGetType(event) == Event.ONDBLCLICK)
374
//                        if (getSelectedFiles().size() == 1) {
375
//                                Pithos app = app;
376
//                                File file = getSelectedFiles().get(0);
377
//                                Window.open(file.getUri(), "_blank", "");
378
//                                event.preventDefault();
379
//                                return;
380
//                        }
381
//                super.onBrowserEvent(event);
382
//        }
383

    
384
        /**
385
         * Update the display of the file list.
386
         */
387
        void update(@SuppressWarnings("unused") boolean sort) {
388
                showCellTable();
389
        }
390

    
391
        /**
392
         * Return the proper icon based on the MIME type of the file.
393
         *
394
         * @param file
395
         * @return the icon
396
         */
397
        protected ImageResource getFileIcon(File file) {
398
                String mimetype = file.getContentType();
399
                boolean shared = file.isShared();
400
                if (mimetype == null)
401
                        return shared ? images.documentShared() : images.document();
402
                mimetype = mimetype.toLowerCase();
403
                if (mimetype.startsWith("application/pdf"))
404
                        return shared ? images.pdfShared() : images.pdf();
405
                else if (mimetype.endsWith("excel"))
406
                        return shared ? images.spreadsheetShared() : images.spreadsheet();
407
                else if (mimetype.endsWith("msword"))
408
                        return shared ? images.wordprocessorShared() : images.wordprocessor();
409
                else if (mimetype.endsWith("powerpoint"))
410
                        return shared ? images.presentationShared() : images.presentation();
411
                else if (mimetype.startsWith("application/zip") ||
412
                                        mimetype.startsWith("application/gzip") ||
413
                                        mimetype.startsWith("application/x-gzip") ||
414
                                        mimetype.startsWith("application/x-tar") ||
415
                                        mimetype.startsWith("application/x-gtar"))
416
                        return shared ? images.zipShared() : images.zip();
417
                else if (mimetype.startsWith("text/html"))
418
                        return shared ? images.htmlShared() : images.html();
419
                else if (mimetype.startsWith("text/plain"))
420
                        return shared ? images.txtShared() : images.txt();
421
                else if (mimetype.startsWith("image/"))
422
                        return shared ? images.imageShared() : images.image();
423
                else if (mimetype.startsWith("video/"))
424
                        return shared ? images.videoShared() : images.video();
425
                else if (mimetype.startsWith("audio/"))
426
                        return shared ? images.audioShared() : images.audio();
427
                return shared ? images.documentShared() : images.document();
428
        }
429

    
430
        /**
431
         * Fill the file cache with data.
432
         */
433
        public void setFiles(final List<File> _files) {
434
                files = new ArrayList<File>();
435
            for (File fres : _files)
436
                        files.add(fres);
437
                Collections.sort(files, new Comparator<File>() {
438

    
439
                        @Override
440
                        public int compare(File arg0, File arg1) {
441
                                return arg0.getName().compareTo(arg1.getName());
442
                        }
443

    
444
                });
445
                folderFileCount = files.size();
446
                
447
                nameHeader.setSorted(true);
448
                nameHeader.toggleReverseSort();
449
                for (SortableHeader otherHeader : allHeaders) {
450
                if (otherHeader != nameHeader) {
451
                    otherHeader.setSorted(false);
452
                    otherHeader.setReverseSort(true);
453
                }
454
            }
455

    
456
        provider.setList(files);
457
        selectionModel.clear();
458
        app.showFolderStatistics(folderFileCount);
459
        celltable.setPageSize(folderFileCount);
460
        }
461

    
462
        /**
463
         * Does the list contains the requested filename
464
         *
465
         * @param fileName
466
         * @return true/false
467
         */
468
        public boolean contains(String fileName) {
469
                for (int i = 0; i < files.size(); i++)
470
                        if (files.get(i).getName().equals(fileName))
471
                                return true;
472
                return false;
473
        }
474

    
475
        public void clearSelectedRows() {
476
                Iterator<File> it = selectionModel.getSelectedSet().iterator();
477
                while(it.hasNext()){
478
                        selectionModel.setSelected(it.next(),false);
479
                }
480
        }
481
        
482
        /**
483
         *
484
         */
485
        public void selectAllRows() {
486
                Iterator<File> it = provider.getList().iterator();
487
                while(it.hasNext()){
488
                        selectionModel.setSelected(it.next(),true);
489
                }
490
        }
491

    
492
        protected void sortFiles(final String sortingProperty, final boolean sortingType){
493
                Collections.sort(files, new Comparator<File>() {
494

    
495
            @Override
496
            public int compare(File arg0, File arg1) {
497
                    if (sortingType){
498
                            if (sortingProperty.equals("version")) {
499
                                    return arg0.getVersion() - arg1.getVersion();
500
                            } else if (sortingProperty.equals("owner")) {
501
                                    return arg0.getOwner().compareTo(arg1.getOwner());
502
                            } else if (sortingProperty.equals("date")) {
503
                                            if (arg0.getLastModified() != null && arg1.getLastModified() != null)
504
                                                    return arg0.getLastModified().compareTo(arg1.getLastModified());
505
                                            return 0;
506
                            } else if (sortingProperty.equals("size")) {
507
                                    return (int) (arg0.getBytes() - arg1.getBytes());
508
                            } else if (sortingProperty.equals("name")) {
509
                                    return arg0.getName().compareTo(arg1.getName());
510
                            } else if (sortingProperty.equals("path")) {
511
                                    return arg0.getUri().compareTo(arg1.getUri());
512
                            } else {
513
                                    return arg0.getName().compareTo(arg1.getName());
514
                            }
515
                    }
516
                    else if (sortingProperty.equals("version")) {
517
                            
518
                            return arg1.getVersion() - arg0.getVersion();
519
                    } else if (sortingProperty.equals("owner")) {
520
                            
521
                            return arg1.getOwner().compareTo(arg0.getOwner());
522
                    } else if (sortingProperty.equals("date")) {
523
                            
524
                            return arg1.getLastModified().compareTo(arg0.getLastModified());
525
                    } else if (sortingProperty.equals("size")) {
526
                            return (int) (arg1.getBytes() - arg0.getBytes());
527
                    } else if (sortingProperty.equals("name")) {
528
                            
529
                            return arg1.getName().compareTo(arg0.getName());
530
                    } else if (sortingProperty.equals("path")) {
531
                            
532
                            return arg1.getUri().compareTo(arg0.getUri());
533
                    } else {
534
                            
535
                            return arg1.getName().compareTo(arg0.getName());
536
                    }
537
            }
538

    
539
                });
540
        }
541
        
542
        final class FileValueUpdater implements ValueUpdater<String>{
543
                private String property;
544
                private SortableHeader header;
545
                /**
546
                 * 
547
                 */
548
                public FileValueUpdater(SortableHeader header,String property) {
549
                        this.property=property;
550
                        this.header=header;
551
                }
552
                @Override
553
                public void update(@SuppressWarnings("unused") String value) {
554
                        header.setSorted(true);
555
                        header.toggleReverseSort();
556

    
557
                for (SortableHeader otherHeader : allHeaders) {
558
                  if (otherHeader != header) {
559
                    otherHeader.setSorted(false);
560
                    otherHeader.setReverseSort(true);
561
                  }
562
                }
563
                celltable.redrawHeaders();
564
                sortFiles(property, header.getReverseSort());
565
                FileList.this.update(true);                        
566
                }
567
                
568
        }
569

    
570
        /**
571
         * Shows the files in the cellTable 
572
     */
573
        private void showCellTable(){
574
                provider.setList(files);
575
                
576
                provider.refresh();
577
                
578
                //celltable.redraw();
579
                celltable.redrawHeaders();                
580
        }
581
}