From b825a05f35b03f1eca8eb5e8b14d11e1077c26d4 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Wed, 4 Oct 2017 15:12:18 +0300 Subject: [PATCH] IDEA-70996 Tasks and IDE Contexts - Shelving changes --- .../src/com/intellij/tasks/LocalTask.java | 6 ++ .../intellij/tasks/impl/LocalTaskImpl.java | 13 +++- .../intellij/tasks/impl/TaskManagerImpl.java | 33 ++++++++++ .../tasks-platform-impl.iml | 1 + .../tasks/actions/OpenTaskDialog.java | 2 +- .../tasks/actions/vcs/VcsOpenTaskPanel.form | 60 +++++++++++-------- .../tasks/actions/vcs/VcsOpenTaskPanel.java | 6 ++ .../com/intellij/tasks/vcs/TaskVcsTest.java | 42 +++++++++++-- 8 files changed, 130 insertions(+), 33 deletions(-) diff --git a/platform/tasks-platform-api/src/com/intellij/tasks/LocalTask.java b/platform/tasks-platform-api/src/com/intellij/tasks/LocalTask.java index 563af590ce79..2847b07cc330 100644 --- a/platform/tasks-platform-api/src/com/intellij/tasks/LocalTask.java +++ b/platform/tasks-platform-api/src/com/intellij/tasks/LocalTask.java @@ -20,6 +20,7 @@ import com.intellij.tasks.timeTracking.model.WorkItem; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.xmlb.annotations.Attribute; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Date; import java.util.List; @@ -54,6 +55,11 @@ public abstract class LocalTask extends Task { public abstract void removeChangelist(final ChangeListInfo info); + @Nullable + public abstract String getShelfName(); + + public abstract void setShelfName(String shelfName); + /** * For serialization only. * @return two branches per repository: feature-branch itself and original branch to merge into diff --git a/platform/tasks-platform-impl/src/com/intellij/tasks/impl/LocalTaskImpl.java b/platform/tasks-platform-impl/src/com/intellij/tasks/impl/LocalTaskImpl.java index f7e4e3952dc4..41f6f06becba 100644 --- a/platform/tasks-platform-impl/src/com/intellij/tasks/impl/LocalTaskImpl.java +++ b/platform/tasks-platform-impl/src/com/intellij/tasks/impl/LocalTaskImpl.java @@ -62,12 +62,12 @@ public class LocalTaskImpl extends LocalTask { private boolean myActive; private List myChangeLists = new ArrayList<>(); + private String myShelfName; private boolean myRunning = false; private List myWorkItems = new ArrayList<>(); private Date myLastPost; private List myBranches = new ArrayList<>(); - /** for serialization */ public LocalTaskImpl() { } @@ -235,6 +235,7 @@ public class LocalTaskImpl extends LocalTask { myChangeLists.remove(info); } + @NotNull @Override @Property(surroundWithTag = false) @@ -257,6 +258,16 @@ public class LocalTaskImpl extends LocalTask { myBranches.add(info); } + @Override + public String getShelfName() { + return myShelfName; + } + + @Override + public void setShelfName(String shelfName) { + myShelfName = shelfName; + } + public boolean isClosed() { return myClosed; } diff --git a/platform/tasks-platform-impl/src/com/intellij/tasks/impl/TaskManagerImpl.java b/platform/tasks-platform-impl/src/com/intellij/tasks/impl/TaskManagerImpl.java index 2c77073b6860..16b3b4534e29 100644 --- a/platform/tasks-platform-impl/src/com/intellij/tasks/impl/TaskManagerImpl.java +++ b/platform/tasks-platform-impl/src/com/intellij/tasks/impl/TaskManagerImpl.java @@ -33,6 +33,8 @@ import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsTaskHandler; import com.intellij.openapi.vcs.VcsType; import com.intellij.openapi.vcs.changes.*; +import com.intellij.openapi.vcs.changes.shelf.ShelveChangesManager; +import com.intellij.openapi.vcs.changes.shelf.ShelvedChangeList; import com.intellij.tasks.*; import com.intellij.tasks.context.WorkingContextManager; import com.intellij.ui.ColoredTreeCellRenderer; @@ -347,6 +349,7 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe myChangeListManager.setDefaultChangeList(changeList); } + unshelveChanges(task); List branches = task.getBranches(false); // we should have exactly one branch per repo MultiMap multiMap = new MultiMap<>(); @@ -376,6 +379,31 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe return task; } + public void shelveChanges(LocalTask task, @NotNull String shelfName) { + Collection changes = ChangeListManager.getInstance(myProject).getDefaultChangeList().getChanges(); + if (changes.isEmpty()) return; + try { + ShelveChangesManager.getInstance(myProject).shelveChanges(changes, shelfName, true); + task.setShelfName(shelfName); + } + catch (Exception e) { + LOG.warn("Can't shelve changes", e); + } + } + + private void unshelveChanges(LocalTask task) { + String name = task.getShelfName(); + if (name != null) { + ShelveChangesManager manager = ShelveChangesManager.getInstance(myProject); + for (ShelvedChangeList list : manager.getShelvedChangeLists()) { + if (name.equals(list.DESCRIPTION)) { + manager.unshelveChangeList(list, list.getChanges(myProject), list.getBinaryFiles(), myChangeListManager.getDefaultChangeList(), true); + return; + } + } + } + } + private List getAllBranches(final String repo) { ArrayList infos = new ArrayList<>(); VcsTaskHandler[] handlers = VcsTaskHandler.getAllHandlers(myProject); @@ -442,6 +470,10 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe private void saveActiveTask() { myContextManager.saveContext(myActiveTask); myActiveTask.setUpdated(new Date()); + String shelfName = myActiveTask.getShelfName(); + if (shelfName != null) { + shelveChanges(myActiveTask, shelfName); + } } private LocalTask doActivate(Task origin, boolean explicitly) { @@ -952,6 +984,7 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe public boolean createChangelist = true; public boolean createBranch = true; public boolean useBranch = false; + public boolean shelveChanges = false; // close task options public boolean commitChanges = true; diff --git a/platform/tasks-platform-impl/tasks-platform-impl.iml b/platform/tasks-platform-impl/tasks-platform-impl.iml index 4da758043da9..c2b658620173 100644 --- a/platform/tasks-platform-impl/tasks-platform-impl.iml +++ b/platform/tasks-platform-impl/tasks-platform-impl.iml @@ -17,5 +17,6 @@ + \ No newline at end of file diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java index 9aab9fd29ae1..1474ecd34908 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java @@ -105,7 +105,7 @@ public class OpenTaskDialog extends DialogWrapper { } myAdditionalPanel.setLayout(new BoxLayout(myAdditionalPanel, BoxLayout.Y_AXIS)); - myPanels = TaskDialogPanelProvider.getOpenTaskPanels(project, task); + myPanels = TaskDialogPanelProvider.getOpenTaskPanels(project, myTask); for (TaskDialogPanel panel : myPanels) { myAdditionalPanel.add(panel.getPanel()); } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/vcs/VcsOpenTaskPanel.form b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/vcs/VcsOpenTaskPanel.form index 46686b256408..0655d4cd1173 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/vcs/VcsOpenTaskPanel.form +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/vcs/VcsOpenTaskPanel.form @@ -3,12 +3,12 @@ - + - + @@ -21,17 +21,7 @@ - - - - - - - - - - - + @@ -41,23 +31,15 @@ - + - - - - - - - - - + @@ -65,7 +47,7 @@ - + @@ -74,7 +56,7 @@ - + @@ -82,10 +64,36 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/vcs/VcsOpenTaskPanel.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/vcs/VcsOpenTaskPanel.java index c5640b1e65d6..93860916b533 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/vcs/VcsOpenTaskPanel.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/vcs/VcsOpenTaskPanel.java @@ -52,6 +52,7 @@ public class VcsOpenTaskPanel extends TaskDialogPanel { private JBLabel myFromLabel; private JBCheckBox myUseBranch; private ComboBox myUseBranchCombo; + private JBCheckBox myShelveChanges; private VcsTaskHandler myVcsTaskHandler; private static final String START_FROM_BRANCH = "start.from.branch"; @@ -84,6 +85,7 @@ public class VcsOpenTaskPanel extends TaskDialogPanel { } }); myCreateChangelist.setSelected(myTaskManager.getState().createChangelist); + myShelveChanges.setSelected(myTaskManager.getState().shelveChanges); VcsTaskHandler[] handlers = VcsTaskHandler.getAllHandlers(project); if (handlers.length == 0) { @@ -167,10 +169,14 @@ public class VcsOpenTaskPanel extends TaskDialogPanel { @Override public void commit() { myTaskManager.getState().createChangelist = myCreateChangelist.isSelected(); + myTaskManager.getState().shelveChanges = myShelveChanges.isSelected(); myTaskManager.getState().createBranch = myCreateBranch.isSelected(); myTaskManager.getState().useBranch = myUseBranch.isSelected(); LocalTask localTask = myTaskManager.getActiveTask(); + if (myShelveChanges.isSelected()) { + myTaskManager.shelveChanges(myPreviousTask, myPreviousTask.getSummary()); + } if (myCreateChangelist.isSelected()) { myTaskManager.createChangeList(localTask, myChangelistName.getText()); } diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskVcsTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskVcsTest.java index 9e3b3ce2ed57..9ced6be01c1b 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskVcsTest.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskVcsTest.java @@ -17,24 +17,30 @@ package com.intellij.tasks.vcs; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.changes.*; import com.intellij.openapi.vcs.changes.committed.MockAbstractVcs; +import com.intellij.openapi.vcs.changes.shelf.ShelveChangesManager; +import com.intellij.openapi.vcs.changes.shelf.ShelvedChangeList; import com.intellij.openapi.vcs.changes.ui.CommitChangeListDialog; import com.intellij.openapi.vcs.impl.projectlevelman.AllVcses; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.tasks.*; +import com.intellij.tasks.actions.OpenTaskDialog; import com.intellij.tasks.impl.LocalTaskImpl; import com.intellij.tasks.impl.TaskChangelistSupport; import com.intellij.tasks.impl.TaskManagerImpl; import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.ui.UIUtil; import com.intellij.vcsUtil.VcsUtil; import icons.TasksIcons; import org.jetbrains.annotations.NotNull; import javax.swing.*; +import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; @@ -208,7 +214,7 @@ public class TaskVcsTest extends CodeInsightFixtureTestCase { LocalTask anotherTask = myTaskManager.findTask("TEST-001"); assertNotNull(anotherTask); - addChangeList("Default (1)", ""); + addChangeList("Default (1)"); assertEquals(1, anotherTask.getChangeLists().size()); assertEquals(2, defaultTask.getChangeLists().size()); @@ -236,7 +242,7 @@ public class TaskVcsTest extends CodeInsightFixtureTestCase { public void testTrackContext() { myTaskManager.getState().trackContextForNewChangelist = true; - addChangeList("New Changelist", ""); + addChangeList("New Changelist"); assertEquals(2, myTaskManager.getLocalTasks().size()); assertEquals(2, myChangeListManager.getChangeListsCopy().size()); LocalChangeList newChangeList = myChangeListManager.findChangeList("New Changelist"); @@ -298,7 +304,7 @@ public class TaskVcsTest extends CodeInsightFixtureTestCase { assertEquals(1, myTaskManager.getLocalTasks().size()); assertEquals(1, myChangeListManager.getChangeListsCopy().size()); - LocalChangeList changeList = addChangeList("New Changelist", ""); + LocalChangeList changeList = addChangeList("New Changelist"); assertEquals(1, myTaskManager.getLocalTasks().size()); assertEquals(2, myChangeListManager.getChangeListsCopy().size()); @@ -312,8 +318,8 @@ public class TaskVcsTest extends CodeInsightFixtureTestCase { assertTrue(ContainerUtil.exists(myTaskManager.getLocalTasks(), task -> task.getSummary().equals("New Changelist"))); } - private LocalChangeList addChangeList(String title, String comment) { - final LocalChangeList list = myChangeListManager.addChangeList(title, comment); + private LocalChangeList addChangeList(String title) { + final LocalChangeList list = myChangeListManager.addChangeList(title, ""); new TaskChangelistSupport(getProject(), myTaskManager).addControls(new JPanel(), null).consume(list); return list; } @@ -412,6 +418,32 @@ public class TaskVcsTest extends CodeInsightFixtureTestCase { assertEquals("1-contains-Illegal$Symbols", myTaskManager.suggestBranchName(withIllegalSymbolsInIssue)); } + public void testShelveChanges() { + + LocalTask activeTask = myTaskManager.getActiveTask(); + addChanges(myChangeListManager.getDefaultChangeList()); + + myTaskManager.getState().shelveChanges = true; + LocalTaskImpl task = new LocalTaskImpl("id", "summary"); + OpenTaskDialog dialog = new OpenTaskDialog(getProject(), task); + try { + dialog.createTask(); + assertEquals(activeTask.getSummary(), activeTask.getShelfName()); + + List lists = ShelveChangesManager.getInstance(getProject()).getShelvedChangeLists(); + assertTrue(lists.stream().anyMatch(list -> list.DESCRIPTION.equals(activeTask.getShelfName()))); + + assertEmpty(myChangeListManager.getDefaultChangeList().getChanges()); + myTaskManager.activateTask(activeTask, true); + Collection changes = myChangeListManager.getDefaultChangeList().getChanges(); + assertNotEmpty(changes); + } + finally { + dialog.close(DialogWrapper.OK_EXIT_CODE); + } + UIUtil.dispatchAllInvocationEvents(); + } + @Override public void setUp() throws Exception { super.setUp();