/*******************************************************************************
* Copyright (c) 2000, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.gyrex.admin.ui.internal.wizards.dialogfields;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Table;
/**
* A list with check boxes and a button bar. Typical buttons are 'Check All' and
* 'Uncheck All'. List model is independent of widget creation. DialogFields
* controls are: Label, List and Composite containing buttons.
*/
public class CheckedListDialogField extends ListDialogField {
private int fCheckAllButtonIndex;
private int fUncheckAllButtonIndex;
private List<Object> fCheckedElements;
private final List<Object> fGrayedElements;
public CheckedListDialogField(final IListAdapter adapter, final String[] customButtonLabels, final ILabelProvider lprovider) {
super(adapter, customButtonLabels, lprovider);
fCheckedElements = new ArrayList<Object>();
fGrayedElements = new ArrayList<Object>();
fCheckAllButtonIndex = -1;
fUncheckAllButtonIndex = -1;
}
/**
* Sets the check state of all elements.
*
* @param state
* the checked state
*/
public void checkAll(final boolean state) {
if (state) {
fCheckedElements = getElements();
} else {
fCheckedElements.clear();
}
if (isOkToUse(fTableControl)) {
((CheckboxTableViewer) fTable).setAllChecked(state);
}
checkStateChanged();
}
private void checkStateChanged() {
//call super and do not update check model
super.dialogFieldChanged();
}
/*
* @see ListDialogField#createTableViewer
*/
@Override
protected TableViewer createTableViewer(final Composite parent) {
final Table table = new Table(parent, SWT.CHECK | getListStyle());
table.setFont(parent.getFont());
final CheckboxTableViewer tableViewer = new CheckboxTableViewer(table);
tableViewer.addCheckStateListener(new ICheckStateListener() {
@Override
public void checkStateChanged(final CheckStateChangedEvent e) {
doCheckStateChanged(e);
}
});
return tableViewer;
}
/*
* @see DialogField#dialogFieldChanged
* Hooks in to get element changes to update check model.
*/
@Override
public void dialogFieldChanged() {
for (int i = fCheckedElements.size() - 1; i >= 0; i--) {
if (!fElements.contains(fCheckedElements.get(i))) {
fCheckedElements.remove(i);
}
}
super.dialogFieldChanged();
}
private void doCheckStateChanged(final CheckStateChangedEvent e) {
if (e.getChecked()) {
fCheckedElements.add(e.getElement());
} else {
fCheckedElements.remove(e.getElement());
}
checkStateChanged();
}
/**
* Gets the checked elements.
*
* @return the list of checked elements
*/
public List<Object> getCheckedElements() {
if (isOkToUse(fTableControl)) {
// workaround for bug 53853
final Object[] checked = ((CheckboxTableViewer) fTable).getCheckedElements();
final ArrayList<Object> res = new ArrayList<Object>(checked.length);
for (final Object element : checked) {
res.add(element);
}
return res;
}
return new ArrayList<Object>(fCheckedElements);
}
/**
* Returns the number of checked elements.
*
* @return the number of checked elements
*/
public int getCheckedSize() {
return fCheckedElements.size();
}
/*
* @see ListDialogField#getListControl
*/
@Override
public Control getListControl(final Composite parent) {
final Control control = super.getListControl(parent);
if (parent != null) {
((CheckboxTableViewer) fTable).setCheckedElements(fCheckedElements.toArray());
((CheckboxTableViewer) fTable).setGrayedElements(fGrayedElements.toArray());
}
return control;
}
/*
* @see ListDialogField#getManagedButtonState
*/
@Override
protected boolean getManagedButtonState(final ISelection sel, final int index) {
if (index == fCheckAllButtonIndex) {
return !fElements.isEmpty();
} else if (index == fUncheckAllButtonIndex) {
return !fElements.isEmpty();
}
return super.getManagedButtonState(sel, index);
}
/**
* Returns true if the element is checked.
*
* @param obj
* the element to check
* @return <code>true</code> if the given element is checked
*/
public boolean isChecked(final Object obj) {
if (isOkToUse(fTableControl)) {
return ((CheckboxTableViewer) fTable).getChecked(obj);
}
return fCheckedElements.contains(obj);
}
public boolean isGrayed(final Object obj) {
if (isOkToUse(fTableControl)) {
return ((CheckboxTableViewer) fTable).getGrayed(obj);
}
return fGrayedElements.contains(obj);
}
/*
* @see ListDialogField#extraButtonPressed
*/
@Override
protected boolean managedButtonPressed(final int index) {
if (index == fCheckAllButtonIndex) {
checkAll(true);
} else if (index == fUncheckAllButtonIndex) {
checkAll(false);
} else {
return super.managedButtonPressed(index);
}
return true;
}
@Override
public void refresh() {
super.refresh();
if (isOkToUse(fTableControl)) {
((CheckboxTableViewer) fTable).setCheckedElements(fCheckedElements.toArray());
((CheckboxTableViewer) fTable).setGrayedElements(fGrayedElements.toArray());
}
}
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField#replaceElement(java.lang.Object, java.lang.Object)
*/
@Override
public void replaceElement(final Object oldElement, final Object newElement) throws IllegalArgumentException {
final boolean wasChecked = isChecked(oldElement);
super.replaceElement(oldElement, newElement);
setChecked(newElement, wasChecked);
}
/**
* Sets the index of the 'check all' button in the button label array passed
* in the constructor. The behavior of the button marked as the check button
* will then be handled internally. (enable state, button invocation
* behavior)
*
* @param checkAllButtonIndex
* the index of the check all button
*/
public void setCheckAllButtonIndex(final int checkAllButtonIndex) {
Assert.isTrue(checkAllButtonIndex < fButtonLabels.length);
fCheckAllButtonIndex = checkAllButtonIndex;
}
/**
* Sets the checked state of an element.
*
* @param object
* the element for which to set the state
* @param state
* the checked state
*/
public void setChecked(final Object object, final boolean state) {
setCheckedWithoutUpdate(object, state);
checkStateChanged();
}
/**
* Sets the checked elements.
*
* @param list
* the list of checked elements
*/
public void setCheckedElements(final Collection<?> list) {
fCheckedElements = new ArrayList<Object>(list);
if (isOkToUse(fTableControl)) {
((CheckboxTableViewer) fTable).setCheckedElements(list.toArray());
}
checkStateChanged();
}
// ------ enable / disable management
/**
* Sets the checked state of an element. No dialog changed listener is
* informed.
*
* @param object
* the element for which to set the state
* @param state
* the checked state
*/
public void setCheckedWithoutUpdate(final Object object, final boolean state) {
if (state) {
if (!fCheckedElements.contains(object)) {
fCheckedElements.add(object);
}
} else {
fCheckedElements.remove(object);
}
if (isOkToUse(fTableControl)) {
((CheckboxTableViewer) fTable).setChecked(object, state);
}
}
public void setGrayedWithoutUpdate(final Object object, final boolean state) {
if (state) {
if (!fGrayedElements.contains(object)) {
fGrayedElements.add(object);
}
} else {
fGrayedElements.remove(object);
}
if (isOkToUse(fTableControl)) {
((CheckboxTableViewer) fTable).setGrayed(object, state);
}
}
/**
* Sets the index of the 'uncheck all' button in the button label array
* passed in the constructor. The behavior of the button marked as the
* uncheck button will then be handled internally. (enable state, button
* invocation behavior)
*
* @param uncheckAllButtonIndex
* the index of the check all button
*/
public void setUncheckAllButtonIndex(final int uncheckAllButtonIndex) {
Assert.isTrue(uncheckAllButtonIndex < fButtonLabels.length);
fUncheckAllButtonIndex = uncheckAllButtonIndex;
}
}