i10n - extract JDK/SDK downloader and detector messages to resource bundles

GitOrigin-RevId: 23c8574e02d0cac96d80318a1e0652c5919e0358
This commit is contained in:
Eugene Petrenko
2020-03-22 19:02:37 +00:00
committed by intellij-monorepo-bot
parent 9c1286d2d2
commit ecca1d2ff8
13 changed files with 139 additions and 115 deletions
@@ -1,10 +1,11 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.projectRoots.impl;
import com.intellij.notification.NotificationDisplayType;
import com.intellij.notification.NotificationGroup;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService;
import com.intellij.openapi.roots.ui.configuration.SdkListPresenter;
import com.intellij.openapi.roots.ui.configuration.UnknownSdk;
@@ -43,10 +44,8 @@ public class UnknownSdkBalloonNotification {
Set<String> usages = new TreeSet<>();
for (Map.Entry<? extends UnknownSdk, UnknownSdkLocalSdkFix> entry : localFixes.entrySet()) {
UnknownSdkLocalSdkFix fix = entry.getValue();
String usage = "\"" + entry.getKey().getSdkName() + "\"" +
" is set to " +
fix.getVersionString() +
" <br/> " +
String usageText = ProjectBundle.message("notification.text.sdk.usage.is.set.to", entry.getKey().getSdkName(), fix.getVersionString());
String usage = usageText + "<br/>" +
SdkListPresenter.presentDetectedSdkPath(fix.getExistingSdkHome());
usages.add(usage);
}
@@ -56,12 +55,12 @@ public class UnknownSdkBalloonNotification {
Map.Entry<? extends UnknownSdk, UnknownSdkLocalSdkFix> entry = localFixes.entrySet().iterator().next();
UnknownSdk info = entry.getKey();
String sdkTypeName = info.getSdkType().getPresentableName();
title = sdkTypeName + " is configured";
change = "Change " + sdkTypeName + "...";
title = ProjectBundle.message("notification.title.sdk.configured", sdkTypeName);
change = ProjectBundle.message("notification.link.change.sdk", sdkTypeName);
}
else {
title = "SDKs are configured";
change = "Change SDKs...";
title = ProjectBundle.message("notification.title.sdks.configured");
change = ProjectBundle.message("notification.link.change.sdks");
}
SDK_CONFIGURED_GROUP.createNotification(title, message.toString(), NotificationType.INFORMATION, null)
@@ -149,14 +149,13 @@ public class UnknownSdkEditorNotification {
}
String sdkTypeName = mySdkType.getPresentableName();
String quotedSdkName = "\"" + mySdkName + "\"";
String notificationText = ProjectBundle.message("config.unknown.sdk.notification.text", sdkTypeName, quotedSdkName);
String notificationText = ProjectBundle.message("config.unknown.sdk.notification.text", sdkTypeName, mySdkName);
String configureText = ProjectBundle.message("config.unknown.sdk.configure");
boolean hasDownload = myFix != null && mySdk != null;
String downloadText = hasDownload ? ProjectBundle.message("config.unknown.sdk.download", myFix.getDownloadDescription()) : "";
String intentionActionText =
hasDownload ? downloadText : ProjectBundle.message("config.unknown.sdk.configure.missing", sdkTypeName, quotedSdkName);
hasDownload ? downloadText : ProjectBundle.message("config.unknown.sdk.configure.missing", sdkTypeName, mySdkName);
EditorNotificationPanel notification = new EditorNotificationPanel() {
@Override
@@ -164,7 +164,7 @@ public class UnknownSdkTracker {
@NotNull Consumer<? super Sdk> onSdkNameReady,
@NotNull Consumer<? super Sdk> onCompleted) {
SdkDownloadTask task;
String title = "Configuring SDK";
String title = ProjectBundle.message("progress.title.downloading.sdk");
try {
task = ProgressManager.getInstance().run(new Task.WithResult<SdkDownloadTask, RuntimeException>(project, title, true) {
@Override
@@ -10,6 +10,7 @@ import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectBundle
import com.intellij.openapi.projectRoots.JdkUtil
import com.intellij.openapi.projectRoots.ProjectJdkTable
import com.intellij.openapi.projectRoots.SdkType
@@ -70,7 +71,7 @@ class JdkAuto : UnknownSdkResolver, JdkDownloaderBase {
return object : UnknownSdkLookup {
val lazyDownloadModel: List<JdkItem> by lazy {
indicator.pushState()
indicator.text = "Downloading JDK list..."
indicator.text = ProjectBundle.message("progress.title.downloading.jdk.list")
try {
JdkListDownloader.getInstance().downloadModelForJdkInstaller(indicator)
} catch(e: ProcessCanceledException) {
@@ -110,7 +111,7 @@ class JdkAuto : UnknownSdkResolver, JdkDownloaderBase {
private fun resolveHintPath(sdk: UnknownSdk, indicator: ProgressIndicator) :UnknownSdkLocalSdkFix? {
val hint = resolveHint(sdk)
val path = hint?.path ?: return null
indicator.text = "Resolving hint path: $path..."
indicator.text = ProjectBundle.message("progress.text.resolving.hint.path", path)
if (!File(path).isDirectory) return null
val version = runCatching {
@@ -157,7 +158,7 @@ class JdkAuto : UnknownSdkResolver, JdkDownloaderBase {
}
val lazyLocalJdks by lazy {
indicator.text = "Detecting local JDKs..."
indicator.text = ProjectBundle.message("progress.text.detecting.local.jdks")
val result = mutableListOf<JavaLocalSdkFix>()
SdkDetector.getInstance().detectSdks(sdkType, indicator, object : DetectedSdkListener {
@@ -187,7 +188,7 @@ class JdkAuto : UnknownSdkResolver, JdkDownloaderBase {
}
private fun tryUsingExistingSdk(req: JdkRequirement, sdkType: SdkType, indicator: ProgressIndicator): List<JavaLocalSdkFix> {
indicator.text = "Checking existing SDKs..."
indicator.text = ProjectBundle.message("progress.text.checking.existing.jdks")
val result = mutableListOf<JavaLocalSdkFix>()
for (it in runReadAction { ProjectJdkTable.getInstance().allJdks }) {
@@ -3,6 +3,7 @@ package com.intellij.openapi.projectRoots.impl.jdkDownloader
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectBundle
import com.intellij.openapi.projectRoots.SdkTypeId
import com.intellij.openapi.ui.ComboBox
import com.intellij.openapi.ui.DialogWrapper
@@ -28,9 +29,6 @@ class JdkDownloadDialog(
val sdkType: SdkTypeId,
val items: List<JdkItem>
) : DialogWrapper(project, parentComponent, false, IdeModalityType.PROJECT) {
companion object {
const val DIALOG_TITLE = "Download JDK"
}
private val panel: JComponent
private var installDirTextField: TextFieldWithBrowseButton
@@ -39,7 +37,7 @@ class JdkDownloadDialog(
private lateinit var selectedPath: String
init {
title = DIALOG_TITLE
title = ProjectBundle.message("dialog.title.download.jdk")
setResizable(false)
val defaultItem = items.filter { it.isDefaultItem }.firstOrNull() /*pick the newest default JDK */
@@ -78,7 +76,7 @@ class JdkDownloadDialog(
installDirTextField = textFieldWithBrowseButton(
project = project,
browseDialogTitle = "Select Path to Install JDK",
browseDialogTitle = ProjectBundle.message("dialog.title.select.path.to.install.jdk"),
fileChooserDescriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor()
)
@@ -94,12 +92,12 @@ class JdkDownloadDialog(
}
panel = panel {
row("Vendor:") { vendorComboBox.invoke().sizeGroup("combo").focused() }
row("Version:") { versionComboBox.invoke().sizeGroup("combo") }
row("Location:") { installDirTextField.invoke() }
row(ProjectBundle.message("dialog.row.jdk.vendor")) { vendorComboBox.invoke().sizeGroup("combo").focused() }
row(ProjectBundle.message("dialog.row.jdk.version")) { versionComboBox.invoke().sizeGroup("combo") }
row(ProjectBundle.message("dialog.row.jdk.location")) { installDirTextField.invoke() }
}
myOKAction.putValue(Action.NAME, "Download")
myOKAction.putValue(Action.NAME, ProjectBundle.message("dialog.button.download.jdk"))
init()
selectVersions(defaultItem.product)
@@ -4,19 +4,21 @@ package com.intellij.openapi.projectRoots.impl.jdkDownloader
import com.intellij.ide.DataManager
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.invokeLater
import com.intellij.openapi.diagnostic.ControlFlowException
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.progress.Task
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectBundle
import com.intellij.openapi.projectRoots.*
import com.intellij.openapi.projectRoots.SimpleJavaSdkType.notSimpleJavaSdkTypeIfAlternativeExistsAndNotDependentSdkType
import com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownload
import com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownloadTask
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.util.NlsProgress.ProgressTitle
import com.intellij.openapi.util.registry.Registry
import org.jetbrains.annotations.Nls
import java.util.function.Consumer
import javax.swing.JComponent
@@ -37,18 +39,23 @@ internal class JdkDownloader : SdkDownload, JdkDownloaderBase {
val project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(parentComponent))
if (project?.isDisposed == true) return
val items = runTaskAndReportError(project,
"Downloading the list of available JDKs...",
"Failed to download the list of installable JDKs") {
JdkListDownloader.getInstance().downloadForUI(it)
} ?: return
val items = try {
computeInBackground(project, ProjectBundle.message("progress.title.downloading.jdk.list")) {
JdkListDownloader.getInstance().downloadForUI(it)
}
}
catch (e: Throwable) {
if (e is ControlFlowException) throw e
LOG.warn("Failed to download the list of installable JDKs. ${e.message}", e)
null
}
if (project?.isDisposed == true) return
if (items.isEmpty()) {
if (items.isNullOrEmpty()) {
Messages.showMessageDialog(project,
"No JDK packages are available for download",
JdkDownloadDialog.DIALOG_TITLE,
ProjectBundle.message("error.message.no.jdk.for.download"),
ProjectBundle.message("error.message.title.download.jdk"),
Messages.getErrorIcon()
)
return
@@ -57,42 +64,30 @@ internal class JdkDownloader : SdkDownload, JdkDownloaderBase {
val (jdkItem, jdkHome) = JdkDownloadDialog(project, parentComponent, sdkTypeId, items).selectJdkAndPath() ?: return
/// prepare the JDK to be installed (e.g. create home dir, write marker file)
val request = runTaskAndReportError(project, "Preparing JDK target folder...", "Failed to prepare JDK installation to $jdkHome") {
JdkInstaller.getInstance().prepareJdkInstallation(jdkItem, jdkHome)
} ?: return
val request = try {
computeInBackground(project, ProjectBundle.message("progress.title.preparing.jdk")) {
JdkInstaller.getInstance().prepareJdkInstallation(jdkItem, jdkHome)
}
} catch (e: Throwable) {
if (e is ControlFlowException) throw e
LOG.warn("Failed to prepare JDK installation to $jdkHome. ${e.message}", e)
Messages.showMessageDialog(project,
ProjectBundle.message("error.message.text.jdk.install.failed", jdkHome),
ProjectBundle.message("error.message.title.download.jdk"),
Messages.getErrorIcon()
)
return
}
sdkCreatedCallback.accept(newDownloadTask(request, project))
}
private inline fun <T : Any> runTaskAndReportError(project: Project?,
title: String,
errorMessage: String,
crossinline action: (ProgressIndicator) -> T): T? {
val task = object : Task.WithResult<T?, Exception>(project, title, true) {
override fun compute(indicator: ProgressIndicator): T? {
try {
return action(indicator)
}
catch (e: ProcessCanceledException) {
throw e
}
catch (e: Exception) {
val msg = "$errorMessage. ${e.message}"
LOG.warn(msg, e)
invokeLater {
Messages.showMessageDialog(project,
msg,
JdkDownloadDialog.DIALOG_TITLE,
Messages.getErrorIcon()
)
}
return null
}
}
}
return ProgressManager.getInstance().run(task)
}
private inline fun <T : Any> computeInBackground(project: Project?,
@Nls title: @ProgressTitle String,
crossinline action: (ProgressIndicator) -> T): T =
ProgressManager.getInstance().run(object : Task.WithResult<T, Exception>(project, title, true) {
override fun compute(indicator: ProgressIndicator) = action(indicator)
})
}
internal interface JdkDownloaderBase {
@@ -10,10 +10,12 @@ import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectBundle
import com.intellij.openapi.util.SystemInfo
import com.intellij.openapi.util.io.FileUtil
import com.intellij.util.Urls
import com.intellij.util.io.HttpRequests
import org.jetbrains.annotations.Nls
import java.io.File
import java.io.IOException
import java.util.*
@@ -89,18 +91,17 @@ class JdkInstaller {
return uniqueDir.absoluteFile
}
fun validateInstallDir(selectedPath: String): Pair<File?, String?> {
if (selectedPath.isBlank()) return null to "Target path is empty"
fun validateInstallDir(selectedPath: String): Pair<File?, @Nls String?> {
if (selectedPath.isBlank()) return null to ProjectBundle.message("dialog.message.error.target.path.empty")
val targetDir = runCatching { File(FileUtil.expandUserHome(selectedPath)) }.getOrElse { t ->
LOG.warn("Failed to resolve user path: $selectedPath. ${t.message}", t)
return null to (t.message ?: "Failed to resolve path")
return null to ProjectBundle.message("dialog.message.error.resolving.path")
}
if (targetDir.isFile) return null to "Target path is an existing file"
if (targetDir.isFile) return null to ProjectBundle.message("dialog.message.error.target.path.exists.file")
if (targetDir.isDirectory && targetDir.listFiles()?.isNotEmpty() == true) {
return null to "Target path is an existing non-empty directory: $targetDir"
return null to ProjectBundle.message("dialog.message.error.target.path.exists.nonEmpty.dir")
}
return targetDir to null
@@ -113,13 +114,13 @@ class JdkInstaller {
JDK_INSTALL_LISTENER_EP_NAME.extensions.forEach { it.onJdkDownloadStarted(request, project) }
val item = request.item
indicator?.text = "Installing ${item.fullPresentationText}..."
indicator?.text = ProjectBundle.message("progress.text.installing.jdk.1", item.fullPresentationText)
val targetDir = request.installDir
val url = Urls.parse(item.url, false) ?: error("Cannot parse download URL: ${item.url}")
if (!url.scheme.equals("https", ignoreCase = true)) error("URL must use https:// protocol, but was: $url")
indicator?.text2 = "Downloading"
indicator?.text2 = ProjectBundle.message("progress.text2.downloading.jdk")
val downloadFile = File(PathManager.getTempPath(), "jdk-${item.archiveFileName}")
try {
try {
@@ -132,25 +133,23 @@ class JdkInstaller {
throw RuntimeException("Failed to download ${item.fullPresentationText} from $url. ${t.message}", t)
}
val invalidFileMessage = "Check your internet connection and try again later"
val sizeDiff = downloadFile.length() - item.archiveSize
if (sizeDiff != 0L) {
throw RuntimeException("The downloaded ${item.fullPresentationText} has incorrect file size,\n" +
"the difference is ${sizeDiff.absoluteValue} bytes.\n" +
invalidFileMessage)
"Check your internet connection and try again later")
}
val actualHashCode = Files.asByteSource(downloadFile).hash(Hashing.sha256()).toString()
if (!actualHashCode.equals(item.sha256, ignoreCase = true)) {
throw RuntimeException("Failed to verify SHA-256 checksum for ${item.fullPresentationText}n\n" +
throw RuntimeException("Failed to verify SHA-256 checksum for ${item.fullPresentationText}\n\n" +
"The actual value is $actualHashCode,\n" +
"but expected ${item.sha256} was expected\n" +
invalidFileMessage)
"Check your internet connection and try again later")
}
indicator?.isIndeterminate = true
indicator?.text2 = "Unpacking"
indicator?.text2 = ProjectBundle.message("progress.text2.unpacking.jdk")
try {
val decompressor = item.packageType.openDecompressor(downloadFile)
@@ -172,7 +171,6 @@ class JdkInstaller {
catch (t: Throwable) {
//if we were cancelled in the middle or failed, let's clean up
FileUtil.delete(targetDir)
if (t is ControlFlowException) throw t
throw t
}
finally {
@@ -213,7 +211,7 @@ class JdkInstaller {
}
private fun writeMarkerFile(request: JdkInstallRequest) {
val markerFile = request.installDir / "intellij-downloader-info.txt"
val markerFile = File(request.installDir.path + "-intellij-downloader-info.txt")
markerFile.writeText("Download started on ${Date()}\n${request.item}")
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.roots.ui.configuration;
import com.intellij.icons.AllIcons;
@@ -129,11 +129,11 @@ public final class SdkListPresenter extends ColoredListCellRenderer<SdkListItem>
if (sdk != null) {
setIcon(((SdkType)sdk.getSdkType()).getIcon());
append(ProjectBundle.message("project.roots.project.jdk.inherited"), SimpleTextAttributes.REGULAR_ATTRIBUTES);
append(" " + sdk.getName(), SimpleTextAttributes.GRAYED_ATTRIBUTES);
append(" ");
append(sdk.getName(), SimpleTextAttributes.GRAYED_ATTRIBUTES);
}
else {
String str = ProjectBundle.message("jdk.combo.box.project.item");
append(str, SimpleTextAttributes.ERROR_ATTRIBUTES);
append(ProjectBundle.message("jdk.combo.box.project.item"), SimpleTextAttributes.ERROR_ATTRIBUTES);
}
}
else if (value instanceof SuggestedItem) {
@@ -142,13 +142,13 @@ public final class SdkListPresenter extends ColoredListCellRenderer<SdkListItem>
String home = item.getHomePath();
String version = item.getVersion();
Icon icon1 = type.getIconForAddAction();
if (Objects.equals(icon1, IconUtil.getAddIcon())) icon1 = type.getIcon();
if (icon1 == null) icon1 = IconUtil.getAddIcon();
Icon icon = icon1;
Icon icon = type.getIconForAddAction();
if (Objects.equals(icon, IconUtil.getAddIcon())) icon = type.getIcon();
if (icon == null) icon = IconUtil.getAddIcon();
setIcon(icon);
append(presentDetectedSdkPath(home));
append(" " + version, SimpleTextAttributes.GRAYED_ATTRIBUTES);
append(" ");
append(version, SimpleTextAttributes.GRAYED_ATTRIBUTES);
}
else if (value instanceof ActionItem) {
ActionItem item = (ActionItem)value;
@@ -162,11 +162,11 @@ public final class SdkListPresenter extends ColoredListCellRenderer<SdkListItem>
Icon icon = sdkType.getIcon();
if (icon == null) icon = AllIcons.General.Add;
setIcon(icon);
append(sdkType.getPresentableName() + "...");
append(ProjectBundle.message("sdk.configure.add.sdkType.subAction", sdkType.getPresentableName()));
break;
case DOWNLOAD:
setIcon(template.getIcon());
append("Download " + sdkType.getPresentableName() + "...");
append(ProjectBundle.message("sdk.configure.download.subAction", sdkType.getPresentableName()));
break;
}
}
@@ -174,11 +174,11 @@ public final class SdkListPresenter extends ColoredListCellRenderer<SdkListItem>
switch (item.myRole) {
case ADD:
setIcon(template.getIcon());
append("Add " + sdkType.getPresentableName() + "...");
append(ProjectBundle.message("sdk.configure.add.sdkType.action", sdkType.getPresentableName()));
break;
case DOWNLOAD:
setIcon(template.getIcon());
append("Download " + sdkType.getPresentableName() + "...");
append(ProjectBundle.message("sdk.configure.download.action", sdkType.getPresentableName()));
break;
}
}
@@ -196,7 +196,8 @@ public final class SdkListPresenter extends ColoredListCellRenderer<SdkListItem>
String version = sdk.getVersionString();
if (version == null) version = ((SdkType)sdk.getSdkType()).getPresentableName();
append(" " + version, SimpleTextAttributes.GRAYED_ATTRIBUTES);
append(" ");
append(version, SimpleTextAttributes.GRAYED_ATTRIBUTES);
}
else if (value instanceof NoneSdkItem) {
SdkAppearanceService.getInstance()
@@ -211,7 +212,8 @@ public final class SdkListPresenter extends ColoredListCellRenderer<SdkListItem>
String version = item.getVersionString();
if (version == null) version = item.getSdkType().getPresentableName();
append(" " + version, SimpleTextAttributes.GRAYED_ATTRIBUTES);
append(" ");
append(version, SimpleTextAttributes.GRAYED_ATTRIBUTES);
}
else {
SdkAppearanceService.getInstance()
@@ -6,6 +6,7 @@ import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.projectRoots.SdkType
import com.intellij.openapi.util.NlsProgress.ProgressTitle
import org.jetbrains.annotations.Contract
import org.jetbrains.annotations.Nls
@@ -45,7 +46,7 @@ interface SdkLookupBuilder {
fun withProject(project: Project?): SdkLookupBuilder
@Contract(pure = true)
fun withProgressMessageTitle(@Nls message: String): SdkLookupBuilder
fun withProgressMessageTitle(@Nls message: @ProgressTitle String): SdkLookupBuilder
/**
* Use these SDKs to test first, the [withSdkName] option has a higher priority
@@ -12,6 +12,7 @@ import com.intellij.openapi.progress.Task
import com.intellij.openapi.progress.util.ProgressIndicatorBase
import com.intellij.openapi.progress.util.ProgressIndicatorListenerAdapter
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectBundle
import com.intellij.openapi.projectRoots.ProjectJdkTable
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.projectRoots.SdkType
@@ -19,6 +20,7 @@ import com.intellij.openapi.projectRoots.impl.UnknownSdkTracker
import com.intellij.openapi.roots.ui.configuration.UnknownSdkResolver.UnknownSdkLookup
import com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownloadTracker
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.NlsProgress.ProgressTitle
import com.intellij.openapi.wm.ex.ProgressIndicatorEx
import com.intellij.util.Consumer
import org.jetbrains.annotations.Nls
@@ -28,7 +30,8 @@ import java.util.function.Predicate
private data class SdkLookupBuilderImpl(
val project: Project? = null,
val progressMessageTitle: String? = null,
@Nls
val progressMessageTitle: @ProgressTitle String? = null,
val progressIndicator: ProgressIndicator? = null,
val sdkName: String? = null,
@@ -48,7 +51,7 @@ private data class SdkLookupBuilderImpl(
private val onSdkResolved: (Sdk?) -> Unit = { }
) : SdkLookupBuilder {
override fun withProject(project: Project?) = copy(project = project)
override fun withProgressMessageTitle(@Nls message: String) = copy(progressMessageTitle = message)
override fun withProgressMessageTitle(@Nls message: @ProgressTitle String) = copy(progressMessageTitle = message)
override fun withSdkName(name: String) = copy(sdkName = name)
override fun withSdkType(sdkType: SdkType) = copy(sdkType = sdkType)
override fun withVersionFilter(filter: (String) -> Boolean) = copy(versionFilter = filter)
@@ -251,7 +254,8 @@ internal class SdkLookupImpl : SdkLookup {
private fun SdkLookupBuilderImpl.runWithProgress(rootProgressIndicator: ProgressIndicatorBase,
onCancelled: () -> Unit,
action: (ProgressIndicator) -> Unit) {
val title = progressMessageTitle ?: "Resolving" + (sdkType?.presentableName ?: "SDK") + "..."
val sdkTypeName = sdkType?.presentableName ?: ProjectBundle.message("sdk")
val title = progressMessageTitle ?: ProjectBundle.message("sdk.lookup.resolving.sdk.progress", sdkTypeName)
ProgressManager.getInstance().run(object : Task.Backgroundable(project, title, true, ALWAYS_BACKGROUND) {
override fun run(indicator: ProgressIndicator) {
val middleMan = object : ProgressIndicatorBase() {
@@ -336,7 +336,7 @@ public class ProjectSdksModel implements SdkModel {
SdkDownload downloadExtension = SdkDownload.EP_NAME.findFirstSafe(it -> it.supportsDownload(type));
if (downloadExtension == null) continue;
String downloadText = ProjectBundle.message("sdk.configure.download.action", type.getPresentableName());
String downloadText = ProjectBundle.message("sdk.configure.download.subAction", type.getPresentableName());
NewSdkAction downloadAction = new NewSdkAction(type, downloadText, downloadExtension.getIconForDownloadAction(type)) {
@Override
public void actionPerformed(@Nullable Sdk selectedSdk,
@@ -355,7 +355,7 @@ public class ProjectSdksModel implements SdkModel {
public Map<SdkType, NewSdkAction> createAddActions(@Nullable Condition<? super SdkTypeId> filter) {
Map<SdkType, NewSdkAction> result = new LinkedHashMap<>();
for (final SdkType type : getAddableSdkTypes(filter)) {
String addOnDiskText = ProjectBundle.message("sdk.configure.add.default.action", type.getPresentableName());
String addOnDiskText = ProjectBundle.message("sdk.configure.add.sdkType.subAction", type.getPresentableName());
NewSdkAction addAction = new NewSdkAction(type, addOnDiskText, type.getIconForAddAction()) {
@Override
@@ -19,7 +19,6 @@ import com.intellij.openapi.projectRoots.SdkType;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.wm.ex.ProgressIndicatorEx;
import com.intellij.util.Consumer;
@@ -309,11 +308,7 @@ public class SdkDownloadTracker implements Disposable {
if (!myProgressIndicator.isCanceled()) {
LOG.warn("SDK Download failed. " + e.getMessage(), e);
myModalityTracker.invokeLater(() -> {
String actualMessage = e.getMessage();
if (StringUtil.isEmptyOrSpaces(actualMessage)) {
actualMessage = "Failed to download " + type.getPresentableName();
}
Messages.showErrorDialog(actualMessage, getTitle());
Messages.showErrorDialog(ProjectBundle.message("error.message.sdk.download.failed", type.getPresentableName()), getTitle());
});
}
onSdkDownloadCompleted(true);
@@ -32,6 +32,7 @@ project.convert.multiple.output.paths.error=The project uses multiple output pat
framework.detected.info.text={0} {1, choice, 1#framework is|2#frameworks are} detected.
sdk=SDK
sdk.java.name=JDK
sdk.java.unknown.name=Unknown
sdk.java.corrupt.error=Probably SDK installed in ''{0}'' is corrupt
@@ -41,10 +42,13 @@ sdk.table.settings=SDK Table
sdk.unknown.name=Unknown SDK
sdk.list.name.required.error=Please specify SDK name
sdk.list.unique.name.required.error=Please specify a different SDK name
sdk.lookup.resolving.sdk.progress=Resolving {0}...
button.add=Add
button.remove=Remove
sdk.configure.add.fromDisk.action=Add {0} from Disk...
sdk.configure.add.default.action={0}...
sdk.configure.add.sdkType.subAction={0}...
sdk.configure.add.sdkType.action=Add {0}...
sdk.configure.download.subAction=Download {0}...
sdk.configure.download.action=Download {0}...
sdk.configure.downloading=Downloading {0}...
sdk.configure.editor.title=SDK Editor
@@ -247,10 +251,10 @@ library.docs.node=Documentation
configurable.DetectionExcludesConfigurable.display.name=Framework Detection Excludes
configurable.PlatformContentEntriesConfigurable.display.name=Project Structure
config.unknown.sdk.text=SDK
config.unknown.sdk.notification.text={0} {1} is missing
config.unknown.sdk.notification.text={0} "{1}" is missing
config.unknown.sdk.configure=Configure...
config.unknown.sdk.download=Download {0}
config.unknown.sdk.configure.missing=Configure missing {0} {1}
config.unknown.sdk.configure.missing=Configure missing {0} "{1}"
config.unknown.sdk.configuration=SDK configuration
combobox.item.add.sdk=Add SDK
label.text.mark.as=Mark as:
@@ -284,4 +288,32 @@ notification.group.project.loading.error=Project Loading Error
dialog.title.create.project=Create Project
dialog.title.new.project=New Project
label.new.project=New project
item.text.empty.project=Empty Project
item.text.empty.project=Empty Project
progress.title.downloading.sdk=Configuring SDK
notification.title.sdks.configured=SDKs are configured
notification.link.change.sdks=Change SDKs...
notification.link.change.sdk=Change {0}...
notification.title.sdk.configured={0} is configured
notification.text.sdk.usage.is.set.to="{0}" is set to {1}
progress.title.downloading.jdk.list=Downloading JDK list...
progress.text.resolving.hint.path=Resolving hint path: {0}...
progress.text.detecting.local.jdks=Detecting local JDKs...
progress.text.checking.existing.jdks=Checking existing JDKs...
dialog.title.download.jdk=Download JDK
dialog.title.select.path.to.install.jdk=Select Path to Install JDK
dialog.button.download.jdk=Download
dialog.row.jdk.location=Location:
dialog.row.jdk.version=Version:
dialog.row.jdk.vendor=Vendor:
error.message.title.download.jdk=Download JDK
error.message.no.jdk.for.download=No JDK packages are available for download
progress.title.preparing.jdk=Preparing JDK target folder...
error.message.text.jdk.install.failed=Failed to prepare JDK installation to {0}
dialog.message.error.target.path.empty=Target path is empty
dialog.message.error.resolving.path=Failed to resolve path
dialog.message.error.target.path.exists.file=Target path is an existing file
dialog.message.error.target.path.exists.nonEmpty.dir=Target path is an existing non-empty directory
progress.text.installing.jdk.1=Installing {0}...
progress.text2.downloading.jdk=Downloading
progress.text2.unpacking.jdk=Unpacking
error.message.sdk.download.failed=Failed to download {0}