1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.vaadin.gwt.client.grid;
35
36 import com.google.gwt.dom.client.Document;
37 import com.google.gwt.dom.client.NativeEvent;
38 import com.google.gwt.dom.client.SpanElement;
39 import com.google.gwt.dom.client.TableCellElement;
40 import com.google.gwt.event.logical.shared.ValueChangeEvent;
41 import com.google.gwt.event.logical.shared.ValueChangeHandler;
42 import com.google.gwt.user.client.DOM;
43 import com.google.gwt.user.client.Element;
44 import com.google.gwt.user.client.ui.CheckBox;
45 import com.google.gwt.user.client.ui.HTML;
46 import com.google.gwt.user.client.ui.Widget;
47 import com.googlecode.mgwt.dom.client.recognizer.tap.MultiTapEvent;
48 import com.googlecode.mgwt.dom.client.recognizer.tap.MultiTapHandler;
49 import com.googlecode.mgwt.dom.client.recognizer.tap.MultiTapRecognizer;
50 import com.googlecode.mgwt.ui.client.widget.touch.TouchDelegate;
51 import com.vaadin.client.BrowserInfo;
52 import com.vaadin.client.UIDL;
53 import com.vaadin.client.Util;
54 import com.vaadin.v7.client.ui.VScrollTablePatched;
55
56
57
58
59
60 public class VMagnoliaTable extends VScrollTablePatched {
61
62 static int checkboxWidth = -1;
63
64 public VMagnoliaTable() {
65 super();
66 MagnoliaTableHead head = (MagnoliaTableHead) tHead;
67 head.addToDom();
68 }
69
70 @Override
71 protected TableHead createTableHead() {
72 return new MagnoliaTableHead();
73 }
74
75 @Override
76 protected VScrollTableBody createScrollBody() {
77 return new MagnoliaTableBody();
78 }
79
80 @Override
81 protected HeaderCell createHeaderCell(String colId, String headerText) {
82 return new MagnoliaHeaderCell(colId, headerText);
83 }
84
85 @Override
86 protected void setMultiSelectMode(int multiselectmode) {
87 this.multiselectmode = multiselectmode;
88 }
89
90
91
92
93 public class MagnoliaHeaderCell extends HeaderCell {
94
95 private Element caption = null;
96 private boolean canBeSorted = false;
97
98 public MagnoliaHeaderCell(String colId, String headerText) {
99 super(colId, headerText);
100 caption = DOM.createSpan();
101 captionContainer.appendChild(caption);
102 setText(headerText);
103 }
104
105 @Override
106 public void setText(String headerText) {
107 if (caption != null) {
108 caption.setInnerHTML(headerText);
109 }
110 }
111
112 @Override
113 protected void updateStyleNames(String primaryStyleName) {
114 super.updateStyleNames(primaryStyleName);
115 if (this.canBeSorted) {
116 addStyleName("sortable");
117 }
118 }
119
120 @Override
121 public void setSortable(boolean sortable) {
122 super.setSortable(sortable);
123
124
125 this.canBeSorted = sortable;
126 }
127 }
128
129
130
131
132 public class MagnoliaTableHead extends TableHead {
133
134 private CheckBox selectAll = null;
135
136 public MagnoliaTableHead() {
137 super();
138 selectAll = new CheckBox();
139 selectAll.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
140
141 @Override
142 public void onValueChange(ValueChangeEvent<Boolean> event) {
143 client.updateVariable(paintableId, "selectAll", event.getValue(), true);
144 }
145 });
146 selectAll.addStyleName("v-select-all");
147 }
148
149 public void addToDom() {
150 div.appendChild(selectAll.getElement());
151 getChildren().add(selectAll);
152 adopt(selectAll);
153 }
154
155 public CheckBox getSelectAllCB() {
156 return selectAll;
157 }
158 }
159
160
161
162
163 public class MagnoliaTableBody extends VScrollTableBody {
164
165 @Override
166 protected VScrollTableRow createScrollTableRow(UIDL uidl, char[] aligns) {
167 return new MagnoliaTableRow(uidl, aligns);
168 }
169
170 @Override
171 protected VScrollTableRow createScrollTableRow() {
172 return new MagnoliaTableRow();
173 }
174
175 @Override
176 public int getColWidth(int columnIndex) {
177 return super.getColWidth(columnIndex);
178 }
179
180
181
182
183 public class MagnoliaTableRow extends VScrollTableRow {
184
185 private CheckBox selectionCheckBox;
186
187 private HTML selectionCheckBoxSpacer;
188
189 private String nodeIcon;
190
191 public MagnoliaTableRow(UIDL uidl, char[] aligns) {
192 super(uidl, aligns);
193 }
194
195 public MagnoliaTableRow() {
196 super();
197 }
198
199 @Override
200 protected void updateStyleNames(String primaryStyleName) {
201
202 if (rowStyle != null) {
203 String[] rowStyles = rowStyle.split(" ");
204 for (String style : rowStyles) {
205 if (style.startsWith("icon")) {
206 if (nodeIcon == null) {
207 nodeIcon = style;
208 } else {
209 nodeIcon += " " + style;
210 }
211 }
212 }
213 }
214 super.updateStyleNames(primaryStyleName);
215 }
216
217
218
219
220
221 @Override
222 protected void setElement(com.google.gwt.user.client.Element elem) {
223 super.setElement(elem);
224 privateConstruction();
225 }
226
227 @Override
228 protected void initCellWithText(String text, char align, String style, boolean textIsHTML, boolean sorted, String description, final TableCellElement td) {
229 super.initCellWithText(text, align, style, textIsHTML, sorted, description, td);
230 if (td.equals(this.getElement().getFirstChildElement())) {
231 insertNodeIcon(td);
232 if (isSingleSelectMode()) {
233 insertSelectionCheckboxSpacer(td);
234 } else {
235 insertSelectionCheckbox(td);
236 }
237 }
238 }
239
240 @Override
241 protected void initCellWithWidget(Widget w, char align, String style, boolean sorted, TableCellElement td) {
242 super.initCellWithWidget(w, align, style, sorted, td);
243 if (td.equals(this.getElement().getFirstChildElement())) {
244 insertNodeIcon(td);
245 if (isSingleSelectMode()) {
246 insertSelectionCheckboxSpacer(td);
247 } else {
248 insertSelectionCheckbox(td);
249 }
250 }
251 }
252
253
254
255
256 private void insertSelectionCheckbox(final TableCellElement td) {
257 com.google.gwt.dom.client.Element container = td.getFirstChildElement();
258 container.insertFirst(selectionCheckBox.getElement());
259 }
260
261
262
263
264 private void insertSelectionCheckboxSpacer(final TableCellElement td) {
265 com.google.gwt.dom.client.Element container = td.getFirstChildElement();
266 container.insertFirst(selectionCheckBoxSpacer.getElement());
267 }
268
269 protected void insertNodeIcon(TableCellElement td) {
270 if (nodeIcon != null) {
271 SpanElement iconElement = Document.get().createSpanElement();
272 iconElement.setClassName(nodeIcon);
273 iconElement.addClassName("v-table-icon-element");
274 td.getFirstChild().insertFirst(iconElement);
275 }
276 }
277
278 private void privateConstruction() {
279 selectionCheckBox = new CheckBox();
280 selectionCheckBox.setValue(isSelected(), false);
281 ValueChangeHandler<Boolean> selectionChangeHandler = new ValueChangeHandler<Boolean>() {
282
283 @Override
284 public void onValueChange(ValueChangeEvent<Boolean> event) {
285 if (event.getSource() instanceof Widget) {
286 final Widget source = (Widget) event.getSource();
287 final Element targetTd = source.getElement().getParentElement().cast();
288 VScrollTableRow row = Util.findWidget(targetTd, null);
289 if (row != null) {
290 boolean wasSelected = row.isSelected();
291
292 if (VMagnoliaTable.this.isSingleSelectMode() && !row.isSelected()) {
293 deselectAll();
294 }
295
296 row.toggleSelection();
297 setRowFocus(row);
298
299
300
301 selectionRangeStart = row;
302 if (wasSelected) {
303 removeRowFromUnsentSelectionRanges(row);
304 }
305
306 sendSelectedRows(true);
307 }
308 }
309 }
310 };
311
312 selectionCheckBox.addValueChangeHandler(selectionChangeHandler);
313 selectionCheckBox.addStyleName("v-selection-cb");
314 getChildren().add(selectionCheckBox);
315 VMagnoliaTable.this.adopt(selectionCheckBox);
316
317 selectionCheckBoxSpacer = new HTML();
318 selectionCheckBoxSpacer.addStyleName("v-selection-cb");
319 getChildren().add(selectionCheckBoxSpacer);
320 VMagnoliaTable.this.adopt(selectionCheckBoxSpacer);
321
322 final TouchDelegatet/widget/touch/TouchDelegate.html#TouchDelegate">TouchDelegate delegate = new TouchDelegate(this);
323 delegate.addTouchHandler(new MultiTapRecognizer(delegate, 1, 2));
324 addHandler(new MultiTapHandler() {
325
326 @Override
327 public void onMultiTap(MultiTapEvent event) {
328 if (BrowserInfo.get().isTouchDevice()) {
329 final NativeEvent doubleClickEvent =
330 Document.get().createDblClickEvent(
331 0,
332 event.getTouchStarts().get(0).get(0).getPageX(),
333 event.getTouchStarts().get(0).get(0).getPageY(),
334 event.getTouchStarts().get(0).get(0).getPageX(),
335 event.getTouchStarts().get(0).get(0).getPageY(),
336 false,
337 false,
338 false,
339 false);
340 getElement().dispatchEvent(doubleClickEvent);
341 }
342 }
343 }, MultiTapEvent.getType());
344 }
345
346 @Override
347 public void toggleSelection() {
348 super.toggleSelection();
349
350 if (selectionCheckBox != null) {
351 selectionCheckBox.setValue(isSelected(), false);
352 }
353 MagnoliaTableHead head = (MagnoliaTableHead) tHead;
354 head.getSelectAllCB().setValue(selectedRowKeys.size() == scrollBody.renderedRows.size(), false);
355 }
356
357 @Override
358 protected boolean isRenderHtmlInCells() {
359 return true;
360 }
361 }
362
363 }
364 }