| /* |
| * Copyright 2010 Google Inc. |
| * |
| * 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.gwt.user.cellview.client; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| /** |
| * An ordered list containing the sort history of {@link Column}s in a table. |
| * The 0th item is the {@link ColumnSortInfo} of the most recently sorted |
| * column. |
| */ |
| public class ColumnSortList { |
| |
| /** |
| * Information about the sort order of a specific column in a table. |
| */ |
| public static class ColumnSortInfo { |
| |
| private final boolean ascending; |
| private final Column<?, ?> column; |
| |
| /** |
| * Construct a new {@link ColumnSortInfo}. |
| * |
| * @param column the column index |
| * @param ascending true if sorted ascending |
| */ |
| public ColumnSortInfo(Column<?, ?> column, boolean ascending) { |
| this.column = column; |
| this.ascending = ascending; |
| } |
| |
| /** |
| * Default constructor used for RPC. |
| */ |
| ColumnSortInfo() { |
| this(null, true); |
| } |
| |
| /** |
| * Check if this object is equal to another. The objects are equal if the |
| * column and ascending values are the equal. |
| * |
| * @param obj the object to check for equality |
| * @return true if objects are the same |
| */ |
| @Override |
| public boolean equals(Object obj) { |
| if (obj == this) { |
| return true; |
| } else if (!(obj instanceof ColumnSortInfo)) { |
| return false; |
| } |
| |
| ColumnSortInfo other = (ColumnSortInfo) obj; |
| return equalsOrBothNull(getColumn(), other.getColumn()) |
| && isAscending() == other.isAscending(); |
| } |
| |
| /** |
| * Get the {@link Column} that was sorted. |
| * |
| * @return the {@link Column} |
| */ |
| public Column<?, ?> getColumn() { |
| return column; |
| } |
| |
| @Override |
| public int hashCode() { |
| return 31 * (column == null ? 0 : column.hashCode()) |
| + (ascending ? 1 : 0); |
| } |
| |
| /** |
| * Check if the column was sorted in ascending or descending order. |
| * |
| * @return true if ascending, false if descending |
| */ |
| public boolean isAscending() { |
| return ascending; |
| } |
| |
| private boolean equalsOrBothNull(Object a, Object b) { |
| return a == null ? b == null : a.equals(b); |
| } |
| } |
| |
| /** |
| * The delegate that handles modifications to the list. |
| */ |
| public static interface Delegate { |
| |
| /** |
| * Called when the list is modified. |
| */ |
| void onModification(); |
| } |
| |
| /** |
| * The delegate that handles modifications. |
| */ |
| private final Delegate delegate; |
| |
| /** |
| * A List used to manage the insertion/removal of {@link ColumnSortInfo}. |
| */ |
| private final List<ColumnSortInfo> infos = new ArrayList<ColumnSortInfo>(); |
| |
| /** |
| * Construct a new {@link ColumnSortList} without a {@link Delegate}. |
| */ |
| public ColumnSortList() { |
| this(null); |
| } |
| |
| /** |
| * Construct a new {@link ColumnSortList} with the specified {@link Delegate}. |
| * |
| * @param delegate the {@link Delegate} to inform of modifications |
| */ |
| public ColumnSortList(Delegate delegate) { |
| this.delegate = delegate; |
| } |
| |
| /** |
| * Removes all of the elements from this list. |
| */ |
| public void clear() { |
| infos.clear(); |
| fireDelegate(); |
| } |
| |
| /** |
| * Check if the specified object equals this list. Two {@link ColumnSortList} |
| * are equals if they are the same size, and all entries are |
| * <code>equals</code> and in the same order. |
| */ |
| @Override |
| public boolean equals(Object obj) { |
| if (obj == this) { |
| return true; |
| } else if (!(obj instanceof ColumnSortList)) { |
| return false; |
| } |
| |
| // Check the size of the lists. |
| ColumnSortList other = (ColumnSortList) obj; |
| return infos.equals(other.infos); |
| } |
| |
| /** |
| * Get the {@link ColumnSortInfo} at the specified index. |
| * |
| * @param index the index |
| * @return the {@link ColumnSortInfo} |
| */ |
| public ColumnSortInfo get(int index) { |
| return infos.get(index); |
| } |
| |
| @Override |
| public int hashCode() { |
| return 31 * infos.hashCode() + 13; |
| } |
| |
| /** |
| * Inserts the specified {@link ColumnSortInfo} at the specified position in |
| * this list. If the column already exists in the sort info, the index will be |
| * adjusted to account for any removed entries. |
| * |
| * @param sortInfo the {@link ColumnSortInfo} to add |
| */ |
| public void insert(int index, ColumnSortInfo sortInfo) { |
| if (sortInfo == null) { |
| throw new IllegalArgumentException("sortInfo cannot be null"); |
| } |
| |
| // Remove sort info for duplicate columns |
| Column<?, ?> column = sortInfo.getColumn(); |
| for (int i = 0; i < infos.size(); i++) { |
| ColumnSortInfo curInfo = infos.get(i); |
| if (curInfo.getColumn() == column) { |
| infos.remove(i); |
| if (i < index) { |
| index--; |
| } |
| i--; |
| } |
| } |
| |
| // Insert the new sort info |
| infos.add(index, sortInfo); |
| fireDelegate(); |
| } |
| |
| /** |
| * Push a {@link Column} onto the list at index zero, setting ascending to |
| * true. If the column already exists, it will be removed from its current |
| * position and placed at the start of the list. If the Column is already at |
| * the start of the list, its ascending bit will be flipped (ascending to |
| * descending and vice versa). |
| * |
| * @param column the {@link Column} to push |
| * @return the {@link ColumnSortInfo} that was pushed |
| */ |
| public ColumnSortInfo push(Column<?, ?> column) { |
| // If the column matches the primary column, toggle the order. |
| boolean ascending = true; |
| if (size() > 0 && get(0).getColumn() == column) { |
| ascending = !get(0).isAscending(); |
| } |
| |
| // Push the new column. |
| ColumnSortInfo toRet = new ColumnSortInfo(column, ascending); |
| push(toRet); |
| return toRet; |
| } |
| |
| /** |
| * Push a {@link ColumnSortInfo} onto the list at index zero. If the column |
| * already exists, it will be removed from its current position and placed at |
| * the start of the list. |
| * |
| * @param sortInfo the {@link ColumnSortInfo} to push |
| */ |
| public void push(ColumnSortInfo sortInfo) { |
| insert(0, sortInfo); |
| } |
| |
| /** |
| * Remove a {@link ColumnSortInfo} from the list. |
| * |
| * @param sortInfo the {@link ColumnSortInfo} to remove |
| */ |
| public boolean remove(ColumnSortInfo sortInfo) { |
| boolean toRet = infos.remove(sortInfo); |
| fireDelegate(); |
| return toRet; |
| } |
| |
| /** |
| * Get the size of the list. |
| * |
| * @return the number of {@link ColumnSortInfo} in the list |
| */ |
| public int size() { |
| return infos.size(); |
| } |
| |
| private void fireDelegate() { |
| if (delegate != null) { |
| delegate.onModification(); |
| } |
| } |
| } |