From: Matti Tahvonen Date: Thu, 28 Jan 2010 17:46:50 +0000 (+0000) Subject: some preliminary drag and drop stuff X-Git-Tag: 6.7.0.beta1~1988^2~45 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=810017204ef10e2d5fbea15ed17b0c1e8a6b0daa;p=vaadin-framework.git some preliminary drag and drop stuff svn changeset:11052/svn branch:6.3_dd --- diff --git a/WebContent/VAADIN/readme.txt b/WebContent/VAADIN/readme.txt index 672862a35c..926bc01a9e 100644 --- a/WebContent/VAADIN/readme.txt +++ b/WebContent/VAADIN/readme.txt @@ -29,7 +29,8 @@ Vaadin Development When developing the Vaadin Library itself, change to "build" directory and run "ant widgetsets" to compile all widgetsets or "ant widgetset-default", "ant-widgetset-reserver", or "ant widgetset-colorpicker" to compile individual -widgetsets. You must have GWT installed under build/gwt. +widgetsets. You must have GWT installed under build/gwt, under the proper +platform directory. See http://dev.vaadin.com/wiki/DevDocs/StartingDevelopment for instructions for installing GWT and compiling widgetsets for Vaadin development. diff --git a/WebContent/VAADIN/themes/base/button/button.css b/WebContent/VAADIN/themes/base/button/button.css index aacc05bbb7..9d4bec0fe4 100644 --- a/WebContent/VAADIN/themes/base/button/button.css +++ b/WebContent/VAADIN/themes/base/button/button.css @@ -23,7 +23,11 @@ -moz-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box; - } +} + +.v-button.v-disabled { + cursor: default; +} .v-ie6 .v-button { display: inline; diff --git a/WebContent/VAADIN/themes/base/styles.css b/WebContent/VAADIN/themes/base/styles.css index f1840c6bf2..28d412536e 100644 --- a/WebContent/VAADIN/themes/base/styles.css +++ b/WebContent/VAADIN/themes/base/styles.css @@ -59,7 +59,11 @@ -moz-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box; - } +} + +.v-button.v-disabled { + cursor: default; +} .v-ie6 .v-button { display: inline; diff --git a/WebContent/VAADIN/themes/reindeer/button/button-link-style.css b/WebContent/VAADIN/themes/reindeer/button/button-link-style.css index 14530c8dff..f4ba80b3cd 100644 --- a/WebContent/VAADIN/themes/reindeer/button/button-link-style.css +++ b/WebContent/VAADIN/themes/reindeer/button/button-link-style.css @@ -14,6 +14,11 @@ cursor: pointer; line-height: inherit; } + +.v-button.v-button-link.v-disabled, +.v-button.v-button-link.v-disabled .v-button-wrap { + cursor: default; + } .v-button-link .v-button-caption, .v-nativebutton-link .v-nativebutton-caption { diff --git a/WebContent/VAADIN/themes/reindeer/styles.css b/WebContent/VAADIN/themes/reindeer/styles.css index afb15e49a8..c4d29c78ce 100644 --- a/WebContent/VAADIN/themes/reindeer/styles.css +++ b/WebContent/VAADIN/themes/reindeer/styles.css @@ -1,5 +1,5 @@ -.v-theme-version:after {content:"6_2_0_dev-20091229";} -.v-theme-version-6_2_0_dev-20091229 {display: none;} +.v-theme-version:after {content:"9_9_9_INTERNAL-DEBUG-BUILD";} +.v-theme-version-9_9_9_INTERNAL-DEBUG-BUILD {display: none;} /* Automatically compiled css file from subdirectories. */ .v-absolutelayout-wrapper { @@ -59,7 +59,11 @@ -moz-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box; - } +} + +.v-button.v-disabled { + cursor: default; +} .v-ie6 .v-button { display: inline; @@ -2177,6 +2181,11 @@ div.v-window-header { cursor: pointer; line-height: inherit; } + +.v-button.v-button-link.v-disabled, +.v-button.v-button-link.v-disabled .v-button-wrap { + cursor: default; + } .v-button-link .v-button-caption, .v-nativebutton-link .v-nativebutton-caption { diff --git a/WebContent/VAADIN/themes/runo/styles.css b/WebContent/VAADIN/themes/runo/styles.css index 06bce5dfa9..7e14ce6d40 100644 --- a/WebContent/VAADIN/themes/runo/styles.css +++ b/WebContent/VAADIN/themes/runo/styles.css @@ -59,7 +59,11 @@ -moz-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box; - } +} + +.v-button.v-disabled { + cursor: default; +} .v-ie6 .v-button { display: inline; diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 2e2c1b680e..584c9805bd 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -24,7 +24,7 @@ VaadinApplicationRunner com.vaadin.terminal.gwt.server.ApplicationRunnerServlet defaultPackages - com.vaadin.tests,com.vaadin.demo,com.vaadin.tests.tickets,com.vaadin.tests.components,com.vaadin.tests.components.layouts,com.vaadin.tests.components.panel,com.vaadin.tests.components.combobox,com.vaadin.tests.components.popupview,com.vaadin.tests.components.datefield,com.vaadin.tests.components.richtextarea,com.vaadin.tests.components.absolutelayout,com.vaadin.tests.components.embedded,com.vaadin.tests.components.splitpanel,com.vaadin.tests.components.abstractfield,com.vaadin.tests.components.form,com.vaadin.tests.components.table,com.vaadin.tests.components.accordion,com.vaadin.tests.components.label,com.vaadin.tests.components.tabsheet,com.vaadin.tests.components.beanitemcontainer,com.vaadin.tests.components.link,com.vaadin.tests.components.textfield,com.vaadin.tests.components.button,com.vaadin.tests.components.optiongroup,com.vaadin.tests.components.tree,com.vaadin.tests.components.caption,com.vaadin.tests.components.orderedlayout,com.vaadin.tests.components.window + com.vaadin.tests,com.vaadin.demo,com.vaadin.tests.tickets,com.vaadin.tests.components,com.vaadin.tests.components.layouts,com.vaadin.tests.components.panel,com.vaadin.tests.components.combobox,com.vaadin.tests.components.popupview,com.vaadin.tests.components.datefield,com.vaadin.tests.components.richtextarea,com.vaadin.tests.components.absolutelayout,com.vaadin.tests.components.embedded,com.vaadin.tests.components.splitpanel,com.vaadin.tests.components.abstractfield,com.vaadin.tests.components.form,com.vaadin.tests.components.table,com.vaadin.tests.components.accordion,com.vaadin.tests.components.label,com.vaadin.tests.components.tabsheet,com.vaadin.tests.components.beanitemcontainer,com.vaadin.tests.components.link,com.vaadin.tests.components.textfield,com.vaadin.tests.components.button,com.vaadin.tests.components.optiongroup,com.vaadin.tests.components.tree,com.vaadin.tests.components.caption,com.vaadin.tests.components.orderedlayout,com.vaadin.tests.components.window,com.vaadin.tests.dd diff --git a/WebContent/index.html b/WebContent/index.html index 46bc8846fd..f7c4fe9c32 100644 --- a/WebContent/index.html +++ b/WebContent/index.html @@ -10,7 +10,7 @@ - + diff --git a/WebContent/release-notes.html b/WebContent/release-notes.html index 0de559fda8..398e93d97c 100644 --- a/WebContent/release-notes.html +++ b/WebContent/release-notes.html @@ -34,125 +34,13 @@
  • Requirements
  • -

    Vaadin @version@ is an update release for Vaadin 6. In addition to various fixes, it -contains a number of significant enhancements.

    +

    Vaadin @version@ is a maintenance release for Vaadin 6.2, +containing a number of important fixes. The fixes are listed in the Change Log below.

    - +

    For recent major enhancements, see the Release +Notes for Vaadin 6.2.0.

    Problem fixes and enhancements planned for upcoming releases can be found from the Vaadin Roadmap in Vaadin Trac.

    @@ -162,6 +50,26 @@ widget sets and refresh your project in Eclipse. If you are upgrading from earli 6.2.0, notice that Vaadin 6.2 uses GWT 1.7.0 (included in the installation package). See General Upgrade Notes for more details on upgrading.

    +

    Change Log

    + +

    The following closed issues have been included in this release:

    + + +

    Upgrading from an Earlier Version of Vaadin 6

    @@ -376,101 +284,6 @@ sets with the regular Vaadin package for your platform.

    For other known problems, see open tickets at developer site dev.vaadin.com.

    -

    Change Log

    - -

    The following closed issues have been included in this release:

    - - -

    Requirements

    Vaadin is available for the following operating systems:

    diff --git a/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java b/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java index 6420aaf838..d516c870a2 100644 --- a/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java +++ b/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java @@ -129,16 +129,6 @@ public class ContainerHierarchicalWrapper implements Container.Hierarchical, return 0; } }; - Object[] array = roots.toArray(); - Arrays.sort(array, basedOnOrderFromWrappedContainer); - roots = new LinkedHashSet(); - for (int i = 0; i < array.length; i++) { - roots.add(array[i]); - } - for (Object object : children.keySet()) { - LinkedList object2 = children.get(object); - Collections.sort(object2, basedOnOrderFromWrappedContainer); - } // Calculate the set of all items in the hierarchy final HashSet s = new HashSet(); @@ -163,6 +153,18 @@ public class ContainerHierarchicalWrapper implements Container.Hierarchical, s.add(id); } } + + Object[] array = roots.toArray(); + Arrays.sort(array, basedOnOrderFromWrappedContainer); + roots = new LinkedHashSet(); + for (int i = 0; i < array.length; i++) { + roots.add(array[i]); + } + for (Object object : children.keySet()) { + LinkedList object2 = children.get(object); + Collections.sort(object2, basedOnOrderFromWrappedContainer); + } + } } } @@ -204,6 +206,7 @@ public class ContainerHierarchicalWrapper implements Container.Hierarchical, */ private void addToHierarchyWrapper(Object itemId) { roots.add(itemId); + } /* diff --git a/src/com/vaadin/data/util/HierarchicalContainer.java b/src/com/vaadin/data/util/HierarchicalContainer.java index f5b65f1dad..2b5519e651 100644 --- a/src/com/vaadin/data/util/HierarchicalContainer.java +++ b/src/com/vaadin/data/util/HierarchicalContainer.java @@ -139,6 +139,25 @@ public class HierarchicalContainer extends IndexedContainer implements return true; } + @Override + public Item addItemAt(int index, Object newItemId) { + Item retval = super.addItemAt(index, newItemId); + if (getParent(newItemId) == null) { + int refIndex = roots.size() - 1; + int indexOfId = indexOfId(roots.get(refIndex)); + while (indexOfId > index) { + refIndex--; + if (refIndex < 0) { + // inserts as first + break; + } + indexOfId = indexOfId(roots.get(refIndex)); + } + roots.add(refIndex + 1, newItemId); + } + return retval; + } + /** *

    * Sets the parent of an Item. The new parent item must exist and be able to @@ -293,7 +312,12 @@ public class HierarchicalContainer extends IndexedContainer implements if (isRoot(itemId)) { roots.remove(itemId); } - children.remove(itemId); + LinkedList remove = children.remove(itemId); + if (remove != null) { + for (Object object : remove) { + removeItem(object); + } + } final Object p = parent.get(itemId); if (p != null) { final LinkedList c = children.get(p); diff --git a/src/com/vaadin/data/util/IndexedContainer.java b/src/com/vaadin/data/util/IndexedContainer.java index f5dddf5e23..d6d6d9e77c 100644 --- a/src/com/vaadin/data/util/IndexedContainer.java +++ b/src/com/vaadin/data/util/IndexedContainer.java @@ -557,6 +557,9 @@ public class IndexedContainer implements Container.Indexed, return null; } } + if (index < 0) { + index = 0; + } return addItemAt(index, newItemId); } diff --git a/src/com/vaadin/launcher/DevelopmentServerLauncher.java b/src/com/vaadin/launcher/DevelopmentServerLauncher.java index 1ba7e69da0..68470937b3 100644 --- a/src/com/vaadin/launcher/DevelopmentServerLauncher.java +++ b/src/com/vaadin/launcher/DevelopmentServerLauncher.java @@ -12,8 +12,6 @@ import org.mortbay.jetty.Server; import org.mortbay.jetty.nio.SelectChannelConnector; import org.mortbay.jetty.webapp.WebAppContext; -import com.vaadin.launcher.util.BrowserLauncher; - /** * Class for running Jetty servlet container within Eclipse project. * @@ -42,7 +40,7 @@ public class DevelopmentServerLauncher { // Start Browser System.out.println("Starting Web Browser."); if (url != null) { - BrowserLauncher.openBrowser(url); + // BrowserLauncher.openBrowser(url); } } diff --git a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml index d7cf1ca4d0..3aaf2e5d1b 100644 --- a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml +++ b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml @@ -14,10 +14,6 @@ - - - - @@ -27,10 +23,18 @@ + + + + + + + + diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index 1c3128dbdf..bd35acddd7 100755 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -40,6 +40,7 @@ import com.vaadin.terminal.gwt.client.ui.VContextMenu; import com.vaadin.terminal.gwt.client.ui.VNotification; import com.vaadin.terminal.gwt.client.ui.VView; import com.vaadin.terminal.gwt.client.ui.VNotification.HideEvent; +import com.vaadin.terminal.gwt.client.ui.dd.DragAndDropManager; import com.vaadin.terminal.gwt.server.AbstractCommunicationManager; /** @@ -596,7 +597,7 @@ public class ApplicationConnection { for (int i = 1; i < variableBurst.size(); i += 2) { String id = variableBurst.get(i); id = id.substring(0, id.indexOf(VAR_FIELD_SEPARATOR)); - if (!idToPaintableDetail.containsKey(id)) { + if (!idToPaintableDetail.containsKey(id) && !id.startsWith("DD")) { // variable owner does not exist anymore variableBurst.remove(i - 1); variableBurst.remove(i - 1); @@ -805,6 +806,12 @@ public class ApplicationConnection { } } + if (json.containsKey("dd")) { + // response contains data for drag and drop service + DragAndDropManager.get().handleServerResponse( + json.getValueMap("dd")); + } + // Check which widgets' size has been updated Set sizeUpdatedWidgets = new HashSet(); diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java index 2a7ee079a9..8e423523ab 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java @@ -158,9 +158,12 @@ public class VAbsoluteLayout extends ComplexPanel implements Container { for (Iterator childIterator = uidl.getChildIterator(); childIterator .hasNext();) { UIDL cc = (UIDL) childIterator.next(); - UIDL componentUIDL = cc.getChildUIDL(0); - unrenderedPids.remove(componentUIDL.getId()); - getWrapper(client, componentUIDL).updateFromUIDL(cc); + // skip the last one (support for VDragDropPane + if (childIterator.hasNext()) { + UIDL componentUIDL = cc.getChildUIDL(0); + unrenderedPids.remove(componentUIDL.getId()); + getWrapper(client, componentUIDL).updateFromUIDL(cc); + } } for (String pid : unrenderedPids) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java index 1c2fcf5b6f..416455c162 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java @@ -191,6 +191,7 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { renderRemainingComponents(pendingCells); for (Cell cell : relativeHeighted) { + // rendering done above so cell.cc should not be null Widget widget2 = cell.cc.getWidget(); client.handleComponentRelativeSize(widget2); cell.cc.updateWidgetSize(); @@ -685,19 +686,20 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { Cell cell = paintableToCell.get(paintable); if (!cell.hasRelativeHeight() || !cell.hasRelativeWidth()) { // cell sizes will only stay still if only relatively - // sized - // components + // sized components // check if changed child affects min col widths - cell.cc.setWidth(""); - cell.cc.setHeight(""); + if (cell.cc != null) { + cell.cc.setWidth(""); + cell.cc.setHeight(""); - cell.cc.updateWidgetSize(); + cell.cc.updateWidgetSize(); - /* - * If this is the result of an caption icon onload event the - * caption size may have changed - */ - cell.cc.updateCaptionSize(); + /* + * If this is the result of an caption icon onload event the + * caption size may have changed + */ + cell.cc.updateCaptionSize(); + } int width = cell.getWidth(); int allocated = columnWidths[cell.col]; @@ -853,9 +855,16 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { } public RenderSpace getAllocatedSpace() { - return new RenderSpace(getAvailableWidth() - - cc.getCaptionWidthAfterComponent(), getAvailableHeight() - - cc.getCaptionHeightAboveComponent()); + if (cc != null) { + return new RenderSpace(getAvailableWidth() + - cc.getCaptionWidthAfterComponent(), + getAvailableHeight() + - cc.getCaptionHeightAboveComponent()); + } else { + // this should not happen normally + return new RenderSpace(getAvailableWidth(), + getAvailableHeight()); + } } public boolean hasContent() { @@ -965,6 +974,8 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { int rowspan = 1; UIDL childUidl; int alignment; + // may be null after setUidl() if content has vanished or changed, set + // in render() ChildComponentContainer cc; public void setUidl(UIDL c) { @@ -986,21 +997,21 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { if (childUidl != null) { if (c == null) { // content has vanished, old content will be removed from - // canvas - // later durin render phase + // canvas later during the render phase cc = null; } else if (cc != null && cc.getWidget() != client.getPaintable(c)) { // content has changed - cc = null; - if (widgetToComponentContainer.containsKey(client - .getPaintable(c))) { - // cc exist for this component (moved) use that for this - // cell - cc = widgetToComponentContainer.get(client - .getPaintable(c)); + Paintable newPaintable = client.getPaintable(c); + if (widgetToComponentContainer.containsKey(newPaintable)) { + // if a key in the map, newPaintable must be a widget + replaceChildComponent(cc.getWidget(), + (Widget) newPaintable); + cc = widgetToComponentContainer.get(newPaintable); cc.setWidth(""); cc.setHeight(""); + } else { + cc = null; } } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java index 8520e52eec..a680835126 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java @@ -40,6 +40,8 @@ import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.ui.VScrollTable.VScrollTableBody.VScrollTableRow; +import com.vaadin.terminal.gwt.client.ui.dd.DragAndDropManager; +import com.vaadin.terminal.gwt.client.ui.dd.Transferable; /** * VScrollTable @@ -148,6 +150,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { private String height; private String width = ""; private boolean rendering = false; + private int dragmode; public VScrollTable() { bodyContainer.addScrollHandler(this); @@ -190,6 +193,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { totalRows = newTotalRows; } + dragmode = uidl.hasAttribute("dragmode") ? uidl + .getIntAttribute("dragmode") : 0; + setCacheRate(uidl.hasAttribute("cr") ? uidl.getDoubleAttribute("cr") : CACHE_RATE_DEFAULT); @@ -2228,13 +2234,14 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { private String[] actionKeys = null; private final TableRowElement rowElement; + private boolean mDown; private VScrollTableRow(int rowKey) { this.rowKey = rowKey; rowElement = Document.get().createTRElement(); setElement(rowElement); - DOM.sinkEvents(getElement(), Event.ONMOUSEUP | Event.ONDBLCLICK - | Event.ONCONTEXTMENU); + DOM.sinkEvents(getElement(), Event.MOUSEEVENTS + | Event.ONDBLCLICK | Event.ONCONTEXTMENU); } private void paintComponent(Paintable p, UIDL uidl) { @@ -2458,6 +2465,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { handleClickEvent(event, targetTdOrTr); break; case Event.ONMOUSEUP: + mDown = false; handleClickEvent(event, targetTdOrTr); if (event.getButton() == Event.BUTTON_LEFT && selectMode > Table.SELECT_MODE_NONE) { @@ -2479,6 +2487,31 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { case Event.ONCONTEXTMENU: showContextMenu(event); break; + case Event.ONMOUSEDOWN: + if (dragmode != 0) { + mDown = true; + event.preventDefault(); + } + break; + case Event.ONMOUSEOUT: + mDown = false; + break; + case Event.ONMOUSEMOVE: + if (mDown && dragmode != 0) { + Transferable transferable = new Transferable(); + transferable.setComponent(VScrollTable.this); + transferable.setItemId("" + rowKey); + + // TODO propertyId + com.vaadin.terminal.gwt.client.ui.dd.DragEvent ev = DragAndDropManager + .get().startDrag(transferable, event, + true); + Element cloneNode = (Element) getElement() + .cloneNode(true); + cloneNode.getStyle().setOpacity(0.4); + ev.setDragImage(cloneNode); + mDown = false; + } default: break; } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTree.java b/src/com/vaadin/terminal/gwt/client/ui/VTree.java index 3394821efb..f3fa28c656 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTree.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTree.java @@ -9,7 +9,11 @@ import java.util.HashSet; import java.util.Iterator; import java.util.Set; +import com.google.gwt.dom.client.NativeEvent; +import com.google.gwt.dom.client.Style; +import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.DeferredCommand; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Window; @@ -22,11 +26,20 @@ import com.vaadin.terminal.gwt.client.MouseEventDetails; import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; +import com.vaadin.terminal.gwt.client.ValueMap; +import com.vaadin.terminal.gwt.client.ui.dd.AbstractDropHandler; +import com.vaadin.terminal.gwt.client.ui.dd.AcceptCallback; +import com.vaadin.terminal.gwt.client.ui.dd.DragAndDropManager; +import com.vaadin.terminal.gwt.client.ui.dd.DragEvent; +import com.vaadin.terminal.gwt.client.ui.dd.DropHandler; +import com.vaadin.terminal.gwt.client.ui.dd.HasDropHandler; +import com.vaadin.terminal.gwt.client.ui.dd.Transferable; +import com.vaadin.terminal.gwt.client.ui.dd.DragAndDropManager.DragEventType; /** * */ -public class VTree extends FlowPanel implements Paintable { +public class VTree extends FlowPanel implements Paintable, HasDropHandler { public static final String CLASSNAME = "v-tree"; @@ -37,6 +50,7 @@ public class VTree extends FlowPanel implements Paintable { private String paintableId; private boolean selectable; private boolean isMultiselect; + private String currentMouseOverKey; private final HashMap keyToNode = new HashMap(); @@ -56,6 +70,10 @@ public class VTree extends FlowPanel implements Paintable { private boolean rendering; + private int dragModes; + + private AbstractDropHandler dropHandler; + public VTree() { super(); setStyleName(CLASSNAME); @@ -116,6 +134,9 @@ public class VTree extends FlowPanel implements Paintable { if ("actions".equals(childUidl.getTag())) { updateActionMap(childUidl); continue; + } else if ("dh".equals(childUidl.getTag())) { + updateDropHandler(childUidl); + continue; } final TreeNode childTree = new TreeNode(); if (childTree.ie6compatnode != null) { @@ -132,10 +153,161 @@ public class VTree extends FlowPanel implements Paintable { selectedIds = uidl.getStringArrayVariableAsSet("selected"); + if (uidl.hasAttribute("dragModes")) { + dragModes = uidl.getIntAttribute("dragModes"); + } + rendering = false; } + private void updateTreeRelatedTransferData(DragEvent drag) { + drag.getTransferrable().setData("itemIdOver", currentMouseOverKey); + + if (currentMouseOverKey != null) { + String detail = getDropDetail(drag.getCurrentGwtEvent()); + Boolean overTreeNode = null; + if (!keyToNode.get(currentMouseOverKey).isLeaf() + && "Center".equals(detail)) { + overTreeNode = true; + } + drag.getTransferrable().setData("itemIdOverIsNode", overTreeNode); + + drag.getTransferrable().setData("detail", detail); + + } + } + + private void updateDropHandler(UIDL childUidl) { + if (dropHandler == null) { + dropHandler = new AbstractDropHandler() { + + @Override + public void dragEnter(DragEvent drag) { + updateTreeRelatedTransferData(drag); + super.dragEnter(drag); + } + + @Override + protected void dragAccepted(final DragEvent drag) { + } + + @Override + public void dragOver(final DragEvent currentDrag) { + final Object oldIdOver = currentDrag.getTransferrable() + .getData("itemIdOver"); + final String oldDetail = (String) currentDrag + .getTransferrable().getData("detail"); + /* + * Using deferred command, so event bubbles to TreeNode + * event listener. Currently here via preview + */ + DeferredCommand.addCommand(new Command() { + public void execute() { + final String detail = getDropDetail(currentDrag + .getCurrentGwtEvent()); + boolean nodeHasChanged = (currentMouseOverKey != null && currentMouseOverKey != oldIdOver) + || (oldIdOver != null); + boolean detailHasChanded = !detail + .equals(oldIdOver); + + if (nodeHasChanged || detailHasChanded) { + ApplicationConnection.getConsole().log( + "Change in Transferable " + + currentMouseOverKey + " " + + detail); + + updateTreeRelatedTransferData(currentDrag); + AcceptCallback accpectedCb = new AcceptCallback() { + public void handleResponse( + ValueMap responseData) { + if (responseData == null // via client + // side + // validation + || responseData + .containsKey("accepted")) { + keyToNode.get(currentMouseOverKey) + .emphasis(detail); + } + } + }; + if (validateOnServer()) { + DragAndDropManager.get().visitServer( + DragEventType.OVER, accpectedCb); + + } else { + if (validates(currentDrag + .getTransferrable())) { + accpectedCb.handleResponse(null); + } else { + keyToNode.get(currentMouseOverKey) + .emphasis(null); + } + if (oldIdOver != null + && oldIdOver != currentMouseOverKey) { + keyToNode.get(oldIdOver).emphasis(null); + } + } + } + + } + }); + } + + @Override + public void dragLeave(DragEvent drag) { + cleanUp(); + } + + private void cleanUp() { + if (currentMouseOverKey != null) { + keyToNode.get(currentMouseOverKey).emphasis(null); + currentMouseOverKey = null; + } + } + + @Override + public boolean drop(DragEvent drag) { + cleanUp(); + return super.drop(drag); + } + + @Override + public Paintable getPaintable() { + return VTree.this; + } + + public ApplicationConnection getApplicationConnection() { + return client; + } + + }; + } + dropHandler.updateRules(childUidl); + } + + public String getDropDetail(NativeEvent event) { + TreeNode treeNode = keyToNode.get(currentMouseOverKey); + // TODO no scroll support + int offsetHeight = treeNode.nodeCaptionDiv.getOffsetHeight(); + int absoluteTop = treeNode.getAbsoluteTop(); + int clientY = event.getClientY(); + int fromTop = clientY - absoluteTop; + + String detail; + float percentageFromTop = (fromTop / (float) offsetHeight); + if (percentageFromTop < 0.2) { + detail = "Top"; + } else if (percentageFromTop > 0.8) { + detail = "Bottom"; + } else { + detail = "Center"; + } + + return detail; + + } + private void handleUpdate(UIDL uidl) { final TreeNode rootNode = keyToNode.get(uidl .getStringAttribute("rootKey")); @@ -204,12 +376,27 @@ public class VTree extends FlowPanel implements Paintable { private Element ie6compatnode; + private Event mouseDownEvent; + public TreeNode() { constructDom(); - sinkEvents(Event.ONCLICK | Event.ONDBLCLICK | Event.ONMOUSEUP + sinkEvents(Event.ONCLICK | Event.ONDBLCLICK | Event.MOUSEEVENTS | Event.ONCONTEXTMENU); } + public void emphasis(String string) { + // ApplicationConnection.getConsole().log("OUTLINE" + string); + Style style = nodeCaptionDiv.getStyle(); + String top = "Top".equals(string) ? "2px solid green" : null; + String bottom = "Bottom".equals(string) ? "2px solid green" : null; + String bg = "Center".equals(string) ? "green" : null; + + style.setProperty("borderTop", top); + style.setProperty("borderBottom", bottom); + style.setBackgroundColor(bg); + + } + @Override public void onBrowserEvent(Event event) { super.onBrowserEvent(event); @@ -235,6 +422,45 @@ public class VTree extends FlowPanel implements Paintable { } else if (type == Event.ONCONTEXTMENU) { showContextMenu(event); } + + if (dragModes != 0 || dropHandler != null) { + if (type == Event.ONMOUSEDOWN) { + if (nodeCaptionDiv.isOrHasChild(event.getTarget())) { + ApplicationConnection.getConsole().log( + "TreeNode m down"); + event.preventDefault(); // prevent text selection + mouseDownEvent = event; + } + } else if (type == Event.ONMOUSEMOVE + || type == Event.ONMOUSEOUT) { + + if (mouseDownEvent != null) { + ApplicationConnection.getConsole().log( + "TreeNode drag start " + event.getType()); + // start actual drag on slight move when mouse is down + Transferable t = new Transferable(); + t.setComponent(VTree.this); + t.setItemId(key); + DragEvent drag = DragAndDropManager.get().startDrag(t, + mouseDownEvent, true); + Element node = (Element) nodeCaptionDiv.cloneNode(true); + node.getStyle().setOpacity(0.4); + node.getStyle().setBackgroundColor("#999"); + drag.setDragImage(node); + event.stopPropagation(); + + mouseDownEvent = null; + } + } else if (type == Event.ONMOUSEUP) { + mouseDownEvent = null; + } + if (type == Event.ONMOUSEOVER) { + mouseDownEvent = null; + currentMouseOverKey = key; + event.stopPropagation(); + } + + } } private void fireClick(Event evt) { @@ -344,6 +570,10 @@ public class VTree extends FlowPanel implements Paintable { } } + public boolean isLeaf() { + return getStyleName().contains("leaf"); + } + private void setState(boolean state, boolean notifyServer) { if (open == state) { return; @@ -484,4 +714,8 @@ public class VTree extends FlowPanel implements Paintable { } } } + + public DropHandler getDropHandler() { + return dropHandler; + } } diff --git a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java index 2bc10b4cc0..d6fa230f3c 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java @@ -316,6 +316,8 @@ public abstract class AbstractCommunicationManager implements private int timeoutInterval = -1; + private DragAndDropService dragAndDropService; + /** * TODO New constructor - document me! * @@ -939,6 +941,10 @@ public abstract class AbstractCommunicationManager implements // add any pending locale definitions requested by the client printLocaleDeclarations(outWriter); + if (dragAndDropService != null) { + dragAndDropService.printJSONResponse(outWriter); + } + outWriter.print("}]"); } outWriter.flush(); @@ -1006,8 +1012,7 @@ public abstract class AbstractCommunicationManager implements if (i + 1 < variableRecords.length) { nextVariable = variableRecords[i + 1]; } - final VariableOwner owner = (VariableOwner) idPaintableMap - .get(variable[VAR_PID]); + final VariableOwner owner = getVariableOwner(variable[VAR_PID]); if (owner != null && owner.isEnabled()) { // TODO this should be Map, but the // VariableOwner API does not guarantee the key is a @@ -1058,8 +1063,13 @@ public abstract class AbstractCommunicationManager implements } } } catch (Exception e) { - handleChangeVariablesError(application2, - (Component) owner, e, m); + if (owner instanceof Component) { + handleChangeVariablesError(application2, + (Component) owner, e, m); + } else { + // TODO DragDropService error handling + throw new RuntimeException(e); + } } } else { @@ -1112,6 +1122,21 @@ public abstract class AbstractCommunicationManager implements return success; } + private VariableOwner getVariableOwner(String string) { + VariableOwner owner = (VariableOwner) idPaintableMap.get(string); + if (owner == null && string.startsWith("DD")) { + return getDragAndDropService(); + } + return owner; + } + + private VariableOwner getDragAndDropService() { + if (dragAndDropService == null) { + dragAndDropService = new DragAndDropService(); + } + return dragAndDropService; + } + /** * Reads the request data from the Request and returns it converted to an * UTF-8 string. diff --git a/src/com/vaadin/ui/AbsoluteLayout.java b/src/com/vaadin/ui/AbsoluteLayout.java index 406ee9072d..e8a6ae5a9d 100644 --- a/src/com/vaadin/ui/AbsoluteLayout.java +++ b/src/com/vaadin/ui/AbsoluteLayout.java @@ -50,6 +50,7 @@ public class AbsoluteLayout extends AbstractLayout { public void addComponent(Component c) { components.add(c); super.addComponent(c); + requestRepaint(); } @Override diff --git a/src/com/vaadin/ui/CustomLayout.java b/src/com/vaadin/ui/CustomLayout.java index 26495a3715..0baa0dd468 100644 --- a/src/com/vaadin/ui/CustomLayout.java +++ b/src/com/vaadin/ui/CustomLayout.java @@ -1,4 +1,4 @@ -/* +/* @ITMillApache2LicenseForJavaFiles@ */ @@ -37,8 +37,6 @@ import com.vaadin.terminal.gwt.client.ui.VCustomLayout; *

    * * @author IT Mill Ltd. - * @author Duy B. Vo (devduy@gmail.com) * @version * @VERSION@ * @since 3.0 @@ -58,14 +56,6 @@ public class CustomLayout extends AbstractLayout { private String templateName = null; - /** - * Default constructor only used by subclasses because the subclasses are - * responsible for setting the appropriate fields. - */ - protected CustomLayout() { - setWidth(100, UNITS_PERCENTAGE); - } - /** * Constructs a custom layout with the template given in the stream. * @@ -78,24 +68,10 @@ public class CustomLayout extends AbstractLayout { * @throws IOException */ public CustomLayout(InputStream templateStream) throws IOException { - this(); - initTemplateContentsFromInputStream(templateStream); - } - - /** - * Constructor for custom layout with given template name. Template file is - * fetched from "/layout/". - */ - public CustomLayout(String template) { - this(); - templateName = template; - } - protected void initTemplateContentsFromInputStream( - InputStream templateStream) throws IOException { InputStreamReader reader = new InputStreamReader(templateStream, "UTF-8"); - StringBuilder b = new StringBuilder(BUFFER_SIZE); + StringBuffer b = new StringBuffer(BUFFER_SIZE); char[] cbuf = new char[BUFFER_SIZE]; int offset = 0; @@ -109,6 +85,16 @@ public class CustomLayout extends AbstractLayout { } templateContents = b.toString(); + setWidth(100, UNITS_PERCENTAGE); + } + + /** + * Constructor for custom layout with given template name. Template file is + * fetched from "/layout/". + */ + public CustomLayout(String template) { + templateName = template; + setWidth(100, UNITS_PERCENTAGE); } /** @@ -260,9 +246,7 @@ public class CustomLayout extends AbstractLayout { * * @param name * template name - * @deprecated Use {@link #setTemplateName(String)} instead */ - @Deprecated @Override public void setStyle(String name) { setTemplateName(name); @@ -273,11 +257,6 @@ public class CustomLayout extends AbstractLayout { return templateName; } - /** Get the contents of the template */ - public String getTemplateContents() { - return templateContents; - } - /** * Set the name of the template used to draw custom layout. * @@ -293,17 +272,6 @@ public class CustomLayout extends AbstractLayout { requestRepaint(); } - /** - * Set the contents of the template used to draw the custom layout. - * - * @param templateContents - */ - public void setTemplateContents(String templateContents) { - this.templateContents = templateContents; - templateName = null; - requestRepaint(); - } - /** * Although most layouts support margins, CustomLayout does not. The * behaviour of this layout is determined almost completely by the actual diff --git a/src/com/vaadin/ui/Select.java b/src/com/vaadin/ui/Select.java index e8e0dfebaa..4174001d87 100644 --- a/src/com/vaadin/ui/Select.java +++ b/src/com/vaadin/ui/Select.java @@ -234,6 +234,12 @@ public class Select extends AbstractSelect implements AbstractSelect.Filtering, currentPage = -1; // current page is always set by client optionRequest = true; + + // Hide the error indicator if needed + if (isRequired() && isEmpty() && getComponentError() == null + && getErrorMessage() != null) { + target.addAttribute("hideErrors", true); + } } /** diff --git a/src/com/vaadin/ui/Table.java b/src/com/vaadin/ui/Table.java index 0563756d40..5b99f614f1 100644 --- a/src/com/vaadin/ui/Table.java +++ b/src/com/vaadin/ui/Table.java @@ -23,7 +23,9 @@ import com.vaadin.data.Property; import com.vaadin.data.util.ContainerOrderedWrapper; import com.vaadin.data.util.IndexedContainer; import com.vaadin.event.Action; +import com.vaadin.event.DataBindedTransferrable; import com.vaadin.event.ItemClickEvent; +import com.vaadin.event.Transferable; import com.vaadin.event.Action.Handler; import com.vaadin.event.ItemClickEvent.ItemClickListener; import com.vaadin.event.ItemClickEvent.ItemClickSource; @@ -31,6 +33,7 @@ import com.vaadin.terminal.KeyMapper; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.Resource; +import com.vaadin.terminal.TransferTranslator; import com.vaadin.terminal.gwt.client.MouseEventDetails; import com.vaadin.terminal.gwt.client.ui.VScrollTable; @@ -54,7 +57,15 @@ import com.vaadin.terminal.gwt.client.ui.VScrollTable; @SuppressWarnings("serial") @ClientWidget(VScrollTable.class) public class Table extends AbstractSelect implements Action.Container, - Container.Ordered, Container.Sortable, ItemClickSource { + Container.Ordered, Container.Sortable, ItemClickSource, + TransferTranslator { + + /** + * Modes that Table support as drag sourse. + */ + public enum DragModes { + NONE, ROWS, CELLS + } private static final int CELL_KEY = 0; @@ -327,6 +338,8 @@ public class Table extends AbstractSelect implements Action.Container, private double cacheRate = CACHE_RATE_DEFAULT; + private DragModes dragMode = DragModes.NONE; + /* Table constructors */ /** @@ -2014,6 +2027,10 @@ public class Table extends AbstractSelect implements Action.Container, target.addAttribute("tabindex", getTabIndex()); } + if (dragMode != DragModes.NONE) { + target.addAttribute("dragmode", dragMode.ordinal()); + } + // Initialize temps final Object[] colids = getVisibleColumns(); final int cols = colids.length; @@ -3299,4 +3316,61 @@ public class Table extends AbstractSelect implements Action.Container, } } } + + public void setDragMode(DragModes newDragMode) { + dragMode = newDragMode; + requestRepaint(); + } + + class TableTransferrable implements DataBindedTransferrable { + + private final HashMap data = new HashMap(); + + public Object getItemId() { + return data.get("itemId"); + } + + public Object getPropertyId() { + return getItemCaptionPropertyId(); + } + + public Component getSourceComponent() { + return Table.this; + } + + public Object getData(String dataFlawor) { + return data.get(dataFlawor); + } + + public Collection getDataFlawors() { + return data.keySet(); + } + + public void setData(String dataFlawor, Object value) { + data.put(dataFlawor, value); + } + + } + + private void updateTransferrable(Map rawVariables, + Transferable tr, boolean isDropTarget) { + Map payload = (Map) rawVariables + .get("payload"); + if (!isDropTarget) { + Object object = payload.get("itemId"); + if (object != null) { + tr.setData("itemId", itemIdMapper.get((String) object)); + payload.remove("itemId"); + } + } + } + + public Transferable getTransferrable(Transferable transferable, + Map rawVariables, boolean isDropTarget) { + if (transferable == null) { + transferable = new TableTransferrable(); + } + updateTransferrable(rawVariables, transferable, isDropTarget); + return transferable; + } } diff --git a/src/com/vaadin/ui/Tree.java b/src/com/vaadin/ui/Tree.java index 28a410fa13..8e5cd8aca7 100644 --- a/src/com/vaadin/ui/Tree.java +++ b/src/com/vaadin/ui/Tree.java @@ -22,14 +22,20 @@ import com.vaadin.data.Container; import com.vaadin.data.Item; import com.vaadin.data.util.ContainerHierarchicalWrapper; import com.vaadin.data.util.IndexedContainer; +import com.vaadin.event.AbstractDropHandler; import com.vaadin.event.Action; +import com.vaadin.event.DataBindedTransferrable; +import com.vaadin.event.DropHandler; +import com.vaadin.event.HasDropHandler; import com.vaadin.event.ItemClickEvent; +import com.vaadin.event.Transferable; import com.vaadin.event.ItemClickEvent.ItemClickListener; import com.vaadin.event.ItemClickEvent.ItemClickSource; import com.vaadin.terminal.KeyMapper; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.Resource; +import com.vaadin.terminal.TransferTranslator; import com.vaadin.terminal.gwt.client.MouseEventDetails; import com.vaadin.terminal.gwt.client.ui.VTree; @@ -45,7 +51,7 @@ import com.vaadin.terminal.gwt.client.ui.VTree; @SuppressWarnings("serial") @ClientWidget(VTree.class) public class Tree extends AbstractSelect implements Container.Hierarchical, - Action.Container, ItemClickSource { + Action.Container, ItemClickSource, TransferTranslator, HasDropHandler { private static final Method EXPAND_METHOD; @@ -102,6 +108,68 @@ public class Tree extends AbstractSelect implements Container.Hierarchical, */ private boolean initialPaint = true; + // TODO sort DD members and methods + public static int DRAG_SORTABLE = 1; + public static int DRAG_OUT = 2; + public static int DRAG_NONE = 0; + + private int itemDragModes = DRAG_OUT; + + class TreeTransferrable implements DataBindedTransferrable { + + private final HashMap data = new HashMap(); + + public Object getItemId() { + return data.get("itemId"); + } + + public Object getPropertyId() { + return getItemCaptionPropertyId(); + } + + public Component getSourceComponent() { + return Tree.this; + } + + public Object getData(String dataFlawor) { + return data.get(dataFlawor); + } + + public Collection getDataFlawors() { + return data.keySet(); + } + + public void setData(String dataFlawor, Object value) { + data.put(dataFlawor, value); + } + } + + public Transferable getTransferrable(Transferable transferable, + Map rawVariables, boolean isDropTarget) { + if (transferable == null) { + transferable = new TreeTransferrable(); + } + Map payload = (Map) rawVariables + .get("payload"); + if (isDropTarget) { + // updating drag target variables + Object object = payload.get("itemIdOver"); + Object object2 = itemIdMapper.get((String) object); + transferable.setData("itemIdOver", object2); + payload.remove("itemIdOver"); + } else { + // updating drag source variables + Object object = payload.get("itemId"); + if (object != null) { + transferable.setData("itemId", itemIdMapper + .get((String) object)); + } + payload.remove("itemId"); + } + + return transferable; + } + /* Tree constructors */ /** @@ -435,6 +503,10 @@ public class Tree extends AbstractSelect implements Container.Hierarchical, target.addAttribute("nullselect", true); } + if (itemDragModes != 0) { + target.addAttribute("dragModes", itemDragModes); + } + } // Initialize variables @@ -579,6 +651,11 @@ public class Tree extends AbstractSelect implements Container.Hierarchical, // New items target.addVariable(this, "newitem", new String[] {}); + + if (abstractDropHandler != null) { + abstractDropHandler.paint(target); + } + } } @@ -1019,6 +1096,8 @@ public class Tree extends AbstractSelect implements Container.Hierarchical, private ItemStyleGenerator itemStyleGenerator; + private AbstractDropHandler abstractDropHandler; + public void addListener(ItemClickListener listener) { addListener(VTree.ITEM_CLICK_EVENT_ID, ItemClickEvent.class, listener, ItemClickEvent.ITEM_CLICK_METHOD); @@ -1075,4 +1154,12 @@ public class Tree extends AbstractSelect implements Container.Hierarchical, return super.removeItem(itemId); } + public DropHandler getDropHandler() { + return abstractDropHandler; + } + + public void setDropHandler(AbstractDropHandler abstractDropHandler) { + this.abstractDropHandler = abstractDropHandler; + } + } diff --git a/tests/src/com/vaadin/tests/components/abstractfield/AbstractFieldCommitWithInvalidValues.html b/tests/src/com/vaadin/tests/components/abstractfield/AbstractFieldCommitWithInvalidValues.html index 40e27920a8..ef2c784e15 100644 --- a/tests/src/com/vaadin/tests/components/abstractfield/AbstractFieldCommitWithInvalidValues.html +++ b/tests/src/com/vaadin/tests/components/abstractfield/AbstractFieldCommitWithInvalidValues.html @@ -21,11 +21,6 @@ - - focus - vaadin=runcomvaadintestscomponentsabstractfieldAbstractFieldCommitWithInvalidValues::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTextField[0] - - click vaadin=runcomvaadintestscomponentsabstractfieldAbstractFieldCommitWithInvalidValues::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0] diff --git a/tests/src/com/vaadin/tests/components/form/FormCommitWithInvalidValues.html b/tests/src/com/vaadin/tests/components/form/FormCommitWithInvalidValues.html index 0d5b435609..b0305e60dc 100644 --- a/tests/src/com/vaadin/tests/components/form/FormCommitWithInvalidValues.html +++ b/tests/src/com/vaadin/tests/components/form/FormCommitWithInvalidValues.html @@ -21,11 +21,6 @@ - - focus - vaadin=runcomvaadintestscomponentsformFormCommitWithInvalidValues::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0] - - click vaadin=runcomvaadintestscomponentsformFormCommitWithInvalidValues::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0] diff --git a/tests/src/com/vaadin/tests/layouts/GridLayoutNPE.java b/tests/src/com/vaadin/tests/layouts/GridLayoutNPE.java new file mode 100644 index 0000000000..5f67aa1a57 --- /dev/null +++ b/tests/src/com/vaadin/tests/layouts/GridLayoutNPE.java @@ -0,0 +1,72 @@ +package com.vaadin.tests.layouts; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.GridLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.Button.ClickEvent; + +public class GridLayoutNPE extends TestBase { + + @Override + protected void setup() { + final VerticalLayout lo = new VerticalLayout(); + + final GridLayout gl = new GridLayout(2, 1); + gl.setSpacing(true); + + final Label toRemove = new Label("First"); + gl.addComponent(toRemove); + final Label toEdit = new Label("Second"); + gl.addComponent(toEdit); + + final Button b = new Button("remove 'First'"); + final Button b2 = new Button("edit 'Second'"); + b2.setVisible(false); + + lo.addComponent(gl); + lo.addComponent(b); + lo.addComponent(b2); + + b.addListener(new Button.ClickListener() { + + public void buttonClick(Button.ClickEvent event) { + gl.removeComponent(toRemove); + + // move another component to where the first was removed + // before rendering to the client + gl.removeComponent(toEdit); + // this could also be the result of removeAllComponents() + // followed by a loop of addComponent(c) + gl.addComponent(toEdit, 0, 0); + + b.setVisible(false); + b2.setVisible(true); + + } + + }); + + b2.addListener(new Button.ClickListener() { + + public void buttonClick(ClickEvent event) { + toEdit.setValue("Second (edited)"); + } + + }); + + addComponent(lo); + } + + @Override + protected String getDescription() { + return "VGridLayout throws an NPE, causing client side to crash"; + } + + @Override + protected Integer getTicketNumber() { + return 4019; + } + +} diff --git a/tests/src/com/vaadin/tests/validation/EmptyFieldErrorIndicators.html b/tests/src/com/vaadin/tests/validation/EmptyFieldErrorIndicators.html deleted file mode 100644 index 3d5f70f994..0000000000 --- a/tests/src/com/vaadin/tests/validation/EmptyFieldErrorIndicators.html +++ /dev/null @@ -1,402 +0,0 @@ - - - - - - -EmptyFieldErrorIndicators - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    EmptyFieldErrorIndicators
    open/run/com.vaadin.tests.validation.EmptyFieldErrorIndicators?restartApplication
    waitForVaadin
    screenCaptureinitial
    scrollvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VDateFieldCalendar[0]/domChild[0]/domChild[1]/domChild[2]/domChild[0]/domChild[0]/domChild[4]168
    pause300
    clickvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0]/domChild[0]
    waitForVaadin
    clickvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0]/domChild[0]
    waitForVaadin
    screenCaptureemptyValidated
    mouseClickvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]22,15
    waitForVaadin
    enterCharactervaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]a
    waitForVaadin
    mouseClickvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VPopupCalendar[0]/domChild[1]15,10
    waitForVaadin
    scroll//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[3]/td/div/select[3]312
    pause300
    mouseClick//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[3]/td[1]/span12,8
    waitForVaadin
    scroll//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[3]/td/div/select[4]5980
    pause300
    mouseClickvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VDateFieldCalendar[0]/domChild[0]/domChild[1]/domChild[1]/domChild[0]/domChild[0]/domChild[1]/domChild[2]/domChild[0]/domChild[0]17,11
    waitForVaadin
    scrollvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VDateFieldCalendar[0]/domChild[0]/domChild[1]/domChild[2]/domChild[0]/domChild[0]/domChild[6]6496
    pause300
    mouseClickvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VPopupCalendar[1]/domChild[1]11,12
    waitForVaadin
    scroll//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[3]/td/div/select[3]364
    pause300
    mouseClick//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[3]/td[1]/span19,9
    waitForVaadin
    scroll//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[3]/td/div/select[4]9919
    pause300
    mouseClickvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VFilterSelect[1]/domChild[1]11,11
    waitForVaadin
    mouseClick//div[@id='VAADIN_COMBOBOX_OPTIONLIST']/div/div[2]/table/tbody/tr[2]/td55,0
    waitForVaadin
    mouseClickvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VOptionGroup[0]/domChild[0]/domChild[0]9,3
    waitForVaadin
    mouseClickvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VOptionGroup[1]/domChild[0]/domChild[0]11,7
    waitForVaadin
    mouseClickvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]32,14
    waitForVaadin
    enterCharactervaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]a
    waitForVaadin
    mouseClickvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VPopupCalendar[0]/domChild[1]12,9
    waitForVaadin
    scroll//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[3]/td/div/select[3]520
    pause300
    mouseClick//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[3]/td[1]/span12,12
    waitForVaadin
    scroll//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[3]/td/div/select[4]689
    pause300
    mouseClickvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VDateFieldCalendar[0]/domChild[0]/domChild[1]/domChild[1]/domChild[0]/domChild[0]/domChild[1]/domChild[2]/domChild[0]/domChild[0]19,15
    waitForVaadin
    scrollvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VDateFieldCalendar[0]/domChild[0]/domChild[1]/domChild[2]/domChild[0]/domChild[0]/domChild[6]798
    pause300
    mouseClickvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VPopupCalendar[1]/domChild[1]11,15
    waitForVaadin
    scroll//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[3]/td/div/select[2]91
    pause300
    mouseClick//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[2]/td/table/tbody/tr[3]/td[1]/span22,12
    waitForVaadin
    scroll//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr[3]/td/div/select[4]4303
    pause300
    mouseClickvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VFilterSelect[1]/domChild[1]9,13
    waitForVaadin
    mouseClick//div[@id='VAADIN_COMBOBOX_OPTIONLIST']/div/div[2]/table/tbody/tr[2]/td/span23,9
    waitForVaadin
    mouseClickvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VOptionGroup[0]/domChild[0]/domChild[0]5,6
    waitForVaadin
    mouseClickvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VOptionGroup[1]/domChild[0]/domChild[0]7,7
    waitForVaadin
    clickvaadin=runcomvaadintestsvalidationEmptyFieldErrorIndicators::PID_SvalidatedFieldPart/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0]/domChild[0]
    waitForVaadin
    screenCapturefilledValidated
    - - diff --git a/tests/src/com/vaadin/tests/validation/EmptyFieldErrorIndicators.java b/tests/src/com/vaadin/tests/validation/EmptyFieldErrorIndicators.java deleted file mode 100644 index 9ea28f672e..0000000000 --- a/tests/src/com/vaadin/tests/validation/EmptyFieldErrorIndicators.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.vaadin.tests.validation; - -import com.vaadin.data.Validator.InvalidValueException; -import com.vaadin.data.validator.AbstractValidator; -import com.vaadin.tests.components.TestBase; -import com.vaadin.ui.Button; -import com.vaadin.ui.ComponentContainer; -import com.vaadin.ui.DateField; -import com.vaadin.ui.Field; -import com.vaadin.ui.Form; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.InlineDateField; -import com.vaadin.ui.NativeSelect; -import com.vaadin.ui.OptionGroup; -import com.vaadin.ui.Panel; -import com.vaadin.ui.PopupDateField; -import com.vaadin.ui.Select; -import com.vaadin.ui.TextField; -import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.Button.ClickListener; - -public class EmptyFieldErrorIndicators extends TestBase { - - @Override - protected void setup() { - getLayout().setSizeFull(); - - HorizontalLayout hl = new HorizontalLayout(); - hl.setSizeFull(); - hl.setSpacing(true); - - ComponentContainer part1 = createPart( - "Empty required fields validation", true, false); - part1.setDebugId("emptyFieldPart"); - hl.addComponent(part1); - - ComponentContainer part2 = createPart( - "Empty required fields with failing validator", true, true); - part1.setDebugId("validatedFieldPart"); - hl.addComponent(part2); - - Panel panel = new Panel(); - panel.setSizeFull(); - panel.setStyleName(Panel.STYLE_LIGHT); - panel.addComponent(hl); - panel.setScrollable(true); - addComponent(panel); - } - - private ComponentContainer createPart(String caption, boolean required, - boolean failValidator) { - VerticalLayout part = new VerticalLayout(); - part.setMargin(true); - - final Form form = createForm(required, failValidator); - part.addComponent(form); - - Button validate = new Button("Validate fields"); - validate.addListener(new ClickListener() { - public void buttonClick(ClickEvent event) { - try { - form.validate(); - } catch (InvalidValueException e) { - } - } - }); - part.addComponent(validate); - - Panel panel = new Panel(caption, part); - panel.setHeight("100%"); - return panel; - } - - private Form createForm(final boolean required, final boolean failValidator) { - // hand-crafted form, not using form field factory - Form form = new Form() { - @Override - public void addField(Object propertyId, Field field) { - super.addField(propertyId, field); - field.setRequired(required); - field.setRequiredError("Missing required value!"); - if (failValidator) { - field - .addValidator(new AbstractValidator( - "Validation error") { - public boolean isValid(Object value) { - return false; - } - }); - } - } - }; - - form.addField("Field", new TextField("Text")); - form.addField("Date", new DateField("Date")); - form.addField("Inline Date", new InlineDateField("Date")); - form.addField("Popup Date", new PopupDateField("Date")); - - form.addField("Native Select", new NativeSelect("NativeSelect")); - - // in #4103, the Select component was behaving differently from others - form.addField("Select", new Select("Select")); - - Select select2 = new Select("Select 2"); - select2.addItem("Value 1"); - form.addField("Select 2", select2); - - OptionGroup optionGroup = new OptionGroup("OptionGroup"); - optionGroup.setMultiSelect(false); - optionGroup.addItem("Option 1"); - optionGroup.addItem("Option 2"); - form.addField("Option Group 1", optionGroup); - - OptionGroup optionGroup2 = new OptionGroup("OptionGroup"); - optionGroup2.setMultiSelect(true); - optionGroup2.addItem("Option 1"); - optionGroup2.addItem("Option 2"); - form.addField("Option Group 2", optionGroup2); - - // TODO could add more different fields - - return form; - } - - @Override - protected String getDescription() { - return "Fields on a form should not show the error indicator if required and empty"; - } - - @Override - protected Integer getTicketNumber() { - return 4013; - } - -}