IDEA-335157 cleanup

GitOrigin-RevId: 6b70d6c25694ac77ab7c82c1f464a4a7c22e798c
This commit is contained in:
Vladimir Krivosheev
2023-10-17 20:50:54 +02:00
committed by intellij-monorepo-bot
parent 904c6d68ea
commit 5afd693a2e
8 changed files with 66 additions and 68 deletions

View File

@@ -4,6 +4,7 @@
package com.intellij.ide.ui.customization
import com.intellij.ide.IdeBundle
import com.intellij.ide.ui.customization.CustomActionsSchema.Companion.loadCustomIcon
import com.intellij.ide.ui.customization.CustomizableActionGroupProvider.CustomizableActionGroupRegistrar
import com.intellij.openapi.actionSystem.*
import com.intellij.openapi.actionSystem.impl.PresentationFactory
@@ -151,33 +152,39 @@ class CustomActionsSchema(private val coroutineScope: CoroutineScope?) : Persist
*/
@ApiStatus.Internal
@Throws(Throwable::class)
@JvmStatic
fun loadCustomIcon(path: String): Icon {
val independentPath = FileUtil.toSystemIndependentName(path)
val urlString = if (independentPath.startsWith("file:") || independentPath.startsWith("jar:")) {
independentPath
}
else "file:$independentPath"
else {
"file:$independentPath"
}
val lastDotIndex = urlString.lastIndexOf('.')
val (rawUrl, ext) = if (lastDotIndex != -1) {
val (rawUrl, ext) = if (lastDotIndex == -1) {
urlString to "svg"
}
else {
urlString.substring(0, lastDotIndex) to urlString.substring(lastDotIndex + 1)
}
else urlString to "svg"
val possibleSuffixes = listOf("@2x_dark", "_dark@2x", "_dark", "@2x")
val adjustedUrl = possibleSuffixes.find { rawUrl.endsWith(it) }?.let { rawUrl.removeSuffix(it) } ?: rawUrl
val fullAdjustedUrl = "$adjustedUrl.$ext"
return try {
doLoadCustomIcon(fullAdjustedUrl)
try {
return doLoadCustomIcon(fullAdjustedUrl)
}
catch (t: Throwable) {
// In Light theme we do not fall back on dark icon, so if the original provided path ends with '_dark'
// and there is no icon file without '_dark' suffix, we will fail.
// And in this case, we just need to load the file chosen by the user.
if (urlString != fullAdjustedUrl) {
doLoadCustomIcon(urlString)
if (urlString == fullAdjustedUrl) {
throw t
}
else {
return doLoadCustomIcon(urlString)
}
else throw t
}
}
@@ -189,11 +196,12 @@ class CustomActionsSchema(private val coroutineScope: CoroutineScope?) : Persist
if (w <= 1 || h <= 1) {
throw FileNotFoundException("Failed to find icon by URL: $url")
}
if (w > EmptyIcon.ICON_18.iconWidth || h > EmptyIcon.ICON_18.iconHeight) {
val s = EmptyIcon.ICON_18.iconWidth / w.coerceAtLeast(h).toFloat()
val scale = EmptyIcon.ICON_18.iconWidth / w.coerceAtLeast(h).toFloat()
// ScaledResultIcon will be returned here, so we will be unable to scale it again or get the dark version,
// but we have nothing to do because the icon is too large
return IconUtil.scale(icon, scale = s, ancestor = null)
return IconUtil.scale(icon, scale = scale, ancestor = null)
}
return icon
}
@@ -498,7 +506,7 @@ class CustomActionsSchema(private val coroutineScope: CoroutineScope?) : Persist
presentation.putClientProperty(PROP_ORIGINAL_ICON, originalIcon)
}
val icon = iconCustomizations.get(actionId)?.let { CustomizationUtil.getIconForPath(actionManager, it) }
val icon = iconCustomizations.get(actionId)?.let { getIconForPath(actionManager = actionManager, iconPath = it) }
?: presentation.getClientProperty(PROP_ORIGINAL_ICON)
presentation.icon = icon
presentation.disabledIcon = if (icon == null) null else getDisabledIcon(icon)
@@ -553,4 +561,25 @@ private object ActionUrlComparator : Comparator<ActionUrl> {
return u1.absolutePosition - u2.absolutePosition
}
}
}
internal fun getIconForPath(actionManager: ActionManager, iconPath: String): Icon? {
val reuseFrom = actionManager.getAction(iconPath)
if (reuseFrom != null) {
return getOriginalIconFrom(reuseFrom)
}
else {
try {
return loadCustomIcon(iconPath)
}
catch (e: Throwable) {
LOG.info(e.message)
return null
}
}
}
internal fun getOriginalIconFrom(reuseFrom: AnAction): Icon? {
val presentation = reuseFrom.templatePresentation
return presentation.getClientProperty(CustomActionsSchema.PROP_ORIGINAL_ICON) ?: presentation.icon
}

View File

@@ -342,16 +342,16 @@ public class CustomizableActionsPanel {
if (userObj instanceof String actionId) {
AnAction action = ActionManager.getInstance().getAction(actionId);
if (action != null) {
return Pair.create(actionId, action.getTemplatePresentation().getIcon());
return new Pair<>(actionId, action.getTemplatePresentation().getIcon());
}
}
else if (userObj instanceof Group group) {
return Pair.create(group.getId(), group.getIcon());
return new Pair<>(group.getId(), group.getIcon());
}
else if (userObj instanceof Pair<?, ?> pair) {
Object first = pair.first;
String actionId = first instanceof Group group ? group.getId() : (String)first;
return Pair.create(actionId, (Icon)pair.second);
return new Pair<>(actionId, (Icon)pair.second);
}
return Pair.empty();
}
@@ -392,15 +392,15 @@ public class CustomizableActionsPanel {
AnAction reuseFrom = actionManager.getAction(path);
if (reuseFrom != null) {
Icon toSet = CustomizationUtil.getOriginalIconFrom(reuseFrom);
Icon defaultIcon = CustomizationUtil.getOriginalIconFrom(action);
Icon toSet = CustomActionsSchemaKt.getOriginalIconFrom(reuseFrom);
Icon defaultIcon = CustomActionsSchemaKt.getOriginalIconFrom(action);
node.setUserObject(Pair.create(value, toSet));
schema.addIconCustomization(actionId, toSet != defaultIcon ? path : null);
}
else {
Icon icon;
try {
icon = CustomActionsSchema.loadCustomIcon(path);
icon = CustomActionsSchema.Companion.loadCustomIcon(path);
}
catch (Throwable t) {
Logger.getInstance(CustomizableActionsPanel.class)
@@ -530,8 +530,8 @@ public class CustomizableActionsPanel {
if (path.isEmpty()) {
path = actionId;
}
Icon icon = CustomizationUtil.getIconForPath(ActionManager.getInstance(), path);
newNode.setUserObject(Pair.create(actionId, icon));
Icon icon = CustomActionsSchemaKt.getIconForPath(ActionManager.getInstance(), path);
newNode.setUserObject(new Pair<>(actionId, icon));
}
}

View File

@@ -64,38 +64,10 @@ public final class CustomizationUtil {
private CustomizationUtil() {
}
public static @Nullable Icon getOriginalIconFrom(@NotNull AnAction reuseFrom) {
Presentation presentation = reuseFrom.getTemplatePresentation();
Icon original = presentation.getClientProperty(CustomActionsSchema.PROP_ORIGINAL_ICON);
if (original != null) return original;
return presentation.getIcon();
}
public static @Nullable Icon getIconForPath(@NotNull ActionManager actionManager, @Nullable String iconPath) {
if (iconPath == null) {
return null;
}
AnAction reuseFrom = actionManager.getAction(iconPath);
if (reuseFrom != null) {
return getOriginalIconFrom(reuseFrom);
}
else {
try {
return CustomActionsSchema.loadCustomIcon(iconPath);
}
catch (Throwable t) {
LOG.info(t.getMessage());
return null;
}
}
}
public static ActionGroup correctActionGroup(final ActionGroup group,
final CustomActionsSchema schema,
final String defaultGroupName,
final String rootGroupName,
public static ActionGroup correctActionGroup(ActionGroup group,
CustomActionsSchema schema,
String defaultGroupName,
String rootGroupName,
boolean force) {
if (!force && !schema.isCorrectActionGroup(group, defaultGroupName)) {
return group;

View File

@@ -12,7 +12,6 @@ import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileSystem
import com.intellij.openapi.vfs.local.CoreLocalFileSystem
import com.intellij.util.SmartList
import java.io.File
internal class PathChooserDialogHelper(private val descriptor: FileChooserDescriptor) {
@@ -32,7 +31,7 @@ internal class PathChooserDialogHelper(private val descriptor: FileChooserDescri
}
fun getChosenFiles(files: Array<File>): List<VirtualFile> {
val virtualFiles = files.mapNotNullTo(SmartList()) {
val virtualFiles = files.mapNotNull {
val virtualFile = fileToVirtualFile(it)
if (virtualFile != null && virtualFile.isValid) {
virtualFile
@@ -49,12 +48,10 @@ internal class PathChooserDialogHelper(private val descriptor: FileChooserDescri
}
companion object {
@JvmStatic
private fun fileToVirtualFile(fileSystem: VirtualFileSystem, file: File): VirtualFile? {
return fileSystem.refreshAndFindFileByPath(FileUtilRt.toSystemIndependentName(file.absolutePath))
}
@JvmStatic
fun fileToCoreLocalVirtualFile(dir: File, name: String): VirtualFile? {
return fileToVirtualFile(CoreLocalFileSystem(), File(dir, name))
}

View File

@@ -1,4 +1,4 @@
// 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.
// 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.ui.mac;
import com.intellij.openapi.fileChooser.FileChooser;
@@ -11,13 +11,13 @@ import com.intellij.openapi.vfs.VirtualFileWrapper;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.PathChooserDialogHelper;
import com.intellij.ui.UIBundle;
import com.intellij.util.Consumer;
import com.intellij.util.ui.OwnerOptional;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.io.File;
import java.nio.file.Path;
import java.util.function.Consumer;
public final class MacFileSaverDialog implements FileSaverDialog {
private FileDialog myFileDialog;
@@ -60,7 +60,7 @@ public final class MacFileSaverDialog implements FileSaverDialog {
myFileDialog.setDirectory(baseDir);
myFileDialog.setFile(filename);
myFileDialog.setFilenameFilter(FileChooser.safeInvokeFilter((dir, name) -> {
return myDescriptor.isFileSelectable(PathChooserDialogHelper.fileToCoreLocalVirtualFile(dir, name));
return myDescriptor.isFileSelectable(PathChooserDialogHelper.Companion.fileToCoreLocalVirtualFile(dir, name));
}, false));
myFileDialog.setVisible(true);

View File

@@ -95,7 +95,7 @@ public final class MacPathChooserDialog implements PathChooserDialog, FileChoose
myFileDialog.setFilenameFilter(FileChooser.safeInvokeFilter((dir, name) -> {
return myFileChooserDescriptor.isFileSelectable(PathChooserDialogHelper.fileToCoreLocalVirtualFile(dir, name));
return myFileChooserDescriptor.isFileSelectable(PathChooserDialogHelper.Companion.fileToCoreLocalVirtualFile(dir, name));
}, false));
myFileDialog.setMultipleMode(myFileChooserDescriptor.isChooseMultiple());

View File

@@ -1,4 +1,4 @@
// 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.
// 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.util.ui;
import com.intellij.ide.IdeEventQueue;
@@ -6,10 +6,10 @@ import com.intellij.ide.IdePopupManager;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.util.Consumer;
import javax.swing.*;
import java.awt.*;
import java.util.function.Consumer;
public final class OwnerOptional {
private static Window findOwnerByComponent(Component component) {
@@ -63,21 +63,21 @@ public final class OwnerOptional {
public OwnerOptional ifDialog(Consumer<? super Dialog> consumer) {
if (myPermanentOwner instanceof Dialog) {
consumer.consume((Dialog)myPermanentOwner);
consumer.accept((Dialog)myPermanentOwner);
}
return this;
}
public OwnerOptional ifNull(Consumer<? super Frame> consumer) {
if (myPermanentOwner == null) {
consumer.consume(null);
consumer.accept(null);
}
return this;
}
public OwnerOptional ifWindow(Consumer<? super Window> consumer) {
if (myPermanentOwner != null) {
consumer.consume(myPermanentOwner);
consumer.accept(myPermanentOwner);
}
return this;
}
@@ -87,7 +87,7 @@ public final class OwnerOptional {
if (myPermanentOwner instanceof IdeFrame.Child ideFrameChild) {
myPermanentOwner = WindowManager.getInstance().getFrame(ideFrameChild.getProject());
}
consumer.consume((Frame)this.myPermanentOwner);
consumer.accept((Frame)this.myPermanentOwner);
}
return this;
}

View File

@@ -39,7 +39,7 @@ internal class ImageDataByUrlLoader internal constructor(
override fun isMyClassLoader(classLoader: ClassLoader): Boolean = this.classLoader === classLoader
override fun toString(): String {
return "UrlResolver(ownerClass=${ownerClass?.name}, classLoader=$classLoader, url=$url, useCacheOnLoad=$useCacheOnLoad)"
return "ImageDataByUrlLoader(ownerClass=${ownerClass?.name}, classLoader=$classLoader, url=$url, useCacheOnLoad=$useCacheOnLoad)"
}
}
@@ -81,7 +81,7 @@ internal class ImageDataByPathResourceLoader(
override fun isMyClassLoader(classLoader: ClassLoader): Boolean = this.classLoader === classLoader
override fun toString(): String = "UrlResolver(ownerClass=${ownerClass?.name}, classLoader=$classLoader, path=$path)"
override fun toString(): String = "ImageDataByPathResourceLoader(ownerClass=${ownerClass?.name}, classLoader=$classLoader, path=$path)"
}
private fun resolveUrl(path: String?,