]> source.dussan.org Git - vaadin-framework.git/commitdiff
Merges from 6.0 branch.
authorJouni Koivuviita <jouni.koivuviita@itmill.com>
Fri, 8 May 2009 12:41:04 +0000 (12:41 +0000)
committerJouni Koivuviita <jouni.koivuviita@itmill.com>
Fri, 8 May 2009 12:41:04 +0000 (12:41 +0000)
svn changeset:7682/svn branch:theme_2009_03

14 files changed:
src/com/itmill/toolkit/demo/sampler/features/accordions/AccordionDisabledExample.java
src/com/itmill/toolkit/demo/sampler/features/tabsheets/TabSheetDisabledExample.java
src/com/itmill/toolkit/terminal/gwt/client/ComponentLocator.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IAccordion.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IContextMenu.java
src/com/itmill/toolkit/terminal/gwt/client/ui/ITabsheet.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IView.java
src/com/itmill/toolkit/tests/components/absolutelayout/AbsoluteLayoutClipping.java [new file with mode: 0644]
src/com/itmill/toolkit/tests/components/tabsheet/TabSheetCaptions.java
src/com/itmill/toolkit/tests/components/tabsheet/TabSheetDisabling.java
src/com/itmill/toolkit/tests/layouts/AbsoluteLayoutAddRemove.java [new file with mode: 0644]
src/com/itmill/toolkit/ui/AbsoluteLayout.java
src/com/itmill/toolkit/ui/Label.java
src/com/itmill/toolkit/ui/TabSheet.java

index 705a857fd755f37d9a197682323e639e7731c15b..14d089809c98b62bb5906ee944c2e5eb8a5aab3b 100644 (file)
@@ -8,6 +8,7 @@ import com.itmill.toolkit.ui.Label;
 import com.itmill.toolkit.ui.VerticalLayout;\r
 import com.itmill.toolkit.ui.Button.ClickEvent;\r
 import com.itmill.toolkit.ui.TabSheet.SelectedTabChangeEvent;\r
+import com.itmill.toolkit.ui.TabSheet.Tab;\r
 \r
 public class AccordionDisabledExample extends VerticalLayout implements\r
         Accordion.SelectedTabChangeListener, Button.ClickListener {\r
@@ -18,6 +19,9 @@ public class AccordionDisabledExample extends VerticalLayout implements
     private Label l1;\r
     private Label l2;\r
     private Label l3;\r
+    private Tab t1;\r
+    private Tab t2;\r
+    private Tab t3;\r
 \r
     private static final ThemeResource icon1 = new ThemeResource(\r
             "icons/action_save.gif");\r
@@ -36,9 +40,9 @@ public class AccordionDisabledExample extends VerticalLayout implements
         a = new Accordion();\r
         a.setHeight("300px");\r
         a.setWidth("400px");\r
-        a.addTab(l1, "Saved actions", icon1);\r
-        a.addTab(l2, "Notes", icon2);\r
-        a.addTab(l3, "Issues", icon3);\r
+        t1 = a.addTab(l1, "Saved actions", icon1);\r
+        t2 = a.addTab(l2, "Notes", icon2);\r
+        t3 = a.addTab(l3, "Issues", icon3);\r
         a.addListener(this);\r
 \r
         b1 = new Button("Disable 'Notes' tab");\r
@@ -56,25 +60,25 @@ public class AccordionDisabledExample extends VerticalLayout implements
     }\r
 \r
     public void selectedTabChange(SelectedTabChangeEvent event) {\r
-        String c = a.getTabCaption(event.getTabSheet().getSelectedTab());\r
+        String c = a.getTab(event.getTabSheet().getSelectedTab()).getCaption();\r
         getWindow().showNotification("Selected tab: " + c);\r
     }\r
 \r
     public void buttonClick(ClickEvent event) {\r
         if (b1.equals(event.getButton())) { // b1 clicked\r
-            if (l2.isEnabled()) {\r
-                l2.setEnabled(false);\r
+            if (t2.isEnabled()) {\r
+                t2.setEnabled(false);\r
                 b1.setCaption("Enable 'Notes' tab");\r
             } else {\r
-                l2.setEnabled(true);\r
+                t2.setEnabled(true);\r
                 b1.setCaption("Disable 'Notes' tab");\r
             }\r
         } else { // b2 clicked\r
-            if (l3.isVisible()) {\r
-                l3.setVisible(false);\r
+            if (t3.isVisible()) {\r
+                t3.setVisible(false);\r
                 b2.setCaption("Show 'Issues' tab");\r
             } else {\r
-                l3.setVisible(true);\r
+                t3.setVisible(true);\r
                 b2.setCaption("Hide 'Issues' tab");\r
             }\r
         }\r
index 12ad969e7193b025e79a1fa4addfad39f25399cb..13c292772ea7e7505827a667d1e9957938fe698b 100644 (file)
@@ -8,6 +8,7 @@ import com.itmill.toolkit.ui.TabSheet;
 import com.itmill.toolkit.ui.VerticalLayout;\r
 import com.itmill.toolkit.ui.Button.ClickEvent;\r
 import com.itmill.toolkit.ui.TabSheet.SelectedTabChangeEvent;\r
+import com.itmill.toolkit.ui.TabSheet.Tab;\r
 \r
 public class TabSheetDisabledExample extends VerticalLayout implements\r
         TabSheet.SelectedTabChangeListener, Button.ClickListener {\r
@@ -24,6 +25,7 @@ public class TabSheetDisabledExample extends VerticalLayout implements
     private VerticalLayout l1;\r
     private VerticalLayout l2;\r
     private VerticalLayout l3;\r
+    private Tab t1, t2, t3;\r
 \r
     public TabSheetDisabledExample() {\r
         setSpacing(true);\r
@@ -44,9 +46,9 @@ public class TabSheetDisabledExample extends VerticalLayout implements
         t = new TabSheet();\r
         t.setHeight("200px");\r
         t.setWidth("400px");\r
-        t.addTab(l1, "Saved actions", icon1);\r
-        t.addTab(l2, "Notes", icon2);\r
-        t.addTab(l3, "Issues", icon3);\r
+        t1 = t.addTab(l1, "Saved actions", icon1);\r
+        t2 = t.addTab(l2, "Notes", icon2);\r
+        t3 = t.addTab(l3, "Issues", icon3);\r
         t.addListener(this);\r
 \r
         toggleEnabled = new Button("Disable 'Notes' tab");\r
@@ -65,21 +67,21 @@ public class TabSheetDisabledExample extends VerticalLayout implements
     }\r
 \r
     public void selectedTabChange(SelectedTabChangeEvent event) {\r
-        String c = t.getTabCaption(event.getTabSheet().getSelectedTab());\r
+        String c = t.getTab(event.getTabSheet().getSelectedTab()).getCaption();\r
         getWindow().showNotification("Selected tab: " + c);\r
     }\r
 \r
     public void buttonClick(ClickEvent event) {\r
         if (toggleEnabled.equals(event.getButton())) {\r
             // toggleEnabled clicked\r
-            l2.setEnabled(!l2.isEnabled());\r
-            toggleEnabled.setCaption((l2.isEnabled() ? "Disable" : "Enable")\r
+            t2.setEnabled(!t2.isEnabled());\r
+            toggleEnabled.setCaption((t2.isEnabled() ? "Disable" : "Enable")\r
                     + " 'Notes' tab");\r
 \r
         } else {\r
             // toggleVisible clicked\r
-            l3.setVisible(!l3.isVisible());\r
-            toggleVisible.setCaption((l3.isVisible() ? "Hide" : "Show")\r
+            t3.setVisible(!t3.isVisible());\r
+            toggleVisible.setCaption((t3.isVisible() ? "Hide" : "Show")\r
                     + " 'Issues' tab");\r
 \r
         }\r
index c4f44c944009df7c0aaf66ca05df3fa46163ee03..da4aea74e3b8165fab420b71af72fb817fbe04b3 100644 (file)
@@ -1,5 +1,6 @@
 package com.itmill.toolkit.terminal.gwt.client;
 
+import java.util.ArrayList;
 import java.util.Iterator;
 
 import com.google.gwt.user.client.DOM;
@@ -7,6 +8,7 @@ import com.google.gwt.user.client.Element;
 import com.google.gwt.user.client.ui.HasWidgets;
 import com.google.gwt.user.client.ui.Widget;
 import com.itmill.toolkit.terminal.gwt.client.ui.IView;
+import com.itmill.toolkit.terminal.gwt.client.ui.IWindow;
 import com.itmill.toolkit.terminal.gwt.client.ui.SubPartAware;
 
 /**
@@ -64,6 +66,15 @@ public class ComponentLocator {
         }
 
         if (e == null || pid == null) {
+
+            // Still test for context menu option
+            String subPartName = client.getContextMenu().getSubPartName(
+                    targetElement);
+            if (subPartName != null) {
+                // IContextMenu, singleton attached directly to rootpanel
+                return "/IContextMenu[0]" + SUBPART_SEPARATOR + subPartName;
+
+            }
             return null;
         }
 
@@ -217,6 +228,12 @@ public class ComponentLocator {
 
         if (w instanceof IView) {
             return "";
+        } else if (w instanceof IWindow) {
+            IWindow win = (IWindow) w;
+            ArrayList<IWindow> subWindowList = client.getView()
+                    .getSubWindowList();
+            int indexOfSubWindow = subWindowList.indexOf(win);
+            return PARENTCHILD_SEPARATOR + "IWindow[" + indexOfSubWindow + "]";
         }
 
         Widget parent = w.getParent();
@@ -225,7 +242,7 @@ public class ComponentLocator {
 
         String simpleName = Util.getSimpleName(w);
 
-        Iterator i = ((HasWidgets) parent).iterator();
+        Iterator<Widget> i = ((HasWidgets) parent).iterator();
         int pos = 0;
         while (i.hasNext()) {
             Object child = i.next();
@@ -262,12 +279,19 @@ public class ComponentLocator {
             } else if (w instanceof HasWidgets) {
                 HasWidgets parent = (HasWidgets) w;
 
-                String simpleName = Util.getSimpleName(parent);
+                String[] split = part.split("\\[");
 
-                Iterator i = parent.iterator();
+                Iterator<? extends Widget> i;
+                String widgetClassName = split[0];
+                if (widgetClassName.equals("IWindow")) {
+                    i = client.getView().getSubWindowList().iterator();
+                } else if (widgetClassName.equals("IContextMenu")) {
+                    return client.getContextMenu();
+                } else {
+                    i = parent.iterator();
+                }
 
                 boolean ok = false;
-                String[] split = part.split("\\[");
                 int pos = Integer.parseInt(split[1].substring(0, split[1]
                         .length() - 1));
                 // ApplicationConnection.getConsole().log(
@@ -275,10 +299,10 @@ public class ComponentLocator {
                 while (i.hasNext()) {
                     // ApplicationConnection.getConsole().log("- child found");
 
-                    Widget child = (Widget) i.next();
+                    Widget child = i.next();
                     String simpleName2 = Util.getSimpleName(child);
 
-                    if (split[0].equals(simpleName2)) {
+                    if (widgetClassName.equals(simpleName2)) {
                         if (pos == 0) {
                             w = child;
                             ok = true;
index 1ed82d51d408dd7e326abf5b40dc38f3cd7d26c3..e924dfab6b7c7eac7c81b52c4900d83a34e3621f 100644 (file)
@@ -582,18 +582,7 @@ public class IAccordion extends ITabsheetBase implements
     }
 
     public void updateCaption(Paintable component, UIDL uidl) {
-        for (Widget w : getChildren()) {
-            StackItem si = (StackItem) w;
-            if (si.getPaintable() == component) {
-                boolean visible = si.isVisible();
-                si.updateCaption(uidl);
-                if (si.isCaptionVisible() != visible) {
-                    si.setVisible(si.isCaptionVisible());
-                }
-
-                return;
-            }
-        }
+        /* Accordion does not render its children's captions */
     }
 
     public boolean requestLayout(Set<Paintable> child) {
index 411e646a0cd0f2974a3a08df79b54116013f9dc6..ba7f5b509b30a6a5513bc03d26b3f286ec6b67a0 100644 (file)
@@ -4,12 +4,17 @@
 
 package com.itmill.toolkit.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;
+import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
 
-public class IContextMenu extends IToolkitOverlay {
+public class IContextMenu extends IToolkitOverlay implements SubPartAware {
 
     private ActionOwner actionOwner;
 
@@ -112,4 +117,42 @@ public class IContextMenu extends IToolkitOverlay {
          * 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<TableRowElement> 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;
+        }
+    }
 }
index e40b6ac0a81406e3b4976535bff9a26c52153d1e..f1a61edc1c34a5f0561e5e99dfad96150b96eced 100644 (file)
@@ -763,14 +763,7 @@ public class ITabsheet extends ITabsheetBase {
     }
 
     public void updateCaption(Paintable component, UIDL uidl) {
-        int i = tp.getWidgetIndex((Widget) component);
-        ICaption c = captions.get("" + i);
-        boolean visible = c.isVisible();
-        c.updateCaption(uidl);
-        if (c.isVisible() != visible) {
-            tb.setVisible(i, c.isVisible());
-            c.setWidth(c.getRequiredWidth() + "px");
-        }
+        /* Tabsheet does not render its children's captions */
     }
 
     public boolean requestLayout(Set<Paintable> child) {
index 0c22da4a1ef231ad9cea6fc9d7d2a1903ab3bd05..b30a1eb8afe09c87e5eb728442e94e7468bad10e 100644 (file)
@@ -4,8 +4,10 @@
 
 package com.itmill.toolkit.terminal.gwt.client.ui;
 
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashSet;
 import java.util.Set;
 
 import com.google.gwt.dom.client.DivElement;
@@ -44,7 +46,7 @@ public class IView extends SimplePanel implements Container,
 
     private Paintable layout;
 
-    private final HashSet subWindows = new HashSet();
+    private final LinkedHashSet<IWindow> subWindows = new LinkedHashSet<IWindow>();
 
     private String id;
 
@@ -231,7 +233,8 @@ public class IView extends SimplePanel implements Container,
         layout.updateFromUIDL(childUidl, client);
 
         // Update subwindows
-        final HashSet removedSubWindows = new HashSet(subWindows);
+        final HashSet<IWindow> removedSubWindows = new HashSet<IWindow>(
+                subWindows);
 
         // Open new windows
         while ((childUidl = uidl.getChildUIDL(childIndex++)) != null) {
@@ -240,7 +243,7 @@ public class IView extends SimplePanel implements Container,
                 if (subWindows.contains(w)) {
                     removedSubWindows.remove(w);
                 } else {
-                    subWindows.add(w);
+                    subWindows.add((IWindow) w);
                 }
                 w.updateFromUIDL(childUidl, client);
             } else if ("actions".equals(childUidl.getTag())) {
@@ -282,8 +285,9 @@ public class IView extends SimplePanel implements Container,
         }
 
         // Close old windows
-        for (final Iterator rem = removedSubWindows.iterator(); rem.hasNext();) {
-            final IWindow w = (IWindow) rem.next();
+        for (final Iterator<IWindow> rem = removedSubWindows.iterator(); rem
+                .hasNext();) {
+            final IWindow w = rem.next();
             client.unregisterPaintable(w);
             subWindows.remove(w);
             w.hide();
@@ -551,7 +555,21 @@ public class IView extends SimplePanel implements Container,
     }
 
     public void updateCaption(Paintable component, UIDL uidl) {
-        // TODO Auto-generated method stub
+        // NOP Subwindows never draw caption for their first child (layout)
+    }
+
+    /**
+     * Return an iterator for current subwindows. This method is meant for
+     * testing purposes only.
+     * 
+     * @return
+     */
+    public ArrayList<IWindow> getSubWindowList() {
+        ArrayList<IWindow> windows = new ArrayList<IWindow>(subWindows.size());
+        for (IWindow widget : subWindows) {
+            windows.add(widget);
+        }
+        return windows;
     }
 
 }
diff --git a/src/com/itmill/toolkit/tests/components/absolutelayout/AbsoluteLayoutClipping.java b/src/com/itmill/toolkit/tests/components/absolutelayout/AbsoluteLayoutClipping.java
new file mode 100644 (file)
index 0000000..b43d005
--- /dev/null
@@ -0,0 +1,42 @@
+package com.itmill.toolkit.tests.components.absolutelayout;
+
+import com.itmill.toolkit.tests.components.TestBase;
+import com.itmill.toolkit.ui.AbsoluteLayout;
+import com.itmill.toolkit.ui.Label;
+
+public class AbsoluteLayoutClipping extends TestBase {
+
+    @Override
+    protected void setup() {
+        setTheme("tests-tickets");
+        AbsoluteLayout abs = new AbsoluteLayout();
+        abs.setStyleName("borders");
+        abs.setWidth("100px");
+        abs.setHeight("100px");
+
+        Label l = new Label("This should be clipped at 100px");
+        l.setSizeUndefined();
+        abs.addComponent(l, "top:50px;left:50px");
+
+        Label l2 = new Label("This should not be visible");
+        l2.setSizeUndefined();
+        abs.addComponent(l2, "top:80px;left:150px");
+
+        Label l3 = new Label("This should be clipped vertically at 100px");
+        l3.setWidth("50px");
+        abs.addComponent(l3, "top:20px;left:0px");
+
+        addComponent(abs);
+    }
+
+    @Override
+    protected String getDescription() {
+        return "An AbsoluteLayout with fixed size should clip at its borders. Nothing outside the black square should be visible.";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 2913;
+    }
+
+}
index be9cfaafbb4797ff38670fff0d643d795acee85c..d1b13ca00dda65bd8452f3e5f4e1773936183d6e 100644 (file)
@@ -1,5 +1,7 @@
 package com.itmill.toolkit.tests.components.tabsheet;\r
 \r
+import java.util.Date;\r
+\r
 import com.itmill.toolkit.tests.components.TestBase;\r
 import com.itmill.toolkit.ui.Button;\r
 import com.itmill.toolkit.ui.Label;\r
@@ -25,20 +27,29 @@ public class TabSheetCaptions extends TestBase {
     protected void setup() {\r
         final TabSheet tabSheet = new TabSheet();\r
 \r
-        panel1 = new Panel("tab 1");\r
+        panel1 = new Panel("Panel initial caption (should also be tab caption)");\r
         panel1.setSizeFull();\r
         panel1.getLayout().setSizeFull();\r
-        panel1.addComponent(new Label("This is first panel"));\r
+        panel1.addComponent(new Label("This is a panel"));\r
         tabSheet.addTab(panel1);\r
 \r
         Button button = new Button("Update tab caption");\r
         button.addListener(new Button.ClickListener() {\r
             public void buttonClick(ClickEvent event) {\r
-                tabSheet.setTabCaption(panel1, "This is a new caption");\r
+                tabSheet.setTabCaption(panel1, "This is a new tab caption "\r
+                        + new Date());\r
+            }\r
+        });\r
+\r
+        Button button2 = new Button("Update panel caption");\r
+        button2.addListener(new Button.ClickListener() {\r
+            public void buttonClick(ClickEvent event) {\r
+                panel1.setCaption("This is a new panel caption " + new Date());\r
             }\r
         });\r
 \r
         addComponent(tabSheet);\r
         addComponent(button);\r
+        addComponent(button2);\r
     }\r
 }\r
index f934cb06896da3db26f0610c47edc5b8171d6ed6..ecac170c3c1edf633347fc3fee79b361c5ca0356 100644 (file)
@@ -21,7 +21,8 @@ public class TabSheetDisabling extends TestBase {
                         new ClickListener() {\r
 \r
                             public void buttonClick(ClickEvent event) {\r
-                                event.getButton().setEnabled(false);\r
+                                Button b = event.getButton();\r
+                                tabSheet.getTab(b).setEnabled(false);\r
 \r
                             }\r
 \r
@@ -30,8 +31,8 @@ public class TabSheetDisabling extends TestBase {
                 buttons[i] = new Button("Hide this tab", new ClickListener() {\r
 \r
                     public void buttonClick(ClickEvent event) {\r
-                        event.getButton().setVisible(false);\r
-\r
+                        Button b = event.getButton();\r
+                        tabSheet.getTab(b).setVisible(false);\r
                     }\r
 \r
                 });\r
diff --git a/src/com/itmill/toolkit/tests/layouts/AbsoluteLayoutAddRemove.java b/src/com/itmill/toolkit/tests/layouts/AbsoluteLayoutAddRemove.java
new file mode 100644 (file)
index 0000000..14702a7
--- /dev/null
@@ -0,0 +1,50 @@
+package com.itmill.toolkit.tests.layouts;
+
+import com.itmill.toolkit.tests.components.TestBase;
+import com.itmill.toolkit.ui.AbsoluteLayout;
+import com.itmill.toolkit.ui.Button;
+import com.itmill.toolkit.ui.Label;
+import com.itmill.toolkit.ui.Layout;
+import com.itmill.toolkit.ui.Button.ClickEvent;
+
+public class AbsoluteLayoutAddRemove extends TestBase {
+
+    @Override
+    protected String getDescription() {
+        return "Tests that addComponent() and removeComponent() works";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 2915;
+    }
+
+    @Override
+    protected void setup() {
+        Layout main = getLayout();
+
+        final Label l = new Label("A Label");
+        final AbsoluteLayout al = new AbsoluteLayout();
+        al.setWidth("300px");
+        al.setHeight("200px");
+        main.addComponent(al);
+
+        final Button b = new Button("Add", new Button.ClickListener() {
+
+            public void buttonClick(ClickEvent event) {
+                if (l.getParent() == null) {
+                    al.addComponent(l);
+                    event.getButton().setCaption("Remove");
+                } else {
+                    al.removeComponent(l);
+                    event.getButton().setCaption("Add");
+                }
+
+            }
+
+        });
+        main.addComponent(b);
+
+    }
+
+}
index fd5e72aff6362d8ade7ff4a51b99b003624569f2..fbac344932ef5bf8ff140f47f972e8b5283c8032 100644 (file)
@@ -52,6 +52,7 @@ public class AbsoluteLayout extends AbstractLayout {
     public void removeComponent(Component c) {
         components.remove(c);
         super.removeComponent(c);
+        requestRepaint();
     }
 
     public void addComponent(Component c, String cssPosition) {
index 4a272ed1d1b5ab603a1480798c01e809939e0559..26d4d169635db2361957915bbd696a51751964b9 100644 (file)
@@ -372,8 +372,10 @@ public class Label extends AbstractComponent implements Property,
      *            the New content mode of the label.
      */
     public void setContentMode(int contentMode) {
-        if (contentMode >= CONTENT_TEXT && contentMode <= CONTENT_RAW) {
+        if (contentMode != this.contentMode && contentMode >= CONTENT_TEXT
+                && contentMode <= CONTENT_RAW) {
             this.contentMode = contentMode;
+            requestRepaint();
         }
     }
 
index 5d2e9ac57fb0007f04ee69d18a8c7f8034eabed2..510cf99d73d989d5156b6084a9736b526e2a6dda 100644 (file)
@@ -6,10 +6,12 @@ package com.itmill.toolkit.ui;
 
 import java.io.Serializable;
 import java.lang.reflect.Method;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Map;
 
+import com.itmill.toolkit.terminal.ErrorMessage;
 import com.itmill.toolkit.terminal.KeyMapper;
 import com.itmill.toolkit.terminal.PaintException;
 import com.itmill.toolkit.terminal.PaintTarget;
@@ -31,7 +33,12 @@ public class TabSheet extends AbstractComponentContainer implements
     /**
      * Linked list of component tabs.
      */
-    private final LinkedList tabs = new LinkedList();
+    private final LinkedList components = new LinkedList();
+
+    /**
+     * Map containing information related to the tabs (caption, icon etc).
+     */
+    private final HashMap<Component, Tab> tabs = new HashMap<Component, Tab>();
 
     /**
      * Selected tab.
@@ -64,7 +71,7 @@ public class TabSheet extends AbstractComponentContainer implements
      * @return the Iterator of the components inside the container.
      */
     public Iterator getComponentIterator() {
-        return java.util.Collections.unmodifiableList(tabs).iterator();
+        return java.util.Collections.unmodifiableList(components).iterator();
     }
 
     /**
@@ -75,15 +82,16 @@ public class TabSheet extends AbstractComponentContainer implements
      */
     @Override
     public void removeComponent(Component c) {
-        if (c != null && tabs.contains(c)) {
+        if (c != null && components.contains(c)) {
             super.removeComponent(c);
             keyMapper.remove(c);
+            components.remove(c);
             tabs.remove(c);
             if (c.equals(selected)) {
-                if (tabs.isEmpty()) {
+                if (components.isEmpty()) {
                     selected = null;
                 } else {
-                    selected = (Component) tabs.getFirst();
+                    selected = (Component) components.getFirst();
                     fireSelectedTabChange();
                 }
             }
@@ -114,16 +122,23 @@ public class TabSheet extends AbstractComponentContainer implements
      * @param icon
      *            the icon to be set for the component and used rendered in tab
      *            bar
+     * @return the created tab
      */
-    public void addTab(Component c, String caption, Resource icon) {
+    public Tab addTab(Component c, String caption, Resource icon) {
         if (c != null) {
-            if (caption != null) {
-                c.setCaption(caption);
-            }
-            if (icon != null) {
-                c.setIcon(icon);
+            components.addLast(c);
+            Tab tab = new TabSheetTabImpl(caption, icon);
+
+            tabs.put(c, tab);
+            if (selected == null) {
+                selected = c;
+                fireSelectedTabChange();
             }
-            addTab(c);
+            super.addComponent(c);
+            requestRepaint();
+            return tab;
+        } else {
+            return null;
         }
     }
 
@@ -133,17 +148,13 @@ public class TabSheet extends AbstractComponentContainer implements
      * 
      * @param c
      *            the component to be added onto tab.
+     * @return the created tab
      */
-    public void addTab(Component c) {
+    public Tab addTab(Component c) {
         if (c != null) {
-            tabs.addLast(c);
-            if (selected == null) {
-                selected = c;
-                fireSelectedTabChange();
-            }
-            super.addComponent(c);
-            requestRepaint();
+            return addTab(c, c.getCaption(), c.getIcon());
         }
+        return null;
     }
 
     /**
@@ -197,54 +208,70 @@ public class TabSheet extends AbstractComponentContainer implements
         target.startTag("tabs");
 
         for (final Iterator i = getComponentIterator(); i.hasNext();) {
-            final Component c = (Component) i.next();
+            final Component component = (Component) i.next();
+            Tab tab = tabs.get(component);
 
             /*
              * If we have no selection, if the current selection is invisible or
              * if the current selection is disabled (but the whole component is
              * not) we select this tab instead
              */
-            if (selected == null || !selected.isVisible()
-                    || (!selected.isEnabled() && isEnabled())) {
-                selected = c;
+            Tab selectedTabInfo = null;
+            if (selected != null) {
+                selectedTabInfo = tabs.get(selected);
+            }
+            if (selected == null || selectedTabInfo == null
+                    || !selectedTabInfo.isVisible()
+                    || !selectedTabInfo.isEnabled()) {
+
+                // The current selection is not valid so we need to change it
+                if (tab.isEnabled() && tab.isVisible()) {
+                    selected = component;
+                } else {
+                    /*
+                     * The current selection is not valid but this tab cannot be
+                     * selected either.
+                     */
+                    selected = null;
+                }
             }
             target.startTag("tab");
-            if (!c.isEnabled() && c.isVisible()) {
+            if (!tab.isEnabled() && tab.isVisible()) {
                 target.addAttribute("disabled", true);
             }
 
-            if (!c.isVisible()) {
+            if (!tab.isVisible()) {
                 target.addAttribute("hidden", true);
             }
 
-            final Resource icon = getTabIcon(c);
+            final Resource icon = tab.getIcon();
             if (icon != null) {
                 target.addAttribute("icon", icon);
             }
-            final String caption = getTabCaption(c);
+            final String caption = tab.getCaption();
             if (caption != null && caption.length() > 0) {
                 target.addAttribute("caption", caption);
             }
 
-            if (c instanceof AbstractComponent) {
-                AbstractComponent ac = (AbstractComponent) c;
-                if (ac.getDescription() != null) {
-                    target.addAttribute("description", ac.getDescription());
-                }
-                if (ac.getComponentError() != null) {
-                    ac.getComponentError().paint(target);
-                }
+            final String description = tab.getDescription();
+            if (description != null) {
+                target.addAttribute("description", description);
             }
 
-            target.addAttribute("key", keyMapper.key(c));
-            if (c.equals(selected)) {
+            final ErrorMessage componentError = tab.getComponentError();
+            if (componentError != null) {
+                componentError.paint(target);
+            }
+
+            target.addAttribute("key", keyMapper.key(component));
+            if (component.equals(selected)) {
                 target.addAttribute("selected", true);
-                c.paint(target);
-                paintedTabs.add(c);
-            } else if (paintedTabs.contains(c)) {
-                c.paint(target);
+                component.paint(target);
+                paintedTabs.add(component);
+            } else if (paintedTabs.contains(component)) {
+                component.paint(target);
             } else {
-                c.requestRepaintRequests();
+                component.requestRepaintRequests();
             }
             target.endTag("tab");
         }
@@ -281,12 +308,16 @@ public class TabSheet extends AbstractComponentContainer implements
      * 
      * @param c
      *            the component.
+     * @deprecated Use {@link #getTab(Component)} and {@link Tab#getCaption()}
+     *             instead.
      */
+    @Deprecated
     public String getTabCaption(Component c) {
-        if (c.getCaption() == null) {
+        Tab info = tabs.get(c);
+        if (info == null) {
             return "";
         } else {
-            return c.getCaption();
+            return info.getCaption();
         }
     }
 
@@ -297,10 +328,15 @@ public class TabSheet extends AbstractComponentContainer implements
      *            the component.
      * @param caption
      *            the caption to set.
+     * @deprecated Use {@link #getTab(Component)} and
+     *             {@link Tab#setCaption(String)} instead.
      */
+    @Deprecated
     public void setTabCaption(Component c, String caption) {
-        if (tabs.contains(c)) {
-            c.setCaption(caption);
+        Tab info = tabs.get(c);
+        if (info != null) {
+            info.setCaption(caption);
+            requestRepaint();
         }
     }
 
@@ -309,32 +345,59 @@ public class TabSheet extends AbstractComponentContainer implements
      * 
      * @param c
      *            the component.
+     * @deprecated Use {@link #getTab(Component)} and {@link Tab#getIcon()}
+     *             instead.
      */
+    @Deprecated
     public Resource getTabIcon(Component c) {
-        return c.getIcon();
+        Tab info = tabs.get(c);
+        if (info == null) {
+            return null;
+        } else {
+            return info.getIcon();
+        }
     }
 
     /**
-     * Sets overridden icon for given component.
+     * Sets icon for the given component.
      * 
      * Normally TabSheet uses icon from component
      * 
      * @param c
+     *            the component
      * @param icon
+     *            the icon to set
+     * @deprecated Use {@link #getTab(Component)} and
+     *             {@link Tab#setIcon(Resource)} instead.
      */
+    @Deprecated
     public void setTabIcon(Component c, Resource icon) {
-        if (tabs.contains(c)) {
-            c.setIcon(icon);
+        Tab info = tabs.get(c);
+        if (info != null) {
+            info.setIcon(icon);
+            requestRepaint();
         }
     }
 
+    /**
+     * Returns the Tab for the component. The Tab object can be used for setting
+     * caption,icon, etc for the tab.
+     * 
+     * @param c
+     *            the component
+     * @return
+     */
+    public Tab getTab(Component c) {
+        return tabs.get(c);
+    }
+
     /**
      * Sets the selected tab.
      * 
      * @param c
      */
     public void setSelectedTab(Component c) {
-        if (c != null && tabs.contains(c) && !selected.equals(c)) {
+        if (c != null && components.contains(c) && !selected.equals(c)) {
             selected = c;
             fireSelectedTabChange();
             requestRepaint();
@@ -372,17 +435,33 @@ public class TabSheet extends AbstractComponentContainer implements
             selected = newComponent;
         }
 
+        Tab newTab = tabs.get(newComponent);
+        Tab oldTab = tabs.get(oldComponent);
+
         // Gets the captions
-        final String oldCaption = getTabCaption(oldComponent);
-        final Resource oldIcon = getTabIcon(oldComponent);
-        final String newCaption = getTabCaption(newComponent);
-        final Resource newIcon = getTabIcon(newComponent);
+        String oldCaption = null;
+        Resource oldIcon = null;
+        String newCaption = null;
+        Resource newIcon = null;
+
+        if (oldTab != null) {
+            oldCaption = oldTab.getCaption();
+            oldIcon = oldTab.getIcon();
+        }
+
+        if (newTab != null) {
+            newCaption = newTab.getCaption();
+            newIcon = newTab.getIcon();
+        } else {
+            newCaption = newComponent.getCaption();
+            newIcon = newComponent.getIcon();
+        }
 
         // Gets the locations
         int oldLocation = -1;
         int newLocation = -1;
         int location = 0;
-        for (final Iterator i = tabs.iterator(); i.hasNext();) {
+        for (final Iterator i = components.iterator(); i.hasNext();) {
             final Component component = (Component) i.next();
 
             if (component == oldComponent) {
@@ -400,27 +479,34 @@ public class TabSheet extends AbstractComponentContainer implements
         } else if (newLocation == -1) {
             removeComponent(oldComponent);
             keyMapper.remove(oldComponent);
-            addComponent(newComponent);
-            tabs.remove(newComponent);
-            tabs.add(oldLocation, newComponent);
-            setTabCaption(newComponent, oldCaption);
-            setTabIcon(newComponent, oldIcon);
+            newTab = addTab(newComponent);
+            components.remove(newComponent);
+            components.add(oldLocation, newComponent);
+            newTab.setCaption(oldCaption);
+            newTab.setIcon(oldIcon);
         } else {
             if (oldLocation > newLocation) {
-                tabs.remove(oldComponent);
-                tabs.add(newLocation, oldComponent);
-                tabs.remove(newComponent);
-                tabs.add(oldLocation, newComponent);
+                components.remove(oldComponent);
+                components.add(newLocation, oldComponent);
+                components.remove(newComponent);
+                components.add(oldLocation, newComponent);
             } else {
-                tabs.remove(newComponent);
-                tabs.add(oldLocation, newComponent);
-                tabs.remove(oldComponent);
-                tabs.add(newLocation, oldComponent);
+                components.remove(newComponent);
+                components.add(oldLocation, newComponent);
+                components.remove(oldComponent);
+                components.add(newLocation, oldComponent);
+            }
+
+            if (newTab != null) {
+                // This should always be true
+                newTab.setCaption(oldCaption);
+                newTab.setIcon(oldIcon);
+            }
+            if (oldTab != null) {
+                // This should always be true
+                oldTab.setCaption(newCaption);
+                oldTab.setIcon(newIcon);
             }
-            setTabCaption(newComponent, oldCaption);
-            setTabIcon(newComponent, oldIcon);
-            setTabCaption(oldComponent, newCaption);
-            setTabIcon(oldComponent, newIcon);
 
             requestRepaint();
         }
@@ -538,4 +624,167 @@ public class TabSheet extends AbstractComponentContainer implements
         paintedTabs.clear();
     }
 
+    /**
+     *
+     */
+    public interface Tab extends Serializable {
+        /**
+         * Returns the visible status for the tab.
+         * 
+         * @return true for visible, false for hidden
+         */
+        public boolean isVisible();
+
+        /**
+         * Sets the visible status for the tab.
+         * 
+         * @param visible
+         *            true for visible, false for hidden
+         */
+        public void setVisible(boolean visible);
+
+        /**
+         * Returns the enabled status for the tab.
+         * 
+         * @return true for enabled, false for disabled
+         */
+        public boolean isEnabled();
+
+        /**
+         * Sets the enabled status for the tab.
+         * 
+         * @param enabled
+         *            true for enabled, false for disabled
+         */
+        public void setEnabled(boolean enabled);
+
+        /**
+         * Sets the caption for the tab.
+         * 
+         * @param caption
+         *            the caption to set
+         */
+        public void setCaption(String caption);
+
+        /**
+         * Gets the caption for the tab.
+         * 
+         */
+        public String getCaption();
+
+        /**
+         * Gets the icon for the tab.
+         * 
+         */
+        public Resource getIcon();
+
+        /**
+         * Sets the icon for the tab.
+         * 
+         * @param icon
+         *            the icon to set
+         */
+        public void setIcon(Resource icon);
+
+        /**
+         * Gets the description for the tab. The description can be used to
+         * briefly describe the state of the tab to the user.
+         * 
+         * @return the description for the tab
+         */
+        public String getDescription();
+
+        /**
+         * Sets the description for the tab.
+         * 
+         * @param description
+         *            the new description string for the tab.
+         */
+        public void setDescription(String description);
+
+        public void setComponentError(ErrorMessage componentError);
+
+        public ErrorMessage getComponentError();
+
+    }
+
+    /**
+     * TabSheet's implementation of Tab
+     * 
+     */
+    public class TabSheetTabImpl implements Tab {
+
+        private String caption = "";
+        private Resource icon = null;
+        private boolean enabled = true;
+        private boolean visible = true;
+        private String description = null;
+        private ErrorMessage componentError = null;
+
+        public TabSheetTabImpl(String caption, Resource icon) {
+            if (caption == null) {
+                caption = "";
+            }
+            this.caption = caption;
+            this.icon = icon;
+        }
+
+        /**
+         * Returns the tab caption. Can never be null.
+         */
+        public String getCaption() {
+            return caption;
+        }
+
+        public void setCaption(String caption) {
+            this.caption = caption;
+            requestRepaint();
+        }
+
+        public Resource getIcon() {
+            return icon;
+        }
+
+        public void setIcon(Resource icon) {
+            this.icon = icon;
+            requestRepaint();
+        }
+
+        public boolean isEnabled() {
+            return enabled;
+        }
+
+        public void setEnabled(boolean enabled) {
+            this.enabled = enabled;
+            requestRepaint();
+        }
+
+        public boolean isVisible() {
+            return visible;
+        }
+
+        public void setVisible(boolean visible) {
+            this.visible = visible;
+            requestRepaint();
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        public void setDescription(String description) {
+            this.description = description;
+            requestRepaint();
+        }
+
+        public ErrorMessage getComponentError() {
+            return componentError;
+        }
+
+        public void setComponentError(ErrorMessage componentError) {
+            this.componentError = componentError;
+            requestRepaint();
+        }
+
+    }
 }