blob: e84ae8a59013df4fad2ec38fcb054760cfcd4ec5 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2012, 2019 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.internal.r.ui.pkgmanager;
import static org.eclipse.statet.internal.r.ui.pkgmanager.RPkgManagerDialog.NO_INPUT;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.ibm.icu.text.DateFormat;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler2;
import org.eclipse.core.databinding.observable.set.IObservableSet;
import org.eclipse.core.databinding.observable.set.WritableSet;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.databinding.viewers.typed.ViewerProperties;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.ICheckable;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IElementComparer;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.menus.CommandContributionItemParameter;
import org.eclipse.statet.ecommons.databinding.jface.DataBindingSupport;
import org.eclipse.statet.ecommons.ui.actions.HandlerContributionItem;
import org.eclipse.statet.ecommons.ui.components.DropDownButton;
import org.eclipse.statet.ecommons.ui.components.History;
import org.eclipse.statet.ecommons.ui.components.SearchText;
import org.eclipse.statet.ecommons.ui.content.IElementFilter;
import org.eclipse.statet.ecommons.ui.content.ObservableSetBinding;
import org.eclipse.statet.ecommons.ui.content.SearchTextBinding;
import org.eclipse.statet.ecommons.ui.content.SetElementFilter;
import org.eclipse.statet.ecommons.ui.content.TableFilterController;
import org.eclipse.statet.ecommons.ui.content.TextElementFilter;
import org.eclipse.statet.ecommons.ui.util.AutoCheckController;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.util.NestedServices;
import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils.CheckboxTableComposite;
import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils.TableComposite;
import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils.TreeComposite;
import org.eclipse.statet.ecommons.ui.workbench.ContextHandlers;
import org.eclipse.statet.r.core.pkgmanager.IRPkgData;
import org.eclipse.statet.r.core.pkgmanager.IRPkgInfo;
import org.eclipse.statet.r.core.pkgmanager.IRPkgInfoAndData;
import org.eclipse.statet.r.core.pkgmanager.IRPkgManager;
import org.eclipse.statet.r.core.pkgmanager.IRPkgSet;
import org.eclipse.statet.r.core.pkgmanager.IRView;
import org.eclipse.statet.r.core.pkgmanager.RPkgAction;
import org.eclipse.statet.r.core.pkgmanager.RPkgResolver;
import org.eclipse.statet.r.core.pkgmanager.RPkgUtils;
import org.eclipse.statet.r.core.pkgmanager.RRepo;
import org.eclipse.statet.r.ui.REnvLabelProvider;
import org.eclipse.statet.r.ui.RUI;
import org.eclipse.statet.rj.renv.core.RLibLocation;
import org.eclipse.statet.rj.renv.core.RPkg;
import org.eclipse.statet.rj.renv.core.RPkgList;
import org.eclipse.statet.rj.renv.runtime.RLibLocationInfo;
public class PkgTab extends Composite {
private static final int VERSION_CHARS= 8;
private static final int AVAIL= 0;
private static final int INST= 1;
private class InstalledFilter implements IElementFilter, SelectionListener {
private static final int INSTALLED= 0x1;
private static final int NOT_INSTALLED= 0x2;
private class Final implements IFinalFilter {
private final int state;
public Final(final int state) {
this.state= state;
}
@Override
public boolean select(final Object element) {
final boolean installed= PkgTab.this.pkgSet.getInstalled().contains((String) element);
if ((this.state & INSTALLED) != 0) {
return installed;
}
else {
return !installed;
}
}
@Override
public boolean isSubOf(final IFinalFilter other) {
return (other == this|| other == null || ((other instanceof Final)
&& this.state == ((Final) other).state ));
}
@Override
public boolean isEqualTo(final IFinalFilter other) {
return (other == this || ((other instanceof Final)
&& this.state == ((Final) other).state ));
}
}
private volatile int state;
private Final filter;
public InstalledFilter() {
PkgTab.this.filterInstButton.addSelectionListener(this);
PkgTab.this.filterNotInstButton.addSelectionListener(this);
}
@Override
public void widgetSelected(final SelectionEvent e) {
if (e.getSource() == PkgTab.this.filterInstButton) {
PkgTab.this.filterNotInstButton.setSelection(false);
}
else if (e.getSource() == PkgTab.this.filterNotInstButton) {
PkgTab.this.filterInstButton.setSelection(false);
}
int state;
if (PkgTab.this.filterInstButton.getSelection()) {
state= INSTALLED;
}
else if (PkgTab.this.filterNotInstButton.getSelection()) {
state= NOT_INSTALLED;
}
else {
state= 0;
}
if (this.state != state) {
this.state= state;
PkgTab.this.filterController.refresh(true);
}
}
@Override
public IFinalFilter getFinal(final boolean newData) {
final int state= this.state;
if (state == 0) {
this.filter= null;
}
else if (this.filter == null || this.filter.state != state) {
this.filter= new Final(state);
}
return this.filter;
}
@Override
public void widgetDefaultSelected(final SelectionEvent e) {
}
}
private final RPkgManagerDialog dialog;
private final IRPkgManager.Ext rPkgManager;
private final TabItem tab;
private IRPkgSet.Ext pkgSet;
private String selectedPkgName;
private int selectedPkgVersionGroup;
private IRPkgData selectedPkgVersion;
private final Map<String, String> selectedPkgVersions= new HashMap<>();
private SearchText filterText;
private Button filterInstButton;
private Button filterNotInstButton;
private CheckboxTableViewer filterPriorityTable;
private IObservableSet<String> filterPrioritySet;
private StackLayout filterViewsStack;
private Link filterViewsMessage;
private CheckboxTableViewer filterRViewsTable;
private IObservableSet<IRView> filterRViewsSet;
private TableFilterController filterController;
private TableComposite pkgTable;
private NestedServices serviceLocator;
private ContextHandlers handlers;
private final History<String> pkgHistory= new org.eclipse.statet.ecommons.ui.components.History<String>() {
@Override
protected void select(final String entry) {
showPkg(entry);
};
};
private ToolBarManager toolBar;
private TreeComposite detailTable;
private Label detailLicense;
private TreeViewer detailDepTable;
private TreeViewer detailRevTable;
private Button installButton;
private DropDownButton updateButton;
private Button uninstallButton;
private Button loadButton;
PkgTab(final RPkgManagerDialog dialog, final TabItem tab, final Composite parent,
final IRPkgManager.Ext rPkgManager) {
super(parent, SWT.NONE);
this.dialog= dialog;
this.tab= tab;
this.rPkgManager= rPkgManager;
setLayout(LayoutUtils.newTabGrid(3));
createContent(this);
updateButtons();
this.tab.addDisposeListener((final DisposeEvent e) -> {
if (this.handlers != null) {
this.handlers.dispose();
this.handlers= null;
}
});
}
private void createContent(final Composite parent) {
final Composite filterCol= createFilter(parent);
filterCol.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
final Composite tableCol= createTable(parent);
tableCol.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
final Composite detailCol= createDetail(parent);
detailCol.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
}
private Composite createFilter(final Composite parent) {
final Group composite= new Group(parent, SWT.NONE);
composite.setLayout(LayoutUtils.newGroupGrid(1));
composite.setText("Filter");
{ final SearchText text= new SearchText(composite, "", SWT.BORDER | SWT.ICON_SEARCH); //$NON-NLS-1$
text.setMessage("Name");
final GridData gd= new GridData(SWT.FILL, SWT.CENTER, true, false);
gd.widthHint= LayoutUtils.hintWidth(text.getTextControl(), 20);
text.setLayoutData(gd);
this.filterText= text;
}
{
// Label label= new Label(composite, SWT.NONE);
// label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
// label.setText("State:");
LayoutUtils.addSmallFiller(composite, false);
{ final Button button= new Button(composite, SWT.CHECK);
this.filterInstButton= button;
button.setText("Installed");
button.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
}
// { Button button= new Button(composite, SWT.CHECK);
// fPkgFilterInstUptButton= button;
// button.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
// button.setText("With Update");
// }
{ final Button button= new Button(composite, SWT.CHECK);
this.filterNotInstButton= button;
button.setText("Not Installed");
button.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
}
}
{ final Label label= new Label(composite, SWT.NONE);
label.setText("Priorities:");
label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
final CheckboxTableViewer viewer= new CheckboxTableViewer(new Table(composite,
SWT.CHECK | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION | SWT.NO_SCROLL ));
this.filterPriorityTable= viewer;
viewer.setContentProvider(new ArrayContentProvider());
viewer.setLabelProvider(new LabelProvider());
final GridData gd= new GridData(SWT.FILL, SWT.FILL, true, false);
gd.heightHint= LayoutUtils.hintHeight(viewer.getTable(),
IRPkgSet.Ext.DEFAULT_PRIORITIES.size(), false );
viewer.getControl().setLayoutData(gd);
}
{ final Label label= new Label(composite, SWT.NONE);
label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
label.setText("Task Views:");
final Composite views= new Composite(composite, SWT.NONE);
final GridData gd= new GridData(SWT.FILL, SWT.FILL, true, true);
views.setLayoutData(gd);
this.filterViewsStack= new StackLayout();
views.setLayout(this.filterViewsStack);
final Link link= new Link(views, SWT.MULTI);
this.filterViewsMessage= link;
link.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
showPkg(e.text);
}
});
link.setText("");
final CheckboxTableComposite table= new CheckboxTableComposite(views,
SWT.CHECK | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION );
this.filterRViewsTable= table.viewer;
table.viewer.setContentProvider(new ArrayContentProvider());
ColumnViewerToolTipSupport.enableFor(table.viewer, ToolTip.NO_RECREATE);
final TableViewerColumn column= table.addColumn("", SWT.LEFT, new ColumnWeightData(100, false));
column.setLabelProvider(new RViewLabelProvider());
gd.widthHint= LayoutUtils.hintWidth(table.table, 20);
this.filterViewsStack.topControl= table;
}
return composite;
}
private Composite createTable(final Composite parent) {
final Composite composite= new Composite(parent, SWT.NONE);
composite.setLayout(LayoutUtils.newCompositeGrid(2));
{ final Label label= new Label(composite, SWT.NONE);
label.setText("Packages:");
label.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false));
}
{ this.toolBar= new ToolBarManager(SWT.HORIZONTAL | SWT.FLAT);
final ToolBar toolBar= this.toolBar.createControl(composite);
toolBar.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false));
}
final TableComposite viewer= new TableComposite(composite,
SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION | SWT.VIRTUAL);
this.pkgTable= viewer;
viewer.viewer.setUseHashlookup(true);
{ final GridData gd= new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1);
gd.heightHint= LayoutUtils.hintHeight(viewer.table, 15);
gd.widthHint= this.dialog.hintWidthInChars(40);
viewer.setLayoutData(gd);
}
ColumnViewerToolTipSupport.enableFor(viewer.viewer, ToolTip.NO_RECREATE);
{
final TableViewerColumn column= viewer.addColumn("Name", SWT.LEFT,
new ColumnWeightData(50));
column.setLabelProvider(new CellLabelProvider() {
@Override
public void update(final ViewerCell cell) {
final String name= (String) cell.getElement();
cell.setImage(RUI.getImage((PkgTab.this.pkgSet.getInstalled().contains(name)) ?
RUI.IMG_OBJ_R_PACKAGE : RUI.IMG_OBJ_R_PACKAGE_NA));
cell.setText(name);
}
@Override
public String getToolTipText(final Object element) {
final String name= (String) element;
final IRPkgInfoAndData v= PkgTab.this.pkgSet.getInstalled().getFirst(name);
if (v != null) {
return v.getTitle();
}
return null;
}
});
}
return composite;
}
private Composite createDetail(final Composite parent) {
final Composite composite= new Composite(parent, SWT.NONE);
composite.setLayout(LayoutUtils.newCompositeGrid(2));
createDetailTable(composite);
createDetailButtons(composite);
createDetailInfo(composite);
return composite;
}
private void createDetailTable(final Composite parent) {
{ final Label label= new Label(parent, SWT.NONE);
label.setText("&Versions:");
label.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false));
}
{ // for layout
final Label label= new Label(parent, SWT.NONE);
final GridData gd= new GridData(SWT.FILL, SWT.FILL, false, false);
gd.heightHint= this.toolBar.getControl().computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
label.setLayoutData(gd);
}
final TreeComposite composite= new TreeComposite(parent,
SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION);
this.detailTable= composite;
{ final GridData gd= new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
gd.heightHint= LayoutUtils.hintHeight(composite.tree, 6);
gd.widthHint= this.dialog.hintWidthInChars(40);
composite.setLayoutData(gd);
}
composite.viewer.setContentProvider(new DetailGroup.ContentProvider(2) {
{ this.groups[AVAIL]= new DetailGroup(AVAIL, "Available");
this.groups[INST]= new DetailGroup(INST, "Installed");
}
@Override
public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) {
if (newInput instanceof String) {
final String name= (String) newInput;
this.groups[AVAIL].setList(PkgTab.this.pkgSet.getAvailable().get(name));
this.groups[INST].setList(PkgTab.this.pkgSet.getInstalled().get(name));
}
else {
this.groups[AVAIL].clearList();
this.groups[INST].clearList();
}
}
});
composite.viewer.setComparer(new IElementComparer() {
@Override
public int hashCode(final Object element) {
if (element instanceof IRPkgData) {
return element.hashCode() + ((IRPkgData) element).getRepoId().hashCode();
}
return element.hashCode();
}
@Override
public boolean equals(final Object a, final Object b) {
if (a == b) {
return true;
}
if (!a.equals(b)) {
return false;
}
if (a instanceof IRPkgData) {
return ((IRPkgData) a).getRepoId().equals(((IRPkgData) b).getRepoId());
}
return false;
}
});
composite.viewer.setAutoExpandLevel(TreeViewer.ALL_LEVELS);
{ final TreeViewerColumn column= composite.addColumn("Repository/Library", SWT.LEFT,
new ColumnWeightData(50, this.dialog.hintWidthInChars(20), true));
column.setLabelProvider(new CellLabelProvider() {
@Override
public void update(final ViewerCell cell) {
final Object element= cell.getElement();
if (element instanceof DetailGroup) {
cell.setText(((DetailGroup) element).getLabel());
return;
}
else if (element instanceof IRPkgInfo) {
final RLibLocation location= ((IRPkgInfo) element).getLibLocation();
cell.setText(REnvLabelProvider.getSafeLabel(location));
return;
}
else if (element instanceof IRPkgData) {
final IRPkgData pkg= (IRPkgData) element;
if (pkg.getRepoId() != null) {
final RRepo repo= RPkgUtils.getRepoById(
PkgTab.this.dialog.getRepoTab().getAvailableRepos(), pkg.getRepoId());
if (repo != null) {
cell.setText(repo.getName());
return;
}
}
cell.setText("-");
return;
}
throw new IllegalStateException();
}
});
}
{ final TreeViewerColumn column= composite.addColumn("Version", SWT.LEFT,
new ColumnPixelData(this.dialog.hintWidthInChars(VERSION_CHARS), true, true) );
column.setLabelProvider(new CellLabelProvider() {
@Override
public void update(final ViewerCell cell) {
final Object element= cell.getElement();
if (element instanceof IRPkgData) {
cell.setText(((IRPkgData) element).getVersion().toString());
return;
}
cell.setText(""); //$NON-NLS-1$
}
@Override
public String getToolTipText(final Object element) {
return (element instanceof IRPkgData) ? getDetailToolTipText((IRPkgData) element) : null;
}
});
}
ColumnViewerToolTipSupport.enableFor(composite.viewer);
composite.viewer.setInput(RPkgManagerDialog.NO_INPUT);
}
private String getDetailToolTipText(final IRPkgData pkgData) {
final StringBuilder sb= new StringBuilder(pkgData.getName());
sb.append("\nVersion: ").append(pkgData.getVersion());
if (pkgData instanceof IRPkgInfoAndData) {
final IRPkgInfoAndData pkgDescr= (IRPkgInfoAndData) pkgData;
sb.append("\nBuilt: ").append(((IRPkgInfoAndData) pkgData).getBuilt());
sb.append("\nInstalled: ").append((pkgDescr.getInstallStamp() != 0) ?
DateFormat.getDateTimeInstance().format(pkgDescr.getInstallStamp()) : "-" );
final RRepo repo= this.rPkgManager.getRepo(pkgDescr.getRepoId());
if (repo != null) {
sb.append("\nFrom: ").append(repo.getName());
}
}
return sb.toString();
}
private void createDetailButtons(final Composite parent) {
final Composite composite= new Composite(parent, SWT.NONE);
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
composite.setLayout(LayoutUtils.newCompositeGrid(1));
{ final Button button= new Button(composite, SWT.PUSH);
this.installButton= button;
button.setText("Install...");
button.setLayoutData(LayoutUtils.createGD(button));
}
{ final SelectionListener defaultUpdate= new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
doUpdateLatest();
}
};
final DropDownButton button= new DropDownButton(composite);
final Menu menu= button.getDropDownMenu();
{ final MenuItem item= new MenuItem(menu, SWT.PUSH);
item.setText("&Update (default)...");
item.addSelectionListener(defaultUpdate);
}
{ final MenuItem item= new MenuItem(menu, SWT.PUSH);
item.setText("&Reinstall...");
item.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
doReinstall(null);
}
});
}
this.updateButton= button;
button.setText("Update...");
button.addSelectionListener(defaultUpdate);
button.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
}
{ final Button button= new Button(composite, SWT.PUSH);
this.uninstallButton= button;
button.setText("Uninstall");
button.setLayoutData(LayoutUtils.createGD(button));
}
LayoutUtils.addSmallFiller(composite, false);
{ final Button button= new Button(composite, SWT.PUSH);
this.loadButton= button;
button.setText("Load");
button.setLayoutData(LayoutUtils.createGD(button));
}
final SelectionListener listener= new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
if (e.getSource() == PkgTab.this.installButton) {
doInstall();
}
else if (e.getSource() == PkgTab.this.updateButton) {
doUpdateLatest();
}
else if (e.getSource() == PkgTab.this.uninstallButton) {
doUninstall();
}
else if (e.getSource() == PkgTab.this.loadButton) {
doLoad();
}
}
};
this.installButton.addSelectionListener(listener);
this.uninstallButton.addSelectionListener(listener);
this.updateButton.addSelectionListener(listener);
this.loadButton.addSelectionListener(listener);
}
private void createDetailInfo(final Composite parent) {
final Group info= new Group(parent, SWT.NONE);
info.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
info.setLayout(LayoutUtils.newGroupGrid(2, true));
info.setText("Info:");
{ final Composite properties= new Composite(info, SWT.NONE);
properties.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
properties.setLayout(LayoutUtils.newCompositeGrid(2));
final Label label= new Label(properties, SWT.NONE);
label.setText("License:");
label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
this.detailLicense= new Label(properties, SWT.NONE);
this.detailLicense.setText(" ");
this.detailLicense.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
}
{ final Composite col= new Composite(info, SWT.NONE);
col.setLayout(LayoutUtils.newCompositeGrid(1));
createDetailRef(col, 0);
col.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
}
{ final Composite col= new Composite(info, SWT.NONE);
col.setLayout(LayoutUtils.newCompositeGrid(1));
createDetailRef(col, 1);
col.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
}
}
private void createDetailRef(final Composite parent, final int type) {
{ final Label label= new Label(parent, SWT.NONE);
label.setText((type == 0) ? "Dependencies:" : "Reverse:");
label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
}
final TreeViewer viewer= new TreeViewer(parent, (SWT.BORDER | SWT.SINGLE) );
if (type == 0) {
this.detailDepTable= viewer;
}
else {
this.detailRevTable= viewer;
}
{ final GridData gd= new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
gd.heightHint= LayoutUtils.hintHeight(viewer.getTree(), 12);
gd.widthHint= this.dialog.hintWidthInChars(20);
viewer.getControl().setLayoutData(gd);
}
viewer.setContentProvider(new DetailGroup.ContentProvider(5) {
private static final int DEPENDS= 0;
private static final int IMPORTS= 1;
private static final int LINKINGTO= 2;
private static final int SUGGESTS= 3;
private static final int ENHANCES= 4;
{ this.groups[DEPENDS]= new DetailGroup(0, "Depends");
this.groups[IMPORTS]= new DetailGroup(1, "Imports");
this.groups[LINKINGTO]= new DetailGroup(2, "Linking To");
this.groups[SUGGESTS]= new DetailGroup(3, "Suggests");
this.groups[ENHANCES]= new DetailGroup(4, "Enhances");
}
@Override
public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) {
if (newInput instanceof IRPkgData) {
final IRPkgData pkg= (IRPkgData) newInput;
this.groups[DEPENDS].setList(pkg.getDepends());
this.groups[IMPORTS].setList(pkg.getImports());
this.groups[LINKINGTO].setList(pkg.getLinkingTo());
this.groups[SUGGESTS].setList(pkg.getSuggests());
this.groups[ENHANCES].setList(pkg.getEnhances());
}
else {
this.groups[DEPENDS].clearList();
this.groups[IMPORTS].clearList();
this.groups[LINKINGTO].clearList();
this.groups[SUGGESTS].clearList();
this.groups[ENHANCES].clearList();
}
}
});
viewer.setAutoExpandLevel(TreeViewer.ALL_LEVELS);
viewer.setLabelProvider(new StyledCellLabelProvider() {
@Override
public void update(final ViewerCell cell) {
final Object element= cell.getElement();
if (element instanceof DetailGroup) {
cell.setText(((DetailGroup) element).getLabel());
cell.setStyleRanges(null);
return;
}
else if (element instanceof RPkg) {
final RPkg pkg= (RPkg) element;
final StyledString text= new StyledString();
text.append(pkg.getName());
final String version= pkg.getVersion().toString();
if (!version.isEmpty()) {
text.append(" (", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
text.append(version, StyledString.QUALIFIER_STYLER);
text.append(")", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
}
cell.setText(text.getString());
cell.setStyleRanges(text.getStyleRanges());
return;
}
throw new IllegalStateException();
}
});
viewer.setInput(NO_INPUT);
viewer.addDoubleClickListener(new IDoubleClickListener() {
@Override
public void doubleClick(final DoubleClickEvent event) {
final Object element= ((IStructuredSelection) event.getSelection()).getFirstElement();
if (element instanceof RPkg) {
showPkg(((RPkg) element).getName());
}
}
});
}
void createActions() {
this.serviceLocator= new NestedServices(this.dialog.getServiceLocator(), "Tab");
this.serviceLocator.bindTo(this);
this.handlers= new ContextHandlers(this.serviceLocator.getLocator().getService(IHandlerService.class));
{ final IHandler2 handler= new AbstractHandler() {
@Override
public void setEnabled(final Object evaluationContext) {
final IStatus status= PkgTab.this.dialog.getStatus();
setBaseEnabled(status != null && status.isOK());
}
@Override
public Object execute(final ExecutionEvent event) throws ExecutionException {
final IStatus status= PkgTab.this.dialog.getStatus();
if (status != null && status.isOK()) {
PkgTab.this.dialog.doApply(true);
}
return null;
}
};
this.handlers.addActivate(IWorkbenchCommandConstants.FILE_REFRESH, handler);
this.toolBar.add(new HandlerContributionItem(new CommandContributionItemParameter(
this.serviceLocator.getLocator(), null, IWorkbenchCommandConstants.FILE_REFRESH,
HandlerContributionItem.STYLE_PUSH ), handler));
}
this.toolBar.add(new Separator());
this.pkgHistory.addActions(this.serviceLocator.getLocator(), this.handlers, this.toolBar);
this.toolBar.update(true);
}
TabItem getTab() {
return this.tab;
}
void addBinding(final DataBindingSupport db) {
this.filterPrioritySet= new WritableSet<>(db.getRealm(), Collections.emptySet(), String.class);
db.getContext().bindSet(
ViewerProperties.checkedElements(String.class)
.observe((ICheckable)this.filterPriorityTable),
this.filterPrioritySet );
new AutoCheckController(this.filterPriorityTable, this.filterPrioritySet);
this.filterRViewsSet= new WritableSet<>(db.getRealm(), Collections.emptySet(), IRView.class);
db.getContext().bindSet(
ViewerProperties.checkedElements(IRView.class)
.observe((ICheckable)this.filterRViewsTable),
this.filterRViewsSet );
new AutoCheckController(this.filterRViewsTable, this.filterRViewsSet);
this.filterController= new TableFilterController(this.pkgTable.viewer);
this.filterController.addFilter(new InstalledFilter());
{ // Priority
final SetElementFilter filter= new SetElementFilter() {
@Override
protected boolean select(final Collection<?> set, final Object element) {
final String name= (String) element;
if (Util.hasPkgPriority(PkgTab.this.pkgSet.getAvailable(), name, set)) {
return true;
}
if (Util.hasPkgPriority(PkgTab.this.pkgSet.getInstalled(), name, set)) {
return true;
}
return false;
}
};
this.filterController.addFilter(filter);
new ObservableSetBinding(this.filterController, this.filterPrioritySet, filter) {
@Override
protected java.util.Collection<?> getAll() {
return PkgTab.this.pkgSet.getPriorities();
}
};
}
{ // Task Views
final SetElementFilter filter= new SetElementFilter();
this.filterController.addFilter(filter);
new ObservableSetBinding(this.filterController, this.filterRViewsSet, filter) {
@Override
protected Collection<?> createFilterSet(final Collection<?> set) {
final Set<String> pkgNames= new HashSet<>(set.size() * 50);
for (final IRView view : (Collection<? extends IRView>) set) {
pkgNames.addAll(view.getPkgList());
}
return pkgNames;
}
};
}
{ final TextElementFilter filter= new TextElementFilter();
this.filterController.addFilter(filter);
new SearchTextBinding(this.filterText, this.filterController, filter);
}
this.filterController.addListener(new TableFilterController.Listener() {
@Override
public void inputUpdated(final boolean newInput) {
if (newInput) {
PkgTab.this.selectedPkgVersion= null;
updateDetail();
}
}
});
this.pkgTable.viewer.addPostSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(final SelectionChangedEvent event) {
final List<?> list= ((IStructuredSelection) event.getSelection()).toList();
doUpdateDetail(list.toArray(new String[list.size()]));
}
});
this.detailTable.viewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(final SelectionChangedEvent event) {
final ITreeSelection treeSelection= (ITreeSelection) event.getSelection();
final Object element= treeSelection.getFirstElement();
updateDetailDetail((element instanceof IRPkgData) ?
treeSelection.getPaths()[0] : null );
}
});
}
private void clearFilter() {
this.filterController.startUpdate();
try {
this.filterText.clearText();
this.filterInstButton.setSelection(false);
this.filterNotInstButton.setSelection(false);
this.filterPrioritySet.clear();
this.filterRViewsSet.clear();
}
finally {
this.filterController.endUpdate();
}
}
public void updateSettings(final IRPkgManager.Ext pkgManager) {
this.filterController.startUpdate();
try {
this.pkgSet= pkgManager.getExtRPkgSet();
if (this.pkgSet == null) {
this.pkgSet= IRPkgSet.DUMMY;
}
this.selectedPkgVersion= null;
final List<String> priorities= this.pkgSet.getPriorities();
{ this.filterPriorityTable.setInput(priorities);
this.filterPrioritySet.retainAll(priorities);
}
{ final List<? extends IRView> views= pkgManager.getRViews();
final Control show;
if (views != null) {
this.filterRViewsTable.setInput(views);
this.filterRViewsSet.retainAll(views);
show= this.filterRViewsTable.getControl().getParent();
}
else {
this.filterRViewsTable.setInput(Collections.EMPTY_LIST);
this.filterRViewsSet.clear();
if (this.pkgSet.getAvailable().contains("ctv")
&& !this.pkgSet.getInstalled().contains("ctv") ) {
this.filterViewsMessage.setText("Install CRAN Task Views (<a href=\"ctv\">ctv</a>) package to filter the packages by tasks.");
show= this.filterViewsMessage;
}
else {
show= this.filterRViewsTable.getControl().getParent();
}
}
if (this.filterViewsStack.topControl != show) {
this.filterViewsStack.topControl= show;
show.getParent().layout(true);
}
}
this.filterController.setInput(this.pkgSet.getNames());
}
finally {
this.filterController.endUpdate();
}
}
private void updateDetail() {
final List<?> list= ((IStructuredSelection) this.pkgTable.viewer.getSelection()).toList();
doUpdateDetail(list.toArray(new String[list.size()]));
}
private void doUpdateDetail(final String[] selection) {
if (selection.length == 1) {
final String name= selection[0];
this.selectedPkgName= name;
this.detailTable.viewer.setInput(name);
ITreeSelection treeSelection= ((ITreeSelection) this.detailTable.viewer.getSelection());
Object element= treeSelection.getFirstElement();
if (!(element instanceof IRPkgData)) {
IRPkgData pkg= null;
if (pkg == null) {
final String repoId= this.selectedPkgVersions.get(name);
if (repoId != null) {
pkg= Util.getPkgByRepo(this.pkgSet.getAvailable(), name, repoId);
}
}
if (pkg == null) {
pkg= this.pkgSet.getAvailable().getFirst(name);
}
if (pkg == null) {
pkg= this.pkgSet.getInstalled().getFirst(name);
}
if (pkg != null) {
this.detailTable.viewer.setSelection(new StructuredSelection(pkg));
}
}
if (this.selectedPkgVersion == null) {
treeSelection= ((ITreeSelection) this.detailTable.viewer.getSelection());
element= treeSelection.getFirstElement();
if (element instanceof IRPkgData) {
updateDetailDetail(treeSelection.getPaths()[0]);
}
}
this.pkgHistory.selected(name);
this.toolBar.update(true);
}
else {
this.selectedPkgName= null;
this.detailTable.viewer.setInput(NO_INPUT);
this.pkgHistory.selected(null);
}
}
private void updateDetailDetail(final TreePath path) {
if (this.selectedPkgName != null && path != null) {
final String name= this.selectedPkgName;
final int id= ((DetailGroup) path.getFirstSegment()).getId();
final IRPkgData pkg= (IRPkgData) path.getLastSegment();
this.selectedPkgVersionGroup= id;
this.selectedPkgVersion= pkg;
IRPkgData first;
if (!pkg.getRepoId().isEmpty()
&& ((first= this.pkgSet.getAvailable().getFirst(name)) != null)
&& !pkg.getRepoId().equals(first.getRepoId()) ) {
this.selectedPkgVersions.put(name, pkg.getRepoId());
}
else {
this.selectedPkgVersions.remove(name);
}
this.detailLicense.setText(pkg.getLicense());
this.detailDepTable.setInput(pkg);
this.detailRevTable.setInput(this.pkgSet.getReverse(name));
}
else {
this.selectedPkgVersionGroup= -1;
this.selectedPkgVersion= null;
this.detailLicense.setText(""); //$NON-NLS-1$
this.detailDepTable.setInput(NO_INPUT);
this.detailRevTable.setInput(NO_INPUT);
}
updateButtons();
}
private boolean isModifiable(final RLibLocation libLocation) {
final RLibLocationInfo info= this.rPkgManager.getRLibPaths().getInfo(libLocation);
return (info != null && info.isWritable());
}
private void updateButtons() {
boolean available;
boolean allInstalled;
boolean allRemovable;
if (this.selectedPkgName != null) {
final String name= this.selectedPkgName;
available= this.pkgSet.getAvailable().contains(name);
final IRPkgInfoAndData pkg= this.pkgSet.getInstalled().getFirst(name);
if (pkg != null) {
allInstalled= true;
allRemovable= isModifiable(pkg.getLibLocation());
}
else {
allInstalled= false;
allRemovable= false;
}
}
else {
final IStructuredSelection selection= (IStructuredSelection) this.pkgTable.viewer.getSelection();
if (selection.isEmpty()) {
available= false;
allInstalled= false;
allRemovable= false;
}
else {
available= false;
allInstalled= true;
allRemovable= true;
final List<String> checkedLocations= new ArrayList<>(8);
for (final Iterator<?> iterator= selection.iterator(); iterator.hasNext();) {
final String name= (String) iterator.next();
if (!available && this.pkgSet.getAvailable().contains(name)) {
available= true;
}
if (allInstalled) {
final IRPkgInfoAndData pkg= this.pkgSet.getInstalled().getFirst(name);
if (pkg != null) {
if (allRemovable) {
final RLibLocation libLoc= pkg.getLibLocation();
if (!checkedLocations.contains(libLoc.getDirectory())) {
allRemovable= isModifiable(libLoc);
checkedLocations.add(libLoc.getDirectory());
}
}
}
else {
allInstalled= false;
allRemovable= false;
}
}
}
}
}
this.installButton.setEnabled(available);
this.updateButton.setEnabled(available);
this.uninstallButton.setEnabled(allRemovable);
this.loadButton.setEnabled(allInstalled);
}
void updateStatus(final IStatus status) {
this.handlers.update(null);
}
private void doInstall() {
final Map<String, List<RPkgAction.Install>> pkgs= getFirstSelectedAsActions(
false, new IGetPkgFilter[0] );
if (pkgs == null) {
return;
}
final RPkgResolver resolver= new RPkgResolver(this.pkgSet, pkgs);
resolver.setAddSuggested(this.dialog.getOptionsTab().installSuggested());
resolver.run();
final InstallPkgsWizard wizard= new InstallPkgsWizard(this.dialog.getTool(), this.rPkgManager,
InstallPkgsWizard.MODE_INSTALL, resolver );
final WizardDialog dialog= new WizardDialog(getShell(), wizard);
dialog.setBlockOnOpen(true);
dialog.open();
this.pkgTable.viewer.refresh(true);
updateButtons();
}
private void doUpdateLatest() {
final Map<String, List<RPkgAction.Install>> pkgs= getFirstSelectedAsActions(
false, new IGetPkgFilter[] {
new RequireInstFilter(),
new LibSourceFilter(),
new LaterVersionFilter(),
});
if (pkgs == null) {
return;
}
final RPkgResolver resolver= new RPkgResolver(this.pkgSet, pkgs);
resolver.setAddSuggested(false);
resolver.run();
final InstallPkgsWizard wizard= new InstallPkgsWizard(this.dialog.getTool(), this.rPkgManager,
InstallPkgsWizard.MODE_UPDATE, resolver );
final WizardDialog dialog= new WizardDialog(getShell(), wizard);
dialog.setBlockOnOpen(true);
dialog.open();
this.pkgTable.viewer.refresh(true);
updateButtons();
}
private void doReinstall(final List<String> names) {
final Map<String, List<RPkgAction.Install>> pkgs= getAllSelectedAsActions(names, true,
new IGetPkgFilter[] {
new RequireInstFilter(),
new LibSourceFilter(),
new NotOlderVersionFilter(),
new ReadOnlyFilter(this.rPkgManager.getRLibPaths()),
});
if (pkgs == null) {
return;
}
final RPkgResolver resolver= new RPkgResolver(this.pkgSet, pkgs);
resolver.setAddRequired(false);
resolver.run();
final InstallPkgsWizard wizard= new InstallPkgsWizard(this.dialog.getTool(), this.rPkgManager,
InstallPkgsWizard.MODE_REINSTALL, resolver );
final WizardDialog dialog= new WizardDialog(getShell(), wizard);
dialog.setBlockOnOpen(true);
dialog.open();
this.pkgTable.viewer.refresh(true);
updateButtons();
}
private void doUninstall() {
final List<? extends IRPkgInfoAndData> pkgs= getSelectedInstalled(
new IGetPkgFilter[] {
new RequireInstFilter(),
new LibSourceFilter(),
new ReadOnlyFilter(this.rPkgManager.getRLibPaths()),
});
if (pkgs == null) {
return;
}
final List<RPkgAction> actions= new ArrayList<>(pkgs.size());
for (final IRPkgInfoAndData pkg : pkgs) {
actions.add(new RPkgAction.Uninstall(pkg));
}
this.rPkgManager.perform(this.dialog.getTool(), actions);
this.pkgTable.viewer.refresh(true);
updateButtons();
}
private void doLoad() {
final List<? extends IRPkgInfoAndData> pkgs= getSelectedInstalled(
new IGetPkgFilter[] {
new RequireInstFilter(),
});
if (pkgs == null) {
return;
}
if (pkgs.size() == 1 && this.selectedPkgVersion != null) {
this.rPkgManager.loadPkgs(this.dialog.getTool(), pkgs, true);
}
else {
this.rPkgManager.loadPkgs(this.dialog.getTool(), pkgs, false);
}
}
// private void revert() {
// List<String> list;
// if (fSelectedPkgName != null) {
// list= Collections.singletonList(fSelectedPkgName);
// }
// else {
// final IStructuredSelection selection= (IStructuredSelection) fPkgTable.viewer.getSelection();
// list= selection.toList();
// }
// fPkgTable.viewer.refresh(true);
// updateButtons();
// }
private List<IRPkgInfoAndData> getSelectedInstalled(final IGetPkgFilter[] filters) {
if (this.selectedPkgName != null) {
final String name= this.selectedPkgName;
IRPkgInfoAndData inst;
if (this.selectedPkgVersionGroup == INST) {
inst= (IRPkgInfoAndData) this.selectedPkgVersion;
}
else {
inst= this.pkgSet.getInstalled().getFirst(name);
}
for (int j= 0; j < filters.length; j++) {
if (filters[j].exclude(inst, null)) {
return null;
}
}
final List<IRPkgInfoAndData> list= new ArrayList<>(1);
list.add(inst);
return list;
}
else {
final IStructuredSelection selection= (IStructuredSelection) this.pkgTable.viewer.getSelection();
final List<IRPkgInfoAndData> list= new ArrayList<>(selection.size());
ITER_SELECTED: for (final Object element : selection.toList()) {
final String name= (String) element;
final IRPkgInfoAndData inst= this.pkgSet.getInstalled().getFirst(name);
for (int j= 0; j < filters.length; j++) {
if (filters[j].exclude(inst, null)) {
continue ITER_SELECTED;
}
}
list.add(inst);
}
if (list.isEmpty()) {
return null;
}
return list;
}
}
private final Map<String, List<RPkgAction.Install>> getFirstSelectedAsActions(
final boolean sameRepo, final IGetPkgFilter[] filters) {
if (this.selectedPkgName != null) {
final String name= this.selectedPkgName;
IRPkgData avail;
if (this.selectedPkgVersionGroup == AVAIL) {
avail= this.selectedPkgVersion;
}
else {
avail= this.pkgSet.getAvailable().getFirst(name);
}
if (avail == null) {
return null;
}
IRPkgInfoAndData inst;
if (this.selectedPkgVersionGroup == INST) {
inst= (IRPkgInfoAndData) this.selectedPkgVersion;
}
else {
inst= this.pkgSet.getInstalled().getFirst(name);
}
if (inst != null && sameRepo) {
avail= getAvailSameRepo(inst, avail);
}
for (int j= 0; j < filters.length; j++) {
if (filters[j].exclude(inst, avail)) {
return null;
}
}
final List<RPkgAction.Install> list= new ArrayList<>(1);
list.add(new RPkgAction.Install(avail, null, inst));
return Collections.singletonMap(name, list);
}
else {
final IStructuredSelection selection= (IStructuredSelection) this.pkgTable.viewer.getSelection();
final Map<String, List<RPkgAction.Install>> map= new HashMap<>(selection.size());
ITER_SELECTED: for (final Object element : selection.toList()) {
final String name= (String) element;
IRPkgData avail= this.pkgSet.getAvailable().getFirst(name);
if (avail == null) {
continue;
}
final IRPkgInfoAndData inst= this.pkgSet.getInstalled().getFirst(name);
if (inst != null && sameRepo) {
avail= getAvailSameRepo(inst, avail);
}
for (int j= 0; j < filters.length; j++) {
if (filters[j].exclude(inst, avail)) {
continue ITER_SELECTED;
}
}
final List<RPkgAction.Install> list= new ArrayList<>(1);
list.add(new RPkgAction.Install(avail, null, inst));
map.put(name, list);
}
if (map.isEmpty()) {
return null;
}
return map;
}
}
private final Map<String, List<RPkgAction.Install>> getAllSelectedAsActions(
List<String> names, final boolean sameRepo, final IGetPkgFilter[] filters) {
if (names == null && this.selectedPkgName != null) {
final String name= this.selectedPkgName;
final IRPkgData avail;
if (this.selectedPkgVersionGroup == AVAIL) {
avail= this.selectedPkgVersion;
}
else {
avail= this.pkgSet.getAvailable().getFirst(name);
}
if (avail == null) {
return null;
}
final List<? extends IRPkgInfoAndData> instList= this.pkgSet.getInstalled().get(name);
if (instList.isEmpty()) {
return null;
}
final List<RPkgAction.Install> list= new ArrayList<>(instList.size());
ITER_INST: for (final IRPkgInfoAndData inst : instList) {
final IRPkgData instAvail= (sameRepo) ? getAvailSameRepo(inst, avail) : avail;
for (int j= 0; j < filters.length; j++) {
if (filters[j].exclude(inst, instAvail)) {
continue ITER_INST;
}
}
list.add(new RPkgAction.Install(instAvail, null, inst));
}
if (list.isEmpty()) {
return null;
}
return Collections.singletonMap(name, list);
}
else {
if (names == null) {
names= ((IStructuredSelection) this.pkgTable.viewer.getSelection()).toList();
}
final Map<String, List<RPkgAction.Install>> map= new HashMap<>(names.size());
for (final String name : names) {
final IRPkgData avail= this.pkgSet.getAvailable().getFirst(name);
if (avail == null) {
continue;
}
final List<? extends IRPkgInfoAndData> instList= this.pkgSet.getInstalled().get(name);
if (instList.isEmpty()) {
continue;
}
final List<RPkgAction.Install> list= new ArrayList<>(instList.size());
ITER_INST: for (final IRPkgInfoAndData inst : instList) {
final IRPkgData instAvail= (sameRepo) ? getAvailSameRepo(inst, avail) : avail;
for (int j= 0; j < filters.length; j++) {
if (filters[j].exclude(inst, instAvail)) {
continue ITER_INST;
}
}
list.add(new RPkgAction.Install(instAvail, null, inst));
}
if (list.isEmpty()) {
continue;
}
map.put(name, list);
}
if (map.isEmpty()) {
return null;
}
return map;
}
}
private IRPkgData getAvailSameRepo(final IRPkgInfoAndData inst, final IRPkgData fallback) {
IRPkgData pkg= null;
if (!inst.getRepoId().isEmpty()) {
final RPkgList<? extends IRPkgData> repoList= this.pkgSet.getAvailable().getBySource(inst.getRepoId());
if (repoList != null) {
pkg= repoList.get(inst.getName());
if (pkg != null) {
return pkg;
}
}
}
return fallback;
}
void showPkg(final String name) {
if (name.equals("R")) {
return;
}
this.filterController.setSelection(name);
}
IRPkgSet.Ext getPkgSet() {
return this.pkgSet;
}
void install(final List<String> pkgNames) {
this.pkgTable.viewer.setSelection(new StructuredSelection());
clearFilter();
this.filterController.schedule(new Runnable() {
@Override
public void run() {
PkgTab.this.filterController.setSelection(pkgNames);
// updateDetail();
doInstall();
}
});
}
void reinstallAll() {
doReinstall(this.pkgSet.getNames());
}
}