[Mercurial] HgVFSListener instead of HgVirtualFileListener.
authorKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Wed, 9 Jun 2010 10:29:24 +0000 (14:29 +0400)
committerKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Wed, 9 Jun 2010 10:29:24 +0000 (14:29 +0400)
plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java [new file with mode: 0644]
plugins/hg4idea/src/org/zmlx/hg4idea/HgVcs.java
plugins/hg4idea/src/org/zmlx/hg4idea/HgVirtualFileListener.java [deleted file]

diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java
new file mode 100644 (file)
index 0000000..4568dbc
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * 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.project.Project;
+import com.intellij.openapi.vcs.FilePath;
+import com.intellij.openapi.vcs.VcsConfiguration;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vcs.VcsVFSListener;
+import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.ui.VcsBackgroundTask;
+import com.intellij.vcsUtil.VcsUtil;
+import org.zmlx.hg4idea.command.HgAddCommand;
+import org.zmlx.hg4idea.command.HgCopyCommand;
+import org.zmlx.hg4idea.command.HgMoveCommand;
+import org.zmlx.hg4idea.command.HgRemoveCommand;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Listens to VFS events (such as adding or deleting bunch of files) and performs necessary operations with the VCS.
+ * @author Kirill Likhodedov
+ */
+public class HgVFSListener extends VcsVFSListener {
+
+  private final VcsDirtyScopeManager dirtyScopeManager; 
+
+  protected HgVFSListener(final Project project, final HgVcs vcs) {
+    super(project, vcs);
+    dirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject);
+  }
+
+  @Override
+  protected String getAddTitle() {
+    return HgVcsMessages.message("hg4idea.add.title");
+  }
+
+  @Override
+  protected String getSingleFileAddTitle() {
+    return HgVcsMessages.message("hg4idea.add.single.title");
+  }
+
+  @Override
+  protected String getSingleFileAddPromptTemplate() {
+    return HgVcsMessages.message("hg4idea.add.body");
+  }
+
+  @Override
+  protected void performAdding(Collection<VirtualFile> addedFiles, final Map<VirtualFile, VirtualFile> copyFromMap) {
+    (new VcsBackgroundTask<VirtualFile>(myProject,
+                                        HgVcsMessages.message("hg4idea.add.progress"),
+                                        VcsConfiguration.getInstance(myProject).getAddRemoveOption(),
+                                        addedFiles) {
+      protected void process(final VirtualFile file) throws VcsException {
+        if (file.isDirectory()) {
+          return;
+        }
+        final VirtualFile copyFrom = copyFromMap.get(file);
+        if (copyFrom != null) {
+          (new HgCopyCommand(myProject)).execute(new HgFile(myProject, copyFrom), new HgFile(myProject, file));
+        } else {
+          (new HgAddCommand(myProject)).execute(new HgFile(myProject, file));
+        }
+        dirtyScopeManager.fileDirty(file);
+      }
+
+    }).queue();
+  }
+
+  @Override
+  protected String getDeleteTitle() {
+    return HgVcsMessages.message("hg4idea.remove.title");
+  }
+
+  @Override
+  protected String getSingleFileDeleteTitle() {
+    return HgVcsMessages.message("hg4idea.remove.single.title");
+  }
+
+  @Override
+  protected String getSingleFileDeletePromptTemplate() {
+    return HgVcsMessages.message("hg4idea.remove.body");
+  }
+
+  @Override
+  protected void performDeletion(List<FilePath> filesToDelete) {
+    (new VcsBackgroundTask<FilePath>(myProject,
+                                        HgVcsMessages.message("hg4idea.remove.progress"),
+                                        VcsConfiguration.getInstance(myProject).getAddRemoveOption(),
+                                        filesToDelete) {
+      protected void process(final FilePath file) throws VcsException {
+        if (file.isDirectory()) {
+          return;
+        }
+        (new HgRemoveCommand(myProject)).execute(new HgFile(VcsUtil.getVcsRootFor(myProject, file), file));
+        dirtyScopeManager.fileDirty(file);
+      }
+
+    }).queue();
+  }
+
+  @Override
+  protected void performMoveRename(List<MovedFileInfo> movedFiles) {
+    (new VcsBackgroundTask<MovedFileInfo>(myProject,
+                                        HgVcsMessages.message("hg4idea.move.progress"),
+                                        VcsConfiguration.getInstance(myProject).getAddRemoveOption(),
+                                        movedFiles) {
+      protected void process(final MovedFileInfo file) throws VcsException {
+        final FilePath source = VcsUtil.getFilePath(file.myOldPath);
+        final FilePath target = VcsUtil.getFilePath(file.myNewPath);
+        (new HgMoveCommand(myProject)).execute(new HgFile(VcsUtil.getVcsRootFor(myProject, source), source), new HgFile(VcsUtil.getVcsRootFor(myProject, target), target));
+        dirtyScopeManager.fileDirty(source);
+        dirtyScopeManager.fileDirty(target);
+      }
+
+    }).queue();
+  }
+
+  @Override
+  protected boolean isDirectoryVersioningSupported() {
+    return false;
+  }
+}
index d4ffd24c9caf3b096090d743ae22c500bf3c4df2..b245312417b0da8cf2828ec6dfac744ccc50daf3 100644 (file)
@@ -59,7 +59,6 @@ public class HgVcs extends AbstractVcs {
 
   private final HgChangeProvider changeProvider;
   private final HgProjectConfigurable configurable;
-  private final HgVirtualFileListener virtualFileListener;
   private final HgRollbackEnvironment rollbackEnvironment;
   private final HgDiffProvider diffProvider;
   private final HgHistoryProvider historyProvider;
@@ -78,6 +77,7 @@ public class HgVcs extends AbstractVcs {
   private final HgProjectSettings projectSettings;
 
   private boolean started = false;
+  private HgVFSListener myVFSListener;
 
   public HgVcs(Project project,
     HgGlobalSettings globalSettings, HgProjectSettings projectSettings) {
@@ -86,7 +86,6 @@ public class HgVcs extends AbstractVcs {
     this.projectSettings = projectSettings;
     configurable = new HgProjectConfigurable(projectSettings);
     changeProvider = new HgChangeProvider(project, getKeyInstanceMethod());
-    virtualFileListener = new HgVirtualFileListener(project, this);
     rollbackEnvironment = new HgRollbackEnvironment(project);
     diffProvider = new HgDiffProvider(project);
     historyProvider = new HgHistoryProvider(project);
@@ -230,7 +229,6 @@ public class HgVcs extends AbstractVcs {
       return;
     }
 
-    LocalFileSystem.getInstance().addVirtualFileListener(virtualFileListener);
     ChangeListManager.getInstance(myProject).registerCommitExecutor(commitExecutor);
 
     StatusBar statusBar = WindowManager.getInstance().getStatusBar(myProject);
@@ -276,6 +274,8 @@ public class HgVcs extends AbstractVcs {
         }
       }
     );
+
+    myVFSListener = new HgVFSListener(myProject, this);
   }
 
   @Override
@@ -284,7 +284,6 @@ public class HgVcs extends AbstractVcs {
       return;
     }
 
-    LocalFileSystem.getInstance().removeVirtualFileListener(virtualFileListener);
     StatusBar statusBar = WindowManager.getInstance().getStatusBar(myProject);
     if (messageBusConnection != null) {
       messageBusConnection.disconnect();
@@ -297,6 +296,11 @@ public class HgVcs extends AbstractVcs {
       //statusBar.removeCustomIndicationComponent(outgoingChangesStatus);
       //statusBar.removeCustomIndicationComponent(hgCurrentBranchStatus);
     }
+
+    if (myVFSListener != null) {
+      Disposer.dispose(myVFSListener);
+      myVFSListener = null;
+    }
   }
 
   public static HgVcs getInstance(Project project) {
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgVirtualFileListener.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgVirtualFileListener.java
deleted file mode 100644 (file)
index c144596..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-// Copyright 2008-2010 Victor Iacoban
-//
-// 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.fileTypes.*;
-import com.intellij.openapi.project.*;
-import com.intellij.openapi.vcs.*;
-import com.intellij.openapi.vcs.FilePath;
-import com.intellij.openapi.vcs.changes.*;
-import com.intellij.openapi.vfs.*;
-import com.intellij.vcsUtil.*;
-import org.jetbrains.annotations.*;
-import org.zmlx.hg4idea.command.*;
-
-import java.io.*;
-import java.util.*;
-
-import static com.intellij.openapi.vcs.VcsShowConfirmationOption.Value.*;
-
-public class HgVirtualFileListener extends VirtualFileAdapter {
-
-  private final Project project;
-  private final AbstractVcs vcs;
-
-  public HgVirtualFileListener(Project project, AbstractVcs vcs) {
-    this.project = project;
-    this.vcs = vcs;
-  }
-
-  @Override
-  public void fileCopied(VirtualFileCopyEvent event) {
-    if (event.isFromRefresh()) {
-      return;
-    }
-    final VirtualFile newFile = event.getFile();
-    FilePath newPath = getFilePath(newFile);
-    VirtualFile newRepo = VcsUtil.getVcsRootFor(project, newFile);
-    boolean newFileProcessable = newRepo != null && VcsUtil.isFileForVcs(newFile, project, vcs) && isFileProcessable(newFile);
-
-    final VirtualFile oldFile = event.getOriginalFile();
-    FilePath oldPath = getFilePath(oldFile);
-    VirtualFile oldRepo = VcsUtil.getVcsRootFor(project, oldFile);
-    boolean oldFileProcessable = oldRepo != null && VcsUtil.isFileForVcs(oldFile, project, vcs) && isFileProcessable(oldFile);
-
-    if (newFileProcessable && oldFileProcessable && oldRepo.equals(newRepo)) {
-      copyFile(newRepo, oldPath, newPath);
-      markDirty(newPath);
-    } else if (newFileProcessable) {
-      addFile(newRepo, newPath, false);
-      markDirty(newPath);
-    }
-  }
-
-  @Override
-  public void fileMoved(VirtualFileMoveEvent event) {
-    VirtualFile oldParent = event.getOldParent();
-    String fileName = event.getFileName();
-
-    FilePath oldPath = VcsUtil.getFilePath(new File(new File(oldParent.getPath()), fileName));
-    VirtualFile oldRepo = VcsUtil.getVcsRootFor(project, oldPath);
-    boolean oldFileProcessable = oldRepo != null && VcsUtil.isFileForVcs(oldPath, project, vcs) && isFileProcessable(oldPath);
-
-    VirtualFile newFile = event.getFile();
-    FilePath newPath = getFilePath(newFile);
-    VirtualFile newRepo = VcsUtil.getVcsRootFor(project, newFile);
-    boolean newFileProcessable = newRepo != null && VcsUtil.isFileForVcs(newFile, project, vcs) && isFileProcessable(newFile);
-
-    if (newFileProcessable && oldFileProcessable && oldRepo.equals(newRepo)) {
-      moveFile(oldRepo, newRepo, oldPath, newPath);
-    } else {
-      HgFileStatusEnum oldStatus = getStatus(oldRepo, oldPath);
-      boolean silent = oldStatus != HgFileStatusEnum.UNVERSIONED;
-
-      if (oldFileProcessable) {
-        deleteFile(oldRepo, oldPath, silent);
-      }
-
-      if (newFileProcessable) {
-        addFile(newRepo, newPath, silent);
-      }
-    }
-
-    markDirty(oldPath);
-    markDirty(newPath);
-  }
-
-  @Override
-  public void fileCreated(VirtualFileEvent event) {
-    if (event.isFromRefresh()) {
-      return;
-    }
-    final VirtualFile file = event.getFile();
-    if (!VcsUtil.isFileForVcs(file, project, vcs)) {
-      return;
-    }
-    if (!isFileProcessable(file) || file.isDirectory()) {
-      return;
-    }
-
-    VirtualFile repo = VcsUtil.getVcsRootFor(project, file);
-    if (repo == null) {
-      return;
-    }
-
-    FilePath path = getFilePath(file);
-    addFile(repo, path, false);
-    markDirty(path);
-  }
-
-  @Override
-  public void fileDeleted(VirtualFileEvent event) {
-    if (event.isFromRefresh()) {
-      return;
-    }
-
-    final VirtualFile file = event.getFile();
-
-    if (!shouldProcess(file)) {
-      return;
-    }
-
-    VirtualFile repo = VcsUtil.getVcsRootFor(project, file);
-    if (repo == null) {
-      return;
-    }
-
-    FilePath path = getFilePath(file);
-    deleteFile(repo, path, false);
-    markDirty(path);
-  }
-
-  @Override
-  public void propertyChanged(VirtualFilePropertyEvent event) {
-    if (VirtualFile.PROP_NAME.equals(event.getPropertyName())) {
-      fileRenamed(event);
-    }
-  }
-
-  private void fileRenamed(VirtualFilePropertyEvent event) {
-    String oldName = (String) event.getOldValue();
-    VirtualFile oldParent = event.getParent();
-
-    FilePath oldPath = VcsUtil.getFilePath(new File(new File(oldParent.getPath()), oldName));
-    VirtualFile oldRepo = VcsUtil.getVcsRootFor(project, oldPath);
-    boolean oldFileProcessable = oldRepo != null && VcsUtil.isFileForVcs(oldPath, project, vcs) && isFileProcessable(oldPath);
-
-    VirtualFile newFile = event.getFile();
-    FilePath newPath = getFilePath(newFile);
-    VirtualFile newRepo = VcsUtil.getVcsRootFor(project, newFile);
-    boolean newFileProcessable = newRepo != null && VcsUtil.isFileForVcs(newFile, project, vcs) && isFileProcessable(newFile);
-
-    if (newFileProcessable && oldFileProcessable && oldRepo.equals(newRepo)) {
-      renameFile(newRepo, oldPath, newPath);
-    } else {
-      if (oldFileProcessable) {
-        deleteFile(oldRepo, oldPath, false);
-      }
-
-      if (newFileProcessable) {
-        addFile(newRepo, newPath, false);
-      }
-    }
-    markDirty(oldPath);
-    markDirty(newPath);
-  }
-
-  private void markDirty(final FilePath path) {
-    HgUtil.markDirectoryDirty(project, path.getParentPath());
-  }
-
-  private FilePath getFilePath(VirtualFile file) {
-    return VcsUtil.getFilePath(file.getPath());
-  }
-
-  private void addFile(@NotNull VirtualFile repo, @NotNull FilePath path, boolean silent) {
-    if (silent || checkAdd(path)) {
-      new HgAddCommand(project).execute(new HgFile(repo, path));
-    }
-  }
-
-  private void copyFile(VirtualFile repo, FilePath oldPath, FilePath newPath) {
-    if (checkAdd(newPath)) {
-      HgCopyCommand command = new HgCopyCommand(project);
-      HgFile source = new HgFile(repo, oldPath);
-      HgFile target = new HgFile(repo, newPath);
-      command.execute(source, target);
-    }
-  }
-
-  private void moveFile(@NotNull VirtualFile repo, VirtualFile newRepo, @NotNull FilePath oldPath, @NotNull FilePath newPath) {
-    HgMoveCommand command = new HgMoveCommand(project);
-    HgFile source = new HgFile(repo, oldPath);
-    HgFile target = new HgFile(repo, newPath);
-    command.execute(source, target);
-  }
-
-  private void renameFile(@NotNull VirtualFile repo, @NotNull FilePath oldPath, @NotNull FilePath newPath) {
-    HgMoveCommand command = new HgMoveCommand(project);
-    HgFile source = new HgFile(repo, oldPath);
-    HgFile target = new HgFile(repo, newPath);
-    command.execute(source, target);
-  }
-
-  private boolean checkAdd(FilePath path) {
-    String title = HgVcsMessages.message("hg4idea.add.confirmation.title");
-    String message = HgVcsMessages.message("hg4idea.add.confirmation.body", path.getPath());
-
-    VcsShowConfirmationOption option = ProjectLevelVcsManager.getInstance(project)
-      .getStandardConfirmation(VcsConfiguration.StandardConfirmation.ADD, vcs);
-
-    boolean processAdd = false;
-    if (DO_ACTION_SILENTLY == option.getValue()) {
-      processAdd = true;
-    } else if (SHOW_CONFIRMATION == option.getValue()) {
-      AbstractVcsHelper helper = AbstractVcsHelper.getInstance(project);
-      processAdd = null != helper.selectFilePathsToProcess(
-        Arrays.asList(path), title, null, title, message, option
-      );
-    }
-    return processAdd;
-  }
-
-  private void deleteFile(@NotNull VirtualFile repo, @NotNull FilePath path, boolean silent) {
-    HgFileStatusEnum status = getStatus(repo, path);
-    if (status == HgFileStatusEnum.UNVERSIONED || status == HgFileStatusEnum.IGNORED) {
-      return;
-    }
-
-    String title = HgVcsMessages.message("hg4idea.delete.confirmation.title");
-    String message = HgVcsMessages.message("hg4idea.delete.confirmation.body", path.getPath());
-
-    boolean processDelete = false;
-
-    VcsShowConfirmationOption option = ProjectLevelVcsManager.getInstance(project)
-      .getStandardConfirmation(VcsConfiguration.StandardConfirmation.REMOVE, vcs);
-
-    if (DO_ACTION_SILENTLY == option.getValue() || status == HgFileStatusEnum.ADDED || silent) {
-      processDelete = true;
-    } else if (SHOW_CONFIRMATION == option.getValue()) {
-      AbstractVcsHelper helper = AbstractVcsHelper.getInstance(project);
-      processDelete = null != helper.selectFilePathsToProcess(
-        Arrays.asList(path), title, null, title, message, option
-      );
-    }
-
-    if (processDelete) {
-      new HgRemoveCommand(project).execute(new HgFile(repo, path));
-    }
-  }
-
-  private HgFileStatusEnum getStatus(VirtualFile repo, FilePath file) {
-    HgStatusCommand status = new HgStatusCommand(project);
-    HgChange change = status.execute(repo, file.getPath());
-    return change != null ? change.getStatus() : HgFileStatusEnum.UNVERSIONED;
-  }
-
-  private boolean shouldProcess(VirtualFile file) {
-    return VcsUtil.isFileForVcs(file, project, vcs) && isFileProcessable(file);
-  }
-
-  private boolean isFileProcessable(VirtualFile file) {
-    if (file == null) {
-      return false;
-    }
-    ChangeListManager changeListManager = ChangeListManager.getInstance(project);
-    return !FileTypeManager.getInstance().isFileIgnored(file.getName())
-      || !changeListManager.isIgnoredFile(file);
-  }
-
-  private boolean isFileProcessable(FilePath file) {
-    if (file == null) {
-      return false;
-    }
-    return !FileTypeManager.getInstance().isFileIgnored(file.getName());
-  }
-}