[Mercurial] Introduced HgRootsConvertor, support for nested roots.
authorKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Mon, 12 Jul 2010 09:36:35 +0000 (13:36 +0400)
committerKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Mon, 12 Jul 2010 09:36:35 +0000 (13:36 +0400)
plugins/hg4idea/src/META-INF/plugin.xml
plugins/hg4idea/src/org/zmlx/hg4idea/HgRootsHandler.java [new file with mode: 0644]
plugins/hg4idea/src/org/zmlx/hg4idea/HgUtil.java
plugins/hg4idea/src/org/zmlx/hg4idea/HgVcs.java

index 6fea72617466b5a30499dd13f00229c32fafe557..d5d089952b2a98cff828fac174e46f8b2534a75a 100644 (file)
@@ -33,6 +33,8 @@
                     serviceImplementation="org.zmlx.hg4idea.HgProjectSettings"/>
     <projectService serviceInterface="org.zmlx.hg4idea.command.HgCommandService"
                     serviceImplementation="org.zmlx.hg4idea.command.HgCommandService"/>
+    <projectService serviceInterface="org.zmlx.hg4idea.HgRootsHandler"
+                    serviceImplementation="org.zmlx.hg4idea.HgRootsHandler" />
   </extensions>
 
   <actions>
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgRootsHandler.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgRootsHandler.java
new file mode 100644 (file)
index 0000000..5da6243
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2000-2010 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 org.zmlx.hg4idea;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vcs.AbstractVcs;
+import com.intellij.openapi.vcs.FilePath;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.vcsUtil.VcsUtil;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Kirill Likhodedov
+ */
+public class HgRootsHandler implements AbstractVcs.RootsConvertor {
+
+  private final Project myProject;
+
+  public HgRootsHandler(Project project) {
+    myProject = project;
+  }
+
+  public static HgRootsHandler getInstance(Project project) {
+    return ServiceManager.getService(project, HgRootsHandler.class);
+  }
+
+  @Override
+  public List<VirtualFile> convertRoots(List<VirtualFile> original) {
+    final Set<VirtualFile> result = new THashSet<VirtualFile>(original.size());
+    for (VirtualFile vf : original) {
+      final VirtualFile root = convertRoot(vf);
+      if (root != null) {
+        result.add(root);
+      }
+    }
+    return new ArrayList<VirtualFile>(result);
+  }
+
+  @Nullable
+  public VirtualFile getRootFor(VirtualFile file) {
+    return convertRoot(VcsUtil.getVcsRootFor(myProject, file));
+  }
+
+  @Nullable
+  public VirtualFile getRootFor(FilePath filepath) {
+    return convertRoot(VcsUtil.getVcsRootFor(myProject, filepath));
+  }
+
+  @Nullable
+  private VirtualFile convertRoot(@Nullable VirtualFile root) {
+    return HgUtil.getHgRootOrNull(myProject, root);
+  }
+
+}
+
index e882af9bd3259358a699fc06b442da00bc1c6ebe..d08fbbb75f1dd011585ad94681a60a6bd6372548 100644 (file)
@@ -196,8 +196,7 @@ public abstract class HgUtil {
    */
   @Nullable
   public static VirtualFile getHgRootOrNull(Project project, FilePath filePath) {
-    final VirtualFile vf = VcsUtil.getVcsRootFor(project, filePath);
-    return (vf == null || !isHgRoot(vf) ? null : vf);
+    return getNearestHgRoot(VcsUtil.getVcsRootFor(project, filePath));
   }
 
   /**
index 52e92e0ef1098ed42fd9a6341914c116637d30cd..6a06a51af968616345c355c9b00a697ea20be5ed 100644 (file)
@@ -14,6 +14,7 @@ package org.zmlx.hg4idea;
 
 import com.intellij.concurrency.JobScheduler;
 import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diff.impl.patch.formove.FilePathComparator;
 import com.intellij.openapi.fileEditor.FileEditorManagerAdapter;
 import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
 import com.intellij.openapi.fileEditor.FileEditorManagerListener;
@@ -34,11 +35,15 @@ import com.intellij.openapi.vcs.diff.DiffProvider;
 import com.intellij.openapi.vcs.history.VcsHistoryProvider;
 import com.intellij.openapi.vcs.rollback.RollbackEnvironment;
 import com.intellij.openapi.vcs.update.UpdateEnvironment;
+import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
+import com.intellij.openapi.vfs.VfsUtil;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.vfs.VirtualFileListener;
 import com.intellij.openapi.vfs.VirtualFileManager;
 import com.intellij.openapi.wm.StatusBar;
 import com.intellij.openapi.wm.WindowManager;
+import com.intellij.util.containers.ComparatorDelegate;
+import com.intellij.util.containers.Convertor;
 import com.intellij.util.messages.MessageBusConnection;
 import com.intellij.util.messages.Topic;
 import org.zmlx.hg4idea.provider.*;
@@ -51,10 +56,12 @@ import org.zmlx.hg4idea.ui.HgCurrentBranchStatus;
 
 import javax.swing.*;
 import java.io.File;
+import java.util.Collections;
+import java.util.List;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 
-public class HgVcs extends AbstractVcs {
+public class HgVcs extends AbstractVcs<CommittedChangeList> {
 
   public static final Topic<HgUpdater> BRANCH_TOPIC =
     new Topic<HgUpdater>("hg4idea.branch", HgUpdater.class);
@@ -212,6 +219,43 @@ public class HgVcs extends AbstractVcs {
   }
 
   @Override
+  public boolean allowsNestedRoots() {
+    return true;
+  }
+
+  @Override
+  public <S> List<S> filterUniqueRoots(final List<S> in, final Convertor<S, VirtualFile> convertor) {
+    Collections.sort(in, new ComparatorDelegate<S, VirtualFile>(convertor, FilePathComparator.getInstance()));
+
+    for (int i = 1; i < in.size(); i++) {
+      final S sChild = in.get(i);
+      final VirtualFile child = convertor.convert(sChild);
+      final VirtualFile childRoot = HgUtil.getHgRootOrNull(myProject, child);
+      if (childRoot == null) {
+        continue;
+      }
+      for (int j = i - 1; j >= 0; --j) {
+        final S sParent = in.get(j);
+        final VirtualFile parent = convertor.convert(sParent);
+        // if the parent is an ancestor of the child and that they share common root, the child is removed
+        if (VfsUtil.isAncestor(parent, child, false) && VfsUtil.isAncestor(childRoot, parent, false)) {
+          in.remove(i);
+          //noinspection AssignmentToForLoopParameter
+          --i;
+          break;
+        }
+      }
+    }
+    return in;
+  }
+
+
+  @Override
+  public RootsConvertor getCustomConvertor() {
+    return HgRootsHandler.getInstance(myProject);
+  }
+
+    @Override
   public boolean isVersionedDirectory(VirtualFile dir) {
     return HgUtil.getNearestHgRoot(dir) != null;
   }