blob: e3ee04111e9538fd8df958e47158bff5f6a9c05c [file] [log] [blame]
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.updateSettings.impl;
import com.intellij.ide.BrowserUtil;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.BrowserHyperlinkListener;
import com.intellij.ui.JBColor;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.Collection;
import java.util.List;
/**
* @author pti
*/
class UpdateInfoDialog extends AbstractUpdateDialog {
private final UpdateChannel myUpdatedChannel;
private final Collection<PluginDownloader> myUpdatedPlugins;
private final BuildInfo myLatestBuild;
private final PatchInfo myPatch;
private final boolean myWriteProtected;
protected UpdateInfoDialog(@NotNull UpdateChannel channel,
boolean enableLink,
Collection<PluginDownloader> updatedPlugins,
Collection<IdeaPluginDescriptor> incompatiblePlugins) {
super(enableLink);
myUpdatedChannel = channel;
myUpdatedPlugins = updatedPlugins;
myLatestBuild = channel.getLatestBuild();
myPatch = myLatestBuild != null ? myLatestBuild.findPatchForCurrentBuild() : null;
myWriteProtected = myPatch != null && !new File(PathManager.getHomePath()).canWrite();
getCancelAction().putValue(DEFAULT_ACTION, Boolean.TRUE);
if (myLatestBuild != null) {
initLicensingInfo(myUpdatedChannel, myLatestBuild);
}
init();
if (incompatiblePlugins != null && !incompatiblePlugins.isEmpty()) {
final boolean onePluginFound = incompatiblePlugins.size() == 1;
String incompatibilityError = "Incompatible with new version plugin";
incompatibilityError += (onePluginFound ? " is" : "s are") + " detected: ";
incompatibilityError += onePluginFound ? "" : "<br>";
incompatibilityError += StringUtil.join(incompatiblePlugins, new Function<IdeaPluginDescriptor, String>() {
@Override
public String fun(IdeaPluginDescriptor downloader) {
return downloader.getName();
}
}, "<br/>");
setErrorText(incompatibilityError);
}
}
@Override
protected JComponent createCenterPanel() {
return new UpdateInfoPanel().myPanel;
}
@NotNull
@Override
protected Action[] createActions() {
List<Action> actions = ContainerUtil.newArrayList();
if (myPatch != null) {
final boolean canRestart = ApplicationManager.getApplication().isRestartCapable();
String button = IdeBundle.message(canRestart ? "updates.download.and.restart.button" : "updates.download.and.install.button");
actions.add(new AbstractAction(button) {
{
setEnabled(!myWriteProtected);
}
@Override
public void actionPerformed(ActionEvent e) {
downloadPatch(canRestart);
}
});
}
List<ButtonInfo> buttons = myLatestBuild.getButtons();
if (buttons.isEmpty()) {
actions.add(new AbstractAction(IdeBundle.message("updates.more.info.button")) {
@Override
public void actionPerformed(ActionEvent e) {
openDownloadPage();
}
});
}
else {
for (ButtonInfo info : buttons) {
if (!info.isDownload() || myPatch == null) {
actions.add(new ButtonAction(info));
}
}
}
actions.add(new AbstractAction(IdeBundle.message("updates.ignore.update.button")) {
@Override
public void actionPerformed(ActionEvent e) {
String build = myLatestBuild.getNumber().asStringWithoutProductCode();
UpdateSettings.getInstance().getIgnoredBuildNumbers().add(build);
doCancelAction();
}
});
actions.add(getCancelAction());
return actions.toArray(new Action[actions.size()]);
}
@Override
protected String getCancelButtonText() {
return IdeBundle.message("updates.remind.later.button");
}
private void downloadPatch(final boolean canRestart) {
final UpdateChecker.DownloadPatchResult result = UpdateChecker.downloadAndInstallPatch(myLatestBuild);
if (result == UpdateChecker.DownloadPatchResult.SUCCESS) {
if (myUpdatedPlugins != null && !myUpdatedPlugins.isEmpty()) {
new PluginUpdateInfoDialog(getContentPanel(), myUpdatedPlugins, true){
@Override
protected boolean downloadModal() {
return true;
}
@Override
protected String getOkButtonText() {
return IdeBundle.message(canRestart ? "update.restart.plugins.update.action" : "update.shutdown.plugins.update.action");
}
}.show();
}
restart();
}
else if (result == UpdateChecker.DownloadPatchResult.FAILED) {
openDownloadPage();
}
}
private void openDownloadPage() {
BrowserUtil.browse(myUpdatedChannel.getHomePageUrl());
}
private static class ButtonAction extends AbstractAction {
private final String myUrl;
private ButtonAction(ButtonInfo info) {
super(info.getName());
myUrl = info.getUrl();
}
@Override
public void actionPerformed(ActionEvent e) {
BrowserUtil.browse(myUrl);
}
}
private class UpdateInfoPanel {
private JPanel myPanel;
private JEditorPane myUpdateMessage;
private JBLabel myCurrentVersion;
private JBLabel myNewVersion;
private JBLabel myPatchLabel;
private JBLabel myPatchInfo;
private JEditorPane myMessageArea;
private JEditorPane myLicenseArea;
public UpdateInfoPanel() {
ApplicationInfo appInfo = ApplicationInfo.getInstance();
ApplicationNamesInfo appNames = ApplicationNamesInfo.getInstance();
String message = myLatestBuild.getMessage();
final String fullProductName = appNames.getFullProductName();
if (message == null) {
message = IdeBundle.message("updates.new.version.available", fullProductName);
}
final String homePageUrl = myUpdatedChannel.getHomePageUrl();
if (!StringUtil.isEmptyOrSpaces(homePageUrl)) {
final int idx = message.indexOf(fullProductName);
if (idx >= 0) {
message = message.substring(0, idx) +
"<a href=\'" + homePageUrl + "\'>" + fullProductName + "</a>" + message.substring(idx + fullProductName.length());
}
}
configureMessageArea(myUpdateMessage, message, null, new BrowserHyperlinkListener());
myCurrentVersion.setText(formatVersion(appInfo.getFullVersion(), appInfo.getBuild().asStringWithoutProductCode()));
myNewVersion.setText(formatVersion(myLatestBuild.getVersion(), myLatestBuild.getNumber().asStringWithoutProductCode()));
if (myPatch != null) {
myPatchInfo.setText(myPatch.getSize() + " MB");
}
else {
myPatchLabel.setVisible(false);
myPatchInfo.setVisible(false);
}
if (myWriteProtected) {
message = IdeBundle.message("updates.write.protected", appNames.getProductName(), PathManager.getHomePath());
configureMessageArea(myMessageArea, message, JBColor.RED, null);
}
else {
configureMessageArea(myMessageArea);
}
if (mySubscribtionLicense && myLicenseInfo != null) {
configureMessageArea(myLicenseArea, myLicenseInfo, myPaidUpgrade ? JBColor.RED : null, null);
}
}
private String formatVersion(String version, String build) {
String[] parts = version.split("\\.", 3);
String major = parts.length > 0 ? parts[0] : "0";
String minor = parts.length > 1 ? parts[1] : "0";
String patch = parts.length > 2 ? parts[2] : "0";
version = major + '.' + minor + '.' + patch;
return IdeBundle.message("updates.version.info", version, build);
}
}
}