mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
Delete old implementation of multiple file merge dialog
This commit is contained in:
@@ -521,9 +521,6 @@ vcs.enable.partial.changelists.redo.restartRequired=true
|
||||
vcs.skip.single.default.changelist=false
|
||||
vcs.skip.single.default.changelist.description=Don't show changelist node in Local Changes view when only the Default changelist exists
|
||||
|
||||
vcs.new.multiple.file.merge=true
|
||||
vcs.new.multiple.file.merge.description=Use new implementation of multiple files merge dialog
|
||||
|
||||
psi.incremental.reparse.depth.limit=1000
|
||||
psi.deferIconLoading=true
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Getter;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.*;
|
||||
import com.intellij.openapi.vcs.actions.AnnotateToggleAction;
|
||||
@@ -47,7 +46,6 @@ import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
import com.intellij.openapi.vcs.merge.MergeDialogCustomizer;
|
||||
import com.intellij.openapi.vcs.merge.MergeProvider;
|
||||
import com.intellij.openapi.vcs.merge.MultipleFileMergeDialog;
|
||||
import com.intellij.openapi.vcs.merge.MultipleFileMergeDialog2;
|
||||
import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
|
||||
import com.intellij.openapi.vcs.versionBrowser.ChangesBrowserSettingsEditor;
|
||||
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
|
||||
@@ -498,18 +496,10 @@ public class AbstractVcsHelperImpl extends AbstractVcsHelper {
|
||||
@NotNull MergeDialogCustomizer mergeDialogCustomizer) {
|
||||
if (files.isEmpty()) return Collections.emptyList();
|
||||
VfsUtil.markDirtyAndRefresh(false, false, false, ArrayUtil.toObjectArray(files, VirtualFile.class));
|
||||
if (Registry.is("vcs.new.multiple.file.merge")) {
|
||||
final MultipleFileMergeDialog2 fileMergeDialog = new MultipleFileMergeDialog2(myProject, files, provider, mergeDialogCustomizer);
|
||||
AppIcon.getInstance().requestAttention(myProject, true);
|
||||
fileMergeDialog.show();
|
||||
return fileMergeDialog.getProcessedFiles();
|
||||
}
|
||||
else {
|
||||
final MultipleFileMergeDialog fileMergeDialog = new MultipleFileMergeDialog(myProject, files, provider, mergeDialogCustomizer);
|
||||
AppIcon.getInstance().requestAttention(myProject, true);
|
||||
fileMergeDialog.show();
|
||||
return fileMergeDialog.getProcessedFiles();
|
||||
}
|
||||
final MultipleFileMergeDialog fileMergeDialog = new MultipleFileMergeDialog(myProject, files, provider, mergeDialogCustomizer);
|
||||
AppIcon.getInstance().requestAttention(myProject, true);
|
||||
fileMergeDialog.show();
|
||||
return fileMergeDialog.getProcessedFiles();
|
||||
}
|
||||
|
||||
public void openCommittedChangesTab(final AbstractVcs vcs,
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.openapi.vcs.merge.MultipleFileMergeDialog">
|
||||
<grid id="27dc6" binding="myRootPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="400"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<grid id="5c044" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="464d7" class="javax.swing.JButton" binding="myAcceptYoursButton" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/VcsBundle" key="multiple.file.merge.accept.yours"/>
|
||||
</properties>
|
||||
</component>
|
||||
<vspacer id="da536">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="7d4c7" class="javax.swing.JButton" binding="myAcceptTheirsButton" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/VcsBundle" key="multiple.file.merge.accept.theirs"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="39393" class="javax.swing.JButton" binding="myMergeButton" custom-create="true" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/VcsBundle" key="multiple.file.merge.merge"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<scrollpane id="9f9b5" class="com.intellij.ui.components.JBScrollPane">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="466f6" class="com.intellij.ui.table.TableView" binding="myTable">
|
||||
<constraints/>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</scrollpane>
|
||||
<grid id="b4733" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="5" left="5" bottom="5" right="5"/>
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="f8ecf" class="com.intellij.ui.components.JBLabel" binding="myDescriptionLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="0" indent="1" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
@@ -1,459 +0,0 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.openapi.vcs.merge;
|
||||
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.diff.DiffManager;
|
||||
import com.intellij.diff.DiffRequestFactory;
|
||||
import com.intellij.diff.InvalidDiffRequestException;
|
||||
import com.intellij.diff.merge.MergeRequest;
|
||||
import com.intellij.diff.merge.MergeResult;
|
||||
import com.intellij.diff.merge.MergeUtil;
|
||||
import com.intellij.diff.util.DiffUtil;
|
||||
import com.intellij.ide.presentation.VirtualFilePresentation;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.impl.mergeTool.MergeVersion;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ex.ProjectManagerEx;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.VcsBundle;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.ColoredTableCellRenderer;
|
||||
import com.intellij.ui.DoubleClickListener;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import com.intellij.ui.TableSpeedSearch;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.ui.speedSearch.SpeedSearchUtil;
|
||||
import com.intellij.ui.table.TableView;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.ColumnInfo;
|
||||
import com.intellij.util.ui.ListTableModel;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class MultipleFileMergeDialog extends DialogWrapper {
|
||||
private static final Logger LOG = Logger.getInstance(MultipleFileMergeDialog.class);
|
||||
|
||||
private JPanel myRootPanel;
|
||||
private JButton myAcceptYoursButton;
|
||||
private JButton myAcceptTheirsButton;
|
||||
private JButton myMergeButton;
|
||||
private TableView<VirtualFile> myTable;
|
||||
private JBLabel myDescriptionLabel;
|
||||
private final MergeProvider myProvider;
|
||||
@Nullable private final MergeSession myMergeSession;
|
||||
private final List<VirtualFile> myFiles;
|
||||
private final ListTableModel<VirtualFile> myModel;
|
||||
@Nullable
|
||||
private final Project myProject;
|
||||
private final ProjectManagerEx myProjectManager;
|
||||
private final List<VirtualFile> myProcessedFiles = new SmartList<>();
|
||||
private final Set<VirtualFile> myBinaryFiles = new HashSet<>();
|
||||
private final MergeDialogCustomizer myMergeDialogCustomizer;
|
||||
|
||||
private final VirtualFileRenderer myVirtualFileRenderer = new VirtualFileRenderer();
|
||||
|
||||
public MultipleFileMergeDialog(@Nullable Project project, @NotNull final List<VirtualFile> files, @NotNull final MergeProvider provider,
|
||||
@NotNull MergeDialogCustomizer mergeDialogCustomizer) {
|
||||
super(project);
|
||||
|
||||
myProject = project;
|
||||
myProjectManager = ProjectManagerEx.getInstanceEx();
|
||||
myProjectManager.blockReloadingProjectOnExternalChanges();
|
||||
myFiles = new ArrayList<>(files);
|
||||
myProvider = provider;
|
||||
myMergeDialogCustomizer = mergeDialogCustomizer;
|
||||
|
||||
final String description = myMergeDialogCustomizer.getMultipleFileMergeDescription(files);
|
||||
if (!StringUtil.isEmptyOrSpaces(description)) {
|
||||
myDescriptionLabel.setText(description);
|
||||
}
|
||||
|
||||
List<ColumnInfo> columns = new ArrayList<>();
|
||||
columns.add(new ColumnInfo<VirtualFile, VirtualFile>(VcsBundle.message("multiple.file.merge.column.name")) {
|
||||
@Override
|
||||
public VirtualFile valueOf(final VirtualFile virtualFile) {
|
||||
return virtualFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableCellRenderer getRenderer(final VirtualFile virtualFile) {
|
||||
return myVirtualFileRenderer;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Comparator<VirtualFile> getComparator() {
|
||||
return VirtualFileComparator.INSTANCE;
|
||||
}
|
||||
});
|
||||
columns.add(new ColumnInfo<VirtualFile, String>(VcsBundle.message("multiple.file.merge.column.type")) {
|
||||
@Override
|
||||
public String valueOf(final VirtualFile virtualFile) {
|
||||
return myBinaryFiles.contains(virtualFile)
|
||||
? VcsBundle.message("multiple.file.merge.type.binary")
|
||||
: VcsBundle.message("multiple.file.merge.type.text");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMaxStringValue() {
|
||||
return VcsBundle.message("multiple.file.merge.type.binary");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAdditionalWidth() {
|
||||
return 10;
|
||||
}
|
||||
});
|
||||
if (myProvider instanceof MergeProvider2) {
|
||||
myMergeSession = ((MergeProvider2)myProvider).createMergeSession(files);
|
||||
Collections.addAll(columns, myMergeSession.getMergeInfoColumns());
|
||||
}
|
||||
else {
|
||||
myMergeSession = null;
|
||||
}
|
||||
myModel = new ListTableModel<>(columns.toArray(ColumnInfo.EMPTY_ARRAY));
|
||||
myModel.setItems(new ArrayList<>(myFiles));
|
||||
myTable.setModelAndUpdateColumns(myModel);
|
||||
myVirtualFileRenderer.setFont(UIUtil.getListFont());
|
||||
myTable.setRowHeight(myVirtualFileRenderer.getPreferredSize().height);
|
||||
setTitle(myMergeDialogCustomizer.getMultipleFileDialogTitle());
|
||||
init();
|
||||
myAcceptYoursButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(@NotNull ActionEvent e) {
|
||||
acceptRevision(MergeSession.Resolution.AcceptedYours);
|
||||
}
|
||||
});
|
||||
myAcceptTheirsButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(@NotNull ActionEvent e) {
|
||||
acceptRevision(MergeSession.Resolution.AcceptedTheirs);
|
||||
}
|
||||
});
|
||||
myTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(@NotNull final ListSelectionEvent e) {
|
||||
updateButtonState();
|
||||
}
|
||||
});
|
||||
for (VirtualFile file : files) {
|
||||
if (file.getFileType().isBinary() || provider.isBinary(file)) {
|
||||
myBinaryFiles.add(file);
|
||||
}
|
||||
}
|
||||
myTable.getSelectionModel().setSelectionInterval(0, 0);
|
||||
new DoubleClickListener() {
|
||||
@Override
|
||||
protected boolean onDoubleClick(MouseEvent event) {
|
||||
showMergeDialog();
|
||||
return true;
|
||||
}
|
||||
}.installOn(myTable);
|
||||
new TableSpeedSearch(myTable, o -> {
|
||||
if (o instanceof VirtualFile) {
|
||||
return ((VirtualFile)o).getName();
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCancelAction() {
|
||||
if (!myProcessedFiles.isEmpty()) {
|
||||
myProvider.mergeDone(myProcessedFiles);
|
||||
}
|
||||
super.doCancelAction();
|
||||
}
|
||||
|
||||
private void updateButtonState() {
|
||||
boolean haveSelection = myTable.getSelectedRowCount() > 0;
|
||||
boolean haveUnmergeableFiles = false;
|
||||
for (VirtualFile file : myTable.getSelection()) {
|
||||
if (myMergeSession != null) {
|
||||
boolean canMerge = myMergeSession.canMerge(file);
|
||||
if (!canMerge) {
|
||||
haveUnmergeableFiles = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
myAcceptYoursButton.setEnabled(haveSelection);
|
||||
myAcceptTheirsButton.setEnabled(haveSelection);
|
||||
myMergeButton.setEnabled(haveSelection && !haveUnmergeableFiles);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected JComponent createCenterPanel() {
|
||||
return myRootPanel;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Action[] createActions() {
|
||||
return new Action[]{getCancelAction()};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Action getCancelAction() {
|
||||
Action action = super.getCancelAction();
|
||||
action.putValue(Action.NAME, CommonBundle.getCloseButtonText());
|
||||
return action;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispose() {
|
||||
myProjectManager.unblockReloadingProjectOnExternalChanges();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
protected boolean beforeResolve(Collection<VirtualFile> files) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNls
|
||||
protected String getDimensionServiceKey() {
|
||||
return "MultipleFileMergeDialog";
|
||||
}
|
||||
|
||||
private void acceptRevision(@NotNull MergeSession.Resolution resolution) {
|
||||
FileDocumentManager.getInstance().saveAllDocuments();
|
||||
final Collection<VirtualFile> files = myTable.getSelection();
|
||||
if (!beforeResolve(files)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
for (VirtualFile file : files) {
|
||||
acceptFileRevision(file, resolution);
|
||||
checkMarkModifiedProject(file);
|
||||
markFileProcessed(file, resolution);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.warn(e);
|
||||
Messages.showErrorDialog(myRootPanel, "Error saving merged data: " + e.getMessage());
|
||||
}
|
||||
|
||||
updateModelFromFiles();
|
||||
}
|
||||
|
||||
private void acceptFileRevision(@NotNull VirtualFile file, @NotNull MergeSession.Resolution resolution) throws Exception {
|
||||
if (myMergeSession != null && !myMergeSession.canMerge(file)) return;
|
||||
|
||||
if (!DiffUtil.makeWritable(myProject, file)) {
|
||||
throw new IOException("File is read-only: " + file.getPresentableName());
|
||||
}
|
||||
|
||||
boolean isCurrent = resolution == MergeSession.Resolution.AcceptedYours;
|
||||
MergeData data = myProvider.loadRevisions(file);
|
||||
|
||||
Ref<Exception> ex = new Ref<>();
|
||||
CommandProcessor.getInstance().executeCommand(myProject, () -> {
|
||||
ApplicationManager.getApplication().runWriteAction(() -> {
|
||||
try {
|
||||
if (isCurrent) {
|
||||
file.setBinaryContent(data.CURRENT);
|
||||
}
|
||||
else {
|
||||
file.setBinaryContent(data.LAST);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
ex.set(e);
|
||||
}
|
||||
});
|
||||
}, "Accept " + (isCurrent ? "Yours" : "Theirs"), null);
|
||||
|
||||
if (!ex.isNull()) throw ex.get();
|
||||
}
|
||||
|
||||
private void markFileProcessed(@NotNull VirtualFile file, @NotNull MergeSession.Resolution resolution) {
|
||||
myFiles.remove(file);
|
||||
if (myMergeSession != null) {
|
||||
myMergeSession.conflictResolvedForFile(file, resolution);
|
||||
}
|
||||
else {
|
||||
myProvider.conflictResolvedForFile(file);
|
||||
}
|
||||
myProcessedFiles.add(file);
|
||||
if (myProject != null) {
|
||||
VcsDirtyScopeManager.getInstance(myProject).fileDirty(file);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateModelFromFiles() {
|
||||
if (myFiles.isEmpty()) {
|
||||
doCancelAction();
|
||||
}
|
||||
else {
|
||||
int selIndex = myTable.getSelectionModel().getMinSelectionIndex();
|
||||
myModel.setItems(new ArrayList<>(myFiles));
|
||||
if (selIndex >= myFiles.size()) {
|
||||
selIndex = myFiles.size() - 1;
|
||||
}
|
||||
myTable.getSelectionModel().setSelectionInterval(selIndex, selIndex);
|
||||
}
|
||||
}
|
||||
|
||||
private void showMergeDialog() {
|
||||
DiffRequestFactory requestFactory = DiffRequestFactory.getInstance();
|
||||
Collection<VirtualFile> files = myTable.getSelection();
|
||||
if (!beforeResolve(files)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final VirtualFile file : files) {
|
||||
final MergeData mergeData;
|
||||
try {
|
||||
mergeData = myProvider.loadRevisions(file);
|
||||
}
|
||||
catch (VcsException ex) {
|
||||
Messages.showErrorDialog(myRootPanel, "Error loading revisions to merge: " + ex.getMessage());
|
||||
break;
|
||||
}
|
||||
|
||||
if (mergeData.CURRENT == null || mergeData.LAST == null || mergeData.ORIGINAL == null) {
|
||||
Messages.showErrorDialog(myRootPanel, "Error loading revisions to merge");
|
||||
break;
|
||||
}
|
||||
|
||||
String leftTitle = myMergeDialogCustomizer.getLeftPanelTitle(file);
|
||||
String baseTitle = myMergeDialogCustomizer.getCenterPanelTitle(file);
|
||||
String rightTitle = myMergeDialogCustomizer.getRightPanelTitle(file, mergeData.LAST_REVISION_NUMBER);
|
||||
String title = myMergeDialogCustomizer.getMergeWindowTitle(file);
|
||||
|
||||
final List<byte[]> byteContents = ContainerUtil.list(mergeData.CURRENT, mergeData.ORIGINAL, mergeData.LAST);
|
||||
List<String> contentTitles = ContainerUtil.list(leftTitle, baseTitle, rightTitle);
|
||||
|
||||
Consumer<MergeResult> callback = result -> {
|
||||
Document document = FileDocumentManager.getInstance().getCachedDocument(file);
|
||||
if (document != null) FileDocumentManager.getInstance().saveDocument(document);
|
||||
checkMarkModifiedProject(file);
|
||||
|
||||
if (result != MergeResult.CANCEL) {
|
||||
markFileProcessed(file, getSessionResolution(result));
|
||||
}
|
||||
};
|
||||
|
||||
MergeRequest request;
|
||||
try {
|
||||
if (myProvider.isBinary(file)) { // respect MIME-types in svn
|
||||
request = requestFactory.createBinaryMergeRequest(myProject, file, byteContents, title, contentTitles, callback);
|
||||
}
|
||||
else {
|
||||
request = requestFactory.createMergeRequest(myProject, file, byteContents, title, contentTitles, callback);
|
||||
}
|
||||
|
||||
MergeUtil.putRevisionInfos(request, mergeData);
|
||||
}
|
||||
catch (InvalidDiffRequestException e) {
|
||||
LOG.error(e);
|
||||
Messages.showErrorDialog(myRootPanel, "Can't show merge dialog");
|
||||
break;
|
||||
}
|
||||
|
||||
DiffManager.getInstance().showMerge(myProject, request);
|
||||
}
|
||||
updateModelFromFiles();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static MergeSession.Resolution getSessionResolution(@NotNull MergeResult result) {
|
||||
switch (result) {
|
||||
case LEFT:
|
||||
return MergeSession.Resolution.AcceptedYours;
|
||||
case RIGHT:
|
||||
return MergeSession.Resolution.AcceptedTheirs;
|
||||
case RESOLVED:
|
||||
return MergeSession.Resolution.Merged;
|
||||
default:
|
||||
throw new IllegalArgumentException(result.name());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkMarkModifiedProject(@NotNull VirtualFile file) {
|
||||
MergeVersion.MergeDocumentVersion.reportProjectFileChangeIfNeeded(myProject, file);
|
||||
}
|
||||
|
||||
private void createUIComponents() {
|
||||
Action mergeAction = new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(@NotNull ActionEvent e) {
|
||||
showMergeDialog();
|
||||
}
|
||||
};
|
||||
mergeAction.putValue(DEFAULT_ACTION, Boolean.TRUE);
|
||||
myMergeButton = createJButtonForAction(mergeAction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myTable;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<VirtualFile> getProcessedFiles() {
|
||||
return myProcessedFiles;
|
||||
}
|
||||
|
||||
private class VirtualFileRenderer extends ColoredTableCellRenderer {
|
||||
@Override
|
||||
protected void customizeCellRenderer(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) {
|
||||
VirtualFile vf = (VirtualFile)value;
|
||||
setIcon(VirtualFilePresentation.getIcon(vf));
|
||||
append(vf.getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
|
||||
final VirtualFile parent = vf.getParent();
|
||||
if (parent != null) {
|
||||
append(" (" + FileUtil.toSystemDependentName(parent.getPresentableUrl()) + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES);
|
||||
}
|
||||
SpeedSearchUtil.applySpeedSearchHighlighting(myTable, this, true, selected);
|
||||
}
|
||||
}
|
||||
|
||||
private static class VirtualFileComparator implements Comparator<VirtualFile> {
|
||||
public static final VirtualFileComparator INSTANCE = new VirtualFileComparator();
|
||||
|
||||
@Override
|
||||
public int compare(VirtualFile file1, VirtualFile file2) {
|
||||
int delta = StringUtil.naturalCompare(file1.getName(), file2.getName());
|
||||
if (delta != 0) return delta;
|
||||
|
||||
VirtualFile parent1 = file1.getParent();
|
||||
VirtualFile parent2 = file2.getParent();
|
||||
String path1 = parent1 != null ? parent1.getPath() : null;
|
||||
String path2 = parent2 != null ? parent2.getPath() : null;
|
||||
return StringUtil.naturalCompare(path1, path2);
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-3
@@ -52,7 +52,7 @@ import javax.swing.tree.TreeNode
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
open class MultipleFileMergeDialog2(
|
||||
open class MultipleFileMergeDialog(
|
||||
private val project: Project,
|
||||
files: List<VirtualFile>,
|
||||
private val mergeProvider: MergeProvider,
|
||||
@@ -71,7 +71,7 @@ open class MultipleFileMergeDialog2(
|
||||
private var groupByDirectory = VcsConfiguration.getInstance(project).GROUP_MULTIFILE_MERGE_BY_DIRECTORY
|
||||
|
||||
private val virtualFileRenderer = object : ChangesBrowserNodeRenderer(project, { !groupByDirectory }, false) {
|
||||
override fun calcFocusedState() = UIUtil.isAncestor(this@MultipleFileMergeDialog2.peer.window, IdeFocusManager.getInstance(project).focusOwner)
|
||||
override fun calcFocusedState() = UIUtil.isAncestor(this@MultipleFileMergeDialog.peer.window, IdeFocusManager.getInstance(project).focusOwner)
|
||||
}
|
||||
|
||||
init {
|
||||
@@ -232,12 +232,21 @@ open class MultipleFileMergeDialog2(
|
||||
@NonNls
|
||||
override fun getDimensionServiceKey(): String = "MultipleFileMergeDialog"
|
||||
|
||||
@JvmSuppressWildcards
|
||||
protected open fun beforeResolve(files: Collection<VirtualFile>): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
private fun acceptRevision(resolution: MergeSession.Resolution) {
|
||||
assert(resolution == MergeSession.Resolution.AcceptedYours || resolution == MergeSession.Resolution.AcceptedTheirs)
|
||||
|
||||
FileDocumentManager.getInstance().saveAllDocuments()
|
||||
val files = getSelectedFiles()
|
||||
|
||||
if (!beforeResolve(files)) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
if (mergeSession is MergeSessionEx) {
|
||||
val supportedFiles = files.filter { file -> mergeSession.canMerge(file) }
|
||||
@@ -399,7 +408,7 @@ open class MultipleFileMergeDialog2(
|
||||
|
||||
|
||||
companion object {
|
||||
private val LOG = Logger.getInstance(MultipleFileMergeDialog2::class.java)
|
||||
private val LOG = Logger.getInstance(MultipleFileMergeDialog::class.java)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.invokeAndWaitIfNeed
|
||||
import com.intellij.openapi.diagnostic.debug
|
||||
import com.intellij.openapi.diagnostic.runAndLogException
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes
|
||||
import com.intellij.openapi.project.ProjectManager
|
||||
import com.intellij.openapi.vcs.merge.MergeDialogCustomizer
|
||||
import com.intellij.openapi.vcs.merge.MergeProvider2
|
||||
import com.intellij.openapi.vcs.merge.MultipleFileMergeDialog
|
||||
@@ -167,7 +168,7 @@ fun resolveConflicts(files: List<VirtualFile>, mergeProvider: MergeProvider2): L
|
||||
|
||||
var processedFiles: List<VirtualFile>? = null
|
||||
invokeAndWaitIfNeed {
|
||||
val fileMergeDialog = MultipleFileMergeDialog(null, files, mergeProvider, object : MergeDialogCustomizer() {
|
||||
val fileMergeDialog = MultipleFileMergeDialog(ProjectManager.getInstance().defaultProject, files, mergeProvider, object : MergeDialogCustomizer() {
|
||||
override fun getMultipleFileDialogTitle() = "Settings Repository: Files Merged with Conflicts"
|
||||
})
|
||||
fileMergeDialog.show()
|
||||
|
||||
Reference in New Issue
Block a user