From e2eb3bbb2276bf6c74f937fc3c3fd971bac8dbef Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Mon, 23 Mar 2015 18:57:42 +0300 Subject: [PATCH] Changes according to Dima's comments for https://upsource.labs.intellij.net/idea-community/review/IDEA-COMMUNITY-CR-1732 --- .../execution/impl/ConsoleViewImpl.java | 2 +- ...tDisplayer.java => ArgumentHintLayer.java} | 60 +++++++++++++++---- .../console/CommandLineConsole.java | 2 +- .../com/jetbrains/python/PyBundle.properties | 2 +- 4 files changed, 50 insertions(+), 16 deletions(-) rename python/src/com/jetbrains/commandInterface/console/{MissingArgumentDisplayer.java => ArgumentHintLayer.java} (70%) diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java index bdb1c48f43b3..9eced8b4fc92 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java @@ -504,7 +504,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo * * @param component component to add */ - public final void addWaterMark(@NotNull final JComponent component) { + public final void addLayerToPane(@NotNull final JComponent component) { getComponent(); // Make sure component exists component.setOpaque(false); component.setVisible(true); diff --git a/python/src/com/jetbrains/commandInterface/console/MissingArgumentDisplayer.java b/python/src/com/jetbrains/commandInterface/console/ArgumentHintLayer.java similarity index 70% rename from python/src/com/jetbrains/commandInterface/console/MissingArgumentDisplayer.java rename to python/src/com/jetbrains/commandInterface/console/ArgumentHintLayer.java index 9fddf05ee9de..373cab1169ca 100644 --- a/python/src/com/jetbrains/commandInterface/console/MissingArgumentDisplayer.java +++ b/python/src/com/jetbrains/commandInterface/console/ArgumentHintLayer.java @@ -16,12 +16,16 @@ package com.jetbrains.commandInterface.console; import com.intellij.execution.console.LanguageConsoleImpl; +import com.intellij.execution.ui.ConsoleViewContentType; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.psi.util.PsiModificationTracker.Listener; -import com.intellij.ui.JBColor; import com.intellij.util.messages.MessageBusConnection; import com.jetbrains.commandInterface.command.Argument; import com.jetbrains.commandInterface.gnuCommandLine.ValidationResult; @@ -34,13 +38,15 @@ import javax.swing.*; import java.awt.*; /** - * Displays missing argument (if required). + * Displays argument hint (if required). * It tracks PSI changes, obtains validation info, and draws itself. - * Will be added as {@link LanguageConsoleImpl#addWaterMark(JComponent) watermark} + * Will be added as {@link LanguageConsoleImpl#addLayerToPane(JComponent) layer} * * @author Ilya.Kazakevich */ -final class MissingArgumentDisplayer extends JPanel implements Listener { +@SuppressWarnings({"InstanceVariableMayNotBeInitialized", "NonSerializableFieldInSerializableClass", "DeserializableClassInSecureContext", + "SerializableClassInSecureContext"}) // Nobody would serialize this class +final class ArgumentHintLayer extends JPanel implements Listener { /** * Braces for mandatory args are [] according to GNU/POSIX recommendations @@ -71,6 +77,16 @@ final class MissingArgumentDisplayer extends JPanel implements Listener { private final int myLineHeightPx; @NotNull private final LanguageConsoleImpl myConsole; + /** + * Color to be used for required arguments + */ + @NotNull + private final Color myRequiredColor; + /** + * Color to be used for optional arguments + */ + @NotNull + private final Color myOptionalColor; /** * Number of chars in current document */ @@ -89,7 +105,7 @@ final class MissingArgumentDisplayer extends JPanel implements Listener { /** * @param console console to wrap */ - private MissingArgumentDisplayer(@NotNull final LanguageConsoleImpl console) { + private ArgumentHintLayer(@NotNull final LanguageConsoleImpl console) { final FontMetrics metrics = console.getFontMetrics(console.getFont()); myCharWidthPx = metrics.charWidth('A'); // Should be monospace myLineHeightPx = metrics.getHeight(); @@ -98,11 +114,17 @@ final class MissingArgumentDisplayer extends JPanel implements Listener { myConsole = console; myDocumentLengthInChars = console.getEditorDocument().getTextLength(); myLastText = console.getFile().getText(); + + + final EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme(); + myRequiredColor = scheme.getAttributes(ConsoleViewContentType.ERROR_OUTPUT_KEY).getForegroundColor(); + myOptionalColor = scheme.getAttributes(EditorColors.FOLDED_TEXT_ATTRIBUTES).getForegroundColor(); } @Override public void modificationCountChanged() { + ApplicationManager.getApplication().assertIsDispatchThread(); final String newText = myConsole.getFile().getText(); if (newText.equals(myLastText)) { // If text did not changed from last time, we do nothing return; @@ -138,20 +160,24 @@ final class MissingArgumentDisplayer extends JPanel implements Listener { } + @SuppressWarnings("NumericCastThatLosesPrecision") // Y will never be > Integer.MAX_VALUE final int y = ((int)Math.round(myConsole.getCurrentEditor().getComponent().getLocation().getY())) + myLineHeightPx; final int spaceToRight = myCharWidthPx * SPACES_BEFORE_ARG; // Space after line end to placeholder final int x = (myPromptWidthPx + (myCharWidthPx * myDocumentLengthInChars)) + spaceToRight; final boolean required = nextArg.first; final String argumentText = nextArg.second.getHelpText(); - g.setColor((required ? JBColor.red : JBColor.gray)); - final String textToShow = StringUtil.isEmpty(argumentText) ? PyBundle.message("commandLine.missingArgument.defaultName") : argumentText; + + + g.setColor(required ? myRequiredColor : myOptionalColor); + final String textToShow = StringUtil.isEmpty(argumentText) ? PyBundle.message("commandLine.argumentHint.defaultName") : argumentText; g.drawString(wrapBracesIfNeeded(required, textToShow), x, y); } /** * Adds appropriate braces to argument help text if needed - * @param required is argument required + * + * @param required is argument required * @param textToShow arg help text * @return text to show */ @@ -160,19 +186,27 @@ final class MissingArgumentDisplayer extends JPanel implements Listener { if (textToShow.startsWith(MANDATORY_ARG_BRACES.first) || textToShow.startsWith(OPTIONAL_ARG_BRACES.first)) { return textToShow; } - final Pair braces = (required ? MANDATORY_ARG_BRACES : OPTIONAL_ARG_BRACES); + final Pair braces = (required ? MANDATORY_ARG_BRACES : OPTIONAL_ARG_BRACES); return String.format("%s%s%s", braces.first, textToShow, braces.second); } /** - * Attaches argument displayer to console. Be sure your console has commands + * Attaches argument displaying layer to console. Be sure your console has commands. + * For now, only {@link CommandLineFile} is supported for now! + * * @param console console to attach + * @throws IllegalArgumentException is passed argument is not {@link CommandLineFile} */ static void attach(@NotNull final LanguageConsoleImpl console) { - final MissingArgumentDisplayer missingArgumentDisplayer = new MissingArgumentDisplayer(console); + final PsiFile consoleFile = console.getFile(); + if (!(consoleFile instanceof CommandLineFile)) { + throw new IllegalArgumentException( + String.format("Passed argument is %s, but has to be %s", consoleFile.getClass(), CommandLineFile.class)); + } + final ArgumentHintLayer argumentHintLayer = new ArgumentHintLayer(console); final MessageBusConnection connection = console.getProject().getMessageBus().connect(); - connection.subscribe(PsiModificationTracker.TOPIC, missingArgumentDisplayer); - console.addWaterMark(missingArgumentDisplayer); + connection.subscribe(PsiModificationTracker.TOPIC, argumentHintLayer); + console.addLayerToPane(argumentHintLayer); } } \ No newline at end of file diff --git a/python/src/com/jetbrains/commandInterface/console/CommandLineConsole.java b/python/src/com/jetbrains/commandInterface/console/CommandLineConsole.java index 18f203c84bd0..071ef1ff7bb4 100644 --- a/python/src/com/jetbrains/commandInterface/console/CommandLineConsole.java +++ b/python/src/com/jetbrains/commandInterface/console/CommandLineConsole.java @@ -90,7 +90,7 @@ public final class CommandLineConsole { contentManager.addContent(content); showHiddenCommandWorkAround(console); - MissingArgumentDisplayer.attach(console); // Display [arguments] + ArgumentHintLayer.attach(console); // Display [arguments] return console; } diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties index ece483d61fbb..c117d0f04428 100644 --- a/python/src/com/jetbrains/python/PyBundle.properties +++ b/python/src/com/jetbrains/python/PyBundle.properties @@ -871,5 +871,5 @@ commandLine.inspection.badOption=Bad or unknown option. make sure this option re commandLine.inspection.badArgument=Argument can't have this value. use autocompletion to check list of possible values. commandLine.inspection.excessArgument=Excess argument or argument is not possible here # What to display if argument is available here, but no name provided -commandLine.missingArgument.defaultName=arguments +commandLine.argumentHint.defaultName=arguments