package jetbrains.mps.ide.script.plugin.migrationtool;
/*Generated by MPS */
import jetbrains.mps.ide.findusages.model.SearchQuery;
import jetbrains.mps.ide.findusages.view.UsagesView;
import javax.swing.JPanel;
import javax.swing.JButton;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.impl.status.InlineProgressIndicator;
import jetbrains.mps.ide.findusages.model.IResultProvider;
import org.jetbrains.annotations.NotNull;
import jetbrains.mps.ide.ThreadUtils;
import jetbrains.mps.ide.findusages.view.treeholder.treeview.ViewOptions;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.IdeActions;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.AbstractAction;
import java.awt.event.ActionEvent;
import javax.swing.JComponent;
import jetbrains.mps.ide.findusages.findalgorithm.finders.IFinder;
import com.intellij.openapi.application.ApplicationManager;
import javax.swing.JLabel;
import com.intellij.openapi.progress.TaskInfo;
import org.jetbrains.annotations.NonNls;
import jetbrains.mps.project.MPSProject;
import java.util.Collection;
import jetbrains.mps.ide.findusages.model.SearchResult;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.smodel.ModelAccessHelper;
import jetbrains.mps.util.Computable;
import javax.swing.JOptionPane;
import jetbrains.mps.smodel.UndoRunnable;
import jetbrains.mps.progress.ProgressMonitorAdapter;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.progress.ProgressIndicator;
import jetbrains.mps.ide.findusages.view.FindUtils;
import jetbrains.mps.baseLanguage.closures.runtime.Wrappers;
import jetbrains.mps.ide.findusages.model.SearchResults;
import java.awt.event.ActionListener;
public abstract class MigrationScriptsView implements ResultsListener {
private MigrationScriptFinder myFinder;
private SearchQuery myQuery;
private MigrationScriptsTool myTool;
private UsagesView myUsagesView;
private JPanel myMainPanel;
private JPanel myControlsPanel;
private JPanel myStatusPanel;
private JButton myApplyButton;
private final Project myProject;
private InlineProgressIndicator myIndicator;
private MigrationScriptsController myController;
public MigrationScriptsView(MigrationScriptFinder finder, IResultProvider provider, SearchQuery query, MigrationScriptsTool tool, @NotNull Project project) {
ThreadUtils.assertEDT();
myProject = project;
myFinder = finder;
myFinder.addResultsListener(this);
myQuery = query;
myTool = tool;
ViewOptions viewOptions = new ViewOptions();
viewOptions.myCategories[0] = true;
viewOptions.myShowSearchedNodes = false;
viewOptions.myGroupSearchedNodes = false;
viewOptions.mySearchedNodesButtonsVisible = false;
myUsagesView = new UsagesView(project, viewOptions);
UsagesView.RerunAction searchAction = new UsagesView.RerunAction(myUsagesView, "Search again");
searchAction.setRunOptions(provider, query);
myUsagesView.setActions(searchAction, new UsagesView.RebuildAction(myUsagesView), new AnAction("Close", "", AllIcons.Actions.Cancel) {
public void actionPerformed(@NotNull AnActionEvent p0) {
MigrationScriptsView.this.close();
}
}, ActionManager.getInstance().getAction(IdeActions.ACTION_PIN_ACTIVE_TAB));
myUsagesView.setContents(finder.getLastSearchResults());
myMainPanel = new JPanel(new BorderLayout());
myMainPanel.add(myUsagesView.getComponent(), BorderLayout.CENTER);
myControlsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
myApplyButton = new JButton(new AbstractAction("Apply Migrations") {
@Override
public void actionPerformed(ActionEvent e) {
applyMigrations();
}
});
myControlsPanel.add(myApplyButton);
myStatusPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));
myControlsPanel.add(myStatusPanel);
myMainPanel.add(myControlsPanel, BorderLayout.SOUTH);
this.myIndicator = new InlineProgressIndicator(true, createTaskInfo());
this.myController = new MigrationScriptsController(myFinder);
}
public UsagesView getUsagesView() {
return myUsagesView;
}
public JComponent getComponent() {
return myMainPanel;
}
@Override
public void resultsChanged(IFinder finder) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
updateControls(true, new JLabel(""));
}
});
}
public abstract void close();
private TaskInfo createTaskInfo() {
return new TaskInfo() {
@NotNull
@Override
public String getTitle() {
return "Applying Migrations";
}
@Override
public String getCancelText() {
return null;
}
@Override
public String getCancelTooltipText() {
return null;
}
@Override
public boolean isCancellable() {
return false;
}
@NonNls
@Override
public String getProcessId() {
return "migration";
}
};
}
private MPSProject getMPSProject() {
return myProject.getComponent(MPSProject.class);
}
private void applyMigrations() {
ThreadUtils.assertEDT();
final Collection<SearchResult<SNode>> aliveIncludedResults = new ModelAccessHelper(getMPSProject().getModelAccess()).runReadAction(new Computable<Collection<SearchResult<SNode>>>() {
public Collection<SearchResult<SNode>> compute() {
return myController.computeAliveIncludedResults(myUsagesView.getIncludedResultNodes(), getMPSProject().getRepository());
}
});
if (aliveIncludedResults.size() == 0) {
JOptionPane.showMessageDialog(myTool.getComponent(), "No job");
return;
}
updateControls(false, myIndicator.getComponent());
final TaskInfo task = createTaskInfo();
// There's no hidden knowledge in use of task.getProcessId(), just picked first string that might serve as group indicator,
// as groupId is irrelevant for us anyway
UndoRunnable ur = new UndoRunnable.Base(task.getTitle(), task.getProcessId(), true) {
public void run() {
myController.process(new ProgressMonitorAdapter(myIndicator), aliveIncludedResults);
checkMigrationResults();
}
};
getMPSProject().getModelAccess().executeCommandInEDT(ur);
}
private void checkMigrationResults() {
final MigrationScriptFinder newFinder = new MigrationScriptFinder(myFinder.getScripts());
ProgressManager.getInstance().run(new Task.Modal(myTool.getProject(), "Searching", true) {
@Override
public void run(@NotNull final ProgressIndicator indicator) {
indicator.setIndeterminate(true);
final IResultProvider provider = FindUtils.makeProvider(newFinder);
final Wrappers._T<SearchResults> results = new Wrappers._T<SearchResults>();
getMPSProject().getRepository().getModelAccess().runReadAction(new Runnable() {
public void run() {
results.value = FindUtils.getSearchResults(new ProgressMonitorAdapter(indicator), myQuery, provider);
}
});
int newCount = results.value.getSearchResults().size();
if (newCount > 0) {
updateControls(false, new JLabel("done, but there " + ((newCount == 1 ? "is 1" : "are " + newCount)) + " applicable node" + ((newCount > 1 ? "s" : "")) + " left"), createShowInNewTabButton(newFinder, provider, myQuery));
} else {
updateControls(false, new JLabel("done"));
}
}
});
}
private JButton createShowInNewTabButton(final MigrationScriptFinder finder, final IResultProvider provider, final SearchQuery query) {
JButton button = new JButton("Show in New Tab");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
updateControls(false, new JLabel("done"));
myTool.addTab(finder, provider, query);
}
});
}
});
return button;
}
private void updateControls(boolean applyButtonEnabled, JComponent... statusComponents) {
myApplyButton.setEnabled(applyButtonEnabled);
if (statusComponents != null) {
myStatusPanel.removeAll();
for (JComponent statusComponent : statusComponents) {
myStatusPanel.add(statusComponent);
}
}
myStatusPanel.revalidate();
myStatusPanel.repaint();
}
}