blob: 8452ef07120ef64ece20da1beb0ce19a18965a1c [file] [log] [blame]
package org.eclipse.update.internal.ui.wizards;
import java.lang.reflect.*;
import java.net.*;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.operation.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.*;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.help.*;
import org.eclipse.update.internal.search.*;
import org.eclipse.update.internal.ui.*;
import org.eclipse.update.internal.ui.model.*;
import org.eclipse.update.internal.ui.parts.*;
import org.eclipse.update.internal.core.*;
import org.eclipse.update.operations.*;
import org.eclipse.update.search.*;
public class SitePage extends BannerPage implements ISearchProvider {
class TreeContentProvider
extends DefaultContentProvider
implements ITreeContentProvider {
public Object[] getElements(Object parent) {
return getAllSiteBookmarks();
}
public Object[] getChildren(final Object parent) {
if (parent instanceof SiteBookmark) {
final SiteBookmark bookmark = (SiteBookmark) parent;
if (bookmark.isUnavailable())
return new Object[0];
final Object[] children =
getSiteCatalogWithIndicator(
bookmark,
!bookmark.isSiteConnected());
treeViewer.getControl().getDisplay().asyncExec(new Runnable() {
public void run() {
if (children.length > 0)
handleSiteExpanded(bookmark, children);
}
});
return children;
}
return new Object[0];
}
public Object getParent(Object element) {
if (element instanceof SiteCategory)
return ((SiteCategory) element).getBookmark();
return null;
}
public boolean hasChildren(Object element) {
return (element instanceof SiteBookmark);
}
}
class TreeLabelProvider extends LabelProvider {
public Image getImage(Object obj) {
if (obj instanceof SiteBookmark)
return UpdateUI.getDefault().getLabelProvider().get(
UpdateUIImages.DESC_SITE_OBJ);
if (obj instanceof SiteCategory)
return UpdateUI.getDefault().getLabelProvider().get(
UpdateUIImages.DESC_CATEGORY_OBJ);
return super.getImage(obj);
}
public String getText(Object obj) {
if (obj instanceof SiteBookmark) {
return ((SiteBookmark) obj).getLabel();
}
return super.getText(obj);
}
}
class ModelListener implements IUpdateModelChangedListener {
public void objectChanged(Object object, String property) {
treeViewer.refresh();
checkItems();
}
public void objectsAdded(Object parent, Object[] children) {
treeViewer.refresh();
checkItems();
}
public void objectsRemoved(Object parent, Object[] children) {
treeViewer.refresh();
checkItems();
}
}
private static DiscoveryFolder discoveryFolder = new DiscoveryFolder();
private CheckboxTreeViewer treeViewer;
private Button addSiteButton;
private Button addLocalButton;
private Button addLocalZippedButton;
private Button editButton;
private Button removeButton;
private Button envFilterCheck;
private SearchRunner searchRunner;
private EnvironmentFilter envFilter;
private UpdateSearchRequest searchRequest;
private ModelListener modelListener;
public SitePage(SearchRunner searchRunner) {
super("SitePage"); //$NON-NLS-1$
setTitle(UpdateUI.getString("SitePage.title")); //$NON-NLS-1$
setDescription(UpdateUI.getString("SitePage.desc")); //$NON-NLS-1$
UpdateUI.getDefault().getLabelProvider().connect(this);
searchRequest =
new UpdateSearchRequest(
new SiteSearchCategory(),
new UpdateSearchScope());
searchRequest.addFilter(new BackLevelFilter());
envFilter = new EnvironmentFilter();
this.searchRunner = searchRunner;
modelListener = new ModelListener();
UpdateUI.getDefault().getUpdateModel().addUpdateModelChangedListener(
modelListener);
}
private void toggleEnvFilter(boolean add) {
if (add)
searchRequest.addFilter(envFilter);
else
searchRequest.removeFilter(envFilter);
searchRunner.setNewSearchNeeded(true);
}
public void dispose() {
UpdateUI.getDefault().getLabelProvider().disconnect(this);
UpdateUI
.getDefault()
.getUpdateModel()
.removeUpdateModelChangedListener(
modelListener);
super.dispose();
}
/*
* (non-Javadoc) @see
* org.eclipse.update.internal.ui.wizards.BannerPage#createContents(org.eclipse.swt.widgets.Composite)
*/
protected Control createContents(Composite parent) {
Composite client = new Composite(parent, SWT.NULL);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
client.setLayout(layout);
Label label = new Label(client, SWT.NULL);
label.setText(UpdateUI.getString("SitePage.label")); //$NON-NLS-1$
GridData gd = new GridData();
gd.horizontalSpan = 2;
label.setLayoutData(gd);
createTreeViewer(client);
Composite buttonContainer = new Composite(client, SWT.NULL);
buttonContainer.setLayoutData(new GridData(GridData.FILL_VERTICAL));
layout = new GridLayout();
layout.marginWidth = 0;
layout.marginHeight = 0;
buttonContainer.setLayout(layout);
addSiteButton = new Button(buttonContainer, SWT.PUSH);
addSiteButton.setText(UpdateUI.getString("SitePage.addUpdateSite")); //$NON-NLS-1$
addSiteButton.setLayoutData(
new GridData(GridData.HORIZONTAL_ALIGN_FILL));
SWTUtil.setButtonDimensionHint(addSiteButton);
addSiteButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
handleAddSite();
}
});
addLocalButton = new Button(buttonContainer, SWT.PUSH);
addLocalButton.setText(UpdateUI.getString("SitePage.addLocalSite")); //$NON-NLS-1$
addLocalButton.setLayoutData(
new GridData(GridData.HORIZONTAL_ALIGN_FILL));
SWTUtil.setButtonDimensionHint(addLocalButton);
addLocalButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
handleAddLocal();
}
});
addLocalZippedButton = new Button(buttonContainer, SWT.PUSH);
addLocalZippedButton.setText(UpdateUI.getString("SitePage.addLocalZippedSite")); //$NON-NLS-1$
addLocalZippedButton.setLayoutData(
new GridData(GridData.HORIZONTAL_ALIGN_FILL));
SWTUtil.setButtonDimensionHint(addLocalZippedButton);
addLocalZippedButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
handleAddLocalZipped();
}
});
editButton = new Button(buttonContainer, SWT.PUSH);
editButton.setText(UpdateUI.getString("SitePage.edit")); //$NON-NLS-1$
editButton.setEnabled(false);
editButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
SWTUtil.setButtonDimensionHint(editButton);
editButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
handleEdit();
}
});
removeButton = new Button(buttonContainer, SWT.PUSH);
removeButton.setText(UpdateUI.getString("SitePage.remove")); //$NON-NLS-1$
removeButton.setEnabled(false);
removeButton.setLayoutData(
new GridData(GridData.HORIZONTAL_ALIGN_FILL));
SWTUtil.setButtonDimensionHint(removeButton);
removeButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
handleRemove();
}
});
envFilterCheck = new Button(client, SWT.CHECK);
envFilterCheck.setText(UpdateUI.getString("SitePage.ignore")); //$NON-NLS-1$
envFilterCheck.setSelection(true);
toggleEnvFilter(true);
envFilterCheck.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
toggleEnvFilter(envFilterCheck.getSelection());
}
});
gd = new GridData();
gd.horizontalSpan = 2;
envFilterCheck.setLayoutData(gd);
Dialog.applyDialogFont(parent);
WorkbenchHelp.setHelp(client, "org.eclipse.update.ui.SitePage"); //$NON-NLS-1$
return client;
}
private void createTreeViewer(Composite parent) {
treeViewer =
new CheckboxTreeViewer(
parent,
SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
treeViewer.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
treeViewer.setContentProvider(new TreeContentProvider());
treeViewer.setLabelProvider(new TreeLabelProvider());
treeViewer.setInput(UpdateUI.getDefault().getUpdateModel());
initializeItems();
treeViewer.addCheckStateListener(new ICheckStateListener() {
public void checkStateChanged(CheckStateChangedEvent e) {
Object element = e.getElement();
if (element instanceof SiteBookmark)
handleSiteChecked((SiteBookmark) element, e.getChecked());
else if (element instanceof SiteCategory) {
handleCategoryChecked(
(SiteCategory) element,
e.getChecked());
}
}
});
treeViewer
.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent e) {
handleSelectionChanged((IStructuredSelection) e.getSelection());
}
});
// treeViewer.addFilter(new ViewerFilter() {
// public boolean select(
// Viewer viewer,
// Object parentElement,
// Object element) {
// if (element instanceof SiteBookmark)
// return !((SiteBookmark) element).isWebBookmark();
// return true;
// }
// });
}
private void initializeItems() {
checkItems();
updateSearchRequest();
}
private void checkItems() {
TreeItem[] items = treeViewer.getTree().getItems();
for (int i = 0; i < items.length; i++) {
SiteBookmark bookmark = (SiteBookmark) items[i].getData();
treeViewer.setChecked(bookmark, bookmark.isSelected());
String[] ignoredCats = bookmark.getIgnoredCategories();
treeViewer.setGrayed(bookmark, ignoredCats.length > 0
&& bookmark.isSelected());
}
}
private void handleAddSite() {
NewUpdateSiteDialog dialog = new NewUpdateSiteDialog(getShell());
dialog.create();
dialog.getShell().setText(UpdateUI.getString("SitePage.new")); //$NON-NLS-1$
if (dialog.open() == NewUpdateSiteDialog.OK)
updateSearchRequest();
}
private void handleAddLocal() {
SiteBookmark siteBookmark = LocalSiteSelector.getLocaLSite(getShell());
if (siteBookmark != null) {
UpdateModel model = UpdateUI.getDefault().getUpdateModel();
model.addBookmark(siteBookmark);
model.saveBookmarks();
updateSearchRequest();
}
return;
}
private void handleAddLocalZipped() {
SiteBookmark siteBookmark =
LocalSiteSelector.getLocaLZippedSite(getShell());
if (siteBookmark != null) {
UpdateModel model = UpdateUI.getDefault().getUpdateModel();
model.addBookmark(siteBookmark);
model.saveBookmarks();
updateSearchRequest();
}
return;
}
private void handleRemove() {
BusyIndicator
.showWhile(treeViewer.getControl().getDisplay(), new Runnable() {
public void run() {
UpdateModel updateModel =
UpdateUI.getDefault().getUpdateModel();
IStructuredSelection ssel =
(IStructuredSelection) treeViewer.getSelection();
SiteBookmark bookmark = (SiteBookmark) ssel.getFirstElement();
if (!bookmark.isReadOnly()) {
updateModel.removeBookmark(bookmark);
updateSearchRequest();
}
}
});
}
private void handleEdit() {
IStructuredSelection ssel =
(IStructuredSelection) treeViewer.getSelection();
SiteBookmark bookmark = (SiteBookmark) ssel.getFirstElement();
URL oldURL = bookmark.getURL();
EditSiteDialog dialog = new EditSiteDialog(getShell(), bookmark);
dialog.create();
String title = bookmark.isLocal() ? UpdateUI.getString("SitePage.dialogEditLocal") : UpdateUI.getString("SitePage.dialogEditUpdateSite"); //$NON-NLS-1$ //$NON-NLS-2$
// //$NON-NLS-2$
dialog.getShell().setText(title);
if (dialog.open() == EditSiteDialog.OK ) {
URL newURL = bookmark.getURL();
if (!UpdateManagerUtils.sameURL(oldURL, newURL)) {
UpdateModel model = UpdateUI.getDefault().getUpdateModel();
model.fireObjectChanged(bookmark, null);
updateSearchRequest();
}
}
}
private void handleSiteChecked(SiteBookmark bookmark, boolean checked) {
if (bookmark.isUnavailable()) {
bookmark.setSelected(false);
treeViewer.setChecked(bookmark, false);
return;
}
bookmark.setSelected(checked);
if (checked)
bookmark.setIgnoredCategories(new String[0]);
if (checked || bookmark.isSiteConnected())
treeViewer.setSubtreeChecked(bookmark, checked);
// at this point, we may realize the site is not available
if (bookmark.isUnavailable()) {
treeViewer.setChecked(bookmark, false);
return;
}
treeViewer.setGrayed(bookmark, false);
updateSearchRequest();
}
private void handleSiteExpanded(SiteBookmark bookmark, Object[] cats) {
if (!bookmark.isSelected()) {
treeViewer.setSubtreeChecked(bookmark, false);
ArrayList result = new ArrayList();
for (int i = 0; i < cats.length; i++) {
if (cats[i] instanceof SiteCategory) {
result.add(((SiteCategory) cats[i]).getFullName());
}
}
bookmark.setIgnoredCategories(
(String[]) result.toArray(new String[result.size()]));
} else {
String[] ignored = bookmark.getIgnoredCategories();
HashSet imap = new HashSet();
for (int i = 0; i < ignored.length; i++) {
imap.add(ignored[i]);
}
for (int i = 0; i < cats.length; i++) {
if (cats[i] instanceof SiteCategory) {
SiteCategory category = (SiteCategory) cats[i];
treeViewer.setChecked(
category,
!imap.contains(category.getFullName()));
}
}
treeViewer.setGrayed(
bookmark,
ignored.length > 0 && ignored.length < cats.length);
}
searchRunner.setNewSearchNeeded(true);
}
private void handleCategoryChecked(
SiteCategory category,
boolean checked) {
SiteBookmark bookmark = category.getBookmark();
ArrayList array = new ArrayList();
if (bookmark.isSelected()) {
String[] ignored = bookmark.getIgnoredCategories();
for (int i = 0; i < ignored.length; i++)
array.add(ignored[i]);
} else {
Object[] categs =
getSiteCatalogWithIndicator(bookmark, !bookmark.isSiteConnected());
for (int i=0; i<categs.length; i++)
array.add(((SiteCategory)categs[i]).getFullName());
}
if (checked) {
array.remove(category.getFullName());
} else {
array.add(category.getFullName());
}
bookmark.setIgnoredCategories(
(String[]) array.toArray(new String[array.size()]));
searchRunner.setNewSearchNeeded(true);
Object[] children = ((TreeContentProvider) treeViewer.getContentProvider())
.getChildren(category.getBookmark());
treeViewer.setChecked(bookmark, array.size() < children.length);
bookmark.setSelected(array.size() < children.length);
treeViewer.setGrayed(
bookmark,
array.size() > 0 && array.size() < children.length);
updateSearchRequest();
}
private void handleSelectionChanged(IStructuredSelection ssel) {
boolean enable = false;
Object item = ssel.getFirstElement();
if (item instanceof SiteBookmark) {
enable = !((SiteBookmark) item).isReadOnly();
}
editButton.setEnabled(enable);
removeButton.setEnabled(enable);
}
private void updateSearchRequest() {
Object[] checked = treeViewer.getCheckedElements();
UpdateSearchScope scope = new UpdateSearchScope();
int nsites = 0;
for (int i = 0; i < checked.length; i++) {
if (checked[i] instanceof SiteBookmark) {
SiteBookmark bookmark = (SiteBookmark) checked[i];
scope.addSearchSite(
bookmark.getLabel(),
bookmark.getURL(),
bookmark.getIgnoredCategories());
nsites++;
}
}
searchRequest.setScope(scope);
searchRunner.setNewSearchNeeded(true);
setPageComplete(nsites > 0);
}
public UpdateSearchRequest getSearchRequest() {
return searchRequest;
}
public void setVisible(boolean value) {
super.setVisible(value);
if (value) {
searchRunner.setSearchProvider(this);
// Reset all unavailable sites, so they can be tried again if the user wants it
SiteBookmark[] bookmarks = getAllSiteBookmarks();
for (int i=0; i<bookmarks.length; i++) {
if (bookmarks[i].isUnavailable())
bookmarks[i].setUnavailable(false);
}
}
}
class CatalogBag {
Object[] catalog;
}
private Object[] getSiteCatalogWithIndicator(
final SiteBookmark bookmark,
final boolean connect) {
final CatalogBag bag = new CatalogBag();
if (bookmark.isUnavailable())
return new Object[0];
IRunnableWithProgress op = new IRunnableWithProgress() {
public void run(IProgressMonitor monitor)
throws InvocationTargetException {
try {
monitor.beginTask("", 3); //$NON-NLS-1$
monitor.worked(1);
if (connect)
bookmark.connect(new SubProgressMonitor(monitor, 1));
else
monitor.worked(1);
bag.catalog =
bookmark.getCatalog(
true,
new SubProgressMonitor(monitor, 1));
} catch (CoreException e) {
throw new InvocationTargetException(e);
} finally {
monitor.done();
}
}
};
try {
getContainer().run(true, true, op);
} catch (InvocationTargetException e) {
UpdateUI.logException(e);
} catch (InterruptedException e) {
}
return (bag.catalog == null) ? new Object[0] : bag.catalog;
}
private SiteBookmark[] getAllSiteBookmarks() {
UpdateModel model = UpdateUI.getDefault().getUpdateModel();
Object[] bookmarks = model.getBookmarkLeafs();
Object[] sitesToVisit =
discoveryFolder.getChildren(discoveryFolder);
SiteBookmark[] all = new SiteBookmark[bookmarks.length + sitesToVisit.length];
System.arraycopy(bookmarks, 0, all, 0, bookmarks.length);
System.arraycopy(
sitesToVisit,
0,
all,
bookmarks.length,
sitesToVisit.length);
return all;
}
}