| /*=============================================================================# |
| # 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()); |
| } |
| |
| } |