summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJohn Alhroos <john.ahlroos@itmill.com>2010-04-13 07:38:05 +0000
committerJohn Alhroos <john.ahlroos@itmill.com>2010-04-13 07:38:05 +0000
commitbaecc2e6fb381c85455b828408b3406c9c22febf (patch)
treef872dd50575c7d878975b77dd6e8a0bb8fdb6494 /src
parent6907aa39e53f3a2ea7ba07436e07b34101c3a8ca (diff)
downloadvaadin-framework-baecc2e6fb381c85455b828408b3406c9c22febf.tar.gz
vaadin-framework-baecc2e6fb381c85455b828408b3406c9c22febf.zip
Implemented CTRL and SHIFT clicking in Table #3520
svn changeset:12494/svn branch:6.4
Diffstat (limited to 'src')
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java112
-rw-r--r--src/com/vaadin/ui/Table.java43
2 files changed, 149 insertions, 6 deletions
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
index 72efa90ab4..37ad81fce5 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
@@ -12,6 +12,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Set;
+import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.NodeList;
@@ -166,6 +167,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
private boolean rendering = false;
private int dragmode;
+ private int multiselectmode;
+ private int lastSelectedRowKey = -1;
+
public VScrollTable() {
bodyContainer.addScrollHandler(this);
bodyContainer.setStyleName(CLASSNAME + "-body");
@@ -210,6 +214,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
dragmode = uidl.hasAttribute("dragmode") ? uidl
.getIntAttribute("dragmode") : 0;
+ multiselectmode = uidl.hasAttribute("multiselectmode") ? uidl
+ .getIntAttribute("multiselectmode") : 0;
+
setCacheRate(uidl.hasAttribute("cr") ? uidl.getDoubleAttribute("cr")
: CACHE_RATE_DEFAULT);
@@ -2353,7 +2360,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
}
}
if (uidl.hasAttribute("selected") && !isSelected()) {
- toggleSelection();
+ toggleSelection(true);
}
}
@@ -2484,6 +2491,18 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
}
}
+ /**
+ * Add this to the element mouse down event by using
+ * element.setPropertyJSO
+ * ("onselectstart",applyDisableTextSelectionIEHack()); Remove it
+ * then again when the mouse is depressed in the mouse up event.
+ *
+ * @return Returns the JSO preventing text selection
+ */
+ private native JavaScriptObject applyDisableTextSelectionIEHack()/*-{
+ return function(){ return false; };
+ }-*/;
+
/*
* React on click that occur on content cells only
*/
@@ -2501,7 +2520,26 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
handleClickEvent(event, targetTdOrTr);
if (event.getButton() == Event.BUTTON_LEFT
&& selectMode > Table.SELECT_MODE_NONE) {
- toggleSelection();
+
+ if (event.getCtrlKey()
+ && selectMode == SELECT_MODE_MULTI
+ && multiselectmode == 0) {
+ toggleSelection(true);
+ } else if (event.getShiftKey()
+ && selectMode == SELECT_MODE_MULTI
+ && multiselectmode == 0) {
+ toggleShiftSelection();
+ } else {
+ if (multiselectmode == 0) {
+ deselectAll();
+ }
+ toggleSelection(multiselectmode == 0);
+ }
+
+ // Remove IE text selection hack
+ event.getTarget().setPropertyJSO(
+ "onselectstart", null);
+
// Note: changing the immediateness of this
// might
// require changes to "clickEvent" immediateness
@@ -2567,6 +2605,19 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
}
event.preventDefault();
event.stopPropagation();
+ } else if (event.getCtrlKey()
+ || event.getShiftKey()
+ && selectMode == SELECT_MODE_MULTI
+ && multiselectmode == 0) {
+ // Prevent default text selection in Firefox
+ event.preventDefault();
+
+ // Prevent default text selection in IE
+ event.getTarget().setPropertyJSO(
+ "onselectstart",
+ applyDisableTextSelectionIEHack());
+
+ event.stopPropagation();
}
break;
case Event.ONMOUSEOUT:
@@ -2646,15 +2697,23 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
event.preventDefault();
}
+ /**
+ * Has the row been selected?
+ *
+ * @return Returns true if selected, else false
+ */
public boolean isSelected() {
return selected;
}
- private void toggleSelection() {
+ /**
+ * Toggle the selection of the row
+ */
+ public void toggleSelection(boolean ctrlSelect) {
selected = !selected;
if (selected) {
- if (selectMode == Table.SELECT_MODE_SINGLE) {
- deselectAll();
+ if (ctrlSelect) {
+ lastSelectedRowKey = rowKey;
}
selectedRowKeys.add(String.valueOf(rowKey));
addStyleName("v-selected");
@@ -2664,6 +2723,47 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
}
}
+ private void toggleShiftSelection() {
+
+ /*
+ * Ensures that we are in multiselect mode and that we have a
+ * previous selection which was not a deselection
+ */
+ if (selectedRowKeys.isEmpty() || lastSelectedRowKey < 0) {
+ deselectAll();
+ toggleSelection(true);
+ return;
+ }
+
+ // Set the selectable range
+ int startKey = lastSelectedRowKey;
+ int endKey = rowKey;
+ if (endKey < startKey) {
+ // Swap keys if in the wrong order
+ startKey ^= endKey;
+ endKey ^= startKey;
+ startKey ^= endKey;
+ }
+
+ // Select the range (not including this row)
+ deselectAll();
+ for (int r = startKey; r <= endKey; r++) {
+ if (r != rowKey) {
+ selectedRowKeys.add(String.valueOf(r));
+ VScrollTableRow row = getRenderedRowByKey(String
+ .valueOf(r));
+ if (!row.isSelected()) {
+ row.toggleSelection(false);
+ }
+ }
+ }
+
+ // Toggle clicked rows selection
+ toggleSelection(false);
+
+ getElement().focus();
+ }
+
/*
* (non-Javadoc)
*
@@ -2768,7 +2868,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
for (int i = 0; i < keys.length; i++) {
final VScrollTableRow row = getRenderedRowByKey((String) keys[i]);
if (row != null && row.isSelected()) {
- row.toggleSelection();
+ row.toggleSelection(false);
}
}
// still ensure all selects are removed from (not necessary rendered)
diff --git a/src/com/vaadin/ui/Table.java b/src/com/vaadin/ui/Table.java
index 610d638ab4..e2c0a0d80f 100644
--- a/src/com/vaadin/ui/Table.java
+++ b/src/com/vaadin/ui/Table.java
@@ -93,6 +93,22 @@ public class Table extends AbstractSelect implements Action.Container,
MULTIROW
}
+ /**
+ * Multi select modes that controls how multi select behaves.
+ */
+ public enum MultiSelectMode {
+ /**
+ * Simple left clicks only selects one item, CTRL+left click selects
+ * multiple items and SHIFT-left click selects a range of items.
+ */
+ DEFAULT,
+ /**
+ * Uses the old method of selection. CTRL- and SHIFT-clicks are disabled and
+ * clicking on the items selects/deselects them.
+ */
+ SIMPLE
+ }
+
private static final int CELL_KEY = 0;
private static final int CELL_HEADER = 1;
@@ -368,6 +384,8 @@ public class Table extends AbstractSelect implements Action.Container,
private DropHandler dropHandler;
+ private MultiSelectMode multiSelectMode = MultiSelectMode.DEFAULT;
+
/* Table constructors */
/**
@@ -2065,6 +2083,10 @@ public class Table extends AbstractSelect implements Action.Container,
target.addAttribute("dragmode", dragMode.ordinal());
}
+ if (multiSelectMode != MultiSelectMode.DEFAULT) {
+ target.addAttribute("multiselectmode", multiSelectMode.ordinal());
+ }
+
// Initialize temps
final Object[] colids = getVisibleColumns();
final int cols = colids.length;
@@ -3433,6 +3455,27 @@ public class Table extends AbstractSelect implements Action.Container,
}
/**
+ * Sets the behavior of how the multi-select mode should behave when the
+ * table is both selectable and in multi-select mode.
+ *
+ * @param mode
+ * The select mode of the table
+ */
+ public void setMultiSelectMode(MultiSelectMode mode) {
+ multiSelectMode = mode;
+ requestRepaint();
+ }
+
+ /**
+ * Returns the select mode in which multi-select is used.
+ *
+ * @return The multi select mode
+ */
+ public MultiSelectMode getMultiSelectMode() {
+ return multiSelectMode;
+ }
+
+ /**
* Lazy loading accept criterion for Table. Accepted target rows are loaded
* from server once per drag and drop operation. Developer must override one
* method that decides on which rows the currently dragged data can be