[platform] making ApplicationInfoEx#getApplicationSvgIconUrl and #getSmallApplicationSvgIconUrl non-null, per .xsd

GitOrigin-RevId: dfe298178bd444b7f71653f3be6af3aa6cc5d63a
This commit is contained in:
Roman Shevchenko
2023-06-14 15:38:46 +02:00
committed by intellij-monorepo-bot
parent 8b34fb6386
commit 034577d3fc
6 changed files with 60 additions and 99 deletions

View File

@@ -22,23 +22,23 @@ public abstract class ApplicationInfoEx extends ApplicationInfo {
public abstract String getAboutImageUrl();
/**
* @deprecated use {@link #getSmallApplicationSvgIconUrl()} instead
*/
/** @deprecated please use {@link #getSmallApplicationSvgIconUrl()} instead */
@Deprecated
@ApiStatus.ScheduledForRemoval
public abstract @NotNull String getSmallIconUrl();
/**
* Return path to an SVG file containing icon of the current version of the product. The path is a relative path inside the product's JAR
* files. It may return a special icon for EAP builds.
* Returns a path to an SVG icon of the product.
* The path is a relative path inside the product's JAR files.
* Please note that release and EAP builds may have different icons.
*/
public abstract @Nullable String getApplicationSvgIconUrl();
public abstract @NotNull String getApplicationSvgIconUrl();
/**
* Return path to an SVG file containing a variant of {@link #getApplicationSvgIconUrl() the product icon} which is suitable for 16x16 images.
* Returns a path to an SVG file,
* containing a variant of {@link #getApplicationSvgIconUrl() the product icon} which is suitable for 16x16 images.
*/
public abstract @Nullable String getSmallApplicationSvgIconUrl();
public abstract @NotNull String getSmallApplicationSvgIconUrl();
public abstract String getToolWindowIconUrl();

View File

@@ -343,6 +343,9 @@ public final class ApplicationInfoImpl extends ApplicationInfoEx {
}
}
requireNonNull(mySvgIconUrl, "Missing attribute: //icon@svg");
requireNonNull(mySmallSvgIconUrl, "Missing attribute: //icon@svg-small");
overrideFromProperties();
essentialPluginsIds.sort(null);
@@ -515,16 +518,16 @@ public final class ApplicationInfoImpl extends ApplicationInfoEx {
}
@Override
public @Nullable String getApplicationSvgIconUrl() {
public @NotNull String getApplicationSvgIconUrl() {
return isEAP() && mySvgEapIconUrl != null ? mySvgEapIconUrl : mySvgIconUrl;
}
@Override
public @Nullable String getSmallApplicationSvgIconUrl() {
public @NotNull String getSmallApplicationSvgIconUrl() {
return getSmallApplicationSvgIconUrl(isEAP());
}
public @Nullable String getSmallApplicationSvgIconUrl(boolean isEap) {
public @NotNull String getSmallApplicationSvgIconUrl(boolean isEap) {
return isEap && mySmallSvgEapIconUrl != null ? mySmallSvgEapIconUrl : mySmallSvgIconUrl;
}

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.ide.impl.ui;
import com.intellij.icons.AllIcons;
@@ -11,23 +11,17 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import static java.util.Objects.requireNonNullElse;
import static com.intellij.openapi.util.NotNullLazyValue.lazy;
final class ProductIconsImpl implements ProductIcons {
private final NotNullLazyValue<Icon> myProductIcon = NotNullLazyValue.createValue(() -> {
ApplicationInfoEx appInfo = ApplicationInfoEx.getInstanceEx();
@SuppressWarnings("deprecation") String fallback = appInfo.getSmallIconUrl();
return IconLoader.getIcon(requireNonNullElse(appInfo.getSmallApplicationSvgIconUrl(), fallback), ProductIconsImpl.class.getClassLoader());
});
private final NotNullLazyValue<Icon> myProjectIcon = NotNullLazyValue.createValue(
() -> PlatformUtils.isJetBrainsProduct()
? AllIcons.Actions.ProjectDirectory
: myProductIcon.getValue()
private final NotNullLazyValue<Icon> myProductIcon = lazy(
() -> IconLoader.getIcon(ApplicationInfoEx.getInstanceEx().getSmallApplicationSvgIconUrl(), ProductIconsImpl.class.getClassLoader())
);
private final NotNullLazyValue<Icon> myProjectNodeIcon = NotNullLazyValue.createValue(
() -> PlatformUtils.isJetBrainsProduct()
? AllIcons.Nodes.IdeaProject
: myProductIcon.getValue()
private final NotNullLazyValue<Icon> myProjectIcon = lazy(
() -> PlatformUtils.isJetBrainsProduct() ? AllIcons.Actions.ProjectDirectory : myProductIcon.getValue()
);
private final NotNullLazyValue<Icon> myProjectNodeIcon = lazy(
() -> PlatformUtils.isJetBrainsProduct() ? AllIcons.Nodes.IdeaProject : myProductIcon.getValue()
);
@Override

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.wm.impl.welcomeScreen;
import com.intellij.application.Topics;
@@ -59,21 +59,19 @@ public final class WelcomeScreenComponentFactory {
NonOpaquePanel panel = new NonOpaquePanel(new BorderLayout());
String welcomeScreenLogoUrl = appInfo.getApplicationSvgIconUrl();
if (welcomeScreenLogoUrl != null) {
Icon icon = IconLoader.getIcon(welcomeScreenLogoUrl, WelcomeScreenComponentFactory.class.getClassLoader());
JLabel logo = new JLabel() {
@Override
public void updateUI() {
super.updateUI();
float scale = JBUIScale.scale(28f) / icon.getIconWidth();
Icon smallLogoIcon = IconUtil.scale(icon, null, scale);
setIcon(smallLogoIcon);
}
};
logo.setBorder(JBUI.Borders.empty(29, 0, 27, 0));
logo.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(logo, BorderLayout.WEST);
}
Icon icon = IconLoader.getIcon(welcomeScreenLogoUrl, WelcomeScreenComponentFactory.class.getClassLoader());
JLabel logo = new JLabel() {
@Override
public void updateUI() {
super.updateUI();
float scale = JBUIScale.scale(28f) / icon.getIconWidth();
Icon smallLogoIcon = IconUtil.scale(icon, null, scale);
setIcon(smallLogoIcon);
}
};
logo.setBorder(JBUI.Borders.empty(29, 0, 27, 0));
logo.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(logo, BorderLayout.WEST);
String applicationName = getAppName();
JLabel appName = new JLabel(applicationName);

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
@file:Suppress("JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE", "ReplaceGetOrSet")
package com.intellij.ui
@@ -18,8 +18,10 @@ import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.DialogWrapper
import com.intellij.openapi.util.*
import com.intellij.openapi.util.Condition
import com.intellij.openapi.util.IconLoader.setUseDarkIcons
import com.intellij.openapi.util.SystemInfo
import com.intellij.openapi.util.SystemInfoRt
import com.intellij.openapi.wm.IdeFrame
import com.intellij.ui.AppIcon.MacAppIcon
import com.intellij.ui.icons.findSvgData
@@ -28,8 +30,6 @@ import com.intellij.ui.scale.JBUIScale.scale
import com.intellij.ui.scale.JBUIScale.sysScale
import com.intellij.ui.scale.ScaleContext
import com.intellij.ui.svg.loadWithSizes
import com.intellij.util.IconUtil
import com.intellij.util.ImageLoader.loadFromResource
import com.intellij.util.JBHiDPIScaledImage
import com.intellij.util.PlatformUtils
import com.intellij.util.io.URLUtil
@@ -68,20 +68,15 @@ fun updateAppWindowIcon(window: Window) {
val smallSvgIconUrl = appInfo.smallApplicationSvgIconUrl
val scaleContext = ScaleContext.create(window)
if (SystemInfoRt.isUnix) {
loadApplicationIconImage(svgPath = svgIconUrl, scaleContext = scaleContext, size = 128)?.let {
loadAppIconImage(svgPath = svgIconUrl, scaleContext = scaleContext, size = 128)?.let {
images.add(it)
}
}
val element = loadApplicationIconImage(svgPath = smallSvgIconUrl, scaleContext = scaleContext, size = 32)
if (element != null) {
images.add(element)
loadAppIconImage(svgPath = smallSvgIconUrl, scaleContext = scaleContext, size = 32)?.let {
images.add(it)
}
if (SystemInfoRt.isWindows) {
@Suppress("DEPRECATION")
loadApplicationIconImage(svgPath = smallSvgIconUrl,
scaleContext = scaleContext,
size = 16,
fallbackPath = appInfo.smallIconUrl)?.let {
loadAppIconImage(svgPath = smallSvgIconUrl, scaleContext = scaleContext, size = 16)?.let {
images.add(it)
}
}
@@ -106,14 +101,7 @@ fun updateAppWindowIcon(window: Window) {
}
}
/**
* Returns a hidpi-aware image.
*/
private fun loadApplicationIconImage(svgPath: String?, scaleContext: ScaleContext, size: Int, fallbackPath: String? = null): Image? {
val image = if (svgPath == null) null else loadAppIconImage(svgPath, scaleContext, size)
return image ?: loadFromResource(path = fallbackPath ?: return null, aClass = AppUIUtil::class.java)
}
/** Returns a HiDPI-aware image. */
private fun loadAppIconImage(svgPath: String, scaleContext: ScaleContext, size: Int): Image? {
val pixScale = scaleContext.getScale(DerivedScaleType.PIX_SCALE).toFloat()
val svgData = findSvgData(path = svgPath, classLoader = AppUIUtil::class.java.classLoader, pixScale = pixScale)
@@ -128,29 +116,12 @@ fun loadSmallApplicationIcon(scaleContext: ScaleContext,
size: Int = 16,
isReleaseIcon: Boolean = !ApplicationInfoImpl.getShadowInstance().isEAP): Icon {
val appInfo = ApplicationInfoImpl.getShadowInstance()
var smallIconUrl = appInfo.smallApplicationSvgIconUrl
if (isReleaseIcon && appInfo.isEAP && appInfo is ApplicationInfoImpl) {
val smallIconUrl = if (isReleaseIcon && appInfo.isEAP && appInfo is ApplicationInfoImpl) {
// This is the way to load the release icon in EAP. Needed for some actions.
smallIconUrl = appInfo.getSmallApplicationSvgIconUrl(false)
}
var image = if (smallIconUrl == null) null else loadAppIconImage(smallIconUrl, scaleContext, size)
if (image != null) {
return JBImageIcon(image)
}
@Suppress("DEPRECATION")
val fallbackSmallIconUrl = appInfo.smallIconUrl
image = loadFromResource(fallbackSmallIconUrl, AppUIUtil::class.java) ?: error("Can't load '$fallbackSmallIconUrl'")
val icon = JBImageIcon(image)
val width = icon.iconWidth
if (width == size) {
return icon
}
val scale = size / width.toFloat()
return IconUtil.scale(icon = icon, ancestor = null, scale = scale)
appInfo.getSmallApplicationSvgIconUrl(false)
} else appInfo.smallApplicationSvgIconUrl
val image = loadAppIconImage(smallIconUrl, scaleContext, size) ?: error("Can't load '${smallIconUrl}'")
return JBImageIcon(image)
}
fun findAppIcon(): String? {
@@ -163,14 +134,8 @@ fun findAppIcon(): String? {
}
}
}
val svgIconUrl = ApplicationInfoImpl.getShadowInstance().applicationSvgIconUrl
if (svgIconUrl != null) {
val url = ApplicationInfoEx::class.java.getResource(svgIconUrl)
if (url != null && URLUtil.FILE_PROTOCOL == url.protocol) {
return URLUtil.urlToFile(url).absolutePath
}
}
return null
val url = ApplicationInfoEx::class.java.getResource(ApplicationInfoImpl.getShadowInstance().applicationSvgIconUrl)
return if (url != null && URLUtil.FILE_PROTOCOL == url.protocol) URLUtil.urlToFile(url).absolutePath else null
}
object AppUIUtil {
@@ -197,7 +162,7 @@ object AppUIUtil {
@JvmStatic
fun loadApplicationIcon(ctx: ScaleContext, size: Int): Icon? {
val url = ApplicationInfoImpl.getShadowInstance().applicationSvgIconUrl
return if (url == null) null else loadAppIconImage(url, ctx, size)?.let { JBImageIcon(it) }
return loadAppIconImage(url, ctx, size)?.let { JBImageIcon(it) }
}
@JvmStatic

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.application.impl;
import com.intellij.testFramework.PlatformTestUtil;
@@ -14,7 +14,7 @@ import static org.assertj.core.api.Assertions.assertThat;
public class ApplicationInfoTest {
@Test
public void shortenCompanyName() throws Exception {
public void shortenCompanyName() {
assertThat(createAppInfo(new XmlElement("company", Map.of("name", "Google Inc."), List.of(), null)).getShortCompanyName()).isEqualTo("Google");
assertThat(createAppInfo(new XmlElement("company", Map.of("name", "JetBrains s.r.o."), List.of(), null)).getShortCompanyName()).isEqualTo("JetBrains");
assertThat(createAppInfo(new XmlElement("company", Map.of("shortName", "Acme Inc."), List.of(), null)).getShortCompanyName()).isEqualTo("Acme Inc.");
@@ -22,9 +22,9 @@ public class ApplicationInfoTest {
@Test
public void pluginsHostProperty() {
@SuppressWarnings("SpellCheckingInspection") String host = "IntellijIdeaRulezzz";
var host = "IntellijIdeaRulezzz";
PlatformTestUtil.withSystemProperty(ApplicationInfoImpl.IDEA_PLUGINS_HOST_PROPERTY, host, () -> {
ApplicationInfoImpl info = createAppInfo();
var info = createAppInfo();
assertThat(info.getPluginManagerUrl()).contains(host).doesNotContain(ApplicationInfoImpl.DEFAULT_PLUGINS_HOST);
assertThat(info.getPluginsListUrl()).contains(host).doesNotContain(ApplicationInfoImpl.DEFAULT_PLUGINS_HOST);
assertThat(info.getPluginsDownloadUrl()).contains(host).doesNotContain(ApplicationInfoImpl.DEFAULT_PLUGINS_HOST);
@@ -33,7 +33,8 @@ public class ApplicationInfoTest {
}
public static @NotNull ApplicationInfoImpl createAppInfo(@NotNull XmlElement @NotNull ... content) {
List<XmlElement> children = new ArrayList<>(List.of(content));
var children = new ArrayList<>(List.of(content));
children.add(new XmlElement("icon", Map.of("svg", "xxx.svg", "svg-small", "xxx.svg"), List.of(), null));
children.add(new XmlElement("plugins", Map.of(), List.of(), null));
return new ApplicationInfoImpl(new XmlElement("state", Map.of(), children, null));
}