mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-04 23:39:07 +07:00
IDEA-335157 cleanup
GitOrigin-RevId: 6b70d6c25694ac77ab7c82c1f464a4a7c22e798c
This commit is contained in:
committed by
intellij-monorepo-bot
parent
904c6d68ea
commit
5afd693a2e
@@ -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
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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?,
|
||||
|
||||
Reference in New Issue
Block a user