Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: frontend/client/src/autotest/common/table/DynamicTable.java

Issue 3554003: Merge remote branch 'cros/upstream' into tempbranch3 (Closed) Base URL: http://git.chromium.org/git/autotest.git
Patch Set: Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 package autotest.common.table; 1 package autotest.common.table;
2 2
3 import autotest.common.SimpleCallback; 3 import autotest.common.SimpleCallback;
4 import autotest.common.table.DataSource.DataCallback; 4 import autotest.common.table.DataSource.DataCallback;
5 import autotest.common.table.DataSource.Query; 5 import autotest.common.table.DataSource.Query;
6 import autotest.common.table.DataSource.SortDirection; 6 import autotest.common.table.DataSource.SortDirection;
7 import autotest.common.table.DataSource.SortSpec; 7 import autotest.common.table.DataSource.SortSpec;
8 import autotest.common.ui.Paginator; 8 import autotest.common.ui.Paginator;
9 9
10 import com.google.gwt.json.client.JSONObject; 10 import com.google.gwt.json.client.JSONObject;
11 import com.google.gwt.user.client.ui.Composite; 11 import com.google.gwt.user.client.ui.Composite;
12 import com.google.gwt.user.client.ui.HTMLPanel; 12 import com.google.gwt.user.client.ui.HTMLPanel;
13 import com.google.gwt.user.client.ui.Image; 13 import com.google.gwt.user.client.ui.Image;
14 14
15 import java.util.ArrayList; 15 import java.util.ArrayList;
16 import java.util.Collections; 16 import java.util.Collections;
17 import java.util.Iterator; 17 import java.util.Iterator;
18 import java.util.List; 18 import java.util.List;
19 19
20 /** 20 /**
21 * Extended DataTable supporting sorting, filtering and pagination. 21 * Extended DataTable supporting sorting, filtering and pagination.
22 */ 22 */
23 public class DynamicTable extends DataTable implements DataCallback { 23 public class DynamicTable extends DataTable implements DataCallback {
24 public static final int NO_COLUMN = -1; 24 public static final int NO_COLUMN = -1;
25 public static final String SORT_UP_IMAGE = "arrow_up.png", 25 public static final String SORT_UP_IMAGE = "arrow_up.png",
26 SORT_DOWN_IMAGE = "arrow_down.png"; 26 SORT_DOWN_IMAGE = "arrow_down.png";
27 27
28 public static interface DynamicTableListener extends DataTableListener { 28 public static interface DynamicTableListener extends DataTableListener {
29 public void onTableRefreshed(); 29 public void onTableRefreshed();
30 } 30 }
31 31
32 static class SortIndicator extends Composite { 32 static class SortIndicator extends Composite {
33 public int column; 33 public int column;
34 private Image image = new Image(); 34 private Image image = new Image();
35 35
36 public SortIndicator(int column) { 36 public SortIndicator(int column) {
37 this.column = column; 37 this.column = column;
38 initWidget(image); 38 initWidget(image);
39 setVisible(false); 39 setVisible(false);
40 } 40 }
41 41
42 public void sortOn(SortDirection direction) { 42 public void sortOn(SortDirection direction) {
43 image.setUrl(direction == SortDirection.ASCENDING ? SORT_UP_IMAGE : SORT_DOWN_IMAGE); 43 image.setUrl(direction == SortDirection.ASCENDING ? SORT_UP_IMAGE : SORT_DOWN_IMAGE);
44 setVisible(true); 44 setVisible(true);
45 } 45 }
46 46
47 public void sortOff() { 47 public void sortOff() {
48 setVisible(false); 48 setVisible(false);
49 } 49 }
50 } 50 }
51 51
52 protected DataSource dataSource; 52 protected DataSource dataSource;
53 private Query currentQuery; 53 private Query currentQuery;
54 54
55 private boolean clientSortable = false; 55 private boolean clientSortable = false;
56 private SortIndicator[] sortIndicators; 56 private SortIndicator[] sortIndicators;
57 private List<SortSpec> sortColumns = new ArrayList<SortSpec>(); 57 private List<SortSpec> sortColumns = new ArrayList<SortSpec>();
58 58
59 protected List<Filter> filters = new ArrayList<Filter>(); 59 protected List<Filter> filters = new ArrayList<Filter>();
60 protected List<Paginator> paginators = new ArrayList<Paginator>(); 60 protected List<Paginator> paginators = new ArrayList<Paginator>();
61 protected Integer rowsPerPage; 61 protected Integer rowsPerPage;
62 62
63 protected List<DynamicTableListener> dynamicTableListeners = 63 protected List<DynamicTableListener> dynamicTableListeners =
64 new ArrayList<DynamicTableListener>(); 64 new ArrayList<DynamicTableListener>();
65 65
66 public DynamicTable(String[][] columns, DataSource dataSource) { 66 public DynamicTable(String[][] columns, DataSource dataSource) {
67 super(columns); 67 super(columns);
68 setDataSource(dataSource); 68 setDataSource(dataSource);
69 } 69 }
70 70
71 // SORTING 71 // SORTING
72 72
73 /** 73 /**
74 * Makes the table client sortable, that is, sortable by the user by 74 * Makes the table client sortable, that is, sortable by the user by
75 * clicking on column headers. 75 * clicking on column headers.
76 */ 76 */
77 public void makeClientSortable() { 77 public void makeClientSortable() {
78 this.clientSortable = true; 78 this.clientSortable = true;
79 table.getRowFormatter().addStyleName(0, 79 table.getRowFormatter().addStyleName(0,
80 DataTable.HEADER_STYLE + "-sortable"); 80 DataTable.HEADER_STYLE + "-sortable");
81 81
82 sortIndicators = new SortIndicator[columns.length]; 82 sortIndicators = new SortIndicator[columns.length];
83 for(int i = 0; i < columns.length; i++) { 83 for(int i = 0; i < columns.length; i++) {
84 sortIndicators[i] = new SortIndicator(i); 84 sortIndicators[i] = new SortIndicator(i);
85 85
86 // we have to use an HTMLPanel here to preserve styles correctly and 86 // we have to use an HTMLPanel here to preserve styles correctly and
87 // not break hover 87 // not break hover
88 // we add a <span> with a unique ID to hold the sort indicator 88 // we add a <span> with a unique ID to hold the sort indicator
89 String name = columns[i][COL_TITLE]; 89 String name = columns[i][COL_TITLE];
90 String id = HTMLPanel.createUniqueId(); 90 String id = HTMLPanel.createUniqueId();
91 HTMLPanel panel = new HTMLPanel(name + 91 HTMLPanel panel = new HTMLPanel(name +
92 " <span id=\"" + id + "\"></span>"); 92 " <span id=\"" + id + "\"></span>");
93 panel.add(sortIndicators[i], id); 93 panel.add(sortIndicators[i], id);
94 table.setWidget(0, i, panel); 94 table.setWidget(0, i, panel);
95 } 95 }
96 } 96 }
97 97
98 private void updateSortIndicators() { 98 private void updateSortIndicators() {
99 if (!clientSortable) { 99 if (!clientSortable) {
100 return; 100 return;
101 } 101 }
102 102
103 SortSpec firstSpec = getFirstSortSpec(); 103 SortSpec firstSpec = getFirstSortSpec();
104 for (SortIndicator indicator : sortIndicators) { 104 for (SortIndicator indicator : sortIndicators) {
105 if (columns[indicator.column][COL_NAME].equals(firstSpec.getField()) ) { 105 if (columns[indicator.column][COL_NAME].equals(firstSpec.getField()) ) {
106 indicator.sortOn(firstSpec.getDirection()); 106 indicator.sortOn(firstSpec.getDirection());
107 } else { 107 } else {
108 indicator.sortOff(); 108 indicator.sortOff();
109 } 109 }
110 } 110 }
111 } 111 }
112 112
113 private SortSpec getFirstSortSpec() { 113 private SortSpec getFirstSortSpec() {
114 if (sortColumns.isEmpty()) { 114 if (sortColumns.isEmpty()) {
115 return null; 115 return null;
116 } 116 }
117 return sortColumns.get(0); 117 return sortColumns.get(0);
118 } 118 }
119 119
120 /** 120 /**
121 * Set column on which data is sorted. You must call <code>refresh()</code> 121 * Set column on which data is sorted. You must call <code>refresh()</code>
122 * after this to display the results. 122 * after this to display the results.
123 * @param columnField field of the column to sort on 123 * @param columnField field of the column to sort on
124 * @param sortDirection DynamicTable.ASCENDING or DynamicTable.DESCENDING 124 * @param sortDirection DynamicTable.ASCENDING or DynamicTable.DESCENDING
125 */ 125 */
126 public void sortOnColumn(String columnField, SortDirection sortDirection) { 126 public void sortOnColumn(String columnField, SortDirection sortDirection) {
127 // remove any existing sort on this column 127 // remove any existing sort on this column
128 for (Iterator<SortSpec> i = sortColumns.iterator(); i.hasNext(); ) { 128 for (Iterator<SortSpec> i = sortColumns.iterator(); i.hasNext(); ) {
129 if (i.next().getField().equals(columnField)) { 129 if (i.next().getField().equals(columnField)) {
130 i.remove(); 130 i.remove();
131 break; 131 break;
132 } 132 }
133 } 133 }
134 134
135 sortColumns.add(0, new SortSpec(columnField, sortDirection)); 135 sortColumns.add(0, new SortSpec(columnField, sortDirection));
136 updateSortIndicators(); 136 updateSortIndicators();
137 } 137 }
138 138
139 /** 139 /**
140 * Defaults to ascending order. 140 * Defaults to ascending order.
141 */ 141 */
142 public void sortOnColumn(String columnField) { 142 public void sortOnColumn(String columnField) {
143 sortOnColumn(columnField, SortDirection.ASCENDING); 143 sortOnColumn(columnField, SortDirection.ASCENDING);
144 } 144 }
145 145
146 public void clearSorts() { 146 public void clearSorts() {
147 sortColumns.clear(); 147 sortColumns.clear();
148 updateSortIndicators(); 148 updateSortIndicators();
149 } 149 }
150 150
151 // PAGINATION 151 // PAGINATION
152 152
153 /** 153 /**
154 * Attach a new paginator to this table. 154 * Attach a new paginator to this table.
155 */ 155 */
156 public void attachPaginator(Paginator paginator) { 156 public void attachPaginator(Paginator paginator) {
157 assert rowsPerPage != null; 157 assert rowsPerPage != null;
158 paginators.add(paginator); 158 paginators.add(paginator);
159 paginator.addCallback(new SimpleCallback() { 159 paginator.addCallback(new SimpleCallback() {
160 public void doCallback(Object source) { 160 public void doCallback(Object source) {
161 setPaginatorStart(((Paginator) source).getStart()); 161 setPaginatorStart(((Paginator) source).getStart());
162 fetchPage(); 162 fetchPage();
163 } 163 }
164 }); 164 });
165 paginator.setResultsPerPage(rowsPerPage.intValue()); 165 paginator.setResultsPerPage(rowsPerPage.intValue());
166 } 166 }
167 167
168 /** 168 /**
169 * Set the page size of this table (only useful if you attach paginators). 169 * Set the page size of this table (only useful if you attach paginators).
170 */ 170 */
171 public void setRowsPerPage(int rowsPerPage) { 171 public void setRowsPerPage(int rowsPerPage) {
172 assert rowsPerPage > 0; 172 assert rowsPerPage > 0;
173 this.rowsPerPage = Integer.valueOf(rowsPerPage); 173 this.rowsPerPage = Integer.valueOf(rowsPerPage);
174 for (Paginator paginator : paginators) { 174 for (Paginator paginator : paginators) {
175 paginator.setResultsPerPage(rowsPerPage); 175 paginator.setResultsPerPage(rowsPerPage);
176 } 176 }
177 } 177 }
178 178
179 /** 179 /**
180 * Set start row for pagination. You must call 180 * Set start row for pagination. You must call
181 * <code>refresh()</code> after this to display the results. 181 * <code>refresh()</code> after this to display the results.
182 */ 182 */
183 public void setPaginatorStart(int start) { 183 public void setPaginatorStart(int start) {
184 for (Paginator paginator : paginators) { 184 for (Paginator paginator : paginators) {
185 paginator.setStart(start); 185 paginator.setStart(start);
186 } 186 }
187 } 187 }
188 188
189 protected void refreshPaginators() { 189 protected void refreshPaginators() {
190 for (Paginator paginator : paginators) { 190 for (Paginator paginator : paginators) {
191 paginator.update(); 191 paginator.update();
192 } 192 }
193 } 193 }
194 194
195 protected void updatePaginatorTotalResults(int totalResults) { 195 protected void updatePaginatorTotalResults(int totalResults) {
196 for (Paginator paginator : paginators) { 196 for (Paginator paginator : paginators) {
197 paginator.setNumTotalResults(totalResults); 197 paginator.setNumTotalResults(totalResults);
198 } 198 }
199 } 199 }
200 200
201 201
202 // FILTERING 202 // FILTERING
203 203
204 public void addFilter(Filter filter) { 204 public void addFilter(Filter filter) {
205 filters.add(filter); 205 filters.add(filter);
206 filter.addCallback(new SimpleCallback() { 206 filter.addCallback(new SimpleCallback() {
207 public void doCallback(Object source) { 207 public void doCallback(Object source) {
208 setPaginatorStart(0); 208 setPaginatorStart(0);
209 refresh(); 209 refresh();
210 } 210 }
211 }); 211 });
212 } 212 }
213 213
214 protected void addFilterParams(JSONObject params) { 214 protected void addFilterParams(JSONObject params) {
215 for (Filter filter : filters) { 215 for (Filter filter : filters) {
216 if (filter.isActive()) { 216 if (filter.isActive()) {
217 filter.addParams(params); 217 filter.addParams(params);
218 } 218 }
219 } 219 }
220 } 220 }
221 221
222 public boolean isAnyUserFilterActive() { 222 public boolean isAnyUserFilterActive() {
223 for (Filter filter : filters) { 223 for (Filter filter : filters) {
224 if (filter.isUserControlled() && filter.isActive()) { 224 if (filter.isUserControlled() && filter.isActive()) {
225 return true; 225 return true;
226 } 226 }
227 } 227 }
228 228
229 return false; 229 return false;
230 } 230 }
231 231
232 232
233 // DATA MANAGEMENT 233 // DATA MANAGEMENT
234 234
235 public void refresh() { 235 public void refresh() {
236 JSONObject params = new JSONObject(); 236 JSONObject params = new JSONObject();
237 addFilterParams(params); 237 addFilterParams(params);
238 dataSource.query(params, this); 238 dataSource.query(params, this);
239 } 239 }
240 240
241 @Override 241 @Override
242 public void onQueryReady(Query query) { 242 public void onQueryReady(Query query) {
243 currentQuery = query; 243 currentQuery = query;
244 if (!paginators.isEmpty()) { 244 if (!paginators.isEmpty()) {
(...skipping 26 matching lines...) Expand all
271 public void handlePage(List<JSONObject> data) { 271 public void handlePage(List<JSONObject> data) {
272 clear(); 272 clear();
273 addRows(data); 273 addRows(data);
274 refreshPaginators(); 274 refreshPaginators();
275 notifyListenersRefreshed(); 275 notifyListenersRefreshed();
276 } 276 }
277 277
278 public String[] getRowData(int row) { 278 public String[] getRowData(int row) {
279 String[] data = new String[columns.length]; 279 String[] data = new String[columns.length];
280 for (int i = 0; i < columns.length; i++) { 280 for (int i = 0; i < columns.length; i++) {
281 if(isWidgetColumn(i)) 281 if(isWidgetColumn(i)) {
282 continue; 282 continue;
283 }
283 data[i] = table.getHTML(row, i); 284 data[i] = table.getHTML(row, i);
284 } 285 }
285 return data; 286 return data;
286 } 287 }
287 288
288 public DataSource getDataSource() { 289 public DataSource getDataSource() {
289 return dataSource; 290 return dataSource;
290 } 291 }
291 292
292 public void setDataSource(DataSource dataSource) { 293 public void setDataSource(DataSource dataSource) {
293 this.dataSource = dataSource; 294 this.dataSource = dataSource;
294 } 295 }
295 296
296 public Query getCurrentQuery() { 297 public Query getCurrentQuery() {
297 return currentQuery; 298 return currentQuery;
298 } 299 }
299 300
300 301
301 // INPUT 302 // INPUT
302 303
303 @Override 304 @Override
304 protected void onCellClicked(int row, int cell, boolean isRightClick) { 305 protected void onCellClicked(int row, int cell, boolean isRightClick) {
305 if (row == headerRow) { 306 if (row == headerRow) {
306 if (isWidgetColumn(cell)) { 307 if (isWidgetColumn(cell)) {
307 // ignore sorting on widget columns 308 // ignore sorting on widget columns
308 return; 309 return;
309 } 310 }
310 String columnName = columns[cell][COL_NAME]; 311 String columnName = columns[cell][COL_NAME];
311 SortDirection newSortDirection = SortDirection.ASCENDING; 312 SortDirection newSortDirection = SortDirection.ASCENDING;
312 SortSpec firstSortSpec = getFirstSortSpec(); 313 SortSpec firstSortSpec = getFirstSortSpec();
313 // when clicking on the last sorted field, invert the sort 314 // when clicking on the last sorted field, invert the sort
314 if (firstSortSpec != null && columnName.equals(firstSortSpec.getFiel d())) { 315 if (firstSortSpec != null && columnName.equals(firstSortSpec.getFiel d())) {
315 newSortDirection = invertSortDirection(firstSortSpec.getDirectio n()); 316 newSortDirection = invertSortDirection(firstSortSpec.getDirectio n());
316 } 317 }
317 318
318 sortOnColumn(columnName, newSortDirection); 319 sortOnColumn(columnName, newSortDirection);
319 refresh(); 320 refresh();
320 return; 321 return;
321 } 322 }
322 323
323 super.onCellClicked(row, cell, isRightClick); 324 super.onCellClicked(row, cell, isRightClick);
324 } 325 }
325 326
326 private SortDirection invertSortDirection(SortDirection direction) { 327 private SortDirection invertSortDirection(SortDirection direction) {
327 return direction == SortDirection.ASCENDING ? 328 return direction == SortDirection.ASCENDING ?
328 SortDirection.DESCENDING : SortDirection .ASCENDING; 329 SortDirection.DESCENDING : SortDirection .ASCENDING;
329 } 330 }
330 331
331 public void addListener(DynamicTableListener listener) { 332 public void addListener(DynamicTableListener listener) {
332 super.addListener(listener); 333 super.addListener(listener);
333 dynamicTableListeners.add(listener); 334 dynamicTableListeners.add(listener);
334 } 335 }
335 336
336 public void removeListener(DynamicTableListener listener) { 337 public void removeListener(DynamicTableListener listener) {
337 super.removeListener(listener); 338 super.removeListener(listener);
338 dynamicTableListeners.remove(listener); 339 dynamicTableListeners.remove(listener);
339 } 340 }
340 341
341 protected void notifyListenersRefreshed() { 342 protected void notifyListenersRefreshed() {
342 for (DynamicTableListener listener : dynamicTableListeners) { 343 for (DynamicTableListener listener : dynamicTableListeners) {
343 listener.onTableRefreshed(); 344 listener.onTableRefreshed();
344 } 345 }
345 } 346 }
346 347
347 public List<SortSpec> getSortSpecs() { 348 public List<SortSpec> getSortSpecs() {
348 return Collections.unmodifiableList(sortColumns); 349 return Collections.unmodifiableList(sortColumns);
349 } 350 }
350 351
351 public void onError(JSONObject errorObject) { 352 public void onError(JSONObject errorObject) {
352 // nothing to do 353 // nothing to do
353 } 354 }
354 } 355 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698