| 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2005, 2007 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 |
| 7 | * |
| 8 | * Contributors: |
| 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.ui.internal.dialogs; |
| 14 | |
| 15 | import java.util.ArrayList; |
| 16 | import java.util.HashMap; |
| 17 | import java.util.HashSet; |
| 18 | import java.util.Iterator; |
| 19 | import java.util.List; |
| 20 | import java.util.Map; |
| 21 | import java.util.Set; |
| 22 | |
| 23 | import org.eclipse.jface.dialogs.IDialogConstants; |
| 24 | import org.eclipse.jface.window.Window; |
| 25 | import org.eclipse.jface.wizard.WizardDialog; |
| 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.layout.GridData; |
| 30 | import org.eclipse.swt.layout.GridLayout; |
| 31 | import org.eclipse.swt.widgets.Button; |
| 32 | import org.eclipse.swt.widgets.Composite; |
| 33 | import org.eclipse.swt.widgets.Shell; |
| 34 | import org.eclipse.ui.IWorkingSet; |
| 35 | import org.eclipse.ui.IWorkingSetManager; |
| 36 | import org.eclipse.ui.PlatformUI; |
| 37 | import org.eclipse.ui.dialogs.IWorkingSetEditWizard; |
| 38 | import org.eclipse.ui.dialogs.IWorkingSetNewWizard; |
| 39 | import org.eclipse.ui.dialogs.IWorkingSetSelectionDialog; |
| 40 | import org.eclipse.ui.dialogs.SelectionDialog; |
| 41 | import org.eclipse.ui.internal.IWorkbenchHelpContextIds; |
| 42 | import org.eclipse.ui.internal.WorkbenchMessages; |
| 43 | import org.eclipse.ui.internal.WorkbenchPlugin; |
| 44 | import org.eclipse.ui.internal.WorkingSet; |
| 45 | import org.eclipse.ui.internal.registry.WorkingSetRegistry; |
| 46 | |
| 47 | /** |
| 48 | * Abstract baseclass for various working set dialogs. |
| 49 | * |
| 50 | * @since 3.2 |
| 51 | */ |
| 52 | public abstract class AbstractWorkingSetDialog extends SelectionDialog |
| 53 | implements IWorkingSetSelectionDialog { |
| 54 | |
| 55 | private static final int ID_NEW = IDialogConstants.CLIENT_ID + 1; |
| 56 | private static final int ID_DETAILS = ID_NEW + 1; |
| 57 | private static final int ID_REMOVE = ID_DETAILS + 1; |
| 58 | private static final int ID_SELECTALL = ID_REMOVE + 1; |
| 59 | private static final int ID_DESELECTALL = ID_SELECTALL + 1; |
| 60 | |
| 61 | private Button newButton; |
| 62 | |
| 63 | private Button detailsButton; |
| 64 | |
| 65 | private Button removeButton; |
| 66 | |
| 67 | private Button selectAllButton; |
| 68 | |
| 69 | private Button deselectAllButton; |
| 70 | |
| 71 | private IWorkingSet[] result; |
| 72 | |
| 73 | private List addedWorkingSets; |
| 74 | |
| 75 | private List removedWorkingSets; |
| 76 | |
| 77 | private Map editedWorkingSets; |
| 78 | |
| 79 | private List removedMRUWorkingSets; |
| 80 | |
| 81 | private Set workingSetIds; |
| 82 | |
| 83 | private boolean canEdit; |
| 84 | |
| 85 | protected AbstractWorkingSetDialog(Shell parentShell, String[] workingSetIds, boolean canEdit) { |
| 86 | super(parentShell); |
| 87 | if (workingSetIds != null) { |
| 88 | this.workingSetIds = new HashSet(); |
| 89 | for (int i = 0; i < workingSetIds.length; i++) { |
| 90 | this.workingSetIds.add(workingSetIds[i]); |
| 91 | } |
| 92 | } |
| 93 | this.canEdit = canEdit; |
| 94 | } |
| 95 | |
| 96 | /** |
| 97 | * Return the set of supported working set types. |
| 98 | * |
| 99 | * @return the supported working set types |
| 100 | */ |
| 101 | protected Set getSupportedWorkingSetIds() { |
| 102 | return workingSetIds; |
| 103 | } |
| 104 | |
| 105 | /** |
| 106 | * Adds the modify buttons to the dialog. |
| 107 | * |
| 108 | * @param composite |
| 109 | * Composite to add the buttons to |
| 110 | */ |
| 111 | protected void addModifyButtons(Composite composite) { |
| 112 | Composite buttonComposite = new Composite(composite, SWT.RIGHT); |
| 113 | GridLayout layout = new GridLayout(); |
| 114 | layout.marginHeight = layout.marginWidth = 0; |
| 115 | layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); |
| 116 | buttonComposite.setLayout(layout); |
| 117 | GridData data = new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.GRAB_VERTICAL); |
| 118 | buttonComposite.setLayoutData(data); |
| 119 | |
| 120 | newButton = createButton(buttonComposite, ID_NEW, |
| 121 | WorkbenchMessages.WorkingSetSelectionDialog_newButton_label, |
| 122 | false); |
| 123 | newButton.addSelectionListener(new SelectionAdapter() { |
| 124 | public void widgetSelected(SelectionEvent e) { |
| 125 | createWorkingSet(); |
| 126 | } |
| 127 | }); |
| 128 | |
| 129 | if (canEdit) { |
| 130 | detailsButton = createButton( |
| 131 | buttonComposite, |
| 132 | ID_DETAILS, |
| 133 | WorkbenchMessages.WorkingSetSelectionDialog_detailsButton_label, |
| 134 | false); |
| 135 | detailsButton.setEnabled(false); |
| 136 | detailsButton.addSelectionListener(new SelectionAdapter() { |
| 137 | public void widgetSelected(SelectionEvent e) { |
| 138 | editSelectedWorkingSet(); |
| 139 | } |
| 140 | }); |
| 141 | |
| 142 | removeButton = createButton( |
| 143 | buttonComposite, |
| 144 | ID_REMOVE, |
| 145 | WorkbenchMessages.WorkingSetSelectionDialog_removeButton_label, |
| 146 | false); |
| 147 | removeButton.setEnabled(false); |
| 148 | removeButton.addSelectionListener(new SelectionAdapter() { |
| 149 | public void widgetSelected(SelectionEvent e) { |
| 150 | removeSelectedWorkingSets(); |
| 151 | } |
| 152 | }); |
| 153 | } |
| 154 | |
| 155 | layout.numColumns = 1; // must manually reset the number of columns because createButton increments it - we want these buttons to be laid out vertically. |
| 156 | } |
| 157 | |
| 158 | /** |
| 159 | * Add the select/deselect buttons. |
| 160 | * |
| 161 | * @param composite Composite to add the buttons to |
| 162 | */ |
| 163 | protected void addSelectionButtons(Composite composite) { |
| 164 | Composite buttonComposite = new Composite(composite, SWT.NONE); |
| 165 | GridLayout layout = new GridLayout(2, false); |
| 166 | layout.marginHeight = layout.marginWidth = 0; |
| 167 | layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); |
| 168 | buttonComposite.setLayout(layout); |
| 169 | GridData data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); |
| 170 | buttonComposite.setLayoutData(data); |
| 171 | |
| 172 | selectAllButton = createButton( |
| 173 | buttonComposite, |
| 174 | ID_SELECTALL, |
| 175 | WorkbenchMessages.SelectionDialog_selectLabel, |
| 176 | false); |
| 177 | selectAllButton.addSelectionListener(new SelectionAdapter() { |
| 178 | public void widgetSelected(SelectionEvent e) { |
| 179 | selectAllSets(); |
| 180 | } |
| 181 | }); |
| 182 | |
| 183 | deselectAllButton = createButton( |
| 184 | buttonComposite, |
| 185 | ID_DESELECTALL, |
| 186 | WorkbenchMessages.SelectionDialog_deselectLabel, |
| 187 | false); |
| 188 | deselectAllButton.addSelectionListener(new SelectionAdapter() { |
| 189 | public void widgetSelected(SelectionEvent e) { |
| 190 | deselectAllSets(); |
| 191 | } |
| 192 | }); |
| 193 | } |
| 194 | |
| 195 | /** |
| 196 | * Select all working sets. |
| 197 | */ |
| 198 | protected abstract void selectAllSets(); |
| 199 | |
| 200 | /** |
| 201 | * Deselect all working sets. |
| 202 | */ |
| 203 | protected abstract void deselectAllSets(); |
| 204 | |
| 205 | /** |
| 206 | * Opens a working set wizard for editing the currently selected working |
| 207 | * set. |
| 208 | * |
| 209 | * @see org.eclipse.ui.dialogs.IWorkingSetPage |
| 210 | */ |
| 211 | void editSelectedWorkingSet() { |
| 212 | IWorkingSetManager manager = WorkbenchPlugin.getDefault() |
| 213 | .getWorkingSetManager(); |
| 214 | IWorkingSet editWorkingSet = (IWorkingSet) getSelectedWorkingSets() |
| 215 | .get(0); |
| 216 | IWorkingSetEditWizard wizard = manager |
| 217 | .createWorkingSetEditWizard(editWorkingSet); |
| 218 | WizardDialog dialog = new WizardDialog(getShell(), wizard); |
| 219 | IWorkingSet originalWorkingSet = (IWorkingSet) editedWorkingSets |
| 220 | .get(editWorkingSet); |
| 221 | boolean firstEdit = originalWorkingSet == null; |
| 222 | |
| 223 | // save the original working set values for restoration when selection |
| 224 | // dialog is cancelled. |
| 225 | if (firstEdit) { |
| 226 | originalWorkingSet = new WorkingSet(editWorkingSet.getName(), |
| 227 | editWorkingSet.getLabel(), editWorkingSet.getElements()); |
| 228 | } else { |
| 229 | editedWorkingSets.remove(editWorkingSet); |
| 230 | } |
| 231 | dialog.create(); |
| 232 | PlatformUI.getWorkbench().getHelpSystem().setHelp(dialog.getShell(), |
| 233 | IWorkbenchHelpContextIds.WORKING_SET_EDIT_WIZARD); |
| 234 | if (dialog.open() == Window.OK) { |
| 235 | editWorkingSet = wizard.getSelection(); |
| 236 | availableWorkingSetsChanged(); |
| 237 | // make sure ok button is enabled when the selected working set |
| 238 | // is edited. Fixes bug 33386. |
| 239 | updateButtonAvailability(); |
| 240 | } |
| 241 | editedWorkingSets.put(editWorkingSet, originalWorkingSet); |
| 242 | } |
| 243 | |
| 244 | /** |
| 245 | * Opens a working set wizard for creating a new working set. |
| 246 | */ |
| 247 | void createWorkingSet() { |
| 248 | IWorkingSetManager manager = WorkbenchPlugin.getDefault() |
| 249 | .getWorkingSetManager(); |
| 250 | String ids[] = null; |
| 251 | if (workingSetIds != null) { |
| 252 | ids = (String[]) workingSetIds.toArray(new String[workingSetIds |
| 253 | .size()]); |
| 254 | } |
| 255 | IWorkingSetNewWizard wizard = manager.createWorkingSetNewWizard(ids); |
| 256 | // the wizard can never be null since we have at least a resource |
| 257 | // working set |
| 258 | // creation page |
| 259 | WizardDialog dialog = new WizardDialog(getShell(), wizard); |
| 260 | |
| 261 | dialog.create(); |
| 262 | PlatformUI.getWorkbench().getHelpSystem().setHelp(dialog.getShell(), |
| 263 | IWorkbenchHelpContextIds.WORKING_SET_NEW_WIZARD); |
| 264 | if (dialog.open() == Window.OK) { |
| 265 | IWorkingSet workingSet = wizard.getSelection(); |
| 266 | manager.addWorkingSet(workingSet); |
| 267 | addedWorkingSets.add(workingSet); |
| 268 | availableWorkingSetsChanged(); |
| 269 | } |
| 270 | } |
| 271 | |
| 272 | protected abstract List getSelectedWorkingSets(); |
| 273 | |
| 274 | /** |
| 275 | * Notifies the dialog that there has been a change to the sets available |
| 276 | * for use. In other words, the user has either added, deleted or renamed a |
| 277 | * set. |
| 278 | * <p> |
| 279 | * Subclasses should override, but should call <code>super.availableWorkingSetsChanged</code> |
| 280 | * to update the selection button enablements. |
| 281 | * </p> |
| 282 | */ |
| 283 | protected void availableWorkingSetsChanged() { |
| 284 | boolean enable = PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSets().length > 0; |
| 285 | if (!(selectAllButton == null || selectAllButton.isDisposed())){ |
| 286 | selectAllButton.setEnabled(enable); |
| 287 | } |
| 288 | if (!(deselectAllButton == null || deselectAllButton.isDisposed())){ |
| 289 | deselectAllButton.setEnabled(enable); |
| 290 | } |
| 291 | } |
| 292 | |
| 293 | /* (non-Javadoc) |
| 294 | * @see org.eclipse.ui.dialogs.IWorkingSetSelectionDialog#getSelection() |
| 295 | */ |
| 296 | public IWorkingSet[] getSelection() { |
| 297 | return result; |
| 298 | } |
| 299 | |
| 300 | /* (non-Javadoc) |
| 301 | * @see org.eclipse.ui.dialogs.IWorkingSetSelectionDialog#setSelection(org.eclipse.ui.IWorkingSet[]) |
| 302 | */ |
| 303 | public void setSelection(IWorkingSet[] selection) { |
| 304 | result = selection; |
| 305 | } |
| 306 | |
| 307 | /** |
| 308 | * Overrides method in Dialog |
| 309 | * |
| 310 | * @see org.eclipse.jface.dialogs.Dialog#open() |
| 311 | */ |
| 312 | public int open() { |
| 313 | addedWorkingSets = new ArrayList(); |
| 314 | removedWorkingSets = new ArrayList(); |
| 315 | editedWorkingSets = new HashMap(); |
| 316 | removedMRUWorkingSets = new ArrayList(); |
| 317 | return super.open(); |
| 318 | } |
| 319 | |
| 320 | /** |
| 321 | * Return the list of working sets that were added during the life of this |
| 322 | * dialog. |
| 323 | * |
| 324 | * @return the working sets |
| 325 | */ |
| 326 | protected final List getAddedWorkingSets() { |
| 327 | return addedWorkingSets; |
| 328 | } |
| 329 | |
| 330 | /** |
| 331 | * Return the map of working sets that were edited during the life of this |
| 332 | * dialog. |
| 333 | * |
| 334 | * @return the working sets |
| 335 | */ |
| 336 | protected final Map getEditedWorkingSets() { |
| 337 | return editedWorkingSets; |
| 338 | } |
| 339 | |
| 340 | /** |
| 341 | * Return the list of working sets that were removed from the MRU list |
| 342 | * during the life of this dialog. |
| 343 | * |
| 344 | * @return the working sets |
| 345 | */ |
| 346 | protected final List getRemovedMRUWorkingSets() { |
| 347 | return removedMRUWorkingSets; |
| 348 | } |
| 349 | |
| 350 | /** |
| 351 | * Return the list of working sets that were removed during the life of this |
| 352 | * dialog. |
| 353 | * |
| 354 | * @return the working sets |
| 355 | */ |
| 356 | protected final List getRemovedWorkingSets() { |
| 357 | return removedWorkingSets; |
| 358 | } |
| 359 | |
| 360 | /** |
| 361 | * Updates the modify buttons' enabled state based on the current seleciton. |
| 362 | */ |
| 363 | protected void updateButtonAvailability() { |
| 364 | List selection = getSelectedWorkingSets(); |
| 365 | boolean hasSelection = selection != null && !selection.isEmpty(); |
| 366 | boolean hasSingleSelection = hasSelection; |
| 367 | WorkingSetRegistry registry = WorkbenchPlugin.getDefault() |
| 368 | .getWorkingSetRegistry(); |
| 369 | |
| 370 | newButton.setEnabled(registry.hasNewPageWorkingSetDescriptor()); |
| 371 | |
| 372 | if (canEdit) |
| 373 | removeButton.setEnabled(hasSelection); |
| 374 | |
| 375 | IWorkingSet selectedWorkingSet = null; |
| 376 | if (hasSelection) { |
| 377 | hasSingleSelection = selection.size() == 1; |
| 378 | if (hasSingleSelection) { |
| 379 | selectedWorkingSet = (IWorkingSet) selection |
| 380 | .get(0); |
| 381 | } |
| 382 | } |
| 383 | if (canEdit) |
| 384 | detailsButton.setEnabled(hasSingleSelection |
| 385 | && selectedWorkingSet.isEditable()); |
| 386 | |
| 387 | getOkButton().setEnabled(true); |
| 388 | } |
| 389 | |
| 390 | /** |
| 391 | * Removes the selected working sets from the workbench. |
| 392 | */ |
| 393 | protected void removeSelectedWorkingSets() { |
| 394 | List selection = getSelectedWorkingSets(); |
| 395 | removeSelectedWorkingSets(selection); |
| 396 | } |
| 397 | |
| 398 | /** |
| 399 | * Remove the working sets contained in the provided selection from the |
| 400 | * working set manager. |
| 401 | * |
| 402 | * @param selection |
| 403 | * the sets |
| 404 | */ |
| 405 | protected void removeSelectedWorkingSets(List selection) { |
| 406 | IWorkingSetManager manager = WorkbenchPlugin.getDefault() |
| 407 | .getWorkingSetManager(); |
| 408 | Iterator iter = selection.iterator(); |
| 409 | while (iter.hasNext()) { |
| 410 | IWorkingSet workingSet = (IWorkingSet) iter.next(); |
| 411 | if (getAddedWorkingSets().contains(workingSet)) { |
| 412 | getAddedWorkingSets().remove(workingSet); |
| 413 | } else { |
| 414 | IWorkingSet[] recentWorkingSets = manager |
| 415 | .getRecentWorkingSets(); |
| 416 | for (int i = 0; i < recentWorkingSets.length; i++) { |
| 417 | if (workingSet.equals(recentWorkingSets[i])) { |
| 418 | getRemovedMRUWorkingSets().add(workingSet); |
| 419 | break; |
| 420 | } |
| 421 | } |
| 422 | getRemovedWorkingSets().add(workingSet); |
| 423 | } |
| 424 | manager.removeWorkingSet(workingSet); |
| 425 | } |
| 426 | availableWorkingSetsChanged(); |
| 427 | } |
| 428 | } |