changelist conflict dialog refactored

This commit is contained in:
unknown
2009-10-07 12:21:27 +04:00
parent 9e9f4e8558
commit 2fa21cbfa7
11 changed files with 190 additions and 115 deletions
@@ -18,7 +18,7 @@ import java.awt.*;
public class EditorNotificationPanel extends JPanel {
protected final JLabel myLabel = new JLabel();
private final JPanel myLinksPanel;
protected final JPanel myLinksPanel;
public EditorNotificationPanel() {
super(new BorderLayout());
@@ -35,7 +35,7 @@ public class EditorNotificationPanel extends JPanel {
myLabel.setText(text);
}
public void createActionLabel(final String text, @NonNls final String actionId) {
public HyperlinkLabel createActionLabel(final String text, @NonNls final String actionId) {
HyperlinkLabel label = new HyperlinkLabel(text, Color.BLUE, LightColors.YELLOW, Color.BLUE);
label.addHyperlinkListener(new HyperlinkListener() {
public void hyperlinkUpdate(final HyperlinkEvent e) {
@@ -45,6 +45,7 @@ public class EditorNotificationPanel extends JPanel {
}
});
myLinksPanel.add(label);
return label;
}
protected void executeAction(final String actionId) {
@@ -0,0 +1,23 @@
package com.intellij.openapi.vcs.readOnlyHandler;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
import javax.swing.*;
public class FileListRenderer extends ColoredListCellRenderer {
protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
// paint selection only as a focus rectangle
mySelected = false;
setBackground(null);
VirtualFile vf = (VirtualFile) value;
setIcon(vf.getIcon());
append(vf.getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
VirtualFile parent = vf.getParent();
if (parent != null) {
append(" (" + FileUtil.toSystemDependentName(parent.getPath()) + ")", SimpleTextAttributes.GRAY_ATTRIBUTES);
}
}
}
@@ -6,12 +6,8 @@ package com.intellij.openapi.vcs.readOnlyHandler;
import com.intellij.util.ui.OptionsDialog;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NonNls;
@@ -39,20 +35,7 @@ public class ReadOnlyStatusDialog extends OptionsDialog {
else {
myUsingFileSystemRadioButton.setSelected(true);
}
myFileList.setCellRenderer(new ColoredListCellRenderer() {
protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
// paint selection only as a focus rectangle
mySelected = false;
setBackground(null);
VirtualFile vf = (VirtualFile) value;
setIcon(vf.getIcon());
append(vf.getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
VirtualFile parent = vf.getParent();
if (parent != null) {
append(" (" + FileUtil.toSystemDependentName(parent.getPath()) + ")", SimpleTextAttributes.GRAY_ATTRIBUTES);
}
}
});
myFileList.setCellRenderer(new FileListRenderer());
setTitle(VcsBundle.message("dialog.title.clear.read.only.file.status"));
init();
@@ -137,4 +120,5 @@ public class ReadOnlyStatusDialog extends OptionsDialog {
final JRootPane pane = getRootPane();
return pane != null ? pane.getDefaultButton() : null;
}
}
@@ -46,12 +46,16 @@ public class ChangelistConflictAccessProvider implements WritingAccessProvider {
changeLists.add(myManager.getChangeList(file));
changes.add(myManager.getChange(file));
}
ChangelistConflictDialog dialog = new ChangelistConflictDialog(myProject, new ArrayList<ChangeList>(changeLists), changes);
dialog.show();
ChangelistConflictDialog dialog;
do {
dialog = new ChangelistConflictDialog(myProject, new ArrayList<ChangeList>(changeLists), denied);
dialog.show();
} while (dialog.isOK() && !dialog.getResolution().resolveConflict(myProject, changes));
if (dialog.isOK()) {
ChangelistConflictResolution resolution = dialog.getResolution();
options.LAST_RESOLUTION = resolution;
resolution.resolveConflict(myProject, resolution == ChangelistConflictResolution.SWITCH ? changes : dialog.getSelectedChanges());
options.LAST_RESOLUTION = dialog.getResolution();
return Collections.emptyList();
}
}
return denied;
@@ -8,14 +8,6 @@
<properties/>
<border type="none"/>
<children>
<grid id="97a7f" binding="myTopPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints>
<grid row="1" column="0" 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/>
</grid>
<grid id="2f133" 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>
@@ -64,9 +56,22 @@
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&lt;html&gt;You are about changing some files from non-active changelist.&#10;This may lead to &lt;br&gt;unwanted effects, e.g. partial commits. Please choose a way to resolve the problem.&lt;/html&gt;"/>
<text value="&lt;html&gt;These files do not belong to active changelist:&lt;/html&gt;"/>
</properties>
</component>
<scrollpane id="6c540">
<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="3aa3b" class="javax.swing.JList" binding="myFileList">
<constraints/>
<properties/>
</component>
</children>
</scrollpane>
</children>
</grid>
<buttonGroups>
@@ -1,45 +1,51 @@
package com.intellij.openapi.vcs.changes.conflicts;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.changes.ChangeList;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.ChangeListManagerImpl;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.vcs.readOnlyHandler.FileListRenderer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.CollectionListModel;
import javax.swing.*;
import java.util.List;
import java.awt.event.ActionEvent;
import java.util.List;
/**
* @author Dmitry Avdeev
*/
public class ChangelistConflictDialog extends MoveChangesDialog {
public class ChangelistConflictDialog extends DialogWrapper {
private JPanel myPanel;
private JPanel myTopPanel;
private JRadioButton myShelveChangesRadioButton;
private JRadioButton myMoveChangesToActiveRadioButton;
private JRadioButton mySwitchToChangelistRadioButton;
private JRadioButton myIgnoreRadioButton;
private JList myFileList;
private final Project myProject;
public ChangelistConflictDialog(Project project,
List<ChangeList> changeLists,
List<Change> conflicts) {
super(project, conflicts, changeLists, "Resolve Changelist Conflict");
public ChangelistConflictDialog(Project project, List<ChangeList> changeLists, List<VirtualFile> conflicts) {
super(project);
myProject = project;
myTopPanel.add(super.createCenterPanel());
setTitle("Resolve Changelist Conflict");
myFileList.setCellRenderer(new FileListRenderer());
myFileList.setModel(new CollectionListModel(conflicts));
ChangeListManagerImpl manager = ChangeListManagerImpl.getInstanceImpl(myProject);
ChangelistConflictResolution resolution = manager.getConflictTracker().getOptions().LAST_RESOLUTION;
if (changeLists.size() > 1) {
mySwitchToChangelistRadioButton.setEnabled(false);
if (resolution == ChangelistConflictResolution.SWITCH) {
resolution = ChangelistConflictResolution.SHELVE;
resolution = ChangelistConflictResolution.IGNORE;
}
}
mySwitchToChangelistRadioButton.setText(VcsBundle.message("switch.to.changelist", changeLists.iterator().next().getName()));
@@ -63,7 +69,6 @@ public class ChangelistConflictDialog extends MoveChangesDialog {
init();
}
@Override
protected JComponent createCenterPanel() {
return myPanel;
@@ -0,0 +1,72 @@
package com.intellij.openapi.vcs.changes.conflicts;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangeList;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.ChangeListManagerImpl;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotificationPanel;
import com.intellij.ui.InplaceButton;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collections;
import java.util.List;
/**
* @author Dmitry Avdeev
*/
public class ChangelistConflictNotificationPanel extends EditorNotificationPanel {
private final ChangeList myChangeList;
private final Change myChange;
private final VirtualFile myFile;
private ChangelistConflictTracker myTracker;
public ChangelistConflictNotificationPanel(ChangelistConflictTracker tracker, VirtualFile file) {
myTracker = tracker;
myFile = file;
final ChangeListManager manager = tracker.getChangeListManager();
myChange = manager.getChange(file);
myChangeList = manager.getChangeList(myChange);
assert myChangeList != null;
myLabel.setText("File from non-active changelist is modified");
createActionLabel("Move changes", "move").
setToolTipText("Move changes to active changelist (" + manager.getDefaultChangeList().getName() + ")");
createActionLabel("Switch changelist", "switch").
setToolTipText("Set active changelist to '" + myChangeList.getName() + "'");
createActionLabel("Ignore", "ignore").
setToolTipText("Hide this notification");
setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 0));
myLinksPanel.add(new InplaceButton("Show options dialog", IconLoader.getIcon("/general/ideOptions.png"), new ActionListener() {
public void actionPerformed(ActionEvent e) {
ShowSettingsUtil.getInstance().editConfigurable(myTracker.getProject(),
new ChangelistConflictConfigurable((ChangeListManagerImpl)manager));
}
}));
}
@Override
protected void executeAction(String actionId) {
if (actionId.equals("move")) {
MoveChangesDialog dialog =
new MoveChangesDialog(myTracker.getProject(), Collections.singletonList(myChange), Collections.singleton(myChangeList),
"Move Changes to Active Changelist");
dialog.show();
if (dialog.isOK()) {
ChangelistConflictResolution.MOVE.resolveConflict(myTracker.getProject(), dialog.getSelectedChanges());
}
} else if (actionId.equals("switch")) {
List<Change> changes = Collections.singletonList(myTracker.getChangeListManager().getChange(myFile));
ChangelistConflictResolution.SWITCH.resolveConflict(myTracker.getProject(), changes);
} else if (actionId.equals("ignore")) {
myTracker.ignoreConflict(myFile, true);
}
}
}
@@ -1,19 +1,14 @@
package com.intellij.openapi.vcs.changes.conflicts;
import com.intellij.CommonBundle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.ChangeListManagerImpl;
import com.intellij.openapi.vcs.changes.LocalChangeList;
import com.intellij.openapi.vcs.changes.shelf.ShelveChangesManager;
import com.intellij.openapi.vcs.changes.*;
import com.intellij.openapi.vcs.changes.shelf.ShelveChangesCommitExecutor;
import com.intellij.openapi.vcs.changes.ui.CommitChangeListDialog;
import com.intellij.openapi.vfs.VirtualFile;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
/**
* @author Dmitry Avdeev
@@ -22,32 +17,29 @@ public enum ChangelistConflictResolution {
SHELVE {
@Override
public boolean resolveConflict(final Project project, Collection<Change> changes) {
public boolean resolveConflict(Project project, Collection<Change> changes) {
LocalChangeList changeList = getManager(project).getChangeList(changes.iterator().next());
assert changeList != null;
try {
ShelveChangesManager.getInstance(project).shelveChanges(changes, changeList.getName());
return true;
}
catch (final Exception ex) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
Messages.showErrorDialog(project, VcsBundle.message("create.patch.error.title", ex.getMessage()), CommonBundle.getErrorTitle());
}
}, ModalityState.NON_MODAL);
return false;
}
return CommitChangeListDialog.commitChanges(project, changes, changeList, new ShelveChangesCommitExecutor(project), null);
}},
MOVE {
@Override
public boolean resolveConflict(Project project, Collection<Change> changes) {
final ChangeListManagerImpl manager = getManager(project);
manager.moveChangesTo(manager.getDefaultChangeList(), changes.toArray(new Change[changes.size()]));
return true;
ChangeListManagerImpl manager = getManager(project);
Set<ChangeList> changeLists = new HashSet<ChangeList>();
for (Change change : changes) {
changeLists.add(manager.getChangeList(change));
}
MoveChangesDialog dialog = new MoveChangesDialog(project, changes, changeLists, "Move Changes");
dialog.show();
if (dialog.isOK()) {
manager.moveChangesTo(manager.getDefaultChangeList(), changes.toArray(new Change[changes.size()]));
return true;
}
return false;
}},
SWITCH {
SWITCH{
@Override
public boolean resolveConflict(Project project, Collection<Change> changes) {
LocalChangeList changeList = getManager(project).getChangeList(changes.iterator().next());
@@ -41,7 +41,6 @@ import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -158,33 +157,8 @@ public class ChangelistConflictTracker {
for (FileEditor editor : editors) {
EditorNotificationPanel panel = editor.getUserData(KEY);
if (add && panel == null) {
panel = new EditorNotificationPanel() {
{
myLabel.setText("File from non-active changelist is modified");
}
@Override
protected void executeAction(String actionId) {
if (actionId.equals("move")) {
Change change = myChangeListManager.getChange(file);
ChangeList changeList = myChangeListManager.getChangeList(change);
MoveChangesDialog dialog =
new MoveChangesDialog(myProject, Collections.singletonList(change), Collections.singletonList(changeList),
"Move changes");
dialog.show();
if (dialog.isOK()) {
ChangelistConflictResolution.MOVE.resolveConflict(myProject, dialog.getSelectedChanges());
}
} else if (actionId.equals("switch")) {
List<Change> changes = Collections.singletonList(myChangeListManager.getChange(file));
ChangelistConflictResolution.SWITCH.resolveConflict(myProject, changes);
} else if (actionId.equals("ignore")) {
ignoreConflict(file, true);
}
}
};
panel.createActionLabel("Move changes", "move");
panel.createActionLabel("Switch changelist", "switch");
panel.createActionLabel("Ignore", "ignore");
panel = new ChangelistConflictNotificationPanel(ChangelistConflictTracker.this, file);
myFileEditorManager.addTopComponent(editor, panel);
editor.putUserData(KEY, panel);
} else if (panel != null) {
@@ -315,15 +289,24 @@ public class ChangelistConflictTracker {
myFileStatusManager.fileStatusChanged(file);
}
public Project getProject() {
return myProject;
}
public ChangeListManager getChangeListManager() {
return myChangeListManager;
}
public Options getOptions() {
return myOptions;
}
public static class Options {
public boolean TRACKING_ENABLED = true;
public boolean SHOW_DIALOG = true;
public boolean SHOW_DIALOG = false;
public boolean HIGHLIGHT_CONFLICTS = true;
public boolean HIGHLIGHT_NON_ACTIVE_CHANGELIST = false;
public ChangelistConflictResolution LAST_RESOLUTION = ChangelistConflictResolution.SHELVE;
public ChangelistConflictResolution LAST_RESOLUTION = ChangelistConflictResolution.IGNORE;
}
}
@@ -32,7 +32,9 @@ import javax.swing.*;
import javax.swing.tree.DefaultTreeModel;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* @author Dmitry Avdeev
@@ -40,7 +42,7 @@ import java.util.List;
public class MoveChangesDialog extends DialogWrapper {
private ChangesTreeList<Change> myTreeList;
public MoveChangesDialog(final Project project, List<Change> selected, final List<ChangeList> changeLists, String title) {
public MoveChangesDialog(final Project project, Collection<Change> selected, final Set<ChangeList> changeLists, String title) {
super(project, true);
setTitle(title);
myTreeList = new ChangesTreeList<Change>(project, selected, true, false, null, null) {
@@ -48,7 +50,7 @@ public class MoveChangesDialog extends DialogWrapper {
@Override
protected DefaultTreeModel buildTreeModel(List<Change> changes, ChangeNodeDecorator changeNodeDecorator) {
TreeModelBuilder builder = new TreeModelBuilder(project, false);
return builder.buildModel(changeLists);
return builder.buildModel(new ArrayList<ChangeList>(changeLists));
}
@Override
@@ -100,12 +100,16 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
private final MyUpdateButtonsRunnable myUpdateButtonsRunnable = new MyUpdateButtonsRunnable(this);
private static void commit(final Project project, final List<Change> changes, final LocalChangeList initialSelection,
private static boolean commit(final Project project, final List<Change> changes, final LocalChangeList initialSelection,
final List<CommitExecutor> executors, final boolean showVcsCommit, final String comment) {
final ChangeListManager manager = ChangeListManager.getInstance(project);
final LocalChangeList defaultList = manager.getDefaultChangeList();
final ArrayList<LocalChangeList> changeLists = new ArrayList<LocalChangeList>(manager.getChangeListsCopy());
new CommitChangeListDialog(project, changes, initialSelection, executors, showVcsCommit, defaultList, changeLists, null, false, comment).show();
CommitChangeListDialog dialog =
new CommitChangeListDialog(project, changes, initialSelection, executors, showVcsCommit, defaultList, changeLists, null, false,
comment);
dialog.show();
return dialog.isOK();
}
public static void commitPaths(final Project project, Collection<FilePath> paths, final LocalChangeList initialSelection,
@@ -119,26 +123,26 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
commitChanges(project, changes, initialSelection, executor, comment);
}
public static void commitChanges(final Project project, final Collection<Change> changes, final LocalChangeList initialSelection,
public static boolean commitChanges(final Project project, final Collection<Change> changes, final LocalChangeList initialSelection,
final CommitExecutor executor, final String comment) {
final ChangeListManager manager = ChangeListManager.getInstance(project);
if (executor == null) {
commitChanges(project, changes, initialSelection, manager.getRegisteredExecutors(), true, comment);
return commitChanges(project, changes, initialSelection, manager.getRegisteredExecutors(), true, comment);
}
else {
commitChanges(project, changes, initialSelection, Collections.singletonList(executor), false, comment);
return commitChanges(project, changes, initialSelection, Collections.singletonList(executor), false, comment);
}
}
public static void commitChanges(final Project project, final Collection<Change> changes, final LocalChangeList initialSelection,
public static boolean commitChanges(final Project project, final Collection<Change> changes, final LocalChangeList initialSelection,
final List<CommitExecutor> executors, final boolean showVcsCommit, final String comment) {
if (changes.isEmpty()) {
Messages.showWarningDialog(project, VcsBundle.message("commit.dialog.no.changes.detected.text") ,
VcsBundle.message("commit.dialog.no.changes.detected.title"));
return;
return false;
}
commit(project, new ArrayList<Change>(changes), initialSelection, executors, showVcsCommit, comment);
return commit(project, new ArrayList<Change>(changes), initialSelection, executors, showVcsCommit, comment);
}
public static void commitAlienChanges(final Project project, final List<Change> changes, final AbstractVcs vcs,