/* * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.vcs.log.ui.filter; import com.google.common.primitives.Chars; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonShortcuts; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.ComponentPopupBuilder; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.EditorTextField; import com.intellij.ui.SoftWrapsEditorCustomization; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.textCompletion.DefaultTextCompletionValueDescriptor; import com.intellij.util.textCompletion.TextFieldWithCompletion; import com.intellij.util.textCompletion.ValuesCompletionProvider.ValuesCompletionProviderDumbAware; import com.intellij.util.ui.JBDimension; import com.intellij.util.ui.JBUI; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.border.CompoundBorder; import java.awt.*; import java.util.*; import java.util.List; class MultilinePopupBuilder { private static final char[] SEPARATORS = {'|', '\n'}; @NotNull private final EditorTextField myTextField; MultilinePopupBuilder(@NotNull Project project, @NotNull final Collection<String> values, @NotNull String initialValue, boolean supportsNegativeValues) { myTextField = createTextField(project, values, supportsNegativeValues, initialValue); } @NotNull private static EditorTextField createTextField(@NotNull Project project, Collection<String> values, boolean supportsNegativeValues, @NotNull String initialValue) { TextFieldWithCompletion textField = new TextFieldWithCompletion(project, new MyCompletionProvider(values, supportsNegativeValues), initialValue, false, true, false) { @Override protected EditorEx createEditor() { EditorEx editor = super.createEditor(); SoftWrapsEditorCustomization.ENABLED.customize(editor); return editor; } }; textField.setBorder(new CompoundBorder(JBUI.Borders.empty(2), textField.getBorder())); return textField; } @NotNull JBPopup createPopup() { JPanel panel = new JPanel(new BorderLayout()); panel.add(myTextField, BorderLayout.CENTER); ComponentPopupBuilder builder = JBPopupFactory.getInstance().createComponentPopupBuilder(panel, myTextField) .setCancelOnClickOutside(true) .setAdText(KeymapUtil.getShortcutsText(CommonShortcuts.CTRL_ENTER.getShortcuts()) + " to finish") .setRequestFocus(true) .setResizable(true) .setMayBeParent(true); final JBPopup popup = builder.createPopup(); popup.setMinimumSize(new JBDimension(200, 90)); AnAction okAction = new DumbAwareAction() { @Override public void actionPerformed(@NotNull AnActionEvent e) { unregisterCustomShortcutSet(popup.getContent()); popup.closeOk(e.getInputEvent()); } }; okAction.registerCustomShortcutSet(CommonShortcuts.CTRL_ENTER, popup.getContent()); return popup; } @NotNull List<String> getSelectedValues() { return ContainerUtil.mapNotNull(StringUtil.tokenize(myTextField.getText(), new String(SEPARATORS)), value -> { String trimmed = value.trim(); return trimmed.isEmpty() ? null : trimmed; }); } private static class MyCompletionProvider extends ValuesCompletionProviderDumbAware<String> { MyCompletionProvider(@NotNull Collection<String> values, boolean supportsNegativeValues) { super(new DefaultTextCompletionValueDescriptor.StringValueDescriptor(), supportsNegativeValues ? ContainerUtil.append(Chars.asList(SEPARATORS), '-') : Chars.asList(SEPARATORS), values, false); } @Nullable @Override public String getAdvertisement() { return "Select one or more values separated with | or new lines"; } } }