diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ScheduleForAdditionAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ScheduleForAdditionAction.java index 1ccf521f69a9..888e2c72ca9d 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ScheduleForAdditionAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ScheduleForAdditionAction.java @@ -28,8 +28,9 @@ import com.intellij.openapi.vcs.*; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.ChangeListManagerImpl; import com.intellij.openapi.vcs.changes.LocalChangeList; +import com.intellij.openapi.vcs.changes.ui.ChangesBrowserBase; import com.intellij.openapi.vcs.changes.ui.ChangesListView; -import com.intellij.openapi.vcs.changes.ui.OldChangesBrowserBase; +import com.intellij.openapi.vcs.changes.ui.CommitDialogChangesBrowser; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ArrayUtil; import com.intellij.util.Consumer; @@ -59,13 +60,13 @@ public class ScheduleForAdditionAction extends AnAction implements DumbAware { Project project = e.getRequiredData(CommonDataKeys.PROJECT); List unversionedFiles = getUnversionedFiles(e, project).collect(Collectors.toList()); - addUnversioned(project, unversionedFiles, this::isStatusForAddition, e.getData(OldChangesBrowserBase.DATA_KEY)); + addUnversioned(project, unversionedFiles, this::isStatusForAddition, e.getData(ChangesBrowserBase.DATA_KEY)); } public static boolean addUnversioned(@NotNull Project project, @NotNull List files, @NotNull Condition unversionedFileCondition, - @Nullable OldChangesBrowserBase browser) { + @Nullable ChangesBrowserBase browser) { boolean result = true; if (!files.isEmpty()) { @@ -73,13 +74,20 @@ public class ScheduleForAdditionAction extends AnAction implements DumbAware { @SuppressWarnings("unchecked") Consumer> consumer = browser == null ? null : changes -> { - browser.rebuildList(); - browser.getViewer().excludeChanges((List)files); + if (browser instanceof CommitDialogChangesBrowser) { + ((CommitDialogChangesBrowser)browser).updateDisplayedChangeLists(); + } browser.getViewer().includeChanges((List)changes); }; ChangeListManagerImpl manager = ChangeListManagerImpl.getInstanceImpl(project); - LocalChangeList targetChangeList = - browser == null ? manager.getDefaultChangeList() : (LocalChangeList)browser.getSelectedChangeList(); + + LocalChangeList targetChangeList; + if (browser instanceof CommitDialogChangesBrowser) { + targetChangeList = ((CommitDialogChangesBrowser)browser).getSelectedChangeList(); + } + else { + targetChangeList = manager.getDefaultChangeList(); + } List exceptions = manager.addUnversionedFiles(targetChangeList, files, unversionedFileCondition, consumer); result = exceptions.isEmpty(); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/AlienChangeListBrowser.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/AlienChangeListBrowser.java index d0357471d987..721f3f934622 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/AlienChangeListBrowser.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/AlienChangeListBrowser.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -16,49 +16,107 @@ package com.intellij.openapi.vcs.changes.ui; import com.intellij.openapi.actionSystem.ActionManager; -import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.VcsDataKeys; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.ChangeList; +import com.intellij.openapi.vcs.changes.LocalChangeList; +import com.intellij.openapi.vcs.changes.RemoteRevisionsCache; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import javax.swing.tree.DefaultTreeModel; import java.util.Collections; import java.util.List; -public class AlienChangeListBrowser extends ChangesBrowser { - private final List myChanges; +public class AlienChangeListBrowser extends CommitDialogChangesBrowser { + @NotNull private final LocalChangeList myChangeList; + @NotNull private final List myChanges; - public AlienChangeListBrowser(final Project project, final List changeLists, final List changes, - final ChangeList initialListSelection, final boolean capableOfExcludingChanges, - final boolean highlightProblems) { - super(project, changeLists, changes, initialListSelection, capableOfExcludingChanges, highlightProblems, null, MyUseCase.LOCAL_CHANGES, null); + public AlienChangeListBrowser(@NotNull Project project, + @NotNull LocalChangeList changelist, + @NotNull List changes) { + super(project, true, true); + myChangeList = changelist; myChanges = changes; - rebuildList(); + + init(); } - @Override - public void rebuildList() { - // dont change lists - myViewer.setChangesToDisplay(myChanges == null ? Collections.emptyList() : myChanges); - } - - protected void setInitialSelection(final List changeLists, final List changes, final ChangeList initialListSelection) { - if (! changeLists.isEmpty()) { - mySelectedChangeList = changeLists.get(0); - } - } - - @Override - protected void buildToolBar(DefaultActionGroup toolBarGroup) { - super.buildToolBar(toolBarGroup); - - toolBarGroup.add(ActionManager.getInstance().getAction("AlienCommitChangesDialog.AdditionalActions")); - } - - @Override @NotNull - public List getCurrentIncludedChanges() { - return ContainerUtil.newArrayList(myChanges); + @Override + protected List createToolbarActions() { + return ContainerUtil.append( + super.createToolbarActions(), + ActionManager.getInstance().getAction("AlienCommitChangesDialog.AdditionalActions") + ); + } + + @NotNull + @Override + protected DefaultTreeModel buildTreeModel(boolean showFlatten) { + RemoteStatusChangeNodeDecorator decorator = RemoteRevisionsCache.getInstance(myProject).getChangesNodeDecorator(); + return TreeModelBuilder.buildFromChanges(myProject, showFlatten, myChanges, decorator); + } + + + @NotNull + @Override + public LocalChangeList getSelectedChangeList() { + return myChangeList; + } + + + @NotNull + @Override + public List getDisplayedChanges() { + return myChanges; + } + + @NotNull + @Override + public List getSelectedChanges() { + return VcsTreeModelData.selected(myViewer).userObjects(Change.class); + } + + @NotNull + @Override + public List getIncludedChanges() { + return myChanges; + } + + @NotNull + @Override + public List getDisplayedUnversionedFiles() { + return Collections.emptyList(); + } + + @NotNull + @Override + public List getSelectedUnversionedFiles() { + return Collections.emptyList(); + } + + @NotNull + @Override + public List getIncludedUnversionedFiles() { + return Collections.emptyList(); + } + + @Override + public void updateDisplayedChangeLists() { + } + + + @Nullable + @Override + public Object getData(String dataId) { + if (VcsDataKeys.CHANGE_LISTS.is(dataId)) { + return new ChangeList[]{myChangeList}; + } + return super.getData(dataId); } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java index cd17073b4972..a88e2aa2c8a5 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java @@ -19,9 +19,7 @@ import com.intellij.diff.util.DiffPlaces; import com.intellij.diff.util.DiffUserDataKeysEx; import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.DataKey; -import com.intellij.openapi.actionSystem.DataSink; -import com.intellij.openapi.actionSystem.TypeSafeDataProvider; +import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.extensions.Extensions; @@ -53,6 +51,7 @@ import com.intellij.util.ui.AbstractLayoutManager; import com.intellij.util.ui.GridBag; import com.intellij.util.ui.JBDimension; import com.intellij.util.ui.JBUI; +import com.intellij.util.ui.components.BorderLayoutPanel; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -70,7 +69,6 @@ import static com.intellij.openapi.vcs.VcsBundle.message; import static com.intellij.util.ArrayUtil.isEmpty; import static com.intellij.util.ArrayUtil.toObjectArray; import static com.intellij.util.ObjectUtils.notNull; -import static com.intellij.util.containers.ContainerUtil.createMaybeSingletonList; import static com.intellij.util.containers.ContainerUtil.isEmpty; import static com.intellij.util.containers.ContainerUtil.map; import static com.intellij.util.containers.ContainerUtil.map2SetNotNull; @@ -80,7 +78,7 @@ import static com.intellij.util.containers.ContainerUtil.newHashMap; import static com.intellij.util.containers.ContainerUtil.newHashSet; import static java.util.Collections.*; -public class CommitChangeListDialog extends DialogWrapper implements CheckinProjectPanel, TypeSafeDataProvider { +public class CommitChangeListDialog extends DialogWrapper implements CheckinProjectPanel, DataProvider { private static final String HELP_ID = "reference.dialogs.vcs.commit"; private static final String TITLE = message("commit.dialog.title"); @@ -110,7 +108,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj @NotNull private final CommitOptionsPanel myCommitOptions; @NotNull private final CommitContext myCommitContext; @NotNull private final ChangeInfoCalculator myChangesInfoCalculator; - @NotNull private final OldChangesBrowserBase myBrowser; + @NotNull private final CommitDialogChangesBrowser myBrowser; @NotNull private final MyChangeProcessor myDiffDetails; @NotNull private final CommitMessage myCommitMessageArea; @NotNull private final CommitLegendPanel myLegend; @@ -290,36 +288,46 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj myCommitMessageArea = new CommitMessage(project, true, true, myShowVcsCommit); if (myIsAlien) { - myCommitMessageArea.setChangeLists(newArrayList(changeLists)); - myBrowser = new AlienChangeListBrowser(project, changeLists, changes, initialSelection, true, true); - } else { - myCommitMessageArea.setChangeLists(createMaybeSingletonList(initialSelection)); - //noinspection unchecked - MultipleChangeListBrowser browser = - new MultipleChangeListBrowser(project, changeLists, (List)changes, initialSelection, () -> updateWarning(), - () -> myHandlers.forEach(CheckinHandler::includedChangesChanged), myShowVcsCommit); - browser.addSelectedListChangeListener(new SelectedListChangeListener() { - @Override - public void selectedListChanged() { - myCommitMessageArea.setChangeLists(createMaybeSingletonList(browser.getSelectedChangeList())); - updateOnListSelection(); - } - }); - myBrowser = browser; - myBrowser.setAlwayExpandList(false); - } - myBrowser.getViewer().addSelectionListener(() -> SwingUtilities.invokeLater(() -> changeDetails())); - myBrowser.setDiffBottomComponent(new DiffCommitMessageEditor(myProject, myCommitMessageArea)); + assert changeLists.size() == 1; + LocalChangeList changeList = changeLists.get(0); - mySplitter = new Splitter(true); - mySplitter.setHonorComponentsMinimumSize(true); - mySplitter.setFirstComponent(myBrowser); - mySplitter.setSecondComponent(myCommitMessageArea); - mySplitter.setProportion(PropertiesComponent.getInstance().getFloat(SPLITTER_PROPORTION_OPTION, SPLITTER_PROPORTION_OPTION_DEFAULT)); + myBrowser = new AlienChangeListBrowser(project, changeList, changes); + + myCommitMessageArea.setChangeList(changeList); + } + else { + MultipleLocalChangeListsBrowser browser = new MultipleLocalChangeListsBrowser(project, true, true, myShowVcsCommit); + myBrowser = browser; + + if (initialSelection != null) browser.setSelectedChangeList(initialSelection); + myCommitMessageArea.setChangeList(browser.getSelectedChangeList()); + + DiffCommitMessageEditor commitMessageEditor = new DiffCommitMessageEditor(myProject, myCommitMessageArea); + browser.setBottomDiffComponent(commitMessageEditor); + + browser.setInclusionChangedListener(() -> myHandlers.forEach(CheckinHandler::includedChangesChanged)); + browser.setSelectedListChangeListener(() -> { + myCommitMessageArea.setChangeList(browser.getSelectedChangeList()); + updateOnListSelection(); + updateWarning(); + }); + + browser.getViewer().addSelectionListener(() -> SwingUtilities.invokeLater(() -> changeDetails())); + browser.getViewer().setKeepTreeState(true); + } + + myBrowser.getViewer().setIncludedChanges(changes); myChangesInfoCalculator = new ChangeInfoCalculator(); myLegend = new CommitLegendPanel(myChangesInfoCalculator); - myBrowser.getBottomPanel().add(JBUI.Panels.simplePanel().addToRight(myLegend.getComponent()), BorderLayout.SOUTH); + BorderLayoutPanel legendPanel = JBUI.Panels.simplePanel().addToRight(myLegend.getComponent()); + BorderLayoutPanel topPanel = JBUI.Panels.simplePanel().addToCenter(myBrowser).addToBottom(legendPanel); + + mySplitter = new Splitter(true); + mySplitter.setHonorComponentsMinimumSize(true); + mySplitter.setFirstComponent(topPanel); + mySplitter.setSecondComponent(myCommitMessageArea); + mySplitter.setProportion(PropertiesComponent.getInstance().getFloat(SPLITTER_PROPORTION_OPTION, SPLITTER_PROPORTION_OPTION_DEFAULT)); if (!myVcsConfiguration.CLEAR_INITIAL_COMMIT_MESSAGE) { setComment(initialSelection, comment); @@ -860,7 +868,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj public Collection getRoots() { ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject); - return map2SetNotNull(myBrowser.getCurrentDisplayedChanges(), change -> vcsManager.getVcsRootFor(ChangesUtil.getFilePath(change))); + return map2SetNotNull(myBrowser.getDisplayedChanges(), change -> vcsManager.getVcsRootFor(ChangesUtil.getFilePath(change))); } @NotNull @@ -920,7 +928,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj @Override public void refresh() { ChangeListManager.getInstance(myProject).invokeAfterUpdate(() -> { - myBrowser.rebuildList(); + myBrowser.updateDisplayedChangeLists(); myCommitOptions.refresh(); }, InvokeAfterUpdateMode.SILENT, "commit dialog", ModalityState.current()); } @@ -955,14 +963,15 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj private void updateLegend() { if (myDisposed || myUpdateDisabled) return; - myChangesInfoCalculator.update(myBrowser.getCurrentDisplayedChanges(), getIncludedChanges(), myBrowser.getUnversionedFilesCount(), + myChangesInfoCalculator.update(myBrowser.getDisplayedChanges(), getIncludedChanges(), + myBrowser.getDisplayedUnversionedFiles().size(), myBrowser.getIncludedUnversionedFiles().size()); myLegend.update(); } @NotNull private List getIncludedChanges() { - return myBrowser.getCurrentIncludedChanges(); + return myBrowser.getIncludedChanges(); } @Override @@ -976,14 +985,13 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj return myCommitMessageArea.getEditorField(); } + @Nullable @Override - public void calcData(DataKey key, DataSink sink) { - if (key == Refreshable.PANEL_KEY) { - sink.put(Refreshable.PANEL_KEY, this); - } - else { - myBrowser.calcData(key, sink); + public Object getData(String dataId) { + if (Refreshable.PANEL_KEY.is(dataId)) { + return this; } + return myBrowser.getData(dataId); } @NotNull @@ -992,13 +1000,8 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj } private void ensureDataIsActual(@NotNull Runnable runnable) { - if (myBrowser.isDataIsDirty()) { - ChangeListManager.getInstance(myProject).invokeAfterUpdate(runnable, InvokeAfterUpdateMode.SYNCHRONOUS_CANCELLABLE, - "Refreshing changelists...", ModalityState.current()); - } - else { - runnable.run(); - } + ChangeListManager.getInstance(myProject).invokeAfterUpdate(runnable, InvokeAfterUpdateMode.SYNCHRONOUS_CANCELLABLE, + "Refreshing changelists...", ModalityState.current()); } private class CommitExecutorAction extends AbstractAction { @@ -1055,13 +1058,13 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj @NotNull @Override protected List getAllChanges() { - return myBrowser.getAllChanges(); + return myBrowser.getDisplayedChanges(); } @Override protected void selectChange(@NotNull Change change) { //noinspection unchecked - myBrowser.select((List)singletonList(change)); + myBrowser.selectEntries((List)singletonList(change)); } @Override diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitDialogChangesBrowser.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitDialogChangesBrowser.java new file mode 100644 index 000000000000..dff93bb85523 --- /dev/null +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitDialogChangesBrowser.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2017 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 com.intellij.openapi.vcs.changes.ui; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.changes.Change; +import com.intellij.openapi.vcs.changes.LocalChangeList; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public abstract class CommitDialogChangesBrowser extends ChangesBrowserBase implements Disposable { + public CommitDialogChangesBrowser(@NotNull Project project, + boolean showCheckboxes, + boolean highlightProblems) { + super(project, showCheckboxes, highlightProblems); + } + + @Override + public void dispose() { + } + + + @NotNull + public abstract LocalChangeList getSelectedChangeList(); + + + @NotNull + public abstract List getDisplayedChanges(); + + @NotNull + public abstract List getSelectedChanges(); + + @NotNull + public abstract List getIncludedChanges(); + + @NotNull + public abstract List getDisplayedUnversionedFiles(); + + @NotNull + public abstract List getSelectedUnversionedFiles(); + + @NotNull + public abstract List getIncludedUnversionedFiles(); + + + public abstract void updateDisplayedChangeLists(); +} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/MultipleChangeListBrowser.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/MultipleChangeListBrowser.java deleted file mode 100644 index 1b2e7eeec734..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/MultipleChangeListBrowser.java +++ /dev/null @@ -1,457 +0,0 @@ -/* - * Copyright 2000-2017 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 com.intellij.openapi.vcs.changes.ui; - -import com.intellij.icons.AllIcons; -import com.intellij.ide.DataManager; -import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.actionSystem.ex.AnActionListener; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ModalityState; -import com.intellij.openapi.diff.DiffBundle; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.ComboBox; -import com.intellij.openapi.util.Condition; -import com.intellij.openapi.vcs.VcsBundle; -import com.intellij.openapi.vcs.VcsConfiguration; -import com.intellij.openapi.vcs.VcsDataKeys; -import com.intellij.openapi.vcs.changes.*; -import com.intellij.openapi.vcs.changes.actions.MoveChangesToAnotherListAction; -import com.intellij.openapi.vcs.changes.actions.RollbackDialogAction; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.wm.IdeFocusManager; -import com.intellij.ui.ColoredListCellRendererWrapper; -import com.intellij.ui.SimpleTextAttributes; -import com.intellij.util.EventDispatcher; -import com.intellij.util.ObjectUtils; -import com.intellij.util.containers.ContainerUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreePath; -import java.awt.*; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.util.*; -import java.util.List; - -import static com.intellij.openapi.util.text.StringUtil.capitalize; -import static com.intellij.openapi.util.text.StringUtil.shortenTextWithEllipsis; -import static java.util.stream.Collectors.toList; - -public class MultipleChangeListBrowser extends OldChangesBrowserBase { - - @NotNull private final ChangeListChooser myChangeListChooser; - @NotNull final ChangeListListener myChangeListListener = new MyChangeListListener(); - @NotNull private final EventDispatcher myDispatcher = - EventDispatcher.create(SelectedListChangeListener.class); - @Nullable private final Runnable myRebuildListListener; - @NotNull private final VcsConfiguration myVcsConfiguration; - private final boolean myUnversionedFilesEnabled; - private boolean myInRebuildList; - private AnAction myMoveActionWithCustomShortcut; - - // todo terrible constructor - public MultipleChangeListBrowser(@NotNull Project project, - @NotNull List changeLists, - @NotNull List changes, - @Nullable ChangeList initialListSelection, - @Nullable Runnable rebuildListListener, - @Nullable Runnable inclusionListener, - boolean unversionedFilesEnabled) { - super(project, changes, true, true, inclusionListener, ChangesBrowser.MyUseCase.LOCAL_CHANGES, null, Object.class); - myRebuildListListener = rebuildListListener; - myVcsConfiguration = ObjectUtils.assertNotNull(VcsConfiguration.getInstance(myProject)); - myUnversionedFilesEnabled = unversionedFilesEnabled; - - init(); - setInitialSelection(changeLists, changes, initialListSelection); - - myChangeListChooser = new ChangeListChooser(); - myHeaderPanel.add(myChangeListChooser, BorderLayout.EAST); - ChangeListManager.getInstance(myProject).addChangeListListener(myChangeListListener); - - setupRebuildListForActions(); - rebuildList(); - } - - private void setupRebuildListForActions() { - ActionManager actionManager = ActionManager.getInstance(); - final AnAction moveAction = actionManager.getAction(IdeActions.MOVE_TO_ANOTHER_CHANGE_LIST); - final AnAction deleteAction = actionManager.getAction("ChangesView.DeleteUnversioned.From.Dialog"); - - actionManager.addAnActionListener(new AnActionListener.Adapter() { - @Override - public void afterActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) { - if (moveAction.equals(action) || myMoveActionWithCustomShortcut != null && myMoveActionWithCustomShortcut.equals(action)) { - rebuildList(); - } - else if (deleteAction.equals(action)) { - UnversionedViewDialog.refreshChanges(myProject, MultipleChangeListBrowser.this); - } - } - }, this); - } - - private boolean isShowUnversioned() { - return myUnversionedFilesEnabled && myVcsConfiguration.SHOW_UNVERSIONED_FILES_WHILE_COMMIT; - } - - private void setShowUnversioned(boolean value) { - myVcsConfiguration.SHOW_UNVERSIONED_FILES_WHILE_COMMIT = value; - rebuildList(); - } - - @Override - protected void setInitialSelection(@NotNull List changeLists, - @NotNull List changes, - @Nullable ChangeList initialListSelection) { - mySelectedChangeList = initialListSelection; - - for (ChangeList list : changeLists) { - if (list instanceof LocalChangeList) { - if (initialListSelection == null && ContainerUtil.intersects(list.getChanges(), changes)) { - mySelectedChangeList = list; - } - } - } - - if (mySelectedChangeList == null) { - mySelectedChangeList = ObjectUtils.chooseNotNull(findDefaultList(changeLists), ContainerUtil.getFirstItem(changeLists)); - } - } - - @Override - public void dispose() { - ChangeListManager.getInstance(myProject).removeChangeListListener(myChangeListListener); - } - - public void addSelectedListChangeListener(@NotNull SelectedListChangeListener listener) { - myDispatcher.addListener(listener); - } - - private void setSelectedList(@Nullable ChangeList list) { - mySelectedChangeList = list; - rebuildList(); - myDispatcher.getMulticaster().selectedListChanged(); - } - - @Override - public void rebuildList() { - if (myInRebuildList) return; - try { - myInRebuildList = true; - - updateListsInChooser(); - super.rebuildList(); - if (myRebuildListListener != null) { - myRebuildListListener.run(); - } - } finally { - myInRebuildList = false; - } - } - - @Override - @NotNull - public List getCurrentIncludedChanges() { - Collection includedObjects = myViewer.getIncludedChanges(); - - return mySelectedChangeList.getChanges().stream().filter(includedObjects::contains).collect(toList()); - } - - @NotNull - @Override - protected DefaultTreeModel buildTreeModel(@NotNull List objects, - @Nullable ChangeNodeDecorator changeNodeDecorator, - boolean showFlatten) { - ChangeListManagerImpl manager = ChangeListManagerImpl.getInstanceImpl(myProject); - TreeModelBuilder builder = new TreeModelBuilder(myProject, showFlatten); - List unversionedFiles = manager.getUnversionedFiles(); - - builder.setChanges(findChanges(objects), changeNodeDecorator); - if (isShowUnversioned()) { - builder.setUnversioned(unversionedFiles); - } - if (myUnversionedFilesEnabled) { - if (!isShowUnversioned() && !unversionedFiles.isEmpty()) { - myViewer.getEmptyText() - .setText("Unversioned files available. ") - .appendText("Show", SimpleTextAttributes.LINK_ATTRIBUTES, e -> setShowUnversioned(true)); - } - else { - myViewer.getEmptyText().setText(capitalize(DiffBundle.message("diff.count.differences.status.text", 0))); - } - } - - return builder.build(); - } - - @NotNull - @Override - protected List getSelectedObjects(@NotNull ChangesBrowserNode node) { - List result = ContainerUtil.newArrayList(); - - result.addAll(node.getAllChangesUnder()); - if (isShowUnversioned()) { - if (isUnderUnversioned(node)) { - result.addAll(node.getAllFilesUnder()); - } - else if (node.isRoot()) { - ChangesBrowserUnversionedFilesNode unversionedFilesNode = findUnversionedFilesNode(); - if (unversionedFilesNode != null) result.addAll(unversionedFilesNode.getAllFilesUnder()); - } - } - - return result; - } - - @Nullable - @Override - protected Object getLeadSelectedObject(@NotNull ChangesBrowserNode node) { - Object result = null; - Object userObject = node.getUserObject(); - - if (userObject instanceof Change || isShowUnversioned() && isUnderUnversioned(node) && userObject instanceof VirtualFile) { - result = userObject; - } - - return result; - } - - @NotNull - @Override - public List getCurrentDisplayedObjects() { - //noinspection unchecked - return (List)getCurrentDisplayedChanges(); - } - - @NotNull - @Override - public List getIncludedUnversionedFiles() { - return isShowUnversioned() - ? ContainerUtil.findAll(myViewer.getIncludedChanges(), VirtualFile.class) - : Collections.emptyList(); - } - - @Override - public int getUnversionedFilesCount() { - int result = 0; - - if (isShowUnversioned()) { - ChangesBrowserUnversionedFilesNode node = findUnversionedFilesNode(); - - if (node != null) { - result = node.getFileCount(); - } - } - - return result; - } - - @Nullable - private ChangesBrowserUnversionedFilesNode findUnversionedFilesNode() { - //noinspection unchecked - Enumeration nodes = myViewer.getRoot().children(); - - return ContainerUtil.findInstance(ContainerUtil.iterate(nodes), ChangesBrowserUnversionedFilesNode.class); - } - - @NotNull - @Override - public List getSelectedChanges() { - Set changes = ContainerUtil.newLinkedHashSet(); - TreePath[] paths = myViewer.getSelectionPaths(); - - if (paths != null) { - for (TreePath path : paths) { - ChangesBrowserNode node = (ChangesBrowserNode)path.getLastPathComponent(); - changes.addAll(node.getAllChangesUnder()); - } - } - - return ContainerUtil.newArrayList(changes); - } - - @NotNull - @Override - public List getAllChanges() { - return myViewer.getRoot().getAllChangesUnder(); - } - - @Override - protected void buildToolBar(@NotNull DefaultActionGroup toolBarGroup) { - super.buildToolBar(toolBarGroup); - - toolBarGroup.add(new AnAction("Refresh Changes", null, AllIcons.Actions.Refresh) { - @Override - public void actionPerformed(AnActionEvent e) { - rebuildList(); - } - }); - if (myUnversionedFilesEnabled) { - toolBarGroup.add(new ShowHideUnversionedFilesAction()); - toolBarGroup.add(UnversionedViewDialog.getUnversionedActionGroup()); - } - else { - toolBarGroup.add(ActionManager.getInstance().getAction(IdeActions.MOVE_TO_ANOTHER_CHANGE_LIST)); - } - UnversionedViewDialog.registerUnversionedActionsShortcuts(DataManager.getInstance().getDataContext(this), myViewer); - // We do not add "Delete" key shortcut for deleting unversioned files as this shortcut is already used to uncheck - // checkboxes in the tree. - myMoveActionWithCustomShortcut = - EmptyAction.registerWithShortcutSet(IdeActions.MOVE_TO_ANOTHER_CHANGE_LIST, CommonShortcuts.getMove(), myViewer); - - RollbackDialogAction rollback = new RollbackDialogAction(); - rollback.registerCustomShortcutSet(this, null); - toolBarGroup.add(rollback); - - EditSourceForDialogAction editSourceAction = new EditSourceForDialogAction(this); - editSourceAction.registerCustomShortcutSet(CommonShortcuts.getEditSource(), this); - toolBarGroup.add(editSourceAction); - - toolBarGroup.add(ActionManager.getInstance().getAction("Vcs.CheckinProjectToolbar")); - } - - @Override - protected void afterDiffRefresh() { - rebuildList(); - setDataIsDirty(false); - ApplicationManager.getApplication().invokeLater( - () -> IdeFocusManager.findInstance().requestFocus(myViewer.getPreferredFocusedComponent(), true)); - } - - @Override - protected List createDiffActions() { - List actions = super.createDiffActions(); - actions.add(new MoveAction()); - return actions; - } - - private void updateListsInChooser() { - Runnable runnable = () -> myChangeListChooser.updateLists(ChangeListManager.getInstance(myProject).getChangeListsCopy()); - if (SwingUtilities.isEventDispatchThread()) { - runnable.run(); - } - else { - ApplicationManager.getApplication().invokeLater(runnable, ModalityState.stateForComponent(this)); - } - } - - @Nullable - private static ChangeList findDefaultList(@NotNull List lists) { - return ContainerUtil.find(lists, (Condition)list -> list instanceof LocalChangeList && ((LocalChangeList)list).isDefault()); - } - - private class ChangeListChooser extends JPanel { - private final static int MAX_LEN = 35; - @NotNull private final ComboBox myChooser; - - public ChangeListChooser() { - super(new BorderLayout(4, 2)); - myChooser = new ComboBox(); - //noinspection unchecked - myChooser.setRenderer(new ColoredListCellRendererWrapper() { - @Override - protected void doCustomize(JList list, LocalChangeList value, int index, boolean selected, boolean hasFocus) { - if (value != null) { - String name = shortenTextWithEllipsis(value.getName().trim(), MAX_LEN, 0); - - append(name, value.isDefault() ? SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES : SimpleTextAttributes.REGULAR_ATTRIBUTES); - } - } - }); - - myChooser.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - if (e.getStateChange() == ItemEvent.SELECTED) { - final LocalChangeList changeList = (LocalChangeList)myChooser.getSelectedItem(); - setSelectedList(changeList); - myChooser.setToolTipText(changeList == null ? "" : (changeList.getName())); - } - } - }); - - myChooser.setEditable(false); - add(myChooser, BorderLayout.CENTER); - - JLabel label = new JLabel(VcsBundle.message("commit.dialog.changelist.label")); - label.setLabelFor(myChooser); - add(label, BorderLayout.WEST); - } - - public void updateLists(@NotNull List lists) { - //noinspection unchecked - myChooser.setModel(new DefaultComboBoxModel(lists.toArray())); - myChooser.setEnabled(lists.size() > 1); - if (lists.contains(mySelectedChangeList)) { - myChooser.setSelectedItem(mySelectedChangeList); - } else { - if (myChooser.getItemCount() > 0) { - myChooser.setSelectedIndex(0); - } - } - mySelectedChangeList = (ChangeList) myChooser.getSelectedItem(); - } - } - - private class MyChangeListListener extends ChangeListAdapter { - public void changeListAdded(ChangeList list) { - updateListsInChooser(); - } - } - - private class ShowHideUnversionedFilesAction extends ToggleAction { - - private ShowHideUnversionedFilesAction() { - super("Show Unversioned Files", null, AllIcons.Vcs.ShowUnversionedFiles); - } - - @Override - public void update(@NotNull AnActionEvent e) { - super.update(e); - - e.getPresentation().setEnabledAndVisible(e.isFromActionToolbar()); - } - - @Override - public boolean isSelected(@NotNull AnActionEvent e) { - return myVcsConfiguration.SHOW_UNVERSIONED_FILES_WHILE_COMMIT; - } - - @Override - public void setSelected(@NotNull AnActionEvent e, boolean state) { - setShowUnversioned(state); - } - } - - private class MoveAction extends MoveChangesToAnotherListAction { - @Override - protected boolean isEnabled(@NotNull AnActionEvent e) { - Change change = e.getData(VcsDataKeys.CURRENT_CHANGE); - if (change == null) return false; - return super.isEnabled(e); - } - - @Override - public void actionPerformed(@NotNull AnActionEvent e) { - Change change = e.getRequiredData(VcsDataKeys.CURRENT_CHANGE); - askAndMove(myProject, Collections.singletonList(change), Collections.emptyList()); - } - } -} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/MultipleLocalChangeListsBrowser.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/MultipleLocalChangeListsBrowser.java index f186cd0fa1ef..cbe70f71396a 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/MultipleLocalChangeListsBrowser.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/MultipleLocalChangeListsBrowser.java @@ -15,6 +15,8 @@ */ package com.intellij.openapi.vcs.changes.ui; +import com.intellij.diff.chains.DiffRequestChain; +import com.intellij.diff.util.DiffUserDataKeysEx; import com.intellij.icons.AllIcons; import com.intellij.ide.DataManager; import com.intellij.ide.DeleteProvider; @@ -57,8 +59,9 @@ import java.util.List; import static com.intellij.openapi.util.text.StringUtil.shortenTextWithEllipsis; import static com.intellij.openapi.vcs.changes.ui.ChangesListView.UNVERSIONED_FILES_DATA_KEY; -public class MultipleLocalChangeListsBrowser extends ChangesBrowserBase implements Disposable { +public class MultipleLocalChangeListsBrowser extends CommitDialogChangesBrowser implements Disposable { private final boolean myEnableUnversioned; + @Nullable private JComponent myBottomDiffComponent; @NotNull private final ChangeListChooser myChangeListChooser; @NotNull private final DeleteProvider myDeleteProvider = new VirtualFileDeleteProvider(); @@ -69,6 +72,8 @@ public class MultipleLocalChangeListsBrowser extends ChangesBrowserBase implemen @NotNull private LocalChangeList myChangeList; + @Nullable private Runnable mySelectedListChangeListener; + public MultipleLocalChangeListsBrowser(@NotNull Project project, boolean showCheckboxes, boolean highlightProblems, @@ -80,17 +85,12 @@ public class MultipleLocalChangeListsBrowser extends ChangesBrowserBase implemen myChangeListChooser = new ChangeListChooser(); installChangeListListener(); - init(); updateDisplayedChangeLists(); setSelectedChangeList(myChangeList); } - @Override - public void dispose() { - } - private void installChangeListListener() { ChangeListAdapter changeListListener = new MyChangeListListener(); ChangeListManager.getInstance(myProject).addChangeListListener(changeListListener); @@ -148,6 +148,20 @@ public class MultipleLocalChangeListsBrowser extends ChangesBrowserBase implemen ); } + @Override + protected void updateDiffContext(@NotNull DiffRequestChain chain) { + super.updateDiffContext(chain); + chain.putUserData(DiffUserDataKeysEx.BOTTOM_PANEL, myBottomDiffComponent); + } + + + public void setBottomDiffComponent(@NotNull JComponent value) { + myBottomDiffComponent = value; + } + + public void setSelectedListChangeListener(@Nullable Runnable runnable) { + mySelectedListChangeListener = runnable; + } private boolean isShowUnversioned() { return myEnableUnversioned && VcsConfiguration.getInstance(myProject).SHOW_UNVERSIONED_FILES_WHILE_COMMIT; @@ -159,6 +173,7 @@ public class MultipleLocalChangeListsBrowser extends ChangesBrowserBase implemen } @NotNull + @Override public LocalChangeList getSelectedChangeList() { return myChangeList; } @@ -167,6 +182,7 @@ public class MultipleLocalChangeListsBrowser extends ChangesBrowserBase implemen myChangeList = list; myChangeListChooser.setToolTipText(list.getName()); updateDisplayedChanges(); + if (mySelectedListChangeListener != null) mySelectedListChangeListener.run(); } public void updateDisplayedChangeLists() { @@ -232,6 +248,45 @@ public class MultipleLocalChangeListsBrowser extends ChangesBrowserBase implemen } + @NotNull + @Override + public List getDisplayedChanges() { + return myChanges; + } + + @NotNull + @Override + public List getSelectedChanges() { + return VcsTreeModelData.selected(myViewer).userObjects(Change.class); + } + + @NotNull + @Override + public List getIncludedChanges() { + return VcsTreeModelData.included(myViewer).userObjects(Change.class); + } + + @NotNull + @Override + public List getDisplayedUnversionedFiles() { + return myUnversioned; + } + + @NotNull + @Override + public List getSelectedUnversionedFiles() { + if (!isShowUnversioned()) return Collections.emptyList(); + return VcsTreeModelData.selected(myViewer).userObjects(VirtualFile.class); + } + + @NotNull + @Override + public List getIncludedUnversionedFiles() { + if (!isShowUnversioned()) return Collections.emptyList(); + return VcsTreeModelData.included(myViewer).userObjects(VirtualFile.class); + } + + private class ChangeListChooser extends JPanel { private final static int MAX_NAME_LEN = 35; @NotNull private final ComboBox myChooser = new ComboBox<>(); @@ -248,6 +303,7 @@ public class MultipleLocalChangeListsBrowser extends ChangesBrowserBase implemen }); myChooser.addItemListener(new ItemListener() { + @Override public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { LocalChangeList changeList = (LocalChangeList)myChooser.getSelectedItem(); @@ -313,12 +369,14 @@ public class MultipleLocalChangeListsBrowser extends ChangesBrowserBase implemen super(VcsBundle.message("commit.dialog.include.action.name")); } + @Override public boolean isSelected(AnActionEvent e) { Change change = e.getData(VcsDataKeys.CURRENT_CHANGE); if (change == null) return false; return myViewer.isIncluded(change); } + @Override public void setSelected(AnActionEvent e, boolean state) { Change change = e.getData(VcsDataKeys.CURRENT_CHANGE); if (change == null) return; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/CommitMessage.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/CommitMessage.java index 461ac212a95b..2d07d6a57546 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/CommitMessage.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/CommitMessage.java @@ -51,6 +51,7 @@ import org.jetbrains.annotations.*; import javax.swing.*; import java.awt.*; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -61,7 +62,6 @@ import static com.intellij.util.containers.ContainerUtil.addIfNotNull; import static com.intellij.util.containers.ContainerUtil.newHashSet; import static com.intellij.util.ui.JBUI.Panels.simplePanel; import static com.intellij.vcs.commit.CommitMessageInspectionProfile.getBodyRightMargin; -import static java.util.Collections.emptyList; import static javax.swing.BorderFactory.createEmptyBorder; public class CommitMessage extends JPanel implements Disposable, DataProvider, CommitMessageI { @@ -69,7 +69,7 @@ public class CommitMessage extends JPanel implements Disposable, DataProvider, C @NotNull private final EditorTextField myEditorField; @Nullable private final TitledSeparator mySeparator; - @NotNull private List myChangeLists = emptyList(); // guarded with WriteLock + @NotNull private List myChangeLists = Collections.emptyList(); // guarded with WriteLock public CommitMessage(@NotNull Project project) { this(project, true, true, true); @@ -210,6 +210,11 @@ public class CommitMessage extends JPanel implements Disposable, DataProvider, C public void dispose() { } + @CalledInAwt + public void setChangeList(@NotNull ChangeList value) { + setChangeLists(Collections.singletonList(value)); + } + @CalledInAwt public void setChangeLists(@NotNull List value) { WriteAction.run(() -> myChangeLists = value);