1package autotest.tko;
2
3import autotest.common.CustomHistory;
4import autotest.common.JSONArrayList;
5import autotest.common.JsonRpcCallback;
6import autotest.common.JsonRpcProxy;
7import autotest.common.StaticDataRepository;
8import autotest.common.CustomHistory.CustomHistoryListener;
9import autotest.common.CustomHistory.HistoryToken;
10import autotest.common.ui.NotifyManager;
11
12import com.google.gwt.event.dom.client.ChangeEvent;
13import com.google.gwt.event.dom.client.ChangeHandler;
14import com.google.gwt.event.dom.client.ClickEvent;
15import com.google.gwt.event.dom.client.ClickHandler;
16import com.google.gwt.json.client.JSONArray;
17import com.google.gwt.json.client.JSONNumber;
18import com.google.gwt.json.client.JSONObject;
19import com.google.gwt.json.client.JSONString;
20import com.google.gwt.json.client.JSONValue;
21import com.google.gwt.user.client.History;
22import com.google.gwt.user.client.ui.Button;
23import com.google.gwt.user.client.ui.Composite;
24import com.google.gwt.user.client.ui.DialogBox;
25import com.google.gwt.user.client.ui.HorizontalPanel;
26import com.google.gwt.user.client.ui.Label;
27import com.google.gwt.user.client.ui.ListBox;
28import com.google.gwt.user.client.ui.Panel;
29import com.google.gwt.user.client.ui.TextBox;
30import com.google.gwt.user.client.ui.VerticalPanel;
31import com.google.gwt.user.client.ui.Widget;
32
33import java.util.Map;
34
35class SavedQueriesControl extends Composite
36                          implements ChangeHandler, ClickHandler, CustomHistoryListener {
37    public static final String HISTORY_TOKEN = "saved_query";
38
39    private static final String ADD_QUERY = "Save current...";
40    private static final String DELETE_QUERY = "Delete query...";
41    private static final String DEFAULT_ITEM = "Saved queries...";
42
43    private static JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy();
44    private static NotifyManager notifyManager = NotifyManager.getInstance();
45
46    private ListBox queryList = new ListBox();
47    private QueryActionDialog<TextBox> addQueryDialog;
48    private QueryActionDialog<ListBox> deleteQueryDialog;
49
50    private static class QueryActionDialog<T extends Widget> extends DialogBox {
51        public T widget;
52        public Button actionButton, cancelButton;
53
54        public QueryActionDialog(T widget, String widgetString, String actionString) {
55            super(false, true);
56            this.widget = widget;
57            Panel dialogPanel = new VerticalPanel();
58            Panel widgetPanel = new HorizontalPanel();
59            widgetPanel.add(new Label(widgetString));
60            widgetPanel.add(widget);
61            dialogPanel.add(widgetPanel);
62
63            Panel buttonPanel = new HorizontalPanel();
64            actionButton = new Button(actionString);
65            cancelButton = new Button("Cancel");
66            buttonPanel.add(actionButton);
67            buttonPanel.add(cancelButton);
68            dialogPanel.add(buttonPanel);
69            add(dialogPanel);
70
71            cancelButton.addClickHandler(new ClickHandler() {
72                public void onClick(ClickEvent event) {
73                    hide();
74                }
75            });
76        }
77    }
78
79    public SavedQueriesControl() {
80        queryList.addChangeHandler(this);
81        populateMainList();
82        initWidget(queryList);
83
84        addQueryDialog = new QueryActionDialog<TextBox>(new TextBox(),
85                                                        "Enter query name:", "Save query");
86        addQueryDialog.actionButton.addClickHandler(this);
87        deleteQueryDialog = new QueryActionDialog<ListBox>(new ListBox(),
88                                                           "Select query:", "Delete query");
89        deleteQueryDialog.actionButton.addClickHandler(this);
90
91        CustomHistory.addHistoryListener(this);
92    }
93
94    private void populateMainList() {
95        queryList.clear();
96        queryList.addItem(DEFAULT_ITEM);
97        queryList.addItem(ADD_QUERY);
98        queryList.addItem(DELETE_QUERY);
99        fillQueryList(queryList);
100    }
101
102    private void fillQueryList(final ListBox list) {
103        StaticDataRepository staticData = StaticDataRepository.getRepository();
104        JSONObject args = new JSONObject();
105        args.put("owner", new JSONString(staticData.getCurrentUserLogin()));
106        rpcProxy.rpcCall("get_saved_queries", args, new JsonRpcCallback() {
107            @Override
108            public void onSuccess(JSONValue result) {
109                for (JSONObject query : new JSONArrayList<JSONObject>(result.isArray())) {
110                    int id = (int) query.get("id").isNumber().doubleValue();
111                    list.addItem(query.get("name").isString().stringValue(),
112                                 Integer.toString(id));
113                }
114            }
115        });
116    }
117
118    @Override
119    public void onChange(ChangeEvent event) {
120        int selected = queryList.getSelectedIndex();
121        queryList.setSelectedIndex(0); // set it back to the default
122
123        String queryName = queryList.getItemText(selected);
124        if (queryName.equals(DEFAULT_ITEM)) {
125            return;
126        }
127        if (queryName.equals(ADD_QUERY)) {
128            addQueryDialog.widget.setText("");
129            addQueryDialog.center();
130            addQueryDialog.widget.setFocus(true);
131            return;
132        }
133        if (queryName.equals(DELETE_QUERY)) {
134            deleteQueryDialog.widget.clear();
135            fillQueryList(deleteQueryDialog.widget);
136            deleteQueryDialog.center();
137            return;
138        }
139
140        String idString = queryList.getValue(selected);
141        // don't use CustomHistory, since we want the token to be processed
142        History.newItem(HISTORY_TOKEN + "=" + idString);
143    }
144
145    public void onClick(ClickEvent event) {
146        if (event.getSource() == addQueryDialog.actionButton) {
147            addQueryDialog.hide();
148            JSONObject args = new JSONObject();
149            args.put("name", new JSONString(addQueryDialog.widget.getText()));
150            args.put("url_token", new JSONString(CustomHistory.getLastHistoryToken().toString()));
151            rpcProxy.rpcCall("add_saved_query", args, new JsonRpcCallback() {
152                @Override
153                public void onSuccess(JSONValue result) {
154                    notifyManager.showMessage("Query saved");
155                    populateMainList();
156                }
157            });
158        } else {
159            assert event.getSource() == deleteQueryDialog.actionButton;
160            deleteQueryDialog.hide();
161            String idString =
162                deleteQueryDialog.widget.getValue(deleteQueryDialog.widget.getSelectedIndex());
163            JSONObject args = new JSONObject();
164            JSONArray ids = new JSONArray();
165            ids.set(0, new JSONNumber(Integer.parseInt(idString)));
166            args.put("id_list", ids);
167            rpcProxy.rpcCall("delete_saved_queries", args, new JsonRpcCallback() {
168                @Override
169                public void onSuccess(JSONValue result) {
170                    notifyManager.showMessage("Query deleted");
171                    populateMainList();
172                }
173            });
174        }
175    }
176
177    public void onHistoryChanged(Map<String, String> arguments) {
178        final String idString = arguments.get(HISTORY_TOKEN);
179        if (idString == null) {
180            return;
181        }
182
183        JSONObject args = new JSONObject();
184        args.put("id", new JSONNumber(Integer.parseInt(idString)));
185        rpcProxy.rpcCall("get_saved_queries", args, new JsonRpcCallback() {
186            @Override
187            public void onSuccess(JSONValue result) {
188                JSONArray queries = result.isArray();
189                if (queries.size() == 0) {
190                    notifyManager.showError("No saved query with ID " + idString);
191                    return;
192                }
193
194                assert queries.size() == 1;
195                JSONObject query = queries.get(0).isObject();
196                int queryId = (int) query.get("id").isNumber().doubleValue();
197                String tokenString = query.get("url_token").isString().stringValue();
198                HistoryToken token;
199                try {
200                    token = HistoryToken.fromString(tokenString);
201                } catch (IllegalArgumentException exc) {
202                    NotifyManager.getInstance().showError("Invalid saved query token " +
203                                                          tokenString);
204                    return;
205                }
206
207                // since this is happening asynchronously, the history may have changed, so ensure
208                // it's set back to what it should be.
209                HistoryToken shortToken = new HistoryToken();
210                shortToken.put(HISTORY_TOKEN, Integer.toString(queryId));
211                CustomHistory.newItem(shortToken);
212
213                CustomHistory.simulateHistoryToken(token);
214            }
215        });
216    }
217}
218