| /******************************************************************************* |
| * 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); |
| } |
| } |