/* * Copyright 2000-2014 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.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupAdapter; import com.intellij.openapi.ui.popup.LightweightWindowEvent; import com.intellij.openapi.util.text.StringUtil; import com.intellij.vcs.log.VcsLogFilter; import com.intellij.vcs.log.impl.MainVcsLogUiProperties; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.Collections; import java.util.List; abstract class MultipleValueFilterPopupComponent<Filter extends VcsLogFilter> extends FilterPopupComponent<Filter> { private static final int MAX_FILTER_VALUE_LENGTH = 30; @NotNull protected final MainVcsLogUiProperties myUiProperties; MultipleValueFilterPopupComponent(@NotNull String filterName, @NotNull MainVcsLogUiProperties uiProperties, @NotNull FilterModel<Filter> filterModel) { super(filterName, filterModel); myUiProperties = uiProperties; } @NotNull protected abstract List<List<String>> getRecentValuesFromSettings(); protected abstract void rememberValuesInSettings(@NotNull Collection<String> values); @NotNull protected abstract List<String> getAllValues(); @NotNull protected ActionGroup createRecentItemsActionGroup() { DefaultActionGroup group = new DefaultActionGroup(); List<List<String>> recentlyFiltered = getRecentValuesFromSettings(); if (!recentlyFiltered.isEmpty()) { group.addSeparator("Recent"); for (List<String> recentGroup : recentlyFiltered) { if (!recentGroup.isEmpty()) { group.add(new PredefinedValueAction(recentGroup)); } } group.addSeparator(); } return group; } @NotNull static String displayableText(@NotNull Collection<String> values) { if (values.size() == 1) { return values.iterator().next(); } return StringUtil.shortenTextWithEllipsis(StringUtil.join(values, "|"), MAX_FILTER_VALUE_LENGTH, 0, true); } @NotNull static String tooltip(@NotNull Collection<String> values) { return StringUtil.join(values, ", "); } @NotNull protected AnAction createSelectMultipleValuesAction() { return new SelectMultipleValuesAction(); } /** * Return true if the filter supports "negative" values, i.e. values like "-value" which means "match anything but 'value'". */ protected boolean supportsNegativeValues() { return false; } protected class PredefinedValueAction extends DumbAwareAction { @NotNull protected final List<String> myValues; public PredefinedValueAction(@NotNull String value) { this(Collections.singletonList(value)); } public PredefinedValueAction(@NotNull List<String> values) { super(null, tooltip(values), null); getTemplatePresentation().setText(displayableText(values), false); myValues = values; } @Override public void actionPerformed(@NotNull AnActionEvent e) { myFilterModel.setFilter(myFilterModel.createFilter(myValues)); rememberValuesInSettings(myValues); } } private class SelectMultipleValuesAction extends DumbAwareAction { @NotNull private final Collection<String> myVariants; SelectMultipleValuesAction() { super("Select..."); myVariants = getAllValues(); } @Override public void actionPerformed(@NotNull AnActionEvent e) { Project project = e.getProject(); if (project == null) { return; } Filter filter = myFilterModel.getFilter(); List<String> values = filter == null ? Collections.emptyList() : myFilterModel.getFilterValues(filter); final MultilinePopupBuilder popupBuilder = new MultilinePopupBuilder(project, myVariants, getPopupText(values), supportsNegativeValues()); JBPopup popup = popupBuilder.createPopup(); popup.addListener(new JBPopupAdapter() { @Override public void onClosed(LightweightWindowEvent event) { if (event.isOk()) { List<String> selectedValues = popupBuilder.getSelectedValues(); if (selectedValues.isEmpty()) { myFilterModel.setFilter(null); } else { myFilterModel.setFilter(myFilterModel.createFilter(selectedValues)); rememberValuesInSettings(selectedValues); } } } }); popup.showUnderneathOf(MultipleValueFilterPopupComponent.this); } @NotNull private String getPopupText(@Nullable Collection<String> selectedValues) { return selectedValues == null || selectedValues.isEmpty() ? "" : StringUtil.join(selectedValues, "\n"); } } }