1 package autotest.tko; 2 3 import autotest.common.SimpleCallback; 4 import autotest.common.Utils; 5 import autotest.common.ui.NotifyManager; 6 import autotest.tko.TkoUtils.FieldInfo; 7 8 import com.google.gwt.event.dom.client.ClickEvent; 9 import com.google.gwt.event.dom.client.ClickHandler; 10 import com.google.gwt.json.client.JSONObject; 11 import com.google.gwt.json.client.JSONString; 12 import com.google.gwt.user.client.ui.Anchor; 13 import com.google.gwt.user.client.ui.CheckBox; 14 import com.google.gwt.user.client.ui.Composite; 15 import com.google.gwt.user.client.ui.FlexTable; 16 import com.google.gwt.user.client.ui.HTML; 17 import com.google.gwt.user.client.ui.HTMLPanel; 18 import com.google.gwt.user.client.ui.HorizontalPanel; 19 import com.google.gwt.user.client.ui.Label; 20 import com.google.gwt.user.client.ui.Panel; 21 import com.google.gwt.user.client.ui.PopupPanel; 22 import com.google.gwt.user.client.ui.RootPanel; 23 import com.google.gwt.user.client.ui.TextArea; 24 import com.google.gwt.user.client.ui.VerticalPanel; 25 import com.google.gwt.user.client.ui.Widget; 26 import com.google.gwt.user.client.ui.PopupPanel.PositionCallback; 27 28 import java.util.HashSet; 29 import java.util.Map; 30 import java.util.Set; 31 32 class CommonPanel extends Composite implements ClickHandler, PositionCallback { 33 private static final String WIKI_URL = "http://autotest.kernel.org/wiki/TkoHowTo"; 34 private static final String SHOW_QUICK_REFERENCE = "Show quick reference"; 35 private static final String HIDE_QUICK_REFERENCE = "Hide quick reference"; 36 private static final String SHOW_CONTROLS = "Show controls"; 37 private static final String HIDE_CONTROLS = "Hide controls"; 38 39 private static CommonPanel theInstance = new CommonPanel(); 40 41 private String savedSqlCondition; 42 private boolean savedShowInvalid = false; 43 private HeaderFieldCollection headerFields = new HeaderFieldCollection(); 44 45 private ParameterizedFieldListPresenter parameterizedFieldPresenter = 46 new ParameterizedFieldListPresenter(headerFields); 47 48 private HTMLPanel htmlPanel; 49 private TextArea customSqlBox = new TextArea(); 50 private CheckBox showInvalid = new CheckBox("Show invalidated tests"); 51 private Anchor quickReferenceLink = new Anchor(SHOW_QUICK_REFERENCE); 52 private PopupPanel quickReferencePopup; 53 private Anchor showHideControlsLink = new Anchor(HIDE_CONTROLS); 54 private Panel allControlsPanel = RootPanel.get("common_all_controls"); 55 private Set<CommonPanelListener> listeners = new HashSet<CommonPanelListener>(); 56 private ParameterizedFieldListDisplay parameterizedFieldDisplay = 57 new ParameterizedFieldListDisplay(); 58 59 60 public static interface CommonPanelListener { 61 /** 62 * Called to show or hide tab-specific controls. 63 */ onSetControlsVisible(boolean visible)64 public void onSetControlsVisible(boolean visible); 65 66 /** 67 * Called when the set of HeaderFields has changed. 68 */ onFieldsChanged()69 public void onFieldsChanged(); 70 } 71 CommonPanel()72 private CommonPanel() { 73 htmlPanel = Utils.divToPanel("common_panel"); 74 initWidget(htmlPanel); 75 } 76 initialize()77 public void initialize() { 78 customSqlBox.setSize("50em", "5em"); 79 quickReferenceLink.addClickHandler(this); 80 showHideControlsLink.addClickHandler(this); 81 82 Panel titlePanel = new HorizontalPanel(); 83 titlePanel.add(getFieldLabel("Custom fields:")); 84 titlePanel.add(new HTML(" <a href=\"" + Utils.escape(WIKI_URL) + "#custom_fields\" " + 85 "target=\"_blank\">[?]</a>")); 86 Panel attributeFilters = new VerticalPanel(); 87 attributeFilters.setStyleName("box"); 88 attributeFilters.add(titlePanel); 89 attributeFilters.add(parameterizedFieldDisplay); 90 91 Panel commonFilterPanel = new VerticalPanel(); 92 commonFilterPanel.add(customSqlBox); 93 commonFilterPanel.add(attributeFilters); 94 commonFilterPanel.add(showInvalid); 95 htmlPanel.add(commonFilterPanel, "common_filters"); 96 htmlPanel.add(quickReferenceLink, "common_quick_reference"); 97 htmlPanel.add(showHideControlsLink, "common_show_hide_controls"); 98 generateQuickReferencePopup(); 99 100 headerFields.populateFromList("all_fields"); 101 notifyOnFieldsChanged(); 102 103 parameterizedFieldPresenter.bindDisplay(parameterizedFieldDisplay); 104 parameterizedFieldPresenter.setListener(new SimpleCallback() { 105 @Override 106 public void doCallback(Object source) { 107 notifyOnFieldsChanged(); 108 } 109 }); 110 } 111 getFieldLabel(String string)112 private Widget getFieldLabel(String string) { 113 Label label = new Label(string); 114 label.setStyleName("field-name"); 115 return label; 116 } 117 getPanel()118 public static CommonPanel getPanel() { 119 return theInstance; 120 } 121 122 /** 123 * For testability. 124 */ setInstance(CommonPanel panel)125 public static void setInstance(CommonPanel panel) { 126 theInstance = panel; 127 } 128 setConditionVisible(boolean visible)129 public void setConditionVisible(boolean visible) { 130 Utils.setElementVisible("common_condition_div", visible); 131 } 132 setSqlCondition(String text)133 public void setSqlCondition(String text) { 134 savedSqlCondition = text; 135 } 136 isViewReadyForQuery()137 public boolean isViewReadyForQuery() { 138 if (customSqlBox.getText().trim().equals("")) { 139 NotifyManager.getInstance().showError("Global filter cannot be empty"); 140 return false; 141 } 142 143 return true; 144 } 145 updateStateFromView()146 public void updateStateFromView() { 147 savedSqlCondition = customSqlBox.getText().trim(); 148 savedShowInvalid = showInvalid.getValue(); 149 } 150 updateViewFromState()151 public void updateViewFromState() { 152 customSqlBox.setText(savedSqlCondition); 153 showInvalid.setValue(savedShowInvalid); 154 } 155 getConditionArgs()156 public JSONObject getConditionArgs() { 157 String condition = savedSqlCondition; 158 if (!savedShowInvalid) { 159 parameterizedFieldPresenter.addFieldIfNotPresent(TestLabelField.TYPE_NAME, 160 "invalidated"); 161 condition = "(" + condition + ") AND test_label_invalidated.id IS NULL"; 162 } 163 164 JSONObject conditionArgs = new JSONObject(); 165 addIfNonempty(conditionArgs, "extra_where", condition); 166 for (HeaderField field : headerFields) { 167 field.addQueryParameters(conditionArgs); 168 } 169 170 return conditionArgs; 171 } 172 addIfNonempty(JSONObject conditionArgs, String key, String value)173 private void addIfNonempty(JSONObject conditionArgs, String key, String value) { 174 if (value.equals("")) { 175 return; 176 } 177 conditionArgs.put(key, new JSONString(value)); 178 } 179 refineCondition(String newCondition)180 public void refineCondition(String newCondition) { 181 setSqlCondition(TkoUtils.joinWithParens(" AND ", savedSqlCondition, newCondition)); 182 } 183 refineCondition(TestSet tests)184 public void refineCondition(TestSet tests) { 185 refineCondition(tests.getPartialSqlCondition()); 186 } 187 handleHistoryArguments(Map<String, String> arguments)188 public void handleHistoryArguments(Map<String, String> arguments) { 189 setSqlCondition(arguments.get("condition")); 190 savedShowInvalid = Boolean.valueOf(arguments.get("show_invalid")); 191 parameterizedFieldPresenter.handleHistoryArguments(arguments); 192 updateViewFromState(); 193 } 194 addHistoryArguments(Map<String, String> arguments)195 public void addHistoryArguments(Map<String, String> arguments) { 196 arguments.put("condition", savedSqlCondition); 197 arguments.put("show_invalid", Boolean.toString(savedShowInvalid)); 198 parameterizedFieldPresenter.addHistoryArguments(arguments); 199 } 200 fillDefaultHistoryValues(Map<String, String> arguments)201 public void fillDefaultHistoryValues(Map<String, String> arguments) { 202 Utils.setDefaultValue(arguments, "condition", ""); 203 Utils.setDefaultValue(arguments, "show_invalid", Boolean.toString(savedShowInvalid)); 204 } 205 onClick(ClickEvent event)206 public void onClick(ClickEvent event) { 207 if (event.getSource() == quickReferenceLink) { 208 handleQuickReferenceClick(); 209 } else { 210 assert event.getSource() == showHideControlsLink; 211 handleShowHideControlsClick(); 212 } 213 } 214 handleShowHideControlsClick()215 private void handleShowHideControlsClick() { 216 boolean areControlsVisible = showHideControlsLink.getText().equals(SHOW_CONTROLS); 217 allControlsPanel.setVisible(areControlsVisible); 218 showHideControlsLink.setText(areControlsVisible ? HIDE_CONTROLS : SHOW_CONTROLS); 219 for (CommonPanelListener listener : listeners) { 220 listener.onSetControlsVisible(areControlsVisible); 221 } 222 } 223 handleQuickReferenceClick()224 private void handleQuickReferenceClick() { 225 if (isQuickReferenceShowing()) { 226 quickReferencePopup.hide(); 227 quickReferenceLink.setText(SHOW_QUICK_REFERENCE); 228 } else { 229 quickReferencePopup.setPopupPositionAndShow(this); 230 quickReferenceLink.setText(HIDE_QUICK_REFERENCE); 231 } 232 } 233 isQuickReferenceShowing()234 private boolean isQuickReferenceShowing() { 235 return quickReferenceLink.getText().equals(HIDE_QUICK_REFERENCE); 236 } 237 generateQuickReferencePopup()238 private void generateQuickReferencePopup() { 239 FlexTable fieldTable = new FlexTable(); 240 fieldTable.setText(0, 0, "Name"); 241 fieldTable.setText(0, 1, "Field"); 242 fieldTable.getRowFormatter().setStyleName(0, "data-row-header"); 243 int row = 1; 244 for (FieldInfo fieldInfo : TkoUtils.getFieldList("all_fields")) { 245 fieldTable.setText(row, 0, fieldInfo.name); 246 fieldTable.setText(row, 1, fieldInfo.field); 247 row++; 248 } 249 quickReferencePopup = new PopupPanel(false); 250 quickReferencePopup.add(fieldTable); 251 } 252 253 /** 254 * PopupListener callback. 255 */ setPosition(int offsetWidth, int offsetHeight)256 public void setPosition(int offsetWidth, int offsetHeight) { 257 quickReferencePopup.setPopupPosition( 258 customSqlBox.getAbsoluteLeft() + customSqlBox.getOffsetWidth(), 259 customSqlBox.getAbsoluteTop()); 260 } 261 addListener(CommonPanelListener listener)262 public void addListener(CommonPanelListener listener) { 263 listeners.add(listener); 264 } 265 getHeaderFields()266 public HeaderFieldCollection getHeaderFields() { 267 return headerFields; 268 } 269 notifyOnFieldsChanged()270 private void notifyOnFieldsChanged() { 271 for (CommonPanelListener listener : listeners) { 272 listener.onFieldsChanged(); 273 } 274 } 275 } 276