blob: 94682c25443403161f1e5ae47bffde0e8119a3f0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2013 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.ant.internal.ui.preferences;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.ant.core.IAntClasspathEntry;
import org.eclipse.ant.internal.core.AntObject;
import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.ant.internal.ui.ColumnSorter;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.ColumnLayoutData;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.PlatformUI;
/**
* Provides the generic implementation for a sub-page in the Ant preference page.
*/
public abstract class AntPage {
protected static final int ADD_BUTTON = IDialogConstants.CLIENT_ID + 1;
protected static final int EDIT_BUTTON = IDialogConstants.CLIENT_ID + 2;
protected static final int REMOVE_BUTTON = IDialogConstants.CLIENT_ID + 3;
protected SelectionAdapter selectionAdapter = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
buttonPressed(((Integer) e.widget.getData()).intValue());
}
};
private AntRuntimePreferencePage preferencePage;
private TableViewer tableViewer;
private AntContentProvider contentProvider;
private AntObjectLabelProvider labelProvider = new AntObjectLabelProvider();
protected Button editButton;
protected Button removeButton;
private final String[] fTableColumnHeaders = { AntPreferencesMessages.AntPage_0, AntPreferencesMessages.AntPage_1,
AntPreferencesMessages.AntPage_2, AntPreferencesMessages.AntPage_3 };
private final ColumnLayoutData[] fTableColumnLayouts = { new ColumnWeightData(33), new ColumnWeightData(23), new ColumnWeightData(22),
new ColumnWeightData(22) };
/**
* Creates an instance of this page.
*/
public AntPage(AntRuntimePreferencePage preferencePage) {
super();
this.preferencePage = preferencePage;
}
/**
* Adds buttons specific to the page.
*/
protected abstract void addButtonsToButtonGroup(Composite parent);
/**
* Give this page a chance to initialize itself
*/
protected abstract void initialize();
/**
* Adds an object to the contents
*/
protected void addContent(Object o) {
if (contentProvider != null) {
contentProvider.add(o);
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ant.internal.ui.preferences.AntPage#buttonPressed(int)
*/
private void buttonPressed(int buttonId) {
switch (buttonId) {
case ADD_BUTTON:
add();
break;
case EDIT_BUTTON:
edit(getSelection());
break;
case REMOVE_BUTTON:
remove();
break;
default:
break;
}
}
/**
* Creates and returns a button with appropriate size and layout.
*
* @param parent
* the control to create the button on
* @param labelKey
* the key to lookup the button's label
* @param buttonId
* the id to assign to this button
* @return a new and initialized button
*/
protected Button createPushButton(Composite parent, String buttonText, int buttonId) {
Button button = new Button(parent, SWT.PUSH);
button.setFont(parent.getFont());
button.setText(buttonText);
button.setData(Integer.valueOf(buttonId));
button.addSelectionListener(selectionAdapter);
preferencePage.setButtonLayoutData(button);
return button;
}
/**
* Creates the group which will contain the buttons.
*/
protected void createButtonGroup(Composite top) {
Composite buttonGroup = new Composite(top, SWT.NONE);
GridLayout layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
buttonGroup.setLayout(layout);
buttonGroup.setLayoutData(new GridData(GridData.FILL_VERTICAL));
buttonGroup.setFont(top.getFont());
addButtonsToButtonGroup(buttonGroup);
}
/**
* Creates the table viewer.
*/
protected void createTable(Composite parent) {
Table table = new Table(parent, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
GridData data = new GridData(GridData.FILL_BOTH);
data.widthHint = 425;
data.heightHint = table.getItemHeight();
data.horizontalSpan = 1;
table.setLayoutData(data);
table.setFont(parent.getFont());
TableLayout tableLayout = new TableLayout();
table.setLayout(tableLayout);
table.setHeaderVisible(true);
table.setLinesVisible(true);
contentProvider = getContentProvider();
tableViewer = new TableViewer(table);
tableViewer.setContentProvider(contentProvider);
tableViewer.setLabelProvider(this.labelProvider);
tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
tableSelectionChanged((IStructuredSelection) event.getSelection());
}
});
tableViewer.addDoubleClickListener(new IDoubleClickListener() {
@Override
public void doubleClick(DoubleClickEvent event) {
if (!event.getSelection().isEmpty() && editButton.isEnabled()) {
edit((IStructuredSelection) event.getSelection());
}
}
});
ArrayList<ColumnSorter> sorters = new ArrayList<>(fTableColumnHeaders.length);
for (int i = 0; i < fTableColumnHeaders.length; i++) {
tableLayout.addColumnData(fTableColumnLayouts[i]);
TableColumn column = new TableColumn(table, SWT.NONE, i);
column.setResizable(fTableColumnLayouts[i].resizable);
column.setText(fTableColumnHeaders[i]);
sorters.add(new ColumnSorter(this.tableViewer, column) {
@Override
public String getCompareText(Object obj, int columnindex) {
return AntPage.this.labelProvider.getColumnText(obj, columnindex);
}
});
}
table.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent event) {
if (editButton.isEnabled() && event.character == SWT.DEL && event.stateMask == 0) {
remove(tableViewer);
}
}
});
restoreColumnSettings(AntUIPlugin.getDefault().getDialogSettings(), sorters);
}
/**
* Persist table settings into the give dialog store, prefixed with the given key.
*
* @param settings
* dialog store
* @since 3.5
*/
public void saveColumnSettings(IDialogSettings settings) {
Table table = this.tableViewer.getTable();
int columnCount = table.getColumnCount();
for (int i = 0; i < columnCount; i++) {
settings.put(getHelpContextId() + ".columnWidth" + i, table.getColumn(i).getWidth()); //$NON-NLS-1$
}
TableColumn column = table.getSortColumn();
if (column != null) {
settings.put(getHelpContextId() + ".sortColumn", table.indexOf(column)); //$NON-NLS-1$
settings.put(getHelpContextId() + ".sortDirection", table.getSortDirection()); //$NON-NLS-1$
}
}
/**
* Restore table settings from the given dialog store using the given key.
*
* @param settings
* dialog settings store
* @since 3.5
*/
private void restoreColumnSettings(IDialogSettings settings, ArrayList<ColumnSorter> sorters) {
restoreColumnWidths(settings);
int idx = 0;
int direction = SWT.DOWN;
try {
idx = settings.getInt(getHelpContextId() + ".sortColumn"); //$NON-NLS-1$
direction = settings.getInt(getHelpContextId() + ".sortDirection"); //$NON-NLS-1$
}
catch (NumberFormatException e) {
// do nothing
}
Table table = this.tableViewer.getTable();
if (table.getColumnCount() < 1) {
return;
}
TableColumn column = table.getColumn(idx);
if (column != null) {
table.setSortColumn(column);
table.setSortDirection(direction);
ColumnSorter sorter = sorters.get(idx);
sorter.setDirection(direction);
}
sorters.clear();
}
/**
* Restores the column widths from dialog settings
*
* @param settings
* @since 3.5
*/
private void restoreColumnWidths(IDialogSettings settings) {
Table table = this.tableViewer.getTable();
int columnCount = table.getColumnCount();
for (int i = 0; i < columnCount; i++) {
int width = -1;
try {
width = settings.getInt(getHelpContextId() + ".columnWidth" + i); //$NON-NLS-1$
}
catch (NumberFormatException e) {
// do nothing
}
if ((width <= 0) || (i == table.getColumnCount() - 1)) {
table.getColumn(i).pack();
} else {
table.getColumn(i).setWidth(width);
}
}
}
/**
* Returns the content provider to use for the table viewer
*
* @return AntPageContentProvider
*/
protected AntContentProvider getContentProvider() {
return new AntContentProvider(false);
}
/**
* Returns the currently listed objects in the table if the library for that entry is still included in the preferences. Default objects are
* included depending on the value of the <code>forDisplay</code> parameter. Returns <code>null</code> if this widget has not yet been created or
* has been disposed.
*
* @param forDisplay
* Whether the result is to be displayed in the UI or stored in the preferences
* @return The list of objects currently displayed in the table
*/
protected List<Object> getContents(boolean forDisplay) {
if (tableViewer == null || tableViewer.getControl().isDisposed()) {
return null;
}
List<IAntClasspathEntry> entries = getPreferencePage().getLibraryEntries();
Object[] elements = contentProvider.getElements(tableViewer.getInput());
List<Object> contents = new ArrayList<>(elements.length);
Object element;
AntObject antObject;
for (int i = 0; i < elements.length; i++) {
element = elements[i];
if (element instanceof AntObject) {
antObject = (AntObject) element;
if (forDisplay) {
if (!antObject.isDefault() && !entries.contains(antObject.getLibraryEntry())) {
continue;
}
} else if (antObject.isDefault() || !entries.contains(antObject.getLibraryEntry())) {
continue;
}
}
contents.add(element);
}
return contents;
}
/**
* Returns the selection in the viewer, or <code>null</code> if none.
*/
protected final IStructuredSelection getSelection() {
if (tableViewer == null || tableViewer.getControl().isDisposed()) {
return null;
}
return ((IStructuredSelection) tableViewer.getSelection());
}
/**
* Returns the shell of the sub-page.
*/
protected final Shell getShell() {
if (tableViewer == null || tableViewer.getControl().isDisposed()) {
return null;
}
return tableViewer.getControl().getShell();
}
/**
* Handles the remove button pressed event
*/
protected void remove() {
remove(tableViewer);
}
protected void remove(TableViewer viewer) {
AntContentProvider antContentProvider = (AntContentProvider) viewer.getContentProvider();
IStructuredSelection sel = (IStructuredSelection) viewer.getSelection();
Iterator<?> itr = sel.iterator();
while (itr.hasNext()) {
antContentProvider.remove(itr.next());
}
}
/**
* Sets the contents of the table on this page. Has no effect if this widget has not yet been created or has been disposed.
*/
protected void setInput(List<?> inputs) {
if (tableViewer == null || tableViewer.getControl().isDisposed()) {
return;
}
tableViewer.setInput(inputs);
tableSelectionChanged((IStructuredSelection) tableViewer.getSelection());
}
/**
* Updates the content element in the table viewer.
*/
protected final void updateContent(Object element) {
if (tableViewer == null || tableViewer.getControl().isDisposed()) {
return;
}
tableViewer.update(element, null);
}
/**
* Creates the default contents of this page
*/
protected Composite createContents(Composite top) {
PlatformUI.getWorkbench().getHelpSystem().setHelp(top, getHelpContextId());
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginHeight = 2;
layout.marginWidth = 2;
top.setLayout(layout);
top.setLayoutData(new GridData(GridData.FILL_BOTH));
createTable(top);
createButtonGroup(top);
return top;
}
protected AntRuntimePreferencePage getPreferencePage() {
return preferencePage;
}
protected TableViewer getTableViewer() {
return tableViewer;
}
/**
* Handles selection changes in the table viewer.
*/
protected void tableSelectionChanged(IStructuredSelection newSelection) {
int size = newSelection.size();
boolean enabled = true;
Iterator<?> itr = newSelection.iterator();
while (itr.hasNext()) {
Object element = itr.next();
if (element instanceof AntObject) {
AntObject antObject = (AntObject) element;
if (antObject.isDefault()) {
enabled = false;
break;
}
}
}
editButton.setEnabled(enabled && size == 1);
removeButton.setEnabled(enabled && size > 0);
}
/**
* Allows the user to edit a custom Ant object.
*
* @param selection
* The selection containing the object to edit
*/
protected abstract void edit(IStructuredSelection selection);
/**
* Allows the user to add a custom Ant object.
*
*/
protected abstract void add();
/**
* Returns this page's help context id, which is hooked to this page on creation.
*
* @return help context id
*/
protected abstract String getHelpContextId();
protected void connectToFolder(final TabItem item, TabFolder folder) {
folder.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (e.item == item) {
// remove ant objects whose library has been removed
setInput(getContents(true));
}
}
});
}
}