mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
packaging UI moved to lang-impl
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
package com.intellij.webcore.packaging;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class InstalledPackage {
|
||||
private final String myName;
|
||||
private final String myVersion;
|
||||
|
||||
public InstalledPackage(String name, String version) {
|
||||
myName = name;
|
||||
myVersion = version;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return myVersion;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getTooltipText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
InstalledPackage aPackage = (InstalledPackage)o;
|
||||
if (myName != null ? !myName.equals(aPackage.myName) : aPackage.myName != null) return false;
|
||||
if (myVersion != null ? !myVersion.equals(aPackage.myVersion) : aPackage.myVersion != null) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = myName != null ? myName.hashCode() : 0;
|
||||
result = 31 * result + (myVersion != null ? myVersion.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,477 @@
|
||||
package com.intellij.webcore.packaging;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.ui.DoubleClickListener;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.table.JBTable;
|
||||
import com.intellij.util.CatchingConsumer;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class InstalledPackagesPanel extends JPanel {
|
||||
protected final JButton myInstallButton;
|
||||
private final JButton myUninstallButton;
|
||||
private final JButton myUpgradeButton;
|
||||
|
||||
protected final JBTable myPackagesTable;
|
||||
private DefaultTableModel myPackagesTableModel;
|
||||
protected PackageManagementService myPackageManagementService;
|
||||
protected final Project myProject;
|
||||
protected final PackagesNotificationPanel myNotificationArea;
|
||||
protected final List<Consumer<Sdk>> myPathChangedListeners = ContainerUtil.createLockFreeCopyOnWriteList();
|
||||
private final Set<String> myCurrentlyInstalling = ContainerUtil.newHashSet();
|
||||
private final Set<InstalledPackage> myWaitingToUpgrade = ContainerUtil.newHashSet();
|
||||
|
||||
public InstalledPackagesPanel(Project project, PackagesNotificationPanel area) {
|
||||
super(new GridBagLayout());
|
||||
myProject = project;
|
||||
myNotificationArea = area;
|
||||
myInstallButton = new JButton("Install");
|
||||
myUninstallButton = new JButton("Uninstall");
|
||||
myUpgradeButton = new JButton("Upgrade");
|
||||
myInstallButton.setMnemonic('I');
|
||||
myUninstallButton.setMnemonic('U');
|
||||
myUpgradeButton.setMnemonic('p');
|
||||
|
||||
myInstallButton.setEnabled(false);
|
||||
myUninstallButton.setEnabled(false);
|
||||
myUpgradeButton.setEnabled(false);
|
||||
|
||||
myPackagesTableModel = new DefaultTableModel(new String[]{"Package", "Version", "Latest"}, 0) {
|
||||
@Override
|
||||
public boolean isCellEditable(int i, int i1) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
final TableCellRenderer tableCellRenderer = new MyTableCellRenderer();
|
||||
myPackagesTable = new JBTable(myPackagesTableModel) {
|
||||
@Override
|
||||
public TableCellRenderer getCellRenderer(int row, int column) {
|
||||
return tableCellRenderer;
|
||||
}
|
||||
};
|
||||
myPackagesTable.getTableHeader().setReorderingAllowed(false);
|
||||
|
||||
Insets anInsets = new Insets(2, 2, 2, 2);
|
||||
JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myPackagesTable,
|
||||
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
|
||||
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
scrollPane.setPreferredSize(new Dimension(500, 500));
|
||||
add(scrollPane, new GridBagConstraints(0, 0, 1, 3, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
|
||||
anInsets, 0, 0));
|
||||
|
||||
addUninstallAction();
|
||||
addUpgradeAction();
|
||||
|
||||
add(myInstallButton,
|
||||
new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
|
||||
anInsets, 0, 0));
|
||||
add(myUninstallButton,
|
||||
new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
|
||||
anInsets, 0, 0));
|
||||
add(myUpgradeButton,
|
||||
new GridBagConstraints(1, 2, 1, 1, 0.0, 1.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, anInsets, 0, 0));
|
||||
|
||||
myPackagesTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent event) {
|
||||
updateUninstallUpgrade();
|
||||
}
|
||||
});
|
||||
|
||||
myInstallButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (myPackageManagementService != null) {
|
||||
ManagePackagesDialog dialog = createManagePackagesDialog();
|
||||
dialog.show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
new DoubleClickListener() {
|
||||
@Override
|
||||
protected boolean onDoubleClick(MouseEvent e) {
|
||||
if (myPackageManagementService != null && myInstallButton.isEnabled()) {
|
||||
ManagePackagesDialog dialog = createManagePackagesDialog();
|
||||
Point p = e.getPoint();
|
||||
int row = myPackagesTable.rowAtPoint(p);
|
||||
int column = myPackagesTable.columnAtPoint(p);
|
||||
if (row >= 0 && column >= 0) {
|
||||
Object pkg = myPackagesTable.getValueAt(row, 0);
|
||||
if (pkg instanceof InstalledPackage) {
|
||||
dialog.selectPackage((InstalledPackage) pkg);
|
||||
}
|
||||
}
|
||||
dialog.show();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}.installOn(myPackagesTable);
|
||||
}
|
||||
|
||||
private ManagePackagesDialog createManagePackagesDialog() {
|
||||
return new ManagePackagesDialog(myProject,
|
||||
myPackageManagementService,
|
||||
new PackageManagementService.Listener() {
|
||||
@Override
|
||||
public void operationStarted(String packageName) {
|
||||
myPackagesTable.setPaintBusy(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void operationFinished(String packageName,
|
||||
@Nullable String errorDescription) {
|
||||
myNotificationArea.showResult(packageName, errorDescription);
|
||||
myPackagesTable.clearSelection();
|
||||
doUpdatePackages(myPackageManagementService);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addPathChangedListener(Consumer<Sdk> consumer) {
|
||||
myPathChangedListeners.add(consumer);
|
||||
}
|
||||
|
||||
private void addUpgradeAction() {
|
||||
myUpgradeButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final int[] rows = myPackagesTable.getSelectedRows();
|
||||
if (myPackageManagementService != null) {
|
||||
final Set<String> upgradedPackages = new HashSet<String>();
|
||||
final Set<String> packagesShouldBePostponed = getPackagesToPostpone();
|
||||
for (int row : rows) {
|
||||
final Object packageObj = myPackagesTableModel.getValueAt(row, 0);
|
||||
if (packageObj instanceof InstalledPackage) {
|
||||
InstalledPackage pkg = (InstalledPackage)packageObj;
|
||||
final String packageName = pkg.getName();
|
||||
final String currentVersion = pkg.getVersion();
|
||||
final String availableVersion = (String)myPackagesTableModel.getValueAt(row, 2);
|
||||
|
||||
if (packagesShouldBePostponed.contains(packageName)) {
|
||||
myWaitingToUpgrade.add((InstalledPackage)packageObj);
|
||||
}
|
||||
else if (PackageVersionComparator.VERSION_COMPARATOR.compare(currentVersion, availableVersion) < 0) {
|
||||
upgradePackage(pkg, availableVersion);
|
||||
upgradedPackages.add(packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (myCurrentlyInstalling.isEmpty() && upgradedPackages.isEmpty() && !myWaitingToUpgrade.isEmpty()) {
|
||||
upgradePostponedPackages();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void upgradePostponedPackages() {
|
||||
final Iterator<InstalledPackage> iterator = myWaitingToUpgrade.iterator();
|
||||
final InstalledPackage toUpgrade = iterator.next();
|
||||
iterator.remove();
|
||||
upgradePackage(toUpgrade, toUpgrade.getVersion());
|
||||
}
|
||||
|
||||
protected Set<String> getPackagesToPostpone() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
private void upgradePackage(@NotNull final InstalledPackage pkg, @Nullable final String toVersion) {
|
||||
final PackageManagementService selPackageManagementService = myPackageManagementService;
|
||||
myPackageManagementService.fetchPackageVersions(pkg.getName(), new CatchingConsumer<List<String>, Exception>() {
|
||||
@Override
|
||||
public void consume(List<String> releases) {
|
||||
if (!releases.isEmpty() &&
|
||||
PackageVersionComparator.VERSION_COMPARATOR.compare(pkg.getVersion(), releases.get(0)) >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final PackageManagementService.Listener listener = new PackageManagementService.Listener() {
|
||||
@Override
|
||||
public void operationStarted(String packageName) {
|
||||
myPackagesTable.setPaintBusy(true);
|
||||
myCurrentlyInstalling.add(packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void operationFinished(String packageName, @Nullable String errorDescription) {
|
||||
myPackagesTable.clearSelection();
|
||||
updatePackages(selPackageManagementService);
|
||||
myPackagesTable.setPaintBusy(false);
|
||||
myCurrentlyInstalling.remove(packageName);
|
||||
if (errorDescription == null) {
|
||||
myNotificationArea.showSuccess("Package " + packageName + " successfully upgraded");
|
||||
}
|
||||
else {
|
||||
myNotificationArea.showError("Upgrade packages failed. <a href=\"xxx\">Details...</a>",
|
||||
"Upgrade Packages Failed",
|
||||
"Upgrade packages failed.\n" + errorDescription);
|
||||
}
|
||||
|
||||
if (myCurrentlyInstalling.isEmpty() && !myWaitingToUpgrade.isEmpty()) {
|
||||
upgradePostponedPackages();
|
||||
}
|
||||
}
|
||||
};
|
||||
PackageManagementServiceEx serviceEx = getServiceEx();
|
||||
if (serviceEx != null) {
|
||||
serviceEx.updatePackage(pkg, toVersion, listener);
|
||||
}
|
||||
else {
|
||||
myPackageManagementService.installPackage(new RepoPackage(pkg.getName(), null /* TODO? */), null, true, null, listener, false);
|
||||
}
|
||||
myUpgradeButton.setEnabled(false);
|
||||
}
|
||||
}, ModalityState.any());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consume(Exception e) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Messages.showErrorDialog("Error occurred. Please, check your internet connection.",
|
||||
"Upgrade Package Failed.");
|
||||
}
|
||||
}, ModalityState.any());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PackageManagementServiceEx getServiceEx() {
|
||||
return ObjectUtils.tryCast(myPackageManagementService, PackageManagementServiceEx.class);
|
||||
}
|
||||
|
||||
private void updateUninstallUpgrade() {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final int[] selected = myPackagesTable.getSelectedRows();
|
||||
boolean upgradeAvailable = false;
|
||||
boolean canUninstall = true;
|
||||
boolean canUpgrade = true;
|
||||
if (myPackageManagementService != null && selected.length != 0) {
|
||||
for (int i = 0; i != selected.length; ++i) {
|
||||
final int index = selected[i];
|
||||
if (index >= myPackagesTable.getRowCount()) continue;
|
||||
final Object value = myPackagesTable.getValueAt(index, 0);
|
||||
if (value instanceof InstalledPackage) {
|
||||
final InstalledPackage pkg = (InstalledPackage)value;
|
||||
if (!canUninstallPackage(pkg)) {
|
||||
canUninstall = false;
|
||||
}
|
||||
if (!canUpgradePackage(pkg)) {
|
||||
canUpgrade = false;
|
||||
}
|
||||
final String pyPackageName = pkg.getName();
|
||||
final String availableVersion = (String)myPackagesTable.getValueAt(index, 2);
|
||||
if (!upgradeAvailable) {
|
||||
upgradeAvailable = PackageVersionComparator.VERSION_COMPARATOR.compare(pkg.getVersion(), availableVersion) < 0 &&
|
||||
!myCurrentlyInstalling.contains(pyPackageName);
|
||||
}
|
||||
if (!canUninstall && !canUpgrade) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
myUninstallButton.setEnabled(canUninstall);
|
||||
myUpgradeButton.setEnabled(upgradeAvailable && canUpgrade);
|
||||
}
|
||||
}, ModalityState.any());
|
||||
}
|
||||
|
||||
protected boolean canUninstallPackage(InstalledPackage pyPackage) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean canUpgradePackage(InstalledPackage pyPackage) {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void addUninstallAction() {
|
||||
myUninstallButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
final List<InstalledPackage> packages = getSelectedPackages();
|
||||
final PackageManagementService selPackageManagementService = myPackageManagementService;
|
||||
if (selPackageManagementService != null) {
|
||||
PackageManagementService.Listener listener = new PackageManagementService.Listener() {
|
||||
@Override
|
||||
public void operationStarted(String packageName) {
|
||||
myPackagesTable.setPaintBusy(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void operationFinished(String packageName, @Nullable String errorDescription) {
|
||||
myPackagesTable.clearSelection();
|
||||
updatePackages(selPackageManagementService);
|
||||
myPackagesTable.setPaintBusy(false);
|
||||
if (errorDescription == null) {
|
||||
if (packageName != null) {
|
||||
myNotificationArea.showSuccess("Package '" + packageName + "' successfully uninstalled");
|
||||
}
|
||||
else {
|
||||
myNotificationArea.showSuccess("Packages successfully uninstalled");
|
||||
}
|
||||
}
|
||||
else {
|
||||
myNotificationArea.showError("Uninstall packages failed. <a href=\"xxx\">Details...</a>",
|
||||
"Uninstall Packages Failed",
|
||||
"Uninstall packages failed.\n" + errorDescription);
|
||||
}
|
||||
}
|
||||
};
|
||||
myPackageManagementService.uninstallPackages(packages, listener);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<InstalledPackage> getSelectedPackages() {
|
||||
final List<InstalledPackage> results = new ArrayList<InstalledPackage>();
|
||||
final int[] rows = myPackagesTable.getSelectedRows();
|
||||
for (int row : rows) {
|
||||
final Object packageName = myPackagesTableModel.getValueAt(row, 0);
|
||||
if (packageName instanceof InstalledPackage) {
|
||||
results.add((InstalledPackage)packageName);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public void updatePackages(@Nullable PackageManagementService packageManagementService) {
|
||||
myPackageManagementService = packageManagementService;
|
||||
myPackagesTable.clearSelection();
|
||||
myPackagesTableModel.getDataVector().clear();
|
||||
doUpdatePackages(packageManagementService);
|
||||
}
|
||||
|
||||
public void doUpdatePackages(final PackageManagementService packageManagementService) {
|
||||
myPackagesTable.setPaintBusy(true);
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
application.executeOnPooledThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Collection<InstalledPackage> packages = Lists.newArrayList();
|
||||
if (packageManagementService != null) {
|
||||
try {
|
||||
packages = packageManagementService.getInstalledPackages();
|
||||
}
|
||||
catch (IOException e) {
|
||||
// do nothing, we already have an empty list
|
||||
}
|
||||
finally {
|
||||
final Collection<InstalledPackage> finalPackages = packages;
|
||||
|
||||
final Map<String, RepoPackage> cache = buildNameToPackageMap(packageManagementService.getAllPackagesCached());
|
||||
if (cache.isEmpty()) {
|
||||
refreshLatestVersions();
|
||||
}
|
||||
application.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (packageManagementService == myPackageManagementService) {
|
||||
myPackagesTableModel.getDataVector().clear();
|
||||
for (InstalledPackage pkg : finalPackages) {
|
||||
RepoPackage repoPackage = cache.get(pkg.getName());
|
||||
final String version = repoPackage != null ? repoPackage.getLatestVersion() : null;
|
||||
myPackagesTableModel
|
||||
.addRow(new Object[]{pkg, pkg.getVersion(), version == null ? "" : version});
|
||||
}
|
||||
if (!cache.isEmpty()) {
|
||||
myPackagesTable.setPaintBusy(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, ModalityState.any());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void refreshLatestVersions() {
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
application.executeOnPooledThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
List<RepoPackage> packages = myPackageManagementService.reloadAllPackages();
|
||||
final Map<String, RepoPackage> packageMap = buildNameToPackageMap(packages);
|
||||
application.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = 0; i != myPackagesTableModel.getRowCount(); ++i) {
|
||||
final InstalledPackage pyPackage = (InstalledPackage)myPackagesTableModel.getValueAt(i, 0);
|
||||
final RepoPackage repoPackage = packageMap.get(pyPackage.getName());
|
||||
myPackagesTableModel.setValueAt(repoPackage == null ? null : repoPackage.getLatestVersion(), i, 2);
|
||||
}
|
||||
myPackagesTable.setPaintBusy(false);
|
||||
}
|
||||
}, ModalityState.stateForComponent(myPackagesTable));
|
||||
}
|
||||
catch (IOException ignored) {
|
||||
myPackagesTable.setPaintBusy(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static Map<String, RepoPackage> buildNameToPackageMap(List<RepoPackage> packages) {
|
||||
final Map<String, RepoPackage> packageMap = new HashMap<String, RepoPackage>();
|
||||
for (RepoPackage aPackage : packages) {
|
||||
packageMap.put(aPackage.getName(), aPackage);
|
||||
}
|
||||
return packageMap;
|
||||
}
|
||||
|
||||
private static class MyTableCellRenderer extends DefaultTableCellRenderer {
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected,
|
||||
final boolean hasFocus, final int row, final int column) {
|
||||
final JLabel cell = (JLabel)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||
final String version = (String)table.getValueAt(row, 1);
|
||||
final String availableVersion = (String)table.getValueAt(row, 2);
|
||||
cell.setIcon(PackageVersionComparator.VERSION_COMPARATOR.compare(version, availableVersion) < 0 && column == 2 ?
|
||||
AllIcons.Vcs.Arrow_right : null);
|
||||
final Object pyPackage = table.getValueAt(row, 0);
|
||||
if (pyPackage instanceof InstalledPackage) {
|
||||
cell.setToolTipText(((InstalledPackage) pyPackage).getTooltipText());
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.webcore.packaging.ManagePackagesDialog">
|
||||
<grid id="a6e0d" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="49" y="40" width="451" height="540"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<preferredSize width="900" height="700"/>
|
||||
</properties>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<grid id="64782" binding="myFilter" custom-create="true" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="1" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="-1" height="30"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children/>
|
||||
</grid>
|
||||
<grid id="6373a" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<splitpane id="70cdc" binding="mySplitPane">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<continuousLayout value="true"/>
|
||||
<oneTouchExpandable value="false"/>
|
||||
</properties>
|
||||
<border type="empty"/>
|
||||
<children>
|
||||
<grid id="7d113" layout-manager="GridLayoutManager" row-count="3" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<splitpane position="right"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithoutIndentWithoutInsets"/>
|
||||
</clientProperties>
|
||||
<border type="none" title-resource-bundle="messages/IdeBundle" title-key="editbox.plugin.description">
|
||||
<size top="0" left="0" bottom="0" right="0"/>
|
||||
</border>
|
||||
<children>
|
||||
<scrollpane id="8853a" class="com.intellij.ui.components.JBScrollPane">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="5" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="300" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<verticalScrollBarPolicy value="22"/>
|
||||
</properties>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="db08a" class="javax.swing.JEditorPane" binding="myDescriptionTextArea">
|
||||
<constraints/>
|
||||
<properties>
|
||||
<contentType value="text/html"/>
|
||||
<editable value="false"/>
|
||||
<maximumSize width="-1" height="-1"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</scrollpane>
|
||||
<component id="a41c0" class="javax.swing.JCheckBox" binding="myVersionCheckBox">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<enabled value="true"/>
|
||||
<selected value="false"/>
|
||||
<text value="Specify version"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="a5b42" class="javax.swing.JCheckBox" binding="myOptionsCheckBox" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<enabled value="true"/>
|
||||
<selected value="false"/>
|
||||
<text value="Options"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="5b85e" class="javax.swing.JTextField" binding="myOptionsField">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="4" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<enabled value="false"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="518ff" class="javax.swing.JComboBox" binding="myVersionComboBox">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="4" vsize-policy="0" hsize-policy="0" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<enabled value="false"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</splitpane>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="bfefe" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="5f791" class="javax.swing.JButton" binding="myInstallButton" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="&Install Package"/>
|
||||
</properties>
|
||||
</component>
|
||||
<hspacer id="df2ac">
|
||||
<constraints>
|
||||
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
<component id="49d5e" class="javax.swing.JButton" binding="myManageButton">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="&Manage Repositories"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="2013f" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="bf6b9" class="javax.swing.JCheckBox" binding="myInstallToUser">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<enabled value="true"/>
|
||||
<selected value="false"/>
|
||||
<text value=""/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="a26a8" binding="myNotificationsAreaPlaceholder" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children/>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
@@ -0,0 +1,563 @@
|
||||
package com.intellij.webcore.packaging;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.BrowserUtil;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.util.CatchingConsumer;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.ui.PlatformColors;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ui.update.UiNotifyConnector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.text.html.HTMLDocument;
|
||||
import javax.swing.text.html.HTMLFrameHyperlinkEvent;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: catherine
|
||||
* <p/>
|
||||
* UI for installing python packages
|
||||
*/
|
||||
public class ManagePackagesDialog extends DialogWrapper {
|
||||
private static final Logger LOG = Logger.getInstance(ManagePackagesDialog.class);
|
||||
|
||||
@NotNull private final Project myProject;
|
||||
private final PackageManagementService myController;
|
||||
|
||||
private JPanel myFilter;
|
||||
private JPanel myMainPanel;
|
||||
private JEditorPane myDescriptionTextArea;
|
||||
private JBList myPackages;
|
||||
private JButton myInstallButton;
|
||||
private JCheckBox myOptionsCheckBox;
|
||||
private JTextField myOptionsField;
|
||||
private JCheckBox myInstallToUser;
|
||||
private JComboBox myVersionComboBox;
|
||||
private JCheckBox myVersionCheckBox;
|
||||
private JButton myManageButton;
|
||||
private final PackagesNotificationPanel myNotificationArea;
|
||||
private JSplitPane mySplitPane;
|
||||
private JPanel myNotificationsAreaPlaceholder;
|
||||
private PackagesModel myPackagesModel;
|
||||
private String mySelectedPackageName;
|
||||
private final Set<String> myInstalledPackages;
|
||||
@Nullable private final PackageManagementService.Listener myPackageListener;
|
||||
|
||||
private Set<String> myCurrentlyInstalling = new HashSet<String>();
|
||||
protected final ListSpeedSearch myListSpeedSearch;
|
||||
|
||||
public ManagePackagesDialog(@NotNull Project project, final PackageManagementService packageManagementService,
|
||||
@Nullable final PackageManagementService.Listener packageListener) {
|
||||
super(project, true);
|
||||
myProject = project;
|
||||
myController = packageManagementService;
|
||||
|
||||
myPackageListener = packageListener;
|
||||
init();
|
||||
setTitle("Available Packages");
|
||||
myPackages = new JBList();
|
||||
myNotificationArea = new PackagesNotificationPanel(project);
|
||||
myNotificationsAreaPlaceholder.add(myNotificationArea.getComponent(), BorderLayout.CENTER);
|
||||
|
||||
final AnActionButton reloadButton = new AnActionButton("Reload List of Packages", AllIcons.Actions.Refresh) {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
myPackages.setPaintBusy(true);
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
application.executeOnPooledThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myController.reloadAllPackages();
|
||||
myPackages.setPaintBusy(false);
|
||||
}
|
||||
catch (final IOException e) {
|
||||
application.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//noinspection DialogTitleCapitalization
|
||||
Messages.showErrorDialog("Error updating package list: " + e.getMessage(), "Reload List of Packages");
|
||||
myPackages.setPaintBusy(false);
|
||||
}
|
||||
}, ModalityState.any());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
myListSpeedSearch = new ListSpeedSearch(myPackages, new Function<Object, String>() {
|
||||
@Override
|
||||
public String fun(Object o) {
|
||||
if (o instanceof RepoPackage)
|
||||
return ((RepoPackage)o).getName();
|
||||
return "";
|
||||
}
|
||||
});
|
||||
JPanel packagesPanel = ToolbarDecorator.createDecorator(myPackages)
|
||||
.disableAddAction()
|
||||
.disableUpDownActions()
|
||||
.disableRemoveAction()
|
||||
.addExtraAction(reloadButton)
|
||||
.createPanel();
|
||||
packagesPanel.setPreferredSize(new Dimension(400, -1));
|
||||
packagesPanel.setMinimumSize(new Dimension(100, -1));
|
||||
myPackages.setFixedCellWidth(0);
|
||||
myPackages.setFixedCellHeight(22);
|
||||
myPackages.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
mySplitPane.setLeftComponent(packagesPanel);
|
||||
|
||||
myPackages.addListSelectionListener(new MyPackageSelectionListener());
|
||||
myInstallToUser.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
myController.installToUserChanged(myInstallToUser.isSelected());
|
||||
}
|
||||
});
|
||||
myOptionsCheckBox.setEnabled(false);
|
||||
myVersionCheckBox.setEnabled(false);
|
||||
myVersionCheckBox.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
myVersionComboBox.setEnabled(myVersionCheckBox.isSelected());
|
||||
}
|
||||
});
|
||||
|
||||
UiNotifyConnector.doWhenFirstShown(myPackages, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
initModel();
|
||||
}
|
||||
});
|
||||
myOptionsCheckBox.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
myOptionsField.setEnabled(myOptionsCheckBox.isSelected());
|
||||
}
|
||||
});
|
||||
myInstallButton.setEnabled(false);
|
||||
myDescriptionTextArea.addHyperlinkListener(new MyHyperlinkListener());
|
||||
addInstallAction();
|
||||
myInstalledPackages = new HashSet<String>();
|
||||
updateInstalledPackages();
|
||||
addManageAction();
|
||||
myPackages.setCellRenderer(new MyTableRenderer());
|
||||
|
||||
if (myController.canInstallToUser()) {
|
||||
myInstallToUser.setVisible(true);
|
||||
myInstallToUser.setSelected(myController.isInstallToUserSelected());
|
||||
myInstallToUser.setText(myController.getInstallToUserText());
|
||||
}
|
||||
else {
|
||||
myInstallToUser.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void selectPackage(@NotNull InstalledPackage pkg) {
|
||||
mySelectedPackageName = pkg.getName();
|
||||
doSelectPackage(mySelectedPackageName);
|
||||
}
|
||||
|
||||
private void addManageAction() {
|
||||
if (myController.getAllRepositories() != null) {
|
||||
myManageButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
ManageRepoDialog dialog = new ManageRepoDialog(myProject, myController);
|
||||
dialog.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
myManageButton.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void addInstallAction() {
|
||||
myInstallButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
final Object pyPackage = myPackages.getSelectedValue();
|
||||
if (pyPackage instanceof RepoPackage) {
|
||||
RepoPackage repoPackage = (RepoPackage)pyPackage;
|
||||
|
||||
String extraOptions = null;
|
||||
if (myOptionsCheckBox.isEnabled() && myOptionsCheckBox.isSelected()) {
|
||||
extraOptions = myOptionsField.getText();
|
||||
}
|
||||
|
||||
String version = null;
|
||||
if (myVersionCheckBox.isEnabled() && myVersionCheckBox.isSelected()) {
|
||||
version = (String) myVersionComboBox.getSelectedItem();
|
||||
}
|
||||
|
||||
final PackageManagementService.Listener listener = new PackageManagementService.Listener() {
|
||||
@Override
|
||||
public void operationStarted(final String packageName) {
|
||||
if (!ApplicationManager.getApplication().isDispatchThread()) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handleInstallationStarted(packageName);
|
||||
}
|
||||
}, ModalityState.stateForComponent(myMainPanel));
|
||||
}
|
||||
else {
|
||||
handleInstallationStarted(packageName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void operationFinished(final String packageName, @Nullable final String errorDescription) {
|
||||
if (!ApplicationManager.getApplication().isDispatchThread()) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handleInstallationFinished(packageName, errorDescription);
|
||||
}
|
||||
}, ModalityState.stateForComponent(myMainPanel));
|
||||
}
|
||||
else {
|
||||
handleInstallationFinished(packageName, errorDescription);
|
||||
}
|
||||
}
|
||||
};
|
||||
myController.installPackage(repoPackage, version, false, extraOptions, listener, myInstallToUser.isSelected());
|
||||
myInstallButton.setEnabled(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void handleInstallationStarted(String packageName) {
|
||||
setDownloadStatus(true);
|
||||
myCurrentlyInstalling.add(packageName);
|
||||
if (myPackageListener != null) {
|
||||
myPackageListener.operationStarted(packageName);
|
||||
}
|
||||
myPackages.repaint();
|
||||
}
|
||||
|
||||
private void handleInstallationFinished(String packageName, String errorDescription) {
|
||||
if (myPackageListener != null) {
|
||||
myPackageListener.operationFinished(packageName, errorDescription);
|
||||
}
|
||||
setDownloadStatus(false);
|
||||
myNotificationArea.showResult(packageName, errorDescription);
|
||||
|
||||
updateInstalledPackages();
|
||||
|
||||
myCurrentlyInstalling.remove(packageName);
|
||||
myPackages.repaint();
|
||||
}
|
||||
|
||||
private void updateInstalledPackages() {
|
||||
try {
|
||||
Collection<InstalledPackage> installedPackages = myController.getInstalledPackages();
|
||||
myInstalledPackages.clear();
|
||||
for (InstalledPackage pkg : installedPackages) {
|
||||
myInstalledPackages.add(pkg.getName());
|
||||
}
|
||||
}
|
||||
catch(IOException e) {
|
||||
LOG.info("Error updating list of installed packages:" + e);
|
||||
}
|
||||
}
|
||||
|
||||
public void initModel() {
|
||||
setDownloadStatus(true);
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
application.executeOnPooledThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myPackagesModel = new PackagesModel(myController.getAllPackages());
|
||||
|
||||
application.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myPackages.setModel(myPackagesModel);
|
||||
doSelectPackage(mySelectedPackageName);
|
||||
setDownloadStatus(false);
|
||||
}
|
||||
}, ModalityState.any());
|
||||
}
|
||||
catch (final IOException e) {
|
||||
application.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Messages.showErrorDialog("Error loading package list:" + e.getMessage(), "Packages");
|
||||
setDownloadStatus(false);
|
||||
}
|
||||
}, ModalityState.any());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void doSelectPackage(@Nullable String packageName) {
|
||||
PackagesModel packagesModel = ObjectUtils.tryCast(myPackages.getModel(), PackagesModel.class);
|
||||
if (packageName == null || packagesModel == null) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < packagesModel.getSize(); i++) {
|
||||
RepoPackage repoPackage = packagesModel.getElementAt(i);
|
||||
if (packageName.equals(repoPackage.getName())) {
|
||||
myPackages.setSelectedIndex(i);
|
||||
myPackages.ensureIndexIsVisible(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void setDownloadStatus(boolean status) {
|
||||
myPackages.setPaintBusy(status);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
return myMainPanel;
|
||||
}
|
||||
|
||||
private void createUIComponents() {
|
||||
myFilter = new MyPackageFilter();
|
||||
}
|
||||
|
||||
public class MyPackageFilter extends FilterComponent {
|
||||
|
||||
public MyPackageFilter() {
|
||||
super("PACKAGE_FILTER", 5);
|
||||
}
|
||||
|
||||
public void filter() {
|
||||
if (myPackagesModel != null)
|
||||
myPackagesModel.filter(getFilter());
|
||||
}
|
||||
}
|
||||
|
||||
private class PackagesModel extends CollectionListModel<RepoPackage> {
|
||||
protected final List<RepoPackage> myFilteredOut = new ArrayList<RepoPackage>();
|
||||
protected List<RepoPackage> myView = new ArrayList<RepoPackage>();
|
||||
|
||||
public PackagesModel(List<RepoPackage> packages) {
|
||||
super(packages);
|
||||
myView = packages;
|
||||
}
|
||||
|
||||
public void add(String urlResource, String element) {
|
||||
super.add(new RepoPackage(element, urlResource));
|
||||
}
|
||||
|
||||
protected void filter(final String filter) {
|
||||
final Collection<RepoPackage> toProcess = toProcess();
|
||||
|
||||
toProcess.addAll(myFilteredOut);
|
||||
myFilteredOut.clear();
|
||||
|
||||
final ArrayList<RepoPackage> filtered = new ArrayList<RepoPackage>();
|
||||
|
||||
for (RepoPackage repoPackage : toProcess) {
|
||||
if (StringUtil.containsIgnoreCase(repoPackage.getName(), filter)) {
|
||||
filtered.add(repoPackage);
|
||||
}
|
||||
else {
|
||||
myFilteredOut.add(repoPackage);
|
||||
}
|
||||
}
|
||||
filter(filtered);
|
||||
}
|
||||
|
||||
public void filter(List<RepoPackage> filtered){
|
||||
myView.clear();
|
||||
myPackages.clearSelection();
|
||||
for (RepoPackage repoPackage : filtered) {
|
||||
myView.add(repoPackage);
|
||||
}
|
||||
Collections.sort(myView);
|
||||
fireContentsChanged(this, 0, myView.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepoPackage getElementAt(int index) {
|
||||
return myView.get(index);
|
||||
}
|
||||
|
||||
protected ArrayList<RepoPackage> toProcess() {
|
||||
return new ArrayList<RepoPackage>(myView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return myView.size();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myFilter;
|
||||
}
|
||||
|
||||
public static class MyHyperlinkListener implements HyperlinkListener {
|
||||
public void hyperlinkUpdate(HyperlinkEvent e) {
|
||||
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
|
||||
JEditorPane pane = (JEditorPane)e.getSource();
|
||||
if (e instanceof HTMLFrameHyperlinkEvent) {
|
||||
HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent)e;
|
||||
HTMLDocument doc = (HTMLDocument)pane.getDocument();
|
||||
doc.processHTMLFrameHyperlinkEvent(evt);
|
||||
}
|
||||
else {
|
||||
URL url = e.getURL();
|
||||
if (url != null) {
|
||||
BrowserUtil.browse(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MyPackageSelectionListener implements ListSelectionListener {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent event) {
|
||||
myOptionsCheckBox.setEnabled(myPackages.getSelectedIndex() >= 0);
|
||||
myVersionCheckBox.setEnabled(myPackages.getSelectedIndex() >= 0);
|
||||
myOptionsCheckBox.setSelected(false);
|
||||
myVersionCheckBox.setSelected(false);
|
||||
myVersionComboBox.setEnabled(false);
|
||||
myOptionsField.setEnabled(false);
|
||||
myDescriptionTextArea.setText("");
|
||||
|
||||
setDownloadStatus(true);
|
||||
final Object pyPackage = myPackages.getSelectedValue();
|
||||
if (pyPackage instanceof RepoPackage) {
|
||||
final String packageName = ((RepoPackage)pyPackage).getName();
|
||||
myVersionComboBox.removeAllItems();
|
||||
if (myVersionCheckBox.isEnabled()) {
|
||||
myController.fetchPackageVersions(packageName, new CatchingConsumer<List<String>, Exception>() {
|
||||
@Override
|
||||
public void consume(final List<String> releases) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (myPackages.getSelectedValue() == pyPackage) {
|
||||
myVersionComboBox.removeAllItems();
|
||||
for (String release : releases) {
|
||||
myVersionComboBox.addItem(release);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, ModalityState.any());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consume(Exception e) {
|
||||
LOG.info("Error retrieving releases", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
myInstallButton.setEnabled(!myCurrentlyInstalling.contains(packageName));
|
||||
|
||||
myController.fetchPackageDetails(packageName, new CatchingConsumer<String, Exception>() {
|
||||
@Override
|
||||
public void consume(final String details) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (myPackages.getSelectedValue() == pyPackage) {
|
||||
myDescriptionTextArea.setText(details);
|
||||
}
|
||||
}
|
||||
}, ModalityState.any());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consume(Exception exception) {
|
||||
LOG.info("Error retrieving package details", exception);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
myInstallButton.setEnabled(false);
|
||||
}
|
||||
setDownloadStatus(false);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Action[] createActions() {
|
||||
return new Action[0];
|
||||
}
|
||||
|
||||
private class MyTableRenderer extends DefaultListCellRenderer {
|
||||
private JLabel myNameLabel = new JLabel();
|
||||
private JLabel myRepositoryLabel = new JLabel();
|
||||
private JPanel myPanel = new JPanel(new BorderLayout());
|
||||
|
||||
private MyTableRenderer() {
|
||||
myPanel.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, 1));
|
||||
// setting border.left on myPanel doesn't prevent from myRepository being painted on left empty area
|
||||
myNameLabel.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 0));
|
||||
|
||||
myRepositoryLabel.setFont(UIUtil.getLabelFont(UIUtil.FontSize.SMALL));
|
||||
myPanel.add(myNameLabel, BorderLayout.WEST);
|
||||
myPanel.add(myRepositoryLabel, BorderLayout.EAST);
|
||||
myNameLabel.setOpaque(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list,
|
||||
Object value,
|
||||
int index,
|
||||
boolean isSelected,
|
||||
boolean cellHasFocus) {
|
||||
if (value instanceof RepoPackage) {
|
||||
RepoPackage repoPackage = (RepoPackage) value;
|
||||
String name = repoPackage.getName();
|
||||
if (myCurrentlyInstalling.contains(name)) {
|
||||
name += " (installing)";
|
||||
}
|
||||
myNameLabel.setText(name);
|
||||
myRepositoryLabel.setText(repoPackage.getRepoUrl());
|
||||
Component orig = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
final Color fg = orig.getForeground();
|
||||
myNameLabel.setForeground(myInstalledPackages.contains(name) ? PlatformColors.BLUE : fg);
|
||||
}
|
||||
myRepositoryLabel.setForeground(Color.GRAY);
|
||||
|
||||
final Color bg;
|
||||
if (isSelected) {
|
||||
bg = UIUtil.getListSelectionBackground();
|
||||
}
|
||||
else {
|
||||
bg = index % 2 == 1 ? UIUtil.getListBackground() : UIUtil.getDecoratedRowColor();
|
||||
}
|
||||
myPanel.setBackground(bg);
|
||||
myNameLabel.setBackground(bg);
|
||||
myRepositoryLabel.setBackground(bg);
|
||||
return myPanel;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.webcore.packaging.ManageRepoDialog">
|
||||
<grid id="cbd77" binding="myMainPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<xy x="48" y="54" width="550" height="342"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children/>
|
||||
</grid>
|
||||
</form>
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.intellij.webcore.packaging;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.InputValidator;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.AnActionButton;
|
||||
import com.intellij.ui.AnActionButtonRunnable;
|
||||
import com.intellij.ui.AnActionButtonUpdater;
|
||||
import com.intellij.ui.ToolbarDecorator;
|
||||
import com.intellij.ui.components.JBList;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import java.awt.*;
|
||||
|
||||
public class ManageRepoDialog extends DialogWrapper {
|
||||
private JPanel myMainPanel;
|
||||
private JBList myList;
|
||||
private boolean myEnabled;
|
||||
|
||||
public ManageRepoDialog(Project project, final PackageManagementService controller) {
|
||||
super(project, false);
|
||||
init();
|
||||
setTitle("Manage Repositories");
|
||||
final DefaultListModel repoModel = new DefaultListModel();
|
||||
for(String repoUrl: controller.getAllRepositories()) {
|
||||
repoModel.addElement(repoUrl);
|
||||
}
|
||||
myList = new JBList();
|
||||
myList.setModel(repoModel);
|
||||
myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
|
||||
myList.addListSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent event) {
|
||||
final Object selected = myList.getSelectedValue();
|
||||
myEnabled = controller.canModifyRepository((String) selected);
|
||||
}
|
||||
});
|
||||
|
||||
final ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myList).disableUpDownActions();
|
||||
decorator.setAddActionName("Add repository");
|
||||
decorator.setRemoveActionName("Remove repository from list");
|
||||
decorator.setEditActionName("Edit repository URL");
|
||||
|
||||
decorator.setAddAction(new AnActionButtonRunnable() {
|
||||
@Override
|
||||
public void run(AnActionButton button) {
|
||||
String url = Messages.showInputDialog("Please input repository URL", "Repository URL", null);
|
||||
if (!repoModel.contains(url) && !StringUtil.isEmptyOrSpaces(url)) {
|
||||
repoModel.addElement(url);
|
||||
controller.addRepository(url);
|
||||
}
|
||||
}
|
||||
});
|
||||
decorator.setEditAction(new AnActionButtonRunnable() {
|
||||
@Override
|
||||
public void run(AnActionButton button) {
|
||||
final String oldValue = (String)myList.getSelectedValue();
|
||||
|
||||
String url = Messages.showInputDialog("Please edit repository URL", "Repository URL", null, oldValue, new InputValidator() {
|
||||
@Override
|
||||
public boolean checkInput(String inputString) {
|
||||
return !repoModel.contains(inputString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canClose(String inputString) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (!StringUtil.isEmptyOrSpaces(url) && !oldValue.equals(url)) {
|
||||
repoModel.addElement(url);
|
||||
repoModel.removeElement(oldValue);
|
||||
controller.removeRepository(oldValue);
|
||||
controller.addRepository(url);
|
||||
}
|
||||
}
|
||||
});
|
||||
decorator.setRemoveAction(new AnActionButtonRunnable() {
|
||||
@Override
|
||||
public void run(AnActionButton button) {
|
||||
String selected = (String)myList.getSelectedValue();
|
||||
controller.removeRepository(selected);
|
||||
repoModel.removeElement(selected);
|
||||
button.setEnabled(false);
|
||||
}
|
||||
});
|
||||
decorator.setRemoveActionUpdater(new AnActionButtonUpdater() {
|
||||
@Override
|
||||
public boolean isEnabled(AnActionEvent e) {
|
||||
return myEnabled;
|
||||
}
|
||||
});
|
||||
decorator.setEditActionUpdater(new AnActionButtonUpdater() {
|
||||
@Override
|
||||
public boolean isEnabled(AnActionEvent e) {
|
||||
return myEnabled;
|
||||
}
|
||||
});
|
||||
|
||||
final JPanel panel = decorator.createPanel();
|
||||
panel.setPreferredSize(new Dimension(800, 600));
|
||||
myMainPanel.add(panel);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
return myMainPanel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
package com.intellij.webcore.packaging;
|
||||
|
||||
import com.intellij.util.CatchingConsumer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public abstract class PackageManagementService {
|
||||
/**
|
||||
* Returns the list of URLs for all configured package repositories.
|
||||
*
|
||||
* @return list of URLs, or null if the repository management is not supported by this package management service.
|
||||
*/
|
||||
@Nullable
|
||||
public List<String> getAllRepositories() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the user can change the URL of the specified repository or remove it from the list.
|
||||
*
|
||||
* @param repositoryUrl the URL to check
|
||||
* @return true if can be modified, false otherwise.
|
||||
*/
|
||||
public boolean canModifyRepository(String repositoryUrl) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void addRepository(String repositoryUrl) {
|
||||
}
|
||||
|
||||
public void removeRepository(String repositoryUrl) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all packages in all configured repositories. Called in a background thread
|
||||
* and may initiate network connections. May return cached data.
|
||||
*
|
||||
* @return the list of all packages in all repositories
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract List<RepoPackage> getAllPackages() throws IOException;
|
||||
|
||||
/**
|
||||
* Reloads the lists of packages for all configured repositories and returns the results. Called in a background thread
|
||||
* and may initiate network connections. May not return cached data.
|
||||
*
|
||||
* @return the list of all packages in all repositories
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract List<RepoPackage> reloadAllPackages() throws IOException;
|
||||
|
||||
/**
|
||||
* Returns the cached list of all packages in all configured repositories, or an empty list if there is no cached information available.
|
||||
*
|
||||
* @return the list of all packages or an empty list.
|
||||
*/
|
||||
public List<RepoPackage> getAllPackagesCached() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the 'install to user' checkbox should be visible.
|
||||
*/
|
||||
public boolean canInstallToUser() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text of the 'install to user' checkbox.
|
||||
*
|
||||
* @return the text of the 'install to user' checkbox.
|
||||
*/
|
||||
public String getInstallToUserText() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the 'install to user' checkbox should be initially selected.
|
||||
*/
|
||||
public boolean isInstallToUserSelected() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the 'install to user' checkbox is checked or unchecked.
|
||||
*/
|
||||
public void installToUserChanged(boolean newValue) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of packages which are currently installed.
|
||||
*
|
||||
* @return the collection of currently installed packages.
|
||||
*/
|
||||
public abstract Collection<InstalledPackage> getInstalledPackages() throws IOException;
|
||||
|
||||
/**
|
||||
* Installs the specified package. Called in the event dispatch thread; needs to take care of spawning a background task itself.
|
||||
*
|
||||
* @param repoPackage the package to install
|
||||
* @param version the version selected by the user, or null if the checkbox to install a specific version is not checked
|
||||
* @param forceUpgrade if true, the latest version of the package is installed even if there is already an installed version
|
||||
* @param extraOptions additional options entered by the user
|
||||
* @param listener the listener that must be called to publish information about the installation progress
|
||||
* @param installToUser the state of the "install to user" checkbox (ignore if not applicable)
|
||||
*/
|
||||
public abstract void installPackage(RepoPackage repoPackage, @Nullable String version, boolean forceUpgrade,
|
||||
@Nullable String extraOptions, Listener listener, boolean installToUser);
|
||||
|
||||
public abstract void uninstallPackages(List<InstalledPackage> installedPackages, Listener listener);
|
||||
|
||||
public abstract void fetchPackageVersions(String packageName, CatchingConsumer<List<String>, Exception> consumer);
|
||||
|
||||
public abstract void fetchPackageDetails(String packageName, CatchingConsumer<String, Exception> consumer);
|
||||
|
||||
public interface Listener {
|
||||
/**
|
||||
* Fired when the installation of the specified package is started.
|
||||
*
|
||||
* @param packageName the name of the package being installed.
|
||||
*/
|
||||
void operationStarted(String packageName);
|
||||
|
||||
/**
|
||||
* Fired when the installation of the specified package has been completed (successfully or unsuccessfully).
|
||||
*
|
||||
* @param packageName the name of the installed package.
|
||||
* @param errorDescription null if the package has been installed successfully, error message otherwise.
|
||||
*/
|
||||
void operationFinished(String packageName, @Nullable String errorDescription);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.intellij.webcore.packaging;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Sergey Simonchik
|
||||
*/
|
||||
public abstract class PackageManagementServiceEx extends PackageManagementService {
|
||||
|
||||
public abstract void updatePackage(@NotNull InstalledPackage installedPackage,
|
||||
@Nullable String version,
|
||||
@NotNull Listener listener);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.intellij.webcore.packaging;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class PackageVersionComparator implements Comparator<String> {
|
||||
public static final Comparator<String> VERSION_COMPARATOR = new PackageVersionComparator();
|
||||
|
||||
@Override
|
||||
public int compare(String version1, String version2) {
|
||||
final List<String> vs1 = parse(version1);
|
||||
final List<String> vs2 = parse(version2);
|
||||
int result = 0;
|
||||
for (int i = 0; i < vs1.size() && i < vs2.size(); i++) {
|
||||
result = vs1.get(i).compareTo(vs2.get(i));
|
||||
if (result != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result == 0) {
|
||||
return vs1.size() - vs2.size();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String replace(@NotNull String s) {
|
||||
final Map<String, String> sub = ImmutableMap.of("pre", "c",
|
||||
"preview", "c",
|
||||
"rc", "c",
|
||||
"dev", "@");
|
||||
final String tmp = sub.get(s);
|
||||
if (tmp != null) {
|
||||
s = tmp;
|
||||
}
|
||||
if (s.equals(".") || s.equals("-")) {
|
||||
return null;
|
||||
}
|
||||
if (s.matches("[0-9]+")) {
|
||||
try {
|
||||
final long value = Long.parseLong(s);
|
||||
return String.format("%08d", value);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return "*" + s;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<String> parse(@Nullable String s) {
|
||||
// Version parsing from pkg_resources ensures that all the "pre", "alpha", "rc", etc. are sorted correctly
|
||||
if (s == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final Pattern COMPONENT_RE = Pattern.compile("\\d+|[a-z]+|\\.|-|.+");
|
||||
final List<String> results = new ArrayList<String>();
|
||||
final Matcher matcher = COMPONENT_RE.matcher(s);
|
||||
while (matcher.find()) {
|
||||
final String component = replace(matcher.group());
|
||||
if (component == null) {
|
||||
continue;
|
||||
}
|
||||
results.add(component);
|
||||
}
|
||||
for (int i = results.size() - 1; i > 0; i--) {
|
||||
if ("00000000".equals(results.get(i))) {
|
||||
results.remove(i);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
results.add("*final");
|
||||
return results;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package com.intellij.webcore.packaging;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogBuilder;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.HyperlinkAdapter;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import java.awt.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class PackagesNotificationPanel {
|
||||
private final JEditorPane myEditorPane = new JEditorPane();
|
||||
private final Project myProject;
|
||||
private final Map<String, Runnable> myLinkHandlers = new HashMap<String, Runnable>();
|
||||
private String myErrorTitle;
|
||||
private String myErrorDescription;
|
||||
|
||||
public PackagesNotificationPanel(Project project) {
|
||||
myProject = project;
|
||||
myEditorPane.setBackground(UIManager.getColor("ArrowButton.background"));
|
||||
myEditorPane.setContentType("text/html");
|
||||
myEditorPane.setEditable(false);
|
||||
myEditorPane.addHyperlinkListener(new HyperlinkAdapter() {
|
||||
@Override
|
||||
protected void hyperlinkActivated(HyperlinkEvent e) {
|
||||
final Runnable handler = myLinkHandlers.get(e.getDescription());
|
||||
if (handler != null) {
|
||||
handler.run();
|
||||
}
|
||||
else if (myErrorTitle != null && myErrorDescription != null) {
|
||||
showError(myProject, myErrorTitle, myErrorDescription);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void showError(@NotNull Project project, @NotNull String title, @NotNull String description) {
|
||||
doShowError(title, description, new DialogBuilder(project));
|
||||
}
|
||||
|
||||
public static void showError(@NotNull Component owner, @NotNull String title, @NotNull String description) {
|
||||
doShowError(title, description, new DialogBuilder(owner));
|
||||
}
|
||||
|
||||
private static void doShowError(String title, String description, DialogBuilder builder) {
|
||||
builder.setTitle(title);
|
||||
final JTextArea textArea = new JTextArea();
|
||||
textArea.setEditable(false);
|
||||
textArea.setText(description);
|
||||
textArea.setWrapStyleWord(false);
|
||||
textArea.setLineWrap(true);
|
||||
final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(textArea);
|
||||
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
final JPanel panel = new JPanel(new BorderLayout(10, 0));
|
||||
panel.setPreferredSize(new Dimension(600, 400));
|
||||
panel.add(scrollPane, BorderLayout.CENTER);
|
||||
panel.add(new JBLabel("Details:", Messages.getErrorIcon(), SwingConstants.LEFT), BorderLayout.NORTH);
|
||||
builder.setCenterPanel(panel);
|
||||
builder.setButtonsAlignment(SwingConstants.CENTER);
|
||||
builder.addOkAction();
|
||||
builder.show();
|
||||
}
|
||||
|
||||
public void showResult(String packageName, @Nullable String errorDescription) {
|
||||
if (StringUtil.isEmpty(errorDescription)) {
|
||||
showSuccess("Package successfully installed.");
|
||||
}
|
||||
else {
|
||||
String title = "Install packages failed";
|
||||
final String firstLine = title + ": Error occurred when installing package " + packageName + ". ";
|
||||
showError(firstLine + "<a href=\"xxx\">Details...</a>",
|
||||
title,
|
||||
firstLine + errorDescription);
|
||||
}
|
||||
}
|
||||
|
||||
public void addLinkHandler(String key, Runnable handler) {
|
||||
myLinkHandlers.put(key, handler);
|
||||
}
|
||||
|
||||
public JComponent getComponent() {
|
||||
return myEditorPane;
|
||||
}
|
||||
|
||||
public void showSuccess(String text) {
|
||||
showContent(text, MessageType.INFO.getPopupBackground());
|
||||
}
|
||||
|
||||
private void showContent(String text, final Color background) {
|
||||
myEditorPane.removeAll();
|
||||
myEditorPane.setText(UIUtil.toHtml(text));
|
||||
myEditorPane.setBackground(background);
|
||||
myEditorPane.setVisible(true);
|
||||
myErrorTitle = null;
|
||||
myErrorDescription = null;
|
||||
}
|
||||
|
||||
public void showError(String text, final String detailsTitle, final String detailsDescription) {
|
||||
showContent(text, MessageType.ERROR.getPopupBackground());
|
||||
myErrorTitle = detailsTitle;
|
||||
myErrorDescription = detailsDescription;
|
||||
}
|
||||
|
||||
public void showWarning(String text) {
|
||||
showContent(text, MessageType.WARNING.getPopupBackground());
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
myEditorPane.setVisible(false);
|
||||
}
|
||||
|
||||
public boolean hasLinkHandler(String key) {
|
||||
return myLinkHandlers.containsKey(key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.intellij.webcore.packaging;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* User: catherine
|
||||
*/
|
||||
public class RepoPackage implements Comparable {
|
||||
private final String myName;
|
||||
private final String myRepoUrl;
|
||||
@Nullable final String myLatestVersion;
|
||||
|
||||
public RepoPackage(String name, String repoUrl) {
|
||||
myName = name;
|
||||
myRepoUrl = repoUrl;
|
||||
myLatestVersion = null;
|
||||
}
|
||||
|
||||
public RepoPackage(String name, String repoUrl, @Nullable String latestVersion) {
|
||||
myName = name;
|
||||
myRepoUrl = repoUrl;
|
||||
myLatestVersion = latestVersion;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
public String getRepoUrl() {
|
||||
return myRepoUrl;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getLatestVersion() {
|
||||
return myLatestVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Object o) {
|
||||
if (o instanceof RepoPackage)
|
||||
return myName.compareTo(((RepoPackage)o).getName());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user