TabView.java revision ed09d8e93668acfbe638d5a8c07879466ca82de6
1package autotest.common.ui;
2
3import autotest.common.CustomHistory;
4import autotest.common.Utils;
5import autotest.common.CustomHistory.HistoryToken;
6
7import com.google.gwt.dom.client.Document;
8import com.google.gwt.dom.client.Element;
9import com.google.gwt.http.client.URL;
10import com.google.gwt.user.client.Event;
11import com.google.gwt.user.client.History;
12import com.google.gwt.user.client.Window;
13import com.google.gwt.user.client.ui.HTMLPanel;
14import com.google.gwt.user.client.ui.Widget;
15
16import java.util.Map;
17
18/**
19 * A widget to facilitate building a tab panel from elements present in the
20 * static HTML document.  Each <code>TabView</code> grabs a certain HTML
21 * element, removes it from the document, and wraps it.  It can then be added
22 * to a TabPanel.  The <code>getTitle()</code> method retrieves a title for the
23 * tab from the "title" attribute of the HTML element.  This class also supports
24 * lazy initialization of the tab by waiting until the tab is first displayed.
25 */
26public abstract class TabView implements HasTabVisible {
27    private boolean initialized = false;
28    private HTMLPanel htmlPanel;
29    private String title;
30    protected boolean visible;
31    private Map<String, String> savedState;
32    protected boolean autorefresh = false;
33    private boolean autorefreshEnabled = true;
34
35    public Widget getWidget() {
36        return htmlPanel;
37    }
38
39    public void attachToDocument() {
40        title = Document.get().getElementById(getElementId()).getAttribute("title");
41        htmlPanel = Utils.divToPanel(getElementId());
42    }
43
44    public void addWidget(Widget widget, String subElementId) {
45        htmlPanel.add(widget, subElementId);
46    }
47
48    public Element getElementById(String subElementId) {
49        return htmlPanel.getElementById(subElementId);
50    }
51
52    // for subclasses to override
53    public void initialize() {}
54
55    public void ensureInitialized() {
56        if (!initialized) {
57            initialize();
58            initialized = true;
59        }
60    }
61
62    // for subclasses to override
63    public void refresh() {}
64
65    public void display() {
66        ensureInitialized();
67        refresh();
68        visible = true;
69    }
70
71    public void hide() {
72        visible = false;
73    }
74
75    public boolean isTabVisible() {
76        return visible;
77    }
78
79    public String getTitle() {
80        return title;
81    }
82
83    public void updateHistory() {
84        CustomHistory.newItem(getHistoryArguments());
85    }
86
87    /**
88     * Subclasses should override this to store any additional history information.
89     */
90    public HistoryToken getHistoryArguments() {
91        HistoryToken arguments = new HistoryToken();
92        arguments.put("tab_id", getElementId());
93        return arguments;
94    }
95
96    /**
97     * Subclasses should override this to actually handle the tokens.
98     * Should *not* trigger a refresh.  refresh() will be called separately.
99     *
100     * @param arguments the parsed history arguments to use
101     */
102    public void handleHistoryArguments(Map<String, String> arguments) {}
103
104    public abstract String getElementId();
105
106    protected void saveHistoryState() {
107        savedState = getHistoryArguments();
108    }
109
110    protected void restoreHistoryState() {
111        handleHistoryArguments(savedState);
112    }
113
114    protected void openHistoryToken(HistoryToken historyToken) {
115        if (isOpenInNewWindowEvent()) {
116            String newUrl = Window.Location.getPath() + "#" + historyToken;
117            Utils.openUrlInNewWindow(URL.encode(newUrl));
118        } else {
119            History.newItem(historyToken.toString());
120        }
121    }
122
123    private static boolean isOpenInNewWindowEvent() {
124        Event event = Event.getCurrentEvent();
125        boolean middleMouseButton = (event.getButton() & Event.BUTTON_MIDDLE) != 0;
126        // allow control-click on windows or command-click on macs (control-click is overridden
127        // on macs to take the place of right-click)
128        return event.getCtrlKey() || event.getMetaKey() || middleMouseButton;
129    }
130
131    public boolean isAutorefreshEnabled() {
132      return autorefreshEnabled;
133    }
134
135    public void setAutorefreshEnabled(boolean autorefreshEnabled) {
136      this.autorefreshEnabled = autorefreshEnabled;
137    }
138
139    public boolean isAutorefreshOn() {
140        return autorefresh;
141    }
142
143    public void setAutorefresh(boolean autorefresh) {
144        this.autorefresh = autorefresh;
145    }
146}
147