blob: bc25f4d0c5ca65599f3038b2d33a1075bdab4812 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2007 BEA Systems, Inc.
* 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:
* wharley@bea.com - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.apt.ui.internal.preferences;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.jdt.apt.core.internal.util.FactoryContainer;
import org.eclipse.jdt.apt.core.internal.util.FactoryPath;
import org.eclipse.jdt.apt.core.internal.util.FactoryPathUtil;
import org.eclipse.jdt.apt.core.internal.util.FactoryPath.Attributes;
import org.eclipse.jdt.apt.core.util.AptConfig;
import org.eclipse.jdt.apt.core.util.IFactoryPath;
import org.eclipse.jdt.apt.ui.internal.util.ExceptionHandler;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.ui.util.PixelConverter;
import org.eclipse.jdt.internal.ui.wizards.IStatusChangeListener;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.CheckedListDialogField;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.IListAdapter;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField;
import org.eclipse.jdt.ui.wizards.BuildPathDialogAccess;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
/**
* Data and controls for the Java Annotation Factory Path preference page.
*/
public class FactoryPathConfigurationBlock extends BaseConfigurationBlock {
private static final int IDX_UP= 0;
private static final int IDX_DOWN= 1;
// 2
private static final int IDX_ADDJAR= 3;
private static final int IDX_ADDEXTJAR= 4;
private static final int IDX_ADDVAR= 5;
// 6
private static final int IDX_EDIT= 7;
private static final int IDX_ADVANCED= 8;
private static final int IDX_REMOVE= 9;
// 10
private static final int IDX_ENABLEALL= 11;
private static final int IDX_DISABLEALL= 12;
private final static String[] buttonLabels = {
Messages.FactoryPathConfigurationBlock_up,
Messages.FactoryPathConfigurationBlock_down,
null, // 2
Messages.FactoryPathConfigurationBlock_addJars,
Messages.FactoryPathConfigurationBlock_addExternalJars,
Messages.FactoryPathConfigurationBlock_addVariable,
null, // 6
Messages.FactoryPathConfigurationBlock_edit,
Messages.FactoryPathConfigurationBlock_advanced,
Messages.FactoryPathConfigurationBlock_remove,
null, // 10
Messages.FactoryPathConfigurationBlock_enableAll,
Messages.FactoryPathConfigurationBlock_disableAll
};
/**
* Event handler for factory path list control
*/
private class FactoryPathAdapter implements IListAdapter, IDialogFieldListener {
public void customButtonPressed(ListDialogField field, int index) {
FactoryPathConfigurationBlock.this.customButtonPressed(index);
}
public void selectionChanged(ListDialogField field) {
boolean enableRemove = canRemove();
field.enableButton(IDX_REMOVE, enableRemove);
boolean enableEdit = canEdit();
field.enableButton(IDX_EDIT, enableEdit);
boolean enableAdvanced = canAdvanced();
field.enableButton(IDX_ADVANCED, enableAdvanced);
}
/**
* This method gets called when, among other things, a checkbox is
* clicked. However, it doesn't get any information about which
* item it was whose checkbox was clicked. We could hook into the
* list control's CheckboxTableViewer event listener for changes to
* individual checkboxes; but that does not get called for enableAll
* and disableAll events.
*/
public void dialogFieldChanged(DialogField field) {
if (!fSettingListContents) {
updateFactoryPathEntries();
}
}
public void doubleClicked(ListDialogField field) {
if (canEdit()) {
editSelectedItem();
}
}
}
private class FactoryPathLabelProvider extends LabelProvider implements ITableLabelProvider {
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
public String getColumnText(Object element, int columnIndex) {
if (!(element instanceof FactoryPathEntry)) {
return ""; //$NON-NLS-1$
}
FactoryPathEntry fpe = (FactoryPathEntry)element;
if (columnIndex == 0) {
return fpe._fc.toString();
}
else {
return ""; //$NON-NLS-1$
}
}
}
/**
* The factory path is a list of containers, plus some information about
* each container. That makes it a list of FactoryPathEntry.
*/
private static class FactoryPathEntry {
/* shallow copies - beware! */
public final FactoryContainer _fc;
public FactoryPath.Attributes _attr;
// CONSTRUCTORS
public FactoryPathEntry(FactoryContainer fc, FactoryPath.Attributes attr) {
_fc = fc;
_attr = attr;
}
// CONVERSION TO/FROM INDIVIDUAL ELEMENTS
public static Map<FactoryContainer, Attributes> pathMapFromList(List<FactoryPathEntry> list) {
Map<FactoryContainer, FactoryPath.Attributes> map =
new LinkedHashMap<FactoryContainer, FactoryPath.Attributes>(list.size());
for (FactoryPathEntry fpe : list) {
map.put(fpe._fc, fpe._attr);
}
return map;
}
public static List<FactoryPathEntry> pathListFromMap(Map<FactoryContainer, Attributes> map) {
List<FactoryPathEntry> list = new ArrayList<FactoryPathEntry>(map.size());
for (Map.Entry<FactoryContainer, Attributes> entry : map.entrySet()) {
FactoryPathEntry fpe = new FactoryPathEntry(entry.getKey(), entry.getValue());
list.add(fpe);
}
return list;
}
// SUPPORT FOR COMPARISON
public boolean equals(Object obj) {
if (!(obj instanceof FactoryPathEntry))
return false;
FactoryPathEntry fpe = (FactoryPathEntry)obj;
return _fc.equals(fpe._fc) && _attr.equals(fpe._attr);
}
public int hashCode() {
return _fc.hashCode() ^ _attr.hashCode();
}
}
private PixelConverter fPixelConverter;
private Composite fBlockControl; // the control representing the entire configuration block
/**
* The factory path at the time this pref pane was launched.
* Use this to see if anything changed at save time.
*/
private List<FactoryPathEntry> fOriginalPath;
private final IJavaProject fJProj;
/**
* The GUI control representing the factory path. Its data items
* are of type FactoryPathEntry.
*/
private CheckedListDialogField fFactoryPathList;
/**
* True while inside setListContents(). Used in order to efficiently
* and correctly add new elements to the factory list: short-circuits
* the factory list field listener code.
*/
private boolean fSettingListContents = false;
public FactoryPathConfigurationBlock(IStatusChangeListener context,
IProject project, IWorkbenchPreferenceContainer container) {
super(context, project, new Key[] {}, container);
fJProj = JavaCore.create(project);
FactoryPathAdapter adapter= new FactoryPathAdapter();
FactoryPathLabelProvider labelProvider = new FactoryPathLabelProvider();
fFactoryPathList= new CheckedListDialogField(adapter, buttonLabels, labelProvider);
fFactoryPathList.setDialogFieldListener(adapter);
fFactoryPathList.setLabelText(Messages.FactoryPathConfigurationBlock_pluginsAndJars);
fFactoryPathList.setUpButtonIndex(IDX_UP);
fFactoryPathList.setDownButtonIndex(IDX_DOWN);
fFactoryPathList.setRemoveButtonIndex(IDX_REMOVE);
fFactoryPathList.setCheckAllButtonIndex(IDX_ENABLEALL);
fFactoryPathList.setUncheckAllButtonIndex(IDX_DISABLEALL);
}
/**
* Respond to the user checking the "enabled" checkbox of an entry
* in the factory path control, by replacing the FactoryPathEntry
* with a new one with the correct "enabled" value.
* We don't have information about which entry was changed, so we
* have to look at all of them. This is inefficient - somewhere
* around O(n log n) depending on how the list is implemented - but
* hopefully the list is not so huge that it's a problem.
*/
private void updateFactoryPathEntries() {
for (FactoryPathEntry fpe : getListContents()) {
boolean checked = fFactoryPathList.isChecked(fpe);
if (checked != fpe._attr.isEnabled()) {
fpe._attr.setEnabled(checked);
}
}
}
/**
* Respond to a button in the button bar.
* Most buttons are handled by code in CheckedListDialogField;
* this method is for the rest, e.g., Add External Jar.
* @param index
*/
public void customButtonPressed(int index) {
FactoryPathEntry[] newEntries = null;
switch (index) {
case IDX_ADDJAR: // add jars in project
newEntries= openJarFileDialog(null);
addEntries(newEntries);
break;
case IDX_ADDEXTJAR: // add external jars
newEntries= openExtJarFileDialog(null);
addEntries(newEntries);
break;
case IDX_ADDVAR: // add jar from classpath variable
newEntries= openVariableSelectionDialog(null);
addEntries(newEntries);
break;
case IDX_EDIT: // edit selected item
if (canEdit()) {
editSelectedItem();
}
break;
case IDX_ADVANCED: // advanced options
advancedOptionsDialog();
break;
}
}
/**
* Can't remove a selection that contains a plugin.
*/
private boolean canRemove() {
List<FactoryPathEntry> selected= getSelectedListContents();
boolean containsPlugin= false;
for (FactoryPathEntry fpe : selected) {
if (fpe._fc.getType() == FactoryContainer.FactoryType.PLUGIN) {
containsPlugin = true;
break;
}
}
return !containsPlugin;
}
/**
* Can only edit a single item at a time. Can't edit plugins.
*/
private boolean canEdit() {
List<FactoryPathEntry> selected= getSelectedListContents();
if (selected.size() != 1) {
return false;
}
FactoryContainer fc = selected.get(0)._fc;
return (fc.getType() != FactoryContainer.FactoryType.PLUGIN);
}
/**
* Can only launch the 'advanced' dialog on a single item at a time.
*/
private boolean canAdvanced() {
List<FactoryPathEntry> selected= getSelectedListContents();
return (selected.size() == 1);
}
/**
* Edit the item selected.
* Precondition: exactly one item is selected in the list,
* and it is an editable item (not a plugin).
* @param field a listbox of FactoryContainers.
*/
private void editSelectedItem() {
List<FactoryPathEntry> selected= getSelectedListContents();
if (selected.size() != 1) {
return;
}
FactoryPathEntry original = selected.get(0);
FactoryPathEntry[] edited = null;
switch (original._fc.getType()) {
case PLUGIN:
return;
case EXTJAR:
edited= openExtJarFileDialog(original);
break;
case VARJAR:
edited= openVariableSelectionDialog(original);
break;
case WKSPJAR:
edited= openJarFileDialog(original);
break;
}
if (edited != null && edited.length > 0) {
fFactoryPathList.replaceElement(original, edited[0]);
}
}
/* (non-Javadoc)
* @see org.eclipse.jdt.apt.ui.internal.preferences.BaseConfigurationBlock#createContents(org.eclipse.swt.widgets.Composite)
*/
protected Control createContents(Composite parent) {
setShell(parent.getShell());
fPixelConverter= new PixelConverter(parent);
fBlockControl= new Composite(parent, SWT.NONE);
fBlockControl.setFont(parent.getFont());
Dialog.applyDialogFont(fBlockControl);
LayoutUtil.doDefaultLayout(fBlockControl, new DialogField[] { fFactoryPathList }, true, SWT.DEFAULT, SWT.DEFAULT);
LayoutUtil.setHorizontalGrabbing(fFactoryPathList.getListControl(null));
fFactoryPathList.enableButton(IDX_ADDJAR, (fJProj != null));
// bugzilla 139101: only enable Advanced and Edit buttons if there is a selection
fFactoryPathList.enableButton(IDX_ADVANCED, false);
fFactoryPathList.enableButton(IDX_EDIT, false);
int buttonBarWidth= fPixelConverter.convertWidthInCharsToPixels(24);
fFactoryPathList.setButtonsMinWidth(buttonBarWidth);
return fBlockControl;
}
@Override
public boolean hasProjectSpecificOptionsNoCache(IProject project) {
return (project == null) ? false : AptConfig.hasProjectSpecificFactoryPath(JavaCore.create(project));
}
/**
* Initialize the user interface based on the cached original settings.
*/
@Override
protected void initContents() {
setListContents(fOriginalPath);
}
/**
* Save reference copies of the settings, so we can see if anything changed.
* This must stay in sync with the actual saved values for the rebuild logic
* to work; so be sure to call this any time you save (eg in performApply()).
*/
@Override
protected void cacheOriginalValues() {
IFactoryPath ifp = AptConfig.getFactoryPath(fJProj);
// we'll risk this downcast because we're such good buddies with apt.core.
FactoryPath fp = (FactoryPath)ifp;
Map<FactoryContainer, FactoryPath.Attributes> path = fp.getAllContainers();
fOriginalPath = FactoryPathEntry.pathListFromMap(path);
super.cacheOriginalValues();
}
/*
* Helper method to get rid of unchecked conversion warning
*/
@SuppressWarnings("unchecked")
private List<FactoryPathEntry> getListContents() {
List<FactoryPathEntry> contents= fFactoryPathList.getElements();
return contents;
}
/*
* Helper method to get rid of unchecked conversion warning
*/
@SuppressWarnings("unchecked")
private List<FactoryPathEntry> getSelectedListContents() {
List<FactoryPathEntry> contents= fFactoryPathList.getSelectedElements();
return contents;
}
/**
* Add new entries to the list control. Differs from setListContents()
* in that the list is not cleared first, and the entries are not copied
* before being added to the list.
* @param entries can be null.
*/
private void addEntries(FactoryPathEntry[] entries) {
if (null == entries) {
return;
}
int insertAt;
List<FactoryPathEntry> selectedElements= getSelectedListContents();
if (selectedElements.size() == 1) {
insertAt= fFactoryPathList.getIndexOfElement(selectedElements.get(0)) + 1;
} else {
insertAt= fFactoryPathList.getSize();
}
try {
fSettingListContents = true;
for (int i = 0; i < entries.length; ++i) {
fFactoryPathList.addElement(entries[i], insertAt + i);
fFactoryPathList.setChecked(entries[i], entries[i]._attr.isEnabled());
}
}
finally {
fSettingListContents = false;
}
}
/**
* Set the contents of the list control. The FPEs in the input list
* will be copied; the originals are left untouched, so that if the
* list control's contents are modified they can be compared with the
* original.
* @param fpeList can be null.
*/
private void setListContents(List<FactoryPathEntry> fpeList) {
try {
fSettingListContents = true;
fFactoryPathList.removeAllElements();
if (fpeList == null) {
return;
}
for (FactoryPathEntry originalFpe : fpeList) {
// clone, because we may later want to compare with the original.
FactoryPathEntry fpe = new FactoryPathEntry(originalFpe._fc, new Attributes(originalFpe._attr));
fFactoryPathList.addElement(fpe);
fFactoryPathList.setChecked(fpe, fpe._attr.isEnabled());
}
}
finally {
fSettingListContents = false;
}
}
/**
* Get all the containers of a certain type currently on the list.
* The format of the returned paths will depend on the container type:
* for EXTJAR it will be an absolute path; for WKSPJAR it will be a
* path relative to the workspace root; for VARJAR it will be a path
* whose first segment is the name of a classpath variable.
* @param type may not be PLUGIN
* @param ignore null, or an item to not put on the list (used when
* editing an existing item).
* @return an array, possibly empty (but never null)
*/
private IPath[] getExistingPaths(FactoryContainer.FactoryType type, FactoryContainer ignore) {
if (type == FactoryContainer.FactoryType.PLUGIN) {
throw new IllegalArgumentException();
}
List<FactoryPathEntry> all = getListContents();
// find out how many entries there are of this type
int countType = 0;
for (FactoryPathEntry fpe : all) {
FactoryContainer fc = fpe._fc;
if (fc.getType() == type && fc != ignore) {
++countType;
}
}
// create an array of paths, one per entry of this type
IPath[] some = new IPath[countType];
int i = 0;
for (FactoryPathEntry fpe : all) {
FactoryContainer fc = fpe._fc;
if (fc.getType() == type && fc != ignore) {
some[i++] = new Path(fc.getId());
}
}
return some;
}
/**
* Launch the "advanced options" dialog, which displays the factory classes
* contained by the selected container and allows the user to specify
* options that are needed only in certain special cases.
*
* We treat advanced options as an attribute of the factory path, not of the
* container; the same container may have different advanced options in different
* projects. We treat advanced options the same way as the "enabled" flag.
*/
private void advancedOptionsDialog() {
List<FactoryPathEntry> selected= getSelectedListContents();
if (selected.size() != 1) {
return;
}
FactoryPathEntry original= selected.get(0);
AdvancedFactoryPathOptionsDialog dialog=
new AdvancedFactoryPathOptionsDialog(getShell(), original._fc, original._attr);
if (dialog.open() == Window.OK) {
original._attr = dialog.getResult();
// If the dialog could change the enabled attribute, we would also
// need to update the checkbox in the GUI here. But it doesn't.
}
}
/**
* Add or edit a project-relative jar file. Only possible when editing
* project properties; this method is disabled in workspace prefs.
* @param original null, or an existing list entry to be edited
* @return a list of additional factory path entries to be added
*/
private FactoryPathEntry[] openJarFileDialog(FactoryPathEntry original) {
if (fJProj == null) {
return null;
}
IWorkspaceRoot root= fJProj.getProject().getWorkspace().getRoot();
if (original == null) {
IPath[] results= BuildPathDialogAccess.chooseJAREntries(getShell(), fJProj.getPath(), new IPath[0]);
if (results == null) {
return null;
}
ArrayList<FactoryPathEntry> res= new ArrayList<FactoryPathEntry>();
for (int i= 0; i < results.length; i++) {
IResource resource= root.findMember(results[i]);
if (resource instanceof IFile) {
FactoryContainer fc = FactoryPathUtil.newWkspJarFactoryContainer(results[i]);
// assume defaults of enabled=true, runInAptMode=false
FactoryPath.Attributes attr = new FactoryPath.Attributes(true, false);
FactoryPathEntry fpe = new FactoryPathEntry(fc, attr);
res.add(fpe);
}
//TODO: handle missing jars
}
return res.toArray(new FactoryPathEntry[res.size()]);
}
else {
IPath[] existingPaths = getExistingPaths(FactoryContainer.FactoryType.WKSPJAR, original._fc);
IPath result= BuildPathDialogAccess.configureJAREntry(getShell(), new Path(original._fc.getId()), existingPaths);
if (result == null) {
return null;
}
IResource resource= root.findMember(result);
if (resource instanceof IFile) {
FactoryPathEntry[] edited = new FactoryPathEntry[1];
FactoryContainer fc= FactoryPathUtil.newWkspJarFactoryContainer(result);
// Use prior value for isEnabled. Assume default of runInAptMode=false
FactoryPath.Attributes attr = new FactoryPath.Attributes(original._attr.isEnabled(), false);
edited[0]= new FactoryPathEntry(fc, attr);
return edited;
}
//TODO: handle missing jars
return null;
}
}
/**
* Add or edit an external (not project-relative) jar file.
* @param original null, or an existing list entry to be edited
* @return a list of additional factory path entries to be added
*/
private FactoryPathEntry[] openExtJarFileDialog(FactoryPathEntry original) {
if (original == null) {
IPath[] selected= BuildPathDialogAccess.chooseExternalJAREntries(getShell());
if (selected == null) {
return null;
}
ArrayList<FactoryPathEntry> res= new ArrayList<FactoryPathEntry>();
for (int i= 0; i < selected.length; i++) {
FactoryContainer fc = FactoryPathUtil.newExtJarFactoryContainer(selected[i].toFile());
// assume defaults of enabled=true, runInAptMode=false
FactoryPath.Attributes attr = new FactoryPath.Attributes(true, false);
FactoryPathEntry fpe = new FactoryPathEntry(fc, attr);
res.add(fpe);
}
return res.toArray(new FactoryPathEntry[res.size()]);
}
else {
IPath result= BuildPathDialogAccess.configureExternalJAREntry(getShell(), new Path(original._fc.getId()));
if (result == null) {
return null;
}
FactoryPathEntry[] edited= new FactoryPathEntry[1];
FactoryContainer fc= FactoryPathUtil.newExtJarFactoryContainer(result.toFile());
// Use prior value for isEnabled. Assume default of runInAptMode=false
FactoryPath.Attributes attr = new FactoryPath.Attributes(original._attr.isEnabled(), false);
edited[0]= new FactoryPathEntry(fc, attr);
return edited;
}
}
/**
* Add or edit an external (not project-relative) jar file whose
* location includes a classpath variable name.
* @param original null, or an existing list entry to be edited
* @return a list of additional factory path entries to be added
*/
private FactoryPathEntry[] openVariableSelectionDialog(FactoryPathEntry original) {
if (original == null) {
IPath[] selected= BuildPathDialogAccess.chooseVariableEntries(getShell(), new IPath[0]);
if (selected == null) {
return null;
}
ArrayList<FactoryPathEntry> res= new ArrayList<FactoryPathEntry>();
for (int i= 0; i < selected.length; i++) {
FactoryContainer fc= FactoryPathUtil.newVarJarFactoryContainer(selected[i]);
// assume defaults of enabled=true, runInAptMode=false
FactoryPath.Attributes attr = new FactoryPath.Attributes(true, false);
FactoryPathEntry fpe = new FactoryPathEntry(fc, attr);
res.add(fpe);
}
return res.toArray(new FactoryPathEntry[res.size()]);
}
else {
IPath[] existingPaths = getExistingPaths(FactoryContainer.FactoryType.VARJAR, original._fc);
IPath result= BuildPathDialogAccess.configureVariableEntry(getShell(), new Path(original._fc.getId()), existingPaths);
if (result == null) {
return null;
}
FactoryPathEntry[] edited= new FactoryPathEntry[1];
FactoryContainer fc= FactoryPathUtil.newVarJarFactoryContainer(result);
// Use prior value for isEnabled. Assume default of runInAptMode=false
FactoryPath.Attributes attr = new FactoryPath.Attributes(original._attr.isEnabled(), false);
edited[0]= new FactoryPathEntry(fc, attr);
return edited;
}
}
/* (non-Javadoc)
* @see org.eclipse.jdt.apt.ui.internal.preferences.BaseConfigurationBlock#updateModel(org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField)
*/
protected void updateModel(DialogField field) {
// We don't use IEclipsePreferences for this pane, so no need to do anything.
}
/* (non-Javadoc)
* @see org.eclipse.jdt.apt.ui.internal.preferences.BaseConfigurationBlock#validateSettings(org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock.Key, java.lang.String, java.lang.String)
*/
protected void validateSettings(Key changedKey, String oldValue, String newValue) {
// TODO: validate that all the specified factory containers exist?
}
protected void saveSettings() {
FactoryPath fp;
if ((fJProj != null) && !fBlockControl.isEnabled()) {
// We're in a project properties pane but the entire configuration
// block control is disabled. That means the per-project settings checkbox
// is unchecked. To save that state, we'll delete the settings file.
fp = null;
}
else {
List<FactoryPathEntry> containers;
Map<FactoryContainer, FactoryPath.Attributes> map;
containers = getListContents();
map = FactoryPathEntry.pathMapFromList(containers);
fp = new FactoryPath();
fp.setContainers(map);
}
try {
AptConfig.setFactoryPath(fJProj, fp);
}
catch (CoreException e) {
final String title = Messages.FactoryPathConfigurationBlock_unableToSaveFactorypath_title;
final String message = Messages.FactoryPathConfigurationBlock_unableToSaveFactorypath_message;
ExceptionHandler.handle(e, fBlockControl.getShell(), title, message);
}
super.saveSettings();
}
/**
* If per-project, restore list contents to current workspace settings;
* the per-project settings checkbox will be cleared for us automatically.
* If workspace, restore list contents to factory-default settings.
*/
public void performDefaults() {
IFactoryPath ifp = AptConfig.getDefaultFactoryPath(fJProj);
// we'll risk this downcast because we're such good buddies with apt.core.
FactoryPath fp = (FactoryPath)ifp;
Map<FactoryContainer, FactoryPath.Attributes> map = fp.getAllContainers();
List<FactoryPathEntry> defaults = FactoryPathEntry.pathListFromMap(map);
setListContents(defaults);
super.performDefaults();
}
/**
* @return true if settings or project-specificness changed since
* the pane was launched - that is, if there is anything to save.
*/
@Override
protected boolean settingsChanged(IScopeContext currContext) {
if (fOriginalPath == null) {
// shouldn't happen, but just in case it does, consider it a change.
return true;
}
// Is the new path the same size, containing the same items
// in the same order? We rely on FactoryPathEntry.equals() here.
List<FactoryPathEntry> newPath = getListContents();
return !fOriginalPath.equals(newPath);
}
}