| 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2005, 2008 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 | *******************************************************************************/ |
| 11 | package org.eclipse.ui.activities; |
| 12 | |
| 13 | import java.util.Collections; |
| 14 | import java.util.HashSet; |
| 15 | import java.util.Hashtable; |
| 16 | import java.util.Iterator; |
| 17 | import java.util.Properties; |
| 18 | import java.util.Set; |
| 19 | |
| 20 | import org.eclipse.core.runtime.IConfigurationElement; |
| 21 | import org.eclipse.core.runtime.IExecutableExtension; |
| 22 | import org.eclipse.jface.dialogs.Dialog; |
| 23 | import org.eclipse.jface.dialogs.IDialogConstants; |
| 24 | import org.eclipse.jface.dialogs.IDialogSettings; |
| 25 | import org.eclipse.jface.dialogs.TrayDialog; |
| 26 | import org.eclipse.jface.preference.PreferencePage; |
| 27 | import org.eclipse.jface.resource.DeviceResourceException; |
| 28 | import org.eclipse.jface.resource.ImageDescriptor; |
| 29 | import org.eclipse.jface.resource.JFaceResources; |
| 30 | import org.eclipse.jface.resource.LocalResourceManager; |
| 31 | import org.eclipse.jface.viewers.CheckboxTableViewer; |
| 32 | import org.eclipse.jface.viewers.ISelectionChangedListener; |
| 33 | import org.eclipse.jface.viewers.IStructuredContentProvider; |
| 34 | import org.eclipse.jface.viewers.IStructuredSelection; |
| 35 | import org.eclipse.jface.viewers.ITableLabelProvider; |
| 36 | import org.eclipse.jface.viewers.LabelProvider; |
| 37 | import org.eclipse.jface.viewers.LabelProviderChangedEvent; |
| 38 | import org.eclipse.jface.viewers.SelectionChangedEvent; |
| 39 | import org.eclipse.jface.viewers.TableViewer; |
| 40 | import org.eclipse.jface.viewers.Viewer; |
| 41 | import org.eclipse.jface.viewers.ViewerComparator; |
| 42 | import org.eclipse.jface.viewers.ViewerFilter; |
| 43 | import org.eclipse.osgi.util.NLS; |
| 44 | import org.eclipse.swt.SWT; |
| 45 | import org.eclipse.swt.events.SelectionAdapter; |
| 46 | import org.eclipse.swt.events.SelectionEvent; |
| 47 | import org.eclipse.swt.graphics.Image; |
| 48 | import org.eclipse.swt.graphics.ImageData; |
| 49 | import org.eclipse.swt.graphics.Point; |
| 50 | import org.eclipse.swt.layout.GridData; |
| 51 | import org.eclipse.swt.layout.GridLayout; |
| 52 | import org.eclipse.swt.widgets.Button; |
| 53 | import org.eclipse.swt.widgets.Composite; |
| 54 | import org.eclipse.swt.widgets.Control; |
| 55 | import org.eclipse.swt.widgets.Label; |
| 56 | import org.eclipse.swt.widgets.Shell; |
| 57 | import org.eclipse.swt.widgets.Table; |
| 58 | import org.eclipse.swt.widgets.TableItem; |
| 59 | import org.eclipse.swt.widgets.Text; |
| 60 | import org.eclipse.ui.IWorkbench; |
| 61 | import org.eclipse.ui.IWorkbenchPreferencePage; |
| 62 | import org.eclipse.ui.PlatformUI; |
| 63 | import org.eclipse.ui.internal.IPreferenceConstants; |
| 64 | import org.eclipse.ui.internal.IWorkbenchHelpContextIds; |
| 65 | import org.eclipse.ui.internal.OverlayIcon; |
| 66 | import org.eclipse.ui.internal.WorkbenchPlugin; |
| 67 | import org.eclipse.ui.internal.activities.InternalActivityHelper; |
| 68 | import org.eclipse.ui.internal.activities.ws.ActivityEnabler; |
| 69 | import org.eclipse.ui.internal.activities.ws.ActivityMessages; |
| 70 | import org.eclipse.ui.plugin.AbstractUIPlugin; |
| 71 | |
| 72 | /** |
| 73 | * Activities preference page that primarily shows categories and can optionally |
| 74 | * show an advanced dialog that allows fine-tune adjustmenet of activities. This |
| 75 | * page may be used by product developers to provide basic ability to tweak the |
| 76 | * enabled activity set. You may provide certain strings to this class via |
| 77 | * method #2 of {@link org.eclipse.core.runtime.IExecutableExtension}. |
| 78 | * |
| 79 | * @see #ACTIVITY_NAME |
| 80 | * @see #ALLOW_ADVANCED |
| 81 | * @see #CAPTION_MESSAGE |
| 82 | * @see #CATEGORY_NAME |
| 83 | * @see #ACTIVITY_PROMPT_BUTTON |
| 84 | * @see #ACTIVITY_PROMPT_BUTTON_TOOLTIP |
| 85 | * |
| 86 | * @since 3.1 |
| 87 | */ |
| 88 | public final class ActivityCategoryPreferencePage extends PreferencePage implements |
| 89 | IWorkbenchPreferencePage, IExecutableExtension { |
| 90 | |
| 91 | /** |
| 92 | * The name to use for the activities. Ie: "Capabilities". |
| 93 | */ |
| 94 | public static final String ACTIVITY_NAME = "activityName"; //$NON-NLS-1$ |
| 95 | |
| 96 | /** |
| 97 | * The parameter to use if you want the page to show the allow button. Must |
| 98 | * be true or false. |
| 99 | */ |
| 100 | public static final String ALLOW_ADVANCED = "allowAdvanced"; //$NON-NLS-1$ |
| 101 | |
| 102 | /** |
| 103 | * The string to use for the message at the top of the preference page. |
| 104 | */ |
| 105 | public static final String CAPTION_MESSAGE = "captionMessage"; //$NON-NLS-1$ |
| 106 | |
| 107 | /** |
| 108 | * The name to use for the activity categories. Ie: "Roles". |
| 109 | */ |
| 110 | public static final String CATEGORY_NAME = "categoryName"; //$NON-NLS-1$ |
| 111 | |
| 112 | /** |
| 113 | * The label to be used for the prompt button. Ie: "&Prompt when enabling capabilities". |
| 114 | */ |
| 115 | public static final String ACTIVITY_PROMPT_BUTTON = "activityPromptButton"; //$NON-NLS-1$ |
| 116 | |
| 117 | /** |
| 118 | * The tooltip to be used for the prompt button. Ie: "Prompt when a feature is first used that requires enablement of capabilities". |
| 119 | */ |
| 120 | public static final String ACTIVITY_PROMPT_BUTTON_TOOLTIP = "activityPromptButtonTooltip"; //$NON-NLS-1$ |
| 121 | |
| 122 | private class AdvancedDialog extends TrayDialog { |
| 123 | |
| 124 | private static final String DIALOG_SETTINGS_SECTION = "ActivityCategoryPreferencePageAdvancedDialogSettings"; //$NON-NLS-1$ |
| 125 | |
| 126 | |
| 127 | ActivityEnabler enabler; |
| 128 | /** |
| 129 | * @param parentShell |
| 130 | */ |
| 131 | protected AdvancedDialog(Shell parentShell) { |
| 132 | super(parentShell); |
| 133 | } |
| 134 | |
| 135 | /* (non-Javadoc) |
| 136 | * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) |
| 137 | */ |
| 138 | protected void configureShell(Shell newShell) { |
| 139 | super.configureShell(newShell); |
| 140 | String activityName = strings.getProperty(ACTIVITY_NAME, ActivityMessages.ActivityEnabler_activities); |
| 141 | activityName = activityName.replaceAll("&", ""); //strips possible mnemonic //$NON-NLS-1$ //$NON-NLS-2$ |
| 142 | newShell.setText(NLS.bind( |
| 143 | ActivityMessages.ActivitiesPreferencePage_advancedDialogTitle, |
| 144 | activityName |
| 145 | )); |
| 146 | } |
| 147 | |
| 148 | /* (non-Javadoc) |
| 149 | * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) |
| 150 | */ |
| 151 | protected Control createDialogArea(Composite parent) { |
| 152 | Composite composite = (Composite) super.createDialogArea(parent); |
| 153 | enabler = new ActivityEnabler(workingCopy, strings); |
| 154 | Control enablerControl = enabler.createControl(composite); |
| 155 | enablerControl.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| 156 | return composite; |
| 157 | } |
| 158 | |
| 159 | /* (non-Javadoc) |
| 160 | * @see org.eclipse.jface.dialogs.Dialog#okPressed() |
| 161 | */ |
| 162 | protected void okPressed() { |
| 163 | enabler.updateActivityStates(); |
| 164 | super.okPressed(); |
| 165 | } |
| 166 | |
| 167 | /* (non-Javadoc) |
| 168 | * @see org.eclipse.jface.window.Dialog#getDialogBoundsSettings() |
| 169 | * |
| 170 | * @since 3.2 |
| 171 | */ |
| 172 | protected IDialogSettings getDialogBoundsSettings() { |
| 173 | IDialogSettings settings = WorkbenchPlugin.getDefault().getDialogSettings(); |
| 174 | IDialogSettings section = settings.getSection(DIALOG_SETTINGS_SECTION); |
| 175 | if (section == null) { |
| 176 | section = settings.addNewSection(DIALOG_SETTINGS_SECTION); |
| 177 | } |
| 178 | return section; |
| 179 | } |
| 180 | |
| 181 | /* |
| 182 | * (non-Javadoc) |
| 183 | * @see org.eclipse.jface.dialogs.Dialog#isResizable() |
| 184 | */ |
| 185 | protected boolean isResizable() { |
| 186 | return true; |
| 187 | } |
| 188 | } |
| 189 | private class CategoryLabelProvider extends LabelProvider implements |
| 190 | ITableLabelProvider, IActivityManagerListener { |
| 191 | |
| 192 | private LocalResourceManager manager = new LocalResourceManager( |
| 193 | JFaceResources.getResources()); |
| 194 | |
| 195 | private ImageDescriptor lockDescriptor; |
| 196 | |
| 197 | private boolean decorate; |
| 198 | |
| 199 | /** |
| 200 | * @param decorate |
| 201 | */ |
| 202 | public CategoryLabelProvider(boolean decorate) { |
| 203 | this.decorate = decorate; |
| 204 | lockDescriptor = AbstractUIPlugin.imageDescriptorFromPlugin( |
| 205 | PlatformUI.PLUGIN_ID, "icons/full/ovr16/lock_ovr.gif"); //$NON-NLS-1$ |
| 206 | } |
| 207 | |
| 208 | /* |
| 209 | * (non-Javadoc) |
| 210 | * |
| 211 | * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, |
| 212 | * int) |
| 213 | */ |
| 214 | public Image getColumnImage(Object element, int columnIndex) { |
| 215 | ICategory category = (ICategory) element; |
| 216 | ImageDescriptor descriptor = PlatformUI.getWorkbench() |
| 217 | .getActivitySupport().getImageDescriptor(category); |
| 218 | if (descriptor != null) { |
| 219 | try { |
| 220 | if (decorate) { |
| 221 | if (isLocked(category)) { |
| 222 | ImageData originalImageData = descriptor |
| 223 | .getImageData(); |
| 224 | OverlayIcon overlay = new OverlayIcon( |
| 225 | descriptor, lockDescriptor, new Point( |
| 226 | originalImageData.width, |
| 227 | originalImageData.height)); |
| 228 | return manager.createImage(overlay); |
| 229 | } |
| 230 | } |
| 231 | |
| 232 | return manager.createImage(descriptor); |
| 233 | } catch (DeviceResourceException e) { |
| 234 | WorkbenchPlugin.log(e); |
| 235 | } |
| 236 | } |
| 237 | return null; |
| 238 | } |
| 239 | |
| 240 | /* (non-Javadoc) |
| 241 | * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) |
| 242 | */ |
| 243 | public String getText(Object element) { |
| 244 | String name = null; |
| 245 | ICategory category = (ICategory) element; |
| 246 | try { |
| 247 | name = category.getName(); |
| 248 | } catch (NotDefinedException e) { |
| 249 | name = category.getId(); |
| 250 | } |
| 251 | if (decorate && isLocked(category)) { |
| 252 | name = NLS.bind(ActivityMessages.ActivitiesPreferencePage_lockedMessage, name); |
| 253 | } |
| 254 | return name; |
| 255 | } |
| 256 | |
| 257 | /* (non-Javadoc) |
| 258 | * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int) |
| 259 | */ |
| 260 | public String getColumnText(Object element, int columnIndex) { |
| 261 | return getText(element); |
| 262 | } |
| 263 | |
| 264 | /* |
| 265 | * (non-Javadoc) |
| 266 | * |
| 267 | * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose() |
| 268 | */ |
| 269 | public void dispose() { |
| 270 | super.dispose(); |
| 271 | manager.dispose(); |
| 272 | } |
| 273 | |
| 274 | /* |
| 275 | * (non-Javadoc) |
| 276 | * |
| 277 | * @see org.eclipse.ui.activities.IActivityManagerListener#activityManagerChanged(org.eclipse.ui.activities.ActivityManagerEvent) |
| 278 | */ |
| 279 | public void activityManagerChanged( |
| 280 | ActivityManagerEvent activityManagerEvent) { |
| 281 | if (activityManagerEvent.haveEnabledActivityIdsChanged()) { |
| 282 | updateCategoryCheckState(); |
| 283 | fireLabelProviderChanged(new LabelProviderChangedEvent(this)); |
| 284 | } |
| 285 | } |
| 286 | } |
| 287 | |
| 288 | private class CategoryContentProvider implements IStructuredContentProvider { |
| 289 | |
| 290 | /* |
| 291 | * (non-Javadoc) |
| 292 | * |
| 293 | * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) |
| 294 | */ |
| 295 | public Object[] getElements(Object inputElement) { |
| 296 | // convert to category objects |
| 297 | return WorkbenchActivityHelper.resolveCategories(workingCopy, |
| 298 | (Set) inputElement); |
| 299 | } |
| 300 | |
| 301 | /* |
| 302 | * (non-Javadoc) |
| 303 | * |
| 304 | * @see org.eclipse.jface.viewers.IContentProvider#dispose() |
| 305 | */ |
| 306 | public void dispose() { |
| 307 | |
| 308 | } |
| 309 | |
| 310 | /* |
| 311 | * (non-Javadoc) |
| 312 | * |
| 313 | * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, |
| 314 | * java.lang.Object, java.lang.Object) |
| 315 | */ |
| 316 | public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { |
| 317 | |
| 318 | } |
| 319 | } |
| 320 | |
| 321 | private class EmptyCategoryFilter extends ViewerFilter { |
| 322 | |
| 323 | /* |
| 324 | * (non-Javadoc) |
| 325 | * |
| 326 | * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, |
| 327 | * java.lang.Object, java.lang.Object) |
| 328 | */ |
| 329 | public boolean select(Viewer viewer, Object parentElement, |
| 330 | Object element) { |
| 331 | ICategory category = (ICategory) element; |
| 332 | if (InternalActivityHelper.getActivityIdsForCategory(workingCopy, |
| 333 | category).isEmpty()) { |
| 334 | return false; |
| 335 | } |
| 336 | return true; |
| 337 | } |
| 338 | } |
| 339 | |
| 340 | protected IWorkbench workbench; |
| 341 | |
| 342 | private CheckboxTableViewer categoryViewer; |
| 343 | |
| 344 | private TableViewer dependantViewer; |
| 345 | |
| 346 | private Text descriptionText; |
| 347 | |
| 348 | private IMutableActivityManager workingCopy; |
| 349 | |
| 350 | private Button activityPromptButton; |
| 351 | |
| 352 | private boolean allowAdvanced = false; |
| 353 | |
| 354 | private Button advancedButton; |
| 355 | |
| 356 | private Properties strings = new Properties(); |
| 357 | |
| 358 | /* |
| 359 | * (non-Javadoc) |
| 360 | * |
| 361 | * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite) |
| 362 | */ |
| 363 | protected Control createContents(Composite parent) { |
| 364 | initializeDialogUnits(parent); |
| 365 | |
| 366 | Composite composite = new Composite(parent, SWT.NONE); |
| 367 | GridLayout layout = new GridLayout(2, false); |
| 368 | layout.marginHeight = layout.marginWidth = 0; |
| 369 | layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); |
| 370 | layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); |
| 371 | composite.setLayout(layout); |
| 372 | Label label = new Label(composite, SWT.WRAP); |
| 373 | label |
| 374 | .setText(strings.getProperty(CAPTION_MESSAGE, ActivityMessages.ActivitiesPreferencePage_captionMessage)); |
| 375 | GridData data = new GridData(GridData.FILL_HORIZONTAL); |
| 376 | data.widthHint = 400; |
| 377 | data.horizontalSpan = 2; |
| 378 | label.setLayoutData(data); |
| 379 | label = new Label(composite, SWT.NONE); //spacer |
| 380 | data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); |
| 381 | data.horizontalSpan = 2; |
| 382 | label.setLayoutData(data); |
| 383 | createPromptButton(composite); |
| 384 | createCategoryArea(composite); |
| 385 | createDetailsArea(composite); |
| 386 | createButtons(composite); |
| 387 | |
| 388 | workbench.getHelpSystem().setHelp(parent, |
| 389 | IWorkbenchHelpContextIds.CAPABILITY_PREFERENCE_PAGE); |
| 390 | |
| 391 | Dialog.applyDialogFont(composite); |
| 392 | |
| 393 | return composite; |
| 394 | } |
| 395 | |
| 396 | /** |
| 397 | * @param composite |
| 398 | */ |
| 399 | private void createPromptButton(Composite composite) { |
| 400 | activityPromptButton = new Button(composite, SWT.CHECK); |
| 401 | activityPromptButton.setText(strings.getProperty(ACTIVITY_PROMPT_BUTTON, ActivityMessages.activityPromptButton)); |
| 402 | activityPromptButton.setToolTipText(strings.getProperty(ACTIVITY_PROMPT_BUTTON_TOOLTIP, ActivityMessages.activityPromptToolTip)); |
| 403 | GridData data = new GridData(); |
| 404 | data.horizontalSpan = 2; |
| 405 | activityPromptButton.setLayoutData(data); |
| 406 | activityPromptButton.setSelection(getPreferenceStore() |
| 407 | .getBoolean( |
| 408 | IPreferenceConstants.SHOULD_PROMPT_FOR_ENABLEMENT)); |
| 409 | } |
| 410 | |
| 411 | private void createButtons(final Composite parent) { |
| 412 | Composite composite = new Composite(parent, SWT.NONE); |
| 413 | GridLayout layout = new GridLayout(4, false); |
| 414 | layout.marginHeight = layout.marginWidth = 0; |
| 415 | layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); |
| 416 | layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); |
| 417 | composite.setLayout(layout); |
| 418 | GridData data = new GridData(GridData.FILL_HORIZONTAL); |
| 419 | data.horizontalSpan = 2; |
| 420 | composite.setLayoutData(data); |
| 421 | |
| 422 | Button enableAll = new Button(composite, SWT.PUSH); |
| 423 | enableAll.addSelectionListener(new SelectionAdapter() { |
| 424 | |
| 425 | /* |
| 426 | * (non-Javadoc) |
| 427 | * |
| 428 | * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) |
| 429 | */ |
| 430 | public void widgetSelected(SelectionEvent e) { |
| 431 | workingCopy.setEnabledActivityIds(workingCopy |
| 432 | .getDefinedActivityIds()); |
| 433 | } |
| 434 | }); |
| 435 | enableAll.setText(ActivityMessages.ActivityEnabler_selectAll); |
| 436 | setButtonLayoutData(enableAll); |
| 437 | |
| 438 | Button disableAll = new Button(composite, SWT.PUSH); |
| 439 | disableAll.addSelectionListener(new SelectionAdapter() { |
| 440 | /* |
| 441 | * (non-Javadoc) |
| 442 | * |
| 443 | * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) |
| 444 | */ |
| 445 | public void widgetSelected(SelectionEvent e) { |
| 446 | workingCopy.setEnabledActivityIds(Collections.EMPTY_SET); |
| 447 | } |
| 448 | }); |
| 449 | disableAll.setText(ActivityMessages.ActivityEnabler_deselectAll); |
| 450 | setButtonLayoutData(disableAll); |
| 451 | |
| 452 | if (allowAdvanced) { |
| 453 | Label spacer = new Label(composite, SWT.NONE); |
| 454 | data = new GridData(GridData.GRAB_HORIZONTAL); |
| 455 | spacer.setLayoutData(data); |
| 456 | advancedButton = new Button(composite, SWT.PUSH); |
| 457 | advancedButton.addSelectionListener(new SelectionAdapter() { |
| 458 | |
| 459 | /* |
| 460 | * (non-Javadoc) |
| 461 | * |
| 462 | * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) |
| 463 | */ |
| 464 | public void widgetSelected(SelectionEvent e) { |
| 465 | AdvancedDialog dialog = new AdvancedDialog(parent.getShell()); |
| 466 | dialog.open(); // logic for updating the working copy is in the dialog class. |
| 467 | } |
| 468 | }); |
| 469 | advancedButton.setText(ActivityMessages.ActivitiesPreferencePage_advancedButton); |
| 470 | setButtonLayoutData(advancedButton); |
| 471 | } |
| 472 | } |
| 473 | |
| 474 | /** |
| 475 | * @param parent |
| 476 | */ |
| 477 | private void createDetailsArea(Composite parent) { |
| 478 | Composite composite = new Composite(parent, SWT.NONE); |
| 479 | GridLayout layout = new GridLayout(); |
| 480 | layout.marginHeight = layout.marginWidth = 0; |
| 481 | layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); |
| 482 | layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); |
| 483 | composite.setLayout(layout); |
| 484 | composite.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| 485 | |
| 486 | new Label(composite, SWT.NONE).setText(ActivityMessages.ActivityEnabler_description); |
| 487 | descriptionText = new Text(composite, SWT.WRAP | SWT.READ_ONLY | SWT.BORDER); |
| 488 | GridData data = new GridData(GridData.FILL_BOTH); |
| 489 | data.heightHint = 100; |
| 490 | data.widthHint = 200; |
| 491 | descriptionText.setLayoutData(data); |
| 492 | |
| 493 | new Label(composite, SWT.NONE).setText(ActivityMessages.ActivitiesPreferencePage_requirements); |
| 494 | dependantViewer = new TableViewer(composite, SWT.BORDER); |
| 495 | dependantViewer.getControl().setLayoutData( |
| 496 | new GridData(GridData.FILL_BOTH)); |
| 497 | dependantViewer.setContentProvider(new CategoryContentProvider()); |
| 498 | dependantViewer.addFilter(new EmptyCategoryFilter()); |
| 499 | dependantViewer.setLabelProvider(new CategoryLabelProvider(false)); |
| 500 | dependantViewer.setInput(Collections.EMPTY_SET); |
| 501 | } |
| 502 | |
| 503 | /** |
| 504 | * @param parent |
| 505 | */ |
| 506 | private void createCategoryArea(Composite parent) { |
| 507 | Composite composite = new Composite(parent, SWT.NONE); |
| 508 | GridLayout layout = new GridLayout(); |
| 509 | layout.marginHeight = layout.marginWidth = 0; |
| 510 | layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); |
| 511 | layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); |
| 512 | composite.setLayout(layout); |
| 513 | GridData data = new GridData(GridData.FILL_BOTH); |
| 514 | data.widthHint = 200; |
| 515 | composite.setLayoutData(data); |
| 516 | Label label = new Label(composite, SWT.NONE); |
| 517 | label.setText(strings.getProperty(CATEGORY_NAME, ActivityMessages.ActivityEnabler_categories) + ':'); |
| 518 | Table table = new Table(composite, SWT.CHECK | SWT.BORDER | SWT.SINGLE); |
| 519 | table.addSelectionListener(new SelectionAdapter() { |
| 520 | |
| 521 | /* |
| 522 | * (non-Javadoc) |
| 523 | * |
| 524 | * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) |
| 525 | */ |
| 526 | public void widgetSelected(SelectionEvent e) { |
| 527 | if (e.detail == SWT.CHECK) { |
| 528 | TableItem tableItem = (TableItem) e.item; |
| 529 | |
| 530 | ICategory category = (ICategory) tableItem.getData(); |
| 531 | if (isLocked(category)) { |
| 532 | tableItem.setChecked(true); |
| 533 | e.doit = false; // veto the check |
| 534 | return; |
| 535 | } |
| 536 | Set activitySet = WorkbenchActivityHelper |
| 537 | .getActivityIdsForCategory(category); |
| 538 | if (tableItem.getChecked()) { |
| 539 | activitySet.addAll(workingCopy.getEnabledActivityIds()); |
| 540 | } else { |
| 541 | HashSet newSet = new HashSet(workingCopy |
| 542 | .getEnabledActivityIds()); |
| 543 | newSet.removeAll(activitySet); |
| 544 | activitySet = newSet; |
| 545 | } |
| 546 | |
| 547 | workingCopy.setEnabledActivityIds(activitySet); |
| 548 | updateCategoryCheckState(); // even though we're reacting to |
| 549 | // a check change we may need to |
| 550 | // refresh a greying change. |
| 551 | // Just process the whole thing. |
| 552 | } |
| 553 | } |
| 554 | }); |
| 555 | categoryViewer = new CheckboxTableViewer(table); |
| 556 | categoryViewer.getControl().setLayoutData( |
| 557 | new GridData(GridData.FILL_BOTH)); |
| 558 | categoryViewer.setContentProvider(new CategoryContentProvider()); |
| 559 | CategoryLabelProvider categoryLabelProvider = new CategoryLabelProvider( |
| 560 | true); |
| 561 | workingCopy.addActivityManagerListener(categoryLabelProvider); |
| 562 | categoryViewer.setLabelProvider(categoryLabelProvider); |
| 563 | categoryViewer.setComparator(new ViewerComparator()); |
| 564 | categoryViewer.addFilter(new EmptyCategoryFilter()); |
| 565 | |
| 566 | categoryViewer |
| 567 | .addSelectionChangedListener(new ISelectionChangedListener() { |
| 568 | |
| 569 | /* |
| 570 | * (non-Javadoc) |
| 571 | * |
| 572 | * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent) |
| 573 | */ |
| 574 | public void selectionChanged(SelectionChangedEvent event) { |
| 575 | ICategory element = (ICategory) ((IStructuredSelection) event |
| 576 | .getSelection()).getFirstElement(); |
| 577 | setDetails(element); |
| 578 | } |
| 579 | }); |
| 580 | categoryViewer.setInput(workingCopy.getDefinedCategoryIds()); |
| 581 | |
| 582 | updateCategoryCheckState(); |
| 583 | } |
| 584 | |
| 585 | /** |
| 586 | * Updates the check and grey state of the categories in the category viewer. |
| 587 | * |
| 588 | * @since 3.2 |
| 589 | */ |
| 590 | private void updateCategoryCheckState() { |
| 591 | ICategory[] enabledCategories = getEnabledCategories(); |
| 592 | ICategory[] partiallyEnabledCategories = getPartialCategories(); |
| 593 | Object[] allChecked = new Object[enabledCategories.length |
| 594 | + partiallyEnabledCategories.length]; |
| 595 | System.arraycopy(enabledCategories, 0, allChecked, 0, enabledCategories.length); |
| 596 | System.arraycopy(partiallyEnabledCategories, 0, allChecked, enabledCategories.length, partiallyEnabledCategories.length); |
| 597 | categoryViewer.setCheckedElements(allChecked); |
| 598 | categoryViewer.setGrayedElements(partiallyEnabledCategories); |
| 599 | } |
| 600 | |
| 601 | private ICategory[] getPartialCategories() { |
| 602 | return WorkbenchActivityHelper.resolveCategories(workingCopy, |
| 603 | InternalActivityHelper |
| 604 | .getPartiallyEnabledCategories(workingCopy)); |
| 605 | } |
| 606 | |
| 607 | private ICategory[] getEnabledCategories() { |
| 608 | return WorkbenchActivityHelper.resolveCategories(workingCopy, |
| 609 | InternalActivityHelper.getEnabledCategories(workingCopy)); |
| 610 | } |
| 611 | |
| 612 | protected void setDetails(ICategory category) { |
| 613 | if (category == null) { |
| 614 | clearDetails(); |
| 615 | return; |
| 616 | } |
| 617 | Set categories = null; |
| 618 | if (WorkbenchActivityHelper.isEnabled(workingCopy, category.getId())) { |
| 619 | categories = WorkbenchActivityHelper.getDisabledCategories( |
| 620 | workingCopy, category.getId()); |
| 621 | |
| 622 | } else { |
| 623 | categories = WorkbenchActivityHelper.getEnabledCategories( |
| 624 | workingCopy, category.getId()); |
| 625 | } |
| 626 | |
| 627 | categories = WorkbenchActivityHelper.getContainedCategories( |
| 628 | workingCopy, category.getId()); |
| 629 | dependantViewer.setInput(categories); |
| 630 | try { |
| 631 | descriptionText.setText(category.getDescription()); |
| 632 | } catch (NotDefinedException e) { |
| 633 | descriptionText.setText(""); //$NON-NLS-1$ |
| 634 | } |
| 635 | } |
| 636 | |
| 637 | /** |
| 638 | * Clear the details area. |
| 639 | */ |
| 640 | protected void clearDetails() { |
| 641 | dependantViewer.setInput(Collections.EMPTY_SET); |
| 642 | descriptionText.setText(""); //$NON-NLS-1$ |
| 643 | } |
| 644 | |
| 645 | /* |
| 646 | * (non-Javadoc) |
| 647 | * |
| 648 | * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) |
| 649 | */ |
| 650 | public void init(IWorkbench workbench) { |
| 651 | this.workbench = workbench; |
| 652 | workingCopy = workbench.getActivitySupport().createWorkingCopy(); |
| 653 | setPreferenceStore(WorkbenchPlugin.getDefault().getPreferenceStore()); |
| 654 | } |
| 655 | |
| 656 | /** |
| 657 | * Return whether the category is locked. |
| 658 | * |
| 659 | * @param category |
| 660 | * the category to test |
| 661 | * @return whether the category is locked |
| 662 | */ |
| 663 | protected boolean isLocked(ICategory category) { |
| 664 | return !WorkbenchActivityHelper.getDisabledCategories(workingCopy, |
| 665 | category.getId()).isEmpty(); |
| 666 | } |
| 667 | |
| 668 | /* |
| 669 | * (non-Javadoc) |
| 670 | * |
| 671 | * @see org.eclipse.jface.preference.PreferencePage#performOk() |
| 672 | */ |
| 673 | public boolean performOk() { |
| 674 | workbench.getActivitySupport().setEnabledActivityIds( |
| 675 | workingCopy.getEnabledActivityIds()); |
| 676 | getPreferenceStore().setValue( |
| 677 | IPreferenceConstants.SHOULD_PROMPT_FOR_ENABLEMENT, |
| 678 | activityPromptButton.getSelection()); |
| 679 | return true; |
| 680 | } |
| 681 | |
| 682 | /* (non-Javadoc) |
| 683 | * @see org.eclipse.jface.preference.PreferencePage#performDefaults() |
| 684 | */ |
| 685 | protected void performDefaults() { |
| 686 | super.performDefaults(); |
| 687 | activityPromptButton.setSelection(getPreferenceStore() |
| 688 | .getDefaultBoolean( |
| 689 | IPreferenceConstants.SHOULD_PROMPT_FOR_ENABLEMENT)); |
| 690 | |
| 691 | Set defaultEnabled = new HashSet(); |
| 692 | Set activityIds = workingCopy.getDefinedActivityIds(); |
| 693 | for (Iterator i = activityIds.iterator(); i.hasNext();) { |
| 694 | String activityId = (String) i.next(); |
| 695 | IActivity activity = workingCopy.getActivity(activityId); |
| 696 | try { |
| 697 | if (activity.isDefaultEnabled()) { |
| 698 | defaultEnabled.add(activityId); |
| 699 | } |
| 700 | } catch (NotDefinedException e) { |
| 701 | // this can't happen - we're iterating over defined activities. |
| 702 | } |
| 703 | } |
| 704 | |
| 705 | workingCopy.setEnabledActivityIds(defaultEnabled); |
| 706 | } |
| 707 | |
| 708 | /* |
| 709 | * (non-Javadoc) |
| 710 | * |
| 711 | * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, |
| 712 | * java.lang.String, java.lang.Object) |
| 713 | */ |
| 714 | public void setInitializationData(IConfigurationElement config, |
| 715 | String propertyName, Object data) { |
| 716 | if (data instanceof Hashtable) { |
| 717 | Hashtable table = (Hashtable)data; |
| 718 | allowAdvanced = Boolean.valueOf((String) table.remove(ALLOW_ADVANCED)).booleanValue(); |
| 719 | strings.putAll(table); |
| 720 | } |
| 721 | } |
| 722 | } |