Add support for horizontal alignment in the LayoutList columns.
[online-glom:gwt-glom.git] / src / main / java / org / glom / web / client / LayoutListView.java
1 /*
2  * Copyright (C) 2010, 2011 Openismus GmbH
3  *
4  * This file is part of GWT-Glom.
5  *
6  * GWT-Glom is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * GWT-Glom is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
14  * for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with GWT-Glom.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 package org.glom.web.client;
21
22 import java.util.ArrayList;
23
24 import org.glom.web.shared.ColumnInfo;
25 import org.glom.web.shared.GlomField;
26
27 import com.google.gwt.cell.client.AbstractCell;
28 import com.google.gwt.safehtml.shared.SafeHtml;
29 import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
30 import com.google.gwt.safehtml.shared.SafeHtmlUtils;
31 import com.google.gwt.user.cellview.client.CellTable;
32 import com.google.gwt.user.cellview.client.Column;
33 import com.google.gwt.user.cellview.client.ColumnSortEvent.AsyncHandler;
34 import com.google.gwt.user.cellview.client.ColumnSortList;
35 import com.google.gwt.user.cellview.client.ColumnSortList.ColumnSortInfo;
36 import com.google.gwt.user.cellview.client.SafeHtmlHeader;
37 import com.google.gwt.user.cellview.client.SimplePager;
38 import com.google.gwt.user.client.rpc.AsyncCallback;
39 import com.google.gwt.user.client.ui.Composite;
40 import com.google.gwt.user.client.ui.HasHorizontalAlignment;
41 import com.google.gwt.user.client.ui.VerticalPanel;
42 import com.google.gwt.view.client.AsyncDataProvider;
43 import com.google.gwt.view.client.HasData;
44 import com.google.gwt.view.client.Range;
45
46 public class LayoutListView extends Composite {
47
48         private class GlomFieldCell extends AbstractCell<GlomField> {
49
50                 // The SafeHtml class is used to escape strings to avoid XSS attacks. This is not strictly
51                 // neccessary because the values aren't coming from a user but I'm using it anyway as a reminder.
52                 @Override
53                 public void render(Context context, GlomField value, SafeHtmlBuilder sb) {
54                         if (value == null) {
55                                 return;
56                         }
57
58                         // get the foreground and background colours if they're set
59                         SafeHtml fgcolour = null, bgcolour = null;
60                         String colour = value.getFGColour();
61                         if (colour == null) {
62                                 fgcolour = SafeHtmlUtils.fromSafeConstant("");
63                         } else {
64                                 fgcolour = SafeHtmlUtils.fromString("color:" + colour + ";");
65                         }
66                         colour = value.getBGColour();
67                         if (colour == null) {
68                                 bgcolour = SafeHtmlUtils.fromSafeConstant("");
69                         } else {
70                                 bgcolour = SafeHtmlUtils.fromString("background-color:" + colour + ";");
71                         }
72
73                         // set the text and colours
74                         sb.appendHtmlConstant("<div style=\"" + fgcolour.asString() + bgcolour.asString() + "\">");
75                         sb.append(SafeHtmlUtils.fromString(value.getText()));
76                         sb.appendHtmlConstant("</div>");
77                 }
78         }
79
80         private abstract class GlomFieldColumn extends Column<GlomField[], GlomField> {
81                 public GlomFieldColumn() {
82                         super(new GlomFieldCell());
83                 }
84         }
85
86         public LayoutListView(ColumnInfo[] columns, int numRows) {
87                 final CellTable<GlomField[]> table = new CellTable<GlomField[]>(20);
88
89                 AsyncDataProvider<GlomField[]> dataProvider = new AsyncDataProvider<GlomField[]>() {
90                         @Override
91                         @SuppressWarnings("unchecked")
92                         protected void onRangeChanged(HasData<GlomField[]> display) {
93                                 // setup the callback object
94                                 final Range range = display.getVisibleRange();
95                                 final int start = range.getStart();
96                                 AsyncCallback<ArrayList<GlomField[]>> callback = new AsyncCallback<ArrayList<GlomField[]>>() {
97                                         public void onFailure(Throwable caught) {
98                                                 // FIXME: need to deal with failure
99                                                 System.out.println("AsyncCallback Failed: OnlineGlomService.getTableData()");
100                                         }
101
102                                         public void onSuccess(ArrayList<GlomField[]> result) {
103                                                 updateRowData(start, result);
104                                         }
105                                 };
106
107                                 // get data from the server
108                                 ColumnSortList colSortList = table.getColumnSortList();
109                                 if (colSortList.size() > 0) {
110                                         // ColumnSortEvent has been requested by the user
111                                         ColumnSortInfo info = colSortList.get(0);
112                                         OnlineGlomServiceAsync.Util.getInstance().getSortedTableData(OnlineGlom.getCurrentTableName(),
113                                                         start, range.getLength(), table.getColumnIndex((Column<GlomField[], ?>) info.getColumn()),
114                                                         info.isAscending(), callback);
115                                 } else {
116                                         OnlineGlomServiceAsync.Util.getInstance().getTableData(OnlineGlom.getCurrentTableName(), start,
117                                                         range.getLength(), callback);
118                                 }
119                         }
120                 };
121
122                 dataProvider.addDataDisplay(table);
123
124                 SimplePager pager = new SimplePager(SimplePager.TextLocation.CENTER);
125                 pager.setDisplay(table);
126
127                 // a panel to hold our widgets
128                 VerticalPanel panel = new VerticalPanel();
129                 panel.add(table);
130                 panel.add(pager);
131
132                 // create instances of GlomFieldColumn to retrieve the GlomField objects
133                 for (int i = 0; i < columns.length; i++) {
134                         // create a new column
135                         final int j = new Integer(i);
136                         GlomFieldColumn column = new GlomFieldColumn() {
137                                 @Override
138                                 public GlomField getValue(GlomField[] object) {
139                                         return object[j];
140                                 }
141                         };
142
143                         // set column properties and add to cell table
144                         switch (columns[i].getAlignment()) {
145                         case HORIZONTAL_ALIGNMENT_LEFT:
146                                 column.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
147                                 break;
148                         case HORIZONTAL_ALIGNMENT_RIGHT:
149                                 column.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
150                                 break;
151                         case HORIZONTAL_ALIGNMENT_AUTO:
152                         default:
153                                 // TODO: log warning, this shouldn't happen
154                                 column.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_DEFAULT);
155                                 break;
156                         }
157                         column.setSortable(true);
158                         table.addColumn(column, new SafeHtmlHeader(SafeHtmlUtils.fromString(columns[i].getHeader())));
159                 }
160
161                 // set row count which is needed for paging
162                 table.setRowCount(numRows);
163
164                 // adds an AsyncHandler to activate sorting for the AsyncDataProvider that was created above
165                 table.addColumnSortHandler(new AsyncHandler(table));
166
167                 // take care of the stuff required for composite widgets
168                 initWidget(panel);
169                 setStyleName("glom-LayoutListView");
170         }
171
172 }