blob: 28f414f61ccb6bfad4d1e69c4eae348ad8e0fef5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2007 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.wst.jsdt.internal.ui.workingsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PlatformUI;
import com.ibm.icu.text.Collator;
public class WorkingSetConfigurationBlock {
//Some static methods for convenience
/**
* Retrieves a working set from the given <code>selection</code>
* or <b>null</b> if no working set could be retrieved.
*
* @param selection the selection to retrieve the working set from
* @return the selected working set or <b>null</b>
*/
public static IWorkingSet[] getSelectedWorkingSet(IStructuredSelection selection) {
if (!(selection instanceof ITreeSelection))
return null;
ITreeSelection treeSelection= (ITreeSelection)selection;
if (treeSelection.isEmpty())
return null;
List elements= treeSelection.toList();
if (elements.size() == 1) {
Object element= elements.get(0);
TreePath[] paths= treeSelection.getPathsFor(element);
if (paths.length != 1)
return null;
TreePath path= paths[0];
if (path.getSegmentCount() == 0)
return null;
Object candidate= path.getSegment(0);
if (!(candidate instanceof IWorkingSet))
return null;
return new IWorkingSet[] {(IWorkingSet)candidate};
} else {
ArrayList result= new ArrayList();
for (Iterator iterator= elements.iterator(); iterator.hasNext();) {
Object element= iterator.next();
if (element instanceof IWorkingSet) {
result.add(element);
}
}
return (IWorkingSet[])result.toArray(new IWorkingSet[result.size()]);
}
}
/**
* Add the <code>element</code> to each given working set in
* <code>workingSets</code> if possible.
*
* @param element the element to add
* @param workingSets the working sets to add the element to
*/
public static void addToWorkingSets(IAdaptable element, IWorkingSet[] workingSets) {
for (int i= 0; i < workingSets.length; i++) {
IWorkingSet workingSet= workingSets[i];
IAdaptable[] adaptedNewElements= workingSet.adaptElements(new IAdaptable[] {element});
if (adaptedNewElements.length == 1) {
IAdaptable[] elements= workingSet.getElements();
IAdaptable[] newElements= new IAdaptable[elements.length + 1];
System.arraycopy(elements, 0, newElements, 0, elements.length);
newElements[newElements.length - 1]= adaptedNewElements[0];
workingSet.setElements(newElements);
}
}
}
/**
* Filters the given working sets such that the following is true:
* for each IWorkingSet s in result: s.getId() is element of workingSetIds
*
* @param workingSets the array to filter
* @param workingSetIds the acceptable working set ids
* @return the filtered elements
*/
public static IWorkingSet[] filter(IWorkingSet[] workingSets, String[] workingSetIds) {
ArrayList result= new ArrayList();
for (int i= 0; i < workingSets.length; i++) {
if (accept(workingSets[i], workingSetIds))
result.add(workingSets[i]);
}
return (IWorkingSet[])result.toArray(new IWorkingSet[result.size()]);
}
private static boolean accept(IWorkingSet set, String[] workingSetIDs) {
for (int i= 0; i < workingSetIDs.length; i++) {
if (workingSetIDs[i].equals(set.getId()))
return true;
}
return false;
}
private static final String WORKINGSET_SELECTION_HISTORY= "workingset_selection_history"; //$NON-NLS-1$
private static final int MAX_HISTORY_SIZE= 5;
private Label fLabel;
private Combo fWorkingSetCombo;
private Button fConfigure;
private IWorkingSet[] fSelectedWorkingSets;
private String fMessage;
private Button fEnableButton;
private ArrayList fSelectionHistory;
private final IDialogSettings fSettings;
private final String fEnableButtonText;
private final String[] fWorkingSetIds;
/**
* @param workingSetIds working set ids from which the user can choose
* @param enableButtonText the text shown for the enable button
* @param settings to store/load the selection history
*/
public WorkingSetConfigurationBlock(String[] workingSetIds, String enableButtonText, IDialogSettings settings) {
Assert.isNotNull(workingSetIds);
Assert.isNotNull(enableButtonText);
Assert.isNotNull(settings);
fWorkingSetIds= workingSetIds;
fEnableButtonText= enableButtonText;
fSelectedWorkingSets= new IWorkingSet[0];
fSettings= settings;
fSelectionHistory= loadSelectionHistory(settings, workingSetIds);
}
/**
* @param message the message to show to the user in the working set selection dialog
*/
public void setDialogMessage(String message) {
fMessage= message;
}
/**
* @param selection the selection to present in the UI or <b>null</b>
*/
public void setSelection(IWorkingSet[] selection) {
if (selection == null)
selection= new IWorkingSet[0];
fSelectedWorkingSets= selection;
if (fWorkingSetCombo != null)
updateSelectedWorkingSets();
}
/**
* @return the selected working sets
*/
public IWorkingSet[] getSelectedWorkingSets() {
if (fEnableButton.getSelection()) {
return fSelectedWorkingSets;
} else {
return new IWorkingSet[0];
}
}
/**
* Add this block to the <code>parent</parent>
*
* @param parent the parent to add the block to
*/
public void createContent(final Composite parent) {
int numColumn= 3;
Composite composite= new Composite(parent, SWT.NONE);
composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
composite.setLayout(new GridLayout(numColumn, false));
fEnableButton= new Button(composite, SWT.CHECK);
fEnableButton.setText(fEnableButtonText);
GridData enableData= new GridData(SWT.FILL, SWT.CENTER, true, false);
enableData.horizontalSpan= numColumn;
fEnableButton.setLayoutData(enableData);
fEnableButton.setSelection(fSelectedWorkingSets.length > 0);
fLabel= new Label(composite, SWT.NONE);
fLabel.setText(WorkingSetMessages.WorkingSetConfigurationBlock_WorkingSetText_name);
fWorkingSetCombo= new Combo(composite, SWT.READ_ONLY | SWT.BORDER);
GridData textData= new GridData(SWT.FILL, SWT.CENTER, true, false);
textData.horizontalSpan= numColumn - 2;
textData.horizontalIndent= 0;
fWorkingSetCombo.setLayoutData(textData);
fConfigure= new Button(composite, SWT.PUSH);
fConfigure.setText(WorkingSetMessages.WorkingSetConfigurationBlock_SelectWorkingSet_button);
GridData configureData= new GridData(SWT.LEFT, SWT.CENTER, false, false);
configureData.widthHint= getButtonWidthHint(fConfigure);
fConfigure.setLayoutData(configureData);
fConfigure.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
SimpleWorkingSetSelectionDialog dialog= new SimpleWorkingSetSelectionDialog(parent.getShell(), fWorkingSetIds, fSelectedWorkingSets);
if (fMessage != null)
dialog.setMessage(fMessage);
if (dialog.open() == Window.OK) {
IWorkingSet[] result= dialog.getSelection();
if (result != null && result.length > 0) {
fSelectedWorkingSets= result;
PlatformUI.getWorkbench().getWorkingSetManager().addRecentWorkingSet(result[0]);
} else {
fSelectedWorkingSets= new IWorkingSet[0];
}
updateWorkingSetSelection();
}
}
});
fEnableButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
updateEnableState(fEnableButton.getSelection());
}
});
updateEnableState(fEnableButton.getSelection());
fWorkingSetCombo.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
updateSelectedWorkingSets();
}
});
fWorkingSetCombo.setItems(getHistoryEntries());
if (fSelectedWorkingSets.length == 0 && fSelectionHistory.size() > 0) {
fWorkingSetCombo.select(historyIndex((String)fSelectionHistory.get(0)));
updateSelectedWorkingSets();
} else {
updateWorkingSetSelection();
}
}
private void updateEnableState(boolean enabled) {
fLabel.setEnabled(enabled);
fWorkingSetCombo.setEnabled(enabled && (fSelectedWorkingSets.length > 0 || getHistoryEntries().length > 0));
fConfigure.setEnabled(enabled);
}
private void updateWorkingSetSelection() {
if (fSelectedWorkingSets.length > 0) {
fWorkingSetCombo.setEnabled(true);
StringBuffer buf= new StringBuffer();
buf.append(fSelectedWorkingSets[0].getLabel());
for (int i= 1; i < fSelectedWorkingSets.length; i++) {
IWorkingSet ws= fSelectedWorkingSets[i];
buf.append(',').append(' ');
buf.append(ws.getLabel());
}
String currentSelection= buf.toString();
int index= historyIndex(currentSelection);
historyInsert(currentSelection);
if (index >= 0) {
fWorkingSetCombo.select(index);
} else {
fWorkingSetCombo.setItems(getHistoryEntries());
fWorkingSetCombo.select(historyIndex(currentSelection));
}
}else {
fEnableButton.setSelection(false);
updateEnableState(false);
}
}
private String[] getHistoryEntries() {
String[] history= (String[])fSelectionHistory.toArray(new String[fSelectionHistory.size()]);
Arrays.sort(history, new Comparator() {
public int compare(Object o1, Object o2) {
return Collator.getInstance().compare(o1, o2);
}
});
return history;
}
private void historyInsert(String entry) {
fSelectionHistory.remove(entry);
fSelectionHistory.add(0, entry);
storeSelectionHistory(fSettings);
}
private int historyIndex(String entry) {
for (int i= 0; i < fWorkingSetCombo.getItemCount(); i++) {
if (fWorkingSetCombo.getItem(i).equals(entry))
return i;
}
return -1;
}
private void updateSelectedWorkingSets() {
String item= fWorkingSetCombo.getItem(fWorkingSetCombo.getSelectionIndex());
String[] workingSetNames= item.split(", "); //$NON-NLS-1$
IWorkingSetManager workingSetManager= PlatformUI.getWorkbench().getWorkingSetManager();
fSelectedWorkingSets= new IWorkingSet[workingSetNames.length];
for (int i= 0; i < workingSetNames.length; i++) {
IWorkingSet set= workingSetManager.getWorkingSet(workingSetNames[i]);
Assert.isNotNull(set);
fSelectedWorkingSets[i]= set;
}
}
private void storeSelectionHistory(IDialogSettings settings) {
String[] history;
if (fSelectionHistory.size() > MAX_HISTORY_SIZE) {
List subList= fSelectionHistory.subList(0, MAX_HISTORY_SIZE);
history= (String[])subList.toArray(new String[subList.size()]);
} else {
history= (String[])fSelectionHistory.toArray(new String[fSelectionHistory.size()]);
}
settings.put(WORKINGSET_SELECTION_HISTORY, history);
}
private ArrayList loadSelectionHistory(IDialogSettings settings, String[] workingSetIds) {
String[] strings= settings.getArray(WORKINGSET_SELECTION_HISTORY);
if (strings == null || strings.length == 0)
return new ArrayList();
ArrayList result= new ArrayList();
HashSet workingSetIdsSet= new HashSet(Arrays.asList(workingSetIds));
IWorkingSetManager workingSetManager= PlatformUI.getWorkbench().getWorkingSetManager();
for (int i= 0; i < strings.length; i++) {
String[] workingSetNames= strings[i].split(", "); //$NON-NLS-1$
boolean valid= true;
for (int j= 0; j < workingSetNames.length && valid; j++) {
IWorkingSet workingSet= workingSetManager.getWorkingSet(workingSetNames[j]);
if (workingSet == null) {
valid= false;
} else {
if (!workingSetIdsSet.contains(workingSet.getId()))
valid= false;
}
}
if (valid) {
result.add(strings[i]);
}
}
return result;
}
private static int getButtonWidthHint(Button button) {
button.setFont(JFaceResources.getDialogFont());
GC gc = new GC(button);
gc.setFont(button.getFont());
FontMetrics fontMetrics= gc.getFontMetrics();
gc.dispose();
int widthHint= Dialog.convertHorizontalDLUsToPixels(fontMetrics, IDialogConstants.BUTTON_WIDTH);
return Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
}
}