mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+33
-26
@@ -71,7 +71,7 @@ public class RefManagerImpl extends RefManager {
|
||||
private final Project myProject;
|
||||
private AnalysisScope myScope;
|
||||
private RefProject myRefProject;
|
||||
private final ConcurrentMap<PsiAnchor, RefElement> myRefTable = ContainerUtil.newConcurrentMap();
|
||||
private final Map<PsiAnchor, RefElement> myRefTable = new THashMap<PsiAnchor, RefElement>(); // guarded by myRefTable
|
||||
|
||||
private final ConcurrentMap<Module, RefModule> myModules = ContainerUtil.newConcurrentMap();
|
||||
private final ProjectIterator myProjectIterator = new ProjectIterator();
|
||||
@@ -129,7 +129,9 @@ public class RefManagerImpl extends RefManager {
|
||||
public void cleanup() {
|
||||
myScope = null;
|
||||
myRefProject = null;
|
||||
myRefTable.clear();
|
||||
synchronized (myRefTable) {
|
||||
myRefTable.clear();
|
||||
}
|
||||
myModules.clear();
|
||||
myContext = null;
|
||||
|
||||
@@ -335,7 +337,10 @@ public class RefManagerImpl extends RefManager {
|
||||
|
||||
@NotNull
|
||||
public List<RefElement> getSortedElements() {
|
||||
List<RefElement> answer = new ArrayList<RefElement>(myRefTable.values());
|
||||
List<RefElement> answer;
|
||||
synchronized (myRefTable) {
|
||||
answer = new ArrayList<RefElement>(myRefTable.values());
|
||||
}
|
||||
ContainerUtil.quickSort(answer, new Comparator<RefElement>() {
|
||||
@Override
|
||||
public int compare(RefElement o1, RefElement o2) {
|
||||
@@ -362,15 +367,17 @@ public class RefManagerImpl extends RefManager {
|
||||
extension.removeReference(refElem);
|
||||
}
|
||||
|
||||
if (element != null && myRefTable.remove(createAnchor(element)) != null) return;
|
||||
synchronized (myRefTable) {
|
||||
if (element != null && myRefTable.remove(createAnchor(element)) != null) return;
|
||||
|
||||
//PsiElement may have been invalidated and new one returned by getElement() is different so we need to do this stuff.
|
||||
for (Map.Entry<PsiAnchor, RefElement> entry : myRefTable.entrySet()) {
|
||||
RefElement value = entry.getValue();
|
||||
if (value == refElem) {
|
||||
//PsiElement may have been invalidated and new one returned by getElement() is different so we need to do this stuff.
|
||||
for (Map.Entry<PsiAnchor, RefElement> entry : myRefTable.entrySet()) {
|
||||
RefElement value = entry.getValue();
|
||||
PsiAnchor anchor = entry.getKey();
|
||||
myRefTable.remove(anchor, refElem);
|
||||
return;
|
||||
if (value == refElem) {
|
||||
myRefTable.remove(anchor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -526,25 +533,25 @@ public class RefManagerImpl extends RefManager {
|
||||
@Nullable Consumer<T> whenCached) {
|
||||
|
||||
PsiAnchor psiAnchor = createAnchor(element);
|
||||
//noinspection unchecked
|
||||
T result = (T)myRefTable.get(psiAnchor);
|
||||
T result;
|
||||
synchronized (myRefTable) {
|
||||
//noinspection unchecked
|
||||
result = (T)myRefTable.get(psiAnchor);
|
||||
|
||||
if (result != null) return result;
|
||||
if (result != null) return result;
|
||||
|
||||
if (!isValidPointForReference()) {
|
||||
//LOG.assertTrue(true, "References may become invalid after process is finished");
|
||||
return null;
|
||||
if (!isValidPointForReference()) {
|
||||
//LOG.assertTrue(true, "References may become invalid after process is finished");
|
||||
return null;
|
||||
}
|
||||
|
||||
result = factory.create();
|
||||
if (result == null) return null;
|
||||
|
||||
myRefTable.put(psiAnchor, result);
|
||||
}
|
||||
|
||||
result = factory.create();
|
||||
if (result == null) return null;
|
||||
|
||||
RefElement prev = myRefTable.putIfAbsent(psiAnchor, result);
|
||||
if (prev == null) {
|
||||
if (whenCached != null) whenCached.consume(result);
|
||||
}
|
||||
else {
|
||||
result = (T)prev;
|
||||
if (whenCached != null) {
|
||||
whenCached.consume(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -15,10 +15,13 @@
|
||||
*/
|
||||
package com.intellij.diff.contents;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Deprecated
|
||||
/** @deprecated Use {@link FileContent} and {@link VirtualFile#contentsToByteArray()} */
|
||||
public interface BinaryFileContent extends FileContent {
|
||||
/**
|
||||
* @return Binary representation of content.
|
||||
|
||||
@@ -101,7 +101,7 @@ public class DiffContentFactoryImpl extends DiffContentFactory {
|
||||
if (file.isDirectory()) return new DirectoryContentImpl(project, file);
|
||||
DocumentContent content = createDocument(project, file);
|
||||
if (content != null) return content;
|
||||
return new BinaryFileContentImpl(project, file);
|
||||
return new FileContentImpl(project, file);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-1
@@ -42,6 +42,7 @@ public abstract class OpenInEditorWithMouseAction extends AnAction implements Du
|
||||
public void register(@NotNull List<? extends Editor> editors) {
|
||||
myEditors = editors;
|
||||
for (Editor editor : editors) {
|
||||
if (editor == null) continue;
|
||||
registerCustomShortcutSet(getShortcutSet(), (EditorGutterComponentEx)editor.getGutter());
|
||||
}
|
||||
}
|
||||
@@ -118,7 +119,7 @@ public abstract class OpenInEditorWithMouseAction extends AnAction implements Du
|
||||
@Nullable
|
||||
private Editor getEditor(@NotNull Component component) {
|
||||
for (Editor editor : myEditors) {
|
||||
if (editor.getGutter() == component) {
|
||||
if (editor != null && editor.getGutter() == component) {
|
||||
return editor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class SetEditorSettingsAction extends ActionGroup implements DumbAware {
|
||||
public class SetEditorSettingsAction extends ActionGroup implements DumbAware {
|
||||
@NotNull private final TextDiffSettingsHolder.TextDiffSettings myTextSettings;
|
||||
@NotNull private final List<? extends Editor> myEditors;
|
||||
|
||||
@@ -125,7 +125,7 @@ public abstract class SetEditorSettingsAction extends ActionGroup implements Dum
|
||||
@Override
|
||||
public void applyDefaults(@NotNull List<? extends Editor> editors) {
|
||||
for (Editor editor : editors) {
|
||||
if (editor.getUserData(EditorImpl.FORCED_SOFT_WRAPS) != null) myForcedSoftWrap = true;
|
||||
if (editor != null && editor.getUserData(EditorImpl.FORCED_SOFT_WRAPS) != null) myForcedSoftWrap = true;
|
||||
}
|
||||
super.applyDefaults(editors);
|
||||
}
|
||||
@@ -157,8 +157,9 @@ public abstract class SetEditorSettingsAction extends ActionGroup implements Dum
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
setSelected(state);
|
||||
for (Editor editor : myEditors) {
|
||||
setSelected(state);
|
||||
if (editor == null) continue;
|
||||
apply(editor, state);
|
||||
}
|
||||
}
|
||||
@@ -171,6 +172,7 @@ public abstract class SetEditorSettingsAction extends ActionGroup implements Dum
|
||||
|
||||
public void applyDefaults(@NotNull List<? extends Editor> editors) {
|
||||
for (Editor editor : editors) {
|
||||
if (editor == null) continue;
|
||||
apply(editor, isSelected());
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -25,14 +25,14 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Allows to compare binary files
|
||||
* Allows to compare files
|
||||
*/
|
||||
public class BinaryFileContentImpl implements DiffContent, BinaryFileContent {
|
||||
public class FileContentImpl implements FileContent, BinaryFileContent {
|
||||
@NotNull private final VirtualFile myFile;
|
||||
@Nullable private final Project myProject;
|
||||
@NotNull private final FileType myType;
|
||||
|
||||
public BinaryFileContentImpl(@Nullable Project project, @NotNull VirtualFile file) {
|
||||
public FileContentImpl(@Nullable Project project, @NotNull VirtualFile file) {
|
||||
assert file.isValid() && !file.isDirectory();
|
||||
myProject = project;
|
||||
myFile = file;
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.diff.tools.binary;
|
||||
|
||||
import com.intellij.diff.DiffContext;
|
||||
import com.intellij.diff.tools.util.EditorsDiffPanelBase;
|
||||
import com.intellij.diff.util.TextDiffType;
|
||||
import com.intellij.openapi.actionSystem.DataProvider;
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class BinaryDiffPanel extends EditorsDiffPanelBase {
|
||||
@NotNull protected final JPanel INSERTED_CONTENT_NOTIFICATION =
|
||||
createNotification("Content added", TextDiffType.INSERTED.getColor(null));
|
||||
@NotNull protected final JPanel REMOVED_CONTENT_NOTIFICATION =
|
||||
createNotification("Content removed", TextDiffType.DELETED.getColor(null));
|
||||
|
||||
@NotNull private final BinaryDiffViewer myViewer;
|
||||
|
||||
public BinaryDiffPanel(@NotNull BinaryDiffViewer viewer,
|
||||
@NotNull BinaryContentPanel editorsPanel,
|
||||
@NotNull DataProvider dataProvider,
|
||||
@NotNull DiffContext context) {
|
||||
super(editorsPanel, dataProvider, context);
|
||||
myViewer = viewer;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected JComponent getCurrentEditor() {
|
||||
FileEditor editor = myViewer.getCurrentEditor();
|
||||
return editor != null ? editor.getComponent() : null;
|
||||
}
|
||||
|
||||
public void addInsertedContentNotification() {
|
||||
myNotificationsPanel.add(INSERTED_CONTENT_NOTIFICATION);
|
||||
myNotificationsPanel.revalidate();
|
||||
}
|
||||
|
||||
public void addRemovedContentNotification() {
|
||||
myNotificationsPanel.add(REMOVED_CONTENT_NOTIFICATION);
|
||||
myNotificationsPanel.revalidate();
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,15 @@ package com.intellij.diff.tools.binary;
|
||||
|
||||
import com.intellij.diff.DiffContext;
|
||||
import com.intellij.diff.actions.impl.FocusOppositePaneAction;
|
||||
import com.intellij.diff.contents.*;
|
||||
import com.intellij.diff.contents.DiffContent;
|
||||
import com.intellij.diff.contents.DocumentContent;
|
||||
import com.intellij.diff.contents.EmptyContent;
|
||||
import com.intellij.diff.contents.FileContent;
|
||||
import com.intellij.diff.requests.ContentDiffRequest;
|
||||
import com.intellij.diff.requests.DiffRequest;
|
||||
import com.intellij.diff.tools.util.DiffNotifications;
|
||||
import com.intellij.diff.tools.util.SimpleDiffPanel;
|
||||
import com.intellij.diff.tools.util.StatusPanel;
|
||||
import com.intellij.diff.tools.util.base.ListenerDiffViewerBase;
|
||||
import com.intellij.diff.util.DiffUserDataKeys;
|
||||
import com.intellij.diff.util.DiffUtil;
|
||||
@@ -27,6 +33,7 @@ import com.intellij.diff.util.Side;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -42,20 +49,17 @@ import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Couple;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.util.ui.AnimatedIcon;
|
||||
import com.intellij.util.ui.AsyncProcessIcon;
|
||||
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 java.awt.*;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.io.IOException;
|
||||
@@ -65,7 +69,7 @@ import java.util.List;
|
||||
public class BinaryDiffViewer extends ListenerDiffViewerBase {
|
||||
public static final Logger LOG = Logger.getInstance(BinaryDiffViewer.class);
|
||||
|
||||
@NotNull private final BinaryDiffPanel myPanel;
|
||||
@NotNull private final SimpleDiffPanel myPanel;
|
||||
@NotNull private final BinaryContentPanel myContentPanel;
|
||||
@NotNull private final MyStatusPanel myStatusPanel;
|
||||
|
||||
@@ -89,6 +93,7 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase {
|
||||
myEditorProvider1 = editors.first.second;
|
||||
myEditor2 = editors.second.first;
|
||||
myEditorProvider2 = editors.second.second;
|
||||
assert myEditor1 != null || myEditor2 != null;
|
||||
|
||||
if (myEditor1 != null && myEditor2 != null) {
|
||||
myEditorFocusListener1 = new MyEditorFocusListener(Side.LEFT);
|
||||
@@ -102,8 +107,7 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase {
|
||||
|
||||
myContentPanel = new BinaryContentPanel(titlePanel, myEditor1, myEditor2);
|
||||
|
||||
myPanel = new BinaryDiffPanel(this, myContentPanel, this, context);
|
||||
if (myEditor1 == null && myEditor2 == null) myPanel.setErrorContent();
|
||||
myPanel = new SimpleDiffPanel(myContentPanel, this, context);
|
||||
|
||||
myStatusPanel = new MyStatusPanel();
|
||||
|
||||
@@ -172,9 +176,9 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase {
|
||||
@NotNull
|
||||
private Pair<FileEditor, FileEditorProvider> createEditor(@NotNull final DiffContent content) throws IOException {
|
||||
if (content instanceof EmptyContent) return Pair.empty();
|
||||
if (content instanceof BinaryFileContent) {
|
||||
if (content instanceof FileContent) {
|
||||
Project project = myProject != null ? myProject : ProjectManager.getInstance().getDefaultProject();
|
||||
VirtualFile file = ((BinaryFileContent)content).getFile();
|
||||
VirtualFile file = ((FileContent)content).getFile();
|
||||
|
||||
FileEditorProvider[] providers = FileEditorProviderManager.getInstance().getProviders(project, file);
|
||||
if (providers.length == 0) throw new IOException("Can't find FileEditorProvider");
|
||||
@@ -254,7 +258,7 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase {
|
||||
@Override
|
||||
public void run() {
|
||||
clearDiffPresentation();
|
||||
myPanel.addInsertedContentNotification();
|
||||
myPanel.addNotification(DiffNotifications.INSERTED_CONTENT);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -264,13 +268,12 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase {
|
||||
@Override
|
||||
public void run() {
|
||||
clearDiffPresentation();
|
||||
myPanel.addRemovedContentNotification();
|
||||
myPanel.addNotification(DiffNotifications.REMOVED_CONTENT);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: compare text with image by-byte?
|
||||
if (!(contents.get(0) instanceof BinaryFileContent) || !(contents.get(1) instanceof BinaryFileContent)) {
|
||||
if (!(contents.get(0) instanceof FileContent) || !(contents.get(1) instanceof FileContent)) {
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -279,18 +282,41 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase {
|
||||
};
|
||||
}
|
||||
|
||||
final BinaryFileContent content1 = (BinaryFileContent)contents.get(0);
|
||||
final BinaryFileContent content2 = (BinaryFileContent)contents.get(1);
|
||||
byte[] bytes1 = content1.getBytes();
|
||||
byte[] bytes2 = content2.getBytes();
|
||||
final VirtualFile file1 = ((FileContent)contents.get(0)).getFile();
|
||||
final VirtualFile file2 = ((FileContent)contents.get(1)).getFile();
|
||||
if (!file1.isValid() || !file2.isValid()) {
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myPanel.addNotification(DiffNotifications.ERROR);
|
||||
clearDiffPresentation();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
final boolean equal = Arrays.equals(bytes1, bytes2);
|
||||
final boolean equal = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
try {
|
||||
// we can't use getInputStream() here because we can't restore BOM marker
|
||||
// (getBom() can return null for binary files, while getInputStream() strips BOM for all files).
|
||||
// It can be made for files from VFS that implements FileSystemInterface though.
|
||||
byte[] bytes1 = file1.contentsToByteArray();
|
||||
byte[] bytes2 = file2.contentsToByteArray();
|
||||
return Arrays.equals(bytes1, bytes2);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.warn(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
clearDiffPresentation();
|
||||
if (equal) myPanel.addContentsEqualNotification();
|
||||
if (equal) myPanel.addNotification(DiffNotifications.EQUAL_CONTENTS);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -299,7 +325,7 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase {
|
||||
@Override
|
||||
public void run() {
|
||||
clearDiffPresentation();
|
||||
myPanel.addOperationCanceledNotification();
|
||||
myPanel.addNotification(DiffNotifications.OPERATION_CANCELED);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -309,7 +335,7 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase {
|
||||
@Override
|
||||
public void run() {
|
||||
clearDiffPresentation();
|
||||
myPanel.addDiffErrorNotification();
|
||||
myPanel.addNotification(DiffNotifications.ERROR);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -333,7 +359,7 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase {
|
||||
@Nullable
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myPanel.getPreferredFocusedComponent();
|
||||
return getCurrentEditor().getPreferredFocusedComponent();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -351,8 +377,9 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase {
|
||||
return myEditor1;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
FileEditor getCurrentEditor() {
|
||||
//noinspection ConstantConditions
|
||||
return getCurrentSide().select(myEditor1, myEditor2);
|
||||
}
|
||||
|
||||
@@ -366,21 +393,10 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase {
|
||||
// Misc
|
||||
//
|
||||
|
||||
@Override
|
||||
protected boolean tryRediffSynchronously() {
|
||||
return myPanel.isWindowFocused();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected OpenFileDescriptor getOpenFileDescriptor() {
|
||||
ContentDiffRequest request = getRequest();
|
||||
FileEditor editor = getCurrentEditor();
|
||||
if (editor == null) return null;
|
||||
|
||||
DiffContent content = getCurrentSide().selectNotNull(request.getContents());
|
||||
|
||||
return content.getOpenFileDescriptor();
|
||||
return getCurrentSide().selectNotNull(getRequest().getContents()).getOpenFileDescriptor();
|
||||
}
|
||||
|
||||
public static boolean canShowRequest(@NotNull DiffContext context, @NotNull DiffRequest request) {
|
||||
@@ -401,10 +417,10 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase {
|
||||
public static boolean canShowContent(@NotNull DiffContent content, @NotNull DiffContext context) {
|
||||
if (content instanceof EmptyContent) return true;
|
||||
if (content instanceof DocumentContent) return true;
|
||||
if (content instanceof BinaryFileContent) {
|
||||
if (content instanceof FileContent) {
|
||||
Project project = context.getProject();
|
||||
if (project == null) project = ProjectManager.getInstance().getDefaultProject();
|
||||
VirtualFile file = ((BinaryFileContent)content).getFile();
|
||||
VirtualFile file = ((FileContent)content).getFile();
|
||||
|
||||
return FileEditorProviderManager.getInstance().getProviders(project, file).length != 0;
|
||||
}
|
||||
@@ -413,8 +429,7 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase {
|
||||
|
||||
public static boolean wantShowContent(@NotNull DiffContent content, @NotNull DiffContext context) {
|
||||
if (content instanceof EmptyContent) return false;
|
||||
if (content instanceof DocumentContent) return false;
|
||||
if (content instanceof BinaryFileContent) {
|
||||
if (content instanceof FileContent) {
|
||||
if (content.getContentType() == null) return false;
|
||||
if (content.getContentType().isBinary()) return true;
|
||||
if (content.getContentType() instanceof UIBasedFileType) return true;
|
||||
@@ -454,27 +469,10 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase {
|
||||
return super.getData(dataId);
|
||||
}
|
||||
|
||||
private static class MyStatusPanel extends JPanel {
|
||||
private final AnimatedIcon myBusySpinner;
|
||||
|
||||
public MyStatusPanel() {
|
||||
super(new BorderLayout());
|
||||
myBusySpinner = new AsyncProcessIcon("StatusPanelSpinner");
|
||||
myBusySpinner.setVisible(false);
|
||||
|
||||
add(myBusySpinner, BorderLayout.WEST);
|
||||
setBorder(IdeBorderFactory.createEmptyBorder(0, 4, 0, 4));
|
||||
}
|
||||
|
||||
public void setBusy(boolean busy) {
|
||||
if (busy) {
|
||||
myBusySpinner.setVisible(true);
|
||||
myBusySpinner.resume();
|
||||
}
|
||||
else {
|
||||
myBusySpinner.setVisible(false);
|
||||
myBusySpinner.suspend();
|
||||
}
|
||||
private static class MyStatusPanel extends StatusPanel {
|
||||
@Override
|
||||
protected int getChangesCount() {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -153,6 +153,7 @@ class DirDiffViewer implements FrameDiffTool.DiffViewer {
|
||||
if (content instanceof DirectoryContent) return true;
|
||||
if (content instanceof FileContent &&
|
||||
content.getContentType() instanceof ArchiveFileType &&
|
||||
((FileContent)content).getFile().isValid() &&
|
||||
((FileContent)content).getFile().isInLocalFileSystem()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -106,8 +106,7 @@ public class OnesideDiffPanel extends DiffPanelBase {
|
||||
// Misc
|
||||
//
|
||||
|
||||
@Nullable
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myCurrentCard == GOOD_CONTENT ? myEditor.getContentComponent() : null;
|
||||
public boolean isGoodContent() {
|
||||
return myCurrentCard == GOOD_CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,25 +26,24 @@ import com.intellij.diff.contents.DocumentContent;
|
||||
import com.intellij.diff.fragments.LineFragment;
|
||||
import com.intellij.diff.requests.ContentDiffRequest;
|
||||
import com.intellij.diff.requests.DiffRequest;
|
||||
import com.intellij.diff.tools.util.DiffDataKeys;
|
||||
import com.intellij.diff.tools.util.FoldingModelSupport;
|
||||
import com.intellij.diff.tools.util.PrevNextDifferenceIterable;
|
||||
import com.intellij.diff.tools.util.StatusPanel;
|
||||
import com.intellij.diff.tools.util.*;
|
||||
import com.intellij.diff.tools.util.base.HighlightPolicy;
|
||||
import com.intellij.diff.tools.util.base.IgnorePolicy;
|
||||
import com.intellij.diff.tools.util.base.InitialScrollPositionSupport;
|
||||
import com.intellij.diff.tools.util.base.TextDiffViewerBase;
|
||||
import com.intellij.diff.tools.util.twoside.TwosideTextDiffViewer;
|
||||
import com.intellij.diff.util.*;
|
||||
import com.intellij.diff.util.DiffUserDataKeys;
|
||||
import com.intellij.diff.util.DiffUserDataKeysEx.ScrollToPolicy;
|
||||
import com.intellij.diff.util.DiffUtil;
|
||||
import com.intellij.diff.util.DiffUtil.DocumentData;
|
||||
import com.intellij.diff.util.DiffUtil.EditorsVisiblePositions;
|
||||
import com.intellij.diff.util.LineRange;
|
||||
import com.intellij.diff.util.Side;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.Separator;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.DiffNavigationContext;
|
||||
import com.intellij.openapi.diff.LineTokenizer;
|
||||
import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorActionManager;
|
||||
@@ -91,7 +90,7 @@ public class OnesideDiffViewer extends TextDiffViewerBase {
|
||||
@NotNull private final PrevNextDifferenceIterable myPrevNextDifferenceIterable;
|
||||
@NotNull private final MyStatusPanel myStatusPanel;
|
||||
|
||||
@NotNull private final MyScrollToLineHelper myScrollToLineHelper = new MyScrollToLineHelper();
|
||||
@NotNull private final MyInitialScrollHelper myInitialScrollHelper = new MyInitialScrollHelper();
|
||||
@NotNull private final MyFoldingModel myFoldingModel;
|
||||
|
||||
@NotNull protected Side myMasterSide = Side.RIGHT;
|
||||
@@ -166,12 +165,12 @@ public class OnesideDiffViewer extends TextDiffViewerBase {
|
||||
Side side = DiffUtil.getUserData(myRequest, myContext, DiffUserDataKeys.MASTER_SIDE);
|
||||
if (side != null && side.select(myActualContent1, myActualContent2) != null) myMasterSide = side;
|
||||
|
||||
myScrollToLineHelper.processContext();
|
||||
myInitialScrollHelper.processContext(myRequest);
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
protected void updateContextHints() {
|
||||
myScrollToLineHelper.updateContext();
|
||||
myInitialScrollHelper.updateContext(myRequest);
|
||||
myFoldingModel.updateContext(myRequest, getFoldingModelSettings());
|
||||
}
|
||||
|
||||
@@ -410,7 +409,7 @@ public class OnesideDiffViewer extends TextDiffViewerBase {
|
||||
myFoldingModel.updateContext(myRequest, getFoldingModelSettings());
|
||||
|
||||
clearDiffPresentation();
|
||||
if (isEqual) myPanel.addContentsEqualNotification();
|
||||
if (isEqual) myPanel.addNotification(DiffNotifications.EQUAL_CONTENTS);
|
||||
|
||||
TIntFunction separatorLines = myFoldingModel.getLineNumberConvertor();
|
||||
myEditor.getGutterComponentEx().setLineNumberConvertor(mergeConverters(data.getLineConvertor1(), separatorLines),
|
||||
@@ -456,7 +455,7 @@ public class OnesideDiffViewer extends TextDiffViewerBase {
|
||||
|
||||
myFoldingModel.install(changedLines, myRequest, getFoldingModelSettings());
|
||||
|
||||
myScrollToLineHelper.onRediff();
|
||||
myInitialScrollHelper.onRediff();
|
||||
|
||||
myStatusPanel.update();
|
||||
myPanel.setGoodContent();
|
||||
@@ -754,7 +753,8 @@ public class OnesideDiffViewer extends TextDiffViewerBase {
|
||||
@Nullable
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myPanel.getPreferredFocusedComponent();
|
||||
if (!myPanel.isGoodContent()) return null;
|
||||
return myEditor.getComponent();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -785,11 +785,6 @@ public class OnesideDiffViewer extends TextDiffViewerBase {
|
||||
// Misc
|
||||
//
|
||||
|
||||
@Override
|
||||
protected boolean tryRediffSynchronously() {
|
||||
return myPanel.isWindowFocused();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected OpenFileDescriptor getOpenFileDescriptor() {
|
||||
@@ -1241,62 +1236,50 @@ public class OnesideDiffViewer extends TextDiffViewerBase {
|
||||
}
|
||||
}
|
||||
|
||||
private class MyScrollToLineHelper {
|
||||
protected boolean myShouldScroll = true;
|
||||
|
||||
@Nullable private ScrollToPolicy myScrollToChange;
|
||||
@Nullable private EditorsVisiblePositions myEditorPosition;
|
||||
@Nullable private LogicalPosition[] myCaretPosition;
|
||||
@Nullable private DiffNavigationContext myNavigationContext;
|
||||
|
||||
public void processContext() {
|
||||
myScrollToChange = myRequest.getUserData(DiffUserDataKeysEx.SCROLL_TO_CHANGE);
|
||||
myEditorPosition = myRequest.getUserData(EditorsVisiblePositions.KEY);
|
||||
myCaretPosition = myRequest.getUserData(DiffUserDataKeysEx.EDITORS_CARET_POSITION);
|
||||
myNavigationContext = myRequest.getUserData(DiffUserDataKeysEx.NAVIGATION_CONTEXT);
|
||||
private class MyInitialScrollHelper extends InitialScrollPositionSupport.TwosideInitialScrollHelper {
|
||||
@NotNull
|
||||
@Override
|
||||
protected List<? extends Editor> getEditors() {
|
||||
return OnesideDiffViewer.this.getEditors();
|
||||
}
|
||||
|
||||
public void updateContext() {
|
||||
@Override
|
||||
protected void disableSyncScroll(boolean value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSlowRediff() {
|
||||
// Will not happen for initial rediff
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected LogicalPosition[] getCaretPositions() {
|
||||
LogicalPosition position = myEditor.getCaretModel().getLogicalPosition();
|
||||
Pair<int[], Side> pair = transferLineFromOneside(position.line);
|
||||
LogicalPosition[] carets = new LogicalPosition[2];
|
||||
carets[0] = getPosition(pair.first[0], position.column);
|
||||
carets[1] = getPosition(pair.first[1], position.column);
|
||||
|
||||
EditorsVisiblePositions editorsPosition = new EditorsVisiblePositions(position, DiffUtil.getScrollingPosition(myEditor));
|
||||
|
||||
myRequest.putUserData(DiffUserDataKeysEx.SCROLL_TO_CHANGE, null);
|
||||
myRequest.putUserData(EditorsVisiblePositions.KEY, editorsPosition);
|
||||
myRequest.putUserData(DiffUserDataKeysEx.EDITORS_CARET_POSITION, carets);
|
||||
myRequest.putUserData(DiffUserDataKeysEx.NAVIGATION_CONTEXT, null);
|
||||
return carets;
|
||||
}
|
||||
|
||||
public void onRediff() {
|
||||
if (myShouldScroll && myScrollToChange != null) {
|
||||
myShouldScroll = !doScrollToChange(myScrollToChange);
|
||||
}
|
||||
if (myShouldScroll && myNavigationContext != null) {
|
||||
myShouldScroll = !doScrollToContext(myNavigationContext);
|
||||
}
|
||||
if (myShouldScroll && myCaretPosition != null && myCaretPosition.length == 2) {
|
||||
LogicalPosition twosidePosition = myMasterSide.selectNotNull(myCaretPosition);
|
||||
int onesideLine = transferLineToOneside(myMasterSide, twosidePosition.line);
|
||||
LogicalPosition position = new LogicalPosition(onesideLine, twosidePosition.column);
|
||||
@Override
|
||||
protected boolean doScrollToPosition() {
|
||||
if (myCaretPosition == null) return false;
|
||||
|
||||
myEditor.getCaretModel().moveToLogicalPosition(position);
|
||||
LogicalPosition twosidePosition = myMasterSide.selectNotNull(myCaretPosition);
|
||||
int onesideLine = transferLineToOneside(myMasterSide, twosidePosition.line);
|
||||
LogicalPosition position = new LogicalPosition(onesideLine, twosidePosition.column);
|
||||
|
||||
if (myEditorPosition != null && myEditorPosition.isSame(position)) {
|
||||
DiffUtil.scrollToPoint(myEditor, myEditorPosition.myPoints[0]);
|
||||
}
|
||||
else {
|
||||
DiffUtil.scrollToCaret(myEditor, false);
|
||||
}
|
||||
myShouldScroll = false;
|
||||
myEditor.getCaretModel().moveToLogicalPosition(position);
|
||||
|
||||
if (myEditorsPosition != null && myEditorsPosition.isSame(position)) {
|
||||
DiffUtil.scrollToPoint(myEditor, myEditorsPosition.myPoints[0], false);
|
||||
}
|
||||
if (myShouldScroll) {
|
||||
doScrollToChange(ScrollToPolicy.FIRST_CHANGE);
|
||||
else {
|
||||
DiffUtil.scrollToCaret(myEditor, false);
|
||||
}
|
||||
myShouldScroll = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -1305,9 +1288,15 @@ public class OnesideDiffViewer extends TextDiffViewerBase {
|
||||
return new LogicalPosition(line, column);
|
||||
}
|
||||
|
||||
private boolean doScrollToLine(@NotNull Side side, @NotNull LogicalPosition position) {
|
||||
private void doScrollToLine(@NotNull Side side, @NotNull LogicalPosition position) {
|
||||
int onesideLine = transferLineToOneside(side, position.line);
|
||||
DiffUtil.scrollEditor(myEditor, onesideLine, position.column, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doScrollToLine() {
|
||||
if (myScrollToLine == null) return false;
|
||||
doScrollToLine(myScrollToLine.first, new LogicalPosition(myScrollToLine.second, 0));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1332,23 +1321,37 @@ public class OnesideDiffViewer extends TextDiffViewerBase {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean doScrollToContext(@NotNull DiffNavigationContext context) {
|
||||
@Override
|
||||
protected boolean doScrollToChange() {
|
||||
if (myScrollToChange == null) return false;
|
||||
return doScrollToChange(myScrollToChange);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doScrollToFirstChange() {
|
||||
return doScrollToChange(ScrollToPolicy.FIRST_CHANGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doScrollToContext() {
|
||||
if (myNavigationContext == null) return false;
|
||||
if (myChangedBlockData == null) return false;
|
||||
if (myActualContent2 == null) return false;
|
||||
|
||||
ChangedLinesIterator changedLinesIterator = new ChangedLinesIterator(Side.RIGHT, myChangedBlockData.getDiffChanges());
|
||||
NavigationContextChecker checker = new NavigationContextChecker(changedLinesIterator, context);
|
||||
NavigationContextChecker checker = new NavigationContextChecker(changedLinesIterator, myNavigationContext);
|
||||
int line = checker.contextMatchCheck();
|
||||
if (line == -1) {
|
||||
// this will work for the case, when spaces changes are ignored, and corresponding fragments are not reported as changed
|
||||
// just try to find target line -> +-
|
||||
AllLinesIterator allLinesIterator = new AllLinesIterator(Side.RIGHT);
|
||||
NavigationContextChecker checker2 = new NavigationContextChecker(allLinesIterator, context);
|
||||
NavigationContextChecker checker2 = new NavigationContextChecker(allLinesIterator, myNavigationContext);
|
||||
line = checker2.contextMatchCheck();
|
||||
}
|
||||
if (line == -1) return false;
|
||||
|
||||
return doScrollToLine(Side.RIGHT, new LogicalPosition(line, 0));
|
||||
doScrollToLine(Side.RIGHT, new LogicalPosition(line, 0));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.markup.*;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.CalledWithWriteLock;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -180,6 +179,10 @@ public class SimpleDiffChange {
|
||||
return DiffUtil.getLineDiffType(myFragment);
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return myIsValid;
|
||||
}
|
||||
|
||||
//
|
||||
// Shift
|
||||
//
|
||||
@@ -222,41 +225,6 @@ public class SimpleDiffChange {
|
||||
return DiffUtil.isSelectedByLine(line, line1, line2);
|
||||
}
|
||||
|
||||
@CalledWithWriteLock
|
||||
public void replaceChange(@NotNull final Side sourceSide) {
|
||||
assert myEditor1 != null && myEditor2 != null;
|
||||
|
||||
if (!myIsValid) return;
|
||||
|
||||
final Document document1 = myEditor1.getDocument();
|
||||
final Document document2 = myEditor2.getDocument();
|
||||
|
||||
DiffUtil.applyModification(sourceSide.other().select(document1, document2),
|
||||
getStartLine(sourceSide.other()), getEndLine(sourceSide.other()),
|
||||
sourceSide.select(document1, document2),
|
||||
getStartLine(sourceSide), getEndLine(sourceSide));
|
||||
|
||||
destroyHighlighter();
|
||||
}
|
||||
|
||||
@CalledWithWriteLock
|
||||
public void appendChange(@NotNull final Side sourceSide) {
|
||||
assert myEditor1 != null && myEditor2 != null;
|
||||
|
||||
if (!myIsValid) return;
|
||||
if (getStartLine(sourceSide) == getEndLine(sourceSide)) return;
|
||||
|
||||
final Document document1 = myEditor1.getDocument();
|
||||
final Document document2 = myEditor2.getDocument();
|
||||
|
||||
DiffUtil.applyModification(sourceSide.other().select(document1, document2),
|
||||
getEndLine(sourceSide.other()), getEndLine(sourceSide.other()),
|
||||
sourceSide.select(document1, document2),
|
||||
getStartLine(sourceSide), getEndLine(sourceSide));
|
||||
|
||||
destroyHighlighter();
|
||||
}
|
||||
|
||||
//
|
||||
// Helpers
|
||||
//
|
||||
@@ -330,7 +298,7 @@ public class SimpleDiffChange {
|
||||
return createIconRenderer(side, "Replace", AllIcons.Diff.Arrow, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
replaceChange(side);
|
||||
myViewer.replaceChange(SimpleDiffChange.this, side);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -340,7 +308,7 @@ public class SimpleDiffChange {
|
||||
return createIconRenderer(side, "Insert", AllIcons.Diff.ArrowLeftDown, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
appendChange(side);
|
||||
myViewer.appendChange(SimpleDiffChange.this, side);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -350,7 +318,7 @@ public class SimpleDiffChange {
|
||||
return createIconRenderer(side.other(), "Revert", AllIcons.Diff.Remove, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
replaceChange(side.other());
|
||||
myViewer.replaceChange(SimpleDiffChange.this, side.other());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
@NotNull private final List<SimpleDiffChange> myInvalidDiffChanges = new ArrayList<SimpleDiffChange>();
|
||||
|
||||
@Nullable private final MyFoldingModel myFoldingModel;
|
||||
@NotNull private final MyInitialScrollHelper myInitialScrollHelper = new MyInitialScrollHelper();
|
||||
@NotNull private final ModifierProvider myModifierProvider;
|
||||
|
||||
public SimpleDiffViewer(@NotNull DiffContext context, @NotNull DiffRequest request) {
|
||||
@@ -157,10 +158,17 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
return new MyFoldingModel(editor1, editor2, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processContextHints() {
|
||||
super.processContextHints();
|
||||
myInitialScrollHelper.processContext(myRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateContextHints() {
|
||||
super.updateContextHints();
|
||||
if (myFoldingModel != null) myFoldingModel.updateContext(myRequest, getFoldingModelSettings());
|
||||
myInitialScrollHelper.updateContext(myRequest);
|
||||
super.updateContextHints();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -171,6 +179,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
protected void onSlowRediff() {
|
||||
super.onSlowRediff();
|
||||
myStatusPanel.setBusy(true);
|
||||
myInitialScrollHelper.onSlowRediff();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -241,7 +250,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
@Override
|
||||
public void run() {
|
||||
clearDiffPresentation();
|
||||
myPanel.addTooBigContentNotification();
|
||||
myPanel.addNotification(DiffNotifications.DIFF_TOO_BIG);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -250,7 +259,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
@Override
|
||||
public void run() {
|
||||
clearDiffPresentation();
|
||||
myPanel.addOperationCanceledNotification();
|
||||
myPanel.addNotification(DiffNotifications.OPERATION_CANCELED);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -260,7 +269,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
@Override
|
||||
public void run() {
|
||||
clearDiffPresentation();
|
||||
myPanel.addDiffErrorNotification();
|
||||
myPanel.addNotification(DiffNotifications.ERROR);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -277,7 +286,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
if (myFoldingModel != null) myFoldingModel.updateContext(myRequest, getFoldingModelSettings());
|
||||
clearDiffPresentation();
|
||||
|
||||
if (data.isEqualContent()) myPanel.addContentsEqualNotification();
|
||||
if (data.isEqualContent()) myPanel.addNotification(DiffNotifications.EQUAL_CONTENTS);
|
||||
|
||||
if (data.getFragments() != null) {
|
||||
for (LineFragment fragment : data.getFragments()) {
|
||||
@@ -290,7 +299,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
myFoldingModel.install(data.getFragments(), myRequest, getFoldingModelSettings());
|
||||
}
|
||||
|
||||
scrollOnRediff();
|
||||
myInitialScrollHelper.onRediff();
|
||||
|
||||
myContentPanel.repaintDivider();
|
||||
myStatusPanel.update();
|
||||
@@ -386,7 +395,6 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
@Override
|
||||
protected boolean doScrollToChange(@NotNull ScrollToPolicy scrollToPolicy) {
|
||||
if (myDiffChanges.isEmpty()) return false;
|
||||
if (myEditor1 == null || myEditor2 == null) return true;
|
||||
@@ -423,7 +431,6 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
mySyncScrollSupport.makeVisible(getCurrentSide(), line1, endLine1, line2, endLine2, animated);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doScrollToContext(@NotNull DiffNavigationContext context) {
|
||||
if (myEditor2 == null) return false;
|
||||
|
||||
@@ -697,7 +704,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
@Override
|
||||
protected void apply(@NotNull Side side, @NotNull List<SimpleDiffChange> changes) {
|
||||
for (SimpleDiffChange change : changes) {
|
||||
change.replaceChange(side);
|
||||
replaceChange(change, side);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -716,7 +723,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
@Override
|
||||
protected void apply(@NotNull Side side, @NotNull List<SimpleDiffChange> changes) {
|
||||
for (SimpleDiffChange change : changes) {
|
||||
change.appendChange(side);
|
||||
appendChange(change, side);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -735,11 +742,48 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
@Override
|
||||
protected void apply(@NotNull Side side, @NotNull List<SimpleDiffChange> changes) {
|
||||
for (SimpleDiffChange change : changes) {
|
||||
change.replaceChange(side.other());
|
||||
replaceChange(change, side.other());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@CalledWithWriteLock
|
||||
public void replaceChange(@NotNull SimpleDiffChange change, @NotNull final Side sourceSide) {
|
||||
assert myEditor1 != null && myEditor2 != null;
|
||||
|
||||
if (!change.isValid()) return;
|
||||
|
||||
final Document document1 = myEditor1.getDocument();
|
||||
final Document document2 = myEditor2.getDocument();
|
||||
|
||||
DiffUtil.applyModification(sourceSide.other().select(document1, document2),
|
||||
change.getStartLine(sourceSide.other()), change.getEndLine(sourceSide.other()),
|
||||
sourceSide.select(document1, document2),
|
||||
change.getStartLine(sourceSide), change.getEndLine(sourceSide));
|
||||
|
||||
change.destroyHighlighter();
|
||||
myDiffChanges.remove(change);
|
||||
}
|
||||
|
||||
@CalledWithWriteLock
|
||||
public void appendChange(@NotNull SimpleDiffChange change, @NotNull final Side sourceSide) {
|
||||
assert myEditor1 != null && myEditor2 != null;
|
||||
|
||||
if (!change.isValid()) return;
|
||||
if (change.getStartLine(sourceSide) == change.getEndLine(sourceSide)) return;
|
||||
|
||||
final Document document1 = myEditor1.getDocument();
|
||||
final Document document2 = myEditor2.getDocument();
|
||||
|
||||
DiffUtil.applyModification(sourceSide.other().select(document1, document2),
|
||||
change.getEndLine(sourceSide.other()), change.getEndLine(sourceSide.other()),
|
||||
sourceSide.select(document1, document2),
|
||||
change.getStartLine(sourceSide), change.getEndLine(sourceSide));
|
||||
|
||||
change.destroyHighlighter();
|
||||
myDiffChanges.remove(change);
|
||||
}
|
||||
|
||||
private class MyToggleExpandByDefaultAction extends ToggleExpandByDefaultAction {
|
||||
@Override
|
||||
protected void expandAll(boolean expand) {
|
||||
@@ -874,7 +918,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
@Override
|
||||
public void paint(@NotNull Graphics g, @NotNull JComponent divider) {
|
||||
if (myEditor1 == null || myEditor2 == null) return;
|
||||
Graphics2D gg = getDividerGraphics(g, divider);
|
||||
Graphics2D gg = DiffDividerDrawUtil.getDividerGraphics(g, divider, myEditor1.getComponent());
|
||||
|
||||
gg.setColor(DiffDrawUtil.getDividerColor(myEditor1));
|
||||
gg.fill(gg.getClipBounds());
|
||||
@@ -1050,4 +1094,26 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
myPaintable.paintOnDivider(gg, divider);
|
||||
}
|
||||
}
|
||||
|
||||
private class MyInitialScrollHelper extends MyInitialScrollPositionHelper {
|
||||
@Override
|
||||
protected boolean doScrollToChange() {
|
||||
if (myScrollToChange == null) return false;
|
||||
SimpleDiffViewer.this.doScrollToChange(myScrollToChange);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doScrollToFirstChange() {
|
||||
SimpleDiffViewer.this.doScrollToChange(ScrollToPolicy.FIRST_CHANGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doScrollToContext() {
|
||||
if (myNavigationContext == null) return false;
|
||||
SimpleDiffViewer.this.doScrollToContext(myNavigationContext);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+29
-6
@@ -73,6 +73,7 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer {
|
||||
@NotNull private final List<SimpleThreesideDiffChange> myInvalidDiffChanges = new ArrayList<SimpleThreesideDiffChange>();
|
||||
|
||||
@NotNull private final MyFoldingModel myFoldingModel;
|
||||
@NotNull private final MyInitialScrollHelper myInitialScrollHelper = new MyInitialScrollHelper();
|
||||
|
||||
public SimpleThreesideDiffViewer(@NotNull DiffContext context, @NotNull DiffRequest request) {
|
||||
super(context, (ContentDiffRequest)request);
|
||||
@@ -134,10 +135,17 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer {
|
||||
return group;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processContextHints() {
|
||||
super.processContextHints();
|
||||
myInitialScrollHelper.processContext(myRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateContextHints() {
|
||||
super.updateContextHints();
|
||||
myFoldingModel.updateContext(myRequest, getFoldingModelSettings());
|
||||
myInitialScrollHelper.updateContext(myRequest);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -148,6 +156,7 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer {
|
||||
protected void onSlowRediff() {
|
||||
super.onSlowRediff();
|
||||
myStatusPanel.setBusy(true);
|
||||
myInitialScrollHelper.onSlowRediff();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -193,7 +202,7 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer {
|
||||
@Override
|
||||
public void run() {
|
||||
clearDiffPresentation();
|
||||
myPanel.addTooBigContentNotification();
|
||||
myPanel.addNotification(DiffNotifications.DIFF_TOO_BIG);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -202,7 +211,7 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer {
|
||||
@Override
|
||||
public void run() {
|
||||
clearDiffPresentation();
|
||||
myPanel.addOperationCanceledNotification();
|
||||
myPanel.addNotification(DiffNotifications.OPERATION_CANCELED);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -212,7 +221,7 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer {
|
||||
@Override
|
||||
public void run() {
|
||||
clearDiffPresentation();
|
||||
myPanel.addDiffErrorNotification();
|
||||
myPanel.addNotification(DiffNotifications.ERROR);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -238,7 +247,7 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer {
|
||||
|
||||
myFoldingModel.install(fragments, myRequest, getFoldingModelSettings());
|
||||
|
||||
scrollOnRediff();
|
||||
myInitialScrollHelper.onRediff();
|
||||
|
||||
myContentPanel.repaintDividers();
|
||||
myStatusPanel.update();
|
||||
@@ -324,7 +333,6 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer {
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
@Override
|
||||
protected boolean doScrollToChange(@NotNull ScrollToPolicy scrollToPolicy) {
|
||||
if (myDiffChanges.isEmpty()) return false;
|
||||
|
||||
@@ -591,7 +599,7 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer {
|
||||
|
||||
@Override
|
||||
public void paint(@NotNull Graphics g, @NotNull JComponent divider) {
|
||||
Graphics2D gg = getDividerGraphics(g, divider);
|
||||
Graphics2D gg = DiffDividerDrawUtil.getDividerGraphics(g, divider, myEditors.get(0).getComponent());
|
||||
|
||||
gg.setColor(DiffDrawUtil.getDividerColor(myEditors.get(0)));
|
||||
gg.fill(gg.getClipBounds());
|
||||
@@ -689,4 +697,19 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer {
|
||||
myPaintable2.paintOnScrollbar(gg, width);
|
||||
}
|
||||
}
|
||||
|
||||
private class MyInitialScrollHelper extends MyInitialScrollPositionHelper {
|
||||
@Override
|
||||
protected boolean doScrollToChange() {
|
||||
if (myScrollToChange == null) return false;
|
||||
SimpleThreesideDiffViewer.this.doScrollToChange(myScrollToChange);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doScrollToFirstChange() {
|
||||
SimpleThreesideDiffViewer.this.doScrollToChange(ScrollToPolicy.FIRST_CHANGE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.diff.tools.util;
|
||||
|
||||
import com.intellij.diff.comparison.DiffTooBigException;
|
||||
import com.intellij.diff.util.TextDiffType;
|
||||
import com.intellij.openapi.diff.DiffBundle;
|
||||
import com.intellij.ui.EditorNotificationPanel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class DiffNotifications {
|
||||
@NotNull public static final JPanel INSERTED_CONTENT =
|
||||
createNotification("Content added", TextDiffType.INSERTED.getColor(null));
|
||||
@NotNull public static final JPanel REMOVED_CONTENT =
|
||||
createNotification("Content removed", TextDiffType.DELETED.getColor(null));
|
||||
|
||||
@NotNull public static final JPanel EQUAL_CONTENTS =
|
||||
createNotification(DiffBundle.message("diff.contents.are.identical.message.text"));
|
||||
@NotNull public static final JPanel ERROR =
|
||||
createNotification("Can not calculate diff");
|
||||
@NotNull public static final JPanel OPERATION_CANCELED =
|
||||
createNotification("Can not calculate diff. Operation canceled.");
|
||||
@NotNull public static final JPanel DIFF_TOO_BIG =
|
||||
createNotification("Can not calculate diff. " + DiffTooBigException.MESSAGE);
|
||||
|
||||
@NotNull
|
||||
public static JPanel createNotification(@NotNull String text) {
|
||||
return new EditorNotificationPanel().text(text);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JPanel createNotification(@NotNull String text, @NotNull final Color background) {
|
||||
return new EditorNotificationPanel() {
|
||||
@Override
|
||||
public Color getBackground() {
|
||||
return background;
|
||||
}
|
||||
}.text(text);
|
||||
}
|
||||
}
|
||||
+6
-17
@@ -20,20 +20,19 @@ import com.intellij.diff.tools.util.base.DiffPanelBase;
|
||||
import com.intellij.diff.util.DiffUtil;
|
||||
import com.intellij.openapi.actionSystem.DataProvider;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public abstract class EditorsDiffPanelBase extends DiffPanelBase {
|
||||
public class SimpleDiffPanel extends DiffPanelBase {
|
||||
private static final String GOOD_CONTENT = "GoodContent";
|
||||
private static final String ERROR_CONTENT = "ErrorContent";
|
||||
|
||||
@NotNull private final JComponent myEditorsPanel;
|
||||
|
||||
public EditorsDiffPanelBase(@NotNull JComponent editorPanel,
|
||||
@NotNull DataProvider dataProvider,
|
||||
@NotNull DiffContext context) {
|
||||
public SimpleDiffPanel(@NotNull JComponent editorPanel,
|
||||
@NotNull DataProvider dataProvider,
|
||||
@NotNull DiffContext context) {
|
||||
super(context.getProject(), dataProvider, context);
|
||||
myEditorsPanel = editorPanel;
|
||||
|
||||
@@ -63,17 +62,7 @@ public abstract class EditorsDiffPanelBase extends DiffPanelBase {
|
||||
// Misc
|
||||
//
|
||||
|
||||
@Nullable
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
if (myCurrentCard != GOOD_CONTENT) return null;
|
||||
|
||||
return getCurrentEditor();
|
||||
public boolean isGoodContent() {
|
||||
return myCurrentCard == GOOD_CONTENT;
|
||||
}
|
||||
|
||||
//
|
||||
// Abstract
|
||||
//
|
||||
|
||||
@Nullable
|
||||
protected abstract JComponent getCurrentEditor();
|
||||
}
|
||||
@@ -30,6 +30,7 @@ public abstract class StatusPanel extends JPanel {
|
||||
public StatusPanel() {
|
||||
super(new BorderLayout());
|
||||
myTextLabel = new JLabel("");
|
||||
myTextLabel.setVisible(false);
|
||||
myBusySpinner = new AsyncProcessIcon("StatusPanelSpinner");
|
||||
myBusySpinner.setVisible(false);
|
||||
|
||||
@@ -40,6 +41,7 @@ public abstract class StatusPanel extends JPanel {
|
||||
|
||||
public void update() {
|
||||
int count = getChangesCount();
|
||||
myTextLabel.setVisible(count != -1);
|
||||
myTextLabel.setText(DiffBundle.message("diff.count.differences.status.text", count));
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.diff.tools.util;
|
||||
|
||||
import com.intellij.diff.util.IntPair;
|
||||
import com.intellij.diff.util.Side;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.LogicalPosition;
|
||||
import com.intellij.openapi.editor.ScrollingModel;
|
||||
@@ -33,6 +34,8 @@ import java.awt.*;
|
||||
import java.util.List;
|
||||
|
||||
public class SyncScrollSupport {
|
||||
private static final Logger LOG = Logger.getInstance(SyncScrollSupport.class);
|
||||
|
||||
public interface SyncScrollable {
|
||||
@CalledInAwt
|
||||
boolean isSyncScrollEnabled();
|
||||
@@ -49,7 +52,8 @@ public class SyncScrollSupport {
|
||||
@NotNull private final MyScrollHelper myHelper1;
|
||||
@NotNull private final MyScrollHelper myHelper2;
|
||||
|
||||
public boolean myDuringSyncScroll = false;
|
||||
private boolean myDisabled = false;
|
||||
private boolean myDuringSyncScroll = false;
|
||||
|
||||
public TwosideSyncScrollSupport(@NotNull Editor editor1, @NotNull Editor editor2, @NotNull SyncScrollable scrollable) {
|
||||
myEditor1 = editor1;
|
||||
@@ -60,8 +64,22 @@ public class SyncScrollSupport {
|
||||
myHelper2 = create(myEditor2, myEditor1, myScrollable, Side.RIGHT);
|
||||
}
|
||||
|
||||
public boolean isDuringSyncScroll() {
|
||||
return myDuringSyncScroll;
|
||||
}
|
||||
|
||||
public boolean setDisabled(boolean value) {
|
||||
if (myDisabled == value) LOG.warn(new Throwable("myDisabled == value: " + myDisabled + " - " + value));
|
||||
return myDisabled = value;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public SyncScrollable getScrollable() {
|
||||
return myScrollable;
|
||||
}
|
||||
|
||||
public void visibleAreaChanged(VisibleAreaEvent e) {
|
||||
if (!myScrollable.isSyncScrollEnabled() || myDuringSyncScroll) return;
|
||||
if (!myScrollable.isSyncScrollEnabled() || myDuringSyncScroll || myDisabled) return;
|
||||
|
||||
myDuringSyncScroll = true;
|
||||
try {
|
||||
@@ -77,15 +95,6 @@ public class SyncScrollSupport {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public SyncScrollable getScrollable() {
|
||||
return myScrollable;
|
||||
}
|
||||
|
||||
public boolean isDuringSyncScroll() {
|
||||
return myDuringSyncScroll;
|
||||
}
|
||||
|
||||
public void makeVisible(@NotNull Side masterSide,
|
||||
int startLine1, int endLine1, int startLine2, int endLine2,
|
||||
final boolean animate) {
|
||||
@@ -142,7 +151,8 @@ public class SyncScrollSupport {
|
||||
@NotNull private final MyScrollHelper myHelper21;
|
||||
@NotNull private final MyScrollHelper myHelper22;
|
||||
|
||||
public boolean myDuringSyncScroll = false;
|
||||
private boolean myDisabled = false;
|
||||
private boolean myDuringSyncScroll = false;
|
||||
|
||||
public ThreesideSyncScrollSupport(@NotNull List<? extends Editor> editors,
|
||||
@NotNull SyncScrollable scrollable1,
|
||||
@@ -160,8 +170,13 @@ public class SyncScrollSupport {
|
||||
myHelper22 = create(editors.get(2), editors.get(1), myScrollable2, Side.RIGHT);
|
||||
}
|
||||
|
||||
public boolean setDisabled(boolean value) {
|
||||
if (myDisabled == value) LOG.warn(new Throwable("myDisabled == value: " + myDisabled + " - " + value));
|
||||
return myDisabled = value;
|
||||
}
|
||||
|
||||
public void visibleAreaChanged(VisibleAreaEvent e) {
|
||||
if (myDuringSyncScroll) return;
|
||||
if (myDuringSyncScroll || myDisabled) return;
|
||||
|
||||
myDuringSyncScroll = true;
|
||||
try {
|
||||
|
||||
@@ -16,11 +16,8 @@
|
||||
package com.intellij.diff.tools.util.base;
|
||||
|
||||
import com.intellij.diff.DiffContext;
|
||||
import com.intellij.diff.comparison.DiffTooBigException;
|
||||
import com.intellij.openapi.actionSystem.DataProvider;
|
||||
import com.intellij.openapi.diff.DiffBundle;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.ui.EditorNotificationPanel;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -29,15 +26,6 @@ import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public abstract class DiffPanelBase extends JPanel implements DataProvider {
|
||||
@NotNull protected final JPanel CONTENTS_EQUAL_NOTIFICATION =
|
||||
createNotification(DiffBundle.message("diff.contents.are.identical.message.text"));
|
||||
@NotNull protected final JPanel CANT_CALCULATE_DIFF =
|
||||
createNotification("Can not calculate diff");
|
||||
@NotNull protected final JPanel CONTENTS_OPERATION_CANCELED_NOTIFICATION =
|
||||
createNotification("Can not calculate diff. Operation canceled.");
|
||||
@NotNull protected final JPanel CONTENTS_TOO_BIG_NOTIFICATION =
|
||||
createNotification("Can not calculate diff. " + DiffTooBigException.MESSAGE);
|
||||
|
||||
@Nullable protected final Project myProject;
|
||||
@NotNull private final DataProvider myDataProvider;
|
||||
@NotNull protected final DiffContext myContext;
|
||||
@@ -82,10 +70,6 @@ public abstract class DiffPanelBase extends JPanel implements DataProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isWindowFocused() {
|
||||
return myContext.isWindowFocused();
|
||||
}
|
||||
|
||||
public boolean isFocused() {
|
||||
return myContext.isFocused();
|
||||
}
|
||||
@@ -114,50 +98,17 @@ public abstract class DiffPanelBase extends JPanel implements DataProvider {
|
||||
return myDataProvider.getData(dataId);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public abstract JComponent getPreferredFocusedComponent();
|
||||
|
||||
//
|
||||
// Notifications
|
||||
//
|
||||
|
||||
public void addContentsEqualNotification() {
|
||||
myNotificationsPanel.add(CONTENTS_EQUAL_NOTIFICATION);
|
||||
myNotificationsPanel.revalidate();
|
||||
}
|
||||
|
||||
public void addTooBigContentNotification() {
|
||||
myNotificationsPanel.add(CONTENTS_TOO_BIG_NOTIFICATION);
|
||||
myNotificationsPanel.revalidate();
|
||||
}
|
||||
|
||||
public void addOperationCanceledNotification() {
|
||||
myNotificationsPanel.add(CONTENTS_OPERATION_CANCELED_NOTIFICATION);
|
||||
myNotificationsPanel.revalidate();
|
||||
}
|
||||
|
||||
public void addDiffErrorNotification() {
|
||||
myNotificationsPanel.add(CANT_CALCULATE_DIFF);
|
||||
myNotificationsPanel.revalidate();
|
||||
}
|
||||
|
||||
public void resetNotifications() {
|
||||
myNotificationsPanel.removeAll();
|
||||
myNotificationsPanel.revalidate();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JPanel createNotification(@NotNull String text) {
|
||||
return new EditorNotificationPanel().text(text);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JPanel createNotification(@NotNull String text, @NotNull final Color background) {
|
||||
return new EditorNotificationPanel() {
|
||||
@Override
|
||||
public Color getBackground() {
|
||||
return background;
|
||||
}
|
||||
}.text(text);
|
||||
public void addNotification(@NotNull JComponent notification) {
|
||||
myNotificationsPanel.add(notification);
|
||||
myNotificationsPanel.revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,13 +147,17 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
|
||||
return myRequest;
|
||||
}
|
||||
|
||||
public boolean isDisposed() {
|
||||
return myDisposed.get();
|
||||
}
|
||||
|
||||
//
|
||||
// Abstract
|
||||
//
|
||||
|
||||
@CalledInAwt
|
||||
protected boolean tryRediffSynchronously() {
|
||||
return true;
|
||||
return myContext.isWindowFocused();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+282
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.diff.tools.util.base;
|
||||
|
||||
import com.intellij.diff.requests.DiffRequest;
|
||||
import com.intellij.diff.util.*;
|
||||
import com.intellij.diff.util.DiffUserDataKeysEx.ScrollToPolicy;
|
||||
import com.intellij.openapi.diff.DiffNavigationContext;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.LogicalPosition;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import org.jetbrains.annotations.CalledInAwt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
|
||||
public class InitialScrollPositionSupport {
|
||||
public abstract static class InitialScrollHelperBase {
|
||||
protected boolean myShouldScroll = true;
|
||||
|
||||
@Nullable protected ScrollToPolicy myScrollToChange;
|
||||
@Nullable protected EditorsVisiblePositions myEditorsPosition;
|
||||
@Nullable protected LogicalPosition[] myCaretPosition;
|
||||
|
||||
public void processContext(@NotNull DiffRequest request) {
|
||||
myScrollToChange = request.getUserData(DiffUserDataKeysEx.SCROLL_TO_CHANGE);
|
||||
myEditorsPosition = request.getUserData(EditorsVisiblePositions.KEY);
|
||||
myCaretPosition = request.getUserData(DiffUserDataKeysEx.EDITORS_CARET_POSITION);
|
||||
}
|
||||
|
||||
public void updateContext(@NotNull DiffRequest request) {
|
||||
LogicalPosition[] carets = getCaretPositions();
|
||||
EditorsVisiblePositions visiblePositions = getVisiblePositions();
|
||||
|
||||
request.putUserData(DiffUserDataKeysEx.SCROLL_TO_CHANGE, null);
|
||||
request.putUserData(EditorsVisiblePositions.KEY, visiblePositions);
|
||||
request.putUserData(DiffUserDataKeysEx.EDITORS_CARET_POSITION, carets);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected abstract LogicalPosition[] getCaretPositions();
|
||||
|
||||
@Nullable
|
||||
protected abstract EditorsVisiblePositions getVisiblePositions();
|
||||
}
|
||||
|
||||
private static abstract class SideInitialScrollHelper extends InitialScrollHelperBase {
|
||||
@Nullable
|
||||
@Override
|
||||
protected LogicalPosition[] getCaretPositions() {
|
||||
return doGetCaretPositions(getEditors());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected EditorsVisiblePositions getVisiblePositions() {
|
||||
return doGetVisiblePositions(getEditors());
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
protected boolean doScrollToPosition() {
|
||||
List<? extends Editor> editors = getEditors();
|
||||
if (myCaretPosition == null || myCaretPosition.length != editors.size()) return false;
|
||||
|
||||
doMoveCaretsToPositions(myCaretPosition, editors);
|
||||
|
||||
try {
|
||||
disableSyncScroll(true);
|
||||
|
||||
if (myEditorsPosition != null && myEditorsPosition.isSame(myCaretPosition)) {
|
||||
doScrollToVisiblePositions(myEditorsPosition, editors);
|
||||
}
|
||||
else {
|
||||
doScrollToCaret(editors);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
disableSyncScroll(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected abstract List<? extends Editor> getEditors();
|
||||
|
||||
protected abstract void disableSyncScroll(boolean value);
|
||||
}
|
||||
|
||||
public static abstract class TwosideInitialScrollHelper extends SideInitialScrollHelper {
|
||||
@Nullable protected Pair<Side, Integer> myScrollToLine;
|
||||
@Nullable protected DiffNavigationContext myNavigationContext;
|
||||
|
||||
@Override
|
||||
public void processContext(@NotNull DiffRequest request) {
|
||||
super.processContext(request);
|
||||
myScrollToLine = request.getUserData(DiffUserDataKeys.SCROLL_TO_LINE);
|
||||
myNavigationContext = request.getUserData(DiffUserDataKeysEx.NAVIGATION_CONTEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateContext(@NotNull DiffRequest request) {
|
||||
super.updateContext(request);
|
||||
request.putUserData(DiffUserDataKeys.SCROLL_TO_LINE, null);
|
||||
request.putUserData(DiffUserDataKeysEx.NAVIGATION_CONTEXT, null);
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
public void onSlowRediff() {
|
||||
if (wasScrolled(getEditors())) myShouldScroll = false;
|
||||
if (myScrollToChange != null) return;
|
||||
if (myShouldScroll) myShouldScroll = !doScrollToLine();
|
||||
if (myNavigationContext != null) return;
|
||||
if (myShouldScroll) myShouldScroll = !doScrollToPosition();
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
public void onRediff() {
|
||||
if (wasScrolled(getEditors())) myShouldScroll = false;
|
||||
if (myShouldScroll) myShouldScroll = !doScrollToChange();
|
||||
if (myShouldScroll) myShouldScroll = !doScrollToLine();
|
||||
if (myShouldScroll) myShouldScroll = !doScrollToContext();
|
||||
if (myShouldScroll) myShouldScroll = !doScrollToPosition();
|
||||
if (myShouldScroll) doScrollToFirstChange();
|
||||
myShouldScroll = false;
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
protected abstract boolean doScrollToChange();
|
||||
|
||||
@CalledInAwt
|
||||
protected abstract boolean doScrollToFirstChange();
|
||||
|
||||
@CalledInAwt
|
||||
protected abstract boolean doScrollToContext();
|
||||
|
||||
@CalledInAwt
|
||||
protected abstract boolean doScrollToLine();
|
||||
}
|
||||
|
||||
public static abstract class ThreesideInitialScrollHelper extends SideInitialScrollHelper {
|
||||
@Nullable protected Pair<ThreeSide, Integer> myScrollToLine;
|
||||
|
||||
@Override
|
||||
public void processContext(@NotNull DiffRequest request) {
|
||||
super.processContext(request);
|
||||
myScrollToLine = request.getUserData(DiffUserDataKeys.SCROLL_TO_LINE_THREESIDE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateContext(@NotNull DiffRequest request) {
|
||||
super.updateContext(request);
|
||||
request.putUserData(DiffUserDataKeys.SCROLL_TO_LINE_THREESIDE, null);
|
||||
}
|
||||
|
||||
public void onSlowRediff() {
|
||||
if (wasScrolled(getEditors())) myShouldScroll = false;
|
||||
if (myScrollToChange != null) return;
|
||||
if (myShouldScroll) myShouldScroll = !doScrollToLine();
|
||||
if (myShouldScroll) myShouldScroll = !doScrollToPosition();
|
||||
}
|
||||
|
||||
public void onRediff() {
|
||||
if (wasScrolled(getEditors())) myShouldScroll = false;
|
||||
if (myShouldScroll) myShouldScroll = !doScrollToChange();
|
||||
if (myShouldScroll) myShouldScroll = !doScrollToLine();
|
||||
if (myShouldScroll) myShouldScroll = !doScrollToPosition();
|
||||
if (myShouldScroll) doScrollToFirstChange();
|
||||
myShouldScroll = false;
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
protected abstract boolean doScrollToChange();
|
||||
|
||||
@CalledInAwt
|
||||
protected abstract boolean doScrollToFirstChange();
|
||||
|
||||
@CalledInAwt
|
||||
protected abstract boolean doScrollToLine();
|
||||
|
||||
@NotNull
|
||||
protected abstract List<? extends Editor> getEditors();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Point[] doGetScrollingPositions(@NotNull List<? extends Editor> editors) {
|
||||
Point[] carets = new Point[editors.size()];
|
||||
for (int i = 0; i < editors.size(); i++) {
|
||||
carets[i] = DiffUtil.getScrollingPosition(editors.get(i));
|
||||
}
|
||||
return carets;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static LogicalPosition[] doGetCaretPositions(@NotNull List<? extends Editor> editors) {
|
||||
LogicalPosition[] carets = new LogicalPosition[editors.size()];
|
||||
for (int i = 0; i < editors.size(); i++) {
|
||||
carets[i] = DiffUtil.getCaretPosition(editors.get(i));
|
||||
}
|
||||
return carets;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static EditorsVisiblePositions doGetVisiblePositions(@NotNull List<? extends Editor> editors) {
|
||||
LogicalPosition[] carets = doGetCaretPositions(editors);
|
||||
Point[] points = doGetScrollingPositions(editors);
|
||||
return new EditorsVisiblePositions(carets, points);
|
||||
}
|
||||
|
||||
public static void doMoveCaretsToPositions(@NotNull LogicalPosition[] positions, @NotNull List<? extends Editor> editors) {
|
||||
for (int i = 0; i < editors.size(); i++) {
|
||||
Editor editor = editors.get(i);
|
||||
if (editor != null) editor.getCaretModel().moveToLogicalPosition(positions[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void doScrollToVisiblePositions(@NotNull EditorsVisiblePositions visiblePositions,
|
||||
@NotNull List<? extends Editor> editors) {
|
||||
for (int i = 0; i < editors.size(); i++) {
|
||||
Editor editor = editors.get(i);
|
||||
if (editor != null) DiffUtil.scrollToPoint(editor, visiblePositions.myPoints[i], false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void doScrollToCaret(@NotNull List<? extends Editor> editors) {
|
||||
for (int i = 0; i < editors.size(); i++) {
|
||||
Editor editor = editors.get(i);
|
||||
if (editor != null) DiffUtil.scrollToCaret(editor, false);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean wasScrolled(@NotNull List<? extends Editor> editors) {
|
||||
for (Editor editor : editors) {
|
||||
if (editor == null) continue;
|
||||
if (editor.getCaretModel().getOffset() != 0) return true;
|
||||
if (editor.getScrollingModel().getVerticalScrollOffset() != 0) return true;
|
||||
if (editor.getScrollingModel().getHorizontalScrollOffset() != 0) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class EditorsVisiblePositions {
|
||||
public static final Key<EditorsVisiblePositions> KEY = Key.create("Diff.EditorsVisiblePositions");
|
||||
|
||||
@NotNull public final LogicalPosition[] myCaretPosition;
|
||||
@NotNull public final Point[] myPoints;
|
||||
|
||||
public EditorsVisiblePositions(@NotNull LogicalPosition caretPosition, @NotNull Point points) {
|
||||
this(new LogicalPosition[]{caretPosition}, new Point[]{points});
|
||||
}
|
||||
|
||||
public EditorsVisiblePositions(@NotNull LogicalPosition[] caretPosition, @NotNull Point[] points) {
|
||||
myCaretPosition = caretPosition;
|
||||
myPoints = points;
|
||||
}
|
||||
|
||||
public boolean isSame(@Nullable LogicalPosition... caretPosition) {
|
||||
// TODO: allow small fluctuations ?
|
||||
if (caretPosition == null) return true;
|
||||
if (myCaretPosition.length != caretPosition.length) return false;
|
||||
for (int i = 0; i < caretPosition.length; i++) {
|
||||
if (!caretPosition[i].equals(myCaretPosition[i])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -16,9 +16,9 @@
|
||||
package com.intellij.diff.tools.util.base;
|
||||
|
||||
import com.intellij.diff.DiffContext;
|
||||
import com.intellij.diff.contents.BinaryFileContent;
|
||||
import com.intellij.diff.contents.DiffContent;
|
||||
import com.intellij.diff.contents.DocumentContent;
|
||||
import com.intellij.diff.contents.FileContent;
|
||||
import com.intellij.diff.requests.ContentDiffRequest;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.event.DocumentAdapter;
|
||||
@@ -79,8 +79,8 @@ public abstract class ListenerDiffViewerBase extends DiffViewerBase {
|
||||
protected VirtualFileListener createFileListener(@NotNull ContentDiffRequest request) {
|
||||
final List<VirtualFile> files = new ArrayList<VirtualFile>(0);
|
||||
for (DiffContent content : request.getContents()) {
|
||||
if (content instanceof BinaryFileContent) {
|
||||
files.add(((BinaryFileContent)content).getFile());
|
||||
if (content instanceof FileContent && !(content instanceof DocumentContent)) {
|
||||
files.add(((FileContent)content).getFile());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.diff.tools.util.threeside;
|
||||
|
||||
import com.intellij.diff.DiffContext;
|
||||
import com.intellij.diff.tools.util.EditorsDiffPanelBase;
|
||||
import com.intellij.openapi.actionSystem.DataProvider;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class ThreesideTextDiffPanel extends EditorsDiffPanelBase {
|
||||
@NotNull private final ThreesideTextDiffViewer myViewer;
|
||||
|
||||
public ThreesideTextDiffPanel(@NotNull ThreesideTextDiffViewer viewer,
|
||||
@NotNull ThreesideTextContentPanel editorPanel,
|
||||
@NotNull DataProvider dataProvider,
|
||||
@NotNull DiffContext context) {
|
||||
super(editorPanel, dataProvider, context);
|
||||
myViewer = viewer;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected JComponent getCurrentEditor() {
|
||||
return myViewer.getCurrentEditor().getContentComponent();
|
||||
}
|
||||
}
|
||||
+23
-128
@@ -24,12 +24,15 @@ import com.intellij.diff.requests.ContentDiffRequest;
|
||||
import com.intellij.diff.requests.DiffRequest;
|
||||
import com.intellij.diff.requests.SimpleDiffRequest;
|
||||
import com.intellij.diff.tools.util.DiffDataKeys;
|
||||
import com.intellij.diff.tools.util.SimpleDiffPanel;
|
||||
import com.intellij.diff.tools.util.SyncScrollSupport;
|
||||
import com.intellij.diff.tools.util.SyncScrollSupport.ThreesideSyncScrollSupport;
|
||||
import com.intellij.diff.tools.util.base.InitialScrollPositionSupport;
|
||||
import com.intellij.diff.tools.util.base.TextDiffViewerBase;
|
||||
import com.intellij.diff.util.*;
|
||||
import com.intellij.diff.util.DiffUserDataKeysEx.ScrollToPolicy;
|
||||
import com.intellij.diff.util.DiffUtil.EditorsVisiblePositions;
|
||||
import com.intellij.diff.util.DiffUserDataKeys;
|
||||
import com.intellij.diff.util.DiffUtil;
|
||||
import com.intellij.diff.util.Side;
|
||||
import com.intellij.diff.util.ThreeSide;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
@@ -37,7 +40,6 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.DiffBundle;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.LogicalPosition;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.editor.event.VisibleAreaEvent;
|
||||
import com.intellij.openapi.editor.event.VisibleAreaListener;
|
||||
@@ -45,7 +47,6 @@ import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.ex.EditorMarkupModel;
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.CalledInAwt;
|
||||
@@ -54,7 +55,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.util.ArrayList;
|
||||
@@ -65,7 +65,7 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase {
|
||||
|
||||
@NotNull private final EditorFactory myEditorFactory = EditorFactory.getInstance();
|
||||
|
||||
@NotNull protected final ThreesideTextDiffPanel myPanel;
|
||||
@NotNull protected final SimpleDiffPanel myPanel;
|
||||
@NotNull protected final ThreesideTextContentPanel myContentPanel;
|
||||
|
||||
@NotNull protected final List<EditorEx> myEditors;
|
||||
@@ -81,8 +81,6 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase {
|
||||
|
||||
@NotNull protected final MySetEditorSettingsAction myEditorSettingsAction;
|
||||
|
||||
@NotNull private final MyScrollToLineHelper myScrollToLineHelper = new MyScrollToLineHelper();
|
||||
|
||||
@Nullable private ThreesideSyncScrollSupport mySyncScrollListener;
|
||||
|
||||
@NotNull private ThreeSide myCurrentSide;
|
||||
@@ -103,7 +101,7 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase {
|
||||
|
||||
myContentPanel = new ThreesideTextContentPanel(myEditors, titlePanel);
|
||||
|
||||
myPanel = new ThreesideTextDiffPanel(this, myContentPanel, this, context);
|
||||
myPanel = new SimpleDiffPanel(myContentPanel, this, context);
|
||||
|
||||
|
||||
//new MyFocusOppositePaneAction().setupAction(myPanel, this); // TODO
|
||||
@@ -133,14 +131,10 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase {
|
||||
protected void processContextHints() {
|
||||
ThreeSide side = myContext.getUserData(DiffUserDataKeys.PREFERRED_FOCUS_THREESIDE);
|
||||
if (side != null) myCurrentSide = side;
|
||||
|
||||
myScrollToLineHelper.processContext();
|
||||
}
|
||||
|
||||
protected void updateContextHints() {
|
||||
myContext.putUserData(DiffUserDataKeys.PREFERRED_FOCUS_THREESIDE, myCurrentSide);
|
||||
|
||||
myScrollToLineHelper.updateContext();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -211,14 +205,12 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase {
|
||||
myEditors.get(1).getScrollingModel().removeVisibleAreaListener(myVisibleAreaListener2);
|
||||
myEditors.get(2).getScrollingModel().removeVisibleAreaListener(myVisibleAreaListener2);
|
||||
|
||||
if (mySyncScrollListener != null) {
|
||||
mySyncScrollListener = null;
|
||||
}
|
||||
mySyncScrollListener = null;
|
||||
}
|
||||
|
||||
protected void disableSyncScrollSupport(boolean disable) {
|
||||
if (mySyncScrollListener != null) {
|
||||
mySyncScrollListener.myDuringSyncScroll = disable;
|
||||
mySyncScrollListener.setDisabled(disable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,17 +225,6 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase {
|
||||
myContentPanel.repaintDividers();
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
protected void scrollOnRediff() {
|
||||
myScrollToLineHelper.onRediff();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSlowRediff() {
|
||||
super.onSlowRediff();
|
||||
myScrollToLineHelper.onSlowRediff();
|
||||
}
|
||||
|
||||
//
|
||||
// Getters
|
||||
//
|
||||
@@ -257,7 +238,7 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase {
|
||||
@Nullable
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myPanel.getPreferredFocusedComponent();
|
||||
return getCurrentEditor().getContentComponent();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -292,11 +273,6 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase {
|
||||
myCurrentSide = side;
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
protected boolean doScrollToChange(@NotNull ScrollToPolicy scrollToChangePolicy) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected abstract SyncScrollSupport.SyncScrollable getSyncScrollable(@NotNull Side side);
|
||||
|
||||
@@ -304,11 +280,6 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase {
|
||||
// Misc
|
||||
//
|
||||
|
||||
@Override
|
||||
protected boolean tryRediffSynchronously() {
|
||||
return myPanel.isWindowFocused();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected OpenFileDescriptor getOpenFileDescriptor() {
|
||||
@@ -407,15 +378,6 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase {
|
||||
return super.getData(dataId);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Graphics2D getDividerGraphics(@NotNull Graphics g, @NotNull Component divider) {
|
||||
int width = divider.getWidth();
|
||||
int editorHeight = myEditors.get(0).getComponent().getHeight();
|
||||
int dividerOffset = divider.getLocationOnScreen().y;
|
||||
int editorOffset = myEditors.get(0).getComponent().getLocationOnScreen().y;
|
||||
return (Graphics2D)g.create(0, editorOffset - dividerOffset, width, editorHeight);
|
||||
}
|
||||
|
||||
private class MyEditorFocusListener extends FocusAdapter {
|
||||
@NotNull private final ThreeSide mySide;
|
||||
|
||||
@@ -447,93 +409,26 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase {
|
||||
}
|
||||
}
|
||||
|
||||
private class MyScrollToLineHelper {
|
||||
protected boolean myShouldScroll = true;
|
||||
|
||||
@Nullable private ScrollToPolicy myScrollToChange;
|
||||
@Nullable private EditorsVisiblePositions myEditorsPosition;
|
||||
@Nullable private LogicalPosition[] myCaretPosition;
|
||||
@Nullable private Pair<ThreeSide, Integer> myScrollToLine;
|
||||
|
||||
public void processContext() {
|
||||
myScrollToChange = myRequest.getUserData(DiffUserDataKeysEx.SCROLL_TO_CHANGE);
|
||||
myEditorsPosition = myRequest.getUserData(EditorsVisiblePositions.KEY);
|
||||
myCaretPosition = myRequest.getUserData(DiffUserDataKeysEx.EDITORS_CARET_POSITION);
|
||||
myScrollToLine = myRequest.getUserData(DiffUserDataKeys.SCROLL_TO_LINE_THREESIDE);
|
||||
protected abstract class MyInitialScrollPositionHelper extends InitialScrollPositionSupport.ThreesideInitialScrollHelper {
|
||||
@NotNull
|
||||
@Override
|
||||
protected List<? extends Editor> getEditors() {
|
||||
return ThreesideTextDiffViewer.this.getEditors();
|
||||
}
|
||||
|
||||
public void updateContext() {
|
||||
LogicalPosition[] carets = DiffUtil.getCaretPositions(myEditors);
|
||||
Point[] points = DiffUtil.getScrollingPositions(myEditors);
|
||||
|
||||
EditorsVisiblePositions editorsPosition = new EditorsVisiblePositions(carets, points);
|
||||
|
||||
myRequest.putUserData(DiffUserDataKeysEx.SCROLL_TO_CHANGE, null);
|
||||
myRequest.putUserData(EditorsVisiblePositions.KEY, editorsPosition);
|
||||
myRequest.putUserData(DiffUserDataKeysEx.EDITORS_CARET_POSITION, carets);
|
||||
myRequest.putUserData(DiffUserDataKeys.SCROLL_TO_LINE_THREESIDE, null);
|
||||
@Override
|
||||
protected void disableSyncScroll(boolean value) {
|
||||
disableSyncScrollSupport(value);
|
||||
}
|
||||
|
||||
public void onSlowRediff() {
|
||||
if (myScrollToChange != null) return;
|
||||
if (myShouldScroll && myScrollToLine != null) {
|
||||
myShouldScroll = !doScrollToLine();
|
||||
}
|
||||
if (myShouldScroll && myCaretPosition != null) {
|
||||
myShouldScroll = !doScrollToPosition();
|
||||
}
|
||||
}
|
||||
|
||||
public void onRediff() {
|
||||
if (DiffUtil.wasScrolled(getEditors())) myShouldScroll = false;
|
||||
if (myShouldScroll && myScrollToChange != null) {
|
||||
myShouldScroll = !doScrollToChange(myScrollToChange);
|
||||
}
|
||||
if (myShouldScroll && myScrollToLine != null) {
|
||||
myShouldScroll = !doScrollToLine();
|
||||
}
|
||||
if (myShouldScroll && myCaretPosition != null) {
|
||||
myShouldScroll = !doScrollToPosition();
|
||||
}
|
||||
if (myShouldScroll) {
|
||||
doScrollToChange(ScrollToPolicy.FIRST_CHANGE);
|
||||
}
|
||||
myShouldScroll = false;
|
||||
}
|
||||
|
||||
private boolean doScrollToPosition() {
|
||||
if (myCaretPosition == null || myCaretPosition.length != 3) return false;
|
||||
|
||||
myEditors.get(0).getCaretModel().moveToLogicalPosition(myCaretPosition[0]);
|
||||
myEditors.get(1).getCaretModel().moveToLogicalPosition(myCaretPosition[1]);
|
||||
myEditors.get(2).getCaretModel().moveToLogicalPosition(myCaretPosition[2]);
|
||||
|
||||
if (myEditorsPosition != null && myEditorsPosition.isSame(myCaretPosition)) {
|
||||
try {
|
||||
disableSyncScrollSupport(true);
|
||||
|
||||
DiffUtil.scrollToPoint(myEditors.get(0), myEditorsPosition.myPoints[0]);
|
||||
DiffUtil.scrollToPoint(myEditors.get(1), myEditorsPosition.myPoints[1]);
|
||||
DiffUtil.scrollToPoint(myEditors.get(2), myEditorsPosition.myPoints[2]);
|
||||
}
|
||||
finally {
|
||||
disableSyncScrollSupport(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
DiffUtil.scrollToCaret(getCurrentEditor(), false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean doScrollToLine() {
|
||||
@Override
|
||||
protected boolean doScrollToLine() {
|
||||
if (myScrollToLine == null) return false;
|
||||
ThreeSide side = myScrollToLine.first;
|
||||
Integer line = myScrollToLine.second;
|
||||
if (side.select(myEditors) == null) return false;
|
||||
if (side.select(getEditors()) == null) return false;
|
||||
|
||||
myCurrentSide = side;
|
||||
DiffUtil.scrollEditor(getCurrentEditor(), line, false);
|
||||
scrollToLine(side, line);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.diff.tools.util.twoside;
|
||||
|
||||
import com.intellij.diff.DiffContext;
|
||||
import com.intellij.diff.tools.util.EditorsDiffPanelBase;
|
||||
import com.intellij.openapi.actionSystem.DataProvider;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class TwosideTextDiffPanel extends EditorsDiffPanelBase {
|
||||
@NotNull private final TwosideTextDiffViewer myViewer;
|
||||
|
||||
public TwosideTextDiffPanel(@NotNull TwosideTextDiffViewer viewer,
|
||||
@NotNull TwosideTextContentPanel content,
|
||||
@NotNull DataProvider dataProvider,
|
||||
@NotNull DiffContext context) {
|
||||
super(content, dataProvider, context);
|
||||
myViewer = viewer;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected JComponent getCurrentEditor() {
|
||||
return myViewer.getCurrentEditor().getContentComponent();
|
||||
}
|
||||
}
|
||||
+19
-144
@@ -21,23 +21,20 @@ import com.intellij.diff.actions.impl.OpenInEditorWithMouseAction;
|
||||
import com.intellij.diff.contents.DiffContent;
|
||||
import com.intellij.diff.contents.DocumentContent;
|
||||
import com.intellij.diff.contents.EmptyContent;
|
||||
import com.intellij.diff.contents.FileContent;
|
||||
import com.intellij.diff.requests.ContentDiffRequest;
|
||||
import com.intellij.diff.requests.DiffRequest;
|
||||
import com.intellij.diff.tools.util.DiffDataKeys;
|
||||
import com.intellij.diff.tools.util.SimpleDiffPanel;
|
||||
import com.intellij.diff.tools.util.SyncScrollSupport;
|
||||
import com.intellij.diff.tools.util.SyncScrollSupport.TwosideSyncScrollSupport;
|
||||
import com.intellij.diff.tools.util.base.InitialScrollPositionSupport;
|
||||
import com.intellij.diff.tools.util.base.TextDiffViewerBase;
|
||||
import com.intellij.diff.util.DiffUserDataKeys;
|
||||
import com.intellij.diff.util.DiffUserDataKeysEx;
|
||||
import com.intellij.diff.util.DiffUserDataKeysEx.ScrollToPolicy;
|
||||
import com.intellij.diff.util.DiffUtil;
|
||||
import com.intellij.diff.util.DiffUtil.EditorsVisiblePositions;
|
||||
import com.intellij.diff.util.Side;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.DiffNavigationContext;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.LogicalPosition;
|
||||
@@ -47,7 +44,6 @@ import com.intellij.openapi.editor.event.VisibleAreaEvent;
|
||||
import com.intellij.openapi.editor.event.VisibleAreaListener;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.CalledInAwt;
|
||||
@@ -56,7 +52,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.util.Collections;
|
||||
@@ -67,7 +62,7 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
|
||||
|
||||
@NotNull private final EditorFactory myEditorFactory = EditorFactory.getInstance();
|
||||
|
||||
@NotNull protected final TwosideTextDiffPanel myPanel;
|
||||
@NotNull protected final SimpleDiffPanel myPanel;
|
||||
@NotNull protected final TwosideTextContentPanel myContentPanel;
|
||||
|
||||
@Nullable protected final EditorEx myEditor1;
|
||||
@@ -82,8 +77,6 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
|
||||
@NotNull private final MyEditorFocusListener myEditorFocusListener2 = new MyEditorFocusListener(Side.RIGHT);
|
||||
@NotNull private final MyVisibleAreaListener myVisibleAreaListener = new MyVisibleAreaListener();
|
||||
|
||||
@NotNull private final MyScrollToLineHelper myScrollToLineHelper = new MyScrollToLineHelper();
|
||||
|
||||
@Nullable protected TwosideSyncScrollSupport mySyncScrollSupport;
|
||||
|
||||
@NotNull private Side myCurrentSide;
|
||||
@@ -108,7 +101,7 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
|
||||
|
||||
myContentPanel = new TwosideTextContentPanel(titlePanel, myEditor1, myEditor2);
|
||||
|
||||
myPanel = new TwosideTextDiffPanel(this, myContentPanel, this, context);
|
||||
myPanel = new SimpleDiffPanel(myContentPanel, this, context);
|
||||
|
||||
|
||||
new MyFocusOppositePaneAction(true).setupAction(myPanel);
|
||||
@@ -149,16 +142,12 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
|
||||
Side side = myContext.getUserData(DiffUserDataKeys.PREFERRED_FOCUS_SIDE);
|
||||
if (side != null) myCurrentSide = side;
|
||||
}
|
||||
|
||||
myScrollToLineHelper.processContext();
|
||||
}
|
||||
|
||||
protected void updateContextHints() {
|
||||
if (myEditor1 != null && myEditor2 != null) {
|
||||
myContext.putUserData(DiffUserDataKeys.PREFERRED_FOCUS_SIDE, myCurrentSide);
|
||||
}
|
||||
|
||||
myScrollToLineHelper.updateContext();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -197,17 +186,6 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
|
||||
myContentPanel.repaintDivider();
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
protected void scrollOnRediff() {
|
||||
myScrollToLineHelper.onRediff();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSlowRediff() {
|
||||
super.onSlowRediff();
|
||||
myScrollToLineHelper.onSlowRediff();
|
||||
}
|
||||
|
||||
//
|
||||
// Listeners
|
||||
//
|
||||
@@ -249,16 +227,12 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
|
||||
myEditor2.getContentComponent().removeFocusListener(myEditorFocusListener2);
|
||||
myEditor2.getScrollingModel().removeVisibleAreaListener(myVisibleAreaListener);
|
||||
}
|
||||
if (myEditor1 != null && myEditor2 != null) {
|
||||
if (mySyncScrollSupport != null) {
|
||||
mySyncScrollSupport = null;
|
||||
}
|
||||
}
|
||||
mySyncScrollSupport = null;
|
||||
}
|
||||
|
||||
protected void disableSyncScrollSupport(boolean disable) {
|
||||
if (mySyncScrollSupport != null) {
|
||||
mySyncScrollSupport.myDuringSyncScroll = disable;
|
||||
mySyncScrollSupport.setDisabled(disable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,7 +264,7 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
|
||||
@Nullable
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myPanel.getPreferredFocusedComponent();
|
||||
return getCurrentEditor().getContentComponent();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -340,16 +314,6 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
|
||||
myCurrentSide = side;
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
protected boolean doScrollToChange(@NotNull ScrollToPolicy scrollToChangePolicy) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@CalledInAwt
|
||||
protected boolean doScrollToContext(@NotNull DiffNavigationContext context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected abstract SyncScrollSupport.SyncScrollable getSyncScrollable();
|
||||
|
||||
@@ -357,11 +321,6 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
|
||||
// Misc
|
||||
//
|
||||
|
||||
@Override
|
||||
protected boolean tryRediffSynchronously() {
|
||||
return myPanel.isWindowFocused();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected OpenFileDescriptor getOpenFileDescriptor() {
|
||||
@@ -458,17 +417,6 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
|
||||
return super.getData(dataId);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Graphics2D getDividerGraphics(@NotNull Graphics g, @NotNull Component divider) {
|
||||
assert myEditor1 != null && myEditor2 != null;
|
||||
|
||||
int width = divider.getWidth();
|
||||
int editorHeight = myEditor1.getComponent().getHeight();
|
||||
int dividerOffset = divider.getLocationOnScreen().y;
|
||||
int editorOffset = myEditor1.getComponent().getLocationOnScreen().y;
|
||||
return (Graphics2D)g.create(0, editorOffset - dividerOffset, width, editorHeight);
|
||||
}
|
||||
|
||||
private class MyEditorFocusListener extends FocusAdapter {
|
||||
@NotNull private final Side mySide;
|
||||
|
||||
@@ -495,99 +443,26 @@ public abstract class TwosideTextDiffViewer extends TextDiffViewerBase {
|
||||
}
|
||||
}
|
||||
|
||||
private class MyScrollToLineHelper {
|
||||
protected boolean myShouldScroll = true;
|
||||
|
||||
@Nullable private ScrollToPolicy myScrollToChange;
|
||||
@Nullable private EditorsVisiblePositions myEditorsPosition;
|
||||
@Nullable private LogicalPosition[] myCaretPosition;
|
||||
@Nullable private Pair<Side, Integer> myScrollToLine;
|
||||
@Nullable private DiffNavigationContext myNavigationContext;
|
||||
|
||||
public void processContext() {
|
||||
myScrollToChange = myRequest.getUserData(DiffUserDataKeysEx.SCROLL_TO_CHANGE);
|
||||
myEditorsPosition = myRequest.getUserData(EditorsVisiblePositions.KEY);
|
||||
myCaretPosition = myRequest.getUserData(DiffUserDataKeysEx.EDITORS_CARET_POSITION);
|
||||
myScrollToLine = myRequest.getUserData(DiffUserDataKeys.SCROLL_TO_LINE);
|
||||
myNavigationContext = myRequest.getUserData(DiffUserDataKeysEx.NAVIGATION_CONTEXT);
|
||||
protected abstract class MyInitialScrollPositionHelper extends InitialScrollPositionSupport.TwosideInitialScrollHelper {
|
||||
@NotNull
|
||||
@Override
|
||||
protected List<? extends Editor> getEditors() {
|
||||
return TwosideTextDiffViewer.this.getEditors();
|
||||
}
|
||||
|
||||
public void updateContext() {
|
||||
List<EditorEx> allEditors = ContainerUtil.list(myEditor1, myEditor2); // we want all editors, not only NotNull ones
|
||||
LogicalPosition[] carets = DiffUtil.getCaretPositions(allEditors);
|
||||
Point[] points = DiffUtil.getScrollingPositions(allEditors);
|
||||
|
||||
EditorsVisiblePositions editorsPosition = new EditorsVisiblePositions(carets, points);
|
||||
|
||||
myRequest.putUserData(DiffUserDataKeysEx.SCROLL_TO_CHANGE, null);
|
||||
myRequest.putUserData(EditorsVisiblePositions.KEY, editorsPosition);
|
||||
myRequest.putUserData(DiffUserDataKeysEx.EDITORS_CARET_POSITION, carets);
|
||||
myRequest.putUserData(DiffUserDataKeys.SCROLL_TO_LINE, null);
|
||||
myRequest.putUserData(DiffUserDataKeysEx.NAVIGATION_CONTEXT, null);
|
||||
@Override
|
||||
protected void disableSyncScroll(boolean value) {
|
||||
disableSyncScrollSupport(value);
|
||||
}
|
||||
|
||||
public void onSlowRediff() {
|
||||
if (myScrollToChange != null) return;
|
||||
if (myNavigationContext != null) return;
|
||||
if (myShouldScroll && myScrollToLine != null) {
|
||||
myShouldScroll = !doScrollToLine();
|
||||
}
|
||||
if (myShouldScroll && myCaretPosition != null) {
|
||||
myShouldScroll = !doScrollToPosition(); // TODO: discard Point in this case, scroll to caret ?
|
||||
}
|
||||
}
|
||||
|
||||
public void onRediff() {
|
||||
if (DiffUtil.wasScrolled(getEditors())) myShouldScroll = false;
|
||||
if (myShouldScroll && myScrollToChange != null) {
|
||||
myShouldScroll = !doScrollToChange(myScrollToChange);
|
||||
}
|
||||
if (myShouldScroll && myScrollToLine != null) {
|
||||
myShouldScroll = !doScrollToLine();
|
||||
}
|
||||
if (myShouldScroll && myNavigationContext != null) {
|
||||
myShouldScroll = !doScrollToContext(myNavigationContext);
|
||||
}
|
||||
if (myShouldScroll && myCaretPosition != null) {
|
||||
myShouldScroll = !doScrollToPosition();
|
||||
}
|
||||
if (myShouldScroll) {
|
||||
doScrollToChange(ScrollToPolicy.FIRST_CHANGE);
|
||||
}
|
||||
myShouldScroll = false;
|
||||
}
|
||||
|
||||
private boolean doScrollToPosition() {
|
||||
if (myCaretPosition == null || myCaretPosition.length != 2) return false;
|
||||
|
||||
if (myEditor1 != null) myEditor1.getCaretModel().moveToLogicalPosition(myCaretPosition[0]);
|
||||
if (myEditor2 != null) myEditor2.getCaretModel().moveToLogicalPosition(myCaretPosition[1]);
|
||||
|
||||
if (myEditorsPosition != null && myEditorsPosition.isSame(myCaretPosition)) {
|
||||
try {
|
||||
disableSyncScrollSupport(true);
|
||||
|
||||
DiffUtil.scrollToPoint(myEditor1, myEditorsPosition.myPoints[0]);
|
||||
DiffUtil.scrollToPoint(myEditor2, myEditorsPosition.myPoints[1]);
|
||||
}
|
||||
finally {
|
||||
disableSyncScrollSupport(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
DiffUtil.scrollToCaret(getCurrentEditor(), false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean doScrollToLine() {
|
||||
@Override
|
||||
protected boolean doScrollToLine() {
|
||||
if (myScrollToLine == null) return false;
|
||||
Side side = myScrollToLine.first;
|
||||
Integer line = myScrollToLine.second;
|
||||
if (side.select(myEditor1, myEditor2) == null) return false;
|
||||
if (side.select(getEditors()) == null) return false;
|
||||
|
||||
myCurrentSide = side;
|
||||
DiffUtil.scrollEditor(getCurrentEditor(), line, false);
|
||||
scrollToLine(side, line);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,19 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DiffDividerDrawUtil {
|
||||
|
||||
/*
|
||||
* Clip given graphics of divider component such that result graphics is aligned with base component by 'y' coordinate.
|
||||
*/
|
||||
@NotNull
|
||||
public static Graphics2D getDividerGraphics(@NotNull Graphics g, @NotNull Component divider, @NotNull Component base) {
|
||||
int width = divider.getWidth();
|
||||
int editorHeight = base.getHeight();
|
||||
int dividerOffset = divider.getLocationOnScreen().y;
|
||||
int editorOffset = base.getLocationOnScreen().y;
|
||||
return (Graphics2D)g.create(0, editorOffset - dividerOffset, width, editorHeight);
|
||||
}
|
||||
|
||||
public static void paintSeparators(@NotNull Graphics2D gg,
|
||||
int width,
|
||||
@NotNull Editor editor1,
|
||||
|
||||
@@ -248,61 +248,6 @@ public class DiffUtil {
|
||||
return editor != null ? editor.getCaretModel().getLogicalPosition() : new LogicalPosition(0, 0);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Point[] getScrollingPositions(@NotNull List<? extends Editor> editors) {
|
||||
Point[] carets = new Point[editors.size()];
|
||||
for (int i = 0; i < editors.size(); i++) {
|
||||
carets[i] = getScrollingPosition(editors.get(i));
|
||||
}
|
||||
return carets;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static LogicalPosition[] getCaretPositions(@NotNull List<? extends Editor> editors) {
|
||||
LogicalPosition[] carets = new LogicalPosition[editors.size()];
|
||||
for (int i = 0; i < editors.size(); i++) {
|
||||
carets[i] = getCaretPosition(editors.get(i));
|
||||
}
|
||||
return carets;
|
||||
}
|
||||
|
||||
public static boolean wasScrolled(@NotNull List<? extends Editor> editors) {
|
||||
for (Editor editor : editors) {
|
||||
if (editor == null) continue;
|
||||
if (editor.getCaretModel().getOffset() != 0) return true;
|
||||
if (editor.getScrollingModel().getVerticalScrollOffset() != 0) return true;
|
||||
if (editor.getScrollingModel().getHorizontalScrollOffset() != 0) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class EditorsVisiblePositions {
|
||||
public static final Key<EditorsVisiblePositions> KEY = Key.create("Diff.EditorsVisiblePositions");
|
||||
|
||||
@NotNull public final LogicalPosition[] myCaretPosition;
|
||||
@NotNull public final Point[] myPoints;
|
||||
|
||||
public EditorsVisiblePositions(@NotNull LogicalPosition caretPosition, @NotNull Point points) {
|
||||
myCaretPosition = new LogicalPosition[]{caretPosition};
|
||||
myPoints = new Point[]{points};
|
||||
}
|
||||
|
||||
public EditorsVisiblePositions(@NotNull LogicalPosition[] caretPosition, @NotNull Point[] points) {
|
||||
myCaretPosition = caretPosition;
|
||||
myPoints = points;
|
||||
}
|
||||
|
||||
public boolean isSame(@Nullable LogicalPosition... caretPosition) {
|
||||
// TODO: allow small fluctuations ?
|
||||
if (caretPosition == null) return true;
|
||||
if (myCaretPosition.length != caretPosition.length) return false;
|
||||
for (int i = 0; i < caretPosition.length; i++) {
|
||||
if (!caretPosition[i].equals(myCaretPosition[i])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// UI
|
||||
//
|
||||
|
||||
@@ -54,7 +54,7 @@ public class EditorTracker extends AbstractProjectComponent {
|
||||
private final Map<Window, List<Editor>> myWindowToEditorsMap = new HashMap<Window, List<Editor>>();
|
||||
private final Map<Window, WindowFocusListener> myWindowToWindowFocusListenerMap = new HashMap<Window, WindowFocusListener>();
|
||||
private final Map<Editor, Window> myEditorToWindowMap = new HashMap<Editor, Window>();
|
||||
private List<Editor> myActiveEditors = Collections.emptyList();
|
||||
private List<Editor> myActiveEditors = Collections.emptyList(); // accessed in EDT only
|
||||
|
||||
private final EventDispatcher<EditorTrackerListener> myDispatcher = EventDispatcher.create(EditorTrackerListener.class);
|
||||
|
||||
@@ -186,7 +186,8 @@ public class EditorTracker extends AbstractProjectComponent {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<Editor> getActiveEditors() {
|
||||
List<Editor> getActiveEditors() {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
return myActiveEditors;
|
||||
}
|
||||
|
||||
@@ -210,6 +211,7 @@ public class EditorTracker extends AbstractProjectComponent {
|
||||
}
|
||||
|
||||
void setActiveEditors(@NotNull List<Editor> editors) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
myActiveEditors = editors;
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
|
||||
@@ -479,6 +479,17 @@ public abstract class UsefulTestCase extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public static void assertOrderedEquals(@NotNull int[] actual, @NotNull int[] expected) {
|
||||
if (actual.length != expected.length) {
|
||||
fail("Expected size: "+expected.length+"; actual: "+actual.length+"\nexpected: "+Arrays.toString(expected)+"\nactual : "+Arrays.toString(actual));
|
||||
}
|
||||
for (int i = 0; i < actual.length; i++) {
|
||||
int a = actual[i];
|
||||
int e = expected[i];
|
||||
assertEquals("not equals at index: "+i, e, a);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> void assertOrderedEquals(final String errorMsg, @NotNull Iterable<T> actual, @NotNull T... expected) {
|
||||
Assert.assertNotNull(actual);
|
||||
Assert.assertNotNull(expected);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -98,6 +98,22 @@ public class ArrayUtil extends ArrayUtilRt {
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Contract(pure=true)
|
||||
public static long[] realloc(@NotNull long[] array, int newSize) {
|
||||
if (newSize == 0) {
|
||||
return EMPTY_LONG_ARRAY;
|
||||
}
|
||||
|
||||
final int oldSize = array.length;
|
||||
if (oldSize == newSize) {
|
||||
return array;
|
||||
}
|
||||
|
||||
long[] result = new long[newSize];
|
||||
System.arraycopy(array, 0, result, 0, Math.min(oldSize, newSize));
|
||||
return result;
|
||||
}
|
||||
@NotNull
|
||||
@Contract(pure=true)
|
||||
public static int[] realloc(@NotNull int[] array, final int newSize) {
|
||||
@@ -131,6 +147,13 @@ public class ArrayUtil extends ArrayUtilRt {
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Contract(pure=true)
|
||||
public static long[] append(@NotNull long[] array, long value) {
|
||||
array = realloc(array, array.length + 1);
|
||||
array[array.length - 1] = value;
|
||||
return array;
|
||||
}
|
||||
@NotNull
|
||||
@Contract(pure=true)
|
||||
public static int[] append(@NotNull int[] array, int value) {
|
||||
@@ -720,6 +743,14 @@ public class ArrayUtil extends ArrayUtilRt {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Contract(pure=true)
|
||||
public static int indexOf(@NotNull long[] ints, long value) {
|
||||
for (int i = 0; i < ints.length; i++) {
|
||||
if (ints[i] == value) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
@Contract(pure=true)
|
||||
public static int indexOf(@NotNull int[] ints, int value) {
|
||||
for (int i = 0; i < ints.length; i++) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.util;
|
||||
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.SingletonIterator;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -30,15 +29,9 @@ import java.util.Set;
|
||||
*/
|
||||
public class SingletonSet<E> implements Set<E> {
|
||||
private final E theElement;
|
||||
@NotNull private final TObjectHashingStrategy<E> strategy;
|
||||
|
||||
public SingletonSet(E e) {
|
||||
this(e, ContainerUtil.<E>canonicalStrategy());
|
||||
}
|
||||
|
||||
public SingletonSet(E e, @NotNull final TObjectHashingStrategy<E> strategy) {
|
||||
theElement = e;
|
||||
this.strategy = strategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,7 +41,8 @@ public class SingletonSet<E> implements Set<E> {
|
||||
|
||||
@Override
|
||||
public boolean contains(Object elem) {
|
||||
return strategy.equals(theElement, (E)elem);
|
||||
//noinspection unchecked
|
||||
return getStrategy().equals(theElement, (E)elem);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -67,8 +61,10 @@ public class SingletonSet<E> implements Set<E> {
|
||||
@Override
|
||||
public <T> T[] toArray(@NotNull T[] a) {
|
||||
if (a.length == 0) {
|
||||
//noinspection unchecked
|
||||
a = (T[]) Array.newInstance(a.getClass().getComponentType(), 1);
|
||||
}
|
||||
//noinspection unchecked
|
||||
a[0] = (T)theElement;
|
||||
if (a.length > 1) {
|
||||
a[1] = null;
|
||||
@@ -120,4 +116,31 @@ public class SingletonSet<E> implements Set<E> {
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected TObjectHashingStrategy<E> getStrategy() {
|
||||
//noinspection unchecked
|
||||
return TObjectHashingStrategy.CANONICAL;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <T> Set<T> withCustomStrategy(T o, @NotNull TObjectHashingStrategy<T> strategy) {
|
||||
return new CustomStrategySingletonSet<T>(o, strategy);
|
||||
}
|
||||
|
||||
private static class CustomStrategySingletonSet<E> extends SingletonSet<E> {
|
||||
@NotNull private final TObjectHashingStrategy<E> strategy;
|
||||
|
||||
private CustomStrategySingletonSet(E e, @NotNull final TObjectHashingStrategy<E> strategy) {
|
||||
super(e);
|
||||
this.strategy = strategy;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected TObjectHashingStrategy<E> getStrategy() {
|
||||
return strategy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2101,7 +2101,7 @@ public class ContainerUtil extends ContainerUtilRt {
|
||||
@NotNull
|
||||
@Contract(pure=true)
|
||||
public static <T> Set<T> singleton(final T o, @NotNull final TObjectHashingStrategy<T> strategy) {
|
||||
return new SingletonSet<T>(o, strategy);
|
||||
return strategy == TObjectHashingStrategy.CANONICAL ? new SingletonSet<T>(o) : SingletonSet.<T>withCustomStrategy(o, strategy);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
package com.intellij.util.containers;
|
||||
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.testFramework.PlatformTestUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ThrowableRunnable;
|
||||
import gnu.trove.TIntArrayList;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
@@ -225,17 +227,21 @@ public class ContainerUtilTest extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testLockFreeCOWPerformanceIsAdequateForRegisteringAllIElementTypesReasonablyQuick() {
|
||||
List<Object> my = ContainerUtil.createLockFreeCopyOnWriteList();
|
||||
long start = System.currentTimeMillis();
|
||||
// see IElementType.ourRegistry
|
||||
for (int i = 0; i < 15000; i++) {
|
||||
my.add(i);
|
||||
assertEquals(i, my.indexOf(i));
|
||||
}
|
||||
long elapsed = System.currentTimeMillis() - start;
|
||||
System.out.println("elapsed = " + elapsed);
|
||||
assertTrue(String.valueOf(elapsed), elapsed < 1000);
|
||||
public void testCOWListPerformanceIsAdequateForRegisteringAllIElementTypesReasonablyQuick() {
|
||||
PlatformTestUtil.startPerformanceTest("COWList add", 1000, new ThrowableRunnable() {
|
||||
@Override
|
||||
public void run() throws Throwable {
|
||||
List<Object> my = ContainerUtil.createLockFreeCopyOnWriteList();
|
||||
long start = System.currentTimeMillis();
|
||||
// see IElementType.ourRegistry
|
||||
for (int i = 0; i < 15000; i++) {
|
||||
my.add(i);
|
||||
assertEquals(i, my.indexOf(i));
|
||||
}
|
||||
long elapsed = System.currentTimeMillis() - start;
|
||||
System.out.println("elapsed = " + elapsed);
|
||||
}
|
||||
}).assertTiming();
|
||||
}
|
||||
|
||||
private static void assertReallyEmpty(List<Object> my) {
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
<orderEntry type="library" name="CGLIB" level="project" />
|
||||
<orderEntry type="library" name="asm" level="project" />
|
||||
<orderEntry type="library" exported="" name="ForkJoin" level="project" />
|
||||
<orderEntry type="module" module-name="testFramework" scope="TEST" />
|
||||
</component>
|
||||
<component name="copyright">
|
||||
<Base>
|
||||
@@ -177,5 +178,4 @@
|
||||
<option name="useAlternate" value="false" />
|
||||
</LanguageOptions>
|
||||
</component>
|
||||
</module>
|
||||
|
||||
</module>
|
||||
+2
-2
@@ -1,5 +1,6 @@
|
||||
package com.intellij.openapi.vcs.changes.actions.migrate;
|
||||
|
||||
import com.intellij.diff.contents.FileContentImpl;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
@@ -22,7 +23,6 @@ import com.intellij.diff.chains.DiffRequestChain;
|
||||
import com.intellij.diff.chains.DiffRequestProducer;
|
||||
import com.intellij.diff.chains.DiffRequestProducerException;
|
||||
import com.intellij.diff.chains.SimpleDiffRequestChain;
|
||||
import com.intellij.diff.contents.BinaryFileContentImpl;
|
||||
import com.intellij.diff.contents.DiffContent;
|
||||
import com.intellij.diff.contents.DocumentContentImpl;
|
||||
import com.intellij.diff.contents.EmptyContent;
|
||||
@@ -118,7 +118,7 @@ public class MigrateToNewDiffUtil {
|
||||
if (oldContent.isBinary()) {
|
||||
VirtualFile file = oldContent.getFile();
|
||||
if (file == null) return null;
|
||||
return new BinaryFileContentImpl(project, file);
|
||||
return new FileContentImpl(project, file);
|
||||
}
|
||||
else {
|
||||
Document document = oldContent.getDocument();
|
||||
|
||||
+1
-1
@@ -206,7 +206,7 @@ public class SvnPropertiesDiffViewer extends TwosideTextDiffViewer {
|
||||
@Override
|
||||
public void paint(@NotNull Graphics g, @NotNull JComponent divider) {
|
||||
assert myEditor1 != null && myEditor2 != null;
|
||||
Graphics2D gg = getDividerGraphics(g, divider);
|
||||
Graphics2D gg = DiffDividerDrawUtil.getDividerGraphics(g, divider, getEditor1().getComponent());
|
||||
Rectangle clip = gg.getClipBounds();
|
||||
if (clip == null) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user