SpreadsheetView.java revision 227a7a1d0484dcfa4c6d996a1c10e95437d059ef
135444864c7b6f49865a7e17aa0052987b72e4728showardpackage autotest.tko;
235444864c7b6f49865a7e17aa0052987b72e4728showard
335444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.common.JsonRpcCallback;
435444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.common.JsonRpcProxy;
535444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.common.Utils;
6c674d3ea684f75f3e05f5834b598050eb1c8856dshowardimport autotest.common.CustomHistory.HistoryToken;
735444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.common.ui.ContextMenu;
835444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.common.ui.NotifyManager;
935444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.common.ui.RightClickTable;
1035444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.common.ui.SimpleHyperlink;
1135444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.common.ui.TableActionsPanel;
123d6ae118f69717e68bc15b9aed7b6a6c7dd9bab0showardimport autotest.common.ui.TableActionsPanel.TableActionsWithExportCsvListener;
139dbdcda5104991cbf344ea5cba1aa58e1af444f3showardimport autotest.common.ui.TableSelectionPanel.SelectionPanelListener;
140c31bc5ef2ecdf8edf19468e1a373520110f5bc6showardimport autotest.tko.CommonPanel.CommonPanelListener;
1535444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.tko.Spreadsheet.CellInfo;
1635444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.tko.Spreadsheet.Header;
1735444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.tko.Spreadsheet.SpreadsheetListener;
18ce12f55f4530950f7fc6ddc73d1867ebb954d356showardimport autotest.tko.TableView.TableSwitchListener;
19ce12f55f4530950f7fc6ddc73d1867ebb954d356showardimport autotest.tko.TableView.TableViewConfig;
2035444864c7b6f49865a7e17aa0052987b72e4728showard
21a5e4d84c9616b0a987e904d3b1d1d3fd9ca1be86showardimport com.google.gwt.event.dom.client.ClickEvent;
22a5e4d84c9616b0a987e904d3b1d1d3fd9ca1be86showardimport com.google.gwt.event.dom.client.ClickHandler;
2379a7b0d387aac103fc1d125353eefa361030452ashowardimport com.google.gwt.event.logical.shared.ResizeEvent;
2479a7b0d387aac103fc1d125353eefa361030452ashowardimport com.google.gwt.event.logical.shared.ResizeHandler;
250d92da0fe19a095fc5678c4159e6a1756df65e48showardimport com.google.gwt.event.logical.shared.ValueChangeEvent;
260d92da0fe19a095fc5678c4159e6a1756df65e48showardimport com.google.gwt.event.logical.shared.ValueChangeHandler;
2735444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.json.client.JSONArray;
2835444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.json.client.JSONObject;
29d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshowardimport com.google.gwt.json.client.JSONString;
3035444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.json.client.JSONValue;
3135444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.user.client.Command;
3235444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.user.client.Event;
33c674d3ea684f75f3e05f5834b598050eb1c8856dshowardimport com.google.gwt.user.client.History;
3435444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.user.client.Window;
3535444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.user.client.ui.Button;
3635444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.user.client.ui.CheckBox;
3735444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.user.client.ui.HTML;
3835444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.user.client.ui.MenuBar;
398a6eb0cf5777dded2354408e8007d9223e813c92showardimport com.google.gwt.user.client.ui.Panel;
409e494cc00c53f9dd0fabec3ef675cb874a9130adshowardimport com.google.gwt.user.client.ui.SimplePanel;
418a6eb0cf5777dded2354408e8007d9223e813c92showardimport com.google.gwt.user.client.ui.VerticalPanel;
4235444864c7b6f49865a7e17aa0052987b72e4728showard
4335444864c7b6f49865a7e17aa0052987b72e4728showardimport java.util.HashMap;
4435444864c7b6f49865a7e17aa0052987b72e4728showardimport java.util.List;
4535444864c7b6f49865a7e17aa0052987b72e4728showardimport java.util.Map;
4635444864c7b6f49865a7e17aa0052987b72e4728showard
4735444864c7b6f49865a7e17aa0052987b72e4728showardpublic class SpreadsheetView extends ConditionTabView
483d6ae118f69717e68bc15b9aed7b6a6c7dd9bab0showard                             implements SpreadsheetListener, TableActionsWithExportCsvListener,
499dbdcda5104991cbf344ea5cba1aa58e1af444f3showard                                        CommonPanelListener, SelectionPanelListener {
508a6eb0cf5777dded2354408e8007d9223e813c92showard    private static final String HISTORY_ONLY_LATEST = "show_only_latest";
5135444864c7b6f49865a7e17aa0052987b72e4728showard    public static final String DEFAULT_ROW = "kernel";
5235444864c7b6f49865a7e17aa0052987b72e4728showard    public static final String DEFAULT_COLUMN = "platform";
53e463a8a926964673c2517bfef5ac394206b106c6showard    public static final String DEFAULT_DRILLDOWN = "job_tag";
5435444864c7b6f49865a7e17aa0052987b72e4728showard
558c9b839c2f5073a755952a8a865a04db3b2d4547showard    private static final String HISTORY_SHOW_INCOMPLETE = "show_incomplete";
568c9b839c2f5073a755952a8a865a04db3b2d4547showard    private static final String HISTORY_COLUMN = "column";
578c9b839c2f5073a755952a8a865a04db3b2d4547showard    private static final String HISTORY_ROW = "row";
58194a59d6976a5dbd5b464fb2b14ceb089f91c050showard    private static final String HISTORY_CONTENT = "content";
598c9b839c2f5073a755952a8a865a04db3b2d4547showard
6035444864c7b6f49865a7e17aa0052987b72e4728showard    private static enum DrilldownType {DRILLDOWN_ROW, DRILLDOWN_COLUMN, DRILLDOWN_BOTH}
6135444864c7b6f49865a7e17aa0052987b72e4728showard
6235444864c7b6f49865a7e17aa0052987b72e4728showard    private static JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy();
63e732ee7d450b11261c82df0950fde8e02f839b26showard    private static JsonRpcProxy afeRpcProxy = JsonRpcProxy.getProxy(JsonRpcProxy.AFE_BASE_URL);
64ce12f55f4530950f7fc6ddc73d1867ebb954d356showard    private TableSwitchListener listener;
6535444864c7b6f49865a7e17aa0052987b72e4728showard    protected Map<String,String[]> drilldownMap = new HashMap<String,String[]>();
66227a7a1d0484dcfa4c6d996a1c10e95437d059efshoward    private HeaderFieldCollection headerFields = new HeaderFieldCollection();
6735444864c7b6f49865a7e17aa0052987b72e4728showard
68227a7a1d0484dcfa4c6d996a1c10e95437d059efshoward    private HeaderSelect rowSelect = new HeaderSelect(headerFields);
69d9e04c1a7950691cc348e70fa2470f8c414ae94fshoward    private HeaderSelectorView rowSelectDisplay = new HeaderSelectorView();
70227a7a1d0484dcfa4c6d996a1c10e95437d059efshoward    private HeaderSelect columnSelect = new HeaderSelect(headerFields);
71d9e04c1a7950691cc348e70fa2470f8c414ae94fshoward    private HeaderSelectorView columnSelectDisplay = new HeaderSelectorView();
7277401f351bd4ef6b6af99e46a9f905b161062574showard    private ContentSelect contentSelect = new ContentSelect();
73d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward    private CheckBox showIncomplete = new CheckBox("Show incomplete tests");
748a6eb0cf5777dded2354408e8007d9223e813c92showard    private CheckBox showOnlyLatest = new CheckBox("Show only latest test per cell");
7535444864c7b6f49865a7e17aa0052987b72e4728showard    private Button queryButton = new Button("Query");
768a6eb0cf5777dded2354408e8007d9223e813c92showard    private TestGroupDataSource normalDataSource = TestGroupDataSource.getStatusCountDataSource();
778a6eb0cf5777dded2354408e8007d9223e813c92showard    private TestGroupDataSource latestDataSource = TestGroupDataSource.getLatestTestsDataSource();
7835444864c7b6f49865a7e17aa0052987b72e4728showard    private Spreadsheet spreadsheet = new Spreadsheet();
7935444864c7b6f49865a7e17aa0052987b72e4728showard    private SpreadsheetDataProcessor spreadsheetProcessor =
808a6eb0cf5777dded2354408e8007d9223e813c92showard        new SpreadsheetDataProcessor(spreadsheet);
8135444864c7b6f49865a7e17aa0052987b72e4728showard    private SpreadsheetSelectionManager selectionManager =
8235444864c7b6f49865a7e17aa0052987b72e4728showard        new SpreadsheetSelectionManager(spreadsheet, null);
839dbdcda5104991cbf344ea5cba1aa58e1af444f3showard    private TableActionsPanel actionsPanel = new TableActionsPanel(false);
849e494cc00c53f9dd0fabec3ef675cb874a9130adshoward    private Panel jobCompletionPanel = new SimplePanel();
85313ab769319f56b940a2784cc0cbdebd005c5799showard    private boolean currentShowIncomplete, currentShowOnlyLatest;
8635444864c7b6f49865a7e17aa0052987b72e4728showard    private boolean notYetQueried = true;
87ce12f55f4530950f7fc6ddc73d1867ebb954d356showard    public SpreadsheetView(TableSwitchListener listener) {
8835444864c7b6f49865a7e17aa0052987b72e4728showard        this.listener = listener;
890c31bc5ef2ecdf8edf19468e1a373520110f5bc6showard        commonPanel.addListener(this);
9035444864c7b6f49865a7e17aa0052987b72e4728showard    }
9135444864c7b6f49865a7e17aa0052987b72e4728showard
9235444864c7b6f49865a7e17aa0052987b72e4728showard    @Override
9335444864c7b6f49865a7e17aa0052987b72e4728showard    public String getElementId() {
9435444864c7b6f49865a7e17aa0052987b72e4728showard        return "spreadsheet_view";
9535444864c7b6f49865a7e17aa0052987b72e4728showard    }
9635444864c7b6f49865a7e17aa0052987b72e4728showard
9735444864c7b6f49865a7e17aa0052987b72e4728showard    @Override
9835444864c7b6f49865a7e17aa0052987b72e4728showard    public void initialize() {
999f4500a294eea35dce003cee41c558fcde3eb09fshoward        super.initialize();
1008a6eb0cf5777dded2354408e8007d9223e813c92showard        normalDataSource.setSkipNumResults(true);
1018a6eb0cf5777dded2354408e8007d9223e813c92showard        latestDataSource.setSkipNumResults(true);
10235444864c7b6f49865a7e17aa0052987b72e4728showard
1033d6ae118f69717e68bc15b9aed7b6a6c7dd9bab0showard        actionsPanel.setActionsWithCsvListener(this);
1049dbdcda5104991cbf344ea5cba1aa58e1af444f3showard        actionsPanel.setSelectionListener(this);
1053d6ae118f69717e68bc15b9aed7b6a6c7dd9bab0showard        actionsPanel.setVisible(false);
106f248952e42ea33c34e41a49817e50f98c65c2716showard
107227a7a1d0484dcfa4c6d996a1c10e95437d059efshoward        headerFields.populateFromList("group_fields");
108227a7a1d0484dcfa4c6d996a1c10e95437d059efshoward        setupHeaderSelect(rowSelect, rowSelectDisplay, DEFAULT_ROW);
109227a7a1d0484dcfa4c6d996a1c10e95437d059efshoward        setupHeaderSelect(columnSelect, columnSelectDisplay, DEFAULT_COLUMN);
110227a7a1d0484dcfa4c6d996a1c10e95437d059efshoward
111227a7a1d0484dcfa4c6d996a1c10e95437d059efshoward        for (HeaderField field : headerFields) {
11277401f351bd4ef6b6af99e46a9f905b161062574showard            contentSelect.addItem(field);
11335444864c7b6f49865a7e17aa0052987b72e4728showard        }
1140d92da0fe19a095fc5678c4159e6a1756df65e48showard        contentSelect.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
1150d92da0fe19a095fc5678c4159e6a1756df65e48showard            public void onValueChange(ValueChangeEvent<Boolean> event) {
1160d92da0fe19a095fc5678c4159e6a1756df65e48showard                if (event.getValue()) {
1177f2b0e15c5928ea2914d078e385ca717d078c6d5showard                    showOnlyLatest.setValue(true);
11877401f351bd4ef6b6af99e46a9f905b161062574showard                    showOnlyLatest.setEnabled(false);
11977401f351bd4ef6b6af99e46a9f905b161062574showard                } else {
12077401f351bd4ef6b6af99e46a9f905b161062574showard                    showOnlyLatest.setEnabled(true);
12177401f351bd4ef6b6af99e46a9f905b161062574showard                }
12277401f351bd4ef6b6af99e46a9f905b161062574showard            }
12377401f351bd4ef6b6af99e46a9f905b161062574showard        });
12477401f351bd4ef6b6af99e46a9f905b161062574showard
125c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        updateViewFromState();
126f248952e42ea33c34e41a49817e50f98c65c2716showard
127a5e4d84c9616b0a987e904d3b1d1d3fd9ca1be86showard        queryButton.addClickHandler(new ClickHandler() {
128a5e4d84c9616b0a987e904d3b1d1d3fd9ca1be86showard            public void onClick(ClickEvent event) {
12935444864c7b6f49865a7e17aa0052987b72e4728showard                doQuery();
13035444864c7b6f49865a7e17aa0052987b72e4728showard                updateHistory();
13135444864c7b6f49865a7e17aa0052987b72e4728showard            }
13235444864c7b6f49865a7e17aa0052987b72e4728showard        });
13335444864c7b6f49865a7e17aa0052987b72e4728showard
13435444864c7b6f49865a7e17aa0052987b72e4728showard        spreadsheet.setVisible(false);
13535444864c7b6f49865a7e17aa0052987b72e4728showard        spreadsheet.setListener(this);
13635444864c7b6f49865a7e17aa0052987b72e4728showard
13735444864c7b6f49865a7e17aa0052987b72e4728showard        SimpleHyperlink swapLink = new SimpleHyperlink("swap");
138a5e4d84c9616b0a987e904d3b1d1d3fd9ca1be86showard        swapLink.addClickHandler(new ClickHandler() {
139a5e4d84c9616b0a987e904d3b1d1d3fd9ca1be86showard            public void onClick(ClickEvent event) {
140f248952e42ea33c34e41a49817e50f98c65c2716showard                List<HeaderField> newRows = columnSelect.getSelectedItems();
141f248952e42ea33c34e41a49817e50f98c65c2716showard                setSelectedHeader(columnSelect, rowSelect.getSelectedItems());
14235444864c7b6f49865a7e17aa0052987b72e4728showard                setSelectedHeader(rowSelect, newRows);
14335444864c7b6f49865a7e17aa0052987b72e4728showard            }
14435444864c7b6f49865a7e17aa0052987b72e4728showard        });
14535444864c7b6f49865a7e17aa0052987b72e4728showard
1468a6eb0cf5777dded2354408e8007d9223e813c92showard        Panel filterOptions = new VerticalPanel();
1478a6eb0cf5777dded2354408e8007d9223e813c92showard        filterOptions.add(showIncomplete);
1488a6eb0cf5777dded2354408e8007d9223e813c92showard        filterOptions.add(showOnlyLatest);
1498a6eb0cf5777dded2354408e8007d9223e813c92showard
1509e494cc00c53f9dd0fabec3ef675cb874a9130adshoward        addWidget(filterOptions, "ss_filter_options");
151d9e04c1a7950691cc348e70fa2470f8c414ae94fshoward        addWidget(rowSelectDisplay, "ss_row_select");
152d9e04c1a7950691cc348e70fa2470f8c414ae94fshoward        addWidget(columnSelectDisplay, "ss_column_select");
1539e494cc00c53f9dd0fabec3ef675cb874a9130adshoward        addWidget(contentSelect, "ss_additional_content");
1549e494cc00c53f9dd0fabec3ef675cb874a9130adshoward        addWidget(swapLink, "ss_swap");
1559e494cc00c53f9dd0fabec3ef675cb874a9130adshoward        addWidget(queryButton, "ss_query_controls");
1569e494cc00c53f9dd0fabec3ef675cb874a9130adshoward        addWidget(actionsPanel, "ss_actions");
1579e494cc00c53f9dd0fabec3ef675cb874a9130adshoward        addWidget(spreadsheet, "ss_spreadsheet");
1589e494cc00c53f9dd0fabec3ef675cb874a9130adshoward        addWidget(jobCompletionPanel, "ss_job_completion");
15935444864c7b6f49865a7e17aa0052987b72e4728showard
16079a7b0d387aac103fc1d125353eefa361030452ashoward        Window.addResizeHandler(new ResizeHandler() {
16179a7b0d387aac103fc1d125353eefa361030452ashoward            public void onResize(ResizeEvent event) {
16235444864c7b6f49865a7e17aa0052987b72e4728showard                if(spreadsheet.isVisible())
16335444864c7b6f49865a7e17aa0052987b72e4728showard                    spreadsheet.fillWindow(true);
16435444864c7b6f49865a7e17aa0052987b72e4728showard            }
16535444864c7b6f49865a7e17aa0052987b72e4728showard        });
16635444864c7b6f49865a7e17aa0052987b72e4728showard
16735444864c7b6f49865a7e17aa0052987b72e4728showard        setupDrilldownMap();
16835444864c7b6f49865a7e17aa0052987b72e4728showard    }
169f6348c999bc60ee048510c8e28f74f944a32d97cshoward
170227a7a1d0484dcfa4c6d996a1c10e95437d059efshoward    private void setupHeaderSelect(HeaderSelect headerSelect, HeaderSelectorView display,
171227a7a1d0484dcfa4c6d996a1c10e95437d059efshoward                                           String defaultField) {
172227a7a1d0484dcfa4c6d996a1c10e95437d059efshoward        headerSelect.bindDisplay(display);
173227a7a1d0484dcfa4c6d996a1c10e95437d059efshoward        headerSelect.selectItem(headerFields.getFieldBySqlName(defaultField));
174227a7a1d0484dcfa4c6d996a1c10e95437d059efshoward    }
175227a7a1d0484dcfa4c6d996a1c10e95437d059efshoward
17635444864c7b6f49865a7e17aa0052987b72e4728showard    protected TestSet getWholeTableTestSet() {
17735444864c7b6f49865a7e17aa0052987b72e4728showard        boolean isSingleTest = spreadsheetProcessor.getNumTotalTests() == 1;
1788a6eb0cf5777dded2354408e8007d9223e813c92showard        if (isSingleTest) {
1798a6eb0cf5777dded2354408e8007d9223e813c92showard            return getTestSet(spreadsheetProcessor.getLastCellInfo());
1808a6eb0cf5777dded2354408e8007d9223e813c92showard        }
181f6348c999bc60ee048510c8e28f74f944a32d97cshoward
182f6348c999bc60ee048510c8e28f74f944a32d97cshoward        if (currentShowOnlyLatest) {
183f6348c999bc60ee048510c8e28f74f944a32d97cshoward            List<Integer> testIndices = spreadsheet.getAllTestIndices();
184f6348c999bc60ee048510c8e28f74f944a32d97cshoward            String filter = "test_idx IN (" + Utils.joinStrings(",", testIndices) + ")";
185f6348c999bc60ee048510c8e28f74f944a32d97cshoward            ConditionTestSet tests = new ConditionTestSet();
186f6348c999bc60ee048510c8e28f74f944a32d97cshoward            tests.addCondition(filter);
187f6348c999bc60ee048510c8e28f74f944a32d97cshoward            return tests;
188f6348c999bc60ee048510c8e28f74f944a32d97cshoward        }
189f6348c999bc60ee048510c8e28f74f944a32d97cshoward
1908a6eb0cf5777dded2354408e8007d9223e813c92showard        return new ConditionTestSet(getFullConditionArgs());
19135444864c7b6f49865a7e17aa0052987b72e4728showard    }
19235444864c7b6f49865a7e17aa0052987b72e4728showard
19335444864c7b6f49865a7e17aa0052987b72e4728showard    protected void setupDrilldownMap() {
19435444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("platform", new String[] {"hostname", "test_name"});
19535444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("hostname", new String[] {"job_tag", "status"});
19635444864c7b6f49865a7e17aa0052987b72e4728showard
19735444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("kernel", new String[] {"test_name", "status"});
19835444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("test_name", new String[] {"job_name", "job_tag"});
19935444864c7b6f49865a7e17aa0052987b72e4728showard
20035444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("status", new String[] {"reason", "job_tag"});
20135444864c7b6f49865a7e17aa0052987b72e4728showard
20235444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("job_owner", new String[] {"job_name", "job_tag"});
20335444864c7b6f49865a7e17aa0052987b72e4728showard
20435444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("test_finished_time", new String[] {"status", "job_tag"});
20535444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("DATE(test_finished_time)",
20635444864c7b6f49865a7e17aa0052987b72e4728showard                         new String[] {"test_finished_time", "job_tag"});
20735444864c7b6f49865a7e17aa0052987b72e4728showard    }
20835444864c7b6f49865a7e17aa0052987b72e4728showard
209f248952e42ea33c34e41a49817e50f98c65c2716showard    protected void setSelectedHeader(HeaderSelect list, List<HeaderField> fields) {
210f248952e42ea33c34e41a49817e50f98c65c2716showard        list.selectItems(fields);
21135444864c7b6f49865a7e17aa0052987b72e4728showard    }
21235444864c7b6f49865a7e17aa0052987b72e4728showard
21335444864c7b6f49865a7e17aa0052987b72e4728showard    @Override
21435444864c7b6f49865a7e17aa0052987b72e4728showard    public void refresh() {
21535444864c7b6f49865a7e17aa0052987b72e4728showard        notYetQueried = false;
2163d6ae118f69717e68bc15b9aed7b6a6c7dd9bab0showard        actionsPanel.setVisible(true);
21735444864c7b6f49865a7e17aa0052987b72e4728showard        spreadsheet.setVisible(false);
21835444864c7b6f49865a7e17aa0052987b72e4728showard        selectionManager.clearSelection();
21935444864c7b6f49865a7e17aa0052987b72e4728showard        spreadsheet.clear();
22035444864c7b6f49865a7e17aa0052987b72e4728showard        setJobCompletionHtml("&nbsp");
22135444864c7b6f49865a7e17aa0052987b72e4728showard
222d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward        final JSONObject condition = getFullConditionArgs();
22377401f351bd4ef6b6af99e46a9f905b161062574showard
22477401f351bd4ef6b6af99e46a9f905b161062574showard        contentSelect.addToCondition(condition);
225c674d3ea684f75f3e05f5834b598050eb1c8856dshoward
22635444864c7b6f49865a7e17aa0052987b72e4728showard        setLoading(true);
227313ab769319f56b940a2784cc0cbdebd005c5799showard        if (currentShowOnlyLatest) {
2288a6eb0cf5777dded2354408e8007d9223e813c92showard            spreadsheetProcessor.setDataSource(latestDataSource);
2298a6eb0cf5777dded2354408e8007d9223e813c92showard        } else {
2308a6eb0cf5777dded2354408e8007d9223e813c92showard            spreadsheetProcessor.setDataSource(normalDataSource);
2318a6eb0cf5777dded2354408e8007d9223e813c92showard        }
232c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        spreadsheetProcessor.setHeaders(rowSelect.getSelectedItems(),
233c674d3ea684f75f3e05f5834b598050eb1c8856dshoward                                        columnSelect.getSelectedItems(),
234f248952e42ea33c34e41a49817e50f98c65c2716showard                                        getQueryParameters());
2358c9b839c2f5073a755952a8a865a04db3b2d4547showard        spreadsheetProcessor.refresh(condition, new Command() {
23635444864c7b6f49865a7e17aa0052987b72e4728showard            public void execute() {
23777401f351bd4ef6b6af99e46a9f905b161062574showard                condition.put("extra_info", null);
23877401f351bd4ef6b6af99e46a9f905b161062574showard
2390281350135d1216c722e1d6fb85044f505c2319bshoward                if (isJobFilteringCondition(condition)) {
2400281350135d1216c722e1d6fb85044f505c2319bshoward                    showCompletionPercentage(condition);
24135444864c7b6f49865a7e17aa0052987b72e4728showard                } else {
24235444864c7b6f49865a7e17aa0052987b72e4728showard                    setLoading(false);
24335444864c7b6f49865a7e17aa0052987b72e4728showard                }
24435444864c7b6f49865a7e17aa0052987b72e4728showard            }
24535444864c7b6f49865a7e17aa0052987b72e4728showard        });
24635444864c7b6f49865a7e17aa0052987b72e4728showard    }
24735444864c7b6f49865a7e17aa0052987b72e4728showard
248f248952e42ea33c34e41a49817e50f98c65c2716showard    private JSONObject getQueryParameters() {
249f248952e42ea33c34e41a49817e50f98c65c2716showard        JSONObject parameters = new JSONObject();
250f248952e42ea33c34e41a49817e50f98c65c2716showard        rowSelect.addQueryParameters(parameters);
251f248952e42ea33c34e41a49817e50f98c65c2716showard        columnSelect.addQueryParameters(parameters);
252f248952e42ea33c34e41a49817e50f98c65c2716showard        return parameters;
2538c9b839c2f5073a755952a8a865a04db3b2d4547showard    }
2548c9b839c2f5073a755952a8a865a04db3b2d4547showard
255d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward    private JSONObject getFullConditionArgs() {
256c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        JSONObject args = commonPanel.getConditionArgs();
257d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward        String condition = TkoUtils.getSqlCondition(args);
2580281350135d1216c722e1d6fb85044f505c2319bshoward        if (!condition.equals("")) {
2590281350135d1216c722e1d6fb85044f505c2319bshoward            condition = "(" + condition + ") AND ";
2600281350135d1216c722e1d6fb85044f505c2319bshoward        }
2610281350135d1216c722e1d6fb85044f505c2319bshoward        condition += "status != 'TEST_NA'";
2620281350135d1216c722e1d6fb85044f505c2319bshoward        if (!currentShowIncomplete) {
2630281350135d1216c722e1d6fb85044f505c2319bshoward            condition += " AND status != 'RUNNING'";
2640281350135d1216c722e1d6fb85044f505c2319bshoward        }
265d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward        args.put("extra_where", new JSONString(condition));
266d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward        return args;
2670281350135d1216c722e1d6fb85044f505c2319bshoward    }
268c674d3ea684f75f3e05f5834b598050eb1c8856dshoward
269c674d3ea684f75f3e05f5834b598050eb1c8856dshoward    private void updateStateFromView() {
270c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        rowSelect.updateStateFromView();
271c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        columnSelect.updateStateFromView();
2727f2b0e15c5928ea2914d078e385ca717d078c6d5showard        currentShowIncomplete = showIncomplete.getValue();
2737f2b0e15c5928ea2914d078e385ca717d078c6d5showard        currentShowOnlyLatest = showOnlyLatest.getValue();
274c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        commonPanel.updateStateFromView();
275c674d3ea684f75f3e05f5834b598050eb1c8856dshoward    }
2760281350135d1216c722e1d6fb85044f505c2319bshoward
27735444864c7b6f49865a7e17aa0052987b72e4728showard    public void doQuery() {
278f248952e42ea33c34e41a49817e50f98c65c2716showard        List<HeaderField> rows = rowSelect.getSelectedItems();
279f248952e42ea33c34e41a49817e50f98c65c2716showard        List<HeaderField> columns = columnSelect.getSelectedItems();
28035444864c7b6f49865a7e17aa0052987b72e4728showard        if (rows.isEmpty() || columns.isEmpty()) {
28135444864c7b6f49865a7e17aa0052987b72e4728showard            NotifyManager.getInstance().showError("You must select row and column fields");
28235444864c7b6f49865a7e17aa0052987b72e4728showard            return;
28335444864c7b6f49865a7e17aa0052987b72e4728showard        }
284c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        if (!rowSelect.checkMachineLabelHeaders() || !columnSelect.checkMachineLabelHeaders()) {
285f248952e42ea33c34e41a49817e50f98c65c2716showard            NotifyManager.getInstance().showError(
286f248952e42ea33c34e41a49817e50f98c65c2716showard                      "You must enter labels for all machine label fields");
287f248952e42ea33c34e41a49817e50f98c65c2716showard            return;
288f248952e42ea33c34e41a49817e50f98c65c2716showard        }
289c674d3ea684f75f3e05f5834b598050eb1c8856dshoward
290c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        updateStateFromView();
29135444864c7b6f49865a7e17aa0052987b72e4728showard        refresh();
29235444864c7b6f49865a7e17aa0052987b72e4728showard    }
29335444864c7b6f49865a7e17aa0052987b72e4728showard
294d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward    private void showCompletionPercentage(JSONObject condition) {
295d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward        rpcProxy.rpcCall("get_job_ids", condition, new JsonRpcCallback() {
29635444864c7b6f49865a7e17aa0052987b72e4728showard            @Override
29735444864c7b6f49865a7e17aa0052987b72e4728showard            public void onSuccess(JSONValue result) {
29835444864c7b6f49865a7e17aa0052987b72e4728showard                finishShowCompletionPercentage(result.isArray());
29935444864c7b6f49865a7e17aa0052987b72e4728showard                setLoading(false);
30035444864c7b6f49865a7e17aa0052987b72e4728showard            }
30135444864c7b6f49865a7e17aa0052987b72e4728showard
30235444864c7b6f49865a7e17aa0052987b72e4728showard            @Override
30335444864c7b6f49865a7e17aa0052987b72e4728showard            public void onError(JSONObject errorObject) {
30435444864c7b6f49865a7e17aa0052987b72e4728showard                super.onError(errorObject);
30535444864c7b6f49865a7e17aa0052987b72e4728showard                setLoading(false);
30635444864c7b6f49865a7e17aa0052987b72e4728showard            }
30735444864c7b6f49865a7e17aa0052987b72e4728showard        });
30835444864c7b6f49865a7e17aa0052987b72e4728showard    }
30935444864c7b6f49865a7e17aa0052987b72e4728showard
31035444864c7b6f49865a7e17aa0052987b72e4728showard    private void finishShowCompletionPercentage(JSONArray jobIds) {
31135444864c7b6f49865a7e17aa0052987b72e4728showard        final int jobCount = jobIds.size();
31235444864c7b6f49865a7e17aa0052987b72e4728showard        if (jobCount == 0) {
31335444864c7b6f49865a7e17aa0052987b72e4728showard            return;
31435444864c7b6f49865a7e17aa0052987b72e4728showard        }
31535444864c7b6f49865a7e17aa0052987b72e4728showard
31635444864c7b6f49865a7e17aa0052987b72e4728showard        JSONObject args = new JSONObject();
31735444864c7b6f49865a7e17aa0052987b72e4728showard        args.put("job__id__in", jobIds);
31835444864c7b6f49865a7e17aa0052987b72e4728showard        afeRpcProxy.rpcCall("get_hqe_percentage_complete", args, new JsonRpcCallback() {
31935444864c7b6f49865a7e17aa0052987b72e4728showard            @Override
32035444864c7b6f49865a7e17aa0052987b72e4728showard            public void onSuccess(JSONValue result) {
32135444864c7b6f49865a7e17aa0052987b72e4728showard                int percentage = (int) (result.isNumber().doubleValue() * 100);
32235444864c7b6f49865a7e17aa0052987b72e4728showard                StringBuilder message = new StringBuilder("Matching ");
32335444864c7b6f49865a7e17aa0052987b72e4728showard                if (jobCount == 1) {
32435444864c7b6f49865a7e17aa0052987b72e4728showard                    message.append("job is ");
32535444864c7b6f49865a7e17aa0052987b72e4728showard                } else {
32635444864c7b6f49865a7e17aa0052987b72e4728showard                    message.append("jobs are ");
32735444864c7b6f49865a7e17aa0052987b72e4728showard                }
32835444864c7b6f49865a7e17aa0052987b72e4728showard                message.append(percentage);
32935444864c7b6f49865a7e17aa0052987b72e4728showard                message.append("% complete");
33035444864c7b6f49865a7e17aa0052987b72e4728showard                setJobCompletionHtml(message.toString());
33135444864c7b6f49865a7e17aa0052987b72e4728showard            }
33235444864c7b6f49865a7e17aa0052987b72e4728showard        });
33335444864c7b6f49865a7e17aa0052987b72e4728showard    }
33435444864c7b6f49865a7e17aa0052987b72e4728showard
33535444864c7b6f49865a7e17aa0052987b72e4728showard    private void setJobCompletionHtml(String html) {
33635444864c7b6f49865a7e17aa0052987b72e4728showard        jobCompletionPanel.clear();
33735444864c7b6f49865a7e17aa0052987b72e4728showard        jobCompletionPanel.add(new HTML(html));
33835444864c7b6f49865a7e17aa0052987b72e4728showard    }
33935444864c7b6f49865a7e17aa0052987b72e4728showard
340d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward    private boolean isJobFilteringCondition(JSONObject condition) {
341d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward        return TkoUtils.getSqlCondition(condition).indexOf("job_tag") != -1;
34235444864c7b6f49865a7e17aa0052987b72e4728showard    }
34335444864c7b6f49865a7e17aa0052987b72e4728showard
34435444864c7b6f49865a7e17aa0052987b72e4728showard    public void onCellClicked(CellInfo cellInfo) {
34535444864c7b6f49865a7e17aa0052987b72e4728showard        Event event = Event.getCurrentEvent();
34635444864c7b6f49865a7e17aa0052987b72e4728showard        TestSet testSet = getTestSet(cellInfo);
34735444864c7b6f49865a7e17aa0052987b72e4728showard        DrilldownType drilldownType = getDrilldownType(cellInfo);
34835444864c7b6f49865a7e17aa0052987b72e4728showard        if (RightClickTable.isRightClick(event)) {
34935444864c7b6f49865a7e17aa0052987b72e4728showard            if (!selectionManager.isEmpty()) {
35035444864c7b6f49865a7e17aa0052987b72e4728showard                testSet = getTestSet(selectionManager.getSelectedCells());
35135444864c7b6f49865a7e17aa0052987b72e4728showard                drilldownType = DrilldownType.DRILLDOWN_BOTH;
35235444864c7b6f49865a7e17aa0052987b72e4728showard            }
35335444864c7b6f49865a7e17aa0052987b72e4728showard            ContextMenu menu = getContextMenu(testSet, drilldownType);
35435444864c7b6f49865a7e17aa0052987b72e4728showard            menu.showAtWindow(event.getClientX(), event.getClientY());
35535444864c7b6f49865a7e17aa0052987b72e4728showard            return;
35635444864c7b6f49865a7e17aa0052987b72e4728showard        }
35735444864c7b6f49865a7e17aa0052987b72e4728showard
3583b8563acf345e8327fb3f0cb4b96869ce55f5080showard        if (isSelectEvent(event)) {
35935444864c7b6f49865a7e17aa0052987b72e4728showard            selectionManager.toggleSelected(cellInfo);
36035444864c7b6f49865a7e17aa0052987b72e4728showard            return;
36135444864c7b6f49865a7e17aa0052987b72e4728showard        }
362c674d3ea684f75f3e05f5834b598050eb1c8856dshoward
363c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        HistoryToken historyToken;
36435444864c7b6f49865a7e17aa0052987b72e4728showard        if (testSet.isSingleTest()) {
365c674d3ea684f75f3e05f5834b598050eb1c8856dshoward            historyToken = listener.getSelectTestHistoryToken(testSet.getTestIndex());
366c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        } else {
367c674d3ea684f75f3e05f5834b598050eb1c8856dshoward            historyToken = getDrilldownHistoryToken(testSet,
368c674d3ea684f75f3e05f5834b598050eb1c8856dshoward                                                    getDefaultDrilldownRow(drilldownType),
369c674d3ea684f75f3e05f5834b598050eb1c8856dshoward                                                    getDefaultDrilldownColumn(drilldownType));
37035444864c7b6f49865a7e17aa0052987b72e4728showard        }
371c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        openHistoryToken(historyToken);
37235444864c7b6f49865a7e17aa0052987b72e4728showard    }
373c674d3ea684f75f3e05f5834b598050eb1c8856dshoward
374c674d3ea684f75f3e05f5834b598050eb1c8856dshoward     private DrilldownType getDrilldownType(CellInfo cellInfo) {
37535444864c7b6f49865a7e17aa0052987b72e4728showard        if (cellInfo.row == null) {
37635444864c7b6f49865a7e17aa0052987b72e4728showard            // column header
37735444864c7b6f49865a7e17aa0052987b72e4728showard            return DrilldownType.DRILLDOWN_COLUMN;
37835444864c7b6f49865a7e17aa0052987b72e4728showard        }
37935444864c7b6f49865a7e17aa0052987b72e4728showard        if (cellInfo.column == null) {
38035444864c7b6f49865a7e17aa0052987b72e4728showard            // row header
38135444864c7b6f49865a7e17aa0052987b72e4728showard            return DrilldownType.DRILLDOWN_ROW;
38235444864c7b6f49865a7e17aa0052987b72e4728showard        }
38335444864c7b6f49865a7e17aa0052987b72e4728showard        return DrilldownType.DRILLDOWN_BOTH;
38435444864c7b6f49865a7e17aa0052987b72e4728showard    }
38535444864c7b6f49865a7e17aa0052987b72e4728showard
38635444864c7b6f49865a7e17aa0052987b72e4728showard    private TestSet getTestSet(CellInfo cellInfo) {
38735444864c7b6f49865a7e17aa0052987b72e4728showard        boolean isSingleTest = cellInfo.testCount == 1;
3888a6eb0cf5777dded2354408e8007d9223e813c92showard        if (isSingleTest) {
3898a6eb0cf5777dded2354408e8007d9223e813c92showard            return new SingleTestSet(cellInfo.testIndex, getFullConditionArgs());
3908a6eb0cf5777dded2354408e8007d9223e813c92showard        }
39135444864c7b6f49865a7e17aa0052987b72e4728showard
3928a6eb0cf5777dded2354408e8007d9223e813c92showard        ConditionTestSet testSet = new ConditionTestSet(getFullConditionArgs());
39335444864c7b6f49865a7e17aa0052987b72e4728showard        if (cellInfo.row != null) {
394c674d3ea684f75f3e05f5834b598050eb1c8856dshoward            setSomeFields(testSet, rowSelect.getSelectedItems(), cellInfo.row);
39535444864c7b6f49865a7e17aa0052987b72e4728showard        }
39635444864c7b6f49865a7e17aa0052987b72e4728showard        if (cellInfo.column != null) {
397c674d3ea684f75f3e05f5834b598050eb1c8856dshoward            setSomeFields(testSet, columnSelect.getSelectedItems(), cellInfo.column);
39835444864c7b6f49865a7e17aa0052987b72e4728showard        }
39935444864c7b6f49865a7e17aa0052987b72e4728showard        return testSet;
40035444864c7b6f49865a7e17aa0052987b72e4728showard    }
40135444864c7b6f49865a7e17aa0052987b72e4728showard
402f248952e42ea33c34e41a49817e50f98c65c2716showard    private void setSomeFields(ConditionTestSet testSet, List<HeaderField> allFields,
403f248952e42ea33c34e41a49817e50f98c65c2716showard                               Header values) {
404f248952e42ea33c34e41a49817e50f98c65c2716showard        for (int i = 0; i < values.size(); i++) {
405f248952e42ea33c34e41a49817e50f98c65c2716showard            HeaderField field = allFields.get(i);
406f248952e42ea33c34e41a49817e50f98c65c2716showard            String value = values.get(i);
407f248952e42ea33c34e41a49817e50f98c65c2716showard            testSet.addCondition(field.getSqlCondition(value));
408f248952e42ea33c34e41a49817e50f98c65c2716showard        }
40935444864c7b6f49865a7e17aa0052987b72e4728showard    }
41035444864c7b6f49865a7e17aa0052987b72e4728showard
41135444864c7b6f49865a7e17aa0052987b72e4728showard    private TestSet getTestSet(List<CellInfo> cells) {
41235444864c7b6f49865a7e17aa0052987b72e4728showard        CompositeTestSet tests = new CompositeTestSet();
41335444864c7b6f49865a7e17aa0052987b72e4728showard        for (CellInfo cell : cells) {
41435444864c7b6f49865a7e17aa0052987b72e4728showard            tests.add(getTestSet(cell));
41535444864c7b6f49865a7e17aa0052987b72e4728showard        }
41635444864c7b6f49865a7e17aa0052987b72e4728showard        return tests;
41735444864c7b6f49865a7e17aa0052987b72e4728showard    }
41835444864c7b6f49865a7e17aa0052987b72e4728showard
419c674d3ea684f75f3e05f5834b598050eb1c8856dshoward    private HistoryToken getDrilldownHistoryToken(TestSet tests, String newRowField,
420227a7a1d0484dcfa4c6d996a1c10e95437d059efshoward                                                  String newColumnField) {
421c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        saveHistoryState();
42264aeecdec485192241e5377b3fa5ac7cf57a0c12showard        commonPanel.refineCondition(tests);
423227a7a1d0484dcfa4c6d996a1c10e95437d059efshoward        rowSelect.selectItem(headerFields.getFieldBySqlName(newRowField));
424227a7a1d0484dcfa4c6d996a1c10e95437d059efshoward        columnSelect.selectItem(headerFields.getFieldBySqlName(newColumnField));
425c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        HistoryToken historyArguments = getHistoryArguments();
426c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        restoreHistoryState();
427c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        return historyArguments;
428c674d3ea684f75f3e05f5834b598050eb1c8856dshoward    }
429c674d3ea684f75f3e05f5834b598050eb1c8856dshoward
430c674d3ea684f75f3e05f5834b598050eb1c8856dshoward    private void doDrilldown(TestSet tests, String newRowField, String newColumnField) {
431c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        History.newItem(getDrilldownHistoryToken(tests, newRowField, newColumnField).toString());
43235444864c7b6f49865a7e17aa0052987b72e4728showard    }
43335444864c7b6f49865a7e17aa0052987b72e4728showard
43435444864c7b6f49865a7e17aa0052987b72e4728showard    private String getDefaultDrilldownRow(DrilldownType type) {
43535444864c7b6f49865a7e17aa0052987b72e4728showard        return getDrilldownRows(type)[0];
43635444864c7b6f49865a7e17aa0052987b72e4728showard    }
43735444864c7b6f49865a7e17aa0052987b72e4728showard
43835444864c7b6f49865a7e17aa0052987b72e4728showard    private String getDefaultDrilldownColumn(DrilldownType type) {
43935444864c7b6f49865a7e17aa0052987b72e4728showard        return getDrilldownColumns(type)[0];
44035444864c7b6f49865a7e17aa0052987b72e4728showard    }
44135444864c7b6f49865a7e17aa0052987b72e4728showard
44235444864c7b6f49865a7e17aa0052987b72e4728showard    private ContextMenu getContextMenu(final TestSet tests, DrilldownType drilldownType) {
44335444864c7b6f49865a7e17aa0052987b72e4728showard        TestContextMenu menu = new TestContextMenu(tests, listener);
44435444864c7b6f49865a7e17aa0052987b72e4728showard
44535444864c7b6f49865a7e17aa0052987b72e4728showard        if (!menu.addViewDetailsIfSingleTest()) {
44635444864c7b6f49865a7e17aa0052987b72e4728showard            MenuBar drilldownMenu = menu.addSubMenuItem("Drill down");
44735444864c7b6f49865a7e17aa0052987b72e4728showard            fillDrilldownMenu(tests, drilldownType, drilldownMenu);
44835444864c7b6f49865a7e17aa0052987b72e4728showard        }
44935444864c7b6f49865a7e17aa0052987b72e4728showard
45035444864c7b6f49865a7e17aa0052987b72e4728showard        menu.addItem("View in table", new Command() {
45135444864c7b6f49865a7e17aa0052987b72e4728showard            public void execute() {
45235444864c7b6f49865a7e17aa0052987b72e4728showard                switchToTable(tests, false);
45335444864c7b6f49865a7e17aa0052987b72e4728showard            }
45435444864c7b6f49865a7e17aa0052987b72e4728showard        });
45535444864c7b6f49865a7e17aa0052987b72e4728showard        menu.addItem("Triage failures", new Command() {
45635444864c7b6f49865a7e17aa0052987b72e4728showard            public void execute() {
45735444864c7b6f49865a7e17aa0052987b72e4728showard                switchToTable(tests, true);
45835444864c7b6f49865a7e17aa0052987b72e4728showard            }
45935444864c7b6f49865a7e17aa0052987b72e4728showard        });
46035444864c7b6f49865a7e17aa0052987b72e4728showard
46135444864c7b6f49865a7e17aa0052987b72e4728showard        menu.addLabelItems();
46235444864c7b6f49865a7e17aa0052987b72e4728showard        return menu;
46335444864c7b6f49865a7e17aa0052987b72e4728showard    }
46435444864c7b6f49865a7e17aa0052987b72e4728showard
46535444864c7b6f49865a7e17aa0052987b72e4728showard    private void fillDrilldownMenu(final TestSet tests, DrilldownType drilldownType, MenuBar menu) {
46635444864c7b6f49865a7e17aa0052987b72e4728showard        for (final String rowField : getDrilldownRows(drilldownType)) {
46735444864c7b6f49865a7e17aa0052987b72e4728showard            for (final String columnField : getDrilldownColumns(drilldownType)) {
46835444864c7b6f49865a7e17aa0052987b72e4728showard                if (rowField.equals(columnField)) {
46935444864c7b6f49865a7e17aa0052987b72e4728showard                    continue;
47035444864c7b6f49865a7e17aa0052987b72e4728showard                }
47135444864c7b6f49865a7e17aa0052987b72e4728showard                menu.addItem(rowField + " vs. " + columnField, new Command() {
47235444864c7b6f49865a7e17aa0052987b72e4728showard                    public void execute() {
47335444864c7b6f49865a7e17aa0052987b72e4728showard                        doDrilldown(tests, rowField, columnField);
47435444864c7b6f49865a7e17aa0052987b72e4728showard                    }
47535444864c7b6f49865a7e17aa0052987b72e4728showard                });
47635444864c7b6f49865a7e17aa0052987b72e4728showard            }
47735444864c7b6f49865a7e17aa0052987b72e4728showard        }
47835444864c7b6f49865a7e17aa0052987b72e4728showard    }
47935444864c7b6f49865a7e17aa0052987b72e4728showard
480f248952e42ea33c34e41a49817e50f98c65c2716showard    private String[] getDrilldownFields(List<HeaderField> fields, DrilldownType type,
48135444864c7b6f49865a7e17aa0052987b72e4728showard                                        DrilldownType otherType) {
482f248952e42ea33c34e41a49817e50f98c65c2716showard        HeaderField lastField = fields.get(fields.size() - 1);
483f248952e42ea33c34e41a49817e50f98c65c2716showard        String lastFieldName = lastField.getSqlName();
48435444864c7b6f49865a7e17aa0052987b72e4728showard        if (type == otherType) {
485f248952e42ea33c34e41a49817e50f98c65c2716showard            return new String[] {lastFieldName};
48635444864c7b6f49865a7e17aa0052987b72e4728showard        } else {
487f248952e42ea33c34e41a49817e50f98c65c2716showard            if (lastField instanceof MachineLabelField) {
488f248952e42ea33c34e41a49817e50f98c65c2716showard                // treat machine label fields like platform, for the purpose of default drilldown
489f248952e42ea33c34e41a49817e50f98c65c2716showard                lastFieldName = "platform";
490f248952e42ea33c34e41a49817e50f98c65c2716showard            }
491e463a8a926964673c2517bfef5ac394206b106c6showard            if (drilldownMap.containsKey(lastFieldName)) {
492e463a8a926964673c2517bfef5ac394206b106c6showard                return drilldownMap.get(lastFieldName);
493e463a8a926964673c2517bfef5ac394206b106c6showard            }
494e463a8a926964673c2517bfef5ac394206b106c6showard            return new String[] {DEFAULT_DRILLDOWN};
49535444864c7b6f49865a7e17aa0052987b72e4728showard        }
49635444864c7b6f49865a7e17aa0052987b72e4728showard    }
49735444864c7b6f49865a7e17aa0052987b72e4728showard
49835444864c7b6f49865a7e17aa0052987b72e4728showard    private String[] getDrilldownRows(DrilldownType type) {
499c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        return getDrilldownFields(rowSelect.getSelectedItems(), type,
500c674d3ea684f75f3e05f5834b598050eb1c8856dshoward                                  DrilldownType.DRILLDOWN_COLUMN);
50135444864c7b6f49865a7e17aa0052987b72e4728showard    }
50235444864c7b6f49865a7e17aa0052987b72e4728showard
50335444864c7b6f49865a7e17aa0052987b72e4728showard    private String[] getDrilldownColumns(DrilldownType type) {
504c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        return getDrilldownFields(columnSelect.getSelectedItems(), type,
505c674d3ea684f75f3e05f5834b598050eb1c8856dshoward                                  DrilldownType.DRILLDOWN_ROW);
50635444864c7b6f49865a7e17aa0052987b72e4728showard    }
50735444864c7b6f49865a7e17aa0052987b72e4728showard
508c674d3ea684f75f3e05f5834b598050eb1c8856dshoward    private void updateViewFromState() {
509c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        rowSelect.updateViewFromState();
510c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        columnSelect.updateViewFromState();
5117f2b0e15c5928ea2914d078e385ca717d078c6d5showard        showIncomplete.setValue(currentShowIncomplete);
5127f2b0e15c5928ea2914d078e385ca717d078c6d5showard        showOnlyLatest.setValue(currentShowOnlyLatest);
513c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        commonPanel.updateViewFromState();
51435444864c7b6f49865a7e17aa0052987b72e4728showard    }
51535444864c7b6f49865a7e17aa0052987b72e4728showard
51635444864c7b6f49865a7e17aa0052987b72e4728showard    @Override
517c674d3ea684f75f3e05f5834b598050eb1c8856dshoward    public HistoryToken getHistoryArguments() {
518c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        HistoryToken arguments = super.getHistoryArguments();
51935444864c7b6f49865a7e17aa0052987b72e4728showard        if (!notYetQueried) {
5208c9b839c2f5073a755952a8a865a04db3b2d4547showard            rowSelect.addHistoryArguments(arguments, HISTORY_ROW);
5218c9b839c2f5073a755952a8a865a04db3b2d4547showard            columnSelect.addHistoryArguments(arguments, HISTORY_COLUMN);
522194a59d6976a5dbd5b464fb2b14ceb089f91c050showard            contentSelect.addHistoryArguments(arguments, HISTORY_CONTENT);
5238c9b839c2f5073a755952a8a865a04db3b2d4547showard            arguments.put(HISTORY_SHOW_INCOMPLETE, Boolean.toString(currentShowIncomplete));
5247f2b0e15c5928ea2914d078e385ca717d078c6d5showard            arguments.put(HISTORY_ONLY_LATEST, Boolean.toString(showOnlyLatest.getValue()));
52535444864c7b6f49865a7e17aa0052987b72e4728showard            commonPanel.addHistoryArguments(arguments);
52635444864c7b6f49865a7e17aa0052987b72e4728showard        }
52735444864c7b6f49865a7e17aa0052987b72e4728showard        return arguments;
52835444864c7b6f49865a7e17aa0052987b72e4728showard    }
52935444864c7b6f49865a7e17aa0052987b72e4728showard
53035444864c7b6f49865a7e17aa0052987b72e4728showard    @Override
53135444864c7b6f49865a7e17aa0052987b72e4728showard    public void handleHistoryArguments(Map<String, String> arguments) {
53235444864c7b6f49865a7e17aa0052987b72e4728showard        super.handleHistoryArguments(arguments);
53335444864c7b6f49865a7e17aa0052987b72e4728showard        commonPanel.handleHistoryArguments(arguments);
5348c9b839c2f5073a755952a8a865a04db3b2d4547showard        rowSelect.handleHistoryArguments(arguments, HISTORY_ROW);
5358c9b839c2f5073a755952a8a865a04db3b2d4547showard        columnSelect.handleHistoryArguments(arguments, HISTORY_COLUMN);
536194a59d6976a5dbd5b464fb2b14ceb089f91c050showard        contentSelect.handleHistoryArguments(arguments, HISTORY_CONTENT);
537c674d3ea684f75f3e05f5834b598050eb1c8856dshoward
5388c9b839c2f5073a755952a8a865a04db3b2d4547showard        currentShowIncomplete = Boolean.valueOf(arguments.get(HISTORY_SHOW_INCOMPLETE));
539194a59d6976a5dbd5b464fb2b14ceb089f91c050showard        currentShowOnlyLatest = Boolean.valueOf(arguments.get(HISTORY_ONLY_LATEST));
540c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        updateViewFromState();
54135444864c7b6f49865a7e17aa0052987b72e4728showard    }
54235444864c7b6f49865a7e17aa0052987b72e4728showard
54335444864c7b6f49865a7e17aa0052987b72e4728showard    @Override
54435444864c7b6f49865a7e17aa0052987b72e4728showard    protected void fillDefaultHistoryValues(Map<String, String> arguments) {
5458c9b839c2f5073a755952a8a865a04db3b2d4547showard        Utils.setDefaultValue(arguments, HISTORY_ROW, DEFAULT_ROW);
5468c9b839c2f5073a755952a8a865a04db3b2d4547showard        Utils.setDefaultValue(arguments, HISTORY_COLUMN, DEFAULT_COLUMN);
5478c9b839c2f5073a755952a8a865a04db3b2d4547showard        Utils.setDefaultValue(arguments, HISTORY_ROW + HeaderSelect.HISTORY_FIXED_VALUES, "");
5488c9b839c2f5073a755952a8a865a04db3b2d4547showard        Utils.setDefaultValue(arguments, HISTORY_COLUMN + HeaderSelect.HISTORY_FIXED_VALUES, "");
5498a6eb0cf5777dded2354408e8007d9223e813c92showard        Utils.setDefaultValue(arguments, HISTORY_SHOW_INCOMPLETE, Boolean.toString(false));
5508a6eb0cf5777dded2354408e8007d9223e813c92showard        Utils.setDefaultValue(arguments, HISTORY_ONLY_LATEST, Boolean.toString(false));
55135444864c7b6f49865a7e17aa0052987b72e4728showard    }
55235444864c7b6f49865a7e17aa0052987b72e4728showard
55335444864c7b6f49865a7e17aa0052987b72e4728showard    private void switchToTable(final TestSet tests, boolean isTriageView) {
55464aeecdec485192241e5377b3fa5ac7cf57a0c12showard        commonPanel.refineCondition(tests);
555ce12f55f4530950f7fc6ddc73d1867ebb954d356showard        TableViewConfig config;
556ce12f55f4530950f7fc6ddc73d1867ebb954d356showard        if (isTriageView) {
557ce12f55f4530950f7fc6ddc73d1867ebb954d356showard            config = TableViewConfig.TRIAGE;
558313ab769319f56b940a2784cc0cbdebd005c5799showard            refineConditionForTriage();
559ce12f55f4530950f7fc6ddc73d1867ebb954d356showard        } else {
560ce12f55f4530950f7fc6ddc73d1867ebb954d356showard            config = TableViewConfig.DEFAULT;
561ce12f55f4530950f7fc6ddc73d1867ebb954d356showard        }
562ce12f55f4530950f7fc6ddc73d1867ebb954d356showard        listener.onSwitchToTable(config);
56335444864c7b6f49865a7e17aa0052987b72e4728showard    }
56435444864c7b6f49865a7e17aa0052987b72e4728showard
565313ab769319f56b940a2784cc0cbdebd005c5799showard    private void refineConditionForTriage() {
566313ab769319f56b940a2784cc0cbdebd005c5799showard        commonPanel.refineCondition("status != 'GOOD'");
567313ab769319f56b940a2784cc0cbdebd005c5799showard    }
568313ab769319f56b940a2784cc0cbdebd005c5799showard
56935444864c7b6f49865a7e17aa0052987b72e4728showard    public ContextMenu getActionMenu() {
57035444864c7b6f49865a7e17aa0052987b72e4728showard        TestSet tests;
57135444864c7b6f49865a7e17aa0052987b72e4728showard        if (selectionManager.isEmpty()) {
57235444864c7b6f49865a7e17aa0052987b72e4728showard            tests = getWholeTableTestSet();
57335444864c7b6f49865a7e17aa0052987b72e4728showard        } else {
57435444864c7b6f49865a7e17aa0052987b72e4728showard            tests = getTestSet(selectionManager.getSelectedCells());
57535444864c7b6f49865a7e17aa0052987b72e4728showard        }
57635444864c7b6f49865a7e17aa0052987b72e4728showard        return getContextMenu(tests, DrilldownType.DRILLDOWN_BOTH);
57735444864c7b6f49865a7e17aa0052987b72e4728showard    }
57835444864c7b6f49865a7e17aa0052987b72e4728showard
5793d6ae118f69717e68bc15b9aed7b6a6c7dd9bab0showard    public void onExportCsv() {
580194a59d6976a5dbd5b464fb2b14ceb089f91c050showard        JSONObject params = new JSONObject();
581194a59d6976a5dbd5b464fb2b14ceb089f91c050showard        contentSelect.addToCondition(params);
582194a59d6976a5dbd5b464fb2b14ceb089f91c050showard        TkoUtils.doCsvRequest(spreadsheetProcessor.getDataSource(), params);
5833d6ae118f69717e68bc15b9aed7b6a6c7dd9bab0showard    }
5843d6ae118f69717e68bc15b9aed7b6a6c7dd9bab0showard
58535444864c7b6f49865a7e17aa0052987b72e4728showard    public void onSelectAll(boolean ignored) {
58635444864c7b6f49865a7e17aa0052987b72e4728showard        selectionManager.selectAll();
58735444864c7b6f49865a7e17aa0052987b72e4728showard    }
58835444864c7b6f49865a7e17aa0052987b72e4728showard
58935444864c7b6f49865a7e17aa0052987b72e4728showard    public void onSelectNone() {
59035444864c7b6f49865a7e17aa0052987b72e4728showard        selectionManager.clearSelection();
59135444864c7b6f49865a7e17aa0052987b72e4728showard    }
59235444864c7b6f49865a7e17aa0052987b72e4728showard
59335444864c7b6f49865a7e17aa0052987b72e4728showard    @Override
59435444864c7b6f49865a7e17aa0052987b72e4728showard    protected boolean hasFirstQueryOccurred() {
59535444864c7b6f49865a7e17aa0052987b72e4728showard        return !notYetQueried;
59635444864c7b6f49865a7e17aa0052987b72e4728showard    }
59735444864c7b6f49865a7e17aa0052987b72e4728showard
59835444864c7b6f49865a7e17aa0052987b72e4728showard    private void setLoading(boolean loading) {
59935444864c7b6f49865a7e17aa0052987b72e4728showard        queryButton.setEnabled(!loading);
60035444864c7b6f49865a7e17aa0052987b72e4728showard        NotifyManager.getInstance().setLoading(loading);
60135444864c7b6f49865a7e17aa0052987b72e4728showard    }
6020c31bc5ef2ecdf8edf19468e1a373520110f5bc6showard
6030c31bc5ef2ecdf8edf19468e1a373520110f5bc6showard    public void onSetControlsVisible(boolean visible) {
6040c31bc5ef2ecdf8edf19468e1a373520110f5bc6showard        TkoUtils.setElementVisible("ss_all_controls", visible);
6050c31bc5ef2ecdf8edf19468e1a373520110f5bc6showard        if (isTabVisible()) {
6060c31bc5ef2ecdf8edf19468e1a373520110f5bc6showard            spreadsheet.fillWindow(true);
6070c31bc5ef2ecdf8edf19468e1a373520110f5bc6showard        }
6080c31bc5ef2ecdf8edf19468e1a373520110f5bc6showard    }
60935444864c7b6f49865a7e17aa0052987b72e4728showard}
610