1 /*******************************************************************************
2 * Copyright (c) 2000, 2011 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 * Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog font
11 * should be activated and used by other components.
12 *******************************************************************************/
13 package org.eclipse.jdt.internal.ui.workingsets;
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.Collections;
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.Hashtable;
21 import java.util.Iterator;
22 import java.util.List;
26 import org.eclipse.swt.SWT;
27 import org.eclipse.swt.events.SelectionAdapter;
28 import org.eclipse.swt.events.SelectionEvent;
29 import org.eclipse.swt.graphics.Image;
30 import org.eclipse.swt.layout.GridData;
31 import org.eclipse.swt.layout.GridLayout;
32 import org.eclipse.swt.widgets.Button;
33 import org.eclipse.swt.widgets.Composite;
34 import org.eclipse.swt.widgets.Control;
35 import org.eclipse.swt.widgets.Shell;
37 import org.eclipse.core.runtime.Assert;
39 import org.eclipse.jface.dialogs.IDialogConstants;
40 import org.eclipse.jface.resource.ImageDescriptor;
41 import org.eclipse.jface.viewers.ArrayContentProvider;
42 import org.eclipse.jface.viewers.CheckStateChangedEvent;
43 import org.eclipse.jface.viewers.CheckboxTableViewer;
44 import org.eclipse.jface.viewers.DoubleClickEvent;
45 import org.eclipse.jface.viewers.ICheckStateListener;
46 import org.eclipse.jface.viewers.IDoubleClickListener;
47 import org.eclipse.jface.viewers.ISelection;
48 import org.eclipse.jface.viewers.ISelectionChangedListener;
49 import org.eclipse.jface.viewers.IStructuredSelection;
50 import org.eclipse.jface.viewers.LabelProvider;
51 import org.eclipse.jface.viewers.SelectionChangedEvent;
52 import org.eclipse.jface.viewers.StructuredSelection;
53 import org.eclipse.jface.viewers.Viewer;
54 import org.eclipse.jface.viewers.ViewerComparator;
55 import org.eclipse.jface.window.Window;
56 import org.eclipse.jface.wizard.WizardDialog;
58 import org.eclipse.ui.IWorkingSet;
59 import org.eclipse.ui.IWorkingSetManager;
60 import org.eclipse.ui.PlatformUI;
61 import org.eclipse.ui.dialogs.IWorkingSetEditWizard;
62 import org.eclipse.ui.dialogs.IWorkingSetNewWizard;
63 import org.eclipse.ui.dialogs.SelectionDialog;
65 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
66 import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
68 public class WorkingSetConfigurationDialog extends SelectionDialog {
70 private static class WorkingSetLabelProvider extends LabelProvider {
71 private Map<ImageDescriptor, Image> fIcons;
72 public WorkingSetLabelProvider() {
73 fIcons= new Hashtable<ImageDescriptor, Image>();
76 public void dispose() {
77 Iterator<Image> iterator= fIcons.values().iterator();
78 while (iterator.hasNext()) {
79 Image icon= iterator.next();
85 public Image getImage(Object object) {
86 Assert.isTrue(object instanceof IWorkingSet);
87 IWorkingSet workingSet= (IWorkingSet)object;
88 ImageDescriptor imageDescriptor= workingSet.getImageDescriptor();
89 if (imageDescriptor == null)
91 Image icon= fIcons.get(imageDescriptor);
93 icon= imageDescriptor.createImage();
94 fIcons.put(imageDescriptor, icon);
99 public String getText(Object object) {
100 Assert.isTrue(object instanceof IWorkingSet);
101 IWorkingSet workingSet= (IWorkingSet)object;
102 return BasicElementLabels.getWorkingSetLabel(workingSet);
106 private List<IWorkingSet> fAllWorkingSets;
107 private CheckboxTableViewer fTableViewer;
109 private Button fNewButton;
110 private Button fEditButton;
111 private Button fRemoveButton;
112 private Button fUpButton;
113 private Button fDownButton;
114 private Button fSelectAll;
115 private Button fDeselectAll;
118 * Sort working sets button.
122 private Button fSortWorkingSet;
124 private IWorkingSet[] fResult;
125 private List<IWorkingSet> fAddedWorkingSets;
126 private List<IWorkingSet> fRemovedWorkingSets;
127 private Map<IWorkingSet, IWorkingSet> fEditedWorkingSets;
128 private List<IWorkingSet> fRemovedMRUWorkingSets;
130 private int nextButtonId= IDialogConstants.CLIENT_ID + 1;
133 * Value of sorted state of working sets.
137 private boolean fIsSortingEnabled;
140 * The working set comparator.
144 private WorkingSetComparator fComparator;
146 public WorkingSetConfigurationDialog(Shell parentShell, IWorkingSet[] allWorkingSets, boolean isSortingEnabled) {
148 setTitle(WorkingSetMessages.WorkingSetConfigurationDialog_title);
149 setMessage(WorkingSetMessages.WorkingSetConfigurationDialog_message);
150 fAllWorkingSets= new ArrayList<IWorkingSet>(allWorkingSets.length);
151 for (int i= 0; i < allWorkingSets.length; i++) {
152 fAllWorkingSets.add(allWorkingSets[i]);
154 fIsSortingEnabled= isSortingEnabled;
161 protected void configureShell(Shell shell) {
162 super.configureShell(shell);
163 PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IJavaHelpContextIds.WORKING_SET_CONFIGURATION_DIALOG);
167 * Returns the selected working sets
169 * @return the selected working sets
171 public IWorkingSet[] getSelection() {
176 * Sets the initial selection
178 * @param workingSets the initial selection
180 public void setSelection(IWorkingSet[] workingSets) {
181 fResult= workingSets;
182 setInitialSelections(workingSets);
189 protected Control createContents(Composite parent) {
190 Control control= super.createContents(parent);
191 setInitialSelection();
192 updateButtonAvailability();
200 protected Control createDialogArea(Composite parent) {
201 Composite composite= (Composite)super.createDialogArea(parent);
203 createMessageArea(composite);
204 Composite inner= new Composite(composite, SWT.NONE);
205 inner.setLayoutData(new GridData(GridData.FILL_BOTH));
206 GridLayout layout= new GridLayout();
207 layout.numColumns= 2;
208 layout.marginHeight= 0;
209 layout.marginWidth= 0;
210 inner.setLayout(layout);
211 createTableViewer(inner);
212 createOrderButtons(inner);
213 createModifyButtons(composite);
214 if (fIsSortingEnabled) {
215 fTableViewer.setComparator(new ViewerComparator(getComparator()) {
217 * @see ViewerComparator#compare(Viewer, Object, Object)
221 public int compare(Viewer viewer, Object e1, Object e2) {
222 return getComparator().compare(e1, e2);
226 fTableViewer.setInput(fAllWorkingSets);
227 applyDialogFont(composite);
232 private void createTableViewer(Composite parent) {
233 fTableViewer= CheckboxTableViewer.newCheckList(parent, SWT.BORDER | SWT.MULTI);
234 fTableViewer.addCheckStateListener(new ICheckStateListener() {
235 public void checkStateChanged(CheckStateChangedEvent event) {
236 updateButtonAvailability();
239 GridData data= new GridData(GridData.FILL_BOTH);
240 data.heightHint= convertHeightInCharsToPixels(20);
241 data.widthHint= convertWidthInCharsToPixels(50);
242 fTableViewer.getTable().setLayoutData(data);
244 fTableViewer.setLabelProvider(new WorkingSetLabelProvider());
245 fTableViewer.setContentProvider(new ArrayContentProvider());
246 fTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
247 public void selectionChanged(SelectionChangedEvent event) {
248 handleSelectionChanged();
251 fTableViewer.addDoubleClickListener(new IDoubleClickListener() {
252 public void doubleClick(DoubleClickEvent event) {
253 if (fEditButton.isEnabled())
254 editSelectedWorkingSet();
259 private void createModifyButtons(Composite composite) {
260 Composite buttonComposite= new Composite(composite, SWT.RIGHT);
261 GridLayout layout= new GridLayout();
262 layout.numColumns= 2;
263 buttonComposite.setLayout(layout);
264 GridData data= new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.GRAB_HORIZONTAL);
265 data.grabExcessHorizontalSpace= true;
266 composite.setData(data);
268 fNewButton= createButton(buttonComposite, nextButtonId++,
269 WorkingSetMessages.WorkingSetConfigurationDialog_new_label, false);
270 fNewButton.addSelectionListener(new SelectionAdapter() {
272 public void widgetSelected(SelectionEvent e) {
277 fEditButton= createButton(buttonComposite, nextButtonId++,
278 WorkingSetMessages.WorkingSetConfigurationDialog_edit_label, false);
279 fEditButton.addSelectionListener(new SelectionAdapter() {
281 public void widgetSelected(SelectionEvent e) {
282 editSelectedWorkingSet();
286 fRemoveButton= createButton(buttonComposite, nextButtonId++,
287 WorkingSetMessages.WorkingSetConfigurationDialog_remove_label, false);
288 fRemoveButton.addSelectionListener(new SelectionAdapter() {
290 public void widgetSelected(SelectionEvent e) {
291 removeSelectedWorkingSets();
296 private void createOrderButtons(Composite parent) {
297 Composite buttons= new Composite(parent, SWT.NONE);
298 buttons.setLayoutData(new GridData(GridData.FILL_VERTICAL));
299 GridLayout layout= new GridLayout();
300 layout.marginHeight= 0;
301 layout.marginWidth= 0;
302 buttons.setLayout(layout);
304 fUpButton= new Button(buttons, SWT.PUSH);
305 fUpButton.setText(WorkingSetMessages.WorkingSetConfigurationDialog_up_label);
306 setButtonLayoutData(fUpButton);
307 fUpButton.addSelectionListener(new SelectionAdapter() {
309 public void widgetSelected(SelectionEvent e) {
310 moveUp(((IStructuredSelection)fTableViewer.getSelection()).toList());
314 fDownButton= new Button(buttons, SWT.PUSH);
315 fDownButton.setText(WorkingSetMessages.WorkingSetConfigurationDialog_down_label);
316 setButtonLayoutData(fDownButton);
317 fDownButton.addSelectionListener(new SelectionAdapter() {
319 public void widgetSelected(SelectionEvent e) {
320 moveDown(((IStructuredSelection)fTableViewer.getSelection()).toList());
324 fSelectAll= new Button(buttons, SWT.PUSH);
325 fSelectAll.setText(WorkingSetMessages.WorkingSetConfigurationDialog_selectAll_label);
326 setButtonLayoutData(fSelectAll);
327 fSelectAll.addSelectionListener(new SelectionAdapter() {
329 public void widgetSelected(SelectionEvent e) {
334 fDeselectAll= new Button(buttons, SWT.PUSH);
335 fDeselectAll.setText(WorkingSetMessages.WorkingSetConfigurationDialog_deselectAll_label);
336 setButtonLayoutData(fDeselectAll);
337 fDeselectAll.addSelectionListener(new SelectionAdapter() {
339 public void widgetSelected(SelectionEvent e) {
344 * A check box that has persistence to sort the working sets alphabetically in the
345 * WorkingSetConfigurationDialog. It restores the unsorted order of the working sets when
350 fSortWorkingSet= new Button(parent, SWT.CHECK);
351 fSortWorkingSet.setText(WorkingSetMessages.WorkingSetConfigurationDialog_sort_working_sets);
352 fSortWorkingSet.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, true, false));
353 fSortWorkingSet.setSelection(fIsSortingEnabled);
354 fSortWorkingSet.addSelectionListener(new SelectionAdapter() {
356 public void widgetSelected(SelectionEvent e) {
357 fIsSortingEnabled= fSortWorkingSet.getSelection();
358 updateButtonAvailability();
359 if (fIsSortingEnabled) {
360 fTableViewer.setComparator(new ViewerComparator(getComparator()) {
362 * @see ViewerComparator#compare(Viewer, Object, Object)
366 public int compare(Viewer viewer, Object e1, Object e2) {
367 return getComparator().compare(e1, e2);
371 fTableViewer.setComparator(null);
381 protected void okPressed() {
382 List<IWorkingSet> newResult= getResultWorkingSets();
383 fResult= newResult.toArray(new IWorkingSet[newResult.size()]);
384 if (fIsSortingEnabled) {
385 Collections.sort(fAllWorkingSets, getComparator());
387 setResult(newResult);
391 @SuppressWarnings({ "unchecked", "rawtypes" })
392 private List<IWorkingSet> getResultWorkingSets() {
393 Object[] checked= fTableViewer.getCheckedElements();
394 return new ArrayList(Arrays.asList(checked));
401 protected void cancelPressed() {
402 restoreAddedWorkingSets();
403 restoreChangedWorkingSets();
404 restoreRemovedWorkingSets();
405 super.cancelPressed();
408 private void setInitialSelection() {
409 List<Object[]> selections= getInitialElementSelections();
410 if (!selections.isEmpty()) {
411 fTableViewer.setCheckedElements(selections.toArray());
415 private void createWorkingSet() {
416 IWorkingSetManager manager= PlatformUI.getWorkbench().getWorkingSetManager();
417 IWorkingSetNewWizard wizard= manager.createWorkingSetNewWizard(new String[] {IWorkingSetIDs.JAVA});
418 // the wizard can't be null since we have at least the Java working set.
419 WizardDialog dialog= new WizardDialog(getShell(), wizard);
421 if (dialog.open() == Window.OK) {
422 IWorkingSet workingSet= wizard.getSelection();
423 if (WorkingSetModel.isSupportedAsTopLevelElement(workingSet)) {
424 fAllWorkingSets.add(workingSet);
425 fTableViewer.add(workingSet);
426 fTableViewer.setSelection(new StructuredSelection(workingSet), true);
427 fTableViewer.setChecked(workingSet, true);
428 manager.addWorkingSet(workingSet);
429 fAddedWorkingSets.add(workingSet);
434 private void editSelectedWorkingSet() {
435 IWorkingSetManager manager= PlatformUI.getWorkbench().getWorkingSetManager();
436 IWorkingSet editWorkingSet= (IWorkingSet)((IStructuredSelection)fTableViewer.getSelection()).getFirstElement();
437 IWorkingSetEditWizard wizard= manager.createWorkingSetEditWizard(editWorkingSet);
438 WizardDialog dialog= new WizardDialog(getShell(), wizard);
439 IWorkingSet originalWorkingSet= fEditedWorkingSets.get(editWorkingSet);
440 boolean firstEdit= originalWorkingSet == null;
442 // save the original working set values for restoration when selection
443 // dialog is cancelled.
446 PlatformUI.getWorkbench().getWorkingSetManager().
447 createWorkingSet(editWorkingSet.getName(), editWorkingSet.getElements());
449 fEditedWorkingSets.remove(editWorkingSet);
452 if (dialog.open() == Window.OK) {
453 editWorkingSet= wizard.getSelection();
454 if (fIsSortingEnabled)
455 fTableViewer.refresh();
457 fTableViewer.update(editWorkingSet, null);
459 // make sure ok button is enabled when the selected working set
460 // is edited. Fixes bug 33386.
461 updateButtonAvailability();
463 fEditedWorkingSets.put(editWorkingSet, originalWorkingSet);
467 * Called when the selection has changed.
469 void handleSelectionChanged() {
470 updateButtonAvailability();
474 * Overrides method in Dialog
476 * @see org.eclipse.jface.dialogs.Dialog#open()
480 fAddedWorkingSets= new ArrayList<IWorkingSet>();
481 fRemovedWorkingSets= new ArrayList<IWorkingSet>();
482 fEditedWorkingSets= new HashMap<IWorkingSet, IWorkingSet>();
483 fRemovedMRUWorkingSets= new ArrayList<IWorkingSet>();
488 * Removes the selected working sets from the workbench.
490 private void removeSelectedWorkingSets() {
491 ISelection selection= fTableViewer.getSelection();
492 if (selection instanceof IStructuredSelection) {
493 IWorkingSetManager manager= PlatformUI.getWorkbench().getWorkingSetManager();
494 Iterator<?> iter= ((IStructuredSelection)selection).iterator();
495 while (iter.hasNext()) {
496 IWorkingSet workingSet= (IWorkingSet)iter.next();
497 if (fAddedWorkingSets.contains(workingSet)) {
498 fAddedWorkingSets.remove(workingSet);
500 IWorkingSet[] recentWorkingSets= manager.getRecentWorkingSets();
501 for (int i= 0; i < recentWorkingSets.length; i++) {
502 if (workingSet.equals(recentWorkingSets[i])) {
503 fRemovedMRUWorkingSets.add(workingSet);
507 fRemovedWorkingSets.add(workingSet);
509 fAllWorkingSets.remove(workingSet);
510 manager.removeWorkingSet(workingSet);
512 fTableViewer.remove(((IStructuredSelection)selection).toArray());
517 * Removes newly created working sets from the working set manager.
519 private void restoreAddedWorkingSets() {
520 IWorkingSetManager manager= PlatformUI.getWorkbench().getWorkingSetManager();
521 Iterator<IWorkingSet> iterator= fAddedWorkingSets.iterator();
523 while (iterator.hasNext()) {
524 manager.removeWorkingSet(iterator.next());
529 * Rolls back changes to working sets.
531 private void restoreChangedWorkingSets() {
532 Iterator<IWorkingSet> iterator= fEditedWorkingSets.keySet().iterator();
534 while (iterator.hasNext()) {
535 IWorkingSet editedWorkingSet= iterator.next();
536 IWorkingSet originalWorkingSet= fEditedWorkingSets.get(editedWorkingSet);
538 if (editedWorkingSet.getName().equals(originalWorkingSet.getName()) == false) {
539 editedWorkingSet.setName(originalWorkingSet.getName());
541 if (editedWorkingSet.getElements().equals(originalWorkingSet.getElements()) == false) {
542 editedWorkingSet.setElements(originalWorkingSet.getElements());
548 * Adds back removed working sets to the working set manager.
550 private void restoreRemovedWorkingSets() {
551 IWorkingSetManager manager= PlatformUI.getWorkbench().getWorkingSetManager();
552 Iterator<IWorkingSet> iterator= fRemovedWorkingSets.iterator();
554 while (iterator.hasNext()) {
555 manager.addWorkingSet(iterator.next());
557 iterator= fRemovedMRUWorkingSets.iterator();
558 while (iterator.hasNext()) {
559 manager.addRecentWorkingSet(iterator.next());
564 * Updates the modify buttons' enabled state based on the current seleciton.
566 private void updateButtonAvailability() {
567 IStructuredSelection selection= (IStructuredSelection) fTableViewer.getSelection();
568 boolean hasSelection= !selection.isEmpty();
569 boolean hasSingleSelection= selection.size() == 1;
571 fRemoveButton.setEnabled(hasSelection && areAllGlobalWorkingSets(selection));
572 fEditButton.setEnabled(hasSingleSelection && ((IWorkingSet)selection.getFirstElement()).isEditable());
573 if (fUpButton != null) {
574 fUpButton.setEnabled(canMoveUp());
576 if (fDownButton != null) {
577 fDownButton.setEnabled(canMoveDown());
581 private boolean areAllGlobalWorkingSets(IStructuredSelection selection) {
582 Set<IWorkingSet> globals= new HashSet<IWorkingSet>(Arrays.asList(PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSets()));
583 for (Iterator<?> iter= selection.iterator(); iter.hasNext();) {
584 if (!globals.contains(iter.next()))
590 private void moveUp(List<IWorkingSet> toMoveUp) {
591 if (toMoveUp.size() > 0) {
592 setElements(moveUp(fAllWorkingSets, toMoveUp));
593 fTableViewer.reveal(toMoveUp.get(0));
597 private void moveDown(List<IWorkingSet> toMoveDown) {
598 if (toMoveDown.size() > 0) {
599 setElements(reverse(moveUp(reverse(fAllWorkingSets), toMoveDown)));
600 fTableViewer.reveal(toMoveDown.get(toMoveDown.size() - 1));
604 private void setElements(List<IWorkingSet> elements) {
605 fAllWorkingSets= elements;
606 fTableViewer.setInput(fAllWorkingSets);
607 updateButtonAvailability();
610 private List<IWorkingSet> moveUp(List<IWorkingSet> elements, List<IWorkingSet> move) {
611 int nElements= elements.size();
612 List<IWorkingSet> res= new ArrayList<IWorkingSet>(nElements);
613 IWorkingSet floating= null;
614 for (int i= 0; i < nElements; i++) {
615 IWorkingSet curr= elements.get(i);
616 if (move.contains(curr)) {
619 if (floating != null) {
625 if (floating != null) {
631 private List<IWorkingSet> reverse(List<IWorkingSet> p) {
632 List<IWorkingSet> reverse= new ArrayList<IWorkingSet>(p.size());
633 for (int i= p.size() - 1; i >= 0; i--) {
634 reverse.add(p.get(i));
639 private boolean canMoveUp() {
640 if (!fIsSortingEnabled) {
641 int[] indc= fTableViewer.getTable().getSelectionIndices();
642 for (int i= 0; i < indc.length; i++) {
651 private boolean canMoveDown() {
652 if (!fIsSortingEnabled) {
653 int[] indc= fTableViewer.getTable().getSelectionIndices();
654 int k= fAllWorkingSets.size() - 1;
655 for (int i= indc.length - 1; i >= 0; i--, k--) {
664 //---- select / deselect --------------------------------------------------
666 private void selectAll() {
667 fTableViewer.setAllChecked(true);
670 private void deselectAll() {
671 fTableViewer.setAllChecked(false);
675 * Returns the list of newly added working sets through this dialog.
677 * @return the list of newly added working sets
680 public List<IWorkingSet> getNewlyAddedWorkingSets() {
681 return fAddedWorkingSets;
686 * Returns whether sorting is enabled for working sets.
688 * @return <code>true</code> if sorting is enabled, <code>false</code> otherwise
691 public boolean isSortingEnabled() {
692 return fIsSortingEnabled;
696 * Returns the working set comparator.
698 * @return the working set comparator
701 private WorkingSetComparator getComparator() {
702 if (fComparator == null) {
703 fComparator= new WorkingSetComparator(true);
709 * Returns all the working sets.
711 * @return all the working sets
714 public IWorkingSet[] getAllWorkingSets() {
715 return fAllWorkingSets.toArray(new IWorkingSet[fAllWorkingSets.size()]);