Package org.intellij.vcs.mks.actions

Source Code of org.intellij.vcs.mks.actions.BasicAction

package org.intellij.vcs.mks.actions;

import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.FileStatusManager;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.WindowManager;
import org.intellij.vcs.mks.MksBundle;
import org.intellij.vcs.mks.MksVcs;
import org.intellij.vcs.mks.MksVcsException;
import org.jetbrains.annotations.NotNull;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

public abstract class BasicAction extends AnAction {
  protected static final String ACTION_CANCELLED_MSG = "The command was cancelled.";
  protected final MksCommand command;

  public BasicAction(MksCommand command) {
    this.command = command;
  }

  protected final void perform(@NotNull Project project, MksVcs mksVcs, @NotNull List<VcsException> exceptions,
                 @NotNull VirtualFile[] affectedFiles) {
    try {
      command.executeCommand(mksVcs, exceptions, affectedFiles);
    } catch (VcsException e) {
      //noinspection ThrowableInstanceNeverThrown
      exceptions.add(new MksVcsException(/*"Unable to obtain file status"*/ e.getMessage(), e));
    }

    WindowManager.getInstance().getStatusBar(project)
        .setInfo(MessageFormat.format(MksBundle.message("action.complete"), getActionName(mksVcs)));
  }

  @Override
  public void actionPerformed(@NotNull AnActionEvent event) {

        final Project project = getProject(event);
    ApplicationManager.getApplication().runWriteAction(new Runnable() {
      public void run() {
        FileDocumentManager.getInstance().saveAllDocuments();
      }
    });
        final VirtualFile[] vFiles = getVirtualFiles(event);

    final MksVcs mksvcs = MksVcs.getInstance(project);
    if (!ProjectLevelVcsManager.getInstance(project).checkAllFilesAreUnder(mksvcs, vFiles)) {
      return;
    }

    final List<VcsException> exceptions = new ArrayList<VcsException>();
    ApplicationManager.getApplication().runWriteAction(new Runnable() {
      public void run() {
        final VirtualFile[] affectedFiles = collectAffectedFiles(project, vFiles);
        //noinspection unchecked
        perform(project, mksvcs, exceptions, affectedFiles);
        for (VirtualFile file : affectedFiles) {
          file.refresh(false, true);
          FileStatusManager.getInstance(project).fileStatusChanged(file);
        }
      }
    });
    mksvcs.showErrors(exceptions, getActionName(mksvcs));


  }

    private VirtualFile[] getVirtualFiles(AnActionEvent event) {
        return PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(event.getDataContext());
    }

    private Project getProject(AnActionEvent event) {
        return PlatformDataKeys.PROJECT.getData(event.getDataContext());
    }

    /**
   * given a list of action-target files, returns ALL the files that should be
   * subject to the action Does not keep directories, but recursively adds
   * directory contents
   *
   * @param project the project subject of the action
   * @param files   the root selection
   * @return the complete set of files this action should apply to
   */
  @NotNull
  protected VirtualFile[] collectAffectedFiles(@NotNull Project project, @NotNull VirtualFile[] files) {
    List<VirtualFile> affectedFiles = new ArrayList<VirtualFile>(files.length);
    ProjectLevelVcsManager projectLevelVcsManager = ProjectLevelVcsManager.getInstance(project);
    for (VirtualFile file : files) {
      if (!file.isDirectory() && projectLevelVcsManager.getVcsFor(file) instanceof MksVcs) {
        affectedFiles.add(file);
      } else if (file.isDirectory() && isRecursive()) {
        addChildren(project, affectedFiles, file);
      }

    }
    return affectedFiles.toArray(new VirtualFile[affectedFiles.size()]);
  }

  /**
   * recursively adds all the children of file to the files list, for which
   * this action makes sense ({@link #appliesTo(com.intellij.openapi.project.Project,com.intellij.openapi.vfs.VirtualFile)}
   * returns true)
   *
   * @param project the project subject of the action
   * @param files   result list
   * @param file  the file whose children should be added to the result list
   *                (recursively)
   */
  private void addChildren(@NotNull Project project, @NotNull List<VirtualFile> files, @NotNull VirtualFile file) {
    VirtualFile[] children = file.getChildren();
    for (VirtualFile child : children) {
      if (!child.isDirectory() && appliesTo(project, child)) {
        files.add(child);
      } else if (child.isDirectory() && isRecursive()) {
        addChildren(project, files, child);
      }
    }
  }

  @NotNull
  protected final String getActionName(@NotNull AbstractVcs abstractvcs) {
    return command.getActionName(abstractvcs);
  }

  protected boolean isRecursive() {
    return true;
  }

  protected boolean appliesTo(@NotNull Project project, @NotNull VirtualFile file) {
    return !file.isDirectory();
  }

  /**
   * disable the action if the event does not apply on MksVcs enabled
   * resources Hide it if the event does not have a project, or if no
   * VirtualFiel are targeted
   *
   * @param e the update event
   */
  @Override
  public void update(@NotNull AnActionEvent e) {
    super.update(e);
    Presentation presentation = e.getPresentation();
    DataContext dataContext = e.getDataContext();
    Project project = getProject(e);
    if (project == null) {
      presentation.setEnabled(false);
      presentation.setVisible(false);
      return;
    }

    VirtualFile[] vFiles = getVirtualFiles(e);
    if (vFiles == null || vFiles.length == 0) {
      presentation.setEnabled(false);
      presentation.setVisible(true);
      return;
    }
    MksVcs mksvcs = MksVcs.getInstance(project);
    boolean enabled = ProjectLevelVcsManager.getInstance(project).checkAllFilesAreUnder(mksvcs, vFiles)
        && isEnabled(project, mksvcs, vFiles);
    // only enable action if all the targets are under the vcs and the action suports all of them

    presentation.setEnabled(enabled);
    presentation.setVisible(enabled);
  }

  protected abstract boolean isEnabled(@NotNull Project project, @NotNull MksVcs mksvcs,
                     @NotNull VirtualFile... vFiles);

}
TOP

Related Classes of org.intellij.vcs.mks.actions.BasicAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.