/*******************************************************************************
* Copyright (c) 2012 xored software, Inc. All rights reserved. This program and the accompanying
* materials are made available under the terms of the Eclipse Public License v1.0 which accompanies
* this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html Contributors:
* xored software, Inc. - initial API and implementation (Yuri Strot)
******************************************************************************/
package com.xored.glance.internal.ui.viewers;
import com.xored.glance.ui.sources.ITextBlock;
import com.xored.glance.ui.sources.ITextBlockListener;
import com.xored.glance.ui.sources.TextChangedEvent;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.text.ITextListener;
import org.eclipse.jface.text.TextEvent;
import org.eclipse.jface.text.TextViewer;
import java.lang.reflect.Field;
import java.util.List;
/**
* @author Yuri Strot
*/
public class TextViewerBlock implements ITextBlock, ITextListener {
private ListenerList listeners;
protected TextViewer viewer;
public TextViewerBlock(TextViewer viewer) {
this.viewer = viewer;
listeners = new ListenerList();
addListeners();
}
@Override
public void addTextBlockListener(ITextBlockListener listener) {
listeners.add(listener);
}
@Override
public int compareTo(ITextBlock o) {
return 0;
}
public void dispose() {
removeListeners();
}
@Override
public String getText() {
return viewer.getDocument().get();
}
@Override
public void removeTextBlockListener(ITextBlockListener listener) {
listeners.remove(listener);
}
@Override
public void textChanged(TextEvent event) {
if (event.getDocumentEvent() != null) {
TextChangedEvent changedEvent = new TextChangedEvent(
event.getOffset(),
event.getLength(),
event.getReplacedText());
fireTextChanged(changedEvent);
}
}
protected void addListeners() {
if (!addFirstListener()) {
viewer.addTextListener(this);
}
}
protected void fireTextChanged(TextChangedEvent changedEvent) {
Object[] objects = listeners.getListeners();
for (Object object : objects) {
ITextBlockListener listener = (ITextBlockListener) object;
listener.textChanged(changedEvent);
}
}
protected void removeListeners() {
viewer.removeTextListener(this);
}
/**
* Add our text listener to the beginning of the listener list thro reflection. This method return
* true if this operation succeed and fail otherwise.
*/
private boolean addFirstListener() {
try {
Field filed = TextViewer.class.getDeclaredField("fTextListeners");
filed.setAccessible(true);
@SuppressWarnings("unchecked")
List<Object> list = (List<Object>) filed.get(viewer);
if (list == null) {
// no listeners, can add it usual way
return false;
}
if (!list.contains(this)) {
list.add(0, this);
}
return true;
} catch (Exception e) {
return false;
}
}
}