| /******************************************************************************* |
| * Copyright (c) 2007, 2008 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.equinox.internal.p2.ui.sdk; |
| |
| import java.net.URL; |
| import org.eclipse.core.runtime.jobs.*; |
| import org.eclipse.equinox.internal.p2.ui.sdk.prefs.PreferenceConstants; |
| import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException; |
| import org.eclipse.equinox.internal.provisional.p2.engine.ProvisioningContext; |
| import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepositoryManager; |
| import org.eclipse.equinox.internal.provisional.p2.ui.*; |
| import org.eclipse.equinox.internal.provisional.p2.ui.actions.*; |
| import org.eclipse.equinox.internal.provisional.p2.ui.dialogs.*; |
| import org.eclipse.equinox.internal.provisional.p2.ui.operations.*; |
| import org.eclipse.equinox.internal.provisional.p2.ui.policy.IQueryProvider; |
| import org.eclipse.equinox.internal.provisional.p2.ui.sdk.ProvPolicies; |
| import org.eclipse.equinox.internal.provisional.p2.ui.sdk.RepositoryManipulationDialog; |
| import org.eclipse.equinox.internal.provisional.p2.ui.viewers.StructuredViewerProvisioningListener; |
| import org.eclipse.jface.action.*; |
| import org.eclipse.jface.dialogs.*; |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.preference.PreferenceDialog; |
| import org.eclipse.jface.resource.JFaceResources; |
| import org.eclipse.jface.util.IPropertyChangeListener; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.jface.viewers.*; |
| import org.eclipse.jface.window.SameShellProvider; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.jface.wizard.WizardDialog; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.BusyIndicator; |
| import org.eclipse.swt.dnd.*; |
| import org.eclipse.swt.events.*; |
| import org.eclipse.swt.graphics.GC; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.*; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.dialogs.PreferencesUtil; |
| |
| /** |
| * Dialog that allows users to update their installed IU's or find new ones. |
| * |
| * @since 3.4 |
| */ |
| public class UpdateAndInstallDialog extends TrayDialog implements IViewMenuProvider { |
| private static final String BUTTONACTION = "buttonAction"; //$NON-NLS-1$ |
| private static final int DEFAULT_HEIGHT = 240; |
| private static final int DEFAULT_WIDTH = 300; |
| private static final int SITE_COLUMN_WIDTH_IN_DLUS = 300; |
| private static final int OTHER_COLUMN_WIDTH_IN_DLUS = 200; |
| private static final int VERTICAL_MARGIN_DLU = 2; |
| private static final int DEFAULT_VIEW_TYPE = AvailableIUViewQueryContext.VIEW_BY_REPO; |
| private static final int INDEX_INSTALLED = 0; |
| private static final int INDEX_AVAILABLE = 1; |
| private static final String DIALOG_SETTINGS_SECTION = "UpdateAndInstallDialog"; //$NON-NLS-1$ |
| private static final String SELECTED_TAB_SETTING = "SelectedTab"; //$NON-NLS-1$ |
| private static final String AVAILABLE_VIEW_TYPE = "AvailableViewType"; //$NON-NLS-1$ |
| private static final String SHOW_LATEST_VERSIONS_ONLY = "ShowLatestVersionsOnly"; //$NON-NLS-1$ |
| private static final String HIDE_INSTALLED_IUS = "HideInstalledContent"; //$NON-NLS-1$ |
| |
| String profileId; |
| Display display; |
| AvailableIUViewQueryContext queryContext; |
| TabFolder tabFolder; |
| AvailableIUGroup availableIUGroup; |
| InstalledIUGroup installedIUGroup; |
| Composite availableIUButtonBar; |
| IRepositoryManipulator repositoryManipulator; |
| ChangeViewAction viewByRepo, viewFlat, viewCategory; |
| Button installedPropButton, availablePropButton, installButton, uninstallButton, updateButton, revertButton, manipulateRepoButton, addRepoButton; |
| Button showInstalledCheckbox, showLatestVersionsCheckbox; |
| ProgressIndicator progressIndicator; |
| Label progressLabel; |
| IPropertyChangeListener preferenceListener; |
| IJobChangeListener progressListener; |
| StructuredViewerProvisioningListener profileListener; |
| |
| private class ChangeViewAction extends Action { |
| int viewType; |
| |
| ChangeViewAction(String text, int viewType) { |
| super(text, IAction.AS_RADIO_BUTTON); |
| this.viewType = viewType; |
| setChecked(this.viewType == queryContext.getViewType()); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.action.IAction#run() |
| */ |
| public void run() { |
| if (this.viewType != queryContext.getViewType()) { |
| queryContext.setViewType(viewType); |
| updateAvailableViewState(); |
| } |
| } |
| } |
| |
| /** |
| * Create an instance of this Dialog. |
| * |
| */ |
| public UpdateAndInstallDialog(Shell shell, String profileId) { |
| super(shell); |
| if (shell != null) |
| this.display = shell.getDisplay(); |
| else |
| this.display = PlatformUI.getWorkbench().getDisplay(); |
| this.profileId = profileId; |
| } |
| |
| protected void configureShell(Shell shell) { |
| shell.setText(ProvSDKMessages.UpdateAndInstallDialog_Title); |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IProvSDKHelpContextIds.UPDATE_AND_INSTALL_DIALOG); |
| |
| super.configureShell(shell); |
| } |
| |
| protected Control createDialogArea(Composite parent) { |
| Composite comp = new Composite(parent, SWT.NONE); |
| GC gc = new GC(comp); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 1; |
| comp.setLayout(layout); |
| |
| GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); |
| comp.setLayoutData(gd); |
| |
| gc.setFont(JFaceResources.getDialogFont()); |
| gc.dispose(); |
| |
| createTabFolder(comp); |
| |
| IPreferenceStore store = ProvSDKUIActivator.getDefault().getPreferenceStore(); |
| preferenceListener = new IPropertyChangeListener() { |
| public void propertyChange(PropertyChangeEvent event) { |
| if (event.getProperty().equals(PreferenceConstants.PREF_SHOW_LATEST_VERSION)) |
| availableIUGroup.getStructuredViewer().refresh(); |
| } |
| }; |
| store.addPropertyChangeListener(preferenceListener); |
| comp.addDisposeListener(new DisposeListener() { |
| public void widgetDisposed(DisposeEvent e) { |
| handleDispose(); |
| } |
| }); |
| |
| Link updatePrefsLink = new Link(comp, SWT.LEFT | SWT.WRAP); |
| updatePrefsLink.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| |
| PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn(getShell(), PreferenceConstants.PREF_PAGE_AUTO_UPDATES, null, null); |
| dialog.open(); |
| } |
| }); |
| updatePrefsLink.setText(ProvSDKMessages.UpdateAndInstallDialog_PrefLink); |
| createProgressArea(comp); |
| initializeWidgetState(); |
| Dialog.applyDialogFont(comp); |
| |
| // Now we want to ensure our button bar on the available |
| // group lines up with the tree. |
| // Layout so far so we know how to line up the buttons |
| getShell().layout(); |
| // Get the tree location and map back into button bar coordinates |
| Point location = availableIUGroup.getTree().getLocation(); |
| location = availableIUGroup.getTree().getParent().toDisplay(location); |
| location = availableIUButtonBar.toControl(location); |
| if (availableIUButtonBar.getLayout() instanceof GridLayout) { |
| ((GridLayout) availableIUButtonBar.getLayout()).marginTop = location.y; |
| getShell().layout(); |
| } |
| |
| return comp; |
| } |
| |
| private void initializeWidgetState() { |
| // Set widgets according to query context |
| showInstalledCheckbox.setSelection(!queryContext.getHideAlreadyInstalled()); |
| showLatestVersionsCheckbox.setSelection(queryContext.getShowLatestVersionsOnly()); |
| updateTreeColumns(); |
| Control focusControl = null; |
| if (tabFolder.getSelectionIndex() == INDEX_INSTALLED) |
| focusControl = installedIUGroup.getDefaultFocusControl(); |
| else |
| focusControl = availableIUGroup.getDefaultFocusControl(); |
| if (focusControl != null) |
| focusControl.setFocus(); |
| } |
| |
| private void createTabFolder(Composite parent) { |
| |
| // tab folder |
| tabFolder = new TabFolder(parent, SWT.NONE); |
| |
| GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); |
| gd.heightHint = convertVerticalDLUsToPixels(DEFAULT_HEIGHT); |
| gd.grabExcessHorizontalSpace = true; |
| gd.grabExcessVerticalSpace = true; |
| tabFolder.setLayoutData(gd); |
| |
| // Installed and Available tabs |
| TabItem installedTab = new TabItem(tabFolder, SWT.NONE); |
| installedTab.setText(ProvSDKMessages.UpdateAndInstallDialog_InstalledSoftware); |
| |
| TabItem availableTab = new TabItem(tabFolder, SWT.NONE); |
| availableTab.setText(ProvSDKMessages.UpdateAndInstallDialog_AvailableSoftware); |
| |
| // Reading the settings will also initialize the query context, so do this before |
| // creating the individual pages, which consult the context. |
| readDialogSettings(); |
| |
| // Now create the actual pages. |
| installedTab.setControl(createInstalledIUsPage(tabFolder)); |
| availableTab.setControl(createAvailableIUsPage(tabFolder)); |
| |
| setDropTarget(tabFolder); |
| |
| tabFolder.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent event) { |
| TabItem item = (TabItem) event.item; |
| Control control = item.getControl(); |
| if (control != null) { |
| control.setFocus(); |
| } |
| } |
| }); |
| } |
| |
| private void createProgressArea(Composite parent) { |
| Composite composite = new Composite(parent, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 2; |
| layout.marginHeight = 0; |
| layout.marginWidth = 0; |
| composite.setLayout(layout); |
| GridData gd = new GridData(SWT.FILL, SWT.FILL, true, false); |
| composite.setLayoutData(gd); |
| progressLabel = new Label(composite, SWT.NONE); |
| progressIndicator = new ProgressIndicator(composite); |
| gd = new GridData(SWT.FILL, SWT.FILL, true, false); |
| progressIndicator.setLayoutData(gd); |
| progressListener = new JobChangeAdapter() { |
| public void done(IJobChangeEvent event) { |
| display.asyncExec(new Runnable() { |
| public void run() { |
| checkProgressIndicator(null); |
| } |
| }); |
| } |
| |
| public void scheduled(final IJobChangeEvent event) { |
| display.asyncExec(new Runnable() { |
| public void run() { |
| checkProgressIndicator(event.getJob().getName()); |
| } |
| }); |
| } |
| }; |
| ProvisioningOperationRunner.addJobChangeListener(progressListener); |
| checkProgressIndicator(null); |
| } |
| |
| // May be called from an async exec, so check that we are still |
| // alive. |
| void checkProgressIndicator(String jobName) { |
| if (progressIndicator.isDisposed()) |
| return; |
| if (ProvisioningOperationRunner.hasScheduledOperations()) { |
| progressIndicator.beginAnimatedTask(); |
| if (jobName == null) |
| progressLabel.setText(ProvSDKMessages.UpdateAndInstallDialog_OperationInProgress); |
| else |
| progressLabel.setText(NLS.bind(ProvSDKMessages.UpdateAndInstallDialog_NamedOperationInProgress, jobName)); |
| } else { |
| progressIndicator.done(); |
| progressLabel.setText(""); //$NON-NLS-1$ |
| } |
| progressLabel.getParent().layout(true); |
| // These may have changed because the status of scheduled provisioning jobs changed |
| validateAvailableIUButtons(); |
| validateInstalledIUButtons(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.dialogs.Dialog#isResizable() |
| */ |
| protected boolean isResizable() { |
| return true; |
| } |
| |
| private IRepositoryManipulator getRepositoryManipulator() { |
| if (repositoryManipulator == null) |
| repositoryManipulator = new IRepositoryManipulator() { |
| public String getManipulatorLabel() { |
| return ProvSDKMessages.UpdateAndInstallDialog_ManageSites; |
| |
| } |
| |
| public boolean manipulateRepositories(Shell shell) { |
| new RepositoryManipulationDialog(shell, this).open(); |
| return true; |
| } |
| |
| public ProvisioningOperation getAddOperation(URL repoURL) { |
| return new AddColocatedRepositoryOperation(getAddOperationLabel(), repoURL); |
| } |
| |
| public String getAddOperationLabel() { |
| return ProvSDKMessages.UpdateAndInstallDialog_AddSiteOperationlabel; |
| } |
| |
| public URL[] getKnownRepositories() { |
| try { |
| return ProvisioningUtil.getMetadataRepositories(IMetadataRepositoryManager.REPOSITORIES_ALL); |
| } catch (ProvisionException e) { |
| return new URL[0]; |
| } |
| } |
| |
| public ProvisioningOperation getRemoveOperation(URL[] reposToRemove) { |
| return new RemoveColocatedRepositoryOperation(getRemoveOperationLabel(), reposToRemove); |
| } |
| |
| public String getRemoveOperationLabel() { |
| return ProvSDKMessages.UpdateAndInstallDialog_RemoveSiteOperationLabel; |
| } |
| |
| public URLValidator getURLValidator(Shell shell) { |
| DefaultMetadataURLValidator validator = new DefaultMetadataURLValidator(); |
| validator.setKnownRepositoriesFlag(IMetadataRepositoryManager.REPOSITORIES_NON_SYSTEM); |
| return validator; |
| } |
| }; |
| return repositoryManipulator; |
| } |
| |
| private Control createAvailableIUsPage(Composite parent) { |
| Composite composite = new Composite(parent, SWT.NONE); |
| GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); |
| gd.widthHint = convertHorizontalDLUsToPixels(DEFAULT_WIDTH); |
| composite.setLayoutData(gd); |
| setDropTarget(composite); |
| |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 2; |
| layout.marginWidth = 0; |
| |
| composite.setLayout(layout); |
| |
| // Now the available group |
| availableIUGroup = new AvailableIUGroup(composite, ProvSDKUIActivator.getDefault().getQueryProvider(), JFaceResources.getDialogFont(), new ProvisioningContext(), queryContext, new AvailableIUPatternFilter(ProvUI.getIUColumnConfig()), ProvUI.getIUColumnConfig(), this, true); |
| |
| // Vertical buttons |
| Composite vButtonBar = (Composite) createAvailableIUsVerticalButtonBar(composite); |
| GridData data = new GridData(GridData.FILL_VERTICAL); |
| vButtonBar.setLayoutData(data); |
| |
| // Selection listeners must be registered on both the normal selection |
| // events and the check mark events. Must be done after buttons |
| // are created so that the buttons can |
| // register and receive their selection notifications before us. |
| availableIUGroup.getStructuredViewer().addSelectionChangedListener(new ISelectionChangedListener() { |
| public void selectionChanged(SelectionChangedEvent event) { |
| validateAvailableIUButtons(); |
| } |
| }); |
| |
| availableIUGroup.getCheckMappingSelectionProvider().addSelectionChangedListener(new ISelectionChangedListener() { |
| public void selectionChanged(SelectionChangedEvent event) { |
| validateAvailableIUButtons(); |
| } |
| }); |
| |
| // We might need to adjust the content of this viewer according to installation |
| // changes. We want to be very selective about refreshing. |
| profileListener = new StructuredViewerProvisioningListener(availableIUGroup.getStructuredViewer(), StructuredViewerProvisioningListener.PROV_EVENT_PROFILE, ProvSDKUIActivator.getDefault().getQueryProvider()) { |
| protected void profileAdded(String id) { |
| // do nothing |
| } |
| |
| protected void profileRemoved(String id) { |
| // do nothing |
| } |
| |
| protected void profileChanged(String id) { |
| if (id.equals(profileId)) { |
| display.asyncExec(new Runnable() { |
| public void run() { |
| if (isClosing()) |
| return; |
| if (!showInstalledCheckbox.getSelection()) |
| refreshAll(); |
| } |
| }); |
| } |
| } |
| }; |
| ProvUI.addProvisioningListener(profileListener); |
| |
| availableIUGroup.setUseBoldFontForFilteredItems(queryContext.getViewType() != AvailableIUViewQueryContext.VIEW_FLAT); |
| setDropTarget(availableIUGroup.getStructuredViewer().getControl()); |
| |
| gd = new GridData(SWT.FILL, SWT.FILL, true, false); |
| gd.horizontalSpan = 2; |
| gd.verticalIndent = convertVerticalDLUsToPixels(VERTICAL_MARGIN_DLU); |
| showLatestVersionsCheckbox = new Button(composite, SWT.CHECK); |
| showLatestVersionsCheckbox.setText(ProvSDKMessages.UpdateAndInstallDialog_ShowLatestVersionsOnly); |
| showLatestVersionsCheckbox.addSelectionListener(new SelectionListener() { |
| public void widgetDefaultSelected(SelectionEvent e) { |
| updateAvailableViewState(); |
| } |
| |
| public void widgetSelected(SelectionEvent e) { |
| updateAvailableViewState(); |
| } |
| }); |
| showLatestVersionsCheckbox.setLayoutData(gd); |
| |
| showInstalledCheckbox = new Button(composite, SWT.CHECK); |
| showInstalledCheckbox.setText(ProvSDKMessages.UpdateAndInstallDialog_ShowAlreadyInstalledItems); |
| showInstalledCheckbox.addSelectionListener(new SelectionListener() { |
| public void widgetDefaultSelected(SelectionEvent e) { |
| updateAvailableViewState(); |
| } |
| |
| public void widgetSelected(SelectionEvent e) { |
| updateAvailableViewState(); |
| } |
| }); |
| gd = new GridData(SWT.FILL, SWT.FILL, true, false); |
| gd.horizontalSpan = 2; |
| showInstalledCheckbox.setLayoutData(gd); |
| |
| validateAvailableIUButtons(); |
| return composite; |
| } |
| |
| public void fillViewMenu(IMenuManager viewMenu) { |
| viewByRepo = new ChangeViewAction(ProvSDKMessages.UpdateAndInstallDialog_ViewBySite, AvailableIUViewQueryContext.VIEW_BY_REPO); |
| viewMenu.add(viewByRepo); |
| viewCategory = new ChangeViewAction(ProvSDKMessages.UpdateAndInstallDialog_ViewByCategory, AvailableIUViewQueryContext.VIEW_BY_CATEGORY); |
| viewMenu.add(viewCategory); |
| viewFlat = new ChangeViewAction(ProvSDKMessages.UpdateAndInstallDialog_ViewByName, AvailableIUViewQueryContext.VIEW_FLAT); |
| viewMenu.add(viewFlat); |
| } |
| |
| private Control createAvailableIUsVerticalButtonBar(Composite parent) { |
| // Create composite. |
| // Cached so we can line things up later. |
| availableIUButtonBar = new Composite(parent, SWT.NULL); |
| |
| // create a layout with spacing and margins appropriate for the font |
| // size. |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 1; |
| layout.marginWidth = 5; |
| layout.marginHeight = 0; |
| layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); |
| layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); |
| availableIUButtonBar.setLayout(layout); |
| |
| // Add the buttons to the button bar. |
| // We use the check box selection provider to determine what to install. For other actions we use the normal selection provider. |
| IAction installAction = new InstallAction(availableIUGroup.getCheckMappingSelectionProvider(), profileId, null, ProvPolicies.getDefault(), getShell()); |
| installButton = createVerticalButton(availableIUButtonBar, installAction, false); |
| |
| // spacer to separate the actions that close the dialog from the others. |
| new Label(availableIUButtonBar, SWT.NONE); |
| |
| IAction propertiesAction = new PropertyDialogAction(new SameShellProvider(parent.getShell()), availableIUGroup.getStructuredViewer()); |
| propertiesAction.setText(ProvSDKMessages.UpdateAndInstallDialog_Properties); |
| availablePropButton = createVerticalButton(availableIUButtonBar, propertiesAction, false); |
| |
| // spacer |
| new Label(availableIUButtonBar, SWT.NONE); |
| |
| IAction addSites = new AddColocatedRepositoryAction(availableIUGroup.getStructuredViewer(), getShell()); |
| // Change the text so it's clear this is adding sites, not just "add". Since items in the list are not all sites. |
| addSites.setText(ProvSDKMessages.UpdateAndInstallDialog_AddSiteButtonText); |
| addRepoButton = createVerticalButton(availableIUButtonBar, addSites, false); |
| |
| IAction manipulateRepos = new Action() { |
| public void runWithEvent(Event event) { |
| getRepositoryManipulator().manipulateRepositories(getShell()); |
| } |
| }; |
| manipulateRepos.setText(ProvSDKMessages.UpdateAndInstallDialog_ManageSites); |
| manipulateRepos.setToolTipText(ProvSDKMessages.UpdateAndInstallDialog_ManageSitesTooltip); |
| manipulateRepoButton = createVerticalButton(availableIUButtonBar, manipulateRepos, false); |
| |
| // spacer |
| new Label(availableIUButtonBar, SWT.NONE); |
| |
| IAction refreshAction = new RefreshAction(availableIUGroup.getStructuredViewer(), availableIUGroup.getStructuredViewer().getControl()) { |
| protected void refresh() { |
| availableIUGroup.refresh(); |
| } |
| }; |
| refreshAction.setToolTipText(ProvSDKMessages.UpdateAndInstallDialog_RefreshTooltip); |
| createVerticalButton(availableIUButtonBar, refreshAction, false); |
| |
| createMenu(availableIUGroup.getStructuredViewer().getControl(), new IAction[] {installAction, propertiesAction, refreshAction}); |
| |
| return availableIUButtonBar; |
| } |
| |
| void updateAvailableViewState() { |
| if (availableIUGroup.getTree() == null || availableIUGroup.getTree().isDisposed()) |
| return; |
| final Composite parent = availableIUGroup.getComposite().getParent(); |
| validateAvailableIUButtons(); |
| availableIUGroup.setUseBoldFontForFilteredItems(queryContext.getViewType() != AvailableIUViewQueryContext.VIEW_FLAT); |
| |
| BusyIndicator.showWhile(display, new Runnable() { |
| public void run() { |
| parent.setRedraw(false); |
| updateTreeColumns(); |
| queryContext.setShowLatestVersionsOnly(showLatestVersionsCheckbox.getSelection()); |
| if (showInstalledCheckbox.getSelection()) |
| queryContext.showAlreadyInstalled(); |
| else |
| queryContext.hideAlreadyInstalled(profileId); |
| availableIUGroup.setQueryContext(queryContext); |
| parent.layout(true); |
| parent.setRedraw(true); |
| } |
| }); |
| } |
| |
| void updateTreeColumns() { |
| if (availableIUGroup.getTree() == null || availableIUGroup.getTree().isDisposed()) |
| return; |
| TreeColumn[] columns = availableIUGroup.getTree().getColumns(); |
| if (columns.length > 0) |
| columns[0].setWidth(convertHorizontalDLUsToPixels(queryContext.getViewType() == AvailableIUViewQueryContext.VIEW_BY_REPO ? SITE_COLUMN_WIDTH_IN_DLUS : OTHER_COLUMN_WIDTH_IN_DLUS)); |
| |
| } |
| |
| void validateAvailableIUButtons() { |
| // This relies on the actions themselves receiving the selection changed |
| // listener before we do, since we use their state to enable the buttons. |
| updateEnablement(installButton); |
| updateEnablement(availablePropButton); |
| updateEnablement(manipulateRepoButton); |
| updateEnablement(addRepoButton); |
| } |
| |
| private Control createInstalledIUsPage(Composite parent) { |
| |
| Composite composite = new Composite(parent, SWT.NONE); |
| GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); |
| gd.widthHint = convertHorizontalDLUsToPixels(DEFAULT_WIDTH); |
| composite.setLayoutData(gd); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 2; |
| layout.marginWidth = 0; |
| composite.setLayout(layout); |
| |
| // Table of installed IU's |
| installedIUGroup = new InstalledIUGroup(composite, ProvSDKUIActivator.getDefault().getQueryProvider(), JFaceResources.getDialogFont(), new ProvisioningContext(), profileId); |
| |
| // Vertical buttons |
| Composite vButtonBar = (Composite) createInstalledIUsVerticalButtonBar(composite, ProvSDKUIActivator.getDefault().getQueryProvider()); |
| GridData data = new GridData(GridData.FILL_VERTICAL); |
| vButtonBar.setLayoutData(data); |
| |
| // Must be done after buttons are created so that the buttons can |
| // register and receive their selection notifications before us. |
| installedIUGroup.getStructuredViewer().addSelectionChangedListener(new ISelectionChangedListener() { |
| public void selectionChanged(SelectionChangedEvent event) { |
| validateInstalledIUButtons(); |
| } |
| }); |
| |
| setDropTarget(installedIUGroup.getStructuredViewer().getControl()); |
| |
| validateInstalledIUButtons(); |
| return composite; |
| } |
| |
| private Control createInstalledIUsVerticalButtonBar(Composite parent, IQueryProvider queryProvider) { |
| // Create composite. |
| Composite composite = new Composite(parent, SWT.NULL); |
| |
| // create a layout with spacing and margins appropriate for the font |
| // size. |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 1; |
| layout.marginWidth = 5; |
| layout.marginHeight = 0; |
| layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); |
| layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); |
| composite.setLayout(layout); |
| |
| // Add the buttons to the button bar. |
| // For update only, we want it to check for all updates if there is nothing selected |
| IAction updateAction = new UpdateAction(new ISelectionProvider() { |
| public void addSelectionChangedListener(ISelectionChangedListener listener) { |
| installedIUGroup.getStructuredViewer().addSelectionChangedListener(listener); |
| } |
| |
| public ISelection getSelection() { |
| StructuredViewer viewer = installedIUGroup.getStructuredViewer(); |
| ISelection selection = viewer.getSelection(); |
| if (selection.isEmpty()) { |
| final Object[] all = ((IStructuredContentProvider) installedIUGroup.getStructuredViewer().getContentProvider()).getElements(viewer.getInput()); |
| return new StructuredSelection(all); |
| } |
| return selection; |
| } |
| |
| public void removeSelectionChangedListener(ISelectionChangedListener listener) { |
| installedIUGroup.getStructuredViewer().removeSelectionChangedListener(listener); |
| } |
| |
| public void setSelection(ISelection selection) { |
| installedIUGroup.getStructuredViewer().setSelection(selection); |
| } |
| }, profileId, null, ProvPolicies.getDefault(), parent.getShell()); |
| updateButton = createVerticalButton(composite, updateAction, false); |
| |
| IAction uninstallAction = new UninstallAction(installedIUGroup.getStructuredViewer(), profileId, null, ProvPolicies.getDefault(), parent.getShell()); |
| uninstallButton = createVerticalButton(composite, uninstallAction, false); |
| |
| // spacer |
| new Label(composite, SWT.NONE); |
| |
| IAction propertiesAction = new PropertyDialogAction(new SameShellProvider(parent.getShell()), installedIUGroup.getStructuredViewer()); |
| propertiesAction.setText(ProvSDKMessages.UpdateAndInstallDialog_Properties); |
| installedPropButton = createVerticalButton(composite, propertiesAction, false); |
| |
| // spacer |
| new Label(composite, SWT.NONE); |
| |
| IAction revertAction = new Action() { |
| public void run() { |
| RevertWizard wizard = new RevertWizard(profileId, ProvSDKUIActivator.getDefault().getQueryProvider()); |
| WizardDialog dialog = new WizardDialog(getShell(), wizard); |
| dialog.create(); |
| dialog.getShell().setSize(600, 500); |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(dialog.getShell(), IProvHelpContextIds.REVERT_CONFIGURATION_WIZARD); |
| |
| dialog.open(); |
| } |
| }; |
| revertAction.setText(ProvSDKMessages.UpdateAndInstallDialog_RevertActionLabel); |
| revertAction.setToolTipText(ProvSDKMessages.UpdateAndInstallDialog_RevertTooltip); |
| |
| revertButton = createVerticalButton(composite, revertAction, false); |
| |
| createMenu(installedIUGroup.getStructuredViewer().getControl(), new IAction[] {updateAction, uninstallAction, propertiesAction}); |
| |
| return composite; |
| } |
| |
| private void createMenu(Control control, IAction[] actions) { |
| MenuManager menuManager = new MenuManager(); |
| for (int i = 0; i < actions.length; i++) |
| menuManager.add(actions[i]); |
| Menu menu = menuManager.createContextMenu(control); |
| control.setMenu(menu); |
| } |
| |
| void validateInstalledIUButtons() { |
| // Note that this relies on the actions getting the selection notification |
| // before we do, since we rely on the action enablement to update |
| // the buttons. This should be ok since the buttons |
| // hook the listener on create. |
| updateEnablement(installedPropButton); |
| updateEnablement(uninstallButton); |
| updateEnablement(updateButton); |
| // special case because revert isn't a standard action |
| revertButton.setEnabled(!ProvisioningOperationRunner.hasScheduledOperationsFor(profileId)); |
| |
| } |
| |
| private void updateEnablement(Button button) { |
| // At this point the action's enablement is correct for its |
| // selection. Now we want to double check other conditions. |
| IAction action = getButtonAction(button); |
| if (action != null) { |
| if (action instanceof ProvisioningAction) |
| ((ProvisioningAction) action).checkEnablement(); |
| button.setEnabled(action.isEnabled()); |
| } |
| } |
| |
| private Button createVerticalButton(Composite parent, IAction action, boolean defaultButton) { |
| Button button = new Button(parent, SWT.PUSH); |
| button.setText(action.getText()); |
| |
| setButtonLayoutData(button); |
| Object data = button.getLayoutData(); |
| if (data instanceof GridData) |
| ((GridData) data).horizontalAlignment = GridData.FILL; |
| |
| button.addListener(SWT.Selection, new Listener() { |
| public void handleEvent(Event event) { |
| verticalButtonPressed(event); |
| } |
| }); |
| button.setToolTipText(action.getToolTipText()); |
| if (defaultButton) { |
| Shell shell = parent.getShell(); |
| if (shell != null) { |
| shell.setDefaultButton(button); |
| } |
| } |
| button.setData(BUTTONACTION, action); |
| return button; |
| } |
| |
| void verticalButtonPressed(Event event) { |
| IAction action = getButtonAction(event.widget); |
| if (action != null) { |
| action.runWithEvent(event); |
| } |
| // Close this dialog if we were performing a profile |
| // modifying operation and it succeeded. |
| if (action instanceof ProfileModificationAction && ((ProfileModificationAction) action).getReturnCode() == Window.OK) |
| close(); |
| } |
| |
| private IAction getButtonAction(Widget widget) { |
| Object data = widget.getData(BUTTONACTION); |
| if (data == null || !(data instanceof IAction)) { |
| return null; |
| } |
| return (IAction) data; |
| } |
| |
| private void readDialogSettings() { |
| if (tabFolder == null || tabFolder.isDisposed()) |
| return; |
| |
| // Initialize the query context using defaults and pref values |
| queryContext = new AvailableIUViewQueryContext(DEFAULT_VIEW_TYPE); |
| IPreferenceStore store = ProvSDKUIActivator.getDefault().getPreferenceStore(); |
| queryContext.setShowLatestVersionsOnly(store.getBoolean(PreferenceConstants.PREF_SHOW_LATEST_VERSION)); |
| queryContext.hideAlreadyInstalled(profileId); |
| |
| // Now refine it based on the dialog settings |
| IDialogSettings settings = ProvSDKUIActivator.getDefault().getDialogSettings(); |
| IDialogSettings section = settings.getSection(DIALOG_SETTINGS_SECTION); |
| if (section != null) { |
| // Default selected tab |
| int tab = 0; |
| if (section.get(SELECTED_TAB_SETTING) != null) |
| tab = section.getInt(SELECTED_TAB_SETTING); |
| tabFolder.setSelection(tab); |
| |
| // View by... |
| try { |
| if (section.get(AVAILABLE_VIEW_TYPE) != null) |
| queryContext.setViewType(section.getInt(AVAILABLE_VIEW_TYPE)); |
| } catch (NumberFormatException e) { |
| // Ignore if there actually was a value that didn't parse. |
| // We'll get a default query context below. |
| } |
| |
| // Show latest versions |
| if (section.get(SHOW_LATEST_VERSIONS_ONLY) != null) |
| queryContext.setShowLatestVersionsOnly(section.getBoolean(SHOW_LATEST_VERSIONS_ONLY)); |
| |
| // Hide installed content |
| boolean hideContent = section.getBoolean(HIDE_INSTALLED_IUS); |
| if (hideContent) |
| queryContext.hideAlreadyInstalled(profileId); |
| else |
| queryContext.showAlreadyInstalled(); |
| } |
| } |
| |
| private void saveDialogSettings() { |
| if (!tabFolder.isDisposed()) { |
| getDialogBoundsSettings().put(SELECTED_TAB_SETTING, tabFolder.getSelectionIndex()); |
| getDialogBoundsSettings().put(AVAILABLE_VIEW_TYPE, queryContext.getViewType()); |
| getDialogBoundsSettings().put(SHOW_LATEST_VERSIONS_ONLY, showLatestVersionsCheckbox.getSelection()); |
| getDialogBoundsSettings().put(HIDE_INSTALLED_IUS, !showInstalledCheckbox.getSelection()); |
| } |
| } |
| |
| protected IDialogSettings getDialogBoundsSettings() { |
| IDialogSettings settings = ProvSDKUIActivator.getDefault().getDialogSettings(); |
| IDialogSettings section = settings.getSection(DIALOG_SETTINGS_SECTION); |
| if (section == null) { |
| section = settings.addNewSection(DIALOG_SETTINGS_SECTION); |
| } |
| return section; |
| } |
| |
| /** |
| * Overridden to provide a close button. |
| * |
| * @param parent |
| * the button bar composite |
| */ |
| protected void createButtonsForButtonBar(Composite parent) { |
| Button button = createButton(parent, IDialogConstants.CLOSE_ID, IDialogConstants.CLOSE_LABEL, true); |
| // workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=231998 |
| TraverseListener traverseListener = new TraverseListener() { |
| public void keyTraversed(TraverseEvent e) { |
| if (e.detail != SWT.TRAVERSE_MNEMONIC) |
| return; |
| if (tabFolder.getSelectionIndex() == INDEX_AVAILABLE && (e.stateMask & SWT.ALT) != SWT.ALT) { |
| Control filter = availableIUGroup.getDefaultFocusControl(); |
| e.doit = filter.isEnabled(); |
| e.detail = SWT.TRAVERSE_NONE; |
| } |
| } |
| }; |
| |
| Control control = button; |
| while (!(control instanceof Shell)) { |
| control.addTraverseListener(traverseListener); |
| control = control.getParent(); |
| } |
| } |
| |
| protected void buttonPressed(int buttonId) { |
| if (IDialogConstants.CLOSE_ID == buttonId) { |
| saveDialogSettings(); |
| close(); |
| } |
| super.buttonPressed(buttonId); |
| } |
| |
| private void setDropTarget(Control control) { |
| DropTarget target = new DropTarget(control, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK); |
| target.setTransfer(new Transfer[] {URLTransfer.getInstance(), FileTransfer.getInstance()}); |
| target.addDropListener(new RepositoryManipulatorDropTarget(getRepositoryManipulator(), control) { |
| protected boolean dropTargetIsValid(DropTargetEvent event) { |
| // Overridden so that drops are only valid on the available software page. |
| if (tabFolder.getSelectionIndex() == INDEX_AVAILABLE) |
| return super.dropTargetIsValid(event); |
| if (tabFolder.getSelectionIndex() == INDEX_INSTALLED) |
| // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=222120 |
| // In the future we may wish to check TabItem.getBounds() and |
| // TabFolder.getItem(point) to determine if the available software |
| // tab got the drop while on the installed software page. |
| // We may also have a different interpretation when the installed software |
| // page is the target. For now we do nothing. |
| return false; |
| return false; |
| } |
| }); |
| } |
| |
| void handleDispose() { |
| if (preferenceListener != null) { |
| ProvSDKUIActivator.getDefault().getPreferenceStore().removePropertyChangeListener(preferenceListener); |
| preferenceListener = null; |
| } |
| if (progressListener != null) { |
| ProvisioningOperationRunner.removeJobChangeListener(progressListener); |
| progressListener = null; |
| } |
| if (profileListener != null) { |
| ProvUI.removeProvisioningListener(profileListener); |
| profileListener = null; |
| } |
| |
| } |
| } |