************************"
- + "
Layouts analyzed on server, total top level problems: "
- + size + "
"));
- if (size > 0) {
- Tree tree = new Tree();
- TreeItem root = new TreeItem("Root problems");
- for (int i = 0; i < size; i++) {
- JSONObject error = array.get(i).isObject();
- printLayoutError(error, root, ac);
- }
- panel.add(tree);
- tree.addItem(root);
-
- }
- if (zeroHeightComponents.size() > 0 || zeroWidthComponents.size() > 0) {
- panel.add(new HTML("
Client side notifications
"
- + "
Following relative sized components where "
- + "rendered to zero size container on client side."
- + " Note that these are not necessary invalid "
- + "states. Just reported here as they might be."));
- if (zeroHeightComponents.size() > 0) {
- panel.add(new HTML(
- "
Vertically zero size:
"));
- printClientSideDetectedIssues(zeroHeightComponents, ac);
- }
- if (zeroWidthComponents.size() > 0) {
- panel.add(new HTML(
- "
Horizontally zero size:
"));
- printClientSideDetectedIssues(zeroWidthComponents, ac);
- }
- }
- log("************************");
- }
-
- private void printClientSideDetectedIssues(
- Set zeroHeightComponents, ApplicationConnection ac) {
- for (final Paintable paintable : zeroHeightComponents) {
- final Container layout = Util.getLayout((Widget) paintable);
-
- VerticalPanel errorDetails = new VerticalPanel();
- errorDetails.add(new Label("" + Util.getSimpleName(paintable)
- + " inside " + Util.getSimpleName(layout)));
- final CheckBox emphasisInUi = new CheckBox(
- "Emphasis components parent in UI (actual component is not visible)");
- emphasisInUi.addClickListener(new ClickListener() {
- public void onClick(Widget sender) {
- if (paintable != null) {
- Element element2 = ((Widget) layout).getElement();
- Widget.setStyleName(element2, "invalidlayout",
- emphasisInUi.isChecked());
- }
- }
- });
- errorDetails.add(emphasisInUi);
- panel.add(errorDetails);
- }
- }
-
- private void printLayoutError(JSONObject error, TreeItem parent,
- final ApplicationConnection ac) {
- final String pid = error.get("id").isString().stringValue();
- final Paintable paintable = ac.getPaintable(pid);
-
- TreeItem errorNode = new TreeItem();
- VerticalPanel errorDetails = new VerticalPanel();
- errorDetails.add(new Label(Util.getSimpleName(paintable) + " id: "
- + pid));
- if (error.containsKey("heightMsg")) {
- errorDetails.add(new Label("Height problem: "
- + error.get("heightMsg")));
- }
- if (error.containsKey("widthMsg")) {
- errorDetails.add(new Label("Width problem: "
- + error.get("widthMsg")));
- }
- final CheckBox emphasisInUi = new CheckBox("Emphasis component in UI");
- emphasisInUi.addClickListener(new ClickListener() {
- public void onClick(Widget sender) {
- if (paintable != null) {
- Element element2 = ((Widget) paintable).getElement();
- Widget.setStyleName(element2, "invalidlayout", emphasisInUi
- .isChecked());
- }
- }
- });
- errorDetails.add(emphasisInUi);
- errorNode.setWidget(errorDetails);
- if (error.containsKey("subErrors")) {
- HTML l = new HTML(
- "Expand this node to show problems that may be dependent on this problem.");
- errorDetails.add(l);
- JSONArray array = error.get("subErrors").isArray();
- for (int i = 0; i < array.size(); i++) {
- JSONValue value = array.get(i);
- if (value != null && value.isObject() != null) {
- printLayoutError(value.isObject(), errorNode, ac);
- } else {
- System.out.print(value);
- }
- }
-
- }
- parent.addItem(errorNode);
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/client/IErrorMessage.java b/src/com/vaadin/terminal/gwt/client/IErrorMessage.java
deleted file mode 100644
index 0f5f45663e..0000000000
--- a/src/com/vaadin/terminal/gwt/client/IErrorMessage.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-@ITMillApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client;
-
-import java.util.Iterator;
-
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.HTML;
-import com.vaadin.terminal.gwt.client.ui.IToolkitOverlay;
-
-public class IErrorMessage extends FlowPanel {
- public static final String CLASSNAME = "i-errormessage";
-
- public IErrorMessage() {
- super();
- setStyleName(CLASSNAME);
- }
-
- public void updateFromUIDL(UIDL uidl) {
- clear();
- if (uidl.getChildCount() == 0) {
- add(new HTML(" "));
- } else {
- for (final Iterator it = uidl.getChildIterator(); it.hasNext();) {
- final Object child = it.next();
- if (child instanceof String) {
- final String errorMessage = (String) child;
- add(new HTML(errorMessage));
- } else if (child instanceof UIDL.XML) {
- final UIDL.XML xml = (UIDL.XML) child;
- add(new HTML(xml.getXMLAsString()));
- } else {
- final IErrorMessage childError = new IErrorMessage();
- add(childError);
- childError.updateFromUIDL((UIDL) child);
- }
- }
- }
- }
-
- /**
- * Shows this error message next to given element.
- *
- * @param indicatorElement
- */
- public void showAt(Element indicatorElement) {
- IToolkitOverlay errorContainer = (IToolkitOverlay) getParent();
- if (errorContainer == null) {
- errorContainer = new IToolkitOverlay();
- errorContainer.setWidget(this);
- }
- errorContainer.setPopupPosition(DOM.getAbsoluteLeft(indicatorElement)
- + 2
- * DOM.getElementPropertyInt(indicatorElement, "offsetHeight"),
- DOM.getAbsoluteTop(indicatorElement)
- + 2
- * DOM.getElementPropertyInt(indicatorElement,
- "offsetHeight"));
- errorContainer.show();
-
- }
-
- public void hide() {
- final IToolkitOverlay errorContainer = (IToolkitOverlay) getParent();
- if (errorContainer != null) {
- errorContainer.hide();
- }
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/client/ITooltip.java b/src/com/vaadin/terminal/gwt/client/ITooltip.java
deleted file mode 100644
index bbea0b4bae..0000000000
--- a/src/com/vaadin/terminal/gwt/client/ITooltip.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
-@ITMillApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.client;
-
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.Timer;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.FlowPanel;
-import com.vaadin.terminal.gwt.client.ui.IToolkitOverlay;
-
-/**
- * TODO open for extension
- */
-public class ITooltip extends IToolkitOverlay {
- private static final String CLASSNAME = "i-tooltip";
- private static final int MARGIN = 4;
- public static final int TOOLTIP_EVENTS = Event.ONKEYDOWN
- | Event.ONMOUSEOVER | Event.ONMOUSEOUT | Event.ONMOUSEMOVE
- | Event.ONCLICK;
- protected static final int MAX_WIDTH = 500;
- private static final int QUICK_OPEN_TIMEOUT = 1000;
- private static final int CLOSE_TIMEOUT = 300;
- private static final int OPEN_DELAY = 750;
- private static final int QUICK_OPEN_DELAY = 100;
- IErrorMessage em = new IErrorMessage();
- Element description = DOM.createDiv();
- private Paintable tooltipOwner;
- private boolean closing = false;
- private boolean opening = false;
- private ApplicationConnection ac;
- // Open next tooltip faster. Disabled after 2 sec of showTooltip-silence.
- private boolean justClosed = false;
-
- public ITooltip(ApplicationConnection client) {
- super(false, false, true);
- ac = client;
- setStyleName(CLASSNAME);
- FlowPanel layout = new FlowPanel();
- setWidget(layout);
- layout.add(em);
- DOM.setElementProperty(description, "className", CLASSNAME + "-text");
- DOM.appendChild(layout.getElement(), description);
- }
-
- private void show(TooltipInfo info) {
- boolean hasContent = false;
- if (info.getErrorUidl() != null) {
- em.setVisible(true);
- em.updateFromUIDL(info.getErrorUidl());
- hasContent = true;
- } else {
- em.setVisible(false);
- }
- if (info.getTitle() != null && !"".equals(info.getTitle())) {
- DOM.setInnerHTML(description, info.getTitle());
- DOM.setStyleAttribute(description, "display", "");
- hasContent = true;
- } else {
- DOM.setInnerHTML(description, "");
- DOM.setStyleAttribute(description, "display", "none");
- }
- if (hasContent) {
- setPopupPositionAndShow(new PositionCallback() {
- public void setPosition(int offsetWidth, int offsetHeight) {
-
- if (offsetWidth > MAX_WIDTH) {
- setWidth(MAX_WIDTH + "px");
- }
-
- offsetWidth = getOffsetWidth();
-
- int x = tooltipEventMouseX + 10 + Window.getScrollLeft();
- int y = tooltipEventMouseY + 10 + Window.getScrollTop();
-
- if (x + offsetWidth + MARGIN - Window.getScrollLeft() > Window
- .getClientWidth()) {
- x = Window.getClientWidth() - offsetWidth - MARGIN;
- }
-
- if (y + offsetHeight + MARGIN - Window.getScrollTop() > Window
- .getClientHeight()) {
- y = tooltipEventMouseY - 5 - offsetHeight;
- }
-
- setPopupPosition(x, y);
- sinkEvents(Event.ONMOUSEOVER | Event.ONMOUSEOUT);
- }
- });
- } else {
- hide();
- }
- }
-
- public void showTooltip(Paintable owner, Event event) {
- if (closing && tooltipOwner == owner) {
- // return to same tooltip, cancel closing
- closeTimer.cancel();
- closing = false;
- justClosedTimer.cancel();
- justClosed = false;
- return;
- }
-
- if (closing) {
- closeNow();
- }
-
- updatePosition(event);
-
- if (opening) {
- showTimer.cancel();
- }
- tooltipOwner = owner;
- if (justClosed) {
- showTimer.schedule(QUICK_OPEN_DELAY);
- } else {
- showTimer.schedule(OPEN_DELAY);
- }
- opening = true;
- }
-
- private void closeNow() {
- if (closing) {
- hide();
- tooltipOwner = null;
- setWidth("");
- closing = false;
- }
- }
-
- private Timer showTimer = new Timer() {
- @Override
- public void run() {
- TooltipInfo info = ac.getTitleInfo(tooltipOwner);
- if (null != info) {
- show(info);
- }
- opening = false;
- }
- };
-
- private Timer closeTimer = new Timer() {
- @Override
- public void run() {
- closeNow();
- justClosedTimer.schedule(2000);
- justClosed = true;
- }
- };
-
- private Timer justClosedTimer = new Timer() {
- @Override
- public void run() {
- justClosed = false;
- }
- };
-
- public void hideTooltip() {
- if (opening) {
- showTimer.cancel();
- opening = false;
- tooltipOwner = null;
- }
- if (!isAttached()) {
- return;
- }
- if (closing) {
- // already about to close
- return;
- }
- closeTimer.schedule(CLOSE_TIMEOUT);
- closing = true;
- justClosed = true;
- justClosedTimer.schedule(QUICK_OPEN_TIMEOUT);
-
- }
-
- private int tooltipEventMouseX;
- private int tooltipEventMouseY;
-
- public void updatePosition(Event event) {
- tooltipEventMouseX = DOM.eventGetClientX(event);
- tooltipEventMouseY = DOM.eventGetClientY(event);
-
- }
-
- public void handleTooltipEvent(Event event, Paintable owner) {
- final int type = DOM.eventGetType(event);
- if ((ITooltip.TOOLTIP_EVENTS & type) == type) {
- if (type == Event.ONMOUSEOVER) {
- showTooltip(owner, event);
- } else if (type == Event.ONMOUSEMOVE) {
- updatePosition(event);
- } else {
- hideTooltip();
- }
- } else {
- // non-tooltip event, hide tooltip
- hideTooltip();
- }
- }
-
- @Override
- public void onBrowserEvent(Event event) {
- final int type = DOM.eventGetType(event);
- // cancel closing event if tooltip is mouseovered; the user might want
- // to scroll of cut&paste
-
- switch (type) {
- case Event.ONMOUSEOVER:
- closeTimer.cancel();
- closing = false;
- break;
- case Event.ONMOUSEOUT:
- hideTooltip();
- break;
- default:
- // NOP
- }
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/client/UIDL.java b/src/com/vaadin/terminal/gwt/client/UIDL.java
index 2205f6b6dd..8429c8a0d9 100644
--- a/src/com/vaadin/terminal/gwt/client/UIDL.java
+++ b/src/com/vaadin/terminal/gwt/client/UIDL.java
@@ -238,12 +238,12 @@ public class UIDL {
return s;
}
- public IUIDLBrowser print_r() {
- return new IUIDLBrowser();
+ public VUIDLBrowser print_r() {
+ return new VUIDLBrowser();
}
- private class IUIDLBrowser extends Tree {
- public IUIDLBrowser() {
+ private class VUIDLBrowser extends Tree {
+ public VUIDLBrowser() {
DOM.setStyleAttribute(getElement(), "position", "");
@@ -255,7 +255,7 @@ public class UIDL {
public void onTreeItemStateChanged(TreeItem item) {
if (item == root) {
removeItem(root);
- IUIDLBrowser.this.removeTreeListener(this);
+ VUIDLBrowser.this.removeTreeListener(this);
addItem(dir());
final Iterator it = treeItemIterator();
while (it.hasNext()) {
diff --git a/src/com/vaadin/terminal/gwt/client/VCaption.java b/src/com/vaadin/terminal/gwt/client/VCaption.java
new file mode 100644
index 0000000000..730680647e
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/VCaption.java
@@ -0,0 +1,443 @@
+/*
+@ITMillApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client;
+
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.HTML;
+import com.vaadin.terminal.gwt.client.ui.Icon;
+
+public class VCaption extends HTML {
+
+ public static final String CLASSNAME = "i-caption";
+
+ private final Paintable owner;
+
+ private Element errorIndicatorElement;
+
+ private Element requiredFieldIndicator;
+
+ private Icon icon;
+
+ private Element captionText;
+
+ private Element clearElement;
+
+ private final ApplicationConnection client;
+
+ private boolean placedAfterComponent = false;
+ private boolean iconOnloadHandled = false;
+
+ private int maxWidth = -1;
+
+ private static String ATTRIBUTE_ICON = "icon";
+ private static String ATTRIBUTE_CAPTION = "caption";
+ private static String ATTRIBUTE_DESCRIPTION = "description";
+ private static String ATTRIBUTE_REQUIRED = "required";
+ private static String ATTRIBUTE_ERROR = "error";
+ private static String ATTRIBUTE_HIDEERRORS = "hideErrors";
+
+ /**
+ *
+ * @param component
+ * optional owner of caption. If not set, getOwner will return
+ * null
+ * @param client
+ */
+ public VCaption(Paintable component, ApplicationConnection client) {
+ super();
+ this.client = client;
+ owner = component;
+ setStyleName(CLASSNAME);
+ sinkEvents(VTooltip.TOOLTIP_EVENTS);
+
+ }
+
+ /**
+ * Updates the caption from UIDL.
+ *
+ * @param uidl
+ * @return true if the position where the caption should be placed has
+ * changed
+ */
+ public boolean updateCaption(UIDL uidl) {
+ setVisible(!uidl.getBooleanAttribute("invisible"));
+
+ boolean wasPlacedAfterComponent = placedAfterComponent;
+
+ placedAfterComponent = true;
+
+ String style = CLASSNAME;
+ if (uidl.hasAttribute("style")) {
+ final String[] styles = uidl.getStringAttribute("style").split(" ");
+ for (int i = 0; i < styles.length; i++) {
+ style += " " + CLASSNAME + "-" + styles[i];
+ }
+ }
+
+ if (uidl.hasAttribute("disabled")) {
+ style += " " + "i-disabled";
+ }
+
+ setStyleName(style);
+
+ if (uidl.hasAttribute(ATTRIBUTE_ICON)) {
+ if (icon == null) {
+ icon = new Icon(client);
+ icon.setWidth("0px");
+ icon.setHeight("0px");
+
+ DOM.insertChild(getElement(), icon.getElement(),
+ getInsertPosition(ATTRIBUTE_ICON));
+ }
+ placedAfterComponent = false;
+
+ iconOnloadHandled = false;
+ icon.setUri(uidl.getStringAttribute(ATTRIBUTE_ICON));
+
+ } else if (icon != null) {
+ // Remove existing
+ DOM.removeChild(getElement(), icon.getElement());
+ icon = null;
+ }
+
+ if (uidl.hasAttribute(ATTRIBUTE_CAPTION)) {
+ if (captionText == null) {
+ captionText = DOM.createDiv();
+ captionText.setClassName("i-captiontext");
+
+ DOM.insertChild(getElement(), captionText,
+ getInsertPosition(ATTRIBUTE_CAPTION));
+ }
+
+ // Update caption text
+ String c = uidl.getStringAttribute(ATTRIBUTE_CAPTION);
+ if (c == null) {
+ c = "";
+ } else {
+ placedAfterComponent = false;
+ }
+ DOM.setInnerText(captionText, c);
+ } else if (captionText != null) {
+ // Remove existing
+ DOM.removeChild(getElement(), captionText);
+ captionText = null;
+ }
+
+ if (uidl.hasAttribute(ATTRIBUTE_DESCRIPTION)) {
+ if (captionText != null) {
+ addStyleDependentName("hasdescription");
+ } else {
+ removeStyleDependentName("hasdescription");
+ }
+ }
+
+ if (uidl.getBooleanAttribute(ATTRIBUTE_REQUIRED)) {
+ if (requiredFieldIndicator == null) {
+ requiredFieldIndicator = DOM.createDiv();
+ requiredFieldIndicator
+ .setClassName("i-required-field-indicator");
+ DOM.setInnerText(requiredFieldIndicator, "*");
+
+ DOM.insertChild(getElement(), requiredFieldIndicator,
+ getInsertPosition(ATTRIBUTE_REQUIRED));
+ }
+ } else if (requiredFieldIndicator != null) {
+ // Remove existing
+ DOM.removeChild(getElement(), requiredFieldIndicator);
+ requiredFieldIndicator = null;
+ }
+
+ if (uidl.hasAttribute(ATTRIBUTE_ERROR)
+ && !uidl.getBooleanAttribute(ATTRIBUTE_HIDEERRORS)) {
+ if (errorIndicatorElement == null) {
+ errorIndicatorElement = DOM.createDiv();
+ DOM.setInnerHTML(errorIndicatorElement, " ");
+ DOM.setElementProperty(errorIndicatorElement, "className",
+ "i-errorindicator");
+
+ DOM.insertChild(getElement(), errorIndicatorElement,
+ getInsertPosition(ATTRIBUTE_ERROR));
+ }
+ } else if (errorIndicatorElement != null) {
+ // Remove existing
+ DOM.removeChild(getElement(), errorIndicatorElement);
+ errorIndicatorElement = null;
+ }
+
+ if (clearElement == null) {
+ clearElement = DOM.createDiv();
+ DOM.setStyleAttribute(clearElement, "clear", "both");
+ DOM.setStyleAttribute(clearElement, "width", "0px");
+ DOM.setStyleAttribute(clearElement, "height", "0px");
+ DOM.setStyleAttribute(clearElement, "overflow", "hidden");
+ DOM.appendChild(getElement(), clearElement);
+ }
+
+ return (wasPlacedAfterComponent != placedAfterComponent);
+ }
+
+ private int getInsertPosition(String element) {
+ int pos = 0;
+ if (element.equals(ATTRIBUTE_ICON)) {
+ return pos;
+ }
+ if (icon != null) {
+ pos++;
+ }
+
+ if (element.equals(ATTRIBUTE_CAPTION)) {
+ return pos;
+ }
+
+ if (captionText != null) {
+ pos++;
+ }
+
+ if (element.equals(ATTRIBUTE_REQUIRED)) {
+ return pos;
+ }
+ if (requiredFieldIndicator != null) {
+ pos++;
+ }
+
+ // if (element.equals(ATTRIBUTE_ERROR)) {
+ // }
+ return pos;
+
+ }
+
+ @Override
+ public void onBrowserEvent(Event event) {
+ super.onBrowserEvent(event);
+ final Element target = DOM.eventGetTarget(event);
+ if (client != null && owner != null && target != getElement()) {
+ client.handleTooltipEvent(event, owner);
+ }
+
+ if (DOM.eventGetType(event) == Event.ONLOAD
+ && icon.getElement() == target && !iconOnloadHandled) {
+ icon.setWidth("");
+ icon.setHeight("");
+
+ /*
+ * IE6 pngFix causes two onload events to be fired and we want to
+ * react only to the first one
+ */
+ iconOnloadHandled = true;
+
+ // if max width defined, recalculate
+ if (maxWidth != -1) {
+ setMaxWidth(maxWidth);
+ } else {
+ String width = getElement().getStyle().getProperty("width");
+ if (width != null && !width.equals("")) {
+ setWidth(getRequiredWidth() + "px");
+ }
+ }
+
+ /*
+ * The size of the icon might affect the size of the component so we
+ * must report the size change to the parent TODO consider moving
+ * the responsibility of reacting to ONLOAD from VCaption to layouts
+ */
+ if (owner != null) {
+ Util.notifyParentOfSizeChange(owner, true);
+ } else {
+ ApplicationConnection
+ .getConsole()
+ .log(
+ "Warning: Icon load event was not propagated because VCaption owner is unknown.");
+ }
+ }
+ }
+
+ public static boolean isNeeded(UIDL uidl) {
+ if (uidl.getStringAttribute(ATTRIBUTE_CAPTION) != null) {
+ return true;
+ }
+ if (uidl.hasAttribute(ATTRIBUTE_ERROR)) {
+ return true;
+ }
+ if (uidl.hasAttribute(ATTRIBUTE_ICON)) {
+ return true;
+ }
+ if (uidl.hasAttribute(ATTRIBUTE_REQUIRED)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns Paintable for which this Caption belongs to.
+ *
+ * @return owner Widget
+ */
+ public Paintable getOwner() {
+ return owner;
+ }
+
+ public boolean shouldBePlacedAfterComponent() {
+ return placedAfterComponent;
+ }
+
+ public int getRenderedWidth() {
+ int width = 0;
+
+ if (icon != null) {
+ width += Util.getRequiredWidth(icon.getElement());
+ }
+
+ if (captionText != null) {
+ width += Util.getRequiredWidth(captionText);
+ }
+ if (requiredFieldIndicator != null) {
+ width += Util.getRequiredWidth(requiredFieldIndicator);
+ }
+ if (errorIndicatorElement != null) {
+ width += Util.getRequiredWidth(errorIndicatorElement);
+ }
+
+ return width;
+
+ }
+
+ public int getRequiredWidth() {
+ int width = 0;
+
+ if (icon != null) {
+ width += Util.getRequiredWidth(icon.getElement());
+ }
+ if (captionText != null) {
+ int textWidth = captionText.getScrollWidth();
+ if (BrowserInfo.get().isFF3()) {
+ /*
+ * In Firefox3 the caption might require more space than the
+ * scrollWidth returns as scrollWidth is rounded down.
+ */
+ int requiredWidth = Util.getRequiredWidth(captionText);
+ if (requiredWidth > textWidth) {
+ textWidth = requiredWidth;
+ }
+
+ }
+ width += textWidth;
+ }
+ if (requiredFieldIndicator != null) {
+ width += Util.getRequiredWidth(requiredFieldIndicator);
+ }
+ if (errorIndicatorElement != null) {
+ width += Util.getRequiredWidth(errorIndicatorElement);
+ }
+
+ return width;
+
+ }
+
+ public int getHeight() {
+ int height = 0;
+ int h;
+
+ if (icon != null) {
+ h = icon.getOffsetHeight();
+ if (h > height) {
+ height = h;
+ }
+ }
+
+ if (captionText != null) {
+ h = captionText.getOffsetHeight();
+ if (h > height) {
+ height = h;
+ }
+ }
+ if (requiredFieldIndicator != null) {
+ h = requiredFieldIndicator.getOffsetHeight();
+ if (h > height) {
+ height = h;
+ }
+ }
+ if (errorIndicatorElement != null) {
+ h = errorIndicatorElement.getOffsetHeight();
+ if (h > height) {
+ height = h;
+ }
+ }
+
+ return height;
+ }
+
+ public void setAlignment(String alignment) {
+ DOM.setStyleAttribute(getElement(), "textAlign", alignment);
+ }
+
+ public void setMaxWidth(int maxWidth) {
+ this.maxWidth = maxWidth;
+ DOM.setStyleAttribute(getElement(), "width", maxWidth + "px");
+
+ if (icon != null) {
+ DOM.setStyleAttribute(icon.getElement(), "width", "");
+ }
+
+ if (captionText != null) {
+ DOM.setStyleAttribute(captionText, "width", "");
+ }
+
+ int requiredWidth = getRequiredWidth();
+ /*
+ * ApplicationConnection.getConsole().log( "Caption maxWidth: " +
+ * maxWidth + ", requiredWidth: " + requiredWidth);
+ */
+ if (requiredWidth > maxWidth) {
+ // Needs to truncate and clip
+ int availableWidth = maxWidth;
+
+ // DOM.setStyleAttribute(getElement(), "width", maxWidth + "px");
+ if (requiredFieldIndicator != null) {
+ availableWidth -= Util.getRequiredWidth(requiredFieldIndicator);
+ }
+
+ if (errorIndicatorElement != null) {
+ availableWidth -= Util.getRequiredWidth(errorIndicatorElement);
+ }
+
+ if (availableWidth < 0) {
+ availableWidth = 0;
+ }
+
+ if (icon != null) {
+ int iconRequiredWidth = Util
+ .getRequiredWidth(icon.getElement());
+ if (availableWidth > iconRequiredWidth) {
+ availableWidth -= iconRequiredWidth;
+ } else {
+ DOM.setStyleAttribute(icon.getElement(), "width",
+ availableWidth + "px");
+ availableWidth = 0;
+ }
+ }
+ if (captionText != null) {
+ int captionWidth = Util.getRequiredWidth(captionText);
+ if (availableWidth > captionWidth) {
+ availableWidth -= captionWidth;
+
+ } else {
+ DOM.setStyleAttribute(captionText, "width", availableWidth
+ + "px");
+ availableWidth = 0;
+ }
+
+ }
+
+ }
+ }
+
+ protected Element getTextElement() {
+ return captionText;
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/VCaptionWrapper.java b/src/com/vaadin/terminal/gwt/client/VCaptionWrapper.java
new file mode 100644
index 0000000000..f67eb77f25
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/VCaptionWrapper.java
@@ -0,0 +1,32 @@
+/*
+@ITMillApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client;
+
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.Widget;
+
+public class VCaptionWrapper extends FlowPanel {
+
+ public static final String CLASSNAME = "i-captionwrapper";
+ VCaption caption;
+ Paintable widget;
+
+ public VCaptionWrapper(Paintable toBeWrapped, ApplicationConnection client) {
+ caption = new VCaption(toBeWrapped, client);
+ add(caption);
+ widget = toBeWrapped;
+ add((Widget) widget);
+ setStyleName(CLASSNAME);
+ }
+
+ public void updateCaption(UIDL uidl) {
+ caption.updateCaption(uidl);
+ setVisible(!uidl.getBooleanAttribute("invisible"));
+ }
+
+ public Paintable getPaintable() {
+ return widget;
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/VDebugConsole.java b/src/com/vaadin/terminal/gwt/client/VDebugConsole.java
new file mode 100755
index 0000000000..aa7663abee
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/VDebugConsole.java
@@ -0,0 +1,466 @@
+/*
+@ITMillApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client;
+
+import java.util.List;
+import java.util.Set;
+
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONValue;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.EventPreview;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.Window.Location;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.CheckBox;
+import com.google.gwt.user.client.ui.ClickListener;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.Panel;
+import com.google.gwt.user.client.ui.Tree;
+import com.google.gwt.user.client.ui.TreeItem;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ui.VToolkitOverlay;
+
+public final class VDebugConsole extends VToolkitOverlay implements Console {
+
+ /**
+ * Builds number. For example 0-custom_tag in 5.0.0-custom_tag.
+ */
+ public static final String VERSION;
+
+ /* Initialize version numbers from string replaced by build-script. */
+ static {
+ if ("@VERSION@".equals("@" + "VERSION" + "@")) {
+ VERSION = "5.9.9-INTERNAL-NONVERSIONED-DEBUG-BUILD";
+ } else {
+ VERSION = "@VERSION@";
+ }
+ }
+
+ Element caption = DOM.createDiv();
+
+ private Panel panel;
+
+ private Button clear = new Button("Clear console");
+ private Button restart = new Button("Restart app");
+ private Button forceLayout = new Button("Force layout");
+ private Button analyzeLayout = new Button("Analyze layouts");
+ private HorizontalPanel actions;
+ private boolean collapsed = false;
+
+ private boolean resizing;
+ private int startX;
+ private int startY;
+ private int initialW;
+ private int initialH;
+
+ private boolean moving = false;
+
+ private int origTop;
+
+ private int origLeft;
+
+ private ApplicationConnection client;
+
+ private static final String help = "Drag=move, shift-drag=resize, doubleclick=min/max."
+ + "Use debug=quiet to log only to browser console.";
+
+ public VDebugConsole(ApplicationConnection client,
+ ApplicationConfiguration cnf, boolean showWindow) {
+ super(false, false);
+
+ this.client = client;
+
+ panel = new FlowPanel();
+ if (showWindow) {
+ DOM.appendChild(getContainerElement(), caption);
+ setWidget(panel);
+ caption.setClassName("i-debug-console-caption");
+ setStyleName("i-debug-console");
+ DOM.setStyleAttribute(getElement(), "zIndex", 20000 + "");
+ DOM.setStyleAttribute(getElement(), "overflow", "hidden");
+
+ sinkEvents(Event.ONDBLCLICK);
+
+ sinkEvents(Event.MOUSEEVENTS);
+
+ panel.setStyleName("i-debug-console-content");
+
+ caption.setInnerHTML("Debug window");
+ caption.setTitle(help);
+
+ show();
+ minimize();
+
+ actions = new HorizontalPanel();
+ actions.add(clear);
+ actions.add(restart);
+ actions.add(forceLayout);
+ actions.add(analyzeLayout);
+
+ panel.add(actions);
+
+ panel.add(new HTML("" + help + ""));
+
+ clear.addClickListener(new ClickListener() {
+ public void onClick(Widget sender) {
+ int width = panel.getOffsetWidth();
+ int height = panel.getOffsetHeight();
+ panel = new FlowPanel();
+ panel.setPixelSize(width, height);
+ panel.setStyleName("i-debug-console-content");
+ panel.add(actions);
+ setWidget(panel);
+ }
+ });
+
+ restart.addClickListener(new ClickListener() {
+ public void onClick(Widget sender) {
+
+ String queryString = Window.Location.getQueryString();
+ if (queryString != null
+ && queryString.contains("restartApplications")) {
+ Window.Location.reload();
+ } else {
+ String url = Location.getHref();
+ String separator = "?";
+ if (url.contains("?")) {
+ separator = "&";
+ }
+ if (!url.contains("restartApplication")) {
+ url += separator;
+ url += "restartApplication";
+ }
+ if (!"".equals(Location.getHash())) {
+ String hash = Location.getHash();
+ url = url.replace(hash, "") + hash;
+ }
+ Window.Location.replace(url);
+ }
+
+ }
+ });
+
+ forceLayout.addClickListener(new ClickListener() {
+ public void onClick(Widget sender) {
+ VDebugConsole.this.client.forceLayout();
+ }
+ });
+
+ analyzeLayout.addClickListener(new ClickListener() {
+ public void onClick(Widget sender) {
+ List runningApplications = ApplicationConfiguration
+ .getRunningApplications();
+ for (ApplicationConnection applicationConnection : runningApplications) {
+ applicationConnection.analyzeLayouts();
+ }
+ }
+ });
+ analyzeLayout
+ .setTitle("Analyzes currently rendered view and "
+ + "reports possible common problems in usage of relative sizes."
+ + "Will cause server visit/rendering of whole screen + lose of"
+ + " all non committed variables form client side.");
+
+ }
+
+ log("Toolkit application servlet version: " + cnf.getServletVersion());
+ log("Widget set is built on version: " + VERSION);
+ log("Application version: " + cnf.getApplicationVersion());
+
+ if (!cnf.getServletVersion().equals(VERSION)) {
+ error("Warning: your widget set seems to be built with a different "
+ + "version than the one used on server. Unexpected "
+ + "behavior may occur.");
+ }
+ }
+
+ private EventPreview dragpreview = new EventPreview() {
+
+ public boolean onEventPreview(Event event) {
+ onBrowserEvent(event);
+ return false;
+ }
+ };
+
+ @Override
+ public void onBrowserEvent(Event event) {
+ super.onBrowserEvent(event);
+ switch (DOM.eventGetType(event)) {
+ case Event.ONMOUSEDOWN:
+ if (DOM.eventGetShiftKey(event)) {
+ resizing = true;
+ DOM.setCapture(getElement());
+ startX = DOM.eventGetScreenX(event);
+ startY = DOM.eventGetScreenY(event);
+ initialW = VDebugConsole.this.getOffsetWidth();
+ initialH = VDebugConsole.this.getOffsetHeight();
+ DOM.eventCancelBubble(event, true);
+ DOM.eventPreventDefault(event);
+ DOM.addEventPreview(dragpreview);
+ } else if (DOM.eventGetTarget(event) == caption) {
+ moving = true;
+ startX = DOM.eventGetScreenX(event);
+ startY = DOM.eventGetScreenY(event);
+ origTop = getAbsoluteTop();
+ origLeft = getAbsoluteLeft();
+ DOM.eventCancelBubble(event, true);
+ DOM.eventPreventDefault(event);
+ DOM.addEventPreview(dragpreview);
+ }
+
+ break;
+ case Event.ONMOUSEMOVE:
+ if (resizing) {
+ int deltaX = startX - DOM.eventGetScreenX(event);
+ int detalY = startY - DOM.eventGetScreenY(event);
+ int w = initialW - deltaX;
+ if (w < 30) {
+ w = 30;
+ }
+ int h = initialH - detalY;
+ if (h < 40) {
+ h = 40;
+ }
+ VDebugConsole.this.setPixelSize(w, h);
+ DOM.eventCancelBubble(event, true);
+ DOM.eventPreventDefault(event);
+ } else if (moving) {
+ int deltaX = startX - DOM.eventGetScreenX(event);
+ int detalY = startY - DOM.eventGetScreenY(event);
+ int left = origLeft - deltaX;
+ if (left < 0) {
+ left = 0;
+ }
+ int top = origTop - detalY;
+ if (top < 0) {
+ top = 0;
+ }
+ VDebugConsole.this.setPopupPosition(left, top);
+ DOM.eventCancelBubble(event, true);
+ DOM.eventPreventDefault(event);
+ }
+ break;
+ case Event.ONLOSECAPTURE:
+ case Event.ONMOUSEUP:
+ if (resizing) {
+ DOM.releaseCapture(getElement());
+ resizing = false;
+ } else if (moving) {
+ DOM.releaseCapture(getElement());
+ moving = false;
+ }
+ DOM.removeEventPreview(dragpreview);
+ break;
+ case Event.ONDBLCLICK:
+ if (DOM.eventGetTarget(event) == caption) {
+ if (collapsed) {
+ panel.setVisible(true);
+ setPixelSize(220, 300);
+ } else {
+ panel.setVisible(false);
+ setPixelSize(120, 20);
+ }
+ collapsed = !collapsed;
+ }
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ private void minimize() {
+ setPixelSize(400, 150);
+ setPopupPosition(Window.getClientWidth() - 410, Window
+ .getClientHeight() - 160);
+ }
+
+ @Override
+ public void setPixelSize(int width, int height) {
+ panel.setHeight((height - 20) + "px");
+ panel.setWidth((width - 2) + "px");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.terminal.gwt.client.Console#log(java.lang.String)
+ */
+ public void log(String msg) {
+ panel.add(new HTML(msg));
+ System.out.println(msg);
+ consoleLog(msg);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.terminal.gwt.client.Console#error(java.lang.String)
+ */
+ public void error(String msg) {
+ panel.add((new HTML(msg)));
+ System.err.println(msg);
+ consoleErr(msg);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.terminal.gwt.client.Console#printObject(java.lang.
+ * Object)
+ */
+ public void printObject(Object msg) {
+ panel.add((new Label(msg.toString())));
+ consoleLog(msg.toString());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.terminal.gwt.client.Console#dirUIDL(com.vaadin
+ * .terminal.gwt.client.UIDL)
+ */
+ public void dirUIDL(UIDL u) {
+ panel.add(u.print_r());
+ consoleLog(u.getChildrenAsXML());
+ }
+
+ private static native void consoleLog(String msg)
+ /*-{
+ if($wnd.console && $wnd.console.log) {
+ $wnd.console.log(msg);
+ }
+ }-*/;
+
+ private static native void consoleErr(String msg)
+ /*-{
+ if($wnd.console) {
+ if ($wnd.console.error)
+ $wnd.console.error(msg);
+ else if ($wnd.console.log)
+ $wnd.console.log(msg);
+ }
+ }-*/;
+
+ public void printLayoutProblems(JSONArray array, ApplicationConnection ac,
+ Set zeroHeightComponents,
+ Set zeroWidthComponents) {
+ int size = array.size();
+ panel.add(new HTML("************************"
+ + "
Layouts analyzed on server, total top level problems: "
+ + size + "
"));
+ if (size > 0) {
+ Tree tree = new Tree();
+ TreeItem root = new TreeItem("Root problems");
+ for (int i = 0; i < size; i++) {
+ JSONObject error = array.get(i).isObject();
+ printLayoutError(error, root, ac);
+ }
+ panel.add(tree);
+ tree.addItem(root);
+
+ }
+ if (zeroHeightComponents.size() > 0 || zeroWidthComponents.size() > 0) {
+ panel.add(new HTML("
Client side notifications
"
+ + "
Following relative sized components where "
+ + "rendered to zero size container on client side."
+ + " Note that these are not necessary invalid "
+ + "states. Just reported here as they might be."));
+ if (zeroHeightComponents.size() > 0) {
+ panel.add(new HTML(
+ "
Vertically zero size:
"));
+ printClientSideDetectedIssues(zeroHeightComponents, ac);
+ }
+ if (zeroWidthComponents.size() > 0) {
+ panel.add(new HTML(
+ "
Horizontally zero size:
"));
+ printClientSideDetectedIssues(zeroWidthComponents, ac);
+ }
+ }
+ log("************************");
+ }
+
+ private void printClientSideDetectedIssues(
+ Set zeroHeightComponents, ApplicationConnection ac) {
+ for (final Paintable paintable : zeroHeightComponents) {
+ final Container layout = Util.getLayout((Widget) paintable);
+
+ VerticalPanel errorDetails = new VerticalPanel();
+ errorDetails.add(new Label("" + Util.getSimpleName(paintable)
+ + " inside " + Util.getSimpleName(layout)));
+ final CheckBox emphasisInUi = new CheckBox(
+ "Emphasis components parent in UI (actual component is not visible)");
+ emphasisInUi.addClickListener(new ClickListener() {
+ public void onClick(Widget sender) {
+ if (paintable != null) {
+ Element element2 = ((Widget) layout).getElement();
+ Widget.setStyleName(element2, "invalidlayout",
+ emphasisInUi.isChecked());
+ }
+ }
+ });
+ errorDetails.add(emphasisInUi);
+ panel.add(errorDetails);
+ }
+ }
+
+ private void printLayoutError(JSONObject error, TreeItem parent,
+ final ApplicationConnection ac) {
+ final String pid = error.get("id").isString().stringValue();
+ final Paintable paintable = ac.getPaintable(pid);
+
+ TreeItem errorNode = new TreeItem();
+ VerticalPanel errorDetails = new VerticalPanel();
+ errorDetails.add(new Label(Util.getSimpleName(paintable) + " id: "
+ + pid));
+ if (error.containsKey("heightMsg")) {
+ errorDetails.add(new Label("Height problem: "
+ + error.get("heightMsg")));
+ }
+ if (error.containsKey("widthMsg")) {
+ errorDetails.add(new Label("Width problem: "
+ + error.get("widthMsg")));
+ }
+ final CheckBox emphasisInUi = new CheckBox("Emphasis component in UI");
+ emphasisInUi.addClickListener(new ClickListener() {
+ public void onClick(Widget sender) {
+ if (paintable != null) {
+ Element element2 = ((Widget) paintable).getElement();
+ Widget.setStyleName(element2, "invalidlayout", emphasisInUi
+ .isChecked());
+ }
+ }
+ });
+ errorDetails.add(emphasisInUi);
+ errorNode.setWidget(errorDetails);
+ if (error.containsKey("subErrors")) {
+ HTML l = new HTML(
+ "Expand this node to show problems that may be dependent on this problem.");
+ errorDetails.add(l);
+ JSONArray array = error.get("subErrors").isArray();
+ for (int i = 0; i < array.size(); i++) {
+ JSONValue value = array.get(i);
+ if (value != null && value.isObject() != null) {
+ printLayoutError(value.isObject(), errorNode, ac);
+ } else {
+ System.out.print(value);
+ }
+ }
+
+ }
+ parent.addItem(errorNode);
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/VErrorMessage.java b/src/com/vaadin/terminal/gwt/client/VErrorMessage.java
new file mode 100644
index 0000000000..81817405a2
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/VErrorMessage.java
@@ -0,0 +1,73 @@
+/*
+@ITMillApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client;
+
+import java.util.Iterator;
+
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HTML;
+import com.vaadin.terminal.gwt.client.ui.VToolkitOverlay;
+
+public class VErrorMessage extends FlowPanel {
+ public static final String CLASSNAME = "i-errormessage";
+
+ public VErrorMessage() {
+ super();
+ setStyleName(CLASSNAME);
+ }
+
+ public void updateFromUIDL(UIDL uidl) {
+ clear();
+ if (uidl.getChildCount() == 0) {
+ add(new HTML(" "));
+ } else {
+ for (final Iterator it = uidl.getChildIterator(); it.hasNext();) {
+ final Object child = it.next();
+ if (child instanceof String) {
+ final String errorMessage = (String) child;
+ add(new HTML(errorMessage));
+ } else if (child instanceof UIDL.XML) {
+ final UIDL.XML xml = (UIDL.XML) child;
+ add(new HTML(xml.getXMLAsString()));
+ } else {
+ final VErrorMessage childError = new VErrorMessage();
+ add(childError);
+ childError.updateFromUIDL((UIDL) child);
+ }
+ }
+ }
+ }
+
+ /**
+ * Shows this error message next to given element.
+ *
+ * @param indicatorElement
+ */
+ public void showAt(Element indicatorElement) {
+ VToolkitOverlay errorContainer = (VToolkitOverlay) getParent();
+ if (errorContainer == null) {
+ errorContainer = new VToolkitOverlay();
+ errorContainer.setWidget(this);
+ }
+ errorContainer.setPopupPosition(DOM.getAbsoluteLeft(indicatorElement)
+ + 2
+ * DOM.getElementPropertyInt(indicatorElement, "offsetHeight"),
+ DOM.getAbsoluteTop(indicatorElement)
+ + 2
+ * DOM.getElementPropertyInt(indicatorElement,
+ "offsetHeight"));
+ errorContainer.show();
+
+ }
+
+ public void hide() {
+ final VToolkitOverlay errorContainer = (VToolkitOverlay) getParent();
+ if (errorContainer != null) {
+ errorContainer.hide();
+ }
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/VTooltip.java b/src/com/vaadin/terminal/gwt/client/VTooltip.java
new file mode 100644
index 0000000000..9e02dc4cc5
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/VTooltip.java
@@ -0,0 +1,225 @@
+/*
+@ITMillApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client;
+
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.vaadin.terminal.gwt.client.ui.VToolkitOverlay;
+
+/**
+ * TODO open for extension
+ */
+public class VTooltip extends VToolkitOverlay {
+ private static final String CLASSNAME = "i-tooltip";
+ private static final int MARGIN = 4;
+ public static final int TOOLTIP_EVENTS = Event.ONKEYDOWN
+ | Event.ONMOUSEOVER | Event.ONMOUSEOUT | Event.ONMOUSEMOVE
+ | Event.ONCLICK;
+ protected static final int MAX_WIDTH = 500;
+ private static final int QUICK_OPEN_TIMEOUT = 1000;
+ private static final int CLOSE_TIMEOUT = 300;
+ private static final int OPEN_DELAY = 750;
+ private static final int QUICK_OPEN_DELAY = 100;
+ VErrorMessage em = new VErrorMessage();
+ Element description = DOM.createDiv();
+ private Paintable tooltipOwner;
+ private boolean closing = false;
+ private boolean opening = false;
+ private ApplicationConnection ac;
+ // Open next tooltip faster. Disabled after 2 sec of showTooltip-silence.
+ private boolean justClosed = false;
+
+ public VTooltip(ApplicationConnection client) {
+ super(false, false, true);
+ ac = client;
+ setStyleName(CLASSNAME);
+ FlowPanel layout = new FlowPanel();
+ setWidget(layout);
+ layout.add(em);
+ DOM.setElementProperty(description, "className", CLASSNAME + "-text");
+ DOM.appendChild(layout.getElement(), description);
+ }
+
+ private void show(TooltipInfo info) {
+ boolean hasContent = false;
+ if (info.getErrorUidl() != null) {
+ em.setVisible(true);
+ em.updateFromUIDL(info.getErrorUidl());
+ hasContent = true;
+ } else {
+ em.setVisible(false);
+ }
+ if (info.getTitle() != null && !"".equals(info.getTitle())) {
+ DOM.setInnerHTML(description, info.getTitle());
+ DOM.setStyleAttribute(description, "display", "");
+ hasContent = true;
+ } else {
+ DOM.setInnerHTML(description, "");
+ DOM.setStyleAttribute(description, "display", "none");
+ }
+ if (hasContent) {
+ setPopupPositionAndShow(new PositionCallback() {
+ public void setPosition(int offsetWidth, int offsetHeight) {
+
+ if (offsetWidth > MAX_WIDTH) {
+ setWidth(MAX_WIDTH + "px");
+ }
+
+ offsetWidth = getOffsetWidth();
+
+ int x = tooltipEventMouseX + 10 + Window.getScrollLeft();
+ int y = tooltipEventMouseY + 10 + Window.getScrollTop();
+
+ if (x + offsetWidth + MARGIN - Window.getScrollLeft() > Window
+ .getClientWidth()) {
+ x = Window.getClientWidth() - offsetWidth - MARGIN;
+ }
+
+ if (y + offsetHeight + MARGIN - Window.getScrollTop() > Window
+ .getClientHeight()) {
+ y = tooltipEventMouseY - 5 - offsetHeight;
+ }
+
+ setPopupPosition(x, y);
+ sinkEvents(Event.ONMOUSEOVER | Event.ONMOUSEOUT);
+ }
+ });
+ } else {
+ hide();
+ }
+ }
+
+ public void showTooltip(Paintable owner, Event event) {
+ if (closing && tooltipOwner == owner) {
+ // return to same tooltip, cancel closing
+ closeTimer.cancel();
+ closing = false;
+ justClosedTimer.cancel();
+ justClosed = false;
+ return;
+ }
+
+ if (closing) {
+ closeNow();
+ }
+
+ updatePosition(event);
+
+ if (opening) {
+ showTimer.cancel();
+ }
+ tooltipOwner = owner;
+ if (justClosed) {
+ showTimer.schedule(QUICK_OPEN_DELAY);
+ } else {
+ showTimer.schedule(OPEN_DELAY);
+ }
+ opening = true;
+ }
+
+ private void closeNow() {
+ if (closing) {
+ hide();
+ tooltipOwner = null;
+ setWidth("");
+ closing = false;
+ }
+ }
+
+ private Timer showTimer = new Timer() {
+ @Override
+ public void run() {
+ TooltipInfo info = ac.getTitleInfo(tooltipOwner);
+ if (null != info) {
+ show(info);
+ }
+ opening = false;
+ }
+ };
+
+ private Timer closeTimer = new Timer() {
+ @Override
+ public void run() {
+ closeNow();
+ justClosedTimer.schedule(2000);
+ justClosed = true;
+ }
+ };
+
+ private Timer justClosedTimer = new Timer() {
+ @Override
+ public void run() {
+ justClosed = false;
+ }
+ };
+
+ public void hideTooltip() {
+ if (opening) {
+ showTimer.cancel();
+ opening = false;
+ tooltipOwner = null;
+ }
+ if (!isAttached()) {
+ return;
+ }
+ if (closing) {
+ // already about to close
+ return;
+ }
+ closeTimer.schedule(CLOSE_TIMEOUT);
+ closing = true;
+ justClosed = true;
+ justClosedTimer.schedule(QUICK_OPEN_TIMEOUT);
+
+ }
+
+ private int tooltipEventMouseX;
+ private int tooltipEventMouseY;
+
+ public void updatePosition(Event event) {
+ tooltipEventMouseX = DOM.eventGetClientX(event);
+ tooltipEventMouseY = DOM.eventGetClientY(event);
+
+ }
+
+ public void handleTooltipEvent(Event event, Paintable owner) {
+ final int type = DOM.eventGetType(event);
+ if ((VTooltip.TOOLTIP_EVENTS & type) == type) {
+ if (type == Event.ONMOUSEOVER) {
+ showTooltip(owner, event);
+ } else if (type == Event.ONMOUSEMOVE) {
+ updatePosition(event);
+ } else {
+ hideTooltip();
+ }
+ } else {
+ // non-tooltip event, hide tooltip
+ hideTooltip();
+ }
+ }
+
+ @Override
+ public void onBrowserEvent(Event event) {
+ final int type = DOM.eventGetType(event);
+ // cancel closing event if tooltip is mouseovered; the user might want
+ // to scroll of cut&paste
+
+ switch (type) {
+ case Event.ONMOUSEOVER:
+ closeTimer.cancel();
+ closing = false;
+ break;
+ case Event.ONMOUSEOUT:
+ hideTooltip();
+ break;
+ default:
+ // NOP
+ }
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/IAbsoluteLayout.java b/src/com/vaadin/terminal/gwt/client/ui/IAbsoluteLayout.java
deleted file mode 100644
index 06134e9515..0000000000
--- a/src/com/vaadin/terminal/gwt/client/ui/IAbsoluteLayout.java
+++ /dev/null
@@ -1,378 +0,0 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-import com.google.gwt.dom.client.DivElement;
-import com.google.gwt.dom.client.Document;
-import com.google.gwt.dom.client.Style;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.ui.ComplexPanel;
-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.BrowserInfo;
-import com.vaadin.terminal.gwt.client.Container;
-import com.vaadin.terminal.gwt.client.ICaption;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.RenderSpace;
-import com.vaadin.terminal.gwt.client.UIDL;
-
-public class IAbsoluteLayout extends ComplexPanel implements Container {
-
- /** Tag name for widget creation */
- public static final String TAGNAME = "absolutelayout";
-
- /** Class name, prefix in styling */
- public static final String CLASSNAME = "i-absolutelayout";
-
- private DivElement marginElement;
-
- protected final Element canvas = DOM.createDiv();
-
- private int excessPixelsHorizontal;
-
- private int excessPixelsVertical;
-
- private Object previousStyleName;
-
- private Map pidToComponentWrappper = new HashMap();
-
- protected ApplicationConnection client;
-
- private boolean rendering;
-
- public IAbsoluteLayout() {
- setElement(Document.get().createDivElement());
- setStyleName(CLASSNAME);
- marginElement = Document.get().createDivElement();
- canvas.getStyle().setProperty("position", "relative");
- marginElement.appendChild(canvas);
- getElement().appendChild(marginElement);
- }
-
- public RenderSpace getAllocatedSpace(Widget child) {
- // TODO needs some special handling for components with only on edge
- // horizontally or vertically defined
- AbsoluteWrapper wrapper = (AbsoluteWrapper) child.getParent();
- int w;
- if (wrapper.left != null && wrapper.right != null) {
- w = wrapper.getOffsetWidth();
- } else if (wrapper.right != null) {
- // left == null
- // available width == right edge == offsetleft + width
- w = wrapper.getOffsetWidth() + wrapper.getElement().getOffsetLeft();
- } else {
- // left != null && right == null || left == null &&
- // right == null
- // available width == canvas width - offset left
- w = canvas.getOffsetWidth() - wrapper.getElement().getOffsetLeft();
- }
- int h;
- if (wrapper.top != null && wrapper.bottom != null) {
- h = wrapper.getOffsetHeight();
- } else if (wrapper.bottom != null) {
- // top not defined, available space 0... bottom of wrapper
- h = wrapper.getElement().getOffsetTop() + wrapper.getOffsetHeight();
- } else {
- // top defined or both undefined, available space == canvas - top
- h = canvas.getOffsetHeight() - wrapper.getElement().getOffsetTop();
- }
-
- return new RenderSpace(w, h);
- }
-
- public boolean hasChildComponent(Widget component) {
- for (Iterator> iterator = pidToComponentWrappper
- .entrySet().iterator(); iterator.hasNext();) {
- if (iterator.next().getValue().paintable == component) {
- return true;
- }
- }
- return false;
- }
-
- public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
- for (Widget wrapper : getChildren()) {
- AbsoluteWrapper w = (AbsoluteWrapper) wrapper;
- if (w.getWidget() == oldComponent) {
- w.setWidget(newComponent);
- return;
- }
- }
- }
-
- public boolean requestLayout(Set children) {
- // component inside an absolute panel never affects parent nor the
- // layout
- return true;
- }
-
- public void updateCaption(Paintable component, UIDL uidl) {
- AbsoluteWrapper parent2 = (AbsoluteWrapper) ((Widget) component)
- .getParent();
- parent2.updateCaption(uidl);
- }
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- rendering = true;
- this.client = client;
- // TODO margin handling
- if (client.updateComponent(this, uidl, true)) {
- rendering = false;
- return;
- }
-
- HashSet unrenderedPids = new HashSet(
- pidToComponentWrappper.keySet());
-
- for (Iterator childIterator = uidl.getChildIterator(); childIterator
- .hasNext();) {
- UIDL cc = childIterator.next();
- UIDL componentUIDL = cc.getChildUIDL(0);
- unrenderedPids.remove(componentUIDL.getId());
- getWrapper(client, componentUIDL).updateFromUIDL(cc);
- }
-
- for (String pid : unrenderedPids) {
- AbsoluteWrapper absoluteWrapper = pidToComponentWrappper.get(pid);
- pidToComponentWrappper.remove(pid);
- absoluteWrapper.destroy();
- }
- rendering = false;
- }
-
- private AbsoluteWrapper getWrapper(ApplicationConnection client,
- UIDL componentUIDL) {
- AbsoluteWrapper wrapper = pidToComponentWrappper.get(componentUIDL
- .getId());
- if (wrapper == null) {
- wrapper = new AbsoluteWrapper(client.getPaintable(componentUIDL));
- pidToComponentWrappper.put(componentUIDL.getId(), wrapper);
- add(wrapper);
- }
- return wrapper;
-
- }
-
- @Override
- public void add(Widget child) {
- super.add(child, canvas);
- }
-
- @Override
- public void setStyleName(String style) {
- super.setStyleName(style);
- if (previousStyleName == null || !previousStyleName.equals(style)) {
- excessPixelsHorizontal = -1;
- excessPixelsVertical = -1;
- }
- }
-
- @Override
- public void setWidth(String width) {
- super.setWidth(width);
- // TODO do this so that canvas gets the sized properly (the area
- // inside marginals)
- canvas.getStyle().setProperty("width", width);
-
- if (!rendering) {
- if (BrowserInfo.get().isIE6()) {
- relayoutWrappersForIe6();
- }
- relayoutRelativeChildren();
- }
- }
-
- private void relayoutRelativeChildren() {
- for (Widget widget : getChildren()) {
- if (widget instanceof AbsoluteWrapper) {
- AbsoluteWrapper w = (AbsoluteWrapper) widget;
- client.handleComponentRelativeSize(w.getWidget());
- w.updateCaptionPosition();
- }
- }
- }
-
- @Override
- public void setHeight(String height) {
- super.setHeight(height);
- // TODO do this so that canvas gets the sized properly (the area
- // inside marginals)
- canvas.getStyle().setProperty("height", height);
-
- if (!rendering) {
- if (BrowserInfo.get().isIE6()) {
- relayoutWrappersForIe6();
- }
- relayoutRelativeChildren();
- }
- }
-
- private void relayoutWrappersForIe6() {
- for (Widget wrapper : getChildren()) {
- if (wrapper instanceof AbsoluteWrapper) {
- ((AbsoluteWrapper) wrapper).ie6Layout();
- }
- }
- }
-
- public class AbsoluteWrapper extends SimplePanel {
- private String css;
- private String left;
- private String top;
- private String right;
- private String bottom;
- private String zIndex;
-
- private Paintable paintable;
- private ICaption caption;
-
- public AbsoluteWrapper(Paintable paintable) {
- this.paintable = paintable;
- setStyleName(CLASSNAME + "-wrapper");
- }
-
- public void updateCaption(UIDL uidl) {
-
- boolean captionIsNeeded = ICaption.isNeeded(uidl);
- if (captionIsNeeded) {
- if (caption == null) {
- caption = new ICaption(paintable, client);
- IAbsoluteLayout.this.add(caption);
- }
- caption.updateCaption(uidl);
- updateCaptionPosition();
- } else {
- if (caption != null) {
- caption.removeFromParent();
- caption = null;
- }
- }
- }
-
- public void destroy() {
- if (caption != null) {
- caption.removeFromParent();
- }
- client.unregisterPaintable(paintable);
- removeFromParent();
- }
-
- public void updateFromUIDL(UIDL componentUIDL) {
- setPosition(componentUIDL.getStringAttribute("css"));
- if (getWidget() != paintable) {
- setWidget((Widget) paintable);
- }
- UIDL childUIDL = componentUIDL.getChildUIDL(0);
- paintable.updateFromUIDL(childUIDL, client);
- if (childUIDL.hasAttribute("cached")) {
- // child may need relative size adjustment if wrapper details
- // have changed this could be optimized (check if wrapper size
- // has changed)
- client.handleComponentRelativeSize((Widget) paintable);
- }
- }
-
- public void setPosition(String stringAttribute) {
- if (css == null || !css.equals(stringAttribute)) {
- css = stringAttribute;
- top = right = bottom = left = zIndex = null;
- if (!css.equals("")) {
- String[] properties = css.split(";");
- for (int i = 0; i < properties.length; i++) {
- String[] keyValue = properties[i].split(":");
- if (keyValue[0].equals("left")) {
- left = keyValue[1];
- } else if (keyValue[0].equals("top")) {
- top = keyValue[1];
- } else if (keyValue[0].equals("right")) {
- right = keyValue[1];
- } else if (keyValue[0].equals("bottom")) {
- bottom = keyValue[1];
- } else if (keyValue[0].equals("z-index")) {
- zIndex = keyValue[1];
- }
- }
- }
- // ensure ne values
- Style style = getElement().getStyle();
- style.setProperty("zIndex", zIndex);
- style.setProperty("top", top);
- style.setProperty("left", left);
- style.setProperty("right", right);
- style.setProperty("bottom", bottom);
-
- if (BrowserInfo.get().isIE6()) {
- ie6Layout();
- }
- }
- updateCaptionPosition();
- }
-
- private void updateCaptionPosition() {
- if (caption != null) {
- Style style = caption.getElement().getStyle();
- style.setProperty("position", "absolute");
- style.setPropertyPx("left", getElement().getOffsetLeft());
- style.setPropertyPx("top", getElement().getOffsetTop()
- - caption.getHeight());
- }
- }
-
- private void ie6Layout() {
- // special handling for IE6 is needed, it does not support
- // setting both left/right or top/bottom
- Style style = getElement().getStyle();
- if (bottom != null && top != null) {
- // define height for wrapper to simulate bottom property
- int bottompixels = measureForIE6(bottom);
- ApplicationConnection.getConsole().log("ALB" + bottompixels);
- int height = canvas.getOffsetHeight() - bottompixels
- - getElement().getOffsetTop();
- ApplicationConnection.getConsole().log("ALB" + height);
- if (height < 0) {
- height = 0;
- }
- style.setPropertyPx("height", height);
- } else {
- // reset possibly existing value
- style.setProperty("height", "");
- }
- if (left != null && right != null) {
- // define width for wrapper to simulate right property
- int rightPixels = measureForIE6(right);
- ApplicationConnection.getConsole().log("ALR" + rightPixels);
- int width = canvas.getOffsetWidth() - rightPixels
- - getElement().getOffsetWidth();
- ApplicationConnection.getConsole().log("ALR" + width);
- if (width < 0) {
- width = 0;
- }
- style.setPropertyPx("width", width);
- } else {
- // reset possibly existing value
- style.setProperty("width", "");
- }
- }
-
- }
-
- private Element measureElement;
-
- private int measureForIE6(String cssLength) {
- if (measureElement == null) {
- measureElement = DOM.createDiv();
- measureElement.getStyle().setProperty("position", "absolute");
- canvas.appendChild(measureElement);
- }
- measureElement.getStyle().setProperty("width", cssLength);
- return measureElement.getOffsetWidth();
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/IAccordion.java b/src/com/vaadin/terminal/gwt/client/ui/IAccordion.java
deleted file mode 100644
index 43c92cab32..0000000000
--- a/src/com/vaadin/terminal/gwt/client/ui/IAccordion.java
+++ /dev/null
@@ -1,647 +0,0 @@
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.ui.ClickListener;
-import com.google.gwt.user.client.ui.ComplexPanel;
-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.ContainerResizedListener;
-import com.vaadin.terminal.gwt.client.ICaption;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.RenderInformation;
-import com.vaadin.terminal.gwt.client.RenderSpace;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-
-public class IAccordion extends ITabsheetBase implements
- ContainerResizedListener {
-
- public static final String CLASSNAME = "i-accordion";
-
- private Set paintables = new HashSet();
-
- private String height;
-
- private String width = "";
-
- private HashMap lazyUpdateMap = new HashMap();
-
- private RenderSpace renderSpace = new RenderSpace(0, 0, true);
-
- private StackItem openTab = null;
-
- private boolean rendering = false;
-
- private int selectedUIDLItemIndex = -1;
-
- private RenderInformation renderInformation = new RenderInformation();
-
- public IAccordion() {
- super(CLASSNAME);
- // IE6 needs this to calculate offsetHeight correctly
- if (BrowserInfo.get().isIE6()) {
- DOM.setStyleAttribute(getElement(), "zoom", "1");
- }
- }
-
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- rendering = true;
- selectedUIDLItemIndex = -1;
- super.updateFromUIDL(uidl, client);
- /*
- * Render content after all tabs have been created and we know how large
- * the content area is
- */
- if (selectedUIDLItemIndex >= 0) {
- StackItem selectedItem = getStackItem(selectedUIDLItemIndex);
- UIDL selectedTabUIDL = lazyUpdateMap.remove(selectedItem);
- open(selectedUIDLItemIndex);
-
- selectedItem.setContent(selectedTabUIDL);
- } else if (!uidl.getBooleanAttribute("cached") && openTab != null) {
- close(openTab);
- }
-
- iLayout();
- // finally render possible hidden tabs
- if (lazyUpdateMap.size() > 0) {
- for (Iterator iterator = lazyUpdateMap.keySet().iterator(); iterator
- .hasNext();) {
- StackItem item = (StackItem) iterator.next();
- item.setContent(lazyUpdateMap.get(item));
- }
- lazyUpdateMap.clear();
- }
-
- renderInformation.updateSize(getElement());
-
- rendering = false;
- }
-
- @Override
- protected void renderTab(UIDL tabUidl, int index, boolean selected,
- boolean hidden) {
- StackItem item;
- int itemIndex;
- if (getWidgetCount() <= index) {
- // Create stackItem and render caption
- item = new StackItem(tabUidl);
- if (getWidgetCount() == 0) {
- item.addStyleDependentName("first");
- }
- itemIndex = getWidgetCount();
- add(item, getElement());
- } else {
- item = getStackItem(index);
- item = moveStackItemIfNeeded(item, index, tabUidl);
- itemIndex = index;
- }
- item.updateCaption(tabUidl);
-
- item.setVisible(!hidden);
-
- if (selected) {
- selectedUIDLItemIndex = itemIndex;
- }
-
- if (tabUidl.getChildCount() > 0) {
- lazyUpdateMap.put(item, tabUidl.getChildUIDL(0));
- }
- }
-
- /**
- * This method tries to find out if a tab has been rendered with a different
- * index previously. If this is the case it re-orders the children so the
- * same StackItem is used for rendering this time. E.g. if the first tab has
- * been removed all tabs which contain cached content must be moved 1 step
- * up to preserve the cached content.
- *
- * @param item
- * @param newIndex
- * @param tabUidl
- * @return
- */
- private StackItem moveStackItemIfNeeded(StackItem item, int newIndex,
- UIDL tabUidl) {
- UIDL tabContentUIDL = null;
- Paintable tabContent = null;
- if (tabUidl.getChildCount() > 0) {
- tabContentUIDL = tabUidl.getChildUIDL(0);
- tabContent = client.getPaintable(tabContentUIDL);
- }
-
- Widget itemWidget = item.getComponent();
- if (tabContent != null) {
- if (tabContent != itemWidget) {
- /*
- * This is not the same widget as before, find out if it has
- * been moved
- */
- int oldIndex = -1;
- StackItem oldItem = null;
- for (int i = 0; i < getWidgetCount(); i++) {
- Widget w = getWidget(i);
- oldItem = (StackItem) w;
- if (tabContent == oldItem.getComponent()) {
- oldIndex = i;
- break;
- }
- }
-
- if (oldIndex != -1 && oldIndex > newIndex) {
- /*
- * The tab has previously been rendered in another position
- * so we must move the cached content to correct position.
- * We move only items with oldIndex > newIndex to prevent
- * moving items already rendered in this update. If for
- * instance tabs 1,2,3 are removed and added as 3,2,1 we
- * cannot re-use "1" when we get to the third tab.
- */
- insert(oldItem, getElement(), newIndex, true);
- return oldItem;
- }
- }
- } else {
- // Tab which has never been loaded. Must assure we use an empty
- // StackItem
- Widget oldWidget = item.getComponent();
- if (oldWidget != null) {
- item = new StackItem(tabUidl);
- insert(item, getElement(), newIndex, true);
- }
- }
- return item;
- }
-
- private void open(int itemIndex) {
- StackItem item = (StackItem) getWidget(itemIndex);
- boolean alreadyOpen = false;
- if (openTab != null) {
- if (openTab.isOpen()) {
- if (openTab == item) {
- alreadyOpen = true;
- } else {
- openTab.close();
- }
- }
- }
-
- if (!alreadyOpen) {
- item.open();
- activeTabIndex = itemIndex;
- openTab = item;
- }
-
- // Update the size for the open tab
- updateOpenTabSize();
- }
-
- private void close(StackItem item) {
- if (!item.isOpen()) {
- return;
- }
-
- item.close();
- activeTabIndex = -1;
- openTab = null;
-
- }
-
- @Override
- protected void selectTab(final int index, final UIDL contentUidl) {
- StackItem item = getStackItem(index);
- if (index != activeTabIndex) {
- open(index);
- iLayout();
- // TODO Check if this is needed
- client.runDescendentsLayout(this);
-
- }
- item.setContent(contentUidl);
- }
-
- public void onSelectTab(StackItem item) {
- final int index = getWidgetIndex(item);
- if (index != activeTabIndex && !disabled && !readonly
- && !disabledTabKeys.contains(tabKeys.get(index))) {
- addStyleDependentName("loading");
- client
- .updateVariable(id, "selected", "" + tabKeys.get(index),
- true);
- }
- }
-
- @Override
- public void setWidth(String width) {
- if (this.width.equals(width)) {
- return;
- }
-
- super.setWidth(width);
- this.width = width;
- if (!rendering) {
- updateOpenTabSize();
-
- if (isDynamicHeight()) {
- Util.updateRelativeChildrenAndSendSizeUpdateEvent(client,
- openTab, this);
- updateOpenTabSize();
- }
-
- if (isDynamicHeight()) {
- openTab.setHeightFromWidget();
- }
- iLayout();
- }
- }
-
- @Override
- public void setHeight(String height) {
- super.setHeight(height);
- this.height = height;
-
- if (!rendering) {
- updateOpenTabSize();
- }
-
- }
-
- /**
- * Sets the size of the open tab
- */
- private void updateOpenTabSize() {
- if (openTab == null) {
- renderSpace.setHeight(0);
- renderSpace.setWidth(0);
- return;
- }
-
- // WIDTH
- if (!isDynamicWidth()) {
- int w = getOffsetWidth();
- openTab.setWidth(w);
- renderSpace.setWidth(w);
- } else {
- renderSpace.setWidth(0);
- }
-
- // HEIGHT
- if (!isDynamicHeight()) {
- int usedPixels = 0;
- for (Widget w : getChildren()) {
- StackItem item = (StackItem) w;
- if (item == openTab) {
- usedPixels += item.getCaptionHeight();
- } else {
- // This includes the captionNode borders
- usedPixels += item.getHeight();
- }
- }
-
- int offsetHeight = getOffsetHeight();
-
- int spaceForOpenItem = offsetHeight - usedPixels;
-
- if (spaceForOpenItem < 0) {
- spaceForOpenItem = 0;
- }
-
- renderSpace.setHeight(spaceForOpenItem);
- openTab.setHeight(spaceForOpenItem);
- } else {
- renderSpace.setHeight(0);
- openTab.setHeightFromWidget();
-
- }
-
- }
-
- public void iLayout() {
- if (openTab == null) {
- return;
- }
-
- if (isDynamicWidth()) {
- int maxWidth = 40;
- for (Widget w : getChildren()) {
- StackItem si = (StackItem) w;
- int captionWidth = si.getCaptionWidth();
- if (captionWidth > maxWidth) {
- maxWidth = captionWidth;
- }
- }
- int widgetWidth = openTab.getWidgetWidth();
- if (widgetWidth > maxWidth) {
- maxWidth = widgetWidth;
- }
- super.setWidth(maxWidth + "px");
- openTab.setWidth(maxWidth);
- }
-
- Util.runWebkitOverflowAutoFix(openTab.getContainerElement());
-
- }
-
- /**
- *
- */
- protected class StackItem extends ComplexPanel implements ClickListener {
-
- public void setHeight(int height) {
- if (height == -1) {
- super.setHeight("");
- DOM.setStyleAttribute(content, "height", "0px");
- } else {
- super.setHeight((height + getCaptionHeight()) + "px");
- DOM.setStyleAttribute(content, "height", height + "px");
- DOM
- .setStyleAttribute(content, "top", getCaptionHeight()
- + "px");
-
- }
- }
-
- public Widget getComponent() {
- if (getWidgetCount() < 2) {
- return null;
- }
- return getWidget(1);
- }
-
- @Override
- public void setVisible(boolean visible) {
- super.setVisible(visible);
- }
-
- public void setHeightFromWidget() {
- Widget paintable = getPaintable();
- if (paintable == null) {
- return;
- }
-
- int paintableHeight = (paintable).getElement().getOffsetHeight();
- setHeight(paintableHeight);
-
- }
-
- /**
- * Returns caption width including padding
- *
- * @return
- */
- public int getCaptionWidth() {
- if (caption == null) {
- return 0;
- }
-
- int captionWidth = caption.getRequiredWidth();
- int padding = Util.measureHorizontalPaddingAndBorder(caption
- .getElement(), 18);
- return captionWidth + padding;
- }
-
- public void setWidth(int width) {
- if (width == -1) {
- super.setWidth("");
- } else {
- super.setWidth(width + "px");
- }
- }
-
- public int getHeight() {
- return getOffsetHeight();
- }
-
- public int getCaptionHeight() {
- return captionNode.getOffsetHeight();
- }
-
- private ICaption caption;
- private boolean open = false;
- private Element content = DOM.createDiv();
- private Element captionNode = DOM.createDiv();
-
- public StackItem(UIDL tabUidl) {
- setElement(DOM.createDiv());
- caption = new ICaption(null, client);
- caption.addClickListener(this);
- if (BrowserInfo.get().isIE6()) {
- DOM.setEventListener(captionNode, this);
- DOM.sinkEvents(captionNode, Event.BUTTON_LEFT);
- }
- super.add(caption, captionNode);
- DOM.appendChild(captionNode, caption.getElement());
- DOM.appendChild(getElement(), captionNode);
- DOM.appendChild(getElement(), content);
- setStylePrimaryName(CLASSNAME + "-item");
- DOM.setElementProperty(content, "className", CLASSNAME
- + "-item-content");
- DOM.setElementProperty(captionNode, "className", CLASSNAME
- + "-item-caption");
- close();
- }
-
- @Override
- public void onBrowserEvent(Event event) {
- onSelectTab(this);
- }
-
- public Element getContainerElement() {
- return content;
- }
-
- public Widget getPaintable() {
- if (getWidgetCount() > 1) {
- return getWidget(1);
- } else {
- return null;
- }
- }
-
- public void replacePaintable(Paintable newPntbl) {
- if (getWidgetCount() > 1) {
- client.unregisterPaintable((Paintable) getWidget(1));
- paintables.remove(getWidget(1));
- remove(1);
- }
- add((Widget) newPntbl, content);
- paintables.add(newPntbl);
- }
-
- public void open() {
- open = true;
- DOM.setStyleAttribute(content, "top", getCaptionHeight() + "px");
- DOM.setStyleAttribute(content, "left", "0px");
- DOM.setStyleAttribute(content, "visibility", "");
- addStyleDependentName("open");
- }
-
- public void hide() {
- DOM.setStyleAttribute(content, "visibility", "hidden");
- }
-
- public void close() {
- DOM.setStyleAttribute(content, "visibility", "hidden");
- DOM.setStyleAttribute(content, "top", "-100000px");
- DOM.setStyleAttribute(content, "left", "-100000px");
- removeStyleDependentName("open");
- setHeight(-1);
- open = false;
- }
-
- public boolean isOpen() {
- return open;
- }
-
- public void setContent(UIDL contentUidl) {
- final Paintable newPntbl = client.getPaintable(contentUidl);
- if (getPaintable() == null) {
- add((Widget) newPntbl, content);
- paintables.add(newPntbl);
- } else if (getPaintable() != newPntbl) {
- replacePaintable(newPntbl);
- }
- newPntbl.updateFromUIDL(contentUidl, client);
- if (contentUidl.getBooleanAttribute("cached")) {
- /*
- * The size of a cached, relative sized component must be
- * updated to report correct size.
- */
- client.handleComponentRelativeSize((Widget) newPntbl);
- }
- if (isOpen() && isDynamicHeight()) {
- setHeightFromWidget();
- }
- }
-
- public void onClick(Widget sender) {
- onSelectTab(this);
- }
-
- public void updateCaption(UIDL uidl) {
- caption.updateCaption(uidl);
- }
-
- public int getWidgetWidth() {
- return DOM.getFirstChild(content).getOffsetWidth();
- }
-
- public boolean contains(Paintable p) {
- return (getPaintable() == p);
- }
-
- public boolean isCaptionVisible() {
- return caption.isVisible();
- }
-
- }
-
- @Override
- protected void clearPaintables() {
- clear();
- }
-
- public boolean isDynamicHeight() {
- return height == null || height.equals("");
- }
-
- public boolean isDynamicWidth() {
- return width == null || width.equals("");
- }
-
- @Override
- protected Iterator getPaintableIterator() {
- return paintables.iterator();
- }
-
- public boolean hasChildComponent(Widget component) {
- if (paintables.contains(component)) {
- return true;
- } else {
- return false;
- }
- }
-
- public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
- for (Widget w : getChildren()) {
- StackItem item = (StackItem) w;
- if (item.getPaintable() == oldComponent) {
- item.replacePaintable((Paintable) newComponent);
- return;
- }
- }
- }
-
- public void updateCaption(Paintable component, UIDL uidl) {
- /* Accordion does not render its children's captions */
- }
-
- public boolean requestLayout(Set child) {
- if (!isDynamicHeight() && !isDynamicWidth()) {
- /*
- * If the height and width has been specified for this container the
- * child components cannot make the size of the layout change
- */
-
- return true;
- }
-
- updateOpenTabSize();
-
- if (renderInformation.updateSize(getElement())) {
- /*
- * Size has changed so we let the child components know about the
- * new size.
- */
- iLayout();
- // TODO Check if this is needed
- client.runDescendentsLayout(this);
-
- return false;
- } else {
- /*
- * Size has not changed so we do not need to propagate the event
- * further
- */
- return true;
- }
-
- }
-
- public RenderSpace getAllocatedSpace(Widget child) {
- return renderSpace;
- }
-
- @Override
- protected int getTabCount() {
- return getWidgetCount();
- }
-
- @Override
- protected void removeTab(int index) {
- StackItem item = getStackItem(index);
- remove(item);
- }
-
- @Override
- protected Paintable getTab(int index) {
- if (index < getWidgetCount()) {
- return (Paintable) (getStackItem(index)).getPaintable();
- }
-
- return null;
- }
-
- private StackItem getStackItem(int index) {
- return (StackItem) getWidget(index);
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/IButton.java b/src/com/vaadin/terminal/gwt/client/ui/IButton.java
deleted file mode 100644
index 4a1dcbad07..0000000000
--- a/src/com/vaadin/terminal/gwt/client/ui/IButton.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
-@ITMillApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.ClickListener;
-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.ITooltip;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-
-public class IButton extends Button implements Paintable {
-
- private String width = null;
-
- public static final String CLASSNAME = "i-button";
-
- // Used only for IE, because it doesn't support :active CSS selector
- private static final String CLASSNAME_DOWN = "i-pressed";
-
- String id;
-
- ApplicationConnection client;
-
- private Element errorIndicatorElement;
-
- private final Element captionElement = DOM.createSpan();
-
- private Icon icon;
-
- /**
- * Helper flat to handle special-case where the button is moved from under
- * mouse while clicking it. In this case mouse leaves the button without
- * moving.
- */
- private boolean clickPending;
-
- public IButton() {
- setStyleName(CLASSNAME);
-
- DOM.appendChild(getElement(), captionElement);
-
- addClickListener(new ClickListener() {
- public void onClick(Widget sender) {
- if (id == null || client == null) {
- return;
- }
- /*
- * TODO isolate workaround. Safari don't always seem to fire
- * onblur previously focused component before button is clicked.
- */
- IButton.this.setFocus(true);
- client.updateVariable(id, "state", true, true);
- clickPending = false;
- }
- });
- sinkEvents(ITooltip.TOOLTIP_EVENTS);
- sinkEvents(Event.ONMOUSEDOWN);
- sinkEvents(Event.ONMOUSEUP);
- }
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-
- // Ensure correct implementation,
- // but don't let container manage caption etc.
- if (client.updateComponent(this, uidl, false)) {
- return;
- }
-
- // Save details
- this.client = client;
- id = uidl.getId();
-
- // Set text
- setText(uidl.getStringAttribute("caption"));
-
- // handle error
- if (uidl.hasAttribute("error")) {
- if (errorIndicatorElement == null) {
- errorIndicatorElement = DOM.createDiv();
- DOM.setElementProperty(errorIndicatorElement, "className",
- "i-errorindicator");
- }
- DOM.insertChild(getElement(), errorIndicatorElement, 0);
-
- // Fix for IE6, IE7
- if (BrowserInfo.get().isIE()) {
- DOM.setInnerText(errorIndicatorElement, " ");
- }
-
- } else if (errorIndicatorElement != null) {
- DOM.removeChild(getElement(), errorIndicatorElement);
- errorIndicatorElement = null;
- }
-
- if (uidl.hasAttribute("readonly")) {
- setEnabled(false);
- }
-
- if (uidl.hasAttribute("icon")) {
- if (icon == null) {
- icon = new Icon(client);
- DOM.insertChild(getElement(), icon.getElement(), 0);
- }
- icon.setUri(uidl.getStringAttribute("icon"));
- } else {
- if (icon != null) {
- DOM.removeChild(getElement(), icon.getElement());
- icon = null;
- }
- }
- if (BrowserInfo.get().isIE7()) {
- if (width.equals("")) {
- setWidth(getOffsetWidth() + "px");
- }
- }
- }
-
- @Override
- public void setText(String text) {
- DOM.setInnerText(captionElement, text);
- }
-
- @Override
- public void onBrowserEvent(Event event) {
- super.onBrowserEvent(event);
-
- if (DOM.eventGetType(event) == Event.ONLOAD) {
- Util.notifyParentOfSizeChange(this, true);
-
- } else if (DOM.eventGetType(event) == Event.ONMOUSEDOWN
- && event.getButton() == Event.BUTTON_LEFT) {
- clickPending = true;
- if (BrowserInfo.get().isIE()) {
- // Only for IE, because it doesn't support :active CSS selector
- // Simple check is cheaper than DOM manipulation
- addStyleName(CLASSNAME_DOWN);
- }
- } else if (DOM.eventGetType(event) == Event.ONMOUSEMOVE) {
- clickPending = false;
- } else if (DOM.eventGetType(event) == Event.ONMOUSEOUT) {
- if (clickPending) {
- click();
- }
- if (BrowserInfo.get().isIE()) {
- removeStyleName(CLASSNAME_DOWN);
- }
- clickPending = false;
- } else if (DOM.eventGetType(event) == Event.ONMOUSEUP) {
- if (BrowserInfo.get().isIE()) {
- removeStyleName(CLASSNAME_DOWN);
- }
- }
-
- if (client != null) {
- client.handleTooltipEvent(event, this);
- }
- }
-
- @Override
- public void setWidth(String width) {
- /* Workaround for IE7 button size part 1 (#2014) */
- if (BrowserInfo.get().isIE7() && this.width != null) {
- if (this.width.equals(width)) {
- return;
- }
-
- if (width == null) {
- width = "";
- }
- }
-
- this.width = width;
- super.setWidth(width);
-
- /* Workaround for IE7 button size part 2 (#2014) */
- if (BrowserInfo.get().isIE7()) {
- super.setWidth(width);
- }
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/ICalendarPanel.java b/src/com/vaadin/terminal/gwt/client/ui/ICalendarPanel.java
deleted file mode 100644
index 31566a75b9..0000000000
--- a/src/com/vaadin/terminal/gwt/client/ui/ICalendarPanel.java
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
-@ITMillApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.Timer;
-import com.google.gwt.user.client.ui.FlexTable;
-import com.google.gwt.user.client.ui.MouseListener;
-import com.google.gwt.user.client.ui.MouseListenerCollection;
-import com.google.gwt.user.client.ui.SourcesMouseEvents;
-import com.google.gwt.user.client.ui.SourcesTableEvents;
-import com.google.gwt.user.client.ui.TableListener;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.DateTimeService;
-import com.vaadin.terminal.gwt.client.LocaleService;
-
-public class ICalendarPanel extends FlexTable implements MouseListener {
-
- private final IDateField datefield;
-
- private IEventButton prevYear;
-
- private IEventButton nextYear;
-
- private IEventButton prevMonth;
-
- private IEventButton nextMonth;
-
- private ITime time;
-
- private Date minDate = null;
-
- private Date maxDate = null;
-
- private CalendarEntrySource entrySource;
-
- /* Needed to identify resolution changes */
- private int resolution = IDateField.RESOLUTION_YEAR;
-
- /* Needed to identify locale changes */
- private String locale = LocaleService.getDefaultLocale();
-
- public ICalendarPanel(IDateField parent) {
- datefield = parent;
- setStyleName(IDateField.CLASSNAME + "-calendarpanel");
- // buildCalendar(true);
- addTableListener(new DateClickListener(this));
- }
-
- public ICalendarPanel(IDateField parent, Date min, Date max) {
- datefield = parent;
- setStyleName(IDateField.CLASSNAME + "-calendarpanel");
- // buildCalendar(true);
- addTableListener(new DateClickListener(this));
-
- }
-
- private void buildCalendar(boolean forceRedraw) {
- final boolean needsMonth = datefield.getCurrentResolution() > IDateField.RESOLUTION_YEAR;
- boolean needsBody = datefield.getCurrentResolution() >= IDateField.RESOLUTION_DAY;
- final boolean needsTime = datefield.getCurrentResolution() >= IDateField.RESOLUTION_HOUR;
- forceRedraw = prevYear == null ? true : forceRedraw;
- buildCalendarHeader(forceRedraw, needsMonth);
- clearCalendarBody(!needsBody);
- if (needsBody) {
- buildCalendarBody();
- }
- if (needsTime) {
- buildTime(forceRedraw);
- } else if (time != null) {
- remove(time);
- time = null;
- }
- }
-
- private void clearCalendarBody(boolean remove) {
- if (!remove) {
- for (int row = 2; row < 8; row++) {
- for (int col = 0; col < 7; col++) {
- setHTML(row, col, " ");
- }
- }
- } else if (getRowCount() > 2) {
- while (getRowCount() > 2) {
- removeRow(2);
- }
- }
- }
-
- private void buildCalendarHeader(boolean forceRedraw, boolean needsMonth) {
- if (forceRedraw) {
- if (prevMonth == null) { // Only do once
- prevYear = new IEventButton();
- prevYear.setHTML("«");
- prevYear.setStyleName("i-button-prevyear");
- nextYear = new IEventButton();
- nextYear.setHTML("»");
- nextYear.setStyleName("i-button-nextyear");
- prevYear.addMouseListener(this);
- nextYear.addMouseListener(this);
- setWidget(0, 0, prevYear);
- setWidget(0, 4, nextYear);
-
- if (needsMonth) {
- prevMonth = new IEventButton();
- prevMonth.setHTML("‹");
- prevMonth.setStyleName("i-button-prevmonth");
- nextMonth = new IEventButton();
- nextMonth.setHTML("›");
- nextMonth.setStyleName("i-button-nextmonth");
- prevMonth.addMouseListener(this);
- nextMonth.addMouseListener(this);
- setWidget(0, 3, nextMonth);
- setWidget(0, 1, prevMonth);
- }
-
- getFlexCellFormatter().setColSpan(0, 2, 3);
- getRowFormatter().addStyleName(0,
- IDateField.CLASSNAME + "-calendarpanel-header");
- } else if (!needsMonth) {
- // Remove month traverse buttons
- prevMonth.removeMouseListener(this);
- nextMonth.removeMouseListener(this);
- remove(prevMonth);
- remove(nextMonth);
- prevMonth = null;
- nextMonth = null;
- }
-
- // Print weekday names
- final int firstDay = datefield.getDateTimeService()
- .getFirstDayOfWeek();
- for (int i = 0; i < 7; i++) {
- int day = i + firstDay;
- if (day > 6) {
- day = 0;
- }
- if (datefield.getCurrentResolution() > IDateField.RESOLUTION_MONTH) {
- setHTML(1, i, ""
- + datefield.getDateTimeService().getShortDay(day)
- + "");
- } else {
- setHTML(1, i, "");
- }
- }
- }
-
- final String monthName = needsMonth ? datefield.getDateTimeService()
- .getMonth(datefield.getShowingDate().getMonth()) : "";
- final int year = datefield.getShowingDate().getYear() + 1900;
- setHTML(0, 2, "" + monthName + " " + year
- + "");
- }
-
- private void buildCalendarBody() {
- // date actually selected?
- Date currentDate = datefield.getCurrentDate();
- Date showing = datefield.getShowingDate();
- boolean selected = (currentDate != null
- && currentDate.getMonth() == showing.getMonth() && currentDate
- .getYear() == showing.getYear());
-
- final int startWeekDay = datefield.getDateTimeService()
- .getStartWeekDay(datefield.getShowingDate());
- final int numDays = DateTimeService.getNumberOfDaysInMonth(datefield
- .getShowingDate());
- int dayCount = 0;
- final Date today = new Date();
- final Date curr = new Date(datefield.getShowingDate().getTime());
- for (int row = 2; row < 8; row++) {
- for (int col = 0; col < 7; col++) {
- if (!(row == 2 && col < startWeekDay)) {
- if (dayCount < numDays) {
- final int selectedDate = ++dayCount;
- String title = "";
- if (entrySource != null) {
- curr.setDate(dayCount);
- final List entries = entrySource.getEntries(curr,
- IDateField.RESOLUTION_DAY);
- if (entries != null) {
- for (final Iterator it = entries.iterator(); it
- .hasNext();) {
- final CalendarEntry entry = (CalendarEntry) it
- .next();
- title += (title.length() > 0 ? ", " : "")
- + entry.getStringForDate(curr);
- }
- }
- }
- final String baseclass = IDateField.CLASSNAME
- + "-calendarpanel-day";
- String cssClass = baseclass;
- if (!isEnabledDate(curr)) {
- cssClass += " " + baseclass + "-disabled";
- }
- if (selected
- && datefield.getShowingDate().getDate() == dayCount) {
- cssClass += " " + baseclass + "-selected";
- }
- if (today.getDate() == dayCount
- && today.getMonth() == datefield
- .getShowingDate().getMonth()
- && today.getYear() == datefield
- .getShowingDate().getYear()) {
- cssClass += " " + baseclass + "-today";
- }
- if (title.length() > 0) {
- cssClass += " " + baseclass + "-entry";
- }
- setHTML(row, col, ""
- + selectedDate + "");
- } else {
- break;
- }
-
- }
- }
- }
- }
-
- private void buildTime(boolean forceRedraw) {
- if (time == null) {
- time = new ITime(datefield);
- setText(8, 0, ""); // Add new row
- getFlexCellFormatter().setColSpan(8, 0, 7);
- setWidget(8, 0, time);
- }
- time.updateTime(forceRedraw);
- }
-
- /**
- *
- * @param forceRedraw
- * Build all from scratch, in case of e.g. locale changes
- */
- public void updateCalendar() {
- // Locale and resolution changes force a complete redraw
- buildCalendar(locale != datefield.getCurrentLocale()
- || resolution != datefield.getCurrentResolution());
- if (datefield instanceof ITextualDate) {
- ((ITextualDate) datefield).buildDate();
- }
- locale = datefield.getCurrentLocale();
- resolution = datefield.getCurrentResolution();
- }
-
- private boolean isEnabledDate(Date date) {
- if ((minDate != null && date.before(minDate))
- || (maxDate != null && date.after(maxDate))) {
- return false;
- }
- return true;
- }
-
- private void processClickEvent(Widget sender, boolean updateVariable) {
- if (!datefield.isEnabled() || datefield.isReadonly()) {
- return;
- }
- Date showingDate = datefield.getShowingDate();
- if (!updateVariable) {
- if (sender == prevYear) {
- showingDate.setYear(showingDate.getYear() - 1);
- updateCalendar();
- } else if (sender == nextYear) {
- showingDate.setYear(showingDate.getYear() + 1);
- updateCalendar();
- } else if (sender == prevMonth) {
- int currentMonth = showingDate.getMonth();
- showingDate.setMonth(currentMonth - 1);
-
- /*
- * If the selected date was e.g. 31.12 the new date would be
- * 31.11 but this date is invalid so the new date will be 1.12.
- * This is taken care of by decreasing the date until we have
- * the correct month.
- */
- while (showingDate.getMonth() == currentMonth) {
- showingDate.setDate(showingDate.getDate() - 1);
- }
-
- updateCalendar();
- } else if (sender == nextMonth) {
- int currentMonth = showingDate.getMonth();
- showingDate.setMonth(currentMonth + 1);
- int requestedMonth = (currentMonth + 1) % 12;
-
- /*
- * If the selected date was e.g. 31.3 the new date would be 31.4
- * but this date is invalid so the new date will be 1.5. This is
- * taken care of by decreasing the date until we have the
- * correct month.
- */
- while (showingDate.getMonth() != requestedMonth) {
- showingDate.setDate(showingDate.getDate() - 1);
- }
-
- updateCalendar();
- }
- } else {
- if (datefield.getCurrentResolution() == IDateField.RESOLUTION_YEAR
- || datefield.getCurrentResolution() == IDateField.RESOLUTION_MONTH) {
- // Due to current UI, update variable if res=year/month
- datefield.setCurrentDate(new Date(showingDate.getTime()));
- if (datefield.getCurrentResolution() == IDateField.RESOLUTION_MONTH) {
- datefield.getClient().updateVariable(datefield.getId(),
- "month", datefield.getCurrentDate().getMonth() + 1,
- false);
- }
- datefield.getClient().updateVariable(datefield.getId(), "year",
- datefield.getCurrentDate().getYear() + 1900,
- datefield.isImmediate());
-
- /* Must update the value in the textfield also */
- updateCalendar();
- }
- }
- }
-
- private Timer timer;
-
- public void onMouseDown(final Widget sender, int x, int y) {
- // Allow user to click-n-hold for fast-forward or fast-rewind.
- // Timer is first used for a 500ms delay after mousedown. After that has
- // elapsed, another timer is triggered to go off every 150ms. Both
- // timers are cancelled on mouseup or mouseout.
- if (sender instanceof IEventButton) {
- processClickEvent(sender, false);
- timer = new Timer() {
- @Override
- public void run() {
- timer = new Timer() {
- @Override
- public void run() {
- processClickEvent(sender, false);
- }
- };
- timer.scheduleRepeating(150);
- }
- };
- timer.schedule(500);
- }
- }
-
- public void onMouseEnter(Widget sender) {
- }
-
- public void onMouseLeave(Widget sender) {
- if (timer != null) {
- timer.cancel();
- }
- }
-
- public void onMouseMove(Widget sender, int x, int y) {
- }
-
- public void onMouseUp(Widget sender, int x, int y) {
- if (timer != null) {
- timer.cancel();
- }
- processClickEvent(sender, true);
- }
-
- private class IEventButton extends IButton implements SourcesMouseEvents {
-
- private MouseListenerCollection mouseListeners;
-
- public IEventButton() {
- super();
- sinkEvents(Event.FOCUSEVENTS | Event.KEYEVENTS | Event.ONCLICK
- | Event.MOUSEEVENTS);
- }
-
- public void addMouseListener(MouseListener listener) {
- if (mouseListeners == null) {
- mouseListeners = new MouseListenerCollection();
- }
- mouseListeners.add(listener);
- }
-
- public void removeMouseListener(MouseListener listener) {
- if (mouseListeners != null) {
- mouseListeners.remove(listener);
- }
- }
-
- @Override
- public void onBrowserEvent(Event event) {
- super.onBrowserEvent(event);
- switch (DOM.eventGetType(event)) {
- case Event.ONMOUSEDOWN:
- case Event.ONMOUSEUP:
- case Event.ONMOUSEMOVE:
- case Event.ONMOUSEOVER:
- case Event.ONMOUSEOUT:
- if (mouseListeners != null) {
- mouseListeners.fireMouseEvent(this, event);
- }
- break;
- }
- }
- }
-
- private class DateClickListener implements TableListener {
-
- private final ICalendarPanel cal;
-
- public DateClickListener(ICalendarPanel panel) {
- cal = panel;
- }
-
- public void onCellClicked(SourcesTableEvents sender, int row, int col) {
- if (sender != cal || row < 2 || row > 7
- || !cal.datefield.isEnabled() || cal.datefield.isReadonly()) {
- return;
- }
-
- final String text = cal.getText(row, col);
- if (text.equals(" ")) {
- return;
- }
-
- try {
- final Integer day = new Integer(text);
- final Date newDate = cal.datefield.getShowingDate();
- newDate.setDate(day.intValue());
- if (!isEnabledDate(newDate)) {
- return;
- }
- if (cal.datefield.getCurrentDate() == null) {
- cal.datefield.setCurrentDate(new Date(newDate.getTime()));
-
- // Init variables with current time
- datefield.getClient().updateVariable(cal.datefield.getId(),
- "hour", newDate.getHours(), false);
- datefield.getClient().updateVariable(cal.datefield.getId(),
- "min", newDate.getMinutes(), false);
- datefield.getClient().updateVariable(cal.datefield.getId(),
- "sec", newDate.getSeconds(), false);
- datefield.getClient().updateVariable(cal.datefield.getId(),
- "msec", datefield.getMilliseconds(), false);
- }
-
- cal.datefield.getCurrentDate().setTime(newDate.getTime());
- cal.datefield.getClient().updateVariable(cal.datefield.getId(),
- "day", cal.datefield.getCurrentDate().getDate(), false);
- cal.datefield.getClient().updateVariable(cal.datefield.getId(),
- "month", cal.datefield.getCurrentDate().getMonth() + 1,
- false);
- cal.datefield.getClient().updateVariable(cal.datefield.getId(),
- "year",
- cal.datefield.getCurrentDate().getYear() + 1900,
- cal.datefield.isImmediate());
-
- if (datefield instanceof ITextualDate
- && resolution < IDateField.RESOLUTION_HOUR) {
- ((IToolkitOverlay) getParent()).hide();
- } else {
- updateCalendar();
- }
-
- } catch (final NumberFormatException e) {
- // Not a number, ignore and stop here
- return;
- }
- }
-
- }
-
- public void setLimits(Date min, Date max) {
- if (min != null) {
- final Date d = new Date(min.getTime());
- d.setHours(0);
- d.setMinutes(0);
- d.setSeconds(1);
- minDate = d;
- } else {
- minDate = null;
- }
- if (max != null) {
- final Date d = new Date(max.getTime());
- d.setHours(24);
- d.setMinutes(59);
- d.setSeconds(59);
- maxDate = d;
- } else {
- maxDate = null;
- }
- }
-
- public void setCalendarEntrySource(CalendarEntrySource entrySource) {
- this.entrySource = entrySource;
- }
-
- public CalendarEntrySource getCalendarEntrySource() {
- return entrySource;
- }
-
- public interface CalendarEntrySource {
- public List getEntries(Date date, int resolution);
- }
-
- /**
- * Sets focus to Calendar panel.
- *
- * @param focus
- */
- public void setFocus(boolean focus) {
- nextYear.setFocus(focus);
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/ICheckBox.java b/src/com/vaadin/terminal/gwt/client/ui/ICheckBox.java
deleted file mode 100644
index 397dc89828..0000000000
--- a/src/com/vaadin/terminal/gwt/client/ui/ICheckBox.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
-@ITMillApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.ui.ClickListener;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.ITooltip;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-
-public class ICheckBox extends com.google.gwt.user.client.ui.CheckBox implements
- Paintable, Field {
-
- public static final String CLASSNAME = "i-checkbox";
-
- String id;
-
- boolean immediate;
-
- ApplicationConnection client;
-
- private Element errorIndicatorElement;
-
- private Icon icon;
-
- private boolean isBlockMode = false;
-
- public ICheckBox() {
- setStyleName(CLASSNAME);
- addClickListener(new ClickListener() {
-
- public void onClick(Widget sender) {
- if (id == null || client == null) {
- return;
- }
- client.updateVariable(id, "state", isChecked(), immediate);
- }
-
- });
- sinkEvents(ITooltip.TOOLTIP_EVENTS);
- Element el = DOM.getFirstChild(getElement());
- while (el != null) {
- DOM.sinkEvents(el,
- (DOM.getEventsSunk(el) | ITooltip.TOOLTIP_EVENTS));
- el = DOM.getNextSibling(el);
- }
- }
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- // Save details
- this.client = client;
- id = uidl.getId();
-
- // Ensure correct implementation
- if (client.updateComponent(this, uidl, false)) {
- return;
- }
-
- if (uidl.hasAttribute("error")) {
- if (errorIndicatorElement == null) {
- errorIndicatorElement = DOM.createDiv();
- errorIndicatorElement.setInnerHTML(" ");
- DOM.setElementProperty(errorIndicatorElement, "className",
- "i-errorindicator");
- DOM.appendChild(getElement(), errorIndicatorElement);
- DOM.sinkEvents(errorIndicatorElement, ITooltip.TOOLTIP_EVENTS
- | Event.ONCLICK);
- }
- } else if (errorIndicatorElement != null) {
- DOM.setStyleAttribute(errorIndicatorElement, "display", "none");
- }
-
- if (uidl.hasAttribute("readonly")) {
- setEnabled(false);
- }
-
- if (uidl.hasAttribute("icon")) {
- if (icon == null) {
- icon = new Icon(client);
- DOM.insertChild(getElement(), icon.getElement(), 1);
- icon.sinkEvents(ITooltip.TOOLTIP_EVENTS);
- icon.sinkEvents(Event.ONCLICK);
- }
- icon.setUri(uidl.getStringAttribute("icon"));
- } else if (icon != null) {
- // detach icon
- DOM.removeChild(getElement(), icon.getElement());
- icon = null;
- }
-
- // Set text
- setText(uidl.getStringAttribute("caption"));
- setChecked(uidl.getBooleanVariable("state"));
- immediate = uidl.getBooleanAttribute("immediate");
- }
-
- @Override
- public void onBrowserEvent(Event event) {
- if (icon != null && (event.getTypeInt() == Event.ONCLICK)
- && (event.getTarget() == icon.getElement())) {
- setChecked(!isChecked());
- }
- super.onBrowserEvent(event);
- if (event.getTypeInt() == Event.ONLOAD) {
- Util.notifyParentOfSizeChange(this, true);
- }
- if (client != null) {
- client.handleTooltipEvent(event, this);
- }
- }
-
- @Override
- public void setWidth(String width) {
- setBlockMode();
- super.setWidth(width);
- }
-
- @Override
- public void setHeight(String height) {
- setBlockMode();
- super.setHeight(height);
- }
-
- /**
- * makes container element (span) to be block element to enable sizing.
- */
- private void setBlockMode() {
- if (!isBlockMode) {
- DOM.setStyleAttribute(getElement(), "display", "block");
- isBlockMode = true;
- }
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/IContextMenu.java b/src/com/vaadin/terminal/gwt/client/ui/IContextMenu.java
deleted file mode 100644
index 5dc2e981b9..0000000000
--- a/src/com/vaadin/terminal/gwt/client/ui/IContextMenu.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
-@ITMillApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.dom.client.NodeList;
-import com.google.gwt.dom.client.TableRowElement;
-import com.google.gwt.dom.client.TableSectionElement;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.MenuBar;
-import com.google.gwt.user.client.ui.MenuItem;
-import com.google.gwt.user.client.ui.PopupPanel;
-
-public class IContextMenu extends IToolkitOverlay implements SubPartAware {
-
- private ActionOwner actionOwner;
-
- private final CMenuBar menu = new CMenuBar();
-
- private int left;
-
- private int top;
-
- /**
- * This method should be used only by Client object as only one per client
- * should exists. Request an instance via client.getContextMenu();
- *
- * @param cli
- * to be set as an owner of menu
- */
- public IContextMenu() {
- super(true, false, true);
- setWidget(menu);
- setStyleName("i-contextmenu");
- }
-
- /**
- * Sets the element from which to build menu
- *
- * @param ao
- */
- public void setActionOwner(ActionOwner ao) {
- actionOwner = ao;
- }
-
- /**
- * Shows context menu at given location.
- *
- * @param left
- * @param top
- */
- public void showAt(int left, int top) {
- this.left = left;
- this.top = top;
- menu.clearItems();
- final Action[] actions = actionOwner.getActions();
- for (int i = 0; i < actions.length; i++) {
- final Action a = actions[i];
- menu.addItem(new MenuItem(a.getHTML(), true, a));
- }
-
- setPopupPositionAndShow(new PositionCallback() {
- public void setPosition(int offsetWidth, int offsetHeight) {
- // mac FF gets bad width due GWT popups overflow hacks,
- // re-determine width
- offsetWidth = menu.getOffsetWidth();
- int left = IContextMenu.this.left;
- int top = IContextMenu.this.top;
- if (offsetWidth + left > Window.getClientWidth()) {
- left = left - offsetWidth;
- if (left < 0) {
- left = 0;
- }
- }
- if (offsetHeight + top > Window.getClientHeight()) {
- top = top - offsetHeight;
- if (top < 0) {
- top = 0;
- }
- }
- setPopupPosition(left, top);
- }
- });
- }
-
- public void showAt(ActionOwner ao, int left, int top) {
- setActionOwner(ao);
- showAt(left, top);
- }
-
- /**
- * Extend standard Gwt MenuBar to set proper settings and to override
- * onPopupClosed method so that PopupPanel gets closed.
- */
- class CMenuBar extends MenuBar {
- public CMenuBar() {
- super(true);
- }
-
- @Override
- public void onPopupClosed(PopupPanel sender, boolean autoClosed) {
- super.onPopupClosed(sender, autoClosed);
- hide();
- }
-
- /*
- * public void onBrowserEvent(Event event) { // Remove current selection
- * when mouse leaves if (DOM.eventGetType(event) == Event.ONMOUSEOUT) {
- * Element to = DOM.eventGetToElement(event); if
- * (!DOM.isOrHasChild(getElement(), to)) { DOM.setElementProperty(
- * super.getSelectedItem().getElement(), "className",
- * super.getSelectedItem().getStylePrimaryName()); } }
- *
- * super.onBrowserEvent(event); }
- */
- }
-
- public Element getSubPartElement(String subPart) {
- int index = Integer.parseInt(subPart.substring(6));
- // ApplicationConnection.getConsole().log(
- // "Searching element for selection index " + index);
- Element wrapperdiv = menu.getElement();
- com.google.gwt.dom.client.TableSectionElement tBody = (TableSectionElement) wrapperdiv
- .getFirstChildElement().getFirstChildElement();
- TableRowElement item = tBody.getRows().getItem(index);
- com.google.gwt.dom.client.Element clickableDivElement = item
- .getFirstChildElement().getFirstChildElement();
- return clickableDivElement.cast();
- }
-
- public String getSubPartName(Element subElement) {
- if (getElement().isOrHasChild(subElement)) {
- com.google.gwt.dom.client.Element e = subElement;
- {
- while (e != null && !e.getTagName().toLowerCase().equals("tr")) {
- e = e.getParentElement();
- // ApplicationConnection.getConsole().log("Found row");
- }
- }
- com.google.gwt.dom.client.TableSectionElement parentElement = (TableSectionElement) e
- .getParentElement();
- NodeList rows = parentElement.getRows();
- for (int i = 0; i < rows.getLength(); i++) {
- if (rows.getItem(i) == e) {
- // ApplicationConnection.getConsole().log(
- // "Found index for row" + 1);
- return "option" + i;
- }
- }
- return null;
- } else {
- return null;
- }
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/ICustomComponent.java b/src/com/vaadin/terminal/gwt/client/ui/ICustomComponent.java
deleted file mode 100644
index 1e92111efa..0000000000
--- a/src/com/vaadin/terminal/gwt/client/ui/ICustomComponent.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
-@ITMillApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.Set;
-
-import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.DeferredCommand;
-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.Paintable;
-import com.vaadin.terminal.gwt.client.RenderSpace;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-
-public class ICustomComponent extends SimplePanel implements Container {
-
- private static final String CLASSNAME = "i-customcomponent";
- private String height;
- private ApplicationConnection client;
- private boolean rendering;
- private String width;
- private RenderSpace renderSpace = new RenderSpace();
-
- public ICustomComponent() {
- super();
- setStyleName(CLASSNAME);
- }
-
- public void updateFromUIDL(UIDL uidl, final ApplicationConnection client) {
- rendering = true;
- if (client.updateComponent(this, uidl, true)) {
- rendering = false;
- return;
- }
- this.client = client;
-
- final UIDL child = uidl.getChildUIDL(0);
- if (child != null) {
- final Paintable p = client.getPaintable(child);
- if (p != getWidget()) {
- if (getWidget() != null) {
- client.unregisterPaintable((Paintable) getWidget());
- clear();
- }
- setWidget((Widget) p);
- }
- p.updateFromUIDL(child, client);
- }
-
- boolean updateDynamicSize = updateDynamicSize();
- if (updateDynamicSize) {
- DeferredCommand.addCommand(new Command() {
- public void execute() {
- // FIXME deferred relative size update needed to fix some
- // scrollbar issues in sampler. This must be the wrong way
- // to do it. Might be that some other component is broken.
- client.handleComponentRelativeSize(ICustomComponent.this);
-
- }
- });
- }
-
- renderSpace.setWidth(getElement().getOffsetWidth());
- renderSpace.setHeight(getElement().getOffsetHeight());
-
- rendering = false;
- }
-
- private boolean updateDynamicSize() {
- boolean updated = false;
- if (isDynamicWidth()) {
- int childWidth = Util.getRequiredWidth(getWidget());
- getElement().getStyle().setPropertyPx("width", childWidth);
- updated = true;
- }
- if (isDynamicHeight()) {
- int childHeight = Util.getRequiredHeight(getWidget());
- getElement().getStyle().setPropertyPx("height", childHeight);
- updated = true;
- }
-
- return updated;
- }
-
- private boolean isDynamicWidth() {
- return width == null || width.equals("");
- }
-
- private boolean isDynamicHeight() {
- return height == null || height.equals("");
- }
-
- public boolean hasChildComponent(Widget component) {
- if (getWidget() == component) {
- return true;
- } else {
- return false;
- }
- }
-
- public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
- if (hasChildComponent(oldComponent)) {
- clear();
- setWidget(newComponent);
- } else {
- throw new IllegalStateException();
- }
- }
-
- public void updateCaption(Paintable component, UIDL uidl) {
- // NOP, custom component dont render composition roots caption
- }
-
- public boolean requestLayout(Set child) {
- return !updateDynamicSize();
- }
-
- public RenderSpace getAllocatedSpace(Widget child) {
- return renderSpace;
- }
-
- @Override
- public void setHeight(String height) {
- super.setHeight(height);
- renderSpace.setHeight(getElement().getOffsetHeight());
-
- if (!height.equals(this.height)) {
- this.height = height;
- if (!rendering) {
- client.runDescendentsLayout(this);
- }
- }
- }
-
- @Override
- public void setWidth(String width) {
- super.setWidth(width);
- renderSpace.setWidth(getElement().getOffsetWidth());
-
- if (!width.equals(this.width)) {
- this.width = width;
- if (!rendering) {
- client.runDescendentsLayout(this);
- }
- }
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/ICustomLayout.java b/src/com/vaadin/terminal/gwt/client/ui/ICustomLayout.java
deleted file mode 100644
index ac7827f22c..0000000000
--- a/src/com/vaadin/terminal/gwt/client/ui/ICustomLayout.java
+++ /dev/null
@@ -1,644 +0,0 @@
-/*
-@ITMillApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import com.google.gwt.dom.client.ImageElement;
-import com.google.gwt.dom.client.NodeList;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.ui.ComplexPanel;
-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.ContainerResizedListener;
-import com.vaadin.terminal.gwt.client.ICaption;
-import com.vaadin.terminal.gwt.client.ICaptionWrapper;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.RenderSpace;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize;
-
-/**
- * Custom Layout implements complex layout defined with HTML template.
- *
- * @author IT Mill
- *
- */
-public class ICustomLayout extends ComplexPanel implements Paintable,
- Container, ContainerResizedListener {
-
- public static final String CLASSNAME = "i-customlayout";
-
- /** Location-name to containing element in DOM map */
- private final HashMap locationToElement = new HashMap();
-
- /** Location-name to contained widget map */
- private final HashMap locationToWidget = new HashMap();
-
- /** Widget to captionwrapper map */
- private final HashMap widgetToCaptionWrapper = new HashMap();
-
- /** Name of the currently rendered style */
- String currentTemplateName;
-
- /** Unexecuted scripts loaded from the template */
- private String scripts = "";
-
- /** Paintable ID of this paintable */
- private String pid;
-
- private ApplicationConnection client;
-
- /** Has the template been loaded from contents passed in UIDL **/
- private boolean hasTemplateContents = false;
-
- private Element elementWithNativeResizeFunction;
-
- private String height = "";
-
- private String width = "";
-
- private HashMap locationToExtraSize = new HashMap();
-
- public ICustomLayout() {
- setElement(DOM.createDiv());
- // Clear any unwanted styling
- DOM.setStyleAttribute(getElement(), "border", "none");
- DOM.setStyleAttribute(getElement(), "margin", "0");
- DOM.setStyleAttribute(getElement(), "padding", "0");
-
- if (BrowserInfo.get().isIE()) {
- DOM.setStyleAttribute(getElement(), "position", "relative");
- }
-
- setStyleName(CLASSNAME);
- }
-
- /**
- * Sets widget to given location.
- *
- * If location already contains a widget it will be removed.
- *
- * @param widget
- * Widget to be set into location.
- * @param location
- * location name where widget will be added
- *
- * @throws IllegalArgumentException
- * if no such location is found in the layout.
- */
- public void setWidget(Widget widget, String location) {
-
- if (widget == null) {
- return;
- }
-
- // If no given location is found in the layout, and exception is throws
- Element elem = (Element) locationToElement.get(location);
- if (elem == null && hasTemplate()) {
- throw new IllegalArgumentException("No location " + location
- + " found");
- }
-
- // Get previous widget
- final Widget previous = locationToWidget.get(location);
- // NOP if given widget already exists in this location
- if (previous == widget) {
- return;
- }
-
- if (previous != null) {
- remove(previous);
- }
-
- // if template is missing add element in order
- if (!hasTemplate()) {
- elem = getElement();
- }
-
- // Add widget to location
- super.add(widget, elem);
- locationToWidget.put(location, widget);
- }
-
- /** Update the layout from UIDL */
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- this.client = client;
- // ApplicationConnection manages generic component features
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- pid = uidl.getId();
- if (!hasTemplate()) {
- // Update HTML template only once
- initializeHTML(uidl, client);
- }
-
- // Evaluate scripts
- eval(scripts);
- scripts = null;
-
- iLayout();
- // TODO Check if this is needed
- client.runDescendentsLayout(this);
-
- Set oldWidgets = new HashSet();
- oldWidgets.addAll(locationToWidget.values());
-
- // For all contained widgets
- for (final Iterator i = uidl.getChildIterator(); i.hasNext();) {
- final UIDL uidlForChild = (UIDL) i.next();
- if (uidlForChild.getTag().equals("location")) {
- final String location = uidlForChild.getStringAttribute("name");
- final Paintable child = client.getPaintable(uidlForChild
- .getChildUIDL(0));
- try {
- setWidget((Widget) child, location);
- child.updateFromUIDL(uidlForChild.getChildUIDL(0), client);
- } catch (final IllegalArgumentException e) {
- // If no location is found, this component is not visible
- }
- oldWidgets.remove(child);
- }
- }
- for (Iterator iterator = oldWidgets.iterator(); iterator.hasNext();) {
- Widget oldWidget = (Widget) iterator.next();
- if (oldWidget.isAttached()) {
- // slot of this widget is emptied, remove it
- remove(oldWidget);
- }
- }
-
- iLayout();
- // TODO Check if this is needed
- client.runDescendentsLayout(this);
-
- }
-
- /** Initialize HTML-layout. */
- private void initializeHTML(UIDL uidl, ApplicationConnection client) {
-
- final String newTemplateContents = uidl
- .getStringAttribute("templateContents");
- final String newTemplate = uidl.getStringAttribute("template");
-
- currentTemplateName = null;
- hasTemplateContents = false;
-
- String template = "";
- if (newTemplate != null) {
- // Get the HTML-template from client
- template = client.getResource("layouts/" + newTemplate + ".html");
- if (template == null) {
- template = "Layout file layouts/"
- + newTemplate
- + ".html is missing. Components will be drawn for debug purposes.";
- } else {
- currentTemplateName = newTemplate;
- }
- } else {
- hasTemplateContents = true;
- template = newTemplateContents;
- }
-
- // Connect body of the template to DOM
- template = extractBodyAndScriptsFromTemplate(template);
-
- // TODO prefix img src:s here with a regeps, cannot work further with IE
-
- String themeUri = client.getThemeUri();
- String relImgPrefix = themeUri + "/layouts/";
-
- // prefix all relative image elements to point to theme dir with a
- // regexp search
- template = template.replaceAll(
- "<((?:img)|(?:IMG))\\s([^>]*)src=\"((?![a-z]+:)[^/][^\"]+)\"",
- "<$1 $2src=\"" + relImgPrefix + "$3\"");
- // also support src attributes without quotes
- template = template
- .replaceAll(
- "<((?:img)|(?:IMG))\\s([^>]*)src=[^\"]((?![a-z]+:)[^/][^ />]+)[ />]",
- "<$1 $2src=\"" + relImgPrefix + "$3\"");
- // also prefix relative style="...url(...)..."
- template = template
- .replaceAll(
- "(<[^>]+style=\"[^\"]*url\\()((?![a-z]+:)[^/][^\"]+)(\\)[^>]*>)",
- "$1 " + relImgPrefix + "$2 $3");
-
- getElement().setInnerHTML(template);
-
- // Remap locations to elements
- locationToElement.clear();
- scanForLocations(getElement());
-
- initImgElements();
-
- elementWithNativeResizeFunction = DOM.getFirstChild(getElement());
- if (elementWithNativeResizeFunction == null) {
- elementWithNativeResizeFunction = getElement();
- }
- publishResizedFunction(elementWithNativeResizeFunction);
-
- }
-
- private native boolean uriEndsWithSlash()
- /*-{
- var path = $wnd.location.pathname;
- if(path.charAt(path.length - 1) == "/")
- return true;
- return false;
- }-*/;
-
- private boolean hasTemplate() {
- if (currentTemplateName == null && !hasTemplateContents) {
- return false;
- } else {
- return true;
- }
- }
-
- /** Collect locations from template */
- private void scanForLocations(Element elem) {
-
- final String location = elem.getAttribute("location");
- if (!"".equals(location)) {
- locationToElement.put(location, elem);
- elem.setInnerHTML("");
- int x = Util.measureHorizontalPaddingAndBorder(elem, 0);
- int y = Util.measureVerticalPaddingAndBorder(elem, 0);
-
- FloatSize fs = new FloatSize(x, y);
-
- locationToExtraSize.put(location, fs);
-
- } else {
- final int len = DOM.getChildCount(elem);
- for (int i = 0; i < len; i++) {
- scanForLocations(DOM.getChild(elem, i));
- }
- }
- }
-
- /** Evaluate given script in browser document */
- private static native void eval(String script)
- /*-{
- try {
- if (script != null)
- eval("{ var document = $doc; var window = $wnd; "+ script + "}");
- } catch (e) {
- }
- }-*/;
-
- /**
- * Img elements needs some special handling in custom layout. Img elements
- * will get their onload events sunk. This way custom layout can notify
- * parent about possible size change.
- */
- private void initImgElements() {
- NodeList nodeList = getElement()
- .getElementsByTagName("IMG");
- for (int i = 0; i < nodeList.getLength(); i++) {
- com.google.gwt.dom.client.ImageElement img = (ImageElement) nodeList
- .getItem(i);
- DOM.sinkEvents((Element) img.cast(), Event.ONLOAD);
- }
- }
-
- /**
- * Extract body part and script tags from raw html-template.
- *
- * Saves contents of all script-tags to private property: scripts. Returns
- * contents of the body part for the html without script-tags. Also replaces
- * all _UID_ tags with an unique id-string.
- *
- * @param html
- * Original HTML-template received from server
- * @return html that is used to create the HTMLPanel.
- */
- private String extractBodyAndScriptsFromTemplate(String html) {
-
- // Replace UID:s
- html = html.replaceAll("_UID_", pid + "__");
-
- // Exctract script-tags
- scripts = "";
- int endOfPrevScript = 0;
- int nextPosToCheck = 0;
- String lc = html.toLowerCase();
- String res = "";
- int scriptStart = lc.indexOf("", scriptStart);
- scripts += html.substring(scriptStart + 1, j) + ";";
- nextPosToCheck = endOfPrevScript = j + "".length();
- scriptStart = lc.indexOf("", scriptStart);
+ scripts += html.substring(scriptStart + 1, j) + ";";
+ nextPosToCheck = endOfPrevScript = j + "".length();
+ scriptStart = lc.indexOf("