summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xscripts/merge.sh6
-rw-r--r--src/com/vaadin/terminal/gwt/client/Util.java14
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java23
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java23
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java64
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VWindow.java6
-rw-r--r--tests/integration_tests.xml2
-rw-r--r--tests/server-side/com/vaadin/tests/server/SourceFileChecker.java77
-rw-r--r--tests/test.xml2
-rw-r--r--tests/testbench/com/vaadin/launcher/DevelopmentServerLauncher.java2
-rw-r--r--tests/testbench/com/vaadin/tests/components/table/HeaderFooterClickLeftRightMiddle.html92
-rw-r--r--tests/testbench/com/vaadin/tests/components/table/HeaderFooterClickLeftRightMiddle.java154
12 files changed, 420 insertions, 45 deletions
diff --git a/scripts/merge.sh b/scripts/merge.sh
index 40423691e8..a8c356ad30 100755
--- a/scripts/merge.sh
+++ b/scripts/merge.sh
@@ -28,6 +28,12 @@ sourceurl="$currentrepowithoutversion/$FROM"
msg=`svn log $sourceurl -r $REVISION --xml|grep "<msg>"|sed "s/<msg>//"|sed "s/<\/msg>//"`
svn merge $sourceurl . -c $REVISION
+if [ "$?" != "0" ]
+then
+ echo "Merge failed. Conflicts must be resolved manually!"
+ exit 3
+fi
+
msg="[merge from $FROM] $msg"
if [ "$AUTOCOMMIT" = "autocommit" ]
then
diff --git a/src/com/vaadin/terminal/gwt/client/Util.java b/src/com/vaadin/terminal/gwt/client/Util.java
index 4514adf7e0..135ab04c98 100644
--- a/src/com/vaadin/terminal/gwt/client/Util.java
+++ b/src/com/vaadin/terminal/gwt/client/Util.java
@@ -1205,4 +1205,18 @@ public class Util {
cur = cur.parentNode;
}
}-*/;
+
+ /**
+ * Checks if the given event is either a touch event or caused by the left
+ * mouse button
+ *
+ * @param event
+ * @return true if the event is a touch event or caused by the left mouse
+ * button, false otherwise
+ */
+ public static boolean isTouchEventOrLeftMouseButton(Event event) {
+ int eventType = event.getTypeInt();
+ boolean touchEvent = Util.isTouchEvent(event);
+ return touchEvent || event.getButton() == Event.BUTTON_LEFT;
+ }
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java
index 376fbd227b..96be51dab0 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java
@@ -627,8 +627,16 @@ public class VCalendarPanel extends FocusableFlexTable implements
* Selects the previous year
*/
private void focusPreviousYear(int years) {
+ int currentMonth = focusedDate.getMonth();
focusedDate.setYear(focusedDate.getYear() - years);
displayedMonth.setYear(displayedMonth.getYear() - years);
+ /*
+ * If the focused date was a leap day (Feb 29), the new date becomes Mar
+ * 1 if the new year is not also a leap year. Set it to Feb 28 instead.
+ */
+ if (focusedDate.getMonth() != currentMonth) {
+ focusedDate.setDate(0);
+ }
renderCalendar();
}
@@ -636,8 +644,16 @@ public class VCalendarPanel extends FocusableFlexTable implements
* Selects the next year
*/
private void focusNextYear(int years) {
+ int currentMonth = focusedDate.getMonth();
focusedDate.setYear(focusedDate.getYear() + years);
displayedMonth.setYear(displayedMonth.getYear() + years);
+ /*
+ * If the focused date was a leap day (Feb 29), the new date becomes Mar
+ * 1 if the new year is not also a leap year. Set it to Feb 28 instead.
+ */
+ if (focusedDate.getMonth() != currentMonth) {
+ focusedDate.setDate(0);
+ }
renderCalendar();
}
@@ -1197,8 +1213,9 @@ public class VCalendarPanel extends FocusableFlexTable implements
if (value == null) {
focusedDate = displayedMonth = null;
} else {
- focusedDate = (Date) value.clone();
- displayedMonth = (Date) value.clone();
+ focusedDate = new Date(value.getYear(), value.getMonth(),
+ value.getDate());
+ displayedMonth = new Date(value.getYear(), value.getMonth(), 1);
}
// Re-render calendar if month or year of focused date has changed
@@ -1212,7 +1229,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
}
if (!hasFocus) {
- focusDay((Date) null);
+ focusDay(null);
}
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java
index 7006a82fd1..5305bf6a23 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java
@@ -1003,6 +1003,20 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
* The filter to apply to the components
*/
public void filterOptions(int page, String filter) {
+ filterOptions(page, filter, true);
+ }
+
+ /**
+ * Filters the options at certain page using the given filter
+ *
+ * @param page
+ * The page to filter
+ * @param filter
+ * The filter to apply to the options
+ * @param immediate
+ * Whether to send the options request immediately
+ */
+ private void filterOptions(int page, String filter, boolean immediate) {
if (filter.equals(lastFilter) && currentPage == page) {
if (!suggestionPopup.isAttached()) {
suggestionPopup.showSuggestions(currentSuggestions,
@@ -1022,7 +1036,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
waitingForFilteringResponse = true;
client.updateVariable(paintableId, "filter", filter, false);
- client.updateVariable(paintableId, "page", page, true);
+ client.updateVariable(paintableId, "page", page, immediate);
lastFilter = filter;
currentPage = page;
}
@@ -1404,7 +1418,12 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
// ask suggestionPopup if it was just closed, we are using GWT
// Popup's auto close feature
if (!suggestionPopup.isJustClosed()) {
- filterOptions(-1, "");
+ // If a focus event is not going to be sent, send the options
+ // request immediately; otherwise queue in the same burst as the
+ // focus event. Fixes #8321.
+ boolean immediate = focused
+ || !client.hasEventListeners(this, EventId.FOCUS);
+ filterOptions(-1, "", immediate);
popupOpenerClicked = true;
lastFilter = "";
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
index c9be032063..e653e1e7b4 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
@@ -2150,7 +2150,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
DOM.appendChild(td, captionContainer);
- DOM.sinkEvents(td, Event.MOUSEEVENTS | Event.TOUCHEVENTS);
+ DOM.sinkEvents(td, Event.MOUSEEVENTS | Event.ONDBLCLICK
+ | Event.ONCONTEXTMENU | Event.TOUCHEVENTS);
setElement(td);
@@ -2267,8 +2268,18 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
scrollBodyPanel.setFocus(true);
}
handleCaptionEvent(event);
- event.stopPropagation();
- event.preventDefault();
+ boolean stopPropagation = true;
+ if (event.getTypeInt() == Event.ONCONTEXTMENU
+ && !client.hasEventListeners(VScrollTable.this,
+ HEADER_CLICK_EVENT_ID)) {
+ // Prevent showing the browser's context menu only when
+ // there is a header click listener.
+ stopPropagation = false;
+ }
+ if (stopPropagation) {
+ event.stopPropagation();
+ event.preventDefault();
+ }
}
}
}
@@ -2325,7 +2336,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
switch (DOM.eventGetType(event)) {
case Event.ONTOUCHSTART:
case Event.ONMOUSEDOWN:
- if (columnReordering) {
+ if (columnReordering
+ && Util.isTouchEventOrLeftMouseButton(event)) {
if (event.getTypeInt() == Event.ONTOUCHSTART) {
/*
* prevent using this event in e.g. scrolling
@@ -2344,7 +2356,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
case Event.ONMOUSEUP:
case Event.ONTOUCHEND:
case Event.ONTOUCHCANCEL:
- if (columnReordering) {
+ if (columnReordering
+ && Util.isTouchEventOrLeftMouseButton(event)) {
dragging = false;
DOM.releaseCapture(getElement());
if (moved) {
@@ -2371,7 +2384,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
if (!moved) {
// mouse event was a click to header -> sort column
- if (sortable) {
+ if (sortable && Util.isTouchEventOrLeftMouseButton(event)) {
if (sortColumn.equals(cid)) {
// just toggle order
client.updateVariable(paintableId, "sortascending",
@@ -2404,20 +2417,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
break;
}
break;
- case Event.ONCONTEXTMENU:
- if (client.hasWidgetEventListeners(VScrollTable.this,
- HEADER_CLICK_EVENT_ID)) {
- // Prevent showing the browser's context menu when there is
- // a right click listener.
- event.preventDefault();
- }
- break;
case Event.ONDBLCLICK:
fireHeaderClickedEvent(event);
break;
case Event.ONTOUCHMOVE:
case Event.ONMOUSEMOVE:
- if (dragging) {
+ if (dragging && Util.isTouchEventOrLeftMouseButton(event)) {
if (event.getTypeInt() == Event.ONTOUCHMOVE) {
/*
* prevent using this event in e.g. scrolling
@@ -2463,6 +2468,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
private void onResizeEvent(Event event) {
switch (DOM.eventGetType(event)) {
case Event.ONMOUSEDOWN:
+ if (!Util.isTouchEventOrLeftMouseButton(event)) {
+ return;
+ }
isResizing = true;
DOM.setCapture(getElement());
dragStartX = DOM.eventGetClientX(event);
@@ -2471,6 +2479,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
DOM.eventPreventDefault(event);
break;
case Event.ONMOUSEUP:
+ if (!Util.isTouchEventOrLeftMouseButton(event)) {
+ return;
+ }
isResizing = false;
DOM.releaseCapture(getElement());
tHead.disableAutoColumnWidthCalculation(this);
@@ -2485,6 +2496,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
fireColumnResizeEvent(cid, originalWidth, getColWidth(cid));
break;
case Event.ONMOUSEMOVE:
+ if (!Util.isTouchEventOrLeftMouseButton(event)) {
+ return;
+ }
if (isResizing) {
final int deltaX = DOM.eventGetClientX(event) - dragStartX;
if (deltaX == 0) {
@@ -3144,7 +3158,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
DOM.appendChild(td, captionContainer);
- DOM.sinkEvents(td, Event.MOUSEEVENTS);
+ DOM.sinkEvents(td, Event.MOUSEEVENTS | Event.ONDBLCLICK
+ | Event.ONCONTEXTMENU);
setElement(td);
}
@@ -3329,8 +3344,18 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
if (DOM.eventGetType(event) == Event.ONMOUSEUP) {
scrollBodyPanel.setFocus(true);
}
- event.stopPropagation();
- event.preventDefault();
+ boolean stopPropagation = true;
+ if (event.getTypeInt() == Event.ONCONTEXTMENU
+ && !client.hasEventListeners(VScrollTable.this,
+ FOOTER_CLICK_EVENT_ID)) {
+ // Show browser context menu if a footer click listener is
+ // not present
+ stopPropagation = false;
+ }
+ if (stopPropagation) {
+ event.stopPropagation();
+ event.preventDefault();
+ }
}
}
@@ -3341,7 +3366,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* The event to handle
*/
protected void handleCaptionEvent(Event event) {
- if (DOM.eventGetType(event) == Event.ONMOUSEUP) {
+ if (event.getTypeInt() == Event.ONMOUSEUP
+ || event.getTypeInt() == Event.ONDBLCLICK) {
fireFooterClickedEvent(event);
}
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VWindow.java b/src/com/vaadin/terminal/gwt/client/ui/VWindow.java
index 870756fec8..d4c8f74605 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VWindow.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VWindow.java
@@ -643,7 +643,7 @@ public class VWindow extends VOverlay implements Container,
}
private void onResizeEvent(Event event) {
- if (resizable) {
+ if (resizable && Util.isTouchEventOrLeftMouseButton(event)) {
switch (event.getTypeInt()) {
case Event.ONMOUSEDOWN:
case Event.ONTOUCHSTART:
@@ -860,6 +860,10 @@ public class VWindow extends VOverlay implements Container,
}
private void onDragEvent(Event event) {
+ if (!Util.isTouchEventOrLeftMouseButton(event)) {
+ return;
+ }
+
switch (DOM.eventGetType(event)) {
case Event.ONTOUCHSTART:
if (event.getTouches().length() > 1) {
diff --git a/tests/integration_tests.xml b/tests/integration_tests.xml
index 22ad356338..3350a0d215 100644
--- a/tests/integration_tests.xml
+++ b/tests/integration_tests.xml
@@ -13,7 +13,7 @@
<fail unless="test.integration.antfile" message="test.integration.antfile must be set for integration tests to run" />
<!-- Test with these browsers -->
- <property name="test_browsers" value="winxp-firefox9" />
+ <property name="test_browsers" value="winxp-firefox10" />
<!-- Path to key file. Default value -->
<property name="sshkey.file" value="id_dsa" />
diff --git a/tests/server-side/com/vaadin/tests/server/SourceFileChecker.java b/tests/server-side/com/vaadin/tests/server/SourceFileChecker.java
index 5d39472712..3115ce49c8 100644
--- a/tests/server-side/com/vaadin/tests/server/SourceFileChecker.java
+++ b/tests/server-side/com/vaadin/tests/server/SourceFileChecker.java
@@ -4,6 +4,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashSet;
+import java.util.Set;
import junit.framework.Assert;
import junit.framework.TestCase;
@@ -23,6 +24,13 @@ public class SourceFileChecker extends TestCase {
+ "tests/server-side";
public static final String CLIENTSIDE_SRC_DIR = getBaseDir()
+ "tests/client-side";
+ private String externalJavaFiles = "com/vaadin/external";
+ private String buildFiles = "build";
+ private Set<String> alwaysIgnore = new HashSet<String>();
+ {
+ alwaysIgnore.add(".settings");
+ alwaysIgnore.add("eclipse");
+ }
public static String getBaseDir() {
if (baseDirectory != null) {
@@ -37,7 +45,7 @@ public class SourceFileChecker extends TestCase {
}
}
- baseDirectory = "";
+ baseDirectory = "./";
return baseDirectory;
}
@@ -45,14 +53,31 @@ public class SourceFileChecker extends TestCase {
TESTBENCH_SRC_DIR, SERVERSIDE_SRC_DIR, CLIENTSIDE_SRC_DIR };
public void testJavaFilesContainsLicense() throws IOException {
- validateJavaFiles(SRC_DIR, new LicenseChecker(),
- "The following files are missing license information:\n{0}");
+ Set<String> ignore = new HashSet<String>(alwaysIgnore);
+ ignore.add(externalJavaFiles);
+ validateFiles(SRC_DIR, new LicenseChecker(), ignore,
+ "The following files are missing license information:\n{0}",
+ ".java");
+ }
+
+ public void testNonJavaFilesUseUnixNewline() throws IOException {
+ Set<String> ignore = new HashSet<String>(alwaysIgnore);
+ ignore.add(buildFiles);
+
+ for (String suffix : new String[] { ".html", ".css", ".xml" }) {
+ validateFiles(getBaseDir(), new DosNewlineDetector(), ignore,
+ "The following files contain CRLF instead of LF:\n{0}",
+ suffix);
+ }
}
public void testJavaFilesUseUnixNewline() throws IOException {
+ Set<String> ignore = new HashSet<String>(alwaysIgnore);
+ ignore.add(externalJavaFiles);
for (String dir : ALL_SRC_DIRS) {
- validateJavaFiles(dir, new DosNewlineDetector(),
- "The following files contain CRLF instead of LF:\n{0}");
+ validateFiles(dir, new DosNewlineDetector(), ignore,
+ "The following files contain CRLF instead of LF:\n{0}",
+ ".java");
}
}
@@ -60,27 +85,45 @@ public class SourceFileChecker extends TestCase {
void validateFile(File f) throws Exception;
}
- private void validateJavaFiles(String directory, FileValidator validator,
- String errorMessage) {
+ private void validateFiles(String directory, FileValidator validator,
+ Set<String> ignore, String errorMessage, String ending) {
File srcDir = new File(directory);
- System.out.println(new File(".").getAbsolutePath());
HashSet<String> missing = new HashSet<String>();
- validateFiles(srcDir, missing, validator, ".java");
+ validateFiles(directory, srcDir, missing, validator, ending, ignore);
if (!missing.isEmpty()) {
- throw new RuntimeException(errorMessage.replace("{0}",
- missing.toString()));
+ throw new RuntimeException(errorMessage.replace("{0}", missing
+ .toString().replace(',', '\n')));
}
}
- private void validateFiles(File srcDir, HashSet<String> missing,
- FileValidator validator, String suffix) {
- Assert.assertTrue("Directory " + srcDir + " does not exist",
- srcDir.exists());
+ private void validateFiles(String baseDirectory, File directory,
+ HashSet<String> missing, FileValidator validator, String suffix,
+ Set<String> ignores) {
+ Assert.assertTrue("Directory " + directory + " does not exist",
+ directory.exists());
+
+ File[] files = directory.listFiles();
+ if (files == null) {
+ throw new RuntimeException("Listing of directory "
+ + directory.getPath() + " failed");
+ }
+ for (File f : files) {
+ boolean ignoreThis = false;
+ for (String ignore : ignores) {
+ if (new File(baseDirectory, ignore).equals(f)) {
+ ignoreThis = true;
+ continue;
+ }
+ }
+
+ if (ignoreThis) {
+ continue;
+ }
- for (File f : srcDir.listFiles()) {
if (f.isDirectory()) {
- validateFiles(f, missing, validator, suffix);
+ validateFiles(baseDirectory, f, missing, validator, suffix,
+ ignores);
} else if (f.getName().endsWith(suffix)) {
try {
validator.validateFile(f);
diff --git a/tests/test.xml b/tests/test.xml
index 9d060c9a29..2baa26218a 100644
--- a/tests/test.xml
+++ b/tests/test.xml
@@ -11,7 +11,7 @@
<!-- Configuration -->
<!-- ================================================================== -->
<!-- Browsers to use for testing -->
- <property name="browsers-windows" value="winxp-ie8,win7-ie9,winxp-firefox9,winxp-safari5,winxp-googlechrome-stable,winxp-opera11" />
+ <property name="browsers-windows" value="winxp-ie8,win7-ie9,winxp-firefox10,winxp-safari5,winxp-googlechrome-stable,winxp-opera11" />
<property name="browsers-linux" value="linux-firefox3,linux-opera10,linux-googlechrome8" />
<property name="browsers-mac" value="osx-firefox3,osx-opera10,osx-googlechrome8,osx-safari4,osx-safari5" />
diff --git a/tests/testbench/com/vaadin/launcher/DevelopmentServerLauncher.java b/tests/testbench/com/vaadin/launcher/DevelopmentServerLauncher.java
index 0fb346736e..b3a7af42b9 100644
--- a/tests/testbench/com/vaadin/launcher/DevelopmentServerLauncher.java
+++ b/tests/testbench/com/vaadin/launcher/DevelopmentServerLauncher.java
@@ -64,7 +64,7 @@ public class DevelopmentServerLauncher {
try {
url = runServer(serverArgs, "Development Server Mode");
// Start Browser
- if (!serverArgs.containsKey("nogui") && url != null) {
+ if (serverArgs.containsKey("gui") && url != null) {
System.out.println("Starting Web Browser.");
// Open browser into application URL
diff --git a/tests/testbench/com/vaadin/tests/components/table/HeaderFooterClickLeftRightMiddle.html b/tests/testbench/com/vaadin/tests/components/table/HeaderFooterClickLeftRightMiddle.html
new file mode 100644
index 0000000000..dfd001bf5c
--- /dev/null
+++ b/tests/testbench/com/vaadin/tests/components/table/HeaderFooterClickLeftRightMiddle.html
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.table.HeaderFooterClickLeftRightMiddle?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VScrollTable[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]</td>
+ <td>59,8</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::PID_SLog_row_0</td>
+ <td>1. Click on header col1 using left</td>
+</tr>
+<tr>
+ <td>mouseDownRight</td>
+ <td>vaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VScrollTable[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseUpRight</td>
+ <td>vaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VScrollTable[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::PID_SLog_row_0</td>
+ <td>2. Click on header col1 using right</td>
+</tr>
+<tr>
+ <td>doubleClick</td>
+ <td>vaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VScrollTable[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::PID_SLog_row_0</td>
+ <td>3. Double click on header col1 using*</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VScrollTable[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]</td>
+ <td>59,8</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::PID_SLog_row_0</td>
+ <td>4. Click on footer col2 using left</td>
+</tr>
+<tr>
+ <td>mouseDownRight</td>
+ <td>vaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VScrollTable[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseUpRight</td>
+ <td>vaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VScrollTable[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::PID_SLog_row_0</td>
+ <td>5. Click on footer col2 using right</td>
+</tr>
+<tr>
+ <td>doubleClick</td>
+ <td>vaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VScrollTable[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::PID_SLog_row_0</td>
+ <td>6. Double click on footer col2 using*</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/tests/testbench/com/vaadin/tests/components/table/HeaderFooterClickLeftRightMiddle.java b/tests/testbench/com/vaadin/tests/components/table/HeaderFooterClickLeftRightMiddle.java
new file mode 100644
index 0000000000..642067d826
--- /dev/null
+++ b/tests/testbench/com/vaadin/tests/components/table/HeaderFooterClickLeftRightMiddle.java
@@ -0,0 +1,154 @@
+package com.vaadin.tests.components.table;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.tests.util.Log;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Table.FooterClickEvent;
+import com.vaadin.ui.Table.FooterClickListener;
+import com.vaadin.ui.Table.HeaderClickEvent;
+import com.vaadin.ui.Table.HeaderClickListener;
+
+public class HeaderFooterClickLeftRightMiddle extends TestBase {
+
+ private Log log = new Log(10);
+
+ @Override
+ protected void setup() {
+ final Table table = new Table();
+ table.setColumnReorderingAllowed(true);
+ table.setContainerDataSource(createContainer());
+ table.setWidth("400px");
+ table.setHeight("400px");
+ table.setImmediate(true);
+ table.setFooterVisible(true);
+
+ CheckBox immediateCheckbox = new CheckBox("Immediate");
+ immediateCheckbox.setImmediate(true);
+ immediateCheckbox.setValue(table.isImmediate());
+ immediateCheckbox.addListener(new ClickListener() {
+
+ public void buttonClick(ClickEvent event) {
+ table.setImmediate(event.getButton().booleanValue());
+ }
+ });
+
+ CheckBox headerClickListenerCheckbox = new CheckBox(
+ "Header click listener");
+ headerClickListenerCheckbox.setImmediate(true);
+ headerClickListenerCheckbox.addListener(new ValueChangeListener() {
+
+ private HeaderClickListener headerClickListener = new HeaderClickListener() {
+
+ public void headerClick(HeaderClickEvent event) {
+ String type = event.isDoubleClick() ? "Double click"
+ : "Click";
+ log.log(type + " on header "
+ + event.getPropertyId().toString() + " using "
+ + event.getButtonName());
+ }
+
+ };
+
+ public void valueChange(ValueChangeEvent event) {
+ if (table.getListeners(HeaderClickEvent.class).isEmpty()) {
+ table.addListener(headerClickListener);
+ } else {
+ table.removeListener(headerClickListener);
+ }
+ }
+ });
+ headerClickListenerCheckbox.setValue(true);
+
+ CheckBox footerClickListenerCheckbox = new CheckBox(
+ "Footer click listener");
+ footerClickListenerCheckbox.setImmediate(true);
+ footerClickListenerCheckbox.addListener(new ValueChangeListener() {
+
+ private FooterClickListener footerClickListener = new FooterClickListener() {
+
+ public void footerClick(FooterClickEvent event) {
+ String type = event.isDoubleClick() ? "Double click"
+ : "Click";
+ log.log(type + " on footer "
+ + event.getPropertyId().toString() + " using "
+ + event.getButtonName());
+ }
+ };
+
+ public void valueChange(ValueChangeEvent event) {
+ if (table.getListeners(FooterClickEvent.class).isEmpty()) {
+ table.addListener(footerClickListener);
+ } else {
+ table.removeListener(footerClickListener);
+ }
+ }
+ });
+ footerClickListenerCheckbox.setValue(true);
+
+ CheckBox sortEnabledCheckbox = new CheckBox("Sortable");
+ sortEnabledCheckbox.setImmediate(true);
+ sortEnabledCheckbox.setValue(!table.isSortDisabled());
+ sortEnabledCheckbox.addListener(new ClickListener() {
+
+ public void buttonClick(ClickEvent event) {
+ table.setSortDisabled(!event.getButton().booleanValue());
+ }
+ });
+
+ CheckBox columnReorderingCheckbox = new CheckBox(
+ "Column reordering allowed");
+ columnReorderingCheckbox.setImmediate(true);
+ columnReorderingCheckbox.setValue(table.isColumnReorderingAllowed());
+ columnReorderingCheckbox.addListener(new ClickListener() {
+
+ public void buttonClick(ClickEvent event) {
+ table.setColumnReorderingAllowed(event.getButton()
+ .booleanValue());
+ }
+ });
+
+ addComponent(immediateCheckbox);
+ addComponent(headerClickListenerCheckbox);
+ addComponent(footerClickListenerCheckbox);
+ addComponent(sortEnabledCheckbox);
+ addComponent(columnReorderingCheckbox);
+ addComponent(table);
+ addComponent(log);
+
+ }
+
+ @Override
+ protected String getDescription() {
+ return "Tests the header click listener";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 4515;
+ }
+
+ private Container createContainer() {
+ IndexedContainer container = new IndexedContainer();
+ container.addContainerProperty("col1", String.class, "");
+ container.addContainerProperty("col2", String.class, "");
+ container.addContainerProperty("col3", String.class, "");
+
+ for (int i = 0; i < 100; i++) {
+ Item item = container.addItem("item " + i);
+ item.getItemProperty("col1").setValue("first" + i);
+ item.getItemProperty("col2").setValue("middle" + i);
+ item.getItemProperty("col3").setValue("last" + i);
+ }
+
+ return container;
+ }
+
+}