1package autotest.tko;
2
3import com.google.gwt.event.dom.client.ChangeEvent;
4import com.google.gwt.event.dom.client.ChangeHandler;
5import com.google.gwt.event.dom.client.ClickEvent;
6import com.google.gwt.event.dom.client.ClickHandler;
7import com.google.gwt.event.logical.shared.CloseEvent;
8import com.google.gwt.event.logical.shared.CloseHandler;
9import com.google.gwt.event.logical.shared.OpenEvent;
10import com.google.gwt.event.logical.shared.OpenHandler;
11import com.google.gwt.user.client.DOM;
12import com.google.gwt.user.client.Window;
13import com.google.gwt.user.client.ui.Anchor;
14import com.google.gwt.user.client.ui.Button;
15import com.google.gwt.user.client.ui.Composite;
16import com.google.gwt.user.client.ui.DisclosurePanel;
17import com.google.gwt.user.client.ui.HorizontalPanel;
18import com.google.gwt.user.client.ui.Panel;
19import com.google.gwt.user.client.ui.TextArea;
20
21import java.util.ArrayList;
22import java.util.Map;
23
24// TODO(showard): combine this code with similar code from autotest.afe.CreateJobView
25public class FilterStringViewer extends Composite {
26
27    public static final String VIEW_FILTER_STRING = "View Filter String";
28    public static final String HIDE_FILTER_STRING = "Hide Filter String";
29    public static final String EDIT_FILTER_STRING = "Edit Filter String";
30    public static final String UNEDIT_FILTER_STRING = "Revert Filter String";
31
32    public static interface EditListener {
33        public void onEdit();
34        public void onRevert();
35    }
36
37    private Anchor view = new Anchor(VIEW_FILTER_STRING);
38    private Button edit = new Button(EDIT_FILTER_STRING);
39    private TextArea queries = new TextArea();
40    private DisclosurePanel queriesPanel = new DisclosurePanel();
41    private boolean filterEdited = false;
42    private boolean viewerEditable = false;
43    private ArrayList<EditListener> listeners = new ArrayList<EditListener>();
44
45    public FilterStringViewer() {
46        edit.addClickHandler(new ClickHandler() {
47            public void onClick(ClickEvent event) {
48                changeEditable(true);
49            }
50        });
51
52        queries.setSize("35em", "10em");
53        queries.setReadOnly(true);
54        queries.addChangeHandler(new ChangeHandler() {
55            public void onChange(ChangeEvent event) {
56                filterEdited = true;
57            }
58        });
59
60        Panel viewerHeaderPanel = new HorizontalPanel();
61        viewerHeaderPanel.add(view);
62        viewerHeaderPanel.add(edit);
63
64        queriesPanel.setHeader(viewerHeaderPanel);
65        queriesPanel.add(queries);
66
67        queriesPanel.addCloseHandler(new CloseHandler<DisclosurePanel>() {
68            public void onClose(CloseEvent<DisclosurePanel> e) {
69                view.setText(VIEW_FILTER_STRING);
70            }
71        });
72        queriesPanel.addOpenHandler(new OpenHandler<DisclosurePanel>() {
73            public void onOpen(OpenEvent<DisclosurePanel> e) {
74                view.setText(HIDE_FILTER_STRING);
75            }
76        });
77
78        initWidget(queriesPanel);
79    }
80
81    public void setText(String text) {
82        queries.setText(text);
83    }
84
85    public String getText() {
86        return queries.getText();
87    }
88
89    public void addEditListener(EditListener listener) {
90        listeners.add(listener);
91    }
92
93    protected void addToHistory(Map<String, String> args, String prefix) {
94        args.put(prefix + "_viewerOpen", String.valueOf(queriesPanel.isOpen()));
95        args.put(prefix + "_viewerEditable", String.valueOf(viewerEditable));
96        if (viewerEditable) {
97            args.put(prefix + "_viewerEdited", String.valueOf(filterEdited));
98            if (filterEdited) {
99                args.put(prefix + "_viewerText", queries.getText());
100            }
101        }
102    }
103
104    protected void handleHistoryArguments(Map<String, String> args, String prefix) {
105        // No _viewerOpen parameter. This is a preconfig without a specified custom filter.
106        if (args.get(prefix + "_viewerOpen") == null) {
107            queriesPanel.setOpen(false);
108            if (viewerEditable) {
109                changeEditable(false);
110            }
111            return;
112        }
113
114        queriesPanel.setOpen(Boolean.parseBoolean(args.get(prefix + "_viewerOpen")));
115        if (viewerEditable) {
116            changeEditable(false);
117        }
118        if (Boolean.parseBoolean(args.get(prefix + "_viewerEditable"))) {
119            changeEditable(false);
120            filterEdited = Boolean.parseBoolean(args.get(prefix + "_viewerEdited"));
121            if (filterEdited) {
122                queries.setText(args.get(prefix + "_viewerText"));
123            }
124        }
125    }
126
127    // Change the viewer's editable state
128    private void changeEditable(boolean clicked) {
129        if (clicked) {
130            DOM.eventGetCurrentEvent().stopPropagation();
131        }
132
133        if (viewerEditable) {
134            // We only want the confirmation on revert from an edited viewer, and only if "revert"
135            // was clicked (not on programmatic revert)
136            boolean userCancelled = filterEdited && clicked
137                && !Window.confirm("Are you sure you want to revert your changes?");
138            if (userCancelled) {
139                return;
140            }
141
142            viewerEditable = false;
143            filterEdited = false;
144            queries.setReadOnly(true);
145            edit.setText(EDIT_FILTER_STRING);
146            for (EditListener listener : listeners) {
147                listener.onRevert();
148            }
149        } else {
150            viewerEditable = true;
151            queries.setReadOnly(false);
152            edit.setText(UNEDIT_FILTER_STRING);
153            queriesPanel.setOpen(true);
154            for (EditListener listener : listeners) {
155                listener.onEdit();
156            }
157        }
158    }
159}
160