blob: 3a1f8b055ab598484c4417ff495a10a5a4f387f2 [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.diff.impl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Alarm;
import com.intellij.util.containers.HashMap;
public class Rediffers {
private final HashMap<EditorSource, Rediff> myRediffers = new HashMap<EditorSource, Rediff>();
private final DiffPanelImpl myPanel;
private final Alarm myAlarm = new Alarm();
private final Runnable myUpdateRequest = new Runnable() {
public void run() {
if (myDisposed) return;
updateNow();
}
};
private boolean myDisposed = false;
public Rediffers(DiffPanelImpl panel) {
myPanel = panel;
}
public void dispose() {
for (Rediff rediff : myRediffers.values()) {
rediff.stopListen();
}
myRediffers.clear();
myAlarm.cancelAllRequests();
myDisposed = true;
}
public void contentRemoved(EditorSource source) {
Rediff rediff = myRediffers.remove(source);
if (rediff != null) rediff.stopListen();
}
public void contentAdded(final EditorSource source) {
Editor editor = source.getEditor();
Rediff rediff = new Rediff(editor.getDocument());
myRediffers.put(source, rediff);
rediff.startListen();
source.addDisposable(new Disposable() {
public void dispose() {
contentRemoved(source);
}
});
}
public void updateNow() {
myPanel.rediff();
myAlarm.cancelAllRequests();
}
private void requestRediff() {
myAlarm.cancelAllRequests();
myAlarm.addRequest(myUpdateRequest, 300);
}
private class Rediff implements DocumentListener, Disposable {
private final Document myDocument;
private boolean myLinstening = false;
public Rediff(Document document) {
myDocument = document;
}
public void beforeDocumentChange(DocumentEvent event) {}
public void documentChanged(DocumentEvent event) {
int newLines = StringUtil.getLineBreakCount(event.getNewFragment());
int oldLines = StringUtil.getLineBreakCount(event.getOldFragment());
if (newLines != oldLines) myPanel.invalidateDiff();
requestRediff();
}
public void stopListen() {
if (myLinstening) myDocument.removeDocumentListener(this);
myLinstening = false;
}
public void startListen() {
if (!myLinstening) myDocument.addDocumentListener(this);
myLinstening = true;
}
public void dispose() {
stopListen();
}
}
}