mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
fix for IDEA-81304 "Show history for selection" for Subversion is not working!
(exception reporting + correct revisions preload)
This commit is contained in:
+11
-1
@@ -32,6 +32,7 @@ import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl;
|
||||
import com.intellij.openapi.vcs.impl.VcsBackgroundableActions;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.WaitForProgressToShow;
|
||||
import com.intellij.vcsUtil.VcsSelection;
|
||||
import com.intellij.vcsUtil.VcsSelectionUtil;
|
||||
|
||||
@@ -77,11 +78,15 @@ public class SelectedBlockHistoryAction extends AbstractVcsAction {
|
||||
final int selectionStart = selection.getSelectionStartLineNumber();
|
||||
final int selectionEnd = selection.getSelectionEndLineNumber();
|
||||
|
||||
final VcsException[] preloadException = new VcsException[1];
|
||||
final CachedRevisionsContents cachedRevisionsContents = new CachedRevisionsContents(project, file);
|
||||
new VcsHistoryProviderBackgroundableProxy(activeVcs, provider, activeVcs.getDiffProvider()).
|
||||
createSessionFor(activeVcs.getKeyInstanceMethod(), new FilePathImpl(file),
|
||||
new Consumer<VcsHistorySession>() {
|
||||
public void consume(VcsHistorySession session) {
|
||||
if (preloadException[0] != null) {
|
||||
reportError(preloadException[0]);
|
||||
}
|
||||
if (session == null) return;
|
||||
final VcsHistoryDialog vcsHistoryDialog =
|
||||
new VcsHistoryDialog(project,
|
||||
@@ -103,7 +108,12 @@ public class SelectedBlockHistoryAction extends AbstractVcsAction {
|
||||
cachedRevisionsContents.setRevisions(revisionList);
|
||||
if (VcsConfiguration.getInstance(project).SHOW_ONLY_CHANGED_IN_SELECTION_DIFF) {
|
||||
// preload while in bckgrnd
|
||||
cachedRevisionsContents.loadContentsFor(revisionList.toArray(new VcsFileRevision[revisionList.size()]));
|
||||
try {
|
||||
cachedRevisionsContents.loadContentsFor(revisionList.toArray(new VcsFileRevision[revisionList.size()]));
|
||||
}
|
||||
catch (VcsException e) {
|
||||
preloadException[0] = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -64,7 +64,7 @@ public class VcsHistoryUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private static int compareNumbers(VcsFileRevision first, VcsFileRevision second) {
|
||||
public static int compareNumbers(VcsFileRevision first, VcsFileRevision second) {
|
||||
return first.getRevisionNumber().compareTo(second.getRevisionNumber());
|
||||
}
|
||||
|
||||
|
||||
+20
-14
@@ -42,7 +42,7 @@ import java.util.*;
|
||||
*/
|
||||
public class CachedRevisionsContents {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.history.impl.CachedRevisionsContents");
|
||||
private final Map<VcsRevisionNumber, String> myCachedContents = new HashMap<VcsRevisionNumber, String>();
|
||||
private final Map<VcsRevisionNumber, String> myCachedContents;
|
||||
private final Project myProject;
|
||||
// managed outside, for reference here
|
||||
private List<VcsFileRevision> myRevisions;
|
||||
@@ -51,13 +51,14 @@ public class CachedRevisionsContents {
|
||||
public CachedRevisionsContents(final Project project, final VirtualFile file) {
|
||||
myProject = project;
|
||||
myFile = file;
|
||||
myCachedContents = Collections.synchronizedMap(new HashMap<VcsRevisionNumber, String>());
|
||||
}
|
||||
|
||||
public void setRevisions(List<VcsFileRevision> revisions) {
|
||||
myRevisions = revisions;
|
||||
}
|
||||
|
||||
public void loadContentsFor(final VcsFileRevision[] revisions) {
|
||||
public void loadContentsFor(final VcsFileRevision[] revisions) throws VcsException {
|
||||
final VcsFileRevision[] revisionsToLoad = revisionsNeededToBeLoaded(revisions);
|
||||
|
||||
final List<VcsFileRevision> toBeLoaded = new LinkedList<VcsFileRevision>();
|
||||
@@ -67,6 +68,7 @@ public class CachedRevisionsContents {
|
||||
}
|
||||
if (toBeLoaded.isEmpty()) return;
|
||||
|
||||
final VcsException[] exception = new VcsException[1];
|
||||
final Runnable process = new Runnable() {
|
||||
public void run() {
|
||||
ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
|
||||
@@ -91,19 +93,17 @@ public class CachedRevisionsContents {
|
||||
vcsFileRevision.loadContent();
|
||||
}
|
||||
catch (final VcsException e) {
|
||||
WaitForProgressToShow.runOrInvokeLaterAboveProgress(new Runnable() {
|
||||
public void run() {
|
||||
Messages.showErrorDialog(VcsBundle.message("message.text.cannot.load.version.because.of.error",
|
||||
vcsFileRevision.getRevisionNumber(), e.getLocalizedMessage()),
|
||||
VcsBundle.message("message.title.load.version"));
|
||||
}
|
||||
}, null, myProject);
|
||||
exception[0] = new VcsException(e);
|
||||
LOG.info(e);
|
||||
return;
|
||||
}
|
||||
catch (ProcessCanceledException ex) {
|
||||
return;
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
|
||||
exception[0] = new VcsException(e);
|
||||
LOG.info(e);
|
||||
return;
|
||||
}
|
||||
String content = null;
|
||||
try {
|
||||
@@ -113,13 +113,16 @@ public class CachedRevisionsContents {
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
exception[0] = new VcsException(e);
|
||||
LOG.info(e);
|
||||
return;
|
||||
}
|
||||
catch (VcsException e) {
|
||||
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
|
||||
exception[0] = new VcsException(e);
|
||||
LOG.info(e);
|
||||
return;
|
||||
}
|
||||
myCachedContents.put(vcsFileRevision.getRevisionNumber(), content);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,9 +139,12 @@ public class CachedRevisionsContents {
|
||||
} else {
|
||||
process.run();
|
||||
}
|
||||
if (exception[0] != null) {
|
||||
throw exception[0];
|
||||
}
|
||||
}
|
||||
|
||||
public String getContentOf(VcsFileRevision revision) {
|
||||
public String getContentOf(VcsFileRevision revision) throws VcsException {
|
||||
if (! myCachedContents.containsKey(revision.getRevisionNumber())) {
|
||||
loadContentsFor(new VcsFileRevision[]{revision});
|
||||
}
|
||||
@@ -157,7 +163,7 @@ public class CachedRevisionsContents {
|
||||
private Collection<VcsFileRevision> collectRevisionsFromFirstTo(VcsFileRevision revision) {
|
||||
ArrayList<VcsFileRevision> result = new ArrayList<VcsFileRevision>();
|
||||
for (VcsFileRevision vcsFileRevision : myRevisions) {
|
||||
if (VcsHistoryUtil.compare(revision, vcsFileRevision) > 0) continue;
|
||||
if (VcsHistoryUtil.compareNumbers(revision, vcsFileRevision) > 0) continue;
|
||||
result.add(vcsFileRevision);
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.diff.FindBlock;
|
||||
import com.intellij.openapi.actionSystem.DataProvider;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.DiffManager;
|
||||
import com.intellij.openapi.diff.DiffPanel;
|
||||
@@ -29,12 +30,11 @@ import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.help.HelpManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.Splitter;
|
||||
import com.intellij.openapi.vcs.AbstractVcs;
|
||||
import com.intellij.openapi.vcs.VcsBundle;
|
||||
import com.intellij.openapi.vcs.VcsConfiguration;
|
||||
import com.intellij.openapi.vcs.VcsDataKeys;
|
||||
import com.intellij.openapi.vcs.*;
|
||||
import com.intellij.openapi.vcs.history.*;
|
||||
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.table.TableView;
|
||||
@@ -61,6 +61,7 @@ public class VcsHistoryDialog extends DialogWrapper implements DataProvider {
|
||||
private final int mySelectionStart;
|
||||
private final int mySelectionEnd;
|
||||
|
||||
// todo equals???
|
||||
private final Map<VcsFileRevision, Block> myRevisionToContentMap = new com.intellij.util.containers.HashMap<VcsFileRevision, Block>();
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.history.impl.VcsHistoryDialog");
|
||||
@@ -173,11 +174,11 @@ public class VcsHistoryDialog extends DialogWrapper implements DataProvider {
|
||||
});
|
||||
|
||||
|
||||
myList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||
final ListSelectionListener selectionListener = new ListSelectionListener() {
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
final VcsFileRevision revision;
|
||||
if (myList.getSelectedRowCount() == 1) {
|
||||
revision = (VcsFileRevision) myList.getItems().get(myList.getSelectedRow());
|
||||
if (myList.getSelectedRowCount() == 1 && !myList.isEmpty()) {
|
||||
revision = (VcsFileRevision)myList.getItems().get(myList.getSelectedRow());
|
||||
myComments.setText(revision.getCommitMessage());
|
||||
myComments.setCaretPosition(0);
|
||||
}
|
||||
@@ -190,21 +191,34 @@ public class VcsHistoryDialog extends DialogWrapper implements DataProvider {
|
||||
}
|
||||
updateDiff();
|
||||
}
|
||||
});
|
||||
};
|
||||
myList.getSelectionModel().addListSelectionListener(selectionListener);
|
||||
|
||||
myChangesOnlyCheckBox.setSelected(configuration.SHOW_ONLY_CHANGED_IN_SELECTION_DIFF);
|
||||
updateRevisionsList();
|
||||
try {
|
||||
updateRevisionsList();
|
||||
}
|
||||
catch (final VcsException e) {
|
||||
// todo test it, always exception
|
||||
canNotLoadRevisionMessage(e);
|
||||
}
|
||||
myChangesOnlyCheckBox.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
configuration.SHOW_ONLY_CHANGED_IN_SELECTION_DIFF = myChangesOnlyCheckBox.isSelected();
|
||||
updateRevisionsList();
|
||||
try {
|
||||
updateRevisionsList();
|
||||
}
|
||||
catch (VcsException e1) {
|
||||
canNotLoadRevisionMessage(e1);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
init();
|
||||
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
if (! VcsHistoryDialog.this.isShowing()) return;
|
||||
myList.getSelectionModel().addSelectionInterval(0, 0);
|
||||
}
|
||||
});
|
||||
@@ -212,6 +226,21 @@ public class VcsHistoryDialog extends DialogWrapper implements DataProvider {
|
||||
setTitle(VcsBundle.message("dialog.title.history.for.file", file.getName()));
|
||||
}
|
||||
|
||||
private void canNotLoadRevisionMessage(final VcsException e) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (! VcsHistoryDialog.this.isShowing()) return;
|
||||
VcsBalloonProblemNotifier.showBalloonForComponent(VcsHistoryDialog.this.getRootPane(),
|
||||
canNoLoadMessage(e), MessageType.ERROR, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String canNoLoadMessage(VcsException e) {
|
||||
return "Can not load revision contents: " + e.getMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myList;
|
||||
@@ -235,15 +264,15 @@ public class VcsHistoryDialog extends DialogWrapper implements DataProvider {
|
||||
return result;
|
||||
}
|
||||
|
||||
protected String getContentOf(VcsFileRevision revision) {
|
||||
protected String getContentOf(VcsFileRevision revision) throws VcsException {
|
||||
return myCachedContents.getContentOf(revision);
|
||||
}
|
||||
|
||||
private void loadContentsFor(final VcsFileRevision[] revisions) {
|
||||
private void loadContentsFor(final VcsFileRevision[] revisions) throws VcsException {
|
||||
myCachedContents.loadContentsFor(revisions);
|
||||
}
|
||||
|
||||
private void updateRevisionsList() {
|
||||
private void updateRevisionsList() throws VcsException {
|
||||
if (myIsInLoading) return;
|
||||
if (myChangesOnlyCheckBox.isSelected()) {
|
||||
loadContentsFor(myRevisions.toArray(new VcsFileRevision[myRevisions.size()]));
|
||||
@@ -267,7 +296,7 @@ public class VcsHistoryDialog extends DialogWrapper implements DataProvider {
|
||||
|
||||
}
|
||||
|
||||
private List<VcsFileRevision> filteredRevisions() throws FilesTooBigForDiffException {
|
||||
private List<VcsFileRevision> filteredRevisions() throws FilesTooBigForDiffException, VcsException {
|
||||
ArrayList<VcsFileRevision> result = new ArrayList<VcsFileRevision>();
|
||||
VcsFileRevision nextRevision = myRevisions.get(myRevisions.size() - 1);
|
||||
result.add(nextRevision);
|
||||
@@ -282,6 +311,7 @@ public class VcsHistoryDialog extends DialogWrapper implements DataProvider {
|
||||
}
|
||||
|
||||
private synchronized void updateDiff() {
|
||||
if (myList.isEmpty()) return;
|
||||
int[] selectedIndices = myList.getSelectedRows();
|
||||
if (selectedIndices.length == 0) {
|
||||
updateDiff(CURRENT, CURRENT);
|
||||
@@ -314,6 +344,12 @@ public class VcsHistoryDialog extends DialogWrapper implements DataProvider {
|
||||
catch (FilesTooBigForDiffException e) {
|
||||
myDiffPanel.setTooBigFileErrorContents();
|
||||
}
|
||||
catch (VcsException e) {
|
||||
final String text = canNoLoadMessage(e);
|
||||
myDiffPanel.setContents(new SimpleContent(text, myContentFileType),
|
||||
new SimpleContent(text, myContentFileType));
|
||||
canNotLoadRevisionMessage(e);
|
||||
}
|
||||
myDiffPanel.setTitle1(VcsBundle.message("diff.content.title.revision.number", firstRev.getRevisionNumber()));
|
||||
myDiffPanel.setTitle2(VcsBundle.message("diff.content.title.revision.number", secondRev.getRevisionNumber()));
|
||||
|
||||
@@ -414,14 +450,14 @@ public class VcsHistoryDialog extends DialogWrapper implements DataProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String getContentToShow(VcsFileRevision revision) throws FilesTooBigForDiffException {
|
||||
protected String getContentToShow(VcsFileRevision revision) throws FilesTooBigForDiffException, VcsException {
|
||||
final Block block = getBlock(revision);
|
||||
if (block == null) return "";
|
||||
return block.getBlockContent();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Block getBlock(VcsFileRevision revision) throws FilesTooBigForDiffException {
|
||||
private Block getBlock(VcsFileRevision revision) throws FilesTooBigForDiffException, VcsException {
|
||||
if (myRevisionToContentMap.containsKey(revision))
|
||||
return myRevisionToContentMap.get(revision);
|
||||
|
||||
|
||||
@@ -20,9 +20,17 @@ import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.popup.Balloon;
|
||||
import com.intellij.openapi.ui.popup.BalloonBuilder;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.vcs.changes.ui.ChangesViewContentManager;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Shows a notification balloon over one of version control related tool windows: Changes View or Version Control View.
|
||||
* By default the notification is shown over the Changes View.
|
||||
@@ -74,4 +82,24 @@ public class VcsBalloonProblemNotifier implements Runnable {
|
||||
public void run() {
|
||||
NOTIFICATION_GROUP.createNotification(myMessage, myMessageType).notify(myProject.isDefault() ? null : myProject);
|
||||
}
|
||||
|
||||
public static void showBalloonForComponent(@NotNull JComponent component, @NotNull final String message, final MessageType type,
|
||||
final boolean atTop) {
|
||||
BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(message, type, null);
|
||||
Balloon balloon = balloonBuilder.createBalloon();
|
||||
Dimension size = component.getSize();
|
||||
Balloon.Position position;
|
||||
int x;
|
||||
int y;
|
||||
if (size == null) {
|
||||
x = y = 0;
|
||||
position = Balloon.Position.above;
|
||||
}
|
||||
else {
|
||||
x = Math.min(10, size.width / 2);
|
||||
y = size.height;
|
||||
position = Balloon.Position.below;
|
||||
}
|
||||
balloon.show(new RelativePoint(component, new Point(x, y)), position);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user