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
34    public Widget getWidget() {
35        return htmlPanel;
36    }
37
38    public void attachToDocument() {
39        title = Document.get().getElementById(getElementId()).getAttribute("title");
40        htmlPanel = Utils.divToPanel(getElementId());
41    }
42
43    public void addWidget(Widget widget, String subElementId) {
44        htmlPanel.add(widget, subElementId);
45    }
46
47    public Element getElementById(String subElementId) {
48        return htmlPanel.getElementById(subElementId);
49    }
50
51    // for subclasses to override
52    public void initialize() {}
53
54    public void ensureInitialized() {
55        if (!initialized) {
56            initialize();
57            initialized = true;
58        }
59    }
60
61    // for subclasses to override
62    public void refresh() {}
63
64    public void display() {
65        ensureInitialized();
66        refresh();
67        visible = true;
68    }
69
70    public void hide() {
71        visible = false;
72    }
73
74    public boolean isTabVisible() {
75        return visible;
76    }
77
78    public String getTitle() {
79        return title;
80    }
81
82    public void updateHistory() {
83        CustomHistory.newItem(getHistoryArguments());
84    }
85
86    /**
87     * Subclasses should override this to store any additional history information.
88     */
89    public HistoryToken getHistoryArguments() {
90        HistoryToken arguments = new HistoryToken();
91        arguments.put("tab_id", getElementId());
92        return arguments;
93    }
94
95    /**
96     * Subclasses should override this to actually handle the tokens.
97     * Should *not* trigger a refresh.  refresh() will be called separately.
98     *
99     * @param arguments the parsed history arguments to use
100     */
101    public void handleHistoryArguments(Map<String, String> arguments) {}
102
103    public abstract String getElementId();
104
105    protected void saveHistoryState() {
106        savedState = getHistoryArguments();
107    }
108
109    protected void restoreHistoryState() {
110        handleHistoryArguments(savedState);
111    }
112
113    protected void openHistoryToken(HistoryToken historyToken) {
114        if (isOpenInNewWindowEvent()) {
115            String newUrl = Window.Location.getPath() + "#" + historyToken;
116            Utils.openUrlInNewWindow(URL.encode(newUrl));
117        } else {
118            History.newItem(historyToken.toString());
119        }
120    }
121
122    private static boolean isOpenInNewWindowEvent() {
123        Event event = Event.getCurrentEvent();
124        boolean middleMouseButton = (event.getButton() & Event.BUTTON_MIDDLE) != 0;
125        // allow control-click on windows or command-click on macs (control-click is overridden
126        // on macs to take the place of right-click)
127        return event.getCtrlKey() || event.getMetaKey() || middleMouseButton;
128    }
129
130    public boolean isAutorefreshOn() {
131        return autorefresh;
132    }
133
134    public void setAutorefresh(boolean autorefresh) {
135        this.autorefresh = autorefresh;
136    }
137}
138