fix dnd bug, and use filelist.getSelectedFiles() on file drop
[pithos] / src / gr / ebs / gss / admin / client / ui / UsersTable.java
1 /*
2  * Copyright 2010 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.admin.client.ui;
20
21 import gr.ebs.gss.admin.client.ui.UsersTable.UserSorter.UserComparator;
22 import gr.ebs.gss.server.domain.dto.StatsDTO;
23 import gr.ebs.gss.server.domain.dto.UserDTO;
24
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.Comparator;
28 import java.util.Date;
29 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.LinkedHashMap;
32 import java.util.LinkedList;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Set;
36
37 import com.google.gwt.event.dom.client.ClickEvent;
38 import com.google.gwt.event.dom.client.ClickHandler;
39 import com.google.gwt.gen2.table.client.AbstractColumnDefinition;
40 import com.google.gwt.gen2.table.client.AbstractScrollTable.ScrollPolicy;
41 import com.google.gwt.gen2.table.client.AbstractScrollTable.SortPolicy;
42 import com.google.gwt.gen2.table.client.CachedTableModel;
43 import com.google.gwt.gen2.table.client.CellRenderer;
44 import com.google.gwt.gen2.table.client.ColumnDefinition;
45 import com.google.gwt.gen2.table.client.DefaultRowRenderer;
46 import com.google.gwt.gen2.table.client.DefaultTableDefinition;
47 import com.google.gwt.gen2.table.client.FixedWidthGridBulkRenderer;
48 import com.google.gwt.gen2.table.client.MutableTableModel;
49 import com.google.gwt.gen2.table.client.PagingOptions;
50 import com.google.gwt.gen2.table.client.PagingScrollTable;
51 import com.google.gwt.gen2.table.client.ScrollTable;
52 import com.google.gwt.gen2.table.client.SelectionGrid.SelectionPolicy;
53 import com.google.gwt.gen2.table.client.TableDefinition;
54 import com.google.gwt.gen2.table.client.TableDefinition.AbstractCellView;
55 import com.google.gwt.gen2.table.client.TableModel;
56 import com.google.gwt.gen2.table.client.TableModelHelper.Request;
57 import com.google.gwt.gen2.table.client.TableModelHelper.Response;
58 import com.google.gwt.gen2.table.event.client.RowSelectionEvent;
59 import com.google.gwt.gen2.table.event.client.RowSelectionHandler;
60 import com.google.gwt.gen2.table.event.client.TableEvent.Row;
61 import com.google.gwt.i18n.client.DateTimeFormat;
62 import com.google.gwt.user.client.ui.Button;
63 import com.google.gwt.user.client.ui.CheckBox;
64 import com.google.gwt.user.client.ui.Composite;
65 import com.google.gwt.user.client.ui.DialogBox;
66 import com.google.gwt.user.client.ui.FlexTable;
67 import com.google.gwt.user.client.ui.HTML;
68 import com.google.gwt.user.client.ui.HasHorizontalAlignment;
69 import com.google.gwt.user.client.ui.Label;
70 import com.google.gwt.user.client.ui.VerticalPanel;
71
72
73 /**
74  * @author kman
75  *
76  */
77 public class UsersTable extends Composite {
78         private CachedTableModel<UserDTO> cachedTableModel = null;
79         private DefaultTableDefinition<UserDTO> tableDefinition = null;
80         private PagingScrollTable<UserDTO> pagingScrollTable = null;
81         private Label countLabel = new Label("There are no users to display.");
82         private DataSourceTableModel tableModel = null;
83
84         private VerticalPanel vPanel = new VerticalPanel();
85         private FlexTable flexTable = new FlexTable();
86
87         /**
88          * Constructor
89          */
90         public UsersTable() {
91                 super();
92                 pagingScrollTable = createScrollTable();
93                 pagingScrollTable.setHeight("200px");
94                 pagingScrollTable.setScrollPolicy(ScrollPolicy.DISABLED);
95                 PagingOptions pagingOptions = new PagingOptions(pagingScrollTable);
96
97                 flexTable.setWidget(0, 0, pagingScrollTable);
98                 flexTable.getFlexCellFormatter().setColSpan(0, 0, 2);
99                 flexTable.setWidget(1, 0, pagingOptions);
100
101                 countLabel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
102                 vPanel.add(countLabel);
103                 vPanel.add(flexTable);
104
105                 vPanel.setWidth("100%");
106                 flexTable.setWidth("100%");
107
108                 super.initWidget(vPanel);
109                 showUsers(new ArrayList<UserDTO>());
110                 pagingScrollTable.setFooterGenerated(true);
111         }
112
113         /**
114          *
115          * @param newList the list of users to show
116          */
117         public void showUsers(List<UserDTO> newList) {
118                 countLabel.setText("There are "+ newList.size() + " users.");
119                 tableModel.setData(newList);
120                 tableModel.setRowCount(newList.size());
121                 cachedTableModel.clearCache();
122                 cachedTableModel.setRowCount(newList.size());
123
124                 pagingScrollTable.gotoPage(0, true);
125                 if(newList.size()<2)
126                         flexTable.setWidget(1, 0, new HTML());
127                 else{
128                         PagingOptions pagingOptions = new PagingOptions(pagingScrollTable);
129                         flexTable.setWidget(1, 0, pagingOptions);
130                 }
131         }
132
133         public UserDTO getUserOnRow(int rowIdx){
134                 String id = pagingScrollTable.getDataTable().getHTML(rowIdx, 0);
135                 final UserDTO m = tableModel.getUserById(Long.parseLong(id));
136                 return m;
137         }
138
139
140         public UserDTO getSelectedRowObject(RowSelectionEvent event){
141                 Set<Row> set = event.getSelectedRows();
142                 if(set.size() == 1) {
143                         int rowIdx = set.iterator().next().getRowIndex();
144                         String id = pagingScrollTable.getDataTable().getHTML(rowIdx, 0);
145                         UserDTO m = tableModel.getUserById(Long.parseLong(id));
146                         return m;
147                 }
148                 return null;
149         }
150
151         public UserDTO getUser(Long id){
152
153                 return tableModel.getUserById(id);
154         }
155
156         public DialogBox createDialogBox(UserDTO m, StatsDTO s) {
157
158                 // Create a dialog box and set the caption text
159                 final DialogBox dialogBox = new DialogBox();
160                 dialogBox.setHTML("User Details: "+m.getUsername());
161
162                 // Create a table to layout the content
163                 VerticalPanel dialogVPanel = new VerticalPanel();
164                 dialogBox.setSize("50%", "50%");
165
166                 ClickHandler cancelHandler = new ClickHandler() {
167                         @Override
168                         public void onClick(ClickEvent event) {
169                                 dialogBox.hide();
170                         }
171                 };
172
173                 dialogBox.setWidget(dialogVPanel);
174                 dialogVPanel.add(new Label("Username: "+m.getUsername()));
175                 dialogVPanel.add(new Label("Email: "+m.getEmail()));
176                 dialogVPanel.add(new Label("Name: "+m.getName()));
177                 if(m.getUserClass()!=null)
178                         dialogVPanel.add(new Label("Quota: "+m.getUserClass().getQuotaAsString()));
179                 dialogVPanel.add(new Label("File Count: "+s.getFileCount()));
180                 dialogVPanel.add(new Label("File Size: "+s.getFileSizeAsString()));
181                 dialogVPanel.add(new Label("Quota Left: "+s.getQuotaLeftAsString()));
182
183                 Button close = new Button("Close");
184                 close.addClickHandler(cancelHandler);
185                 dialogVPanel.add(close);
186
187                 // Return the dialog box
188                 return dialogBox;
189         }
190
191         /**
192          * Initializes the scroll table
193          * @return
194          */
195         private PagingScrollTable<UserDTO> createScrollTable() {
196                 // create our own table model
197                 tableModel = new DataSourceTableModel();
198                 // add it to cached table model
199                 cachedTableModel = createCachedTableModel(tableModel);
200
201                 // create the table definition
202                 TableDefinition<UserDTO> tableDef = createTableDefinition();
203
204                 // create the paging scroll table
205                 pagingScrollTable = new PagingScrollTable<UserDTO>(cachedTableModel, tableDef);
206                 pagingScrollTable.setPageSize(10);
207                 pagingScrollTable.setEmptyTableWidget(new HTML("There is no data to display"));
208                 pagingScrollTable.getDataTable().setSelectionPolicy(SelectionPolicy.ONE_ROW);
209
210                 FixedWidthGridBulkRenderer<UserDTO> bulkRenderer = new FixedWidthGridBulkRenderer<UserDTO>(pagingScrollTable.getDataTable(), pagingScrollTable);
211                 pagingScrollTable.setBulkRenderer(bulkRenderer);
212
213
214                 pagingScrollTable.setCellPadding(3);
215                 pagingScrollTable.setCellSpacing(0);
216                 pagingScrollTable.setResizePolicy(ScrollTable.ResizePolicy.FILL_WIDTH);
217
218                 pagingScrollTable.setSortPolicy(SortPolicy.SINGLE_CELL);
219
220                 return pagingScrollTable;
221         }
222
223         public void addRowSelectionHandler(RowSelectionHandler handler){
224                 pagingScrollTable.getDataTable().addRowSelectionHandler(handler);
225         }
226
227         /**
228          * Create the {@link CachedTableModel}
229          * @param aTableModel
230          * @return
231          */
232         private CachedTableModel<UserDTO> createCachedTableModel(DataSourceTableModel aTableModel) {
233                 CachedTableModel<UserDTO> tm = new CachedTableModel<UserDTO>(aTableModel);
234                 tm.setPreCachedRowCount(20);
235                 tm.setPostCachedRowCount(20);
236                 tm.setRowCount(20);
237                 return tm;
238         }
239
240         private DefaultTableDefinition<UserDTO> createTableDefinition() {
241                 tableDefinition = new DefaultTableDefinition<UserDTO>();
242
243                 final String[] rowColors = new String[] { "#FFFFDD", "EEEEEE" };
244                 tableDefinition.setRowRenderer(new DefaultRowRenderer<UserDTO>(rowColors));
245
246                 // id
247                 {
248                         IdColumnDefinition columnDef = new IdColumnDefinition();
249                         columnDef.setColumnSortable(true);
250                         columnDef.setColumnTruncatable(false);
251                         columnDef.setPreferredColumnWidth(35);
252                         columnDef.setHeader(0, new HTML("Id"));
253                         columnDef.setHeaderCount(1);
254                         columnDef.setHeaderTruncatable(false);
255                         tableDefinition.addColumnDefinition(columnDef);
256                 }
257                 {
258                         UserClassColumnDefinition columnDef = new UserClassColumnDefinition();
259                         columnDef.setColumnSortable(true);
260                         columnDef.setColumnTruncatable(true);
261                         columnDef.setHeader(0, new HTML("User Class"));
262                         columnDef.setHeaderCount(1);
263                         columnDef.setHeaderTruncatable(false);
264                         tableDefinition.addColumnDefinition(columnDef);
265                 }
266                 {
267                         ActiveColumnDefinition columnDef = new ActiveColumnDefinition();
268                         columnDef.setColumnSortable(true);
269                         columnDef.setColumnTruncatable(true);
270                         columnDef.setHeader(0, new HTML("Active"));
271                         columnDef.setHeaderCount(1);
272                         columnDef.setHeaderTruncatable(false);
273                         columnDef.setCellRenderer(new CellRenderer<UserDTO, Boolean>() {
274
275                                 @Override
276                                 public void renderRowValue(UserDTO rowValue, ColumnDefinition<UserDTO, Boolean> aColumnDef, AbstractCellView<UserDTO> view) {
277                                         CheckBox check = new CheckBox();
278                                         check.setValue(aColumnDef.getCellValue(rowValue));
279                                         check.setEnabled(false);
280                                         view.setWidget(check);
281
282                                 }
283                         });
284                         tableDefinition.addColumnDefinition(columnDef);
285                 }
286                 // username
287                 {
288                         UsernameColumnDefinition columnDef = new UsernameColumnDefinition();
289                         columnDef.setColumnSortable(true);
290                         columnDef.setColumnTruncatable(true);
291                         columnDef.setHeader(0, new HTML("Username"));
292                         columnDef.setHeaderCount(1);
293                         columnDef.setHeaderTruncatable(false);
294                         tableDefinition.addColumnDefinition(columnDef);
295                 }
296                 {
297                         EmailColumnDefinition columnDef = new EmailColumnDefinition();
298                         columnDef.setColumnSortable(true);
299                         columnDef.setColumnTruncatable(true);
300                         columnDef.setHeader(0, new HTML("Email"));
301                         columnDef.setHeaderCount(1);
302                         columnDef.setHeaderTruncatable(false);
303                         tableDefinition.addColumnDefinition(columnDef);
304                 }
305                 {
306                         FullNameColumnDefinition columnDef = new FullNameColumnDefinition();
307                         columnDef.setColumnSortable(true);
308                         columnDef.setColumnTruncatable(true);
309                         columnDef.setHeader(0, new HTML("Name"));
310                         columnDef.setHeaderCount(1);
311                         columnDef.setHeaderTruncatable(false);
312                         tableDefinition.addColumnDefinition(columnDef);
313                 }
314
315                 {
316                         LastLoginColumnDefinition columnDef = new LastLoginColumnDefinition();
317                         columnDef.setColumnSortable(true);
318                         columnDef.setColumnTruncatable(true);
319                         columnDef.setHeader(0, new HTML("Last Login"));
320                         columnDef.setHeaderCount(1);
321                         columnDef.setHeaderTruncatable(false);
322                         tableDefinition.addColumnDefinition(columnDef);
323                 }
324
325
326
327                 return tableDefinition;
328         }
329
330
331         private class DataSourceTableModel extends MutableTableModel<UserDTO> {
332                 private Map<Long, UserDTO> map;
333                 private UserSorter sorter = new UserSorter();
334                 public void setData(List<UserDTO> list) {
335                         // toss the list, index by id in a map.
336                         map = new HashMap<Long, UserDTO>(list.size());
337                         for(UserDTO m : list)
338                                 map.put(m.getId(), m);
339                 }
340
341                 public UserDTO getUserById(long id) {
342                         return map.get(id);
343                 }
344
345                 @Override
346                 protected boolean onRowInserted(int beforeRow) {
347                         return true;
348                 }
349
350                 @Override
351                 protected boolean onRowRemoved(int row) {
352                         return true;
353                 }
354
355                 @Override
356                 protected boolean onSetRowValue(int row, UserDTO rowValue) {
357
358                         return true;
359                 }
360
361                 @Override
362                 public void requestRows(
363                                 final Request request,
364                                 TableModel.Callback<UserDTO> callback) {
365
366                         callback.onRowsReady(request, new Response<UserDTO>(){
367
368                                 @Override
369                                 public Iterator<UserDTO> getRowValues() {
370                                         final int col = request.getColumnSortList().getPrimaryColumn();
371                                         final boolean ascending = request.getColumnSortList().isPrimaryAscending();
372                                         if(col < 0)
373                                                 map = sorter.sort(map, new UserComparator(ascending,0));
374                                         else
375                                                 map = sorter.sort(map, new UserComparator(ascending,col));
376                                         return map.values().iterator();
377                                 }});
378                 }
379
380         }
381
382
383         private final class IdColumnDefinition extends AbstractColumnDefinition<UserDTO, Long> {
384                 @Override
385                 public Long getCellValue(UserDTO rowValue) {
386                         return rowValue.getId();
387                 }
388                 @Override
389                 public void setCellValue(UserDTO rowValue, Long cellValue) { }
390         }
391
392
393         private final class UsernameColumnDefinition extends
394                         AbstractColumnDefinition<UserDTO, String> {
395                 @Override
396                 public String getCellValue(final UserDTO rowValue) {
397                         return rowValue.getUsername();
398                 }
399
400                 @Override
401                 public void setCellValue(final UserDTO rowValue, final String cellValue) {}
402         }
403
404
405         private final class FullNameColumnDefinition extends
406                         AbstractColumnDefinition<UserDTO, String> {
407                 @Override
408                 public String getCellValue(final UserDTO rowValue) {
409                         return rowValue.getName();
410                 }
411
412                 @Override
413                 public void setCellValue(final UserDTO rowValue, final String cellValue) {}
414         }
415
416
417         private final class EmailColumnDefinition extends
418                         AbstractColumnDefinition<UserDTO, String> {
419                 @Override
420                 public String getCellValue(final UserDTO rowValue) {
421                         return rowValue.getEmail();
422                 }
423
424                 @Override
425                 public void setCellValue(final UserDTO rowValue, final String cellValue) {}
426         }
427
428
429         private final class UserClassColumnDefinition extends
430                         AbstractColumnDefinition<UserDTO, String> {
431                 @Override
432                 public String getCellValue(final UserDTO rowValue) {
433                         if(rowValue.getUserClass() != null)
434                                 return rowValue.getUserClass().getName();
435                         return "";
436                 }
437
438                 @Override
439                 public void setCellValue(final UserDTO rowValue, final String cellValue) {}
440         }
441
442
443         private final class ActiveColumnDefinition extends
444                         AbstractColumnDefinition<UserDTO, Boolean> {
445                 @Override
446                 public Boolean getCellValue(final UserDTO rowValue) {
447                         if(rowValue.isActive() == null)
448                                 return true;
449                         return rowValue.isActive();
450                 }
451
452                 @Override
453                 public void setCellValue(final UserDTO rowValue, final Boolean cellValue) {
454                         rowValue.setActive(cellValue);
455                 }
456         }
457
458
459         private final class LastLoginColumnDefinition extends AbstractColumnDefinition<UserDTO, String> {
460
461                 @Override
462                 public String getCellValue(final UserDTO rowValue) {
463                         if(rowValue.getCurrentLoginDate()==null)
464                                 return  "no data";
465                         return DateTimeFormat.getFormat("dd/MM/yyyy hh:mm:ss tt").format(rowValue.getCurrentLoginDate());
466                 }
467
468                 @Override
469                 public void setCellValue(final UserDTO rowValue, final String cellValue) {}
470         }
471
472
473
474         public static class UserSorter {
475
476
477                 public Map<Long, UserDTO> sort(Map<Long, UserDTO> map, Comparator<UserDTO> comparator) {
478                         final List<UserDTO> list = new LinkedList<UserDTO>(map.values());
479                         Collections.sort(list, comparator);
480                         Map<Long, UserDTO> result = new LinkedHashMap<Long, UserDTO>(list.size());
481                         for(UserDTO p : list)
482                                 result.put(p.getId(), p);
483                         return result;
484                 }
485
486                 public final static class UserComparator implements Comparator<UserDTO> {
487
488                         private final boolean ascending;
489                         private int property;
490                         public UserComparator(boolean isAscending, int aProperty) {
491                                 ascending = isAscending;
492                                 property = aProperty;
493                         }
494
495                         @Override
496                         public int compare(UserDTO m1, UserDTO m2) {
497                                 switch(property){
498                                         case 0:
499                                                 if(ascending)
500                                                         return m1.getId().compareTo(m2.getId());
501                                                 return m2.getId().compareTo(m1.getId());
502                                         case 1:
503                                                 if(ascending)
504                                                         return m1.getUserClass().getName().compareTo(m2.getUserClass().getName());
505                                                 return m2.getUserClass().getName().compareTo(m1.getUserClass().getName());
506                                         case 2:
507                                                 if(ascending)
508                                                         return m1.isActive().compareTo(m2.isActive());
509                                                 return m2.isActive().compareTo(m1.isActive());
510                                         case 3:
511                                                 if(ascending)
512                                                         return m1.getUsername().compareTo(m2.getUsername());
513                                                 return m2.getUsername().compareTo(m1.getUsername());
514                                         case 4:
515                                                 if(ascending)
516                                                         return m1.getEmail().compareTo(m2.getEmail());
517                                                 return m2.getEmail().compareTo(m1.getEmail());
518                                         case 5:
519                                                 if(ascending)
520                                                         return m1.getName().compareTo(m2.getName());
521                                                 return m2.getName().compareTo(m1.getName());
522                                         case 6:
523                                                 return new DateComparator(ascending).compare(m2, m1);
524                                         default:
525
526                                 }
527                                 String s1 = m1.getUsername();
528                                 String s2 = m2.getUsername();
529                                 if(ascending)
530                                         return s1.compareTo(s2);
531                                 return s2.compareTo(s1);
532                         }
533                 }
534
535
536                 public final static class DateComparator implements Comparator<UserDTO> {
537
538                         private final boolean ascending;
539
540                         public DateComparator(boolean isAscending) {
541                                 ascending = isAscending;
542                         }
543
544                         @Override
545                         public int compare(UserDTO m1, UserDTO m2) {
546                                 final Date d1 = m1.getLastLoginDate();
547                                 final Date d2 = m2.getLastLoginDate();
548                                 if(d1==null && d2==null)
549                                         return 0;
550                                 if(d1==null && d2 != null)
551                                         return -1;
552                                 if(d2==null && d1 != null)
553                                         return 1;
554                                 if(ascending)
555                                         return d1.compareTo(d2);
556                                 return d2.compareTo(d1);
557                         }
558                 }
559         }
560
561
562
563 }