/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.ui.common.widget.accumulator; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.teiid.designer.ui.common.InternalUiConstants; import org.teiid.designer.ui.common.UiConstants; import org.teiid.designer.ui.common.UiPlugin; import org.teiid.designer.ui.common.util.OrderableViewerSorter; import org.teiid.designer.ui.common.widget.MessageLabel; /** * AccumulatorPanel The panel contains two display columns with a column of buttons between them. The lefthand, or "available" * column is displayed through an interface so that a List, Table, or Tree can be accomodated. The righthand, or "selected" column * is displayed by this panel through a one-column Table. The buttons are move-right, move-all-right, move-left, and * move-all-left. In addition up and down buttons apply to the contents of the right side table. * * @since 8.0 */ public class AccumulatorPanel extends Composite implements InternalUiConstants { // ============================================================ // Static variables // ============================================================ final public static int DEFAULT_RESET_BUTTON_MARGIN_HEIGHT = 10; final public static int DEFAULT_LEFT_SIDE_WIDTH_HINT = (int)(Display.getDefault().getBounds().width * .10); final public static int DEFAULT_RIGHT_SIDE_WIDTH_HINT = DEFAULT_LEFT_SIDE_WIDTH_HINT; final public static int DEFAULT_LEFT_AND_RIGHT_SIDE_HEIGHT_HINT = (int)(Display.getDefault().getBounds().height * .10); // ============================================================ // Instance variables // ============================================================ private IAccumulatorSource source; private ILabelProvider labelProvider = null; private Table rightTable; private TableViewer tableViewer; private Collection /*<Object>*/initialRightSideItems; private String leftSideLabelText = null; private String rightSideLabelText = null; private Button rightButton; private Button leftButton; private Button allRightButton; private Button allLeftButton; private Button upButton; private Button downButton; private Button resetButton; private Button sortButton; private int resetButtonMarginHeight; private int leftSideWidthHint; private int rightSideWidthHint; private int leftAndRightSideHeightHint; private boolean isSorting = false; private boolean ignoreLeftSideSelectionChanges = false; private boolean ignoreRightSideSelectionChanges = false; private java.util.List /*<IAccumulatedValuesChangeListener>*/changeListeners; private MessageLabel messageLabel; // ============================================================ // Constructors // ============================================================ /** * Constructor. * * @param parent Parent of this control * @param source Provider of data for "available" column, and provider of control to display the column * @param initialRightSideItemsColl Items initially displayed in the "selected" column * @param labelProvider Optional ILabelProvider; if this argument is non-null, then this label provider will be used to * display the right-hand side list (actually a one-column table); if null, the toString() of each object will be used, * with no image. * @param leftSideLabelText Optional left side column label. Default if null is "Available". * @param rightSideLabelText Optional right side column label. Default if null is "Selected". * @param resetButtonMarginHeight Display margin height in pixels for the Reset button. If < 1, default value is used. * @param leftSideWidthHint Width hint for left side control. If < 1, default value is used. * @param rightSideWidthHint Width hint for right side control. If < 1, default value is used. * @param leftAndRightSideHeightHint Height hint for both the left and right side controls. If < 1, default value is used. */ public AccumulatorPanel( Composite parent, IAccumulatorSource source, Collection /*<Object>*/initialRightSideItemsColl, ILabelProvider labelProvider, String leftSideLabelText, String rightSideLabelText, int resetButtonMarginHeight, int leftSideWidthHint, int rightSideWidthHint, int leftAndRightSideHeightHint ) { super(parent, SWT.NONE); this.source = source; this.labelProvider = labelProvider; this.initialRightSideItems = initialRightSideItemsColl; this.leftSideLabelText = leftSideLabelText; this.rightSideLabelText = rightSideLabelText; if (resetButtonMarginHeight < 0) { this.resetButtonMarginHeight = DEFAULT_RESET_BUTTON_MARGIN_HEIGHT; } else { this.resetButtonMarginHeight = resetButtonMarginHeight; } if (leftSideWidthHint < 1) { this.leftSideWidthHint = DEFAULT_LEFT_SIDE_WIDTH_HINT; } else { this.leftSideWidthHint = leftSideWidthHint; } if (rightSideWidthHint < 1) { this.rightSideWidthHint = DEFAULT_RIGHT_SIDE_WIDTH_HINT; } else { this.rightSideWidthHint = rightSideWidthHint; } if (leftAndRightSideHeightHint < 1) { this.leftAndRightSideHeightHint = DEFAULT_LEFT_AND_RIGHT_SIDE_HEIGHT_HINT; } else { this.leftAndRightSideHeightHint = leftAndRightSideHeightHint; } init(); } /** * Constructor. * * @param parent Parent of this control * @param source Provider of data for "available" column, and provider of control to display the column * @param initialRightSideItemsColl items initially displayed in the "selected" column * @param labelProvider optional ILabelProvider; if this argument is non-null, then this label provider will be used to * display the right-hand side list (actually a one-column table); if null, the toString() of each object will be used, * with no image. * @param leftSideLabelText optional left side column label. Default if null is "Available". * @param rightSideLabelText optional right side column label. Default if null is "Selected". */ public AccumulatorPanel( Composite parent, IAccumulatorSource source, Collection /*<Object>*/initialRightSideItemsColl, ILabelProvider labelProvider, String leftSideLabelText, String rightSideLabelText ) { this(parent, source, initialRightSideItemsColl, labelProvider, leftSideLabelText, rightSideLabelText, -1, -1, -1, -1); } // ============================================================ // Instance methods // ============================================================ /** * Initialize the panel. */ private void init() { // Set overall grid layout GridLayout gridLayout = new GridLayout(); this.setLayout(gridLayout); gridLayout.numColumns = 4; GridData gridData = new GridData(GridData.FILL_BOTH); this.setLayoutData(gridData); // Set label above the Available side Label leftSideLabel = new Label(this, SWT.NONE); if (leftSideLabelText == null) { leftSideLabelText = Util.getString("AccumulatorColumnLabel.available"); //$NON-NLS-1$ } leftSideLabel.setText(leftSideLabelText); GridData leftSideLabelGridData = new GridData(); leftSideLabelGridData.horizontalSpan = 2; leftSideLabelGridData.horizontalAlignment = GridData.FILL; leftSideLabelGridData.verticalAlignment = GridData.FILL; leftSideLabel.setLayoutData(leftSideLabelGridData); // Set label above the Selected side Label rightSideLabel = new Label(this, SWT.NONE); if (rightSideLabelText == null) { rightSideLabelText = Util.getString("AccumulatorColumnLabel.selected"); //$NON-NLS-1$ } rightSideLabel.setText(rightSideLabelText); GridData rightSideLabelGridData = new GridData(); rightSideLabelGridData.horizontalSpan = 2; rightSideLabelGridData.verticalAlignment = GridData.FILL; rightSideLabelGridData.horizontalAlignment = GridData.FILL; rightSideLabel.setLayoutData(rightSideLabelGridData); // Add the control which displays the Available side list Control leftSideControl = source.createControl(this); source.addSelectionListener(new SelectionListener() { @Override public void widgetDefaultSelected( SelectionEvent ev ) { leftSideControlSelectionChanged(); } @Override public void widgetSelected( SelectionEvent ev ) { leftSideControlSelectionChanged(); } }); GridData leftSideControlGridData = new GridData(); leftSideControlGridData.widthHint = leftSideWidthHint; leftSideControlGridData.heightHint = leftAndRightSideHeightHint; leftSideControlGridData.verticalAlignment = GridData.FILL; leftSideControlGridData.horizontalAlignment = GridData.FILL; leftSideControlGridData.grabExcessHorizontalSpace = true; leftSideControlGridData.grabExcessVerticalSpace = true; leftSideControl.setLayoutData(leftSideControlGridData); // Add the navigation buttons Composite controlButtons = new Composite(this, SWT.NONE); GridData controlButtonsGridData = new GridData(); controlButtonsGridData.verticalAlignment = GridData.FILL; controlButtonsGridData.horizontalAlignment = GridData.FILL; controlButtons.setLayoutData(controlButtonsGridData); GridLayout controlButtonsGridLayout = new GridLayout(); controlButtonsGridLayout.verticalSpacing = 2; controlButtons.setLayout(controlButtonsGridLayout); rightButton = new Button(controlButtons, SWT.PUSH); rightButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent ev ) { rightButtonPressed(); } }); Image rightButtonImage = UiPlugin.getDefault().getImage(UiConstants.Images.RIGHT); rightButton.setImage(rightButtonImage); GridData rightButtonGridData = new GridData(); rightButtonGridData.verticalAlignment = GridData.FILL; rightButtonGridData.horizontalAlignment = GridData.FILL; rightButton.setLayoutData(rightButtonGridData); leftButton = new Button(controlButtons, SWT.PUSH); leftButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent ev ) { leftButtonPressed(); } }); Image leftButtonImage = UiPlugin.getDefault().getImage(UiConstants.Images.LEFT); leftButton.setImage(leftButtonImage); GridData leftButtonGridData = new GridData(); leftButtonGridData.verticalAlignment = GridData.FILL; leftButtonGridData.horizontalAlignment = GridData.FILL; leftButton.setLayoutData(leftButtonGridData); allRightButton = new Button(controlButtons, SWT.PUSH); allRightButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent ev ) { allRightButtonPressed(); } }); Image allRightButtonImage = UiPlugin.getDefault().getImage(UiConstants.Images.ALL_RIGHT); allRightButton.setImage(allRightButtonImage); GridData allRightButtonGridData = new GridData(); allRightButtonGridData.verticalAlignment = GridData.FILL; allRightButtonGridData.horizontalAlignment = GridData.FILL; allRightButton.setLayoutData(allRightButtonGridData); allRightButton.setVisible(this.source.supportsAddAll()); allLeftButton = new Button(controlButtons, SWT.PUSH); allLeftButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent ev ) { allLeftButtonPressed(); } }); Image allLeftButtonImage = UiPlugin.getDefault().getImage(UiConstants.Images.ALL_LEFT); allLeftButton.setImage(allLeftButtonImage); GridData allLeftButtonGridData = new GridData(); allLeftButtonGridData.verticalAlignment = GridData.FILL; allLeftButtonGridData.horizontalAlignment = GridData.FILL; allLeftButton.setLayoutData(allLeftButtonGridData); // Add the Selected list rightTable = new Table(this, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); tableViewer = new TableViewer(rightTable); tableViewer.setSorter(new OrderableViewerSorter()); if (labelProvider != null) { tableViewer.setLabelProvider(labelProvider); } rightTable.addSelectionListener(new SelectionListener() { @Override public void widgetDefaultSelected( SelectionEvent ev ) { rightSideControlSelectionChanged(); } @Override public void widgetSelected( SelectionEvent ev ) { rightSideControlSelectionChanged(); } }); GridData rightTableGridData = new GridData(); rightTableGridData.widthHint = rightSideWidthHint; rightTableGridData.heightHint = leftAndRightSideHeightHint; rightTableGridData.verticalAlignment = GridData.FILL; rightTableGridData.horizontalAlignment = GridData.FILL; rightTableGridData.grabExcessHorizontalSpace = true; rightTableGridData.grabExcessVerticalSpace = true; rightTable.setLayoutData(rightTableGridData); // Add the up and down buttons Composite upDownButtons = new Composite(this, SWT.NONE); GridData upDownButtonsGridData = new GridData(); upDownButtonsGridData.verticalAlignment = GridData.FILL; upDownButtonsGridData.horizontalAlignment = GridData.FILL; upDownButtons.setLayoutData(upDownButtonsGridData); GridLayout upDownButtonsGridLayout = new GridLayout(); upDownButtonsGridLayout.verticalSpacing = 2; upDownButtons.setLayout(upDownButtonsGridLayout); upButton = new Button(upDownButtons, SWT.PUSH); upButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent ev ) { upButtonPressed(); } }); Image upButtonImage = UiPlugin.getDefault().getImage(UiConstants.Images.UP); upButton.setImage(upButtonImage); GridData upButtonGridData = new GridData(); upButtonGridData.verticalAlignment = GridData.FILL; upButtonGridData.horizontalAlignment = GridData.FILL; upButton.setLayoutData(upButtonGridData); downButton = new Button(upDownButtons, SWT.PUSH); downButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent ev ) { downButtonPressed(); } }); Image downButtonImage = UiPlugin.getDefault().getImage(UiConstants.Images.DOWN); downButton.setImage(downButtonImage); GridData downButtonGridData = new GridData(); downButtonGridData.verticalAlignment = GridData.FILL; downButtonGridData.horizontalAlignment = GridData.FILL; downButton.setLayoutData(downButtonGridData); // Add the Reset button Composite resetButtonComposite = new Composite(this, SWT.NONE); GridLayout resetButtonGridLayout = new GridLayout(); resetButtonGridLayout.marginHeight = this.resetButtonMarginHeight; resetButtonComposite.setLayout(resetButtonGridLayout); GridData resetButtonCompositeGridData = new GridData(); resetButtonCompositeGridData.horizontalSpan = 2; resetButtonComposite.setLayoutData(resetButtonCompositeGridData); resetButton = new Button(resetButtonComposite, SWT.PUSH); resetButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent ev ) { resetButtonPressed(); } }); String resetButtonText = Util.getString("ButtonText.reset"); //$NON-NLS-1$ resetButton.setText(resetButtonText); GridData resetButtonGridData = new GridData(GridData.FILL_BOTH); resetButtonGridData.verticalAlignment = GridData.VERTICAL_ALIGN_END; resetButtonGridData.horizontalAlignment = GridData.END; resetButton.setLayoutData(resetButtonGridData); // Add the Sort button (checkbox) sortButton = new Button(this, SWT.CHECK); sortButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent ev ) { sortButtonChanged(); } }); String sortButtonText = Util.getString("ButtonText.keepSortedAlphabetically"); //$NON-NLS-1$ sortButton.setText(sortButtonText); GridData sortButtonGridData = new GridData(); sortButtonGridData.verticalAlignment = GridData.BEGINNING; sortButtonGridData.horizontalAlignment = GridData.CENTER; sortButtonGridData.horizontalSpan = 2; sortButton.setLayoutData(sortButtonGridData); messageLabel = new MessageLabel(this); messageLabel.setAlignment(SWT.LEFT); messageLabel.setErrorStatus(null); messageLabel.setFont(this.getFont()); GridData messageLabelGridData = new GridData(GridData.FILL_HORIZONTAL); messageLabelGridData.horizontalSpan = 4; messageLabel.setLayoutData(messageLabelGridData); // Populate the list initiallyPopulateRightTable(); // Initially enable/disable the buttons setButtonStates(); // Initialize changeListeners to empty changeListeners = new ArrayList(); } public void addAccumulatedValuesChangeListener( IAccumulatedValuesChangeListener listener ) { changeListeners.add(listener); } private void initiallyPopulateRightTable() { rightTable.removeAll(); Object[] items = initialRightSideItems.toArray(); insertItemsIntoRightTable(items); notifyListeners(); } // private void insertItemIntoRightTable(Object item) { // if (!isSorting) { // java.util.List /*<String>*/ order = rightTableItemsListWithItemAppended(item); // OrderableViewerSorter sorter = (OrderableViewerSorter)tableViewer.getSorter(); // sorter.setStringsOrder(order); // } // tableViewer.add(item); // //Do not call notifyListeners() here. Call it in the methods calling this method. // } private void insertItemsIntoRightTable( Object[] items ) { if (!isSorting) { java.util.List /*<String>*/order = rightTableItemsListWithItemsAppended(items); OrderableViewerSorter sorter = (OrderableViewerSorter)tableViewer.getSorter(); sorter.setStringsOrder(order); } tableViewer.add(items); // Do not call notifyListeners() here. Call it in the methods calling this method. } void leftSideControlSelectionChanged() { if (!ignoreLeftSideSelectionChanges) { setButtonStates(); } } void rightSideControlSelectionChanged() { if (!ignoreRightSideSelectionChanges) { setButtonStates(); } } void rightButtonPressed() { // Get selected left side items Collection /*<Object>*/itemsToMoveToSelected = source.getSelectedAvailableValues(); // Insert each onto right side Object[] items = itemsToMoveToSelected.toArray(); insertItemsIntoRightTable(items); // Tell left side to remove them ignoreLeftSideSelectionChanges = true; source.accumulatedValuesAdded(itemsToMoveToSelected); ignoreLeftSideSelectionChanges = false; // Set button states setButtonStates(); notifyListeners(); } void leftButtonPressed() { // Get selected right side items int[] selectedItemIndices = rightTable.getSelectionIndices(); Object[] selectedObjects = new Object[selectedItemIndices.length]; for (int i = 0; i < selectedObjects.length; i++) { selectedObjects[i] = tableViewer.getElementAt(selectedItemIndices[i]); } ignoreRightSideSelectionChanges = true; // Remove them from the right side tableViewer.remove(selectedObjects); ignoreRightSideSelectionChanges = false; // Tell left side to add them source.accumulatedValuesRemoved(Arrays.asList(selectedObjects)); // Reset button states setButtonStates(); notifyListeners(); } void allRightButtonPressed() { // Get all left side items Collection /*<Object>*/itemsToMoveToSelected = source.getAvailableValues(); // Add each to right side Object[] items = itemsToMoveToSelected.toArray(); insertItemsIntoRightTable(items); // Tell left side to remove them ignoreLeftSideSelectionChanges = true; source.accumulatedValuesAdded(itemsToMoveToSelected); ignoreLeftSideSelectionChanges = false; // Set button states setButtonStates(); notifyListeners(); } void allLeftButtonPressed() { // Get all right side items Object[] obj = getRightTableItems(); ignoreRightSideSelectionChanges = true; // Remove them from right side tableViewer.remove(obj); // Tell left side to add them ignoreRightSideSelectionChanges = false; Collection itemsColl = Arrays.asList(obj); source.accumulatedValuesRemoved(itemsColl); // Set button states setButtonStates(); notifyListeners(); } void upButtonPressed() { // Have to compute what the new item order should be, tell it to the sorter and save // selections. Then remove all items and re-add them, which the sorter // will then put in the desired order. Then reset the selection. // Get all items Object[] items = getRightTableItems(); // Get selected items int[] selectedIndices = rightTable.getSelectionIndices(); Object[] selectedItems = new Object[selectedIndices.length]; for (int i = 0; i < selectedItems.length; i++) { selectedItems[i] = items[selectedIndices[i]]; } // Form into new order Object[] itemsInNewOrder = new Object[items.length]; int firstSelectionIndex = selectedIndices[0]; int lastSelectionIndex = selectedIndices[selectedIndices.length - 1]; for (int i = 0; i < firstSelectionIndex - 1; i++) { itemsInNewOrder[i] = items[i]; } Object itemMovingInBackOfSelections = items[firstSelectionIndex - 1]; for (int i = firstSelectionIndex; i <= lastSelectionIndex; i++) { itemsInNewOrder[i - 1] = items[i]; } itemsInNewOrder[lastSelectionIndex] = itemMovingInBackOfSelections; for (int i = lastSelectionIndex + 1; i < items.length; i++) { itemsInNewOrder[i] = items[i]; } // BWP- code to save and remove scroll bar positions removed, not working. Was attempting // to use getSelection() and setSelection(), but was not restoring scroll bar position. // Remove all items tableViewer.remove(items); // Set item order in the sorter java.util.List /*<String>*/order = new ArrayList(itemsInNewOrder.length); for (int i = 0; i < itemsInNewOrder.length; i++) { String text; if (labelProvider != null) { text = labelProvider.getText(itemsInNewOrder[i]); } else { text = itemsInNewOrder[i].toString(); } order.add(text); } OrderableViewerSorter sorter = (OrderableViewerSorter)tableViewer.getSorter(); sorter.setStringsOrder(order); // Re-add the items tableViewer.add(items); // Restore the selection java.util.List itemsList = Arrays.asList(getRightTableItems()); int[] newSelectedIndices = new int[selectedIndices.length]; for (int i = 0; i < newSelectedIndices.length; i++) { newSelectedIndices[i] = itemsList.indexOf(items[selectedIndices[i]]); } rightTable.setSelection(newSelectedIndices); setButtonStates(); } void downButtonPressed() { // Have to compute what the new item order should be, tell it to the sorter, and save // selections. Then remove all items and re-add them, which the sorter // will then put in the desired order. Then reset the selection. // Get all items Object[] items = getRightTableItems(); // Get selected items int[] selectedIndices = rightTable.getSelectionIndices(); Object[] selectedItems = new Object[selectedIndices.length]; for (int i = 0; i < selectedItems.length; i++) { selectedItems[i] = items[selectedIndices[i]]; } // Form into new order Object[] itemsInNewOrder = new Object[items.length]; int firstSelectionIndex = selectedIndices[0]; int lastSelectionIndex = selectedIndices[selectedIndices.length - 1]; for (int i = 0; i < firstSelectionIndex; i++) { itemsInNewOrder[i] = items[i]; } Object itemMovingInFrontOfSelections = items[lastSelectionIndex + 1]; for (int i = firstSelectionIndex; i <= lastSelectionIndex; i++) { itemsInNewOrder[i + 1] = items[i]; } itemsInNewOrder[firstSelectionIndex] = itemMovingInFrontOfSelections; for (int i = lastSelectionIndex + 2; i < items.length; i++) { itemsInNewOrder[i] = items[i]; } // BWP- code to save and remove scroll bar positions removed, not working. Was attempting // to use getSelection() and setSelection(), but was not restoring scroll bar position. // Remove all items tableViewer.remove(items); // Set item order in the sorter java.util.List /*<String>*/order = new ArrayList(itemsInNewOrder.length); for (int i = 0; i < itemsInNewOrder.length; i++) { String text; if (labelProvider != null) { text = labelProvider.getText(itemsInNewOrder[i]); } else { text = itemsInNewOrder[i].toString(); } order.add(text); } OrderableViewerSorter sorter = (OrderableViewerSorter)tableViewer.getSorter(); sorter.setStringsOrder(order); // Re-add the items tableViewer.add(items); // Restore the selection java.util.List itemsList = Arrays.asList(getRightTableItems()); int[] newSelectedIndices = new int[selectedIndices.length]; for (int i = 0; i < newSelectedIndices.length; i++) { newSelectedIndices[i] = itemsList.indexOf(items[selectedIndices[i]]); } rightTable.setSelection(newSelectedIndices); // Set button states setButtonStates(); } void sortButtonChanged() { if (sortButton.getSelection()) { // Now sorting. To get the items sorted, have to remove them then re-add them. First // save the selection so that we can restore it. isSorting = true; OrderableViewerSorter sorter = (OrderableViewerSorter)tableViewer.getSorter(); sorter.setStringsOrder(null); Object[] items = getRightTableItems(); int[] selectedItemIndices = rightTable.getSelectionIndices(); Object[] selectedItems = new Object[selectedItemIndices.length]; for (int i = 0; i < selectedItems.length; i++) { selectedItems[i] = items[selectedItemIndices[i]]; } // Save scroll bar positions int vertScrollBarPosit = -1; if (rightTable.getVerticalBar().isVisible()) { vertScrollBarPosit = rightTable.getVerticalBar().getSelection(); } int horizScrollBarPosit = -1; if (rightTable.getHorizontalBar().isVisible()) { horizScrollBarPosit = rightTable.getHorizontalBar().getSelection(); } // Remove all items tableViewer.remove(items); // Re-add the items. Will now be put in alphabetical order. tableViewer.add(items); // Restore the selection java.util.List itemsList = Arrays.asList(getRightTableItems()); int[] newSelectedItemIndices = new int[selectedItemIndices.length]; for (int i = 0; i < newSelectedItemIndices.length; i++) { newSelectedItemIndices[i] = itemsList.indexOf(items[selectedItemIndices[i]]); } rightTable.setSelection(newSelectedItemIndices); // Restore the scroll bar positions if (vertScrollBarPosit >= 0) { rightTable.getVerticalBar().setSelection(vertScrollBarPosit); } if (horizScrollBarPosit >= 0) { rightTable.getHorizontalBar().setSelection(horizScrollBarPosit); } } else { // Now not sorting. We don't change the already sorted table. Merely set a flag so // that future inserts will be at the end of the table. isSorting = false; } // Set the button states setButtonStates(); } private void setButtonStates() { int numLeftSideItems = source.getAvailableValuesCount(); if (numLeftSideItems == 0 || !source.getSelectionStatus().isOK()) { // No left side items. Disable both move-right buttons. rightButton.setEnabled(false); allRightButton.setEnabled(false); } else { allRightButton.setEnabled(true); // Enable move-selected-right button iff. anything selected. int numLeftSideSelectedItems = source.getSelectedAvailableValuesCount(); rightButton.setEnabled((numLeftSideSelectedItems > 0)); } int numRightSideItems = rightTable.getItemCount(); if (numRightSideItems == 0) { // No right side items. Disable both move-left buttons, also up and down buttons. leftButton.setEnabled(false); allLeftButton.setEnabled(false); upButton.setEnabled(false); downButton.setEnabled(false); } else { allLeftButton.setEnabled(true); // Enable move-selected-left button iff. anything selected. int numRightSideSelectedItems = rightTable.getSelectionCount(); boolean anyRightSideItemsSelected = (numRightSideSelectedItems > 0); leftButton.setEnabled(anyRightSideItemsSelected); if (sortButton.getSelection() || (!anyRightSideItemsSelected)) { // If sorting alphabetically or no right side items selected, disable up and down // buttons. upButton.setEnabled(false); downButton.setEnabled(false); } else { boolean contiguous = isRightSideSelectionContiguous(); if (contiguous) { // Contiguous right side selection. Enable up button iff. selection does not // include topmost row. Enable down button iff. selection does not include // bottommost row. upButton.setEnabled((!isFirstRightSideItemSelected())); downButton.setEnabled((!isLastRightSideItemSelected())); } else { // Right side selection is discontiguous. Disable up and down buttons. upButton.setEnabled(false); downButton.setEnabled(false); } } } setStatus(source.getSelectionStatus()); } private void setStatus( IStatus status ) { messageLabel.setErrorStatus(status); } private boolean isRightSideSelectionContiguous() { int[] indices = rightTable.getSelectionIndices(); boolean contiguous; if (indices.length == 0) { contiguous = false; } else { boolean gapFound = false; int i = 0; while ((i < indices.length - 1) && (!gapFound)) { if (indices[i + 1] - indices[i] > 1) { gapFound = true; } else { i++; } } contiguous = (!gapFound); } return contiguous; } private boolean isFirstRightSideItemSelected() { int[] indices = rightTable.getSelectionIndices(); boolean firstItemSelected; if (indices.length == 0) { firstItemSelected = false; } else { firstItemSelected = (indices[0] == 0); } return firstItemSelected; } private boolean isLastRightSideItemSelected() { int[] indices = rightTable.getSelectionIndices(); boolean lastItemSelected; if (indices.length == 0) { lastItemSelected = false; } else { lastItemSelected = (indices[indices.length - 1] == rightTable.getItemCount() - 1); } return lastItemSelected; } void resetButtonPressed() { // First, figure out which items currently on right side did not start out on right // side. Collection /*<Object>*/itemsThatWereAddedToRight = getItemsMovedToSelected(); // Next, figure out which items started out on the right side but are not there now. Collection /*<String>*/itemsThatWereRemovedFromRight = getItemsRemovedFromSelected(); // Re-populate the righthand list to its initial state. initiallyPopulateRightTable(); // Inform the source of values removed from the right side and values added to the // right side. source.accumulatedValuesRemoved(itemsThatWereAddedToRight); source.accumulatedValuesAdded(itemsThatWereRemovedFromRight); // Set the button states setButtonStates(); } private Object[] getRightTableItems() { // Return all items on the right side. int numItems = rightTable.getItemCount(); Object[] items = new Object[numItems]; for (int i = 0; i < numItems; i++) { items[i] = tableViewer.getElementAt(i); } return items; } // private java.util.List /*<String>*/ rightTableItemsListWithItemAppended(Object item) { // Object[] items = getRightTableItems(); // java.util.List itemsList = new ArrayList(items.length + 1); // for (int i = 0; i <= items.length; i++) { // Object curObj; // if (i < items.length) { // curObj = tableViewer.getElementAt(i); // } else { // curObj = item; // } // String text; // if (labelProvider != null) { // text = labelProvider.getText(curObj); // } else { // text = curObj.toString(); // } // itemsList.add(text); // } // return itemsList; // } private java.util.List /*<String>*/rightTableItemsListWithItemsAppended( Object[] newItems ) { Object[] items = getRightTableItems(); java.util.List itemsList = new ArrayList(items.length + newItems.length); for (int i = 0; i < items.length; i++) { final Object curObj = tableViewer.getElementAt(i); String text; if (labelProvider != null) { text = labelProvider.getText(curObj); } else { text = curObj.toString(); } itemsList.add(text); } for (int i = 0; i < newItems.length; i++) { final Object curObj = newItems[i]; String text; if (labelProvider != null) { text = labelProvider.getText(curObj); } else { text = curObj.toString(); } itemsList.add(text); } return itemsList; } /** * Return those items which started out as available but were moved to selected. * * @return Collection (Object) of those items moved from available to selected. */ public Collection /*<Object>*/getItemsMovedToSelected() { Object[] obj = getRightTableItems(); Collection /*<Object>*/itemsThatWereAddedToRight = new ArrayList(obj.length); for (int i = 0; i < obj.length; i++) { if (!initialRightSideItems.contains(obj[i])) { itemsThatWereAddedToRight.add(obj[i]); } } return itemsThatWereAddedToRight; } /** * Return those items which started out as selected but were moved to available. * * @return Collection (Object) of those items moved from selected to available. */ public Collection /*<Object>*/getItemsRemovedFromSelected() { Collection /*<Object>*/itemsThatWereRemovedFromRight = new ArrayList(initialRightSideItems.size()); Collection /*<Object>*/rightSideItems = Arrays.asList(getRightTableItems()); Iterator it = initialRightSideItems.iterator(); while (it.hasNext()) { Object curItem = it.next(); boolean hasBeenRemoved = (!rightSideItems.contains(curItem)); if (hasBeenRemoved) { itemsThatWereRemovedFromRight.add(curItem); } } return itemsThatWereRemovedFromRight; } /** * Return Collection (Object) of selected items. * * @return Collection (Object) of the selected items */ public Collection /*<Object>*/getSelectedItems() { Object[] obj = getRightTableItems(); Collection /*<Object>*/coll = Arrays.asList(obj); return coll; } /** * Repopulate the selected items. No IAccumulatorSource methods are called. Method intended for use when the contents of both * the available and selected sides have changed while being displayed, e.g. a selection elsewhere has changed, causing the * accumulator to be completely repopulated. * * @param selectedItems new Collection of selected items */ public void repopulateSelectedItems( Collection newSelectedItems ) { int numRightSideItems = rightTable.getItemCount(); Object[] rightSideItems = new Object[numRightSideItems]; for (int i = 0; i < numRightSideItems; i++) { rightSideItems[i] = tableViewer.getElementAt(i); } tableViewer.remove(rightSideItems); Iterator it = newSelectedItems.iterator(); while (it.hasNext()) { Object item = it.next(); tableViewer.add(item); } source.accumulatedValuesAdded(newSelectedItems); notifyListeners(); } /** * Inform the accumulator that the population of the available side has changed. The accumulator will then reset button states * accordingly. */ public void availableItemsHaveChanged() { setButtonStates(); } private void notifyListeners() { if (changeListeners != null) { int numListeners = changeListeners.size(); for (int i = numListeners - 1; i >= 0; i--) { IAccumulatedValuesChangeListener listener = (IAccumulatedValuesChangeListener)changeListeners.get(i); listener.accumulatedValuesChanged(this); } } } }// end AccumulatorPanel