blob: 91222f27ed6b2507d8c030150b596100fef2f325 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2009 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.p2.ui;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Hashtable;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.ui.*;
import org.eclipse.equinox.internal.p2.ui.dialogs.*;
import org.eclipse.equinox.internal.p2.ui.model.*;
import org.eclipse.equinox.internal.p2.ui.viewers.*;
import org.eclipse.equinox.internal.provisional.p2.repository.RepositoryEvent;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.operations.ProvisioningSession;
import org.eclipse.equinox.p2.operations.RepositoryTracker;
import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.viewers.*;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.AccessibleAdapter;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.dnd.*;
import org.eclipse.swt.events.*;
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.*;
import org.eclipse.ui.dialogs.PatternFilter;
import org.eclipse.ui.progress.WorkbenchJob;
import org.eclipse.ui.statushandlers.StatusManager;
/**
* Page that allows users to update, add, remove, import, and
* export repositories. This page can be hosted inside a preference
* dialog or inside its own dialog.
*
* When hosting this page inside a non-preference dialog, some of the
* dialog methods will likely have to call page methods. The following
* snippet shows how to host this page inside a TitleAreaDialog.
* <pre>
* TitleAreaDialog dialog = new TitleAreaDialog(shell) {
*
* RepositoryManipulationPage page;
*
* protected Control createDialogArea(Composite parent) {
* page = new RepositoryManipulationPage();
* page.setProvisioningUI(ProvisioningUI.getDefaultUI());
* page.createControl(parent);
* this.setTitle("Software Sites");
* this.setMessage("The enabled sites will be searched for software. Disabled sites are ignored.");
* return page.getControl();
* }
*
* protected void okPressed() {
* if (page.performOk())
* super.okPressed();
* }
*
* protected void cancelPressed() {
* if (page.performCancel())
* super.cancelPressed();
* }
* };
* dialog.open();
* </pre>
*
* @noextend This class is not intended to be subclassed by clients.
*
* @since 2.0
*/
public class RepositoryManipulationPage extends PreferencePage implements IWorkbenchPreferencePage, ICopyable {
final static String DEFAULT_FILTER_TEXT = ProvUIMessages.RepositoryManipulationPage_DefaultFilterString;
private final static int FILTER_DELAY = 200;
StructuredViewerProvisioningListener listener;
CheckboxTableViewer repositoryViewer;
Table table;
ProvisioningUI ui;
Policy policy;
Display display;
boolean changed = false;
MetadataRepositoryElementComparator comparator;
RepositoryDetailsLabelProvider labelProvider;
RepositoryTracker tracker;
RepositoryTracker localCacheRepoManipulator;
CachedMetadataRepositories input;
Text pattern, details;
PatternFilter filter;
WorkbenchJob filterJob;
Button addButton, removeButton, editButton, refreshButton, disableButton, exportButton;
class CachedMetadataRepositories extends MetadataRepositories {
Hashtable<String, Object> cachedElements;
CachedMetadataRepositories() {
super(ui);
setIncludeDisabledRepositories(getPolicy().getRepositoriesVisible());
}
public int getQueryType() {
return QueryProvider.METADATA_REPOS;
}
public Object[] fetchChildren(Object o, IProgressMonitor monitor) {
if (cachedElements == null) {
Object[] children = super.fetchChildren(o, monitor);
cachedElements = new Hashtable<String, Object>(children.length);
for (int i = 0; i < children.length; i++) {
if (children[i] instanceof MetadataRepositoryElement)
cachedElements.put(URIUtil.toUnencodedString(((MetadataRepositoryElement) children[i]).getLocation()), children[i]);
}
}
return cachedElements.values().toArray();
}
}
class MetadataRepositoryPatternFilter extends PatternFilter {
MetadataRepositoryPatternFilter() {
setIncludeLeadingWildcard(true);
}
public boolean isElementVisible(Viewer viewer, Object element) {
if (element instanceof MetadataRepositoryElement) {
return wordMatches(labelProvider.getColumnText(element, RepositoryDetailsLabelProvider.COL_NAME) + " " + labelProvider.getColumnText(element, RepositoryDetailsLabelProvider.COL_LOCATION)); //$NON-NLS-1$
}
return false;
}
}
/**
* Create a repository manipulation page that will display the repositories
* available to the user.
*/
public RepositoryManipulationPage() {
this.setProvisioningUI(ProvisioningUI.getDefaultUI());
}
/**
* Set the provisioning UI that provides the session, policy, and other
* services for the UI. This method must be called before the contents are
* created or it will have no effect.
*
* @param ui the provisioning UI to use for this page.
*/
public void setProvisioningUI(ProvisioningUI ui) {
this.ui = ui;
this.policy = ui.getPolicy();
tracker = ui.getRepositoryTracker();
}
protected Control createContents(Composite parent) {
display = parent.getDisplay();
// The help refers to the full-blown dialog. No help if it's read only.
if (policy.getRepositoriesVisible())
PlatformUI.getWorkbench().getHelpSystem().setHelp(parent.getShell(), IProvHelpContextIds.REPOSITORY_MANIPULATION_DIALOG);
Composite composite = new Composite(parent, SWT.NONE);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
composite.setLayoutData(gd);
GridLayout layout = new GridLayout();
layout.numColumns = policy.getRepositoriesVisible() ? 2 : 1;
layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
composite.setLayout(layout);
// Filter box
pattern = new Text(composite, SWT.SINGLE | SWT.BORDER | SWT.SEARCH | SWT.CANCEL);
pattern.getAccessible().addAccessibleListener(new AccessibleAdapter() {
public void getName(AccessibleEvent e) {
e.result = DEFAULT_FILTER_TEXT;
}
});
pattern.setText(DEFAULT_FILTER_TEXT);
pattern.selectAll();
pattern.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
applyFilter();
}
});
pattern.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.keyCode == SWT.ARROW_DOWN) {
if (table.getItemCount() > 0) {
table.setFocus();
} else if (e.character == SWT.CR) {
return;
}
}
}
});
pattern.addFocusListener(new FocusAdapter() {
public void focusGained(FocusEvent e) {
display.asyncExec(new Runnable() {
public void run() {
if (!pattern.isDisposed()) {
if (DEFAULT_FILTER_TEXT.equals(pattern.getText().trim())) {
pattern.selectAll();
}
}
}
});
}
});
gd = new GridData(SWT.FILL, SWT.FILL, true, false);
pattern.setLayoutData(gd);
// spacer to fill other column
if (policy.getRepositoriesVisible())
new Label(composite, SWT.NONE);
// Table of available repositories
table = new Table(composite, SWT.CHECK | SWT.MULTI | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
repositoryViewer = new CheckboxTableViewer(table);
// Key listener for delete
table.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.keyCode == SWT.DEL) {
removeRepositories();
}
}
});
setTableColumns();
CopyUtils.activateCopy(this, table);
repositoryViewer.setComparer(new ProvElementComparer());
comparator = new MetadataRepositoryElementComparator(RepositoryDetailsLabelProvider.COL_NAME);
repositoryViewer.setComparator(comparator);
filter = new MetadataRepositoryPatternFilter();
repositoryViewer.setFilters(new ViewerFilter[] {filter});
// We don't need a deferred content provider because we are caching local results before
// actually querying
repositoryViewer.setContentProvider(new ProvElementContentProvider());
labelProvider = new RepositoryDetailsLabelProvider();
repositoryViewer.setLabelProvider(labelProvider);
// Edit the nickname
repositoryViewer.setCellModifier(new ICellModifier() {
public boolean canModify(Object element, String property) {
return element instanceof MetadataRepositoryElement;
}
public Object getValue(Object element, String property) {
return ((MetadataRepositoryElement) element).getName();
}
public void modify(Object element, String property, Object value) {
if (value != null && value.toString().length() >= 0) {
MetadataRepositoryElement repo;
if (element instanceof Item) {
repo = (MetadataRepositoryElement) ((Item) element).getData();
} else if (element instanceof MetadataRepositoryElement) {
repo = (MetadataRepositoryElement) element;
} else {
return;
}
if (!value.toString().equals(repo.getName())) {
changed = true;
repo.setNickname(value.toString());
if (comparator.getSortKey() == RepositoryDetailsLabelProvider.COL_NAME)
repositoryViewer.refresh(true);
else
repositoryViewer.update(repo, null);
}
}
}
});
repositoryViewer.setColumnProperties(new String[] {"nickname"}); //$NON-NLS-1$
repositoryViewer.setCellEditors(new CellEditor[] {new TextCellEditor(repositoryViewer.getTable())});
repositoryViewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
if (policy.getRepositoriesVisible())
validateButtons();
setDetails();
}
});
repositoryViewer.setCheckStateProvider(new ICheckStateProvider() {
public boolean isChecked(Object element) {
return ((MetadataRepositoryElement) element).isEnabled();
}
public boolean isGrayed(Object element) {
return false;
}
});
repositoryViewer.addCheckStateListener(new ICheckStateListener() {
public void checkStateChanged(CheckStateChangedEvent event) {
MetadataRepositoryElement element = (MetadataRepositoryElement) event.getElement();
element.setEnabled(event.getChecked());
// paranoid that an equal but not identical element was passed in as the selection.
// update the cache map just in case.
input.cachedElements.put(URIUtil.toUnencodedString(element.getLocation()), element);
// update the viewer to show the change
updateForEnablementChange(new MetadataRepositoryElement[] {element});
}
});
// Input last
repositoryViewer.setInput(getInput());
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
data.widthHint = convertWidthInCharsToPixels(ILayoutConstants.DEFAULT_TABLE_WIDTH);
data.heightHint = convertHeightInCharsToPixels(ILayoutConstants.DEFAULT_TABLE_HEIGHT);
table.setLayoutData(data);
// Drop targets and vertical buttons only if repository manipulation is provided.
if (policy.getRepositoriesVisible()) {
DropTarget target = new DropTarget(table, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK);
target.setTransfer(new Transfer[] {URLTransfer.getInstance(), FileTransfer.getInstance()});
target.addDropListener(new RepositoryManipulatorDropTarget(ui, table));
// Vertical buttons
Composite verticalButtonBar = createVerticalButtonBar(composite);
data = new GridData(SWT.FILL, SWT.FILL, false, false);
data.verticalAlignment = SWT.TOP;
data.verticalIndent = 0;
verticalButtonBar.setLayoutData(data);
listener = getViewerProvisioningListener();
ProvUI.addProvisioningListener(listener);
composite.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent event) {
ProvUI.removeProvisioningListener(listener);
}
});
validateButtons();
}
// Details area
details = new Text(composite, SWT.READ_ONLY | SWT.WRAP);
data = new GridData(SWT.FILL, SWT.FILL, true, false);
data.heightHint = convertHeightInCharsToPixels(ILayoutConstants.DEFAULT_SITEDETAILS_HEIGHT);
details.setLayoutData(data);
Dialog.applyDialogFont(composite);
return composite;
}
private Button createVerticalButton(Composite parent, String label, boolean defaultButton) {
Button button = new Button(parent, SWT.PUSH);
button.setText(label);
GridData data = setVerticalButtonLayoutData(button);
data.horizontalAlignment = GridData.FILL;
button.setToolTipText(label);
if (defaultButton) {
Shell shell = parent.getShell();
if (shell != null) {
shell.setDefaultButton(button);
}
}
return button;
}
private GridData setVerticalButtonLayoutData(Button button) {
GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
Point minSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
data.widthHint = Math.max(widthHint, minSize.x);
button.setLayoutData(data);
return data;
}
private void setTableColumns() {
table.setHeaderVisible(true);
String[] columnHeaders;
if (policy.getRepositoriesVisible())
columnHeaders = new String[] {ProvUIMessages.RepositoryManipulationPage_NameColumnTitle, ProvUIMessages.RepositoryManipulationPage_LocationColumnTitle, ProvUIMessages.RepositoryManipulationPage_EnabledColumnTitle};
else
columnHeaders = new String[] {ProvUIMessages.RepositoryManipulationPage_NameColumnTitle, ProvUIMessages.RepositoryManipulationPage_LocationColumnTitle};
for (int i = 0; i < columnHeaders.length; i++) {
TableColumn tc = new TableColumn(table, SWT.NONE, i);
tc.setResizable(true);
tc.setText(columnHeaders[i]);
if (i == RepositoryDetailsLabelProvider.COL_ENABLEMENT) {
tc.setWidth(convertWidthInCharsToPixels(ILayoutConstants.DEFAULT_SMALL_COLUMN_WIDTH));
tc.setAlignment(SWT.CENTER);
} else if (i == RepositoryDetailsLabelProvider.COL_NAME) {
tc.setWidth(convertWidthInCharsToPixels(ILayoutConstants.DEFAULT_COLUMN_WIDTH));
} else {
tc.setWidth(convertWidthInCharsToPixels(ILayoutConstants.DEFAULT_PRIMARY_COLUMN_WIDTH));
}
tc.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {
columnSelected((TableColumn) e.widget);
}
public void widgetSelected(SelectionEvent e) {
columnSelected((TableColumn) e.widget);
}
});
// First column only
if (i == 0) {
table.setSortColumn(tc);
table.setSortDirection(SWT.UP);
}
}
}
private Composite createVerticalButtonBar(Composite parent) {
// Create composite.
Composite composite = new Composite(parent, SWT.NONE);
initializeDialogUnits(composite);
// 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);
createVerticalButtons(composite);
return composite;
}
private void createVerticalButtons(Composite parent) {
addButton = createVerticalButton(parent, ProvUIMessages.RepositoryManipulationPage_Add, false);
addButton.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
addRepository();
}
});
editButton = createVerticalButton(parent, ProvUIMessages.RepositoryManipulationPage_Edit, false);
editButton.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
changeRepositoryProperties();
}
});
removeButton = createVerticalButton(parent, ProvUIMessages.RepositoryManipulationPage_Remove, false);
removeButton.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
removeRepositories();
}
});
refreshButton = createVerticalButton(parent, ProvUIMessages.RepositoryManipulationPage_RefreshConnection, false);
refreshButton.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
refreshRepository();
}
});
disableButton = createVerticalButton(parent, ProvUIMessages.RepositoryManipulationPage_DisableButton, false);
disableButton.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
toggleRepositoryEnablement();
}
});
Button button = createVerticalButton(parent, ProvUIMessages.RepositoryManipulationPage_Import, false);
button.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
importRepositories();
}
});
exportButton = createVerticalButton(parent, ProvUIMessages.RepositoryManipulationPage_Export, false);
exportButton.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
exportRepositories();
}
});
}
CachedMetadataRepositories getInput() {
if (input == null)
input = new CachedMetadataRepositories();
return input;
}
/*
* (non-Javadoc)
* @see org.eclipse.jface.preference.PreferencePage#performOk()
*/
public boolean performOk() {
if (changed)
ElementUtils.updateRepositoryUsingElements(getElements(), getShell());
return super.performOk();
}
private StructuredViewerProvisioningListener getViewerProvisioningListener() {
return new StructuredViewerProvisioningListener(repositoryViewer, ProvUIProvisioningListener.PROV_EVENT_METADATA_REPOSITORY) {
protected void repositoryDiscovered(RepositoryEvent e) {
RepositoryManipulationPage.this.safeRefresh(null);
}
protected void repositoryChanged(RepositoryEvent e) {
RepositoryManipulationPage.this.safeRefresh(null);
}
};
}
MetadataRepositoryElement[] getElements() {
return getInput().cachedElements.values().toArray(new MetadataRepositoryElement[getInput().cachedElements.size()]);
}
MetadataRepositoryElement[] getSelectedElements() {
Object[] items = ((IStructuredSelection) repositoryViewer.getSelection()).toArray();
ArrayList<Object> list = new ArrayList<Object>(items.length);
for (int i = 0; i < items.length; i++) {
if (items[i] instanceof MetadataRepositoryElement)
list.add(items[i]);
}
return list.toArray(new MetadataRepositoryElement[list.size()]);
}
void validateButtons() {
MetadataRepositoryElement[] elements = getSelectedElements();
exportButton.setEnabled(elements.length > 0);
removeButton.setEnabled(elements.length > 0);
editButton.setEnabled(elements.length == 1);
refreshButton.setEnabled(elements.length == 1);
if (elements.length >= 1) {
if (toggleMeansDisable(elements))
disableButton.setText(ProvUIMessages.RepositoryManipulationPage_DisableButton);
else
disableButton.setText(ProvUIMessages.RepositoryManipulationPage_EnableButton);
disableButton.setEnabled(true);
} else {
disableButton.setText(ProvUIMessages.RepositoryManipulationPage_EnableButton);
disableButton.setEnabled(false);
}
}
void addRepository() {
AddRepositoryDialog dialog = new AddRepositoryDialog(getShell(), ui) {
protected RepositoryTracker getRepositoryTracker() {
return RepositoryManipulationPage.this.getLocalCacheRepoTracker();
}
};
dialog.setTitle(ProvUIMessages.ColocatedRepositoryManipulator_AddSiteOperationLabel);
dialog.open();
}
void refreshRepository() {
final MetadataRepositoryElement[] selected = getSelectedElements();
final ProvisionException[] fail = new ProvisionException[1];
final boolean[] remove = new boolean[1];
remove[0] = false;
if (selected.length != 1)
return;
final URI location = selected[0].getLocation();
ProgressMonitorDialog dialog = new ProgressMonitorDialog(getShell());
try {
dialog.run(true, true, new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) {
monitor.beginTask(NLS.bind(ProvUIMessages.RepositoryManipulationPage_ContactingSiteMessage, location), 100);
try {
tracker.clearRepositoryNotFound(location);
// If the manager doesn't know this repo, refreshing it will not work.
// We temporarily add it, but we must remove it in case the user cancels out of this page.
if (!includesRepo(tracker.getKnownRepositories(ui.getSession()), location)) {
// Start a batch operation so we can swallow events
remove[0] = true;
ui.signalRepositoryOperationStart();
tracker.addRepository(location, selected[0].getName(), ui.getSession());
}
tracker.refreshRepositories(new URI[] {location}, ui.getSession(), monitor);
} catch (OperationCanceledException e) {
// Catch canceled login attempts
fail[0] = new ProvisionException(new Status(IStatus.CANCEL, ProvUIActivator.PLUGIN_ID, ProvUIMessages.RepositoryManipulationPage_RefreshOperationCanceled, e));
} finally {
// Check if the monitor was canceled
if (fail[0] == null && monitor.isCanceled())
fail[0] = new ProvisionException(new Status(IStatus.CANCEL, ProvUIActivator.PLUGIN_ID, ProvUIMessages.RepositoryManipulationPage_RefreshOperationCanceled));
// If we temporarily added a repo so we could read it, remove it.
if (remove[0]) {
tracker.removeRepositories(new URI[] {location}, ui.getSession());
// stop swallowing events
ui.signalRepositoryOperationComplete(null, false);
}
}
}
});
} catch (InvocationTargetException e) {
// nothing to report
} catch (InterruptedException e) {
// nothing to report
}
if (fail[0] != null) {
// If the repo was not found, tell ProvUI that we will be reporting it.
// We are going to report problems directly to the status manager because we
// do not want the automatic repo location editing to kick in.
if (fail[0].getStatus().getCode() == ProvisionException.REPOSITORY_NOT_FOUND) {
tracker.addNotFound(location);
}
if (!fail[0].getStatus().matches(IStatus.CANCEL)) {
// An error is only shown if the dialog was not canceled
ProvUI.handleException(fail[0], null, StatusManager.SHOW);
}
} else {
// Confirm that it was successful
MessageDialog.openInformation(getShell(), ProvUIMessages.RepositoryManipulationPage_TestConnectionTitle, NLS.bind(ProvUIMessages.RepositoryManipulationPage_TestConnectionSuccess, URIUtil.toUnencodedString(location)));
}
repositoryViewer.update(selected[0], null);
setDetails();
}
boolean includesRepo(URI[] repos, URI repo) {
for (int i = 0; i < repos.length; i++)
if (repos[i].equals(repo))
return true;
return false;
}
void toggleRepositoryEnablement() {
MetadataRepositoryElement[] selected = getSelectedElements();
if (selected.length >= 1) {
boolean enableSites = !toggleMeansDisable(selected);
for (int i = 0; i < selected.length; i++) {
selected[i].setEnabled(enableSites);
input.cachedElements.put(URIUtil.toUnencodedString(selected[i].getLocation()), selected[i]);
}
updateForEnablementChange(selected);
}
validateButtons();
}
void updateForEnablementChange(MetadataRepositoryElement[] updated) {
if (comparator.getSortKey() == RepositoryDetailsLabelProvider.COL_ENABLEMENT)
repositoryViewer.refresh(true);
else
for (int i = 0; i < updated.length; i++)
repositoryViewer.update(updated[i], null);
changed = true;
}
void importRepositories() {
BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
public void run() {
MetadataRepositoryElement[] imported = UpdateManagerCompatibility.importSites(getShell());
if (imported.length > 0) {
Hashtable<String, Object> repos = getInput().cachedElements;
changed = true;
for (int i = 0; i < imported.length; i++)
repos.put(URIUtil.toUnencodedString(imported[i].getLocation()), imported[i]);
safeRefresh(null);
}
}
});
}
void exportRepositories() {
BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
public void run() {
MetadataRepositoryElement[] elements = getSelectedElements();
if (elements.length == 0)
elements = getElements();
UpdateManagerCompatibility.exportSites(getShell(), elements);
}
});
}
void changeRepositoryProperties() {
final MetadataRepositoryElement[] selected = getSelectedElements();
if (selected.length != 1)
return;
RepositoryNameAndLocationDialog dialog = new RepositoryNameAndLocationDialog(getShell(), ui) {
protected String getInitialLocationText() {
return URIUtil.toUnencodedString(selected[0].getLocation());
}
protected String getInitialNameText() {
return selected[0].getName();
}
};
int retCode = dialog.open();
if (retCode == Window.OK) {
selected[0].setNickname(dialog.getName());
selected[0].setLocation(dialog.getLocation());
changed = true;
repositoryViewer.update(selected[0], null);
setDetails();
}
}
void columnSelected(TableColumn tc) {
TableColumn[] cols = table.getColumns();
for (int i = 0; i < cols.length; i++) {
if (cols[i] == tc) {
if (i != comparator.getSortKey()) {
comparator.setSortKey(i);
table.setSortColumn(tc);
comparator.sortAscending();
table.setSortDirection(SWT.UP);
} else {
if (comparator.isAscending()) {
table.setSortDirection(SWT.DOWN);
comparator.sortDescending();
} else {
table.setSortDirection(SWT.UP);
comparator.sortAscending();
}
}
repositoryViewer.refresh();
break;
}
}
}
void safeRefresh(final MetadataRepositoryElement elementToSelect) {
Runnable runnable = new Runnable() {
public void run() {
repositoryViewer.refresh();
if (elementToSelect != null)
repositoryViewer.setSelection(new StructuredSelection(elementToSelect), true);
}
};
if (Display.getCurrent() == null)
display.asyncExec(runnable);
else
runnable.run();
}
void applyFilter() {
String text = pattern.getText();
if (text == DEFAULT_FILTER_TEXT)
text = ""; //$NON-NLS-1$
if (text.length() == 0)
filter.setPattern(null);
else
filter.setPattern(text);
if (filterJob != null)
filterJob.cancel();
filterJob = new WorkbenchJob("filter job") { //$NON-NLS-1$
public IStatus runInUIThread(IProgressMonitor monitor) {
if (monitor.isCanceled())
return Status.CANCEL_STATUS;
if (!repositoryViewer.getTable().isDisposed())
repositoryViewer.refresh();
return Status.OK_STATUS;
}
};
filterJob.setSystem(true);
filterJob.schedule(FILTER_DELAY);
}
void setDetails() {
MetadataRepositoryElement[] selections = getSelectedElements();
if (selections.length == 1) {
details.setText(selections[0].getDescription());
} else {
details.setText(""); //$NON-NLS-1$
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
*/
public void init(IWorkbench workbench) {
noDefaultAndApplyButton();
if (ui == null) {
setProvisioningUI(ProvisioningUI.getDefaultUI());
}
}
void removeRepositories() {
MetadataRepositoryElement[] selections = getSelectedElements();
if (selections.length > 0) {
String message = ProvUIMessages.RepositoryManipulationPage_RemoveConfirmMessage;
if (selections.length == 1)
message = NLS.bind(ProvUIMessages.RepositoryManipulationPage_RemoveConfirmSingleMessage, URIUtil.toUnencodedString(selections[0].getLocation()));
if (MessageDialog.openQuestion(getShell(), ProvUIMessages.RepositoryManipulationPage_RemoveConfirmTitle, message)) {
changed = true;
for (int i = 0; i < selections.length; i++) {
getInput().cachedElements.remove(URIUtil.toUnencodedString(selections[i].getLocation()));
}
safeRefresh(null);
}
}
}
// Return a repo manipulator that only operates on the local cache.
// Labels and other presentation info are used from the original manipulator.
RepositoryTracker getLocalCacheRepoTracker() {
if (localCacheRepoManipulator == null)
localCacheRepoManipulator = new RepositoryTracker() {
public void addRepository(URI location, String nickname, ProvisioningSession session) {
MetadataRepositoryElement element = (MetadataRepositoryElement) getInput().cachedElements.get(URIUtil.toUnencodedString(location));
if (element == null) {
element = new MetadataRepositoryElement(getInput(), location, true);
getInput().cachedElements.put(URIUtil.toUnencodedString(location), element);
}
if (nickname != null)
element.setNickname(nickname);
changed = true;
safeRefresh(element);
}
public URI[] getKnownRepositories(ProvisioningSession session) {
return RepositoryManipulationPage.this.getKnownRepositories();
}
public void removeRepositories(URI[] repoLocations, ProvisioningSession session) {
RepositoryManipulationPage.this.removeRepositories();
}
public void refreshRepositories(URI[] locations, ProvisioningSession session, IProgressMonitor monitor) {
// Nothing to refresh in the local cache
}
};
return localCacheRepoManipulator;
}
/*
* (non-Javadoc)
* @see org.eclipse.equinox.p2.ui.ICopyable#copyToClipboard(org.eclipse.swt.widgets.Control)
*/
public void copyToClipboard(Control activeControl) {
MetadataRepositoryElement[] elements = getSelectedElements();
if (elements.length == 0)
elements = getElements();
String text = ""; //$NON-NLS-1$
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < elements.length; i++) {
buffer.append(labelProvider.getClipboardText(elements[i], CopyUtils.DELIMITER));
if (i > 0)
buffer.append(CopyUtils.NEWLINE);
}
text = buffer.toString();
if (text.length() == 0)
return;
Clipboard clipboard = new Clipboard(PlatformUI.getWorkbench().getDisplay());
clipboard.setContents(new Object[] {text}, new Transfer[] {TextTransfer.getInstance()});
clipboard.dispose();
}
// If more than half of the selected repos are enabled, toggle means disable.
// Otherwise it means enable.
private boolean toggleMeansDisable(MetadataRepositoryElement[] elements) {
double count = 0;
for (int i = 0; i < elements.length; i++)
if (elements[i].isEnabled())
count++;
return (count / elements.length) > 0.5;
}
URI[] getKnownRepositories() {
MetadataRepositoryElement[] elements = getElements();
URI[] locations = new URI[elements.length];
for (int i = 0; i < elements.length; i++)
locations[i] = elements[i].getLocation();
return locations;
}
}