/*******************************************************************************
* Copyright (c) 2015 Bruno Medeiros and other Contributors.
* 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:
* Bruno Medeiros - initial API and implementation
*******************************************************************************/
package melnorme.lang.ide.ui.editor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.information.IInformationPresenter;
import org.eclipse.jface.text.source.IOverviewRuler;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import melnorme.lang.ide.core.text.TextSourceUtils;
import melnorme.utilbox.core.CommonException;
import melnorme.utilbox.misc.NumberUtil;
import melnorme.utilbox.ownership.IDisposable;
public class LangSourceViewer extends ProjectionViewerExt implements ISourceViewerExt {
public LangSourceViewer(Composite parent, IVerticalRuler verticalRuler, int styles) {
super(parent, verticalRuler, null, false, styles);
}
public LangSourceViewer(Composite parent, IVerticalRuler verticalRuler, IOverviewRuler overviewRuler,
boolean showAnnotationsOverview, int styles) {
super(parent, verticalRuler, overviewRuler, showAnnotationsOverview, styles);
}
/* ----------------- Shift operation ----------------- */
@Override
public boolean canDoOperation(int operation) {
if (getTextWidget() == null)
return false;
switch (operation) {
case SHIFT_LEFT:
return isEditable() && fIndentChars != null;
case SHIFT_RIGHT:
return isEditable() && fIndentChars != null && (areMultipleLinesSelected() || isCursorAtIndent());
}
return super.canDoOperation(operation);
}
protected boolean isCursorAtIndent() {
IDocument document = getDocument();
if(document == null) {
return false;
}
Point sel = getSelectedRange();
try {
int startLine = document.getLineOfOffset(sel.x);
IRegion line = document.getLineInformation(startLine);
int lineStart = line.getOffset();
String indent = TextSourceUtils.getLineIndentForLine(document.get(), line);
return NumberUtil.isInRange(lineStart, sel.x, lineStart + indent.length());
} catch(BadLocationException x) {
}
return false;
}
@Override
protected void shift(boolean useDefaultPrefixes, boolean right, boolean ignoreWhitespace) {
Point selection = getSelectedRange();
super.shift(useDefaultPrefixes, right, ignoreWhitespace);
Point newSelection = getSelectedRange();
if(selection.y == 0 && selection.x == newSelection.x) {
// Prevent the shift from creating a selection, this happens due to a quirk in shift operation
setSelectedRange(selection.x + newSelection.y, 0);
}
}
/* ----------------- Quick Outline ----------------- */
protected IInformationPresenter outlinePresenter;
public void setOutlinePresenter(IInformationPresenter outlinePresenter) {
this.outlinePresenter = outlinePresenter;
}
{
addConfigurationOwned(new IDisposable() {
@Override
public void dispose() {
if(outlinePresenter != null) {
outlinePresenter.uninstall();
outlinePresenter = null;
}
}
});
}
@Override
public void showOutline() throws CommonException {
if(outlinePresenter != null) {
outlinePresenter.showInformation();
} else {
throw new CommonException("Outline not available. ", null);
}
}
/* ----------------- Content Assist ----------------- */
// Override to grant public access to field.
@Override
public IContentAssistant getContentAssistant() {
return fContentAssistant;
}
}