| // Copyright (C) 2014 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package com.google.gerrit.client; |
| |
| import com.google.gerrit.client.ui.NavigationTable; |
| import com.google.gerrit.client.ui.OnEditEnabler; |
| import com.google.gerrit.client.ui.SmallHeading; |
| import com.google.gwt.event.dom.client.ClickEvent; |
| import com.google.gwt.event.dom.client.ClickHandler; |
| import com.google.gwt.event.dom.client.KeyCodes; |
| import com.google.gwt.event.dom.client.KeyPressEvent; |
| import com.google.gwt.event.dom.client.KeyPressHandler; |
| import com.google.gwt.event.logical.shared.ValueChangeEvent; |
| import com.google.gwt.event.logical.shared.ValueChangeHandler; |
| import com.google.gwt.user.client.Event; |
| import com.google.gwt.user.client.ui.Button; |
| import com.google.gwt.user.client.ui.CheckBox; |
| import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter; |
| import com.google.gwt.user.client.ui.FlowPanel; |
| import com.google.gwt.user.client.ui.FocusWidget; |
| import com.google.gwt.user.client.ui.HasEnabled; |
| import com.google.gwt.user.client.ui.HorizontalPanel; |
| import com.google.gwt.user.client.ui.Image; |
| import com.google.gwt.user.client.ui.ImageResourceRenderer; |
| import com.google.gwtexpui.globalkey.client.NpTextBox; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| public class StringListPanel extends FlowPanel implements HasEnabled { |
| private final StringListTable t; |
| private HorizontalPanel titlePanel; |
| protected final HorizontalPanel buttonPanel; |
| private final Button deleteButton; |
| private Image info; |
| protected FocusWidget widget; |
| |
| public StringListPanel(String title, List<String> fieldNames, FocusWidget w, boolean autoSort) { |
| widget = w; |
| if (title != null) { |
| titlePanel = new HorizontalPanel(); |
| SmallHeading titleLabel = new SmallHeading(title); |
| titlePanel.add(titleLabel); |
| add(titlePanel); |
| } |
| |
| t = new StringListTable(fieldNames, autoSort); |
| add(t); |
| |
| buttonPanel = new HorizontalPanel(); |
| buttonPanel.setStyleName(Gerrit.RESOURCES.css().stringListPanelButtons()); |
| deleteButton = new Button(Gerrit.C.stringListPanelDelete()); |
| deleteButton.setEnabled(false); |
| deleteButton.addClickHandler( |
| new ClickHandler() { |
| @Override |
| public void onClick(ClickEvent event) { |
| widget.setEnabled(true); |
| t.deleteChecked(); |
| } |
| }); |
| buttonPanel.add(deleteButton); |
| add(buttonPanel); |
| } |
| |
| public void display(List<List<String>> values) { |
| t.display(values); |
| } |
| |
| public void setInfo(String msg) { |
| if (info == null && titlePanel != null) { |
| info = new Image(Gerrit.RESOURCES.info()); |
| titlePanel.add(info); |
| } |
| if (info != null) { |
| info.setTitle(msg); |
| } |
| } |
| |
| public List<List<String>> getValues() { |
| return t.getValues(); |
| } |
| |
| public List<String> getValues(int i) { |
| List<List<String>> allValuesList = getValues(); |
| List<String> singleValueList = new ArrayList<>(allValuesList.size()); |
| for (List<String> values : allValuesList) { |
| singleValueList.add(values.get(i)); |
| } |
| return singleValueList; |
| } |
| |
| private class StringListTable extends NavigationTable<List<String>> { |
| private final Button addButton; |
| private final List<NpTextBox> inputs; |
| private final boolean autoSort; |
| |
| StringListTable(List<String> names, boolean autoSort) { |
| this.autoSort = autoSort; |
| |
| addButton = new Button(new ImageResourceRenderer().render(Gerrit.RESOURCES.listAdd())); |
| addButton.setTitle(Gerrit.C.stringListPanelAdd()); |
| OnEditEnabler e = new OnEditEnabler(addButton); |
| inputs = new ArrayList<>(); |
| |
| FlexCellFormatter fmt = table.getFlexCellFormatter(); |
| fmt.addStyleName(0, 0, Gerrit.RESOURCES.css().iconHeader()); |
| fmt.addStyleName(0, 0, Gerrit.RESOURCES.css().leftMostCell()); |
| for (int i = 0; i < names.size(); i++) { |
| fmt.addStyleName(0, i + 1, Gerrit.RESOURCES.css().dataHeader()); |
| table.setText(0, i + 1, names.get(i)); |
| |
| NpTextBox input = new NpTextBox(); |
| input.setVisibleLength(35); |
| input.addKeyPressHandler( |
| new KeyPressHandler() { |
| @Override |
| public void onKeyPress(KeyPressEvent event) { |
| if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) { |
| widget.setEnabled(true); |
| add(); |
| } |
| } |
| }); |
| inputs.add(input); |
| fmt.addStyleName(1, i + 1, Gerrit.RESOURCES.css().dataHeader()); |
| table.setWidget(1, i + 1, input); |
| e.listenTo(input); |
| } |
| addButton.setEnabled(false); |
| |
| addButton.addClickHandler( |
| new ClickHandler() { |
| @Override |
| public void onClick(ClickEvent event) { |
| widget.setEnabled(true); |
| add(); |
| } |
| }); |
| fmt.addStyleName(1, 0, Gerrit.RESOURCES.css().iconHeader()); |
| fmt.addStyleName(1, 0, Gerrit.RESOURCES.css().leftMostCell()); |
| table.setWidget(1, 0, addButton); |
| |
| if (!autoSort) { |
| fmt.addStyleName(0, names.size() + 1, Gerrit.RESOURCES.css().iconHeader()); |
| fmt.addStyleName(0, names.size() + 2, Gerrit.RESOURCES.css().iconHeader()); |
| fmt.addStyleName(1, names.size() + 1, Gerrit.RESOURCES.css().iconHeader()); |
| fmt.addStyleName(1, names.size() + 2, Gerrit.RESOURCES.css().iconHeader()); |
| } |
| } |
| |
| void display(List<List<String>> values) { |
| for (int row = 2; row < table.getRowCount(); row++) { |
| table.removeRow(row--); |
| } |
| int row = 2; |
| for (List<String> v : values) { |
| populate(row, v); |
| row++; |
| } |
| updateNavigationLinks(); |
| } |
| |
| List<List<String>> getValues() { |
| List<List<String>> values = new ArrayList<>(); |
| for (int row = 2; row < table.getRowCount(); row++) { |
| values.add(getRowItem(row)); |
| } |
| return values; |
| } |
| |
| @Override |
| protected List<String> getRowItem(int row) { |
| List<String> v = new ArrayList<>(); |
| for (int i = 0; i < inputs.size(); i++) { |
| v.add(table.getText(row, i + 1)); |
| } |
| return v; |
| } |
| |
| private void populate(int row, List<String> values) { |
| FlexCellFormatter fmt = table.getFlexCellFormatter(); |
| fmt.addStyleName(row, 0, Gerrit.RESOURCES.css().iconCell()); |
| fmt.addStyleName(row, 0, Gerrit.RESOURCES.css().leftMostCell()); |
| CheckBox checkBox = new CheckBox(); |
| checkBox.addValueChangeHandler( |
| new ValueChangeHandler<Boolean>() { |
| @Override |
| public void onValueChange(ValueChangeEvent<Boolean> event) { |
| enableDelete(); |
| } |
| }); |
| table.setWidget(row, 0, checkBox); |
| for (int i = 0; i < values.size(); i++) { |
| fmt.addStyleName(row, i + 1, Gerrit.RESOURCES.css().dataCell()); |
| table.setText(row, i + 1, values.get(i)); |
| } |
| if (!autoSort) { |
| fmt.addStyleName(row, values.size() + 1, Gerrit.RESOURCES.css().iconCell()); |
| fmt.addStyleName(row, values.size() + 2, Gerrit.RESOURCES.css().dataCell()); |
| |
| Image down = new Image(Gerrit.RESOURCES.arrowDown()); |
| down.setTitle(Gerrit.C.stringListPanelDown()); |
| down.addClickHandler( |
| new ClickHandler() { |
| @Override |
| public void onClick(ClickEvent event) { |
| moveDown(row); |
| } |
| }); |
| table.setWidget(row, values.size() + 1, down); |
| |
| Image up = new Image(Gerrit.RESOURCES.arrowUp()); |
| up.setTitle(Gerrit.C.stringListPanelUp()); |
| up.addClickHandler( |
| new ClickHandler() { |
| @Override |
| public void onClick(ClickEvent event) { |
| moveUp(row); |
| } |
| }); |
| table.setWidget(row, values.size() + 2, up); |
| } |
| } |
| |
| @Override |
| protected void onCellSingleClick(Event event, int row, int column) { |
| if (column == inputs.size() + 1 && row >= 2 && row < table.getRowCount() - 2) { |
| moveDown(row); |
| } else if (column == inputs.size() + 2 && row > 2) { |
| moveUp(row); |
| } |
| } |
| |
| void moveDown(int row) { |
| if (row < table.getRowCount() - 1) { |
| swap(row, row + 1); |
| } |
| } |
| |
| void moveUp(int row) { |
| if (row > 2) { |
| swap(row - 1, row); |
| } |
| } |
| |
| void swap(int row1, int row2) { |
| List<String> value = getRowItem(row1); |
| List<String> nextValue = getRowItem(row2); |
| populate(row1, nextValue); |
| populate(row2, value); |
| updateNavigationLinks(); |
| widget.setEnabled(true); |
| } |
| |
| private void updateNavigationLinks() { |
| if (!autoSort) { |
| for (int row = 2; row < table.getRowCount(); row++) { |
| table.getWidget(row, inputs.size() + 1).setVisible(row < table.getRowCount() - 1); |
| table.getWidget(row, inputs.size() + 2).setVisible(row > 2); |
| } |
| } |
| } |
| |
| void add() { |
| List<String> values = new ArrayList<>(); |
| for (NpTextBox input : inputs) { |
| values.add(input.getValue().trim()); |
| input.setValue(""); |
| } |
| insert(values); |
| } |
| |
| void insert(List<String> v) { |
| int insertPos = table.getRowCount(); |
| if (autoSort) { |
| for (int row = 1; row < table.getRowCount(); row++) { |
| int compareResult = v.get(0).compareTo(table.getText(row, 1)); |
| if (compareResult < 0) { |
| insertPos = row; |
| break; |
| } else if (compareResult == 0) { |
| return; |
| } |
| } |
| } |
| table.insertRow(insertPos); |
| populate(insertPos, v); |
| updateNavigationLinks(); |
| } |
| |
| void enableDelete() { |
| for (int row = 2; row < table.getRowCount(); row++) { |
| if (((CheckBox) table.getWidget(row, 0)).getValue()) { |
| deleteButton.setEnabled(true); |
| return; |
| } |
| } |
| deleteButton.setEnabled(false); |
| } |
| |
| void deleteChecked() { |
| deleteButton.setEnabled(false); |
| for (int row = 2; row < table.getRowCount(); row++) { |
| if (((CheckBox) table.getWidget(row, 0)).getValue()) { |
| table.removeRow(row--); |
| } |
| } |
| updateNavigationLinks(); |
| } |
| |
| @Override |
| protected void onOpenRow(int row) {} |
| |
| @Override |
| protected Object getRowItemKey(List<String> item) { |
| return item.get(0); |
| } |
| |
| void setEnabled(boolean enabled) { |
| addButton.setVisible(enabled); |
| for (NpTextBox input : inputs) { |
| input.setEnabled(enabled); |
| } |
| for (int row = 2; row < table.getRowCount(); row++) { |
| table.getWidget(row, 0).setVisible(enabled); |
| if (!autoSort) { |
| table.getWidget(row, inputs.size() + 1).setVisible(enabled); |
| table.getWidget(row, inputs.size() + 2).setVisible(enabled); |
| } |
| } |
| if (enabled) { |
| updateNavigationLinks(); |
| } |
| } |
| } |
| |
| @Override |
| public boolean isEnabled() { |
| return deleteButton.isVisible(); |
| } |
| |
| @Override |
| public void setEnabled(boolean enabled) { |
| t.setEnabled(enabled); |
| deleteButton.setVisible(enabled); |
| } |
| } |