Improve Update Project notification: oneline & with filter info

Mention just the whole number of affected files, no matter whether they were added, modified or deleted. This information is not critical in this place and, if needed, can be achieved from the update project tree.
This makes the notification oneline: IDEA-172375

If there is a scope filter, calculate the number of files under this filter, to let user know if he needs to view updated files at all: IDEA-172015.
This commit is contained in:
Kirill Likhodedov
2017-06-06 19:35:27 +03:00
parent e679944269
commit 4116cc338b
3 changed files with 50 additions and 25 deletions
@@ -41,6 +41,7 @@ import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx;
import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.search.scope.packageSet.NamedScope;
import com.intellij.util.WaitForProgressToShow; import com.intellij.util.WaitForProgressToShow;
import com.intellij.util.containers.MultiMap; import com.intellij.util.containers.MultiMap;
import com.intellij.util.ui.OptionsDialog; import com.intellij.util.ui.OptionsDialog;
@@ -54,7 +55,6 @@ import java.io.File;
import java.util.*; import java.util.*;
import static com.intellij.openapi.util.text.StringUtil.pluralize; import static com.intellij.openapi.util.text.StringUtil.pluralize;
import static com.intellij.openapi.util.text.StringUtil.toLowerCase;
import static com.intellij.openapi.vcs.VcsNotifier.STANDARD_NOTIFICATION; import static com.intellij.openapi.vcs.VcsNotifier.STANDARD_NOTIFICATION;
import static com.intellij.util.ObjectUtils.notNull; import static com.intellij.util.ObjectUtils.notNull;
@@ -416,25 +416,24 @@ public abstract class AbstractCommonUpdateAction extends AbstractVcsAction {
}); });
} }
private String prepareNotificationWithUpdateInfo() { @NotNull
StringBuffer text = new StringBuffer(); private String prepareNotificationWithUpdateInfo(@NotNull UpdateInfoTree tree) {
final List<FileGroup> groups = myUpdatedFiles.getTopLevelGroups(); String scopeText = "";
for (FileGroup group : groups) { NamedScope scopeFilter = tree.getFilterScope();
appendGroup(text, group); if (scopeFilter != null) {
} int filteredFiles = tree.getFilesCount(true);
return text.toString(); String filterName = scopeFilter.getName();
} if (filteredFiles == 0) {
scopeText = filterName + " wasn't modified";
private void appendGroup(final StringBuffer text, final FileGroup group) { }
final int s = group.getFiles().size(); else {
if (s > 0) { scopeText = "In " + filterName + ": " + filteredFiles + " " + pluralize("file", filteredFiles) + " modified";
text.append(s).append(" ").append(pluralize("File", s)).append(" ").append(toLowerCase(group.getUpdateName())).append("<br/>"); }
scopeText += "<br/>In all scopes: ";
} }
final List<FileGroup> list = group.getChildren(); int allFiles = tree.getFilesCount(false);
for (FileGroup g : list) { return scopeText + allFiles + " " + pluralize("file", allFiles) + " modified";
appendGroup(text, g);
}
} }
@Override @Override
@@ -533,8 +532,8 @@ public abstract class AbstractCommonUpdateAction extends AbstractVcsAction {
title = "Project Updated"; title = "Project Updated";
type = NotificationType.INFORMATION; type = NotificationType.INFORMATION;
} }
Notification notification = STANDARD_NOTIFICATION.createNotification(title, prepareNotificationWithUpdateInfo(), type, null); Notification notification = STANDARD_NOTIFICATION.createNotification(title, prepareNotificationWithUpdateInfo(tree), type, null);
notification.addAction(new ViewUpdateInfoNotification(myProject, tree, "View")); notification.addAction(new ViewUpdateInfoNotification(myProject, tree, "View"));
VcsNotifier.getInstance(myProject).notify(notification); VcsNotifier.getInstance(myProject).notify(notification);
} }
@@ -25,6 +25,7 @@ import com.intellij.psi.search.scope.packageSet.PackageSetBase;
import com.intellij.ui.SimpleTextAttributes; import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.PlatformIcons; import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*; import javax.swing.*;
import java.io.File; import java.io.File;
@@ -55,14 +56,14 @@ public class FileTreeNode extends FileOrDirectoryTreeNode {
} }
@Override @Override
protected boolean acceptFilter(Pair<PackageSetBase, NamedScopesHolder> filter, boolean showOnlyFilteredItems) { protected boolean acceptFilter(@Nullable Pair<PackageSetBase, NamedScopesHolder> filter, boolean showOnlyFilteredItems) {
try { try {
VirtualFilePointer filePointer = getFilePointer(); VirtualFilePointer filePointer = getFilePointer();
if (!filePointer.isValid()) { if (!filePointer.isValid()) {
return false; return false;
} }
VirtualFile file = filePointer.getFile(); VirtualFile file = filePointer.getFile();
if (file != null && file.isValid() && filter.first.contains(file, getProject(), filter.second)) { if (file != null && file.isValid() && filter != null && filter.first.contains(file, getProject(), filter.second)) {
applyFilter(true); applyFilter(true);
return true; return true;
} }
@@ -114,7 +114,7 @@ public class UpdateInfoTree extends PanelWithActionsAndCloseButton {
myProject = project; myProject = project;
myUpdatedFiles = updatedFiles; myUpdatedFiles = updatedFiles;
myRootName = rootName; myRootName = rootName;
myShowOnlyFilteredItems = VcsConfiguration.getInstance(myProject).UPDATE_FILTER_BY_SCOPE; myShowOnlyFilteredItems = VcsConfiguration.getInstance(myProject).UPDATE_FILTER_BY_SCOPE;
myFileStatusManager = FileStatusManager.getInstance(myProject); myFileStatusManager = FileStatusManager.getInstance(myProject);
@@ -358,6 +358,20 @@ public class UpdateInfoTree extends PanelWithActionsAndCloseButton {
return result.toArray(new File[result.size()]); return result.toArray(new File[result.size()]);
} }
int getFilesCount(boolean filtered) {
Pair<PackageSetBase, NamedScopesHolder> scopeFilter = getScopeFilter();
int[] result = new int[1];
TreeUtil.traverse(myRoot, node -> {
if (node instanceof FileTreeNode) {
if (!filtered || ((FileTreeNode)node).acceptFilter(scopeFilter, true)) {
result[0]++;
}
}
return true;
});
return result[0];
}
public void expandRootChildren() { public void expandRootChildren() {
TreeNode root = (TreeNode)myTreeModel.getRoot(); TreeNode root = (TreeNode)myTreeModel.getRoot();
@@ -449,7 +463,7 @@ public class UpdateInfoTree extends PanelWithActionsAndCloseButton {
@Nullable @Nullable
private Pair<PackageSetBase, NamedScopesHolder> getScopeFilter() { private Pair<PackageSetBase, NamedScopesHolder> getScopeFilter() {
String scopeName = VcsConfiguration.getInstance(myProject).UPDATE_FILTER_SCOPE_NAME; String scopeName = getFilterScopeName();
if (scopeName != null) { if (scopeName != null) {
for (NamedScopesHolder holder : NamedScopesHolder.getAllNamedScopeHolders(myProject)) { for (NamedScopesHolder holder : NamedScopesHolder.getAllNamedScopeHolders(myProject)) {
NamedScope scope = holder.getScope(scopeName); NamedScope scope = holder.getScope(scopeName);
@@ -464,6 +478,17 @@ public class UpdateInfoTree extends PanelWithActionsAndCloseButton {
return null; return null;
} }
@Nullable
private String getFilterScopeName() {
return VcsConfiguration.getInstance(myProject).UPDATE_FILTER_SCOPE_NAME;
}
@Nullable
NamedScope getFilterScope() {
Pair<PackageSetBase, NamedScopesHolder> filter = getScopeFilter();
return filter == null ? null : filter.second.getScope(getFilterScopeName());
}
private class FilterAction extends ToggleAction implements DumbAware { private class FilterAction extends ToggleAction implements DumbAware {
public FilterAction() { public FilterAction() {
super("Scope Filter", VcsBundle.getString("settings.filter.update.project.info.by.scope"), AllIcons.General.Filter); super("Scope Filter", VcsBundle.getString("settings.filter.update.project.info.by.scope"), AllIcons.General.Filter);
@@ -483,7 +508,7 @@ public class UpdateInfoTree extends PanelWithActionsAndCloseButton {
public void update(AnActionEvent e) { public void update(AnActionEvent e) {
super.update(e); super.update(e);
e.getPresentation().setEnabled(!myGroupByChangeList && VcsConfiguration.getInstance(myProject).UPDATE_FILTER_SCOPE_NAME != null); e.getPresentation().setEnabled(!myGroupByChangeList && getFilterScopeName() != null);
} }
} }