diff options
author | Teemu Suo-Anttila <teemusa@vaadin.com> | 2015-06-01 09:32:37 +0300 |
---|---|---|
committer | Teemu Suo-Anttila <teemusa@vaadin.com> | 2015-06-01 09:34:46 +0300 |
commit | 6677046e5e23667403b8fb0499a618495796e1c8 (patch) | |
tree | 0d4bb0bf40b16be2c9e7e6158729f5bd3ff54d22 /client | |
parent | cf563c053fdf0d6b2991eba98e1cc118a8e74e54 (diff) | |
parent | 5b92ec790e3d3949992275d54ee8ac61ad94c157 (diff) | |
download | vaadin-framework-6677046e5e23667403b8fb0499a618495796e1c8.tar.gz vaadin-framework-6677046e5e23667403b8fb0499a618495796e1c8.zip |
Merge remote-tracking branch 'origin/master' into grid-unbuffered-editor
This also refactors some event handling logic.
Change-Id: I9cf96381650076da01686c5d964eb3e7e92c24c0
Diffstat (limited to 'client')
26 files changed, 676 insertions, 137 deletions
diff --git a/client/src/com/vaadin/client/ApplicationConfiguration.java b/client/src/com/vaadin/client/ApplicationConfiguration.java index f4b2c93111..0db8dc297e 100644 --- a/client/src/com/vaadin/client/ApplicationConfiguration.java +++ b/client/src/com/vaadin/client/ApplicationConfiguration.java @@ -688,7 +688,7 @@ public class ApplicationConfiguration implements EntryPoint { * cleared up when an API for extending the debug window is * implemented. */ - VDebugWindow window = GWT.create(VDebugWindow.class); + VDebugWindow window = VDebugWindow.get(); if (LogConfiguration.loggingIsEnabled()) { window.addSection((Section) GWT.create(LogSection.class)); diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java index a8266ad451..510994745e 100644 --- a/client/src/com/vaadin/client/ApplicationConnection.java +++ b/client/src/com/vaadin/client/ApplicationConnection.java @@ -863,7 +863,11 @@ public class ApplicationConnection implements HasHandlers { + ApplicationConstants.UIDL_PATH + '/'); if (extraParams != null && extraParams.length() > 0) { - uri = SharedUtil.addGetParameters(uri, extraParams); + if (extraParams.equals(getRepaintAllParameters())) { + payload.put(ApplicationConstants.RESYNCHRONIZE_ID, true); + } else { + uri = SharedUtil.addGetParameters(uri, extraParams); + } } uri = SharedUtil.addGetParameters(uri, UIConstants.UI_ID_PARAMETER + "=" + configuration.getUIId()); @@ -1285,12 +1289,18 @@ public class ApplicationConnection implements HasHandlers { StringBuilder html = new StringBuilder(); if (caption != null) { - html.append("<h1>"); + html.append("<h1 class='"); + html.append(VNotification.getDependentStyle(this, + VNotification.CAPTION)); + html.append("'>"); html.append(caption); html.append("</h1>"); } if (message != null) { - html.append("<p>"); + html.append("<p class='"); + html.append(VNotification.getDependentStyle(this, + VNotification.DESCRIPTION)); + html.append("'>"); html.append(message); html.append("</p>"); } @@ -1544,10 +1554,27 @@ public class ApplicationConnection implements HasHandlers { * e.g. critical server-side notifications */ if (syncId != -1) { - assert (lastSeenServerSyncId == UNDEFINED_SYNC_ID || syncId == lastSeenServerSyncId + 1) : "Newly retrieved server sync id was not exactly one larger than the previous one (new: " - + syncId + ", last seen: " + lastSeenServerSyncId + ")"; - - lastSeenServerSyncId = syncId; + if (lastSeenServerSyncId == UNDEFINED_SYNC_ID + || syncId == (lastSeenServerSyncId + 1)) { + lastSeenServerSyncId = syncId; + } else { + getLogger().warning( + "Expected sync id: " + (lastSeenServerSyncId + 1) + + ", received: " + syncId + + ". Resynchronizing from server."); + lastSeenServerSyncId = syncId; + + // Copied from below... + ValueMap meta = json.getValueMap("meta"); + if (meta == null || !meta.containsKey("async")) { + // End the request if the received message was a + // response, not sent asynchronously + endRequest(); + } + resumeResponseHandling(lock); + repaintAll(); + return; + } } } else { syncId = -1; diff --git a/client/src/com/vaadin/client/Util.java b/client/src/com/vaadin/client/Util.java index 197300f549..ccafd874a2 100644 --- a/client/src/com/vaadin/client/Util.java +++ b/client/src/com/vaadin/client/Util.java @@ -51,6 +51,8 @@ public class Util { * * Stops execution on firefox browsers on a breakpoint. * + * @deprecated As of 7.4.0, use {@link WidgetUtil#browserDebugger()} + * instead. */ @Deprecated public static void browserDebugger() { @@ -62,6 +64,9 @@ public class Util { * space bar (because space is considered as char). If return 0 use * getCharCode. * + * @deprecated As of 7.4.0, use {@link WidgetUtil#getKeyCode(KeyEvent)} + * instead. + * * @param event * @return return key code * @since 7.2.4 @@ -78,6 +83,9 @@ public class Util { * TODO fix crossplat issues clientX vs pageX. See quircksmode. Not critical * for vaadin as we scroll div istead of page. * + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#getElementFromPoint(int, int)} instead. + * * @param x * @param y * @return the element at given coordinates @@ -136,6 +144,10 @@ public class Util { return null; } + /** + * @deprecated As of 7.4.0, use {@link WidgetUtil#parseRelativeSize(String)} + * instead. + */ @Deprecated public static float parseRelativeSize(String size) { return WidgetUtil.parseRelativeSize(size); @@ -144,6 +156,9 @@ public class Util { /** * Converts html entities to text. * + * @deprecated As of 7.4.0, use {@link WidgetUtil#escapeHTML(String)} + * instead. + * * @param html * @return escaped string presentation of given html */ @@ -155,6 +170,9 @@ public class Util { /** * Escapes the string so it is safe to write inside an HTML attribute. * + * @deprecated As of 7.4.0, use {@link WidgetUtil#escapeAttribute(String)} + * instead. + * * @param attribute * The string to escape * @return An escaped version of <literal>attribute</literal>. @@ -169,6 +187,9 @@ public class Util { * * Deprecate this if there appears similar method into GWT someday. * + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#cloneNode(Element, boolean)} instead. + * * @param element * @param deep * clone child tree also @@ -180,6 +201,11 @@ public class Util { return DOM.asOld(WidgetUtil.cloneNode(element, deep)); } + /** + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#measureHorizontalPaddingAndBorder(Element, int)} + * instead. + */ @Deprecated public static int measureHorizontalPaddingAndBorder(Element element, int paddingGuess) { @@ -187,6 +213,11 @@ public class Util { paddingGuess); } + /** + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#measureVerticalPaddingAndBorder(Element, int)} + * instead. + */ @Deprecated public static int measureVerticalPaddingAndBorder(Element element, int paddingGuess) { @@ -194,21 +225,38 @@ public class Util { .measureVerticalPaddingAndBorder(element, paddingGuess); } + /** + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#measureHorizontalBorder(Element)} instead. + */ @Deprecated public static int measureHorizontalBorder(Element element) { return WidgetUtil.measureHorizontalBorder(element); } + /** + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#measureVerticalBorder(Element)} instead. + */ @Deprecated public static int measureVerticalBorder(Element element) { return WidgetUtil.measureVerticalBorder(element); } + /** + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#measureMarginLeft(Element)} instead. + */ @Deprecated public static int measureMarginLeft(Element element) { return WidgetUtil.measureMarginLeft(element); } + /** + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#setHeightExcludingPaddingAndBorder(Widget, String, int)} + * instead. + */ @Deprecated public static int setHeightExcludingPaddingAndBorder(Widget widget, String height, int paddingBorderGuess) { @@ -216,6 +264,11 @@ public class Util { paddingBorderGuess); } + /** + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#setWidthExcludingPaddingAndBorder(Widget, String, int)} + * instead. + */ @Deprecated public static int setWidthExcludingPaddingAndBorder(Widget widget, String width, int paddingBorderGuess) { @@ -223,6 +276,11 @@ public class Util { paddingBorderGuess); } + /** + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#setWidthExcludingPaddingAndBorder(Element, int, int, boolean)} + * instead. + */ @Deprecated public static int setWidthExcludingPaddingAndBorder(Element element, int requestedWidth, int horizontalPaddingBorderGuess, @@ -232,6 +290,11 @@ public class Util { requestedWidthIncludesPaddingBorder); } + /** + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#setHeightExcludingPaddingAndBorder(Element, int, int, boolean)} + * instead. + */ @Deprecated public static int setHeightExcludingPaddingAndBorder(Element element, int requestedHeight, int verticalPaddingBorderGuess, @@ -241,6 +304,9 @@ public class Util { requestedHeightIncludesPaddingBorder); } + /** + * @deprecated As of 7.4, use {@link Class#getSimpleName()} instead. + */ @Deprecated public static String getSimpleName(Object widget) { if (widget == null) { @@ -251,11 +317,19 @@ public class Util { return name.substring(name.lastIndexOf('.') + 1); } + /** + * @deprecated As of 7.4.0, use {@link WidgetUtil#setFloat(Element, String)} + * instead. + */ @Deprecated public static void setFloat(Element element, String value) { WidgetUtil.setFloat(element, value); } + /** + * @deprecated As of 7.4.0, use {@link WidgetUtil#getNativeScrollbarSize()} + * instead. + */ @Deprecated public static int getNativeScrollbarSize() { return WidgetUtil.getNativeScrollbarSize(); @@ -264,6 +338,10 @@ public class Util { /** * Defers the execution of {@link #runWebkitOverflowAutoFix(Element)} * + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#runWebkitOverflowAutoFixDeferred(Element)} + * instead. + * * @since 7.2.6 * @param elem * with overflow auto @@ -278,6 +356,9 @@ public class Util { * * See: our bug #2138 and https://bugs.webkit.org/show_bug.cgi?id=21462 * + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#runWebkitOverflowAutoFix(Element)} instead. + * * @param elem * with overflow auto */ @@ -314,6 +395,9 @@ public class Util { return uidl.getBooleanAttribute("cached"); } + /** + * @deprecated As of 7.4.0, use {@link WidgetUtil#alert(String)} instead. + */ @Deprecated public static void alert(String string) { WidgetUtil.alert(string); @@ -345,6 +429,9 @@ public class Util { * Gets the border-box width for the given element, i.e. element width + * border + padding. Always rounds up to nearest integer. * + * @deprecated As of 7.4.0, use {@link WidgetUtil#getRequiredWidth(Element)} + * instead. + * * @param element * The element to check * @return The border-box width for the element @@ -358,6 +445,9 @@ public class Util { * Gets the border-box height for the given element, i.e. element height + * border + padding. Always rounds up to nearest integer. * + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#getRequiredHeight(Element)} instead. + * * @param element * The element to check * @return The border-box height for the element @@ -368,35 +458,63 @@ public class Util { return WidgetUtil.getRequiredHeight(element); } + /** + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#getRequiredWidthBoundingClientRect(Element)} + * instead. + */ @Deprecated public int getRequiredWidthBoundingClientRect( com.google.gwt.dom.client.Element element) { return WidgetUtil.getRequiredWidthBoundingClientRect(element); } + /** + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#getRequiredHeightComputedStyle(Element)} + * instead. + */ @Deprecated public static int getRequiredHeightComputedStyle( com.google.gwt.dom.client.Element element) { return WidgetUtil.getRequiredHeightComputedStyle(element); } + /** + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#getRequiredWidthComputedStyle(Element)} + * instead. + */ @Deprecated public static int getRequiredWidthComputedStyle( com.google.gwt.dom.client.Element element) { return WidgetUtil.getRequiredWidthComputedStyle(element); } + /** + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#getRequiredHeightBoundingClientRect(Element)} + * instead. + */ @Deprecated public static int getRequiredHeightBoundingClientRect( com.google.gwt.dom.client.Element element) { return WidgetUtil.getRequiredHeightBoundingClientRect(element); } + /** + * @deprecated As of 7.4.0, use {@link WidgetUtil#getRequiredWidth(Widget)} + * instead. + */ @Deprecated public static int getRequiredWidth(Widget widget) { return WidgetUtil.getRequiredWidth(widget); } + /** + * @deprecated As of 7.4.0, use {@link WidgetUtil#getRequiredHeight(Widget)} + * instead. + */ @Deprecated public static int getRequiredHeight(Widget widget) { return WidgetUtil.getRequiredHeight(widget); @@ -405,6 +523,9 @@ public class Util { /** * Detects what is currently the overflow style attribute in given element. * + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#mayHaveScrollBars(Element)} instead. + * * @param pe * the element to detect * @return true if auto or scroll @@ -481,6 +602,8 @@ public class Util { /** * Will (attempt) to focus the given DOM Element. * + * @deprecated As of 7.4.0, use {@link WidgetUtil#focus(Element)} instead. + * * @param el * the element to focus */ @@ -511,6 +634,9 @@ public class Util { * Helper method to find first instance of given Widget type found by * traversing DOM upwards from given element. * + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#findWidget(Element, Class)} instead. + * * @param element * the element where to start seeking of Widget * @param class1 @@ -525,6 +651,9 @@ public class Util { /** * Force webkit to redraw an element * + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#forceWebkitRedraw(Element)} instead. + * * @param element * The element that should be redrawn */ @@ -538,6 +667,9 @@ public class Util { * necessary in cases where IE8 "forgets" to update child elements when they * resize. * + * @deprecated As of 7.4.0, use {@link WidgetUtil#forceIE8Redraw(Element)} + * instead. + * * @param e * The element to perform the hack on */ @@ -551,6 +683,9 @@ public class Util { * necessary in cases where IE "forgets" to update child elements when they * resize. * + * @deprecated As of 7.4.0, use {@link WidgetUtil#forceIERedraw(Element)} + * instead. + * * @since 7.3 * @param e * The element to perform the hack on @@ -566,6 +701,9 @@ public class Util { * * Does nothing if the element is not attached to the DOM. * + * @deprecated As of 7.4.0, use {@link WidgetUtil#detachAttach(Element)} + * instead. + * * @param element * The element to detach and re-attach */ @@ -574,6 +712,10 @@ public class Util { WidgetUtil.detachAttach(element); } + /** + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#sinkOnloadForImages(Element)} instead. + */ @Deprecated public static void sinkOnloadForImages(Element element) { WidgetUtil.sinkOnloadForImages(element); @@ -582,6 +724,9 @@ public class Util { /** * Returns the index of the childElement within its parent. * + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#getChildElementIndex(Element)} instead. + * * @param subElement * @return */ @@ -656,6 +801,10 @@ public class Util { * resets it to its current value. Used mainly to work around rendering * issues in IE (and possibly in other browsers) * + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#setStyleTemporarily(Element, String, String)} + * instead. + * * @param element * The target element * @param styleProperty @@ -674,6 +823,9 @@ public class Util { * position from either first changed touch (if touch event) or from the * event itself. * + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#getTouchOrMouseClientX(Event)} instead. + * * @param event * @return */ @@ -687,6 +839,9 @@ public class Util { * event. Please note that this is not always the same as the target of the * event e.g. if event capture is used. * + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#getElementUnderMouse(NativeEvent)} instead. + * * @param event * the mouse event to get coordinates from * @return the element at the coordinates of the event @@ -702,6 +857,9 @@ public class Util { * position from either first changed touch (if touch event) or from the * event itself. * + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#getTouchOrMouseClientY(Event)} instead. + * * @param event * @return */ @@ -711,6 +869,9 @@ public class Util { } /** + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#getTouchOrMouseClientY(NativeEvent)} + * instead. * * @see #getTouchOrMouseClientY(Event) * @param currentGwtEvent @@ -722,6 +883,10 @@ public class Util { } /** + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#getTouchOrMouseClientX(NativeEvent)} + * instead. + * * @see #getTouchOrMouseClientX(Event) * * @param event @@ -732,16 +897,29 @@ public class Util { return WidgetUtil.getTouchOrMouseClientX(event); } + /** + * @deprecated As of 7.4.0, use {@link WidgetUtil#isTouchEvent(Event)} + * instead. + */ @Deprecated public static boolean isTouchEvent(Event event) { return WidgetUtil.isTouchEvent(event); } + /** + * @deprecated As of 7.4.0, use {@link WidgetUtil#isTouchEvent(NativeEvent)} + * instead. + */ @Deprecated public static boolean isTouchEvent(NativeEvent event) { return WidgetUtil.isTouchEvent(event); } + /** + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#simulateClickFromTouchEvent(Event, Widget)} + * instead. + */ @Deprecated public static void simulateClickFromTouchEvent(Event touchevent, Widget widget) { @@ -751,6 +929,9 @@ public class Util { /** * Gets the currently focused element. * + * @deprecated As of 7.4.0, use {@link WidgetUtil#getFocusedElement()} + * instead. + * * @return The active element or null if no active element could be found. */ @Deprecated @@ -772,6 +953,9 @@ public class Util { /** * Gets currently focused element and checks if it's editable * + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#isFocusedElementEditable()} instead. + * * @since 7.4 * * @return true if focused element is editable @@ -787,6 +971,9 @@ public class Util { * be e.g used to check whether component should react to some events or * not. * + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#isAttachedAndDisplayed(Widget)} instead. + * * @param widget * @return true if attached and displayed */ @@ -799,6 +986,9 @@ public class Util { * Scrolls an element into view vertically only. Modified version of * Element.scrollIntoView. * + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#scrollIntoViewVertically(Element)} instead. + * * @param elem * The element to scroll into view */ @@ -811,6 +1001,10 @@ public class Util { * Checks if the given event is either a touch event or caused by the left * mouse button * + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#isTouchEventOrLeftMouseButton(Event)} + * instead. + * * @param event * @return true if the event is a touch event or caused by the left mouse * button, false otherwise @@ -868,6 +1062,9 @@ public class Util { * Resolve a relative URL to an absolute URL based on the current document's * location. * + * @deprecated As of 7.4.0, use {@link WidgetUtil#getAbsoluteUrl(String)} + * instead. + * * @param url * a string with the relative URL to resolve * @return the corresponding absolute URL as a string @@ -885,6 +1082,10 @@ public class Util { * to the start. This makes Firefox work the same way as other browsers * (#13477) * + * @deprecated As of 7.4.0, use + * {@link WidgetUtil#setSelectionRange(Element, int, int, String)} + * instead. + * * @param elem * the html input element. * @param pos diff --git a/client/src/com/vaadin/client/connectors/GridConnector.java b/client/src/com/vaadin/client/connectors/GridConnector.java index 2542e80075..8e27f526bf 100644 --- a/client/src/com/vaadin/client/connectors/GridConnector.java +++ b/client/src/com/vaadin/client/connectors/GridConnector.java @@ -1449,6 +1449,13 @@ public class GridConnector extends AbstractHasComponentsConnector implements || lazyDetailsScrollAdjuster.isWorkPending(); } + /** + * Gets the listener used by this connector for tracking when row detail + * visibility changes. + * + * @since 7.5.0 + * @return the used details listener + */ public DetailsListener getDetailsListener() { return detailsListener; } diff --git a/client/src/com/vaadin/client/connectors/ImageRendererConnector.java b/client/src/com/vaadin/client/connectors/ImageRendererConnector.java index ef54daaaa1..f7690cb6fe 100644 --- a/client/src/com/vaadin/client/connectors/ImageRendererConnector.java +++ b/client/src/com/vaadin/client/connectors/ImageRendererConnector.java @@ -42,9 +42,11 @@ public class ImageRendererConnector extends ClickableRendererConnector<String> { @Override public String decode(JsonValue value) { - return ((URLReference) JsonDecoder.decodeValue( + URLReference reference = (URLReference) JsonDecoder.decodeValue( TypeDataStore.getType(URLReference.class), value, null, - getConnection())).getURL(); + getConnection()); + + return reference != null ? reference.getURL() : null; } @Override diff --git a/client/src/com/vaadin/client/debug/internal/HierarchySection.java b/client/src/com/vaadin/client/debug/internal/HierarchySection.java index c772a9d267..ffb4042e69 100644 --- a/client/src/com/vaadin/client/debug/internal/HierarchySection.java +++ b/client/src/com/vaadin/client/debug/internal/HierarchySection.java @@ -66,9 +66,69 @@ public class HierarchySection implements Section { "Show used connectors and how to optimize widgetset"); private final Button showHierarchy = new DebugButton(Icon.HIERARCHY, "Show the connector hierarchy tree"); + private final Button generateDesign = new DebugButton(Icon.SHOW_DESIGN, + "Generate a declarative design for the given component sub tree"); private HandlerRegistration highlightModeRegistration = null; + public interface FindHandler { + + /** + * Called when the user hovers over a connector, which is highlighted. + * Also called when hovering outside the tree, e.g. over the debug + * console, but in this case the connector is null + * + * @param connector + */ + void onHover(ComponentConnector connector); + + /** + * Called when the user clicks on a highlighted connector. + * + * @param connector + */ + void onSelected(ComponentConnector connector); + + } + + private FindHandler inspectComponent = new FindHandler() { + + @Override + public void onHover(ComponentConnector connector) { + if (connector == null) { + infoPanel.clear(); + } else { + printState(connector, false); + } + } + + @Override + public void onSelected(ComponentConnector connector) { + stopFind(); + printState(connector, true); + } + + }; + private FindHandler showComponentDesign = new FindHandler() { + + @Override + public void onHover(ComponentConnector connector) { + Highlight.showOnly(connector); + } + + @Override + public void onSelected(ComponentConnector connector) { + stopFind(); + connector.getConnection().getUIConnector() + .showServerDesign(connector); + content.setWidget(new HTML( + "Design file for component sent to server log")); + } + + }; + + private FindHandler activeFindHandler; + public HierarchySection() { controls.add(showHierarchy); showHierarchy.setStylePrimaryName(VDebugWindow.STYLENAME_BUTTON); @@ -84,7 +144,7 @@ public class HierarchySection implements Section { find.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { - toggleFind(); + toggleFind(inspectComponent); } }); @@ -107,6 +167,17 @@ public class HierarchySection implements Section { } }); + controls.add(generateDesign); + generateDesign.setStylePrimaryName(VDebugWindow.STYLENAME_BUTTON); + generateDesign.addClickHandler(new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + content.setWidget(new HTML( + "Select a layout or component to generate the declarative design")); + toggleFind(showComponentDesign); + } + }); + hierarchyPanel.addListener(new SelectConnectorListener() { @Override public void select(ServerConnector connector, Element element) { @@ -132,7 +203,8 @@ public class HierarchySection implements Section { + showHierarchy.getTitle() + "<br/>" + find.getHTML() + " " + find.getTitle() + "<br/>" + analyze.getHTML() + " " + analyze.getTitle() + "<br/>" + generateWS.getHTML() + " " - + generateWS.getTitle() + "<br/>"); + + generateWS.getTitle() + "<br/>" + generateDesign.getHTML() + + " " + generateDesign.getTitle() + "<br/>"); info.setStyleName(VDebugWindow.STYLENAME + "-info"); helpPanel.add(info); } @@ -189,33 +261,62 @@ public class HierarchySection implements Section { // NOP } + private boolean isFindMode(FindHandler handler) { + return activeFindHandler == handler; + } + private boolean isFindMode() { - return (highlightModeRegistration != null); + return (activeFindHandler != null); } - private void toggleFind() { + private void toggleFind(FindHandler handler) { if (isFindMode()) { - stopFind(); + // Currently finding something + if (isFindMode(handler)) { + // Toggle off, stop finding + stopFind(); + return; + } else { + // Stop finding something else, start finding this + stopFind(); + startFind(handler); + } } else { - startFind(); + // Not currently finding anything + startFind(handler); } } - private void startFind() { + private void startFind(FindHandler handler) { + if (isFindMode()) { + stopFind(); + } Highlight.hideAll(); - if (!isFindMode()) { - highlightModeRegistration = Event - .addNativePreviewHandler(highlightModeHandler); + + highlightModeRegistration = Event + .addNativePreviewHandler(highlightModeHandler); + activeFindHandler = handler; + if (handler == inspectComponent) { find.addStyleDependentName(VDebugWindow.STYLENAME_ACTIVE); + } else if (handler == showComponentDesign) { + generateDesign.addStyleDependentName(VDebugWindow.STYLENAME_ACTIVE); } + } + /** + * Stop any current find operation, regardless of the handler + */ private void stopFind() { - if (isFindMode()) { - highlightModeRegistration.removeHandler(); - highlightModeRegistration = null; - find.removeStyleDependentName(VDebugWindow.STYLENAME_ACTIVE); + if (!isFindMode()) { + return; } + + highlightModeRegistration.removeHandler(); + highlightModeRegistration = null; + find.removeStyleDependentName(VDebugWindow.STYLENAME_ACTIVE); + generateDesign.removeStyleDependentName(VDebugWindow.STYLENAME_ACTIVE); + activeFindHandler = null; } private void printState(ServerConnector connector, boolean serverDebug) { @@ -244,7 +345,9 @@ public class HierarchySection implements Section { Element eventTarget = WidgetUtil.getElementFromPoint(event .getNativeEvent().getClientX(), event.getNativeEvent() .getClientY()); + if (VDebugWindow.get().getElement().isOrHasChild(eventTarget)) { + // Do not prevent using debug window controls infoPanel.clear(); return; } @@ -258,21 +361,21 @@ public class HierarchySection implements Section { RootPanel.get(), eventTarget); } if (connector != null) { - printState(connector, false); + activeFindHandler.onHover(connector); event.cancel(); event.consume(); event.getNativeEvent().stopPropagation(); return; } } - infoPanel.clear(); + // Not over any connector + activeFindHandler.onHover(null); } if (event.getTypeInt() == Event.ONCLICK) { Highlight.hideAll(); event.cancel(); event.consume(); event.getNativeEvent().stopPropagation(); - stopFind(); Element eventTarget = WidgetUtil.getElementFromPoint(event .getNativeEvent().getClientX(), event.getNativeEvent() .getClientY()); @@ -286,10 +389,12 @@ public class HierarchySection implements Section { } if (connector != null) { - printState(connector, true); + activeFindHandler.onSelected(connector); return; } } + // Click on something else -> stop find operation + stopFind(); } event.cancel(); } diff --git a/client/src/com/vaadin/client/debug/internal/Icon.java b/client/src/com/vaadin/client/debug/internal/Icon.java index d05eca2f6f..a30dc05fcb 100644 --- a/client/src/com/vaadin/client/debug/internal/Icon.java +++ b/client/src/com/vaadin/client/debug/internal/Icon.java @@ -18,6 +18,7 @@ package com.vaadin.client.debug.internal; public enum Icon { + // Font can be updated using e.g. http://icomoon.io/ SEARCH(""), // OK(""), // REMOVE(""), // @@ -46,6 +47,7 @@ public enum Icon { RESET(""), // PERSIST(""), // TESTBENCH(""), // + SHOW_DESIGN(""), // ; private String id; diff --git a/client/src/com/vaadin/client/debug/internal/VDebugWindow.java b/client/src/com/vaadin/client/debug/internal/VDebugWindow.java index 3393d7371b..b543c23e4d 100644 --- a/client/src/com/vaadin/client/debug/internal/VDebugWindow.java +++ b/client/src/com/vaadin/client/debug/internal/VDebugWindow.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.Date; import com.google.gwt.core.client.Duration; +import com.google.gwt.core.shared.GWT; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.dom.client.Style; @@ -174,7 +175,6 @@ public final class VDebugWindow extends VOverlay { */ public VDebugWindow() { super(false, false); - instance = this; getElement().getStyle().setOverflow(Overflow.HIDDEN); setStylePrimaryName(STYLENAME); @@ -255,7 +255,7 @@ public final class VDebugWindow extends VOverlay { */ public static VDebugWindow get() { if (instance == null) { - instance = new VDebugWindow(); + instance = GWT.create(VDebugWindow.class); } return instance; } diff --git a/client/src/com/vaadin/client/debug/internal/theme/font.eot b/client/src/com/vaadin/client/debug/internal/theme/font.eot Binary files differindex cf38942e0a..0244d9afcc 100755 --- a/client/src/com/vaadin/client/debug/internal/theme/font.eot +++ b/client/src/com/vaadin/client/debug/internal/theme/font.eot diff --git a/client/src/com/vaadin/client/debug/internal/theme/font.svg b/client/src/com/vaadin/client/debug/internal/theme/font.svg index c5a97a6c8b..313645c78f 100755 --- a/client/src/com/vaadin/client/debug/internal/theme/font.svg +++ b/client/src/com/vaadin/client/debug/internal/theme/font.svg @@ -33,4 +33,5 @@ <glyph unicode="" d="M731.428 448q0 59.428-23.144 113.428t-62.572 93.428-93.428 62.572-113.428 23.142-113.428-23.142-93.43-62.572-62.57-93.428-23.144-113.428 23.144-113.428 62.57-93.428 93.43-62.572 113.428-23.144 113.428 23.144 93.428 62.572 62.572 93.428 23.144 113.428zM877.714 448q0-119.428-58.856-220.286t-159.714-159.714-220.286-58.856-220.286 58.856-159.714 159.714-58.856 220.286 58.856 220.286 159.714 159.714 220.286 58.856 220.286-58.856 159.714-159.714 58.856-220.286z" horiz-adv-x="878" /> <glyph unicode="" d="M283.428 192q0-34.286-24.286-58.286t-58-24q-34.286 0-58.286 24t-24 58.286 24 58.286 58.286 24q33.714 0 58-24t24.286-58.286zM530.286 82.286q0-30.286-21.428-51.714t-51.714-21.428-51.714 21.428-21.428 51.714 21.428 51.714 51.714 21.428 51.714-21.428 21.428-51.714zM182.856 448q0-37.714-26.856-64.572t-64.57-26.856-64.57 26.856-26.856 64.572 26.856 64.572 64.57 26.856 64.57-26.856 26.856-64.572zM777.144 192q0-26.286-18.856-45.144t-45.144-18.856-45.144 18.856-18.856 45.144 18.856 45.144 45.144 18.856 45.144-18.856 18.856-45.144zM301.714 704q0-41.714-29.428-71.144t-71.144-29.428-71.144 29.428-29.43 71.144 29.43 71.144 71.144 29.428 71.144-29.428 29.428-71.144zM566.856 813.714q0-45.714-32-77.714t-77.714-32-77.714 32-32 77.714 32 77.714 77.714 32 77.714-32 32-77.714zM877.714 448q0-22.856-16-38.856t-38.856-16-38.856 16-16 38.856 16 38.856 38.856 16 38.856-16 16-38.856zM758.856 704q0-18.856-13.428-32.286t-32.286-13.428-32.286 13.428-13.428 32.286 13.428 32.286 32.286 13.428 32.286-13.428 13.428-32.286z" horiz-adv-x="896" /> <glyph unicode="" d="M877.714 448q0-119.428-58.856-220.286t-159.714-159.714-220.286-58.856-220.286 58.856-159.714 159.714-58.856 220.286 58.856 220.286 159.714 159.714 220.286 58.856 220.286-58.856 159.714-159.714 58.856-220.286z" horiz-adv-x="878" /> +<glyph unicode="" d="M838.857 733.714q16-16 27.429-43.429t11.429-50.286v-658.286q0-22.857-16-38.857t-38.857-16h-768q-22.857 0-38.857 16t-16 38.857v914.286q0 22.857 16 38.857t38.857 16h512q22.857 0 50.286-11.429t43.429-27.429zM585.143 873.143v-214.857h214.857q-5.714 16.571-12.571 23.429l-178.857 178.857q-6.857 6.857-23.429 12.571zM804.571 0v585.143h-237.714q-22.857 0-38.857 16t-16 38.857v237.714h-438.857v-877.714h731.429zM274.286 512q4.571 6.286 12 7.143t13.714-3.714l29.143-21.714q6.286-4.571 7.143-12t-3.714-13.714l-104-138.857 104-138.857q4.571-6.286 3.714-13.714t-7.143-12l-29.143-21.714q-6.286-4.571-13.714-3.714t-12 7.143l-129.143 172q-8 10.857 0 21.714zM732.571 340q8-10.857 0-21.714l-129.143-172q-4.571-6.286-12-7.143t-13.714 3.714l-29.143 21.714q-6.286 4.571-7.143 12t3.714 13.714l104 138.857-104 138.857q-4.571 6.286-3.714 13.714t7.143 12l29.143 21.714q6.286 4.571 13.714 3.714t12-7.143zM378.286 76.571q-7.429 1.143-11.714 7.429t-3.143 13.714l78.857 474.857q1.143 7.429 7.429 11.714t13.714 3.143l36-5.714q7.429-1.143 11.714-7.429t3.143-13.714l-78.857-474.857q-1.143-7.429-7.429-11.714t-13.714-3.143z" /> </font></defs></svg>
\ No newline at end of file diff --git a/client/src/com/vaadin/client/debug/internal/theme/font.ttf b/client/src/com/vaadin/client/debug/internal/theme/font.ttf Binary files differindex 734e69ac3f..56ed0cfbff 100755 --- a/client/src/com/vaadin/client/debug/internal/theme/font.ttf +++ b/client/src/com/vaadin/client/debug/internal/theme/font.ttf diff --git a/client/src/com/vaadin/client/debug/internal/theme/font.woff b/client/src/com/vaadin/client/debug/internal/theme/font.woff Binary files differindex a9e6d5576b..9f5ed668ec 100755 --- a/client/src/com/vaadin/client/debug/internal/theme/font.woff +++ b/client/src/com/vaadin/client/debug/internal/theme/font.woff diff --git a/client/src/com/vaadin/client/renderers/ClickableRenderer.java b/client/src/com/vaadin/client/renderers/ClickableRenderer.java index f5368d31c9..83059f8f01 100644 --- a/client/src/com/vaadin/client/renderers/ClickableRenderer.java +++ b/client/src/com/vaadin/client/renderers/ClickableRenderer.java @@ -33,6 +33,7 @@ import com.vaadin.client.widget.grid.CellReference; import com.vaadin.client.widget.grid.EventCellReference; import com.vaadin.client.widgets.Escalator; import com.vaadin.client.widgets.Grid; +import com.vaadin.client.widgets.Grid.Section; /** * An abstract superclass for renderers that render clickable widgets. Click @@ -152,7 +153,9 @@ public abstract class ClickableRenderer<T, W extends Widget> extends Cell cell = container.getCell(e); EventCellReference<T> cellReference = new EventCellReference<T>( grid); - cellReference.set(cell); + // FIXME: Section is currently always body. Might be useful for the + // future to have an actual check. + cellReference.set(cell, Section.BODY); return cellReference; } diff --git a/client/src/com/vaadin/client/renderers/ImageRenderer.java b/client/src/com/vaadin/client/renderers/ImageRenderer.java index b1e8ce5702..9e61e60919 100644 --- a/client/src/com/vaadin/client/renderers/ImageRenderer.java +++ b/client/src/com/vaadin/client/renderers/ImageRenderer.java @@ -29,6 +29,8 @@ import com.vaadin.client.widget.grid.RendererCellReference; */ public class ImageRenderer extends ClickableRenderer<String, Image> { + public static final String TRANSPARENT_GIF_1PX = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs="; + @Override public Image createWidget() { Image image = GWT.create(Image.class); @@ -38,6 +40,11 @@ public class ImageRenderer extends ClickableRenderer<String, Image> { @Override public void render(RendererCellReference cell, String url, Image image) { - image.setUrl(url); + if (url == null) { + image.setUrl(TRANSPARENT_GIF_1PX); + } + else { + image.setUrl(url); + } } } diff --git a/client/src/com/vaadin/client/ui/VFormLayout.java b/client/src/com/vaadin/client/ui/VFormLayout.java index 3781305e52..42dbbde32a 100644 --- a/client/src/com/vaadin/client/ui/VFormLayout.java +++ b/client/src/com/vaadin/client/ui/VFormLayout.java @@ -223,7 +223,7 @@ public class VFormLayout extends SimplePanel { private Icon icon; - private Element captionText; + private Element captionContent; /** * @@ -274,13 +274,13 @@ public class VFormLayout extends SimplePanel { } if (state.caption != null) { - if (captionText == null) { - captionText = DOM.createSpan(); + if (captionContent == null) { + captionContent = DOM.createSpan(); - AriaHelper.bindCaption(owner.getWidget(), captionText); + AriaHelper.bindCaption(owner.getWidget(), captionContent); - DOM.insertChild(getElement(), captionText, icon == null ? 0 - : 1); + DOM.insertChild(getElement(), captionContent, + icon == null ? 0 : 1); } String c = state.caption; if (c == null) { @@ -288,12 +288,16 @@ public class VFormLayout extends SimplePanel { } else { isEmpty = false; } - DOM.setInnerText(captionText, c); + if (state.captionAsHtml) { + captionContent.setInnerHTML(c); + } else { + captionContent.setInnerText(c); + } } else { // TODO should span also be removed } - if (state.description != null && captionText != null) { + if (state.description != null && captionContent != null) { addStyleDependentName("hasdescription"); } else { removeStyleDependentName("hasdescription"); diff --git a/client/src/com/vaadin/client/ui/VNotification.java b/client/src/com/vaadin/client/ui/VNotification.java index 2892d4e3ac..4f0c2eb625 100644 --- a/client/src/com/vaadin/client/ui/VNotification.java +++ b/client/src/com/vaadin/client/ui/VNotification.java @@ -63,8 +63,8 @@ public class VNotification extends VOverlay { private static final String STYLENAME_POSITION_CENTER = "v-position-center"; private static final String STYLENAME_POSITION_ASSISTIVE = "v-position-assistive"; - private static final String CAPTION = "caption"; - private static final String DESCRIPTION = "description"; + public static final String CAPTION = "caption"; + public static final String DESCRIPTION = "description"; /** * Position that is only accessible for assistive devices, invisible for @@ -532,7 +532,18 @@ public class VNotification extends VOverlay { html, position, style); } - private static String getDependentStyle(ApplicationConnection client, + /** + * Meant for internal usage only. + * + * @since 7.5.0 + * @param client + * application connection + * @param style + * the dependent style name + * @return the given dependent style name prefixed with current notification + * primary style + */ + public static String getDependentStyle(ApplicationConnection client, String style) { VNotification notification = createNotification(-1, client .getUIConnector().getWidget()); diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java index 6a8ce67678..d3958a2f00 100644 --- a/client/src/com/vaadin/client/ui/VScrollTable.java +++ b/client/src/com/vaadin/client/ui/VScrollTable.java @@ -3659,16 +3659,15 @@ public class VScrollTable extends FlowPanel implements HasWidgets, // Do a more thorough update if a column is resized from // the server *after* the header has been properly // initialized - final int colIx = getColIndexByKey(c.cid); final int newWidth = width; - Scheduler.get().scheduleDeferred( - new ScheduledCommand() { + Scheduler.get().scheduleFinally(new ScheduledCommand() { - @Override - public void execute() { - setColWidth(colIx, newWidth, true); - } - }); + @Override + public void execute() { + final int colIx = getColIndexByKey(cid); + setColWidth(colIx, newWidth, true); + } + }); refreshContentWidths = true; } else { // get min width with no indent or padding @@ -3710,7 +3709,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, if (refreshContentWidths) { // Recalculate the column sizings if any column has changed - Scheduler.get().scheduleDeferred(new ScheduledCommand() { + Scheduler.get().scheduleFinally(new ScheduledCommand() { @Override public void execute() { diff --git a/client/src/com/vaadin/client/ui/VTabsheet.java b/client/src/com/vaadin/client/ui/VTabsheet.java index a02679a0fc..8e4f3cb643 100644 --- a/client/src/com/vaadin/client/ui/VTabsheet.java +++ b/client/src/com/vaadin/client/ui/VTabsheet.java @@ -909,7 +909,6 @@ public class VTabsheet extends VTabsheetBase implements Focusable, SubPartAware deco = DOM.createDiv(); - addStyleDependentName("loading"); // Indicate initial progress tb.setStyleName(CLASSNAME + "-tabs"); DOM.setElementProperty(contentNode, "className", CLASSNAME + "-content"); DOM.setElementProperty(deco, "className", CLASSNAME + "-deco"); diff --git a/client/src/com/vaadin/client/ui/VTextualDate.java b/client/src/com/vaadin/client/ui/VTextualDate.java index 9055609e69..4d80b30f4f 100644 --- a/client/src/com/vaadin/client/ui/VTextualDate.java +++ b/client/src/com/vaadin/client/ui/VTextualDate.java @@ -363,7 +363,12 @@ public class VTextualDate extends VDateField implements Field, ChangeHandler, } protected void setText(String text) { - if (inputPrompt != null && (text == null || "".equals(text))) { + if (inputPrompt != null + && (text == null || "".equals(text)) + && !this.text.getStyleName() + .contains( + VTextField.CLASSNAME + "-" + + VTextField.CLASSNAME_FOCUS)) { text = readonly ? "" : inputPrompt; setPrompting(true); } else { diff --git a/client/src/com/vaadin/client/ui/VWindow.java b/client/src/com/vaadin/client/ui/VWindow.java index d28686e777..c5cab8ff6b 100644 --- a/client/src/com/vaadin/client/ui/VWindow.java +++ b/client/src/com/vaadin/client/ui/VWindow.java @@ -1354,7 +1354,9 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, @Override public void onKeyUp(KeyUpEvent event) { - // do nothing + if (isClosable() && event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) { + onCloseClick(); + } } @Override diff --git a/client/src/com/vaadin/client/ui/csslayout/CssLayoutConnector.java b/client/src/com/vaadin/client/ui/csslayout/CssLayoutConnector.java index a0ef1fbb3e..bef506b492 100644 --- a/client/src/com/vaadin/client/ui/csslayout/CssLayoutConnector.java +++ b/client/src/com/vaadin/client/ui/csslayout/CssLayoutConnector.java @@ -32,6 +32,7 @@ import com.vaadin.shared.ui.Connect; import com.vaadin.shared.ui.LayoutClickRpc; import com.vaadin.shared.ui.csslayout.CssLayoutServerRpc; import com.vaadin.shared.ui.csslayout.CssLayoutState; +import com.vaadin.shared.util.SharedUtil; import com.vaadin.ui.CssLayout; /** @@ -160,13 +161,7 @@ public class CssLayoutConnector extends AbstractLayoutConnector { * @return A string converted to camelcase */ private static final String makeCamelCase(String cssProperty) { - // TODO this might be cleaner to implement with regexp - while (cssProperty.contains("-")) { - int indexOf = cssProperty.indexOf("-"); - cssProperty = cssProperty.substring(0, indexOf) - + String.valueOf(cssProperty.charAt(indexOf + 1)) - .toUpperCase() + cssProperty.substring(indexOf + 2); - } + cssProperty = SharedUtil.dashSeparatedToCamelCase(cssProperty); if ("float".equals(cssProperty)) { if (BrowserInfo.get().isIE()) { return "styleFloat"; diff --git a/client/src/com/vaadin/client/ui/tabsheet/TabsheetConnector.java b/client/src/com/vaadin/client/ui/tabsheet/TabsheetConnector.java index 469fc6ba95..1b043c8a51 100644 --- a/client/src/com/vaadin/client/ui/tabsheet/TabsheetConnector.java +++ b/client/src/com/vaadin/client/ui/tabsheet/TabsheetConnector.java @@ -42,6 +42,7 @@ public class TabsheetConnector extends TabsheetBaseConnector implements final boolean selected = key.equals(getState().selected); if (selected) { getWidget().waitingForResponse = false; + getWidget().setActiveTabIndex(i); getWidget().selectTab(i); break; } diff --git a/client/src/com/vaadin/client/ui/ui/UIConnector.java b/client/src/com/vaadin/client/ui/ui/UIConnector.java index da23ec4a5a..8249b45855 100644 --- a/client/src/com/vaadin/client/ui/ui/UIConnector.java +++ b/client/src/com/vaadin/client/ui/ui/UIConnector.java @@ -818,6 +818,18 @@ public class UIConnector extends AbstractSingleComponentContainerConnector serverConnector); } + /** + * Sends a request to the server to print a design to the console for the + * given component. + * + * @since 7.5 + * @param connector + * the component connector to output a declarative design for + */ + public void showServerDesign(ServerConnector connector) { + getRpcProxy(DebugWindowServerRpc.class).showServerDesign(connector); + } + @OnStateChange("theme") void onThemeChange() { final String oldTheme = activeTheme; @@ -1069,5 +1081,4 @@ public class UIConnector extends AbstractSingleComponentContainerConnector private static Logger getLogger() { return Logger.getLogger(UIConnector.class.getName()); } - } diff --git a/client/src/com/vaadin/client/widget/grid/EventCellReference.java b/client/src/com/vaadin/client/widget/grid/EventCellReference.java index 7ca1d5de75..854d91920b 100644 --- a/client/src/com/vaadin/client/widget/grid/EventCellReference.java +++ b/client/src/com/vaadin/client/widget/grid/EventCellReference.java @@ -19,6 +19,7 @@ import com.google.gwt.dom.client.TableCellElement; import com.vaadin.client.widget.escalator.Cell; import com.vaadin.client.widgets.Grid; import com.vaadin.client.widgets.Grid.Column; +import com.vaadin.client.widgets.Grid.Section; /** * A data class which contains information which identifies a cell being the @@ -33,12 +34,11 @@ import com.vaadin.client.widgets.Grid.Column; */ public class EventCellReference<T> extends CellReference<T> { - private Grid<T> grid; + private Section section; private TableCellElement element; public EventCellReference(Grid<T> grid) { super(new RowReference<T>(grid)); - this.grid = grid; } /** @@ -47,22 +47,76 @@ public class EventCellReference<T> extends CellReference<T> { * @param targetCell * cell to point to */ - public void set(Cell targetCell) { + public void set(Cell targetCell, Section section) { + Grid<T> grid = getGrid(); int row = targetCell.getRow(); int columnIndexDOM = targetCell.getColumn(); Column<?, T> column = grid.getVisibleColumns().get(columnIndexDOM); + // Row objects only make sense for body section of Grid. + T rowObject; + if (section == Section.BODY) { + rowObject = grid.getDataSource().getRow(row); + } else { + rowObject = null; + } + // At least for now we don't need to have the actual TableRowElement // available. - getRowReference().set(row, grid.getDataSource().getRow(row), null); + getRowReference().set(row, rowObject, null); + int columnIndex = grid.getColumns().indexOf(column); set(columnIndexDOM, columnIndex, column); this.element = targetCell.getElement(); + this.section = section; } @Override public TableCellElement getElement() { return element; } + + /** + * Is the cell reference for a cell in the header of the Grid. + * + * @since 7.5 + * @return <code>true</true> if referenced cell is in the header, + * <code>false</code> if not + */ + public boolean isHeader() { + return section == Section.HEADER; + } + + /** + * Is the cell reference for a cell in the body of the Grid. + * + * @since 7.5 + * @return <code>true</true> if referenced cell is in the body, + * <code>false</code> if not + */ + public boolean isBody() { + return section == Section.BODY; + } + + /** + * Is the cell reference for a cell in the footer of the Grid. + * + * @since 7.5 + * @return <code>true</true> if referenced cell is in the footer, + * <code>false</code> if not + */ + public boolean isFooter() { + return section == Section.FOOTER; + } + + /** + * Gets the Grid section where the referenced cell is. + * + * @since 7.5 + * @return grid section + */ + public Section getSection() { + return section; + } } diff --git a/client/src/com/vaadin/client/widgets/Escalator.java b/client/src/com/vaadin/client/widgets/Escalator.java index 7c18df3c7d..bb497e7e13 100644 --- a/client/src/com/vaadin/client/widgets/Escalator.java +++ b/client/src/com/vaadin/client/widgets/Escalator.java @@ -1354,6 +1354,8 @@ public class Escalator extends Widget implements RequiresResize, * Any extra content, such as spacers for the body, should not be * included in this count. * + * @since 7.5.0 + * * @return the actual DOM count of rows */ public abstract int getDomRowCount(); @@ -1755,6 +1757,8 @@ public class Escalator extends Widget implements RequiresResize, * In practice, this applies for all header and footer rows. For body * rows, it applies for all rows except spacer rows. * + * @since 7.5.0 + * * @param tr * the row element to check for if it is or has elements that * can be frozen @@ -2118,6 +2122,8 @@ public class Escalator extends Widget implements RequiresResize, * Note that {@link Escalator#getBody() the body} will calculate its * height, while the others will return a precomputed value. * + * @since 7.5.0 + * * @return the height of this table section */ protected abstract double getHeightOfSection(); @@ -5465,6 +5471,12 @@ public class Escalator extends Widget implements RequiresResize, } } + /** + * Utility class for parsing and storing SubPart request string attributes + * for Grid and Escalator. + * + * @since 7.5.0 + */ public static class SubPartArguments { private String type; private int[] indices; @@ -6647,7 +6659,7 @@ public class Escalator extends Widget implements RequiresResize, @Override @SuppressWarnings("deprecation") public com.google.gwt.user.client.Element getSubPartElement(String subPart) { - SubPartArguments args = parseSubPartArguments(subPart); + SubPartArguments args = SubPartArguments.create(subPart); Element tableStructureElement = getSubPartElementTableStructure(args); if (tableStructureElement != null) { @@ -6810,8 +6822,4 @@ public class Escalator extends Widget implements RequiresResize, private String getSubPartNameSpacer(Element subElement) { return body.spacerContainer.getSubPartName(subElement); } - - public static SubPartArguments parseSubPartArguments(String subPart) { - return SubPartArguments.create(subPart); - } } diff --git a/client/src/com/vaadin/client/widgets/Grid.java b/client/src/com/vaadin/client/widgets/Grid.java index cc37074259..9cd42199c7 100644 --- a/client/src/com/vaadin/client/widgets/Grid.java +++ b/client/src/com/vaadin/client/widgets/Grid.java @@ -224,6 +224,8 @@ public class Grid<T> extends ResizeComposite implements /** * Abstract base class for Grid header and footer sections. * + * @since 7.5.0 + * * @param <ROWTYPE> * the type of the rows in the section */ @@ -1111,6 +1113,7 @@ public class Grid<T> extends ResizeComposite implements public static final int KEYCODE_HIDE = KeyCodes.KEY_ESCAPE; private static final String ERROR_CLASS_NAME = "error"; + private static final String NOT_EDITABLE_CLASS_NAME = "not-editable"; protected enum State { INACTIVE, ACTIVATING, BINDING, ACTIVE, SAVING @@ -1136,6 +1139,7 @@ public class Grid<T> extends ResizeComposite implements private boolean enabled = false; private State state = State.INACTIVE; private int rowIndex = -1; + private int columnIndex = -1; private String styleName = null; private HandlerRegistration scrollHandler; @@ -1202,8 +1206,11 @@ public class Grid<T> extends ResizeComposite implements state = State.ACTIVE; bindTimeout.cancel(); - showOverlay(grid.getEscalator().getBody() - .getRowElement(request.getRowIndex())); + assert rowIndex == request.getRowIndex() : "Request row index " + + request.getRowIndex() + + " did not match the saved row index " + rowIndex; + + showOverlay(); } } @@ -1273,17 +1280,33 @@ public class Grid<T> extends ResizeComposite implements } /** - * Opens the editor over the row with the given index. + * Equivalent to {@code editRow(rowIndex, -1)}. + * + * @see #editRow(int, int) + */ + public void editRow(int rowIndex) { + editRow(rowIndex, -1); + } + + /** + * Opens the editor over the row with the given index and attempts to + * focus the editor widget in the given column index. Does not move + * focus if the widget is not focusable or if the column index is -1. * * @param rowIndex * the index of the row to be edited + * @param columnIndex + * the column index of the editor widget that should be + * initially focused or -1 to not set focus * * @throws IllegalStateException * if this editor is not enabled * @throws IllegalStateException * if this editor is already in edit mode + * + * @since 7.5 */ - public void editRow(int rowIndex) { + public void editRow(int rowIndex, int columnIndex) { if (!enabled) { throw new IllegalStateException( "Cannot edit row: editor is not enabled"); @@ -1294,6 +1317,7 @@ public class Grid<T> extends ResizeComposite implements } this.rowIndex = rowIndex; + this.columnIndex = columnIndex; state = State.ACTIVATING; @@ -1482,15 +1506,31 @@ public class Grid<T> extends ResizeComposite implements } /** - * Opens the editor overlay over the given table row. + * Equivalent to {@code showOverlay()}. The argument is ignored. + * + * @param unused + * ignored argument * - * @param tr - * the row to be edited + * @deprecated As of 7.5, use {@link #showOverlay()} instead. */ - protected void showOverlay(TableRowElement tr) { + @Deprecated + protected void showOverlay(TableRowElement unused) { + showOverlay(); + } + + /** + * Opens the editor overlay over the table row indicated by + * {@link #getRow()}. + * + * @since 7.5 + */ + protected void showOverlay() { DivElement gridElement = DivElement.as(grid.getElement()); + TableRowElement tr = grid.getEscalator().getBody() + .getRowElement(rowIndex); + scrollHandler = grid.addScrollHandler(new ScrollHandler() { @Override public void onScroll(ScrollEvent event) { @@ -1513,10 +1553,22 @@ public class Grid<T> extends ResizeComposite implements Column<?, T> column = grid.getVisibleColumn(i); if (column.isEditable()) { Widget editor = getHandler().getWidget(column); + if (editor != null) { columnToWidget.put(column, editor); attachWidget(editor, cell); } + + if (i == columnIndex) { + if (editor instanceof Focusable) { + ((Focusable) editor).focus(); + } else if (editor instanceof com.google.gwt.user.client.ui.Focusable) { + ((com.google.gwt.user.client.ui.Focusable) editor) + .setFocus(true); + } + } + } else { + cell.addClassName(NOT_EDITABLE_CLASS_NAME); } } @@ -1553,7 +1605,7 @@ public class Grid<T> extends ResizeComposite implements // Move message and buttons wrapper on top of cell wrapper if // there is not enough space visible space under and fix the // overlay from the bottom - editorOverlay.appendChild(cellWrapper); + editorOverlay.insertFirst(messageAndButtonsWrapper); int gridHeight = grid.getElement().getOffsetHeight(); editorOverlay.getStyle() .setBottom( @@ -2377,8 +2429,26 @@ public class Grid<T> extends ResizeComposite implements } }); checkBox.setValue(selected); - selectionCell.setWidget(checkBox); + // Select all with space when "select all" cell is active + addHeaderKeyUpHandler(new HeaderKeyUpHandler() { + @Override + public void onKeyUp(GridKeyUpEvent event) { + if (event.getNativeKeyCode() != KeyCodes.KEY_SPACE) { + return; + } + HeaderRow targetHeaderRow = getHeader().getRow( + event.getFocusedCell().getRowIndex()); + if (!targetHeaderRow.isDefault()) { + return; + } + if (event.getFocusedCell().getColumn() == SelectionColumn.this) { + // Send events to ensure row selection state is + // updated + checkBox.setValue(!checkBox.getValue(), true); + } + } + }); } } @@ -3622,24 +3692,26 @@ public class Grid<T> extends ResizeComposite implements private void resolveDragElementHorizontalPosition(final int clientX) { double left = clientX - table.getAbsoluteLeft(); - final double frozenColumnsWidth = getFrozenColumnsWidth(); - if (left < frozenColumnsWidth) { - left = (int) frozenColumnsWidth; - } - // do not show the drag element beyond a spanned header cell + // Do not show the drag element beyond a spanned header cell // limitation final Double leftBound = possibleDropPositions.firstKey(); final Double rightBound = possibleDropPositions.lastKey(); - double scrollLeft = getScrollLeft(); + final double scrollLeft = getScrollLeft(); if (left + scrollLeft < leftBound) { left = leftBound - scrollLeft + autoScrollX; } else if (left + scrollLeft > rightBound) { left = rightBound - scrollLeft + autoScrollX; } - // do not show the drag element beyond the grid - left = Math.max(0, Math.min(left, table.getClientWidth())); + // Do not show the drag element beyond the grid + final int bodyOffsetWidth = getEscalator().getBody().getElement() + .getOffsetWidth(); + // Do not show on left of the frozen columns (even if scrolled) + final int frozenColumnsWidth = (int) getFrozenColumnsWidth(); + + left = Math + .max(frozenColumnsWidth, Math.min(left, bodyOffsetWidth)); left -= dragElement.getClientWidth() / 2; dragElement.getStyle().setLeft(left, Unit.PX); @@ -3933,7 +4005,7 @@ public class Grid<T> extends ResizeComposite implements @Override protected <T> SelectionModel<T> createModel() { - return new SelectionModelSingle<T>(); + return GWT.create(SelectionModelSingle.class); } }, @@ -3944,7 +4016,7 @@ public class Grid<T> extends ResizeComposite implements @Override protected <T> SelectionModel<T> createModel() { - return new SelectionModelMulti<T>(); + return GWT.create(SelectionModelMulti.class); } }, @@ -3955,7 +4027,7 @@ public class Grid<T> extends ResizeComposite implements @Override protected <T> SelectionModel<T> createModel() { - return new SelectionModelNone<T>(); + return GWT.create(SelectionModelNone.class); } }; @@ -5135,9 +5207,12 @@ public class Grid<T> extends ResizeComposite implements if (event.getNativeKeyCode() != KeyCodes.KEY_ENTER) { return; } - - sorter.sort(event.getFocusedCell().getColumn(), - event.isShiftKeyDown()); + if (getHeader().getRow(event.getFocusedCell().getRowIndex()) + .isDefault()) { + // Only sort for enter on the default header + sorter.sort(event.getFocusedCell().getColumn(), + event.isShiftKeyDown()); + } } }); @@ -6298,7 +6373,7 @@ public class Grid<T> extends ResizeComposite implements assert cell != null : "received " + eventType + "-event with a null cell target"; - eventCell.set(cell); + eventCell.set(cell, getSectionFromContainer(container)); // Editor can steal focus from Grid and is still handled if (handleEditorEvent(event, container)) { @@ -6333,6 +6408,20 @@ public class Grid<T> extends ResizeComposite implements } } + private Section getSectionFromContainer(RowContainer container) { + assert container != null : "RowContainer should not be null"; + + if (container == escalator.getBody()) { + return Section.BODY; + } else if (container == escalator.getFooter()) { + return Section.FOOTER; + } else if (container == escalator.getHeader()) { + return Section.HEADER; + } + assert false : "RowContainer was not header, footer or body."; + return null; + } + private boolean isOrContainsInSpacer(Node node) { Node n = node; while (n != null && n != getElement()) { @@ -6369,51 +6458,44 @@ public class Grid<T> extends ResizeComposite implements } private boolean handleEditorEvent(Event event, RowContainer container) { - int type = event.getTypeInt(); - boolean editorIsActive = editor.getState() != Editor.State.INACTIVE; + final int type = event.getTypeInt(); + final int key = event.getKeyCode(); + final boolean editorIsActive = editor.getState() != Editor.State.INACTIVE; - if (editorIsActive) { - // React to closing by keyboard in buffered and unbuffered mode - if (type == Event.ONKEYDOWN - && event.getKeyCode() == Editor.KEYCODE_HIDE) { - editor.cancel(); - return true; - } - // Swallow all other events in buffered mode and everything except - // ONCLICK in unbuffered mode - if (editor.isBuffered() || type != Event.ONCLICK) { - return true; - } - } + final boolean openEvent = type == Event.ONDBLCLICK + || (type == Event.ONKEYDOWN && key == Editor.KEYCODE_SHOW); - if (container == escalator.getBody() && editor.isEnabled()) { + final boolean moveEvent = type == Event.ONCLICK; - boolean opened = false; + final boolean closeEvent = type == Event.ONKEYDOWN + && key == Editor.KEYCODE_HIDE; - if (editorIsActive && !editor.isBuffered() && type == Event.ONCLICK) { - editor.hide(); - cellFocusHandler.setCellFocus(eventCell); - editor.editRow(eventCell.getRowIndex()); - opened = true; - } else if (type == Event.ONDBLCLICK) { - editor.editRow(eventCell.getRowIndex()); - opened = true; - } else if (type == Event.ONKEYDOWN - && event.getKeyCode() == Editor.KEYCODE_SHOW) { - editor.editRow(cellFocusHandler.rowWithFocus); - opened = true; - } + if (!editorIsActive && editor.isEnabled() && openEvent) { + editor.editRow(eventCell.getRowIndex(), + eventCell.getColumnIndexDOM()); + fireEvent(new EditorOpenEvent(eventCell)); - if (opened) { - if (editorIsActive) { - fireEvent(new EditorMoveEvent(eventCell)); - } else { - fireEvent(new EditorOpenEvent(eventCell)); - } - return true; - } + return true; + + } else if (editorIsActive && eventCell.isBody() && moveEvent) { + editor.hide(); + cellFocusHandler.setCellFocus(eventCell); + + editor.editRow(eventCell.getRowIndex(), + eventCell.getColumnIndexDOM()); + + fireEvent(new EditorMoveEvent(eventCell)); + + return true; + + } else if (editorIsActive && closeEvent) { + editor.cancel(); + FocusUtil.setFocus(this, true); + + return true; } - return false; + + return editorIsActive; } private boolean handleRendererEvent(Event event, RowContainer container) { @@ -6639,7 +6721,7 @@ public class Grid<T> extends ResizeComposite implements return DOM.asOld(escalatorElement); } - SubPartArguments args = Escalator.parseSubPartArguments(subPart); + SubPartArguments args = SubPartArguments.create(subPart); Element editor = getSubPartElementEditor(args); if (editor != null) { @@ -7949,4 +8031,17 @@ public class Grid<T> extends ResizeComposite implements public boolean isEditorBuffered() { return editor.isBuffered(); } + + /** + * Returns the {@link EventCellReference} for the latest event fired from + * this Grid. + * <p> + * Note: This cell reference will be updated when firing the next event. + * + * @since 7.5 + * @return event cell reference + */ + public EventCellReference<T> getEventCell() { + return eventCell; + } } |