diff options
Diffstat (limited to 'src/com/vaadin')
24 files changed, 324 insertions, 265 deletions
diff --git a/src/com/vaadin/event/LayoutEvents.java b/src/com/vaadin/event/LayoutEvents.java index e35d527347..5c7fc0db28 100644 --- a/src/com/vaadin/event/LayoutEvents.java +++ b/src/com/vaadin/event/LayoutEvents.java @@ -3,6 +3,7 @@ */ package com.vaadin.event; +import java.io.Serializable; import java.lang.reflect.Method; import com.vaadin.event.MouseEvents.ClickEvent; @@ -28,21 +29,93 @@ public interface LayoutEvents { } /** + * The interface for adding and removing <code>LayoutClickEvent</code> + * listeners. By implementing this interface a class explicitly announces + * that it will generate a <code>LayoutClickEvent</code> when a component + * inside it is clicked and a <code>LayoutClickListener</code> is + * registered. + * <p> + * Note: The general Java convention is not to explicitly declare that a + * class generates events, but to directly define the + * <code>addListener</code> and <code>removeListener</code> methods. That + * way the caller of these methods has no real way of finding out if the + * class really will send the events, or if it just defines the methods to + * be able to implement an interface. + * </p> + * + * @since 6.5.2 + * @see LayoutClickListener + * @see LayoutClickEvent + */ + public interface LayoutClickNotifier extends Serializable { + /** + * Add a click listener to the layout. The listener is called whenever + * the user clicks inside the layout. An event is also triggered when + * the click targets a component inside a nested layout or Panel, + * provided the targeted component does not prevent the click event from + * propagating. A caption is not considered part of a component. + * + * The child component that was clicked is included in the + * {@link LayoutClickEvent}. + * + * Use {@link #removeListener(LayoutClickListener)} to remove the + * listener. + * + * @param listener + * The listener to add + */ + public void addListener(LayoutClickListener listener); + + /** + * Removes an LayoutClickListener. + * + * @param listener + * LayoutClickListener to be removed + */ + public void removeListener(LayoutClickListener listener); + } + + /** * An event fired when the layout has been clicked. The event contains * information about the target layout (component) and the child component * that was clicked. If no child component was found it is set to null. - * */ public static class LayoutClickEvent extends ClickEvent { - private Component childComponent; + private final Component clickedComponent; + private final Component childComponent; public LayoutClickEvent(Component source, - MouseEventDetails mouseEventDetails, Component childComponent) { + MouseEventDetails mouseEventDetails, + Component clickedComponent, Component childComponent) { super(source, mouseEventDetails); + this.clickedComponent = clickedComponent; this.childComponent = childComponent; } + /** + * Returns the component that was clicked, which is somewhere inside the + * parent layout on which the listener was registered. + * + * For the direct child component of the layout, see + * {@link #getChildComponent()}. + * + * @return clicked {@link Component}, null if none found + */ + public Component getClickedComponent() { + return clickedComponent; + } + + /** + * Returns the direct child component of the layout which contains the + * clicked component. + * + * For the clicked component inside that child component of the layout, + * see {@link #getClickedComponent()}. + * + * @return direct child {@link Component} of the layout which contains + * the clicked Component, null if none found + */ public Component getChildComponent() { return childComponent; } diff --git a/src/com/vaadin/event/ShortcutAction.java b/src/com/vaadin/event/ShortcutAction.java index cd426d2f72..c722d2e80e 100644 --- a/src/com/vaadin/event/ShortcutAction.java +++ b/src/com/vaadin/event/ShortcutAction.java @@ -367,5 +367,7 @@ public class ShortcutAction extends Action { public static final int CTRL = 17; public static final int ALT = 18; + + public static final int META = 91; } } diff --git a/src/com/vaadin/terminal/gwt/client/BrowserInfo.java b/src/com/vaadin/terminal/gwt/client/BrowserInfo.java index 1ac060c29f..5981c2cfed 100644 --- a/src/com/vaadin/terminal/gwt/client/BrowserInfo.java +++ b/src/com/vaadin/terminal/gwt/client/BrowserInfo.java @@ -169,6 +169,10 @@ public class BrowserInfo { return browserDetails.isIE(); } + public boolean isFirefox() { + return browserDetails.isFirefox(); + } + public boolean isSafari() { return browserDetails.isSafari(); } @@ -213,6 +217,11 @@ public class BrowserInfo { && browserDetails.getBrowserEngineVersion() == 1.9; } + public boolean isFF4() { + return browserDetails.isFirefox() + && browserDetails.getBrowserMajorVersion() == 4; + } + /** * Returns the Gecko version if the browser is Gecko based. The Gecko * version for Firefox 2 is 1.8 and 1.9 for Firefox 3. diff --git a/src/com/vaadin/terminal/gwt/client/EventId.java b/src/com/vaadin/terminal/gwt/client/EventId.java index c6b725a562..077564e846 100644 --- a/src/com/vaadin/terminal/gwt/client/EventId.java +++ b/src/com/vaadin/terminal/gwt/client/EventId.java @@ -3,4 +3,5 @@ package com.vaadin.terminal.gwt.client; public interface EventId { public static final String BLUR = "blur"; public static final String FOCUS = "focus"; + public static final String LAYOUT_CLICK = "layout_click"; } diff --git a/src/com/vaadin/terminal/gwt/client/Util.java b/src/com/vaadin/terminal/gwt/client/Util.java index 6095c35c85..2ee4ba8cbd 100644 --- a/src/com/vaadin/terminal/gwt/client/Util.java +++ b/src/com/vaadin/terminal/gwt/client/Util.java @@ -816,6 +816,11 @@ public class Util { * <literal>element</literal> is not part of any child component, null is * returned. * + * This method returns the immediate child of the parent that contains the + * element. See + * {@link #getPaintableForElement(ApplicationConnection, Container, Element)} + * for the deepest nested paintable of parent that contains the element. + * * @param client * A reference to ApplicationConnection * @param parent @@ -855,6 +860,56 @@ public class Util { } /** + * Locates the nested child component of <literal>parent</literal> which + * contains the element <literal>element</literal>. The child component is + * also returned if "element" is part of its caption. If + * <literal>element</literal> is not part of any child component, null is + * returned. + * + * This method returns the deepest nested Paintable. See + * {@link #getChildPaintableForElement(ApplicationConnection, Container, Element)} + * for the immediate child component of parent that contains the element. + * + * @param client + * A reference to ApplicationConnection + * @param parent + * The widget that contains <literal>element</literal>. + * @param element + * An element that is a sub element of the parent + * @return The Paintable which the element is a part of. Null if the element + * does not belong to a child. + */ + public static Paintable getPaintableForElement( + ApplicationConnection client, Container parent, Element element) { + Element rootElement = ((Widget) parent).getElement(); + while (element != null && element != rootElement) { + Paintable paintable = client.getPaintable(element); + if (paintable == null) { + String ownerPid = VCaption.getCaptionOwnerPid(element); + if (ownerPid != null) { + paintable = client.getPaintable(ownerPid); + } + } + + if (paintable != null) { + // check that inside the rootElement + while (element != null && element != rootElement) { + element = (Element) element.getParentElement(); + } + if (element != rootElement) { + return null; + } else { + return paintable; + } + } + + element = (Element) element.getParentElement(); + } + + return null; + } + + /** * Will (attempt) to focus the given DOM Element. * * @param el diff --git a/src/com/vaadin/terminal/gwt/client/ui/ShortcutActionHandler.java b/src/com/vaadin/terminal/gwt/client/ui/ShortcutActionHandler.java index 77210caa63..01f7187aa1 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/ShortcutActionHandler.java +++ b/src/com/vaadin/terminal/gwt/client/ui/ShortcutActionHandler.java @@ -224,6 +224,7 @@ class ShortcutKeyCombination { public static final int SHIFT = 16; public static final int CTRL = 17; public static final int ALT = 18; + public static final int META = 91; char keyCode = 0; private int modifiersMask; @@ -255,6 +256,10 @@ class ShortcutKeyCombination { modifiersMask = modifiersMask | KeyboardListener.MODIFIER_SHIFT; break; + case META: + modifiersMask = modifiersMask + | KeyboardListener.MODIFIER_META; + break; default: break; } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java index 50e33c4c19..b0590ce5a0 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java @@ -24,6 +24,7 @@ import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.BrowserInfo; import com.vaadin.terminal.gwt.client.Container; +import com.vaadin.terminal.gwt.client.EventId; import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.UIDL; @@ -39,8 +40,6 @@ public class VAbsoluteLayout extends ComplexPanel implements Container { /** Class name, prefix in styling */ public static final String CLASSNAME = "v-absolutelayout"; - public static final String CLICK_EVENT_IDENTIFIER = "click"; - private DivElement marginElement; protected final Element canvas = DOM.createDiv(); @@ -58,7 +57,7 @@ public class VAbsoluteLayout extends ComplexPanel implements Container { private boolean rendering; private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler( - this, CLICK_EVENT_IDENTIFIER) { + this, EventId.LAYOUT_CLICK) { @Override protected Paintable getChildComponent(Element element) { @@ -427,17 +426,17 @@ public class VAbsoluteLayout extends ComplexPanel implements Container { } /** - * Returns the child component which contains "element". The child component - * is also returned if "element" is part of its caption. + * Returns the deepest nested child component which contains "element". The + * child component is also returned if "element" is part of its caption. * * @param element - * An element that is a sub element of the root element in this - * layout + * An element that is a nested sub element of the root element in + * this layout * @return The Paintable which the element is a part of. Null if the element * belongs to the layout and not to a child. */ private Paintable getComponent(Element element) { - return Util.getChildPaintableForElement(client, this, element); + return Util.getPaintableForElement(client, this, element); } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java index e0a74735b7..213651ab89 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java @@ -21,6 +21,7 @@ import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.BrowserInfo; import com.vaadin.terminal.gwt.client.Container; +import com.vaadin.terminal.gwt.client.EventId; import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.StyleConstants; @@ -33,14 +34,13 @@ import com.vaadin.terminal.gwt.client.ValueMap; public class VCssLayout extends SimplePanel implements Paintable, Container { public static final String TAGNAME = "csslayout"; public static final String CLASSNAME = "v-" + TAGNAME; - public static final String CLICK_EVENT_IDENTIFIER = "click"; private FlowPane panel = new FlowPane(); private Element margin = DOM.createDiv(); private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler( - this, CLICK_EVENT_IDENTIFIER) { + this, EventId.LAYOUT_CLICK) { @Override protected Paintable getChildComponent(Element element) { @@ -253,8 +253,8 @@ public class VCssLayout extends SimplePanel implements Paintable, Container { } private Paintable getComponent(Element element) { - return Util.getChildPaintableForElement(client, VCssLayout.this, - element); + return Util + .getPaintableForElement(client, VCssLayout.this, element); } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java index e5e3efd7c8..1d26103ae2 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java @@ -23,6 +23,7 @@ import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.Container; +import com.vaadin.terminal.gwt.client.EventId; import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.client.RenderSpace; import com.vaadin.terminal.gwt.client.StyleConstants; @@ -35,8 +36,6 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { public static final String CLASSNAME = "v-gridlayout"; - public static final String CLICK_EVENT_IDENTIFIER = "click"; - private DivElement margin = Document.get().createDivElement(); private final AbsolutePanel canvas = new AbsolutePanel(); @@ -72,7 +71,7 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { private boolean sizeChangedDuringRendering = false; private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler( - this, CLICK_EVENT_IDENTIFIER) { + this, EventId.LAYOUT_CLICK) { @Override protected Paintable getChildComponent(Element element) { @@ -1111,17 +1110,17 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { } /** - * Returns the child component which contains "element". The child component - * is also returned if "element" is part of its caption. + * Returns the deepest nested child component which contains "element". The + * child component is also returned if "element" is part of its caption. * * @param element - * An element that is a sub element of the root element in this - * layout + * An element that is a nested sub element of the root element in + * this layout * @return The Paintable which the element is a part of. Null if the element * belongs to the layout and not to a child. */ private Paintable getComponent(Element element) { - return Util.getChildPaintableForElement(client, this, element); + return Util.getPaintableForElement(client, this, element); } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java b/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java index 60610556c9..2b996d5792 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java @@ -77,8 +77,8 @@ public class VMenuBar extends SimpleFocusablePanel implements Paintable, private String width = "notinited"; - private VLazyExecutor iconLoadedExecutioner = new VLazyExecutor( - 100, new ScheduledCommand() { + private VLazyExecutor iconLoadedExecutioner = new VLazyExecutor(100, + new ScheduledCommand() { public void execute() { iLayout(true); @@ -578,13 +578,6 @@ public class VMenuBar extends SimpleFocusablePanel implements Paintable, * @param item */ public void showChildMenu(CustomMenuItem item) { - final int shadowSpace = 10; - - popup = new VOverlay(true, false, true); - popup.setStyleName(CLASSNAME + "-popup"); - popup.setWidget(item.getSubMenu()); - popup.addCloseHandler(this); - popup.addAutoHidePartner(item.getElement()); int left = 0; int top = 0; @@ -597,6 +590,18 @@ public class VMenuBar extends SimpleFocusablePanel implements Paintable, top = item.getParentMenu().getAbsoluteTop() + item.getParentMenu().getOffsetHeight(); } + showChildMenuAt(item, top, left); + } + + protected void showChildMenuAt(CustomMenuItem item, int top, int left) { + final int shadowSpace = 10; + + popup = new VOverlay(true, false, true); + popup.setStyleName(CLASSNAME + "-popup"); + popup.setWidget(item.getSubMenu()); + popup.addCloseHandler(this); + popup.addAutoHidePartner(item.getElement()); + popup.setPopupPosition(left, top); item.getSubMenu().onShow(); @@ -758,7 +763,7 @@ public class VMenuBar extends SimpleFocusablePanel implements Paintable, * A class to hold information on menu items * */ - private class CustomMenuItem extends Widget implements HasHTML { + protected static class CustomMenuItem extends Widget implements HasHTML { private ApplicationConnection client; diff --git a/src/com/vaadin/terminal/gwt/client/ui/VNotification.java b/src/com/vaadin/terminal/gwt/client/ui/VNotification.java index 7e7ccf1791..bc0b0367bd 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VNotification.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VNotification.java @@ -9,6 +9,7 @@ import java.util.Date; import java.util.EventObject;
import java.util.Iterator;
+import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
@@ -255,6 +256,10 @@ public class VNotification extends VOverlay { fade();
return false;
}
+ } else if (type == Event.ONKEYDOWN
+ && event.getKeyCode() == KeyCodes.KEY_ESCAPE) {
+ fade();
+ return false;
}
if (temporaryStyle == STYLE_SYSTEM) {
return true;
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java index bf64219a7b..fe8f6ab6b3 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java @@ -16,6 +16,7 @@ import com.google.gwt.user.client.Element; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.BrowserInfo; +import com.vaadin.terminal.gwt.client.EventId; import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize; import com.vaadin.terminal.gwt.client.RenderInformation.Size; @@ -30,8 +31,6 @@ public class VOrderedLayout extends CellBasedLayout { public static final String CLASSNAME = "v-orderedlayout"; - public static final String CLICK_EVENT_IDENTIFIER = "click"; - private int orientation; // Can be removed once OrderedLayout is removed @@ -57,7 +56,7 @@ public class VOrderedLayout extends CellBasedLayout { private ValueMap alignments; private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler( - this, CLICK_EVENT_IDENTIFIER) { + this, EventId.LAYOUT_CLICK) { @Override protected Paintable getChildComponent(Element element) { @@ -954,17 +953,17 @@ public class VOrderedLayout extends CellBasedLayout { } /** - * Returns the child component which contains "element". The child component - * is also returned if "element" is part of its caption. + * Returns the deepest nested child component which contains "element". The + * child component is also returned if "element" is part of its caption. * * @param element - * An element that is a sub element of the root element in this - * layout + * An element that is a nested sub element of the root element in + * this layout * @return The Paintable which the element is a part of. Null if the element * belongs to the layout and not to a child. */ private Paintable getComponent(Element element) { - return Util.getChildPaintableForElement(client, this, element); + return Util.getPaintableForElement(client, this, element); } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java index 1cdd9c16e1..00a711c389 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java @@ -2224,6 +2224,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, RowHeadersHeaderCell() { super("0", ""); + this.setStyleName(CLASSNAME + "-header-cell-rowheader"); } @Override @@ -3798,7 +3799,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, if (showRowHeaders) { boolean sorted = tHead.getHeaderCell(col).isSorted(); addCell(uidl, buildCaptionHtmlSnippet(uidl), aligns[col++], - "", true, sorted); + "rowheader", true, sorted); visibleColumnIndex++; } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java index 422f48b2a7..33b97d16cf 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java @@ -536,16 +536,16 @@ public class VSplitPanel extends ComplexPanel implements Container, } } + if (origX != newX) { + resized = true; + } + // Reversed position if (positionReversed) { newX = getOffsetWidth() - newX - getSplitterSize(); } setSplitPosition(newX + "px"); - - if (origX != newX) { - resized = true; - } } private void onVerticalMouseMove(int y) { @@ -579,16 +579,16 @@ public class VSplitPanel extends ComplexPanel implements Container, } } + if (origY != newY) { + resized = true; + } + // Reversed position if (positionReversed) { newY = getOffsetHeight() - newY - getSplitterSize(); } setSplitPosition(newY + "px"); - - if (origY != newY) { - resized = true; - } } public void onMouseUp(Event event) { diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java index bf3ba8f759..5f06285b1f 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java @@ -1564,14 +1564,14 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * If one needs to override parts of the host page, it is suggested that one * overrides on of several submethods which are called by this method: * <ul> - * <li> {@link #setAjaxPageHeaders(HttpServletResponse)} - * <li> {@link #writeAjaxPageHtmlHeadStart(BufferedWriter)} - * <li> {@link #writeAjaxPageHtmlHeader(BufferedWriter, String, String)} - * <li> {@link #writeAjaxPageHtmlBodyStart(BufferedWriter)} + * <li> {@link #setAjaxPageHeaders(HttpServletResponse) + * <li> {@link #writeAjaxPageHtmlHeadStart(BufferedWriter, HttpServletRequest) + * <li> {@link #writeAjaxPageHtmlHeader(BufferedWriter, String, String, HttpServletRequest) + * <li> {@link #writeAjaxPageHtmlBodyStart(BufferedWriter, HttpServletRequest) * <li> - * {@link #writeAjaxPageHtmlVaadinScripts(Window, String, Application, BufferedWriter, String, String, String, String, String, String)} + * {@link #writeAjaxPageHtmlVaadinScripts(Window, String, Application, BufferedWriter, String, String, String, HttpServletRequest) * <li> - * {@link #writeAjaxPageHtmlMainDiv(BufferedWriter, String, String, String)} + * {@link #writeAjaxPageHtmlMainDiv(BufferedWriter, String, String, String, HttpServletRequest) * <li> {@link #writeAjaxPageHtmlBodyEnd(BufferedWriter)} * </ul> * @@ -1622,9 +1622,9 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements if (!fragment) { setAjaxPageHeaders(response); - writeAjaxPageHtmlHeadStart(page); - writeAjaxPageHtmlHeader(page, title, themeUri); - writeAjaxPageHtmlBodyStart(page); + writeAjaxPageHtmlHeadStart(page, request); + writeAjaxPageHtmlHeader(page, title, themeUri, request); + writeAjaxPageHtmlBodyStart(page, request); } String appId = appUrl; @@ -1669,7 +1669,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements + "\""; } - writeAjaxPageHtmlMainDiv(page, appId, classNames, divStyle); + writeAjaxPageHtmlMainDiv(page, appId, classNames, divStyle, request); if (!fragment) { page.write("</body>\n</html>\n"); @@ -1737,10 +1737,11 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * @param appId * @param classNames * @param divStyle + * @param request * @throws IOException */ protected void writeAjaxPageHtmlMainDiv(final BufferedWriter page, - String appId, String classNames, String divStyle) + String appId, String classNames, String divStyle, HttpServletRequest request) throws IOException { page.write("<div id=\"" + appId + "\" class=\"" + classNames + "\" " + (divStyle != null ? divStyle : "") + "></div>\n"); @@ -1913,10 +1914,11 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * Override this method if you want to add some custom html to the page. * * @param page + * @param request * @throws IOException */ - protected void writeAjaxPageHtmlBodyStart(final BufferedWriter page) - throws IOException { + protected void writeAjaxPageHtmlBodyStart(final BufferedWriter page, + final HttpServletRequest request) throws IOException { page.write("\n</head>\n<body scroll=\"auto\" class=\"" + ApplicationConnection.GENERATED_BODY_CLASSNAME + "\">\n"); } @@ -1930,15 +1932,26 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * @param page * @param title * @param themeUri + * @param request * @throws IOException */ protected void writeAjaxPageHtmlHeader(final BufferedWriter page, - String title, String themeUri) throws IOException { + String title, String themeUri, final HttpServletRequest request) + throws IOException { page.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\n"); - // Force IE9 into IE8 mode. Remove when IE 9 mode works (#5546), chrome - // frame if available #5261 - page.write("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=8,chrome=1\"/>\n"); + WebBrowser browser = getApplicationContext(request.getSession()) + .getBrowser(); + if (browser.isIE()) { + // Chrome frame in all versions of IE (only if Chrome frame is + // installed) + if (browser.getBrowserMajorVersion() == 9) { + // Force IE9 into IE8 mode. Remove when IE 9 mode works (#5546) + page.write("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=8,chrome=1\"/>\n"); + } else { + page.write("<meta http-equiv=\"X-UA-Compatible\" content=\"chrome=1\"/>\n"); + } + } page.write("<style type=\"text/css\">" + "html, body {height:100%;margin:0;}</style>"); @@ -1962,10 +1975,11 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * beginning of the page. * * @param page + * @param request * @throws IOException */ - protected void writeAjaxPageHtmlHeadStart(final BufferedWriter page) - throws IOException { + protected void writeAjaxPageHtmlHeadStart(final BufferedWriter page, + final HttpServletRequest request) throws IOException { // write html header page.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD " + "XHTML 1.0 Transitional//EN\" " diff --git a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java index d9d31f0951..4cad1cc8e6 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java @@ -85,6 +85,8 @@ import com.vaadin.ui.Window; public abstract class AbstractCommunicationManager implements Paintable.RepaintRequestListener, Serializable { + private static final String DASHDASH = "--"; + private static final Logger logger = Logger .getLogger(AbstractCommunicationManager.class.getName()); @@ -382,8 +384,6 @@ public abstract class AbstractCommunicationManager implements Response response, StreamVariable streamVariable, String variableName, VariableOwner owner, String boundary) throws IOException { - boundary = CRLF + "--" + boundary + "--"; - // multipart parsing, supports only one file for request, but that is // fine for our current terminal @@ -417,7 +417,8 @@ public abstract class AbstractCommunicationManager implements } } - contentLength -= (boundary.length() + 2); // 2 == CRLF + contentLength -= (boundary.length() + CRLF.length() + 2 + * DASHDASH.length() + 2); // 2 == CRLF /* * Reads bytes from the underlying stream. Compares the read bytes to @@ -2167,7 +2168,14 @@ public abstract class AbstractCommunicationManager implements abstract protected void cleanStreamVariable(VariableOwner owner, String name); - private static class SimpleMultiPartInputStream extends InputStream { + /** + * Stream that extracts content from another stream until the boundary + * string is encountered. + * + * Public only for unit tests, should be considered private for all other + * purposes. + */ + public static class SimpleMultiPartInputStream extends InputStream { /** * Counter of how many characters have been matched to boundary string @@ -2192,7 +2200,8 @@ public abstract class AbstractCommunicationManager implements public SimpleMultiPartInputStream(InputStream realInputStream, String boundaryString) { - boundary = boundaryString.toCharArray(); + boundary = (CRLF + DASHDASH + boundaryString + DASHDASH) + .toCharArray(); this.realInputStream = realInputStream; } diff --git a/src/com/vaadin/ui/AbsoluteLayout.java b/src/com/vaadin/ui/AbsoluteLayout.java index 538cc26c77..3b0239af7b 100644 --- a/src/com/vaadin/ui/AbsoluteLayout.java +++ b/src/com/vaadin/ui/AbsoluteLayout.java @@ -12,10 +12,11 @@ import java.util.Map; import com.vaadin.event.LayoutEvents.LayoutClickEvent; import com.vaadin.event.LayoutEvents.LayoutClickListener; +import com.vaadin.event.LayoutEvents.LayoutClickNotifier; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.Sizeable; -import com.vaadin.terminal.gwt.client.MouseEventDetails; +import com.vaadin.terminal.gwt.client.EventId; import com.vaadin.terminal.gwt.client.ui.VAbsoluteLayout; /** @@ -25,9 +26,10 @@ import com.vaadin.terminal.gwt.client.ui.VAbsoluteLayout; */ @SuppressWarnings("serial") @ClientWidget(VAbsoluteLayout.class) -public class AbsoluteLayout extends AbstractLayout { +public class AbsoluteLayout extends AbstractLayout implements + LayoutClickNotifier { - private static final String CLICK_EVENT = VAbsoluteLayout.CLICK_EVENT_IDENTIFIER; + private static final String CLICK_EVENT = EventId.LAYOUT_CLICK; // The components in the layout private Collection<Component> components = new LinkedHashSet<Component>(); @@ -560,62 +562,11 @@ public class AbsoluteLayout extends AbstractLayout { } } - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.AbstractComponent#changeVariables(java.lang.Object, - * java.util.Map) - */ - @SuppressWarnings("unchecked") - @Override - public void changeVariables(Object source, Map<String, Object> variables) { - super.changeVariables(source, variables); - if (variables.containsKey(CLICK_EVENT)) { - fireClick((Map<String, Object>) variables.get(CLICK_EVENT)); - } - - } - - /** - * Fires a click event when the layout is clicked - * - * @param parameters - * The parameters recieved from the client side implementation - */ - private void fireClick(Map<String, Object> parameters) { - MouseEventDetails mouseDetails = MouseEventDetails - .deSerialize((String) parameters.get("mouseDetails")); - Component childComponent = (Component) parameters.get("component"); - - fireEvent(new LayoutClickEvent(this, mouseDetails, childComponent)); - } - - /** - * Add a click listener to the layout. The listener is called whenever the - * user clicks inside the layout. Also when the click targets a component - * inside the Panel, provided the targeted component does not prevent the - * click event from propagating. - * - * The child component that was clicked is included in the - * {@link LayoutClickEvent}. - * - * Use {@link #removeListener(LayoutClickListener)} to remove the listener. - * - * @param listener - * The listener to add - */ public void addListener(LayoutClickListener listener) { addListener(CLICK_EVENT, LayoutClickEvent.class, listener, LayoutClickListener.clickMethod); } - /** - * Remove a click listener from the layout. The listener should earlier have - * been added using {@link #addListener(LayoutClickListener)}. - * - * @param listener - * The listener to remove - */ public void removeListener(LayoutClickListener listener) { removeListener(CLICK_EVENT, LayoutClickEvent.class, listener); } diff --git a/src/com/vaadin/ui/AbstractLayout.java b/src/com/vaadin/ui/AbstractLayout.java index 5cb698e688..d0cc549138 100644 --- a/src/com/vaadin/ui/AbstractLayout.java +++ b/src/com/vaadin/ui/AbstractLayout.java @@ -4,8 +4,14 @@ package com.vaadin.ui; +import java.util.Map; + +import com.vaadin.event.LayoutEvents.LayoutClickEvent; +import com.vaadin.event.LayoutEvents.LayoutClickNotifier; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; +import com.vaadin.terminal.gwt.client.EventId; +import com.vaadin.terminal.gwt.client.MouseEventDetails; import com.vaadin.ui.Layout.MarginHandler; /** @@ -21,6 +27,8 @@ import com.vaadin.ui.Layout.MarginHandler; public abstract class AbstractLayout extends AbstractComponentContainer implements Layout, MarginHandler { + private static final String CLICK_EVENT = EventId.LAYOUT_CLICK; + protected MarginInfo margins = new MarginInfo(false); /* @@ -77,4 +85,45 @@ public abstract class AbstractLayout extends AbstractComponentContainer } + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.AbstractComponent#changeVariables(java.lang.Object, + * java.util.Map) + */ + @SuppressWarnings("unchecked") + @Override + public void changeVariables(Object source, Map<String, Object> variables) { + super.changeVariables(source, variables); + // not all subclasses use these events + if (this instanceof LayoutClickNotifier + && variables.containsKey(CLICK_EVENT)) { + fireClick((Map<String, Object>) variables.get(CLICK_EVENT)); + } + + } + + /** + * Fire a layout click event. + * + * Note that this method is only used by the subclasses that implement + * {@link LayoutClickNotifier}, and can be overridden for custom click event + * firing. + * + * @param parameters + * The parameters received from the client side implementation + */ + protected void fireClick(Map<String, Object> parameters) { + MouseEventDetails mouseDetails = MouseEventDetails + .deSerialize((String) parameters.get("mouseDetails")); + Component clickedComponent = (Component) parameters.get("component"); + Component childComponent = clickedComponent; + while (childComponent != null && childComponent.getParent() != this) { + childComponent = childComponent.getParent(); + } + + fireEvent(new LayoutClickEvent(this, mouseDetails, clickedComponent, + childComponent)); + } + } diff --git a/src/com/vaadin/ui/AbstractOrderedLayout.java b/src/com/vaadin/ui/AbstractOrderedLayout.java index 7bd52f8feb..8dfbe07b18 100644 --- a/src/com/vaadin/ui/AbstractOrderedLayout.java +++ b/src/com/vaadin/ui/AbstractOrderedLayout.java @@ -11,17 +11,17 @@ import java.util.Map; import com.vaadin.event.LayoutEvents.LayoutClickEvent; import com.vaadin.event.LayoutEvents.LayoutClickListener; +import com.vaadin.event.LayoutEvents.LayoutClickNotifier; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.Sizeable; -import com.vaadin.terminal.gwt.client.MouseEventDetails; -import com.vaadin.terminal.gwt.client.ui.VOrderedLayout; +import com.vaadin.terminal.gwt.client.EventId; @SuppressWarnings("serial") public abstract class AbstractOrderedLayout extends AbstractLayout implements - Layout.AlignmentHandler, Layout.SpacingHandler { + Layout.AlignmentHandler, Layout.SpacingHandler, LayoutClickNotifier { - private static final String CLICK_EVENT = VOrderedLayout.CLICK_EVENT_IDENTIFIER; + private static final String CLICK_EVENT = EventId.LAYOUT_CLICK; private static final Alignment ALIGNMENT_DEFAULT = Alignment.TOP_LEFT; @@ -350,50 +350,11 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements AlignmentUtils.setComponentAlignment(this, component, alignment); } - @SuppressWarnings("unchecked") - @Override - public void changeVariables(Object source, Map<String, Object> variables) { - super.changeVariables(source, variables); - if (variables.containsKey(CLICK_EVENT)) { - fireClick((Map<String, Object>) variables.get(CLICK_EVENT)); - } - - } - - private void fireClick(Map<String, Object> parameters) { - MouseEventDetails mouseDetails = MouseEventDetails - .deSerialize((String) parameters.get("mouseDetails")); - Component childComponent = (Component) parameters.get("component"); - - fireEvent(new LayoutClickEvent(this, mouseDetails, childComponent)); - } - - /** - * Add a click listener to the layout. The listener is called whenever the - * user clicks inside the layout. Also when the click targets a component - * inside the Panel, provided the targeted component does not prevent the - * click event from propagating. - * - * The child component that was clicked is included in the - * {@link LayoutClickEvent}. - * - * Use {@link #removeListener(LayoutClickListener)} to remove the listener. - * - * @param listener - * The listener to add - */ public void addListener(LayoutClickListener listener) { addListener(CLICK_EVENT, LayoutClickEvent.class, listener, LayoutClickListener.clickMethod); } - /** - * Remove a click listener from the layout. The listener should earlier have - * been added using {@link #addListener(LayoutClickListener)}. - * - * @param listener - * The listener to remove - */ public void removeListener(LayoutClickListener listener) { removeListener(CLICK_EVENT, LayoutClickEvent.class, listener); } diff --git a/src/com/vaadin/ui/AbstractSplitPanel.java b/src/com/vaadin/ui/AbstractSplitPanel.java index f81e62aab0..9be8564432 100644 --- a/src/com/vaadin/ui/AbstractSplitPanel.java +++ b/src/com/vaadin/ui/AbstractSplitPanel.java @@ -387,7 +387,8 @@ public abstract class AbstractSplitPanel extends AbstractLayout { } - private void fireClick(Map<String, Object> parameters) { + @Override + protected void fireClick(Map<String, Object> parameters) { MouseEventDetails mouseDetails = MouseEventDetails .deSerialize((String) parameters.get("mouseDetails")); diff --git a/src/com/vaadin/ui/CssLayout.java b/src/com/vaadin/ui/CssLayout.java index db5bae678b..5789a65ed3 100644 --- a/src/com/vaadin/ui/CssLayout.java +++ b/src/com/vaadin/ui/CssLayout.java @@ -6,14 +6,14 @@ package com.vaadin.ui; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; -import java.util.Map; import com.vaadin.event.LayoutEvents.LayoutClickEvent; import com.vaadin.event.LayoutEvents.LayoutClickListener; +import com.vaadin.event.LayoutEvents.LayoutClickNotifier; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.Paintable; -import com.vaadin.terminal.gwt.client.MouseEventDetails; +import com.vaadin.terminal.gwt.client.EventId; import com.vaadin.terminal.gwt.client.ui.VCssLayout; /** @@ -58,9 +58,9 @@ import com.vaadin.terminal.gwt.client.ui.VCssLayout; * */ @ClientWidget(VCssLayout.class) -public class CssLayout extends AbstractLayout { +public class CssLayout extends AbstractLayout implements LayoutClickNotifier { - private static final String CLICK_EVENT = VCssLayout.CLICK_EVENT_IDENTIFIER; + private static final String CLICK_EVENT = EventId.LAYOUT_CLICK; /** * Custom layout slots containing the components. @@ -250,52 +250,11 @@ public class CssLayout extends AbstractLayout { } } - @SuppressWarnings("unchecked") - @Override - public void changeVariables(Object source, Map<String, Object> variables) { - super.changeVariables(source, variables); - - if (variables.containsKey(CLICK_EVENT)) { - fireClick((Map<String, Object>) variables.get(CLICK_EVENT)); - } - - } - - private void fireClick(Map<String, Object> parameters) { - MouseEventDetails mouseDetails = MouseEventDetails - .deSerialize((String) parameters.get("mouseDetails")); - Component childComponent = (Component) parameters.get("component"); - - fireEvent(new LayoutClickEvent(this, mouseDetails, childComponent)); - } - - /** - * Add a click listener to the layout. The listener is called whenever the - * user clicks inside the layout. Also when the click targets a component - * inside the Panel, provided the targeted component does not prevent the - * click event from propagating. A caption is not considered part of a - * component. - * - * The child component that was clicked is included in the - * {@link LayoutClickEvent}. - * - * Use {@link #removeListener(LayoutClickListener)} to remove the listener. - * - * @param listener - * The listener to add - */ public void addListener(LayoutClickListener listener) { addListener(CLICK_EVENT, LayoutClickEvent.class, listener, LayoutClickListener.clickMethod); } - /** - * Remove a click listener from the layout. The listener should earlier have - * been added using {@link #addListener(LayoutClickListener)}. - * - * @param listener - * The listener to remove - */ public void removeListener(LayoutClickListener listener) { removeListener(CLICK_EVENT, LayoutClickEvent.class, listener); } diff --git a/src/com/vaadin/ui/GridLayout.java b/src/com/vaadin/ui/GridLayout.java index fc16daa7c7..40b0ca9a6c 100644 --- a/src/com/vaadin/ui/GridLayout.java +++ b/src/com/vaadin/ui/GridLayout.java @@ -14,9 +14,10 @@ import java.util.Map.Entry; import com.vaadin.event.LayoutEvents.LayoutClickEvent; import com.vaadin.event.LayoutEvents.LayoutClickListener; +import com.vaadin.event.LayoutEvents.LayoutClickNotifier; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; -import com.vaadin.terminal.gwt.client.MouseEventDetails; +import com.vaadin.terminal.gwt.client.EventId; import com.vaadin.terminal.gwt.client.ui.VGridLayout; /** @@ -42,9 +43,9 @@ import com.vaadin.terminal.gwt.client.ui.VGridLayout; @SuppressWarnings("serial") @ClientWidget(VGridLayout.class) public class GridLayout extends AbstractLayout implements - Layout.AlignmentHandler, Layout.SpacingHandler { + Layout.AlignmentHandler, Layout.SpacingHandler, LayoutClickNotifier { - private static final String CLICK_EVENT = VGridLayout.CLICK_EVENT_IDENTIFIER; + private static final String CLICK_EVENT = EventId.LAYOUT_CLICK; /** * Initial grid columns. @@ -1378,51 +1379,11 @@ public class GridLayout extends AbstractLayout implements AlignmentUtils.setComponentAlignment(this, component, alignment); } - @SuppressWarnings("unchecked") - @Override - public void changeVariables(Object source, Map<String, Object> variables) { - super.changeVariables(source, variables); - - if (variables.containsKey(CLICK_EVENT)) { - fireClick((Map<String, Object>) variables.get(CLICK_EVENT)); - } - - } - - private void fireClick(Map<String, Object> parameters) { - MouseEventDetails mouseDetails = MouseEventDetails - .deSerialize((String) parameters.get("mouseDetails")); - Component childComponent = (Component) parameters.get("component"); - - fireEvent(new LayoutClickEvent(this, mouseDetails, childComponent)); - } - - /** - * Add a click listener to the layout. The listener is called whenever the - * user clicks inside the layout. Also when the click targets a component - * inside the Panel, provided the targeted component does not prevent the - * click event from propagating. - * - * The child component that was clicked is included in the - * {@link LayoutClickEvent}. - * - * Use {@link #removeListener(LayoutClickListener)} to remove the listener. - * - * @param listener - * The listener to add - */ public void addListener(LayoutClickListener listener) { addListener(CLICK_EVENT, LayoutClickEvent.class, listener, LayoutClickListener.clickMethod); } - /** - * Remove a click listener from the layout. The listener should earlier have - * been added using {@link #addListener(LayoutClickListener)}. - * - * @param listener - * The listener to remove - */ public void removeListener(LayoutClickListener listener) { removeListener(CLICK_EVENT, LayoutClickEvent.class, listener); } diff --git a/src/com/vaadin/ui/Table.java b/src/com/vaadin/ui/Table.java index 7a114fb021..89f50f01ab 100644 --- a/src/com/vaadin/ui/Table.java +++ b/src/com/vaadin/ui/Table.java @@ -659,7 +659,7 @@ public class Table extends AbstractSelect implements Action.Container, int i = 0; for (final Iterator<Object> it = visibleColumns.iterator(); it .hasNext(); i++) { - alignments[i++] = getColumnAlignment(it.next()); + alignments[i] = getColumnAlignment(it.next()); } return alignments; diff --git a/src/com/vaadin/ui/Upload.java b/src/com/vaadin/ui/Upload.java index 9023e8ed75..053e1897fc 100644 --- a/src/com/vaadin/ui/Upload.java +++ b/src/com/vaadin/ui/Upload.java @@ -218,7 +218,7 @@ public class Upload extends AbstractComponent implements Component.Focusable { } /** - * Upload.Received event is sent when the upload receives a file, regardless + * Upload.FinishedEvent is sent when the upload receives a file, regardless * of whether the reception was successful or failed. If you wish to * distinguish between the two cases, use either SucceededEvent or * FailedEvent, which are both subclasses of the FinishedEvent. @@ -303,7 +303,7 @@ public class Upload extends AbstractComponent implements Component.Focusable { } /** - * Upload.Interrupted event is sent when the upload is received, but the + * Upload.FailedEvent event is sent when the upload is received, but the * reception is interrupted for some reason. * * @author IT Mill Ltd. @@ -391,7 +391,8 @@ public class Upload extends AbstractComponent implements Component.Focusable { } /** - * Upload.Success event is sent when the upload is received successfully. + * Upload.SucceededEvent event is sent when the upload is received + * successfully. * * @author IT Mill Ltd. * @version @@ -415,7 +416,7 @@ public class Upload extends AbstractComponent implements Component.Focusable { } /** - * Upload.Started event is sent when the upload is started to received. + * Upload.StartedEvent event is sent when the upload is started to received. * * @author IT Mill Ltd. * @version |