/*******************************************************************************
* Copyright (c) 2007, 2008 Edgar Espina.
* 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
*
*******************************************************************************/
package org.deved.antlride.internal.ui.preferences;
import java.io.IOException;
import org.deved.antlride.common.ui.AntlrImages;
import org.deved.antlride.core.AntlrConstants;
import org.deved.antlride.core.AntlrCore;
import org.deved.antlride.core.resources.AntlrLanguageTarget;
import org.deved.antlride.core.resources.AntlrLanguageTargetRepository;
import org.deved.antlride.core.resources.AntlrPackage;
import org.deved.antlride.core.resources.AntlrPackages;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.dltk.ui.preferences.AbstractOptionsBlock;
import org.eclipse.dltk.ui.preferences.PreferenceKey;
import org.eclipse.dltk.ui.util.IStatusChangeListener;
import org.eclipse.dltk.ui.util.PixelConverter;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
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.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
@SuppressWarnings("restriction")
public class AntlrBuilderBlock extends AbstractOptionsBlock {
private class AntlrLanguageLabelProvider extends LabelProvider {
@Override
public String getText(Object element) {
return super.getText(element);
}
@Override
public Image getImage(Object element) {
return AntlrImages.getImage(AntlrImages.TARGET_LANGUAGE);
}
}
private class AntlrLanguageTargetContentProvider implements
IStructuredContentProvider {
public Object[] getElements(Object inputElement) {
AntlrPackage ap = (AntlrPackage) inputElement;
return ap == null ? new Object[0] : ap.getLanguageTargets();
}
public void dispose() {
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}
private class AntlrPackageSelectionChangedListener implements
ISelectionChangedListener {
public void selectionChanged(SelectionChangedEvent event) {
AntlrPackage ap = null;
IStructuredSelection selection = (IStructuredSelection) event
.getSelection();
if (!selection.isEmpty()) {
ap = (AntlrPackage) selection.getFirstElement();
langViewer.setInput(ap);
AntlrLanguageTarget[] targets = ap.getLanguageTargets();
langViewer.setSelection(new StructuredSelection(targets[0]));
} else {
langViewer.setInput(ap);
}
}
}
private class AntlrLanguageSelectionChangedListener implements
ISelectionChangedListener {
public void selectionChanged(SelectionChangedEvent event) {
IStructuredSelection selection = (IStructuredSelection) event
.getSelection();
removeButton.setEnabled(!selection.isEmpty());
}
}
private class RemoveCustomLanguageTarget implements SelectionListener {
public void widgetSelected(SelectionEvent e) {
IStructuredSelection selection = (IStructuredSelection) custLangViewer
.getSelection();
if (!selection.isEmpty()) {
AntlrLanguageTargetRepository
.delete((AntlrLanguageTarget) selection
.getFirstElement());
custLangViewer.setInput(AntlrLanguageTargetRepository.list());
}
}
public void widgetDefaultSelected(SelectionEvent e) {
}
}
private class AddCustomLanguageTarget implements SelectionListener {
public void widgetSelected(SelectionEvent e) {
AntlrLanguageTargetDialog dialog = new AntlrLanguageTargetDialog(
getShell(), "Add language target");
IStructuredSelection ss = (IStructuredSelection) packageViewer
.getSelection();
dialog.setInput((AntlrPackage) ss.getFirstElement());
dialog.open();
if (dialog.getLanguageTarget() != null)
custLangViewer.setInput(AntlrLanguageTargetRepository
.list());
}
public void widgetDefaultSelected(SelectionEvent e) {
}
}
private AntlrPackages packages;
private TableViewer packageViewer;
private TableViewer langViewer;
private TableViewer custLangViewer;
private Button removeButton;
private final static PreferenceKey RUNTIME = new PreferenceKey(
AntlrCore.PLUGIN_ID, AntlrConstants.ANTLR_BUILDER_RUNTIME);
private final static PreferenceKey[] keys = { RUNTIME };
private static final IStatus NO_RUNTIME = new Status(IStatus.ERROR,
AntlrCore.PLUGIN_ID,
"No package defined. Please add an ANTLR package.");
private static final IStatus NO_PROBLEM = new Status(IStatus.OK,
AntlrCore.PLUGIN_ID, "Builder");
public AntlrBuilderBlock(IStatusChangeListener context, IProject project,
IWorkbenchPreferenceContainer container) {
super(context, project, keys, container);
}
@Override
protected Control createOptionsBlock(Composite parent) {
packages = AntlrPackages.getInstance();
SashForm form = new SashForm(parent, SWT.VERTICAL);
createPackagePanel(form);
createLanguagePanel(form);
form.setWeights(new int[] { 35, 65 });
updateInput();
return form;
}
private void createLanguagePanel(Composite parent) {
Composite optionsParent = createSubsection(parent, "Languages:");
GridLayout layout = new GridLayout(4, false);
optionsParent.setLayout(layout);
Label label = new Label(optionsParent, SWT.NONE);
GridData gd = new GridData();
gd.verticalAlignment = SWT.BEGINNING;
gd.horizontalSpan = 2;
label.setText("Available language targets");
label.setLayoutData(gd);
label = new Label(optionsParent, SWT.NONE);
gd = new GridData();
gd.verticalAlignment = SWT.BEGINNING;
gd.horizontalSpan = 2;
label.setText("Custom language targets");
label.setLayoutData(gd);
Table table = new Table(optionsParent, SWT.SINGLE | SWT.FULL_SELECTION
| SWT.BORDER);
gd = new GridData(GridData.FILL_BOTH);
gd.horizontalSpan = 2;
table.setLayoutData(gd);
Composite composite = new Composite(optionsParent, SWT.NONE);
composite.setLayout(new GridLayout(2, false));
gd = new GridData(GridData.FILL_BOTH);
gd.horizontalSpan = 2;
composite.setLayoutData(gd);
Table table2 = new Table(composite, SWT.SINGLE | SWT.FULL_SELECTION
| SWT.BORDER);
gd = new GridData(GridData.FILL_BOTH);
gd.horizontalSpan = 2;
table2.setLayoutData(gd);
Button addButton = new Button(composite, SWT.PUSH);
addButton.setText("Add...");
addButton.setToolTipText("Add language target");
addButton.addSelectionListener(new AddCustomLanguageTarget());
gd = new GridData();
gd.widthHint = 100;
addButton.setLayoutData(gd);
removeButton = new Button(composite, SWT.PUSH);
removeButton.setText("Remove");
removeButton.setToolTipText("Remove target language");
removeButton.setEnabled(false);
removeButton.addSelectionListener(new RemoveCustomLanguageTarget());
gd = new GridData();
gd.widthHint = 100;
removeButton.setLayoutData(gd);
langViewer = new TableViewer(table);
langViewer.setContentProvider(new AntlrLanguageTargetContentProvider());
langViewer.setLabelProvider(new AntlrLanguageLabelProvider());
custLangViewer = new TableViewer(table2);
custLangViewer.setContentProvider(new ArrayContentProvider());
custLangViewer.setLabelProvider(new AntlrLanguageLabelProvider());
custLangViewer
.addSelectionChangedListener(new AntlrLanguageSelectionChangedListener());
custLangViewer.setInput(AntlrLanguageTargetRepository.list());
}
@Override
protected boolean processChanges(IWorkbenchPreferenceContainer container) {
try {
packages.save();
} catch (IOException e) {
AntlrCore.error("Can't save packages", e);
return false;
}
AntlrPackage selectedPackage = packages.getSelectedPackage();
if (selectedPackage != null) {
setString(RUNTIME, selectedPackage.getVersion());
}
return super.processChanges(container);
}
private Composite createPackagePanel(Composite parent) {
Composite composite = createSubsection(parent,
AntlrPreferenceMessages.Builder_Packages);
GridLayout layout = new GridLayout(2, false);
layout.verticalSpacing = 10;
composite.setLayout(layout);
packageViewer = new TableViewer(composite, SWT.CHECK | SWT.BORDER
| SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION);
final Table table = packageViewer.getTable();
table.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
if (event.detail == SWT.CHECK) {
updateSelection();
TableItem item = (TableItem) event.item;
AntlrPackage ap = (AntlrPackage) item.getData();
item.setChecked(true);
ap.setSelected(true);
}
}
});
GridData gd = new GridData(GridData.FILL_BOTH);
// gd.verticalSpan = 10;
gd.horizontalSpan = 2;
table.setLayoutData(gd);
table.setHeaderVisible(true);
table.setLinesVisible(true);
packageViewer.setUseHashlookup(true);
int[] widths = { 75, 250 };
for (int i = 0; i < AntlrPackage.PROPERTIES.length; i++) {
TableColumn tableColumn = new TableColumn(table, SWT.LEFT);
tableColumn.setText(AntlrPackage.PROPERTIES[i]);
tableColumn.setWidth(widths[i]);
}
packageViewer.setLabelProvider(new PackageLabelProvider());
packageViewer.setContentProvider(new ArrayContentProvider());
Button addButton = new Button(composite, SWT.NONE);
gd = new GridData();
gd.widthHint = 100;
addButton.setLayoutData(gd);
addButton.setText(AntlrPreferenceMessages.Builder_Package_Add);
addButton.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
Shell shell = new Shell(getShell());
AntlrPackageDialog dialog = new AntlrPackageDialog(shell,
packages, "Add ANTLR Package");
dialog.open();
AntlrPackage selectedPackage = dialog.getSelectedPackage();
if (selectedPackage != null) {
packages.register(selectedPackage);
AntlrPackage[] pkgs = packages.getPackages();
updateInput();
if (pkgs.length == 1) {
table.getItem(0).setChecked(true);
}
}
dialog = null;
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
final Button removeButton = new Button(composite, SWT.NONE);
gd = new GridData();
gd.widthHint = 100;
removeButton.setLayoutData(gd);
removeButton.setText(AntlrPreferenceMessages.Builder_Package_Remove);
removeButton.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
int selectionIndex = table.getSelectionIndex();
if (selectionIndex >= 0) {
TableItem item = table.getItem(selectionIndex);
AntlrPackage ap = (AntlrPackage) item.getData();
packages.unregister(ap);
updateInput();
AntlrPackage[] pkgs = packages.getPackages();
if (pkgs.length > 0) {
AntlrPackage selectedPackage = packages
.getSelectedPackage();
if (selectedPackage == null) {
selectedPackage = pkgs[0];
selectedPackage.setSelected(true);
}
int index = packages.getSelectedPackageIndex();
table.getItem(index).setChecked(true);
}
}
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
packageViewer
.addSelectionChangedListener(new AntlrPackageSelectionChangedListener());
return composite;
}
private void updateInput() {
AntlrPackage[] pkgs = this.packages.getPackages();
if (pkgs.length == 0) {
statusChanged(NO_RUNTIME);
} else {
statusChanged(NO_PROBLEM);
}
packageViewer.setInput(pkgs);
if (pkgs.length > 0) {
packageViewer.setSelection(new StructuredSelection(packages
.getSelectedPackage()));
} else {
packageViewer.setSelection(StructuredSelection.EMPTY);
}
int selectedIndex = packages.getSelectedPackageIndex();
if (selectedIndex >= 0) {
packageViewer.getTable().getItem(selectedIndex).setChecked(true);
}
}
@Override
public void dispose() {
super.dispose();
}
private void updateSelection() {
Table table = packageViewer.getTable();
for (int i = 0; i < table.getItemCount(); i++) {
TableItem titem = table.getItem(i);
titem.setChecked(false);
AntlrPackage ap = (AntlrPackage) titem.getData();
ap.setSelected(false);
}
}
protected Control[] addLabelledTextField(Composite parent, String label,
String option, PreferenceKey key, int textLimit, int indentation,
int align) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout(2, false));
PixelConverter pixelConverter = new PixelConverter(composite);
Text textControl;
Label labelControl;
if (align == SWT.LEFT) {
textControl = new Text(composite, SWT.BORDER | SWT.SINGLE);
labelControl = new Label(composite, SWT.NONE);
} else {
labelControl = new Label(composite, SWT.NONE);
textControl = new Text(composite, SWT.BORDER | SWT.SINGLE);
}
GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
gd.widthHint = pixelConverter
.convertWidthInCharsToPixels(textLimit + 1);
textControl.setLayoutData(gd);
textControl.setTextLimit(textLimit);
textControl.setText(getString(key));
textControl.setData("key", key);
textControl.setData("option", option);
textControl.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
numberFieldChanged((Text) e.widget);
}
});
labelControl.setText(label);
gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
gd.horizontalIndent = indentation;
labelControl.setLayoutData(gd);
return new Control[] { labelControl, textControl };
}
private void numberFieldChanged(Text textControl) {
setString(textControl.getData("key"), textControl.getText());
}
private Composite createSubsection(Composite parent, String label) {
Group group = new Group(parent, SWT.SHADOW_NONE);
group.setText(label);
GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false);
group.setLayoutData(data);
return group;
}
private class PackageLabelProvider extends LabelProvider implements
ITableLabelProvider {
public Image getColumnImage(Object element, int columnIndex) {
if (columnIndex == 0) {
return AntlrImages.getImage(AntlrImages.PACKAGE);
}
return null;
}
public String getColumnText(Object element, int columnIndex) {
AntlrPackage ap = (AntlrPackage) element;
if (columnIndex == 0) {
return ap.getVersion();
} else if (columnIndex == 1) {
return ap.getDescription();
}
return "";
}
}
}