IJPL-156230 merge: update balloons ui

GitOrigin-RevId: 30ee775078f295f69cdeb39cc14879223c4f22a0
This commit is contained in:
Aleksandr Krasilnikov
2024-06-04 16:08:16 +02:00
committed by intellij-monorepo-bot
parent 3d19d3c1e5
commit 286ea02437
5 changed files with 108 additions and 41 deletions

View File

@@ -74,8 +74,10 @@ apply.somehow.status.message.cant.apply.some=Cannot apply {0, number} of {1, num
merge.dialog.apply.partially.resolved.changes.confirmation.message=There {0, choice, 0#'{1, choice, 1#is|2#are}'|1#is|2#are} {0, choice, 0#|1#one change|2#{0, number} changes}{0, choice, 0#|1#'{1, choice, 0#|1# and }'}{1, choice, 0#|1#one conflict|2#{1, number} conflicts} left unprocessed.\nSave changes and mark the conflict resolved anyway?
apply.patch.partially.resolved.changes.confirmation.message=There {0, choice, 1#is one hunk|2#are {0, number} hunks} left unprocessed.\nSave changes and finish resolve?
apply.partially.resolved.merge.dialog.title=Apply Changes
merge.all.changes.processed.message.text=All changes have been processed.<br><a href="">Save changes and finish merging</a>
apply.patch.all.changes.processed.message.text=All hunks have been processed.<br><a href=\"\">Save changes and finish resolve</a>
merge.all.changes.processed.title.text=All changes have been processed
merge.all.changes.processed.message.text=Save changes and finish merging
apply.patch.all.changes.processed.title.text=All hunks have been processed
apply.patch.all.changes.processed.message.text=Save changes and finish resolve
merge.save.and.finish.button=Save and &Finish
merge.continue.button=&Continue
merge.color.options.background.color.label=Important

View File

@@ -58,10 +58,7 @@ import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageDialogBuilder;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.LineTokenizer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.ex.Range;
@@ -78,6 +75,7 @@ import com.intellij.util.concurrency.annotations.RequiresEdt;
import com.intellij.util.concurrency.annotations.RequiresWriteLock;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.xml.util.XmlStringUtil;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import org.jetbrains.annotations.ApiStatus;
@@ -717,8 +715,9 @@ public class MergeThreesideViewer extends ThreesideTextDiffViewerEx {
JComponent component = getEditor().getComponent();
RelativePoint point = new RelativePoint(component, new Point(component.getWidth() / 2, JBUIScale.scale(5)));
String message = DiffBundle.message("merge.all.changes.processed.message.text");
DiffUtil.showSuccessPopup(message, point, this, () -> {
String title = DiffBundle.message("merge.all.changes.processed.title.text");
@NlsSafe String message = XmlStringUtil.wrapInHtmlTag(DiffBundle.message("merge.all.changes.processed.message.text"), "a");
DiffBalloons.showSuccessPopup(title, message, point, this, () -> {
if (isDisposed() || myLoadingPanel.isLoading()) return;
destroyChangedBlocks();
myMergeContext.finishMerge(MergeResult.RESOLVED);

View File

@@ -0,0 +1,93 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.diff.util
import com.intellij.icons.AllIcons
import com.intellij.icons.ExpUiIcons
import com.intellij.openapi.Disposable
import com.intellij.openapi.ui.popup.Balloon
import com.intellij.openapi.ui.popup.JBPopupFactory
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.NlsContexts
import com.intellij.ui.ExperimentalUI
import com.intellij.ui.awt.RelativePoint
import com.intellij.ui.dsl.builder.HyperlinkEventAction
import com.intellij.ui.dsl.builder.panel
import com.intellij.ui.dsl.gridLayout.UnscaledGaps
import com.intellij.ui.dsl.gridLayout.UnscaledGapsY
import com.intellij.util.ui.EmptyIcon
import com.intellij.util.ui.JBUI
import java.awt.Color
import javax.swing.Icon
object DiffBalloons {
@JvmStatic
fun showSuccessPopup(title: @NlsContexts.PopupContent String,
message: @NlsContexts.PopupContent String,
point: RelativePoint,
disposable: Disposable,
hyperlinkHandler: Runnable) {
createAndShowBalloon(
title, message,
if (ExperimentalUI.isNewUI()) ExpUiIcons.Status.Success else null,
JBUI.CurrentTheme.Editor.Tooltip.SUCCESS_BACKGROUND,
JBUI.CurrentTheme.Editor.Tooltip.SUCCESS_BORDER,
point,
disposable,
HyperlinkEventAction { hyperlinkHandler.run() }
)
}
@JvmStatic
fun showWarningPopup(title: @NlsContexts.PopupContent String,
message: @NlsContexts.PopupContent String,
point: RelativePoint,
disposable: Disposable
) {
createAndShowBalloon(
title, message,
if (ExperimentalUI.isNewUI()) ExpUiIcons.Status.Warning else AllIcons.General.Warning,
JBUI.CurrentTheme.Editor.Tooltip.WARNING_BACKGROUND,
JBUI.CurrentTheme.Editor.Tooltip.WARNING_BORDER,
point,
disposable
)
}
private fun createAndShowBalloon(
title: @NlsContexts.PopupContent String,
message: @NlsContexts.PopupContent String,
icon: Icon?,
fillColor: Color,
borderColor: Color,
point: RelativePoint,
disposable: Disposable,
listener: HyperlinkEventAction? = null
) {
val balloonContent = panel {
val gap = 6
row {
if (icon!= null) {
icon(icon).customize(UnscaledGaps(right = gap, bottom = gap))
}
text(title).bold().customize(UnscaledGaps(bottom = gap))
}.customize(UnscaledGapsY.EMPTY)
row {
if (icon!= null) {
icon(EmptyIcon.create(icon)).customize(UnscaledGaps(right = gap))
}
text(message, action = listener ?: HyperlinkEventAction.HTML_HYPERLINK_INSTANCE).customize(UnscaledGaps.EMPTY)
}
}.andTransparent()
val balloon = JBPopupFactory.getInstance()
.createBalloonBuilder(balloonContent)
.setBorderInsets(JBUI.insets(12, 13, 12, 21))
.setFillColor(fillColor)
.setBorderColor(borderColor)
.setAnimationCycle(200)
.createBalloon()
balloon.show(point, Balloon.Position.below)
Disposer.register(disposable, balloon)
}
}

View File

@@ -68,10 +68,7 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.DialogWrapperDialog;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.WindowWrapper;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.HtmlBuilder;
@@ -90,7 +87,6 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.ui.*;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBPanel;
import com.intellij.ui.components.panels.VerticalLayout;
@@ -110,8 +106,6 @@ import org.jetbrains.annotations.*;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import java.awt.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -565,30 +559,6 @@ public final class DiffUtil {
return result.wrapWithHtmlBody().toString();
}
public static void showSuccessPopup(@NotNull @NlsContexts.PopupContent String message,
@NotNull RelativePoint point,
@NotNull Disposable disposable,
@Nullable Runnable hyperlinkHandler) {
HyperlinkListener listener = null;
if (hyperlinkHandler != null) {
listener = new HyperlinkAdapter() {
@Override
protected void hyperlinkActivated(@NotNull HyperlinkEvent e) {
hyperlinkHandler.run();
}
};
}
Color bgColor = MessageType.INFO.getPopupBackground();
Balloon balloon = JBPopupFactory.getInstance()
.createHtmlTextBalloonBuilder(message, null, bgColor, listener)
.setAnimationCycle(200)
.createBalloon();
balloon.show(point, Balloon.Position.below);
Disposer.register(disposable, balloon);
}
//
// Titles
//

View File

@@ -3,14 +3,16 @@ package com.intellij.openapi.vcs.changes.patch.tool;
import com.intellij.diff.DiffContext;
import com.intellij.diff.merge.*;
import com.intellij.diff.util.DiffBalloons;
import com.intellij.diff.util.DiffUserDataKeys;
import com.intellij.diff.util.DiffUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diff.DiffBundle;
import com.intellij.openapi.ui.MessageDialogBuilder;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.scale.JBUIScale;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -112,8 +114,9 @@ final class ApplyPatchMergeTool implements MergeTool {
int yOffset = new RelativePoint(getResultEditor().getComponent(), new Point(0, JBUIScale.scale(5))).getPoint(component).y;
RelativePoint point = new RelativePoint(component, new Point(component.getWidth() / 2, yOffset));
String message = DiffBundle.message("apply.patch.all.changes.processed.message.text");
DiffUtil.showSuccessPopup(message, point, this, () -> {
String title = DiffBundle.message("apply.patch.all.changes.processed.title.text");
@NlsSafe String message = XmlStringUtil.wrapInHtmlTag(DiffBundle.message("apply.patch.all.changes.processed.message.text"), "a");
DiffBalloons.showSuccessPopup(title, message, point, this, () -> {
if (isDisposed()) return;
myMergeContext.finishMerge(MergeResult.RESOLVED);
});