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(); } }