--- /dev/null
+package com.intellij.util;
+
+import com.intellij.codeInsight.completion.CompletionContributor;
+import com.intellij.codeInsight.completion.CompletionParameters;
+import com.intellij.codeInsight.completion.CompletionResultSet;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiPlainTextFile;
+
+/**
+ * @author sergey.evdokimov
+ */
+public class CompletionContributorForTextField extends CompletionContributor {
+
+ @Override
+ public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
+ PsiFile file = parameters.getOriginalFile();
+ if (!(file instanceof PsiPlainTextFile)) return;
+
+ ApplicationManager.getApplication().assertReadAccessAllowed();
+
+ TextFieldCompletionProvider field = file.getUserData(TextFieldCompletionProvider.COMPLETING_TEXT_FIELD_KEY);
+ if (field == null) return;
+
+ String text = file.getText();
+ int offset = parameters.getOffset();
+
+ String prefix = field.getPrefix(text.substring(0, Math.min(text.length(), offset)));
+
+ CompletionResultSet activeResult;
+
+ if (!result.getPrefixMatcher().getPrefix().equals(prefix)) {
+ activeResult = result.withPrefixMatcher(prefix);
+ }
+ else {
+ activeResult = result;
+ }
+
+ field.addCompletionVariants(text, offset, prefix, activeResult);
+ }
+}
--- /dev/null
+package com.intellij.util;
+
+import com.intellij.codeInsight.completion.CompletionResultSet;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.PlainTextLanguage;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiFileFactory;
+import com.intellij.ui.EditorTextField;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author sergey.evdokimov
+ */
+public abstract class TextFieldCompletionProvider {
+
+ static final Key<TextFieldCompletionProvider> COMPLETING_TEXT_FIELD_KEY = Key.create("COMPLETING_TEXT_FIELD_KEY");
+
+ public void apply(@NotNull EditorTextField field) {
+ Project project = field.getProject();
+ assert project != null;
+ field.setDocument(createDocument(project));
+ }
+
+ private Document createDocument(final Project project) {
+ final FileType fileType = PlainTextLanguage.INSTANCE.getAssociatedFileType();
+ assert fileType != null;
+
+ final long stamp = LocalTimeCounter.currentTime();
+ final PsiFile psiFile = PsiFileFactory.getInstance(project)
+ .createFileFromText("Dummy." + fileType.getDefaultExtension(), fileType, "", stamp, true, false);
+
+ psiFile.putUserData(COMPLETING_TEXT_FIELD_KEY, this);
+
+ final Document document = PsiDocumentManager.getInstance(project).getDocument(psiFile);
+ assert document != null;
+ return document;
+ }
+
+ @NotNull
+ protected String getPrefix(@NotNull String currentTextPrefix) {
+ return currentTextPrefix;
+ }
+
+ protected abstract void addCompletionVariants(@NotNull String text, int offset, @NotNull String prefix, @NotNull CompletionResultSet result);
+}
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.svn.integrate;
+package com.intellij.openapi.vcs;
public class CheckSamePattern<T> {
private boolean mySame;
* Git utilities for working with configuration
*/
public class GitConfigUtil {
+ public static final String USER_NAME = "user.name";
+
/**
* A private constructor for utility class
*/
import git4idea.GitBranch;
import git4idea.GitTag;
import git4idea.commands.GitFileUtils;
+import git4idea.config.GitConfigUtil;
import git4idea.history.GitHistoryUtils;
import git4idea.history.wholeTree.CommitHashPlusParents;
import org.jetbrains.annotations.NotNull;
if (current != null) {
refs.setTrackedRemote(current.getTrackedRemoteName(myProject, myRoot));
}
+ refs.setUsername(GitConfigUtil.getValue(myProject, myRoot, GitConfigUtil.USER_NAME));
return refs;
}
import git4idea.GitBranch;
import java.util.Collection;
-import java.util.List;
import java.util.TreeSet;
/**
private final TreeSet<String> myLocalBranches;
private final TreeSet<String> myRemoteBranches;
private String myTrackedRemoteName;
+ private String myUsername;
public SymbolicRefs() {
myTags = new TreeSet<String>();
return myTrackedRemoteName;
}
+ public String getUsername() {
+ return myUsername;
+ }
+
+ public void setUsername(String username) {
+ myUsername = username;
+ }
+
public static enum Kind {
TAG,
LOCAL,
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.CustomComponentAction;
import com.intellij.openapi.actionSystem.impl.SimpleDataContext;
+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.JBPopupFactory;
-import com.intellij.openapi.ui.popup.ListPopup;
import com.intellij.openapi.util.IconLoader;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.ui.UIUtil;
/**
* @author irengrig
*/
-public abstract class BasePopupAction extends AnAction implements CustomComponentAction {
+public abstract class BasePopupAction extends DumbAwareAction implements CustomComponentAction {
private static final Icon ARROWS_ICON = IconLoader.getIcon("/ide/statusbar_arrows.png");
protected final JLabel myLabel;
- private final JPanel myPanel;
- private final Project myProject;
+ protected final JPanel myPanel;
+ protected final Project myProject;
public BasePopupAction(final Project project, final String labeltext) {
myProject = project;
final DefaultActionGroup group = createActionGroup();
final DataContext parent = DataManager.getInstance().getDataContext((Component) myPanel.getParent());
final DataContext dataContext = SimpleDataContext.getSimpleContext(PlatformDataKeys.PROJECT.getName(), myProject, parent);
- final ListPopup popup = JBPopupFactory.getInstance()
+ final JBPopup popup = JBPopupFactory.getInstance()
.createActionGroupPopup(null, group, dataContext, JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, true,
new Runnable() {
@Override
*/
package git4idea.history.wholeTree;
-import com.intellij.ide.DataManager;
-import com.intellij.openapi.actionSystem.*;
-import com.intellij.openapi.actionSystem.ex.CustomComponentAction;
-import com.intellij.openapi.actionSystem.impl.SimpleDataContext;
+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.JBPopupFactory;
-import com.intellij.openapi.ui.popup.ListPopup;
-import com.intellij.openapi.util.IconLoader;
-import com.intellij.openapi.vcs.actions.SelectedBlockHistoryAction;
-import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.Consumer;
-import com.intellij.util.ui.UIUtil;
import git4idea.GitBranch;
import git4idea.history.browser.SymbolicRefs;
-import javax.swing.*;
-import javax.swing.border.BevelBorder;
-import javax.swing.border.CompoundBorder;
-import java.awt.*;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
import java.util.TreeSet;
/**
doAction(null);
}
- private class SelectBranchAction extends AnAction {
+ private class SelectBranchAction extends DumbAwareAction {
private final String myValue;
private SelectBranchAction(String text, String value) {
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vcs.AbstractFilterChildren;
-import com.intellij.openapi.vcs.ComparableComparator;
-import com.intellij.openapi.vcs.VcsDataKeys;
-import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.committed.CommittedChangesTreeBrowser;
import com.intellij.openapi.vcs.changes.committed.RepositoryChangesBrowser;
// private JTextField myFilterField;
private String myPreviousFilter;
private List<String> mySearchContext;
+ private List<String> myUsersSearchContext;
private String mySelectedBranch;
private BranchSelectorAction myBranchSelectorAction;
private MySpecificDetails myDetails;
private StepType myState;
private MoreAction myMoreAction;
+ private UsersFilterAction myUsersFilterAction;
+ private MyFilterUi myUserFilterI;
public GitLogUI(Project project, final Mediator mediator) {
myProject = project;
myMediator = mediator;
+ mySearchContext = new ArrayList<String>();
+ myUsersSearchContext = new ArrayList<String>();
myRefs = new HashMap<VirtualFile, SymbolicRefs>();
myRecalculatedCommon = new SymbolicRefs();
myPreviousFilter = "";
myDescriptionRenderer = new DescriptionRenderer();
mySelectionSpeedometer = new Speedometer(20, 400);
createTableModel();
- mySearchContext = new ArrayList<String>();
myState = StepType.CONTINUE;
myUIRefresh = new UIRefresh() {
myRecalculatedCommon.clear();
if (myRefs.isEmpty()) return;
- String current = null;
- boolean same = true;
+ final CheckSamePattern<String> currentUser = new CheckSamePattern<String>();
+ final CheckSamePattern<String> currentBranch = new CheckSamePattern<String>();
for (SymbolicRefs refs : myRefs.values()) {
myRecalculatedCommon.addLocals(refs.getLocalBranches());
myRecalculatedCommon.addRemotes(refs.getRemoteBranches());
myRecalculatedCommon.addTags(refs.getTags());
final String currentFromRefs = refs.getCurrent() == null ? null : refs.getCurrent().getFullName();
- if (current == null) {
- current = currentFromRefs;
- } else if (! current.equals(currentFromRefs)) {
- same = false;
- }
+ currentBranch.iterate(currentFromRefs);
+ currentUser.iterate(refs.getUsername());
}
- if (same) {
+ if (currentBranch.isSame()) {
myRecalculatedCommon.setCurrent(myRefs.values().iterator().next().getCurrent());
}
+ if (currentUser.isSame()) {
+ final String username = currentUser.getSameValue();
+ myRecalculatedCommon.setUsername(username);
+ myUserFilterI.setMe(username);
+ }
myBranchSelectorAction.setSymbolicRefs(myRecalculatedCommon);
}
reloadRequest();
}
});
+ myUserFilterI = new MyFilterUi(new Runnable() {
+ @Override
+ public void run() {
+ reloadRequest();
+ }
+ });
+ myUsersFilterAction = new UsersFilterAction(myProject, myUserFilterI);
myFilterAction = new FilterAction(myProject);
group.add(new MyTextFieldAction());
group.add(myBranchSelectorAction);
+ group.add(myUsersFilterAction);
// first create filters...
//group.add(myFilterAction);
group.add(new MyCherryPick());
mySearchContext.clear();
final List<String> words = new ArrayList<String>();
for (String string : strings) {
+ if (string.trim().length() == 0) continue;
mySearchContext.add(string.toLowerCase());
final String word = StringUtil.escapeToRegexp(string);
sb.append(word).append(".*");
}
List<ColumnInfo> columns() {
+ initAuthor();
return Arrays.asList((ColumnInfo)COMMENT, AUTHOR, DATE);
}
}
};
- private abstract class HighlightingRendererBase {
+ private static abstract class HighlightingRendererBase {
+ private final List<String> mySearchContext;
+
+ protected HighlightingRendererBase(List<String> searchContext) {
+ mySearchContext = searchContext;
+ }
+
protected abstract void usual(final String s);
protected abstract void highlight(final String s);
private class HighLightingRenderer extends ColoredTableCellRenderer {
private final SimpleTextAttributes myHighlightAttributes;
+ private final List<String> mySearchContext;
private final SimpleTextAttributes myUsualAttributes;
protected final HighlightingRendererBase myWorker;
- public HighLightingRenderer(SimpleTextAttributes highlightAttributes, SimpleTextAttributes usualAttributes) {
+ public HighLightingRenderer(SimpleTextAttributes highlightAttributes, SimpleTextAttributes usualAttributes,
+ final List<String> searchContext) {
myHighlightAttributes = highlightAttributes;
+ mySearchContext = searchContext;
myUsualAttributes = usualAttributes == null ? SimpleTextAttributes.REGULAR_ATTRIBUTES : usualAttributes;
- myWorker = new HighlightingRendererBase() {
+ myWorker = new HighlightingRendererBase(searchContext) {
@Override
protected void usual(String s) {
append(s, myUsualAttributes);
private final Consumer<String> myConsumer;
private Inner() {
- super(HIGHLIGHT_TEXT_ATTRIBUTES, null);
+ super(HIGHLIGHT_TEXT_ATTRIBUTES, null, mySearchContext);
myIssueLinkRenderer = new IssueLinkRenderer(myProject, this);
myConsumer = new Consumer<String>() {
@Override
return bkgColor;
}
- private final ColumnInfo<Object, String> AUTHOR = new ColumnInfo<Object, String>("Author") {
- private final TableCellRenderer myRenderer = new HighLightingRenderer(HIGHLIGHT_TEXT_ATTRIBUTES, SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ private ColumnInfo<Object, String> AUTHOR;
- @Override
- public String valueOf(Object o) {
- if (o instanceof GitCommit) {
- return ((GitCommit) o).getAuthor();
+ private void initAuthor() {
+ AUTHOR = new ColumnInfo<Object, String>("Author") {
+ private final TableCellRenderer myRenderer = new HighLightingRenderer(HIGHLIGHT_TEXT_ATTRIBUTES,
+ SimpleTextAttributes.REGULAR_ATTRIBUTES, myUsersSearchContext);
+
+ @Override
+ public String valueOf(Object o) {
+ if (o instanceof GitCommit) {
+ return ((GitCommit)o).getAuthor();
+ }
+ return "";
}
- return "";
- }
- @Override
- public TableCellRenderer getRenderer(Object o) {
- return myRenderer;
- }
- };
+ @Override
+ public TableCellRenderer getRenderer(Object o) {
+ return myRenderer;
+ }
+ };
+ }
+
private final ColumnInfo<Object, String> DATE = new ColumnInfo<Object, String>("Date") {
private final TableCellRenderer myRenderer = new SimpleRenderer(SimpleTextAttributes.REGULAR_ATTRIBUTES, false);
myDetailsCache.resetBranchesCache();
final Collection<String> startingPoints = mySelectedBranch == null ? Collections.<String>emptyList() : Collections.singletonList(mySelectedBranch);
myDescriptionRenderer.resetIcons();
- if (StringUtil.isEmptyOrSpaces(myPreviousFilter)) {
- mySearchContext.clear();
- myMediator.reload(new RootsHolder(myRootsUnderVcs), startingPoints, Collections.<ChangesFilter.Filter>emptyList(), null);
+ final boolean commentFilterEmpty = StringUtil.isEmptyOrSpaces(myPreviousFilter);
+ mySearchContext.clear();
+ myUsersSearchContext.clear();
+
+ if (commentFilterEmpty && (myUserFilterI.myFilter == null)) {
+ myUsersSearchContext.clear();
+ myMediator.reload(new RootsHolder(myRootsUnderVcs), startingPoints, Collections.<Collection<ChangesFilter.Filter>>emptyList(), null);
} else {
- final List<ChangesFilter.Filter> filters = new ArrayList<ChangesFilter.Filter>();
- final Pair<String, List<String>> preparse = preparse(myPreviousFilter);
- filters.add(new ChangesFilter.Comment(preparse.getFirst()));
+ final List<Collection<ChangesFilter.Filter>> filters = new ArrayList<Collection<ChangesFilter.Filter>>();
- for (String s : preparse.getSecond()) {
- filters.add(new ChangesFilter.Author(s));
- filters.add(new ChangesFilter.Committer(s));
+ if (! commentFilterEmpty) {
+ final Pair<String, List<String>> preparse = preparse(myPreviousFilter);
+ final String first = preparse.getFirst();
+ filters.add(Collections.<ChangesFilter.Filter>singletonList(new ChangesFilter.Comment(first)));
+ }
+ if (myUserFilterI.myFilter != null) {
+ final String[] strings = myUserFilterI.myFilter.split(",");
+ final List<ChangesFilter.Filter> userFilters = new ArrayList<ChangesFilter.Filter>();
+ for (String string : strings) {
+ string = string.trim();
+ if (string.length() == 0) continue;
+ myUsersSearchContext.add(string.toLowerCase());
+ final String regexp = StringUtil.escapeToRegexp(string);
+ userFilters.add(new ChangesFilter.Committer(regexp));
+ }
+ filters.add(userFilters);
}
- myMediator.reload(new RootsHolder(myRootsUnderVcs), startingPoints, filters, myPreviousFilter.split("[\\s]"));
+ myMediator.reload(new RootsHolder(myRootsUnderVcs), startingPoints, filters, commentFilterEmpty ? null : myPreviousFilter.split("[\\s]"));
}
updateMoreVisibility();
selectionChanged();
private final StringBuilder mySb;
private HtmlHighlighter(String text) {
+ super(mySearchContext);
myText = text;
mySb = new StringBuilder();
}
myMoreAction.setVisible(false);
}
}
+
+ private static class MyFilterUi implements UserFilterI {
+ private boolean myMeIsKnown;
+ private String myMe;
+ private String myFilter;
+ private final Runnable myReloadCallback;
+
+ public MyFilterUi(Runnable reloadCallback) {
+ myReloadCallback = reloadCallback;
+ }
+
+ @Override
+ public void allSelected() {
+ myFilter = null;
+ myReloadCallback.run();
+ }
+
+ @Override
+ public void meSelected() {
+ myFilter = myMe;
+ myReloadCallback.run();
+ }
+
+ @Override
+ public void filter(String s) {
+ myFilter = s;
+ myReloadCallback.run();
+ }
+
+ @Override
+ public boolean isMeKnown() {
+ return myMeIsKnown;
+ }
+
+ @Override
+ public String getMe() {
+ return myMe;
+ }
+
+ public void setMe(final String me) {
+ myMeIsKnown = ! StringUtil.isEmptyOrSpaces(me);
+ myMe = me == null ? "" : me.trim();
+ }
+ }
}
public void loadSkeleton(final Mediator.Ticket ticket,
final RootsHolder rootsHolder,
final Collection<String> startingPoints,
- final Collection<ChangesFilter.Filter> filters,
+ final Collection<Collection<ChangesFilter.Filter>> filters,
String[] possibleHashes,
final LoadGrowthController loadGrowthController) {
if (myPreviousAlgorithm != null) {
if (filters.isEmpty()) {
final LoaderAndRefresherImpl loaderAndRefresher =
- new LoaderAndRefresherImpl(ticket, filters, myMediator, startingPoints, myDetailsCache, myProject, rootHolder, myUsersIndex,
- loadGrowthController.getId());
+ new LoaderAndRefresherImpl(ticket, Collections.<ChangesFilter.Filter>emptyList(), myMediator, startingPoints, myDetailsCache,
+ myProject, rootHolder, myUsersIndex, loadGrowthController.getId());
list.add(loaderAndRefresher);
} else {
- for (ChangesFilter.Filter filter : filters) {
+ Collection<Collection<ChangesFilter.Filter>> reordered = new ArrayList<Collection<ChangesFilter.Filter>>();
+ final Iterator<Collection<ChangesFilter.Filter>> iterator = filters.iterator();
+ if (iterator.hasNext()) {
+ final Collection<ChangesFilter.Filter> first = iterator.next();
+ for (ChangesFilter.Filter filter : first) {
+ final ArrayList<ChangesFilter.Filter> newList = new ArrayList<ChangesFilter.Filter>();
+ newList.add(filter);
+ reordered.add(newList);
+ }
+ }
+ while (iterator.hasNext()) {
+ final Collection<ChangesFilter.Filter> next = iterator.next();
+ final Collection<Collection<ChangesFilter.Filter>> reorderedCopy = reordered;
+ reordered = new ArrayList<Collection<ChangesFilter.Filter>>();
+ for (ChangesFilter.Filter filter : next) {
+ for (Collection<ChangesFilter.Filter> filterCollection : reorderedCopy) {
+ final ArrayList<ChangesFilter.Filter> newList = new ArrayList<ChangesFilter.Filter>(filterCollection);
+ newList.add(filter);
+ reordered.add(newList);
+ }
+ }
+ }
+
+ for (Collection<ChangesFilter.Filter> filterCollection : reordered) {
final LoaderAndRefresherImpl loaderAndRefresher =
- new LoaderAndRefresherImpl(ticket, Collections.singletonList(filter), myMediator, startingPoints, myDetailsCache, myProject,
- rootHolder, myUsersIndex, loadGrowthController.getId());
+ new LoaderAndRefresherImpl(ticket, filterCollection, myMediator, startingPoints, myDetailsCache, myProject, rootHolder, myUsersIndex,
+ loadGrowthController.getId());
list.add(loaderAndRefresher);
}
}
-
++ i;
}
void loadSkeleton(Mediator.Ticket ticket,
RootsHolder rootsHolder,
final Collection<String> startingPoints,
- final Collection<ChangesFilter.Filter> filters, String[] possibleHashes, LoadGrowthController loadGrowthController);
+ final Collection<Collection<ChangesFilter.Filter>> filters, String[] possibleHashes, LoadGrowthController loadGrowthController);
void resume();
}
public interface Mediator {
void reload(RootsHolder rootsHolder,
final Collection<String> startingPoints,
- final Collection<ChangesFilter.Filter> filters,
+ final Collection<Collection<ChangesFilter.Filter>> filters,
@Nullable String[] possibleHashes);
/**
@Override
public void reload(final RootsHolder rootsHolder,
final Collection<String> startingPoints,
- final Collection<ChangesFilter.Filter> filters,
+ final Collection<Collection<ChangesFilter.Filter>> filters,
String[] possibleHashes) {
myTicket.increment();
myTableWrapper.reset();
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2011 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package git4idea.history.browser;
+package git4idea.history.wholeTree;
-import java.util.Collection;
-
-public interface Mediator {
- Collection<GitCommit> getOrLoadParents(final GitCommit commit);
+/**
+ * @author irengrig
+ * Date: 1/20/11
+ * Time: 7:36 PM
+ */
+public interface UserFilterI {
+ void allSelected();
+ void meSelected();
+ void filter(final String s);
+ boolean isMeKnown();
+ String getMe();
}
--- /dev/null
+/*
+ * Copyright 2000-2011 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 git4idea.history.wholeTree;
+
+import com.intellij.codeInsight.completion.CompletionResultSet;
+import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonShortcuts;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.fileTypes.FileTypes;
+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.Comparing;
+import com.intellij.ui.EditorCustomization;
+import com.intellij.ui.EditorTextField;
+import com.intellij.ui.EditorTextFieldProvider;
+import com.intellij.util.TextFieldCompletionProvider;
+import git4idea.history.NewGitUsersComponent;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import javax.swing.border.CompoundBorder;
+import java.awt.*;
+import java.util.List;
+
+/**
+ * @author irengrig
+ * Date: 1/20/11
+ * Time: 7:35 PM
+ */
+public class UsersFilterAction extends BasePopupAction {
+ public static final String ALL = "All";
+ public static final String USER = "User:";
+ private final UserFilterI myUserFilterI;
+ private AnAction myAllAction;
+ private AnAction mySelectMe;
+ private AnAction mySelect;
+ private String myCurrentText;
+ private final NewGitUsersComponent myUsers;
+ private EditorTextField myEditorField;
+ private JBPopup myPopup;
+ private ComponentPopupBuilder myComponentPopupBuilder;
+ private AnAction mySelectOkAction;
+
+ public UsersFilterAction(final Project project, final UserFilterI userFilterI) {
+ super(project, USER);
+ myUserFilterI = userFilterI;
+ myCurrentText = "";
+ myUsers = NewGitUsersComponent.getInstance(myProject);
+ myAllAction = new DumbAwareAction(ALL) {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ myLabel.setText(ALL);
+ myUserFilterI.allSelected();
+ myCurrentText = "";
+ myPanel.setToolTipText(USER + " " + ALL);
+ }
+ };
+ mySelectMe = new DumbAwareAction() {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final String meText = getMeText();
+ myLabel.setText(meText);
+ myPanel.setToolTipText(USER + " " + meText);
+ myUserFilterI.meSelected();
+ myCurrentText = "";
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ super.update(e);
+ e.getPresentation().setVisible(myUserFilterI.isMeKnown());
+ e.getPresentation().setText(getMeText());
+ }
+ };
+ createPopup(project);
+ mySelect = new DumbAwareAction("Select..") {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ if (myPopup != null) {
+ mySelectOkAction.unregisterCustomShortcutSet(myPopup.getContent());
+ }
+ myPopup = myComponentPopupBuilder.createPopup();
+ myEditorField.setText(myCurrentText);
+ final JComponent content = myPopup.getContent();
+ mySelectOkAction.registerCustomShortcutSet(CommonShortcuts.CTRL_ENTER, content);
+ myPopup.showInScreenCoordinates(myLabel, new Point(0,0));
+ //myPopup.showInCenterOf(myLabel);
+ }
+ };
+ myLabel.setText(ALL);
+ }
+
+ private void createPopup(Project project) {
+ final JPanel panel = new JPanel(new BorderLayout());
+ final EditorTextFieldProvider service = ServiceManager.getService(project, EditorTextFieldProvider.class);
+ myEditorField = service.getEditorField(FileTypes.PLAIN_TEXT.getLanguage(), project, EditorCustomization.Feature.SOFT_WRAP);
+ myEditorField.setBorder(new CompoundBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2), myEditorField.getBorder()));
+ myEditorField.setText("s");
+ myEditorField.setText(myCurrentText);
+ myEditorField.setPreferredSize(new Dimension(200, 70));
+ panel.add(myEditorField, BorderLayout.CENTER);
+
+ final TextFieldCompletionProvider textFieldCompletionProvider = new TextFieldCompletionProvider() {
+ @NotNull
+ @Override
+ protected String getPrefix(@NotNull String currentTextPrefix) {
+ final int text = currentTextPrefix.lastIndexOf(',');
+ return text == -1 ? currentTextPrefix : currentTextPrefix.substring(text + 1).trim();
+ }
+
+ @Override
+ protected void addCompletionVariants(@NotNull String text,
+ int offset,
+ @NotNull String prefix,
+ @NotNull CompletionResultSet result) {
+ final List<String> list = myUsers.get();
+ if (list != null) {
+ for (String completionVariant : list) {
+ final LookupElementBuilder element = LookupElementBuilder.create(completionVariant);
+ result.addElement(element.addLookupString(completionVariant.toLowerCase()));
+ }
+ }
+ }
+ };
+ textFieldCompletionProvider.apply(myEditorField);
+
+ myComponentPopupBuilder = JBPopupFactory.getInstance().createComponentPopupBuilder(panel, myEditorField)
+ .setCancelOnClickOutside(true).setDimensionServiceKey(myProject,
+ "git4idea.history.wholeTree.UsersFilterAction.Select", false)
+ .setAdText(KeymapUtil.getShortcutsText(CommonShortcuts.CTRL_ENTER.getShortcuts()) + " to finish")
+ .setTitle("Specify user names, comma separated")
+ .setMovable(true)
+ .setRequestFocus(true).setResizable(true);
+ mySelectOkAction = new AnAction() {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ myPopup.closeOk(e.getInputEvent());
+ final String newText = myEditorField.getText();
+ if (Comparing.equal(newText.trim(), myCurrentText.trim())) return;
+ myCurrentText = newText;
+ final String[] pieces = myCurrentText.trim().split(",");
+ if (pieces.length == 0) {
+ myLabel.setText(ALL);
+ } else if (pieces.length == 1) {
+ myLabel.setText(pieces[0].trim());
+ } else {
+ myLabel.setText(pieces[0].trim() + "+");
+ }
+ myPanel.setToolTipText(USER + " " + myCurrentText);
+ myUserFilterI.filter(myCurrentText);
+ }
+ };
+ }
+
+ private String getMeText() {
+ return new StringBuilder().append("me ( ").append(myUserFilterI.getMe()).append(" )").toString();
+ }
+
+ @Override
+ protected DefaultActionGroup createActionGroup() {
+ final DefaultActionGroup group = new DefaultActionGroup();
+ group.add(myAllAction);
+ group.add(mySelectMe);
+ group.add(mySelect);
+ return group;
+ }
+}
package org.jetbrains.idea.svn.integrate;
import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.vcs.CheckSamePattern;
import com.intellij.openapi.vcs.VcsDataKeys;
import com.intellij.openapi.vcs.changes.ChangeList;
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;