package org.ovirt.engine.ui.common.widget.table; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.cellview.client.Column; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Widget; /** * Context menu widget providing UI for {@link ColumnController} interface. * <p> * By design, the API is column-based (instead of index-based) so that * menu item operations map directly to GWT {@link Column} objects. * * @param <T> * Table row data type. */ public class ColumnContextMenu<T> extends Composite { interface WidgetUiBinder extends UiBinder<Widget, ColumnContextMenu> { WidgetUiBinder uiBinder = GWT.create(WidgetUiBinder.class); } @UiField FlowPanel container; private final ColumnController<T> controller; private final Map<Column<T, ?>, ColumnContextMenuItem<T>> items = new HashMap<>(); public ColumnContextMenu(ColumnController<T> controller) { this.controller = controller; initWidget(WidgetUiBinder.uiBinder.createAndBindUi(this)); } /** * Add new item to the context menu. */ public void addItem(Column<T, ?> column) { if (containsItem(column)) { return; } ColumnContextMenuItem<T> newItem = new ColumnContextMenuItem<>(controller, column); items.put(column, newItem); container.add(newItem); } /** * Remove item from the context menu. */ public void removeItem(Column<T, ?> column) { ColumnContextMenuItem<T> removedItem = items.remove(column); if (removedItem != null) { container.remove(removedItem); } } /** * Check if the context menu contains given item. */ public boolean containsItem(Column<T, ?> column) { return items.containsKey(column); } /** * Update context menu items according to the {@link ColumnController}. */ public void update() { List<Column<T, ?>> columns = new ArrayList<>(items.keySet()); Map<Integer, ColumnContextMenuItem<T>> itemsToRender = new TreeMap<>(); // Collect valid items for rendering, remove invalid items for (Column<T, ?> column : columns) { int columnIndex = controller.getColumnIndex(column); if (columnIndex >= 0) { ColumnContextMenuItem<T> item = items.get(column); itemsToRender.put(columnIndex, item); } else { removeItem(column); } } // Render items container.clear(); for (ColumnContextMenuItem<T> item : itemsToRender.values()) { container.add(item); item.update(); } } }