package org.eclipse.eclipsemonkey.lang.ruby.doms.editors;
/**
* Copyright (c) 2007 Aptana, 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. If redistributing this code,
* this entire header must remain intact.
*/
import org.eclipse.eclipsemonkey.utils.StringUtils;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import org.jruby.Ruby;
import org.jruby.RubyBoolean;
import org.jruby.RubyClass;
import org.jruby.RubyFixnum;
import org.jruby.RubyNumeric;
import org.jruby.RubyObject;
import org.jruby.RubyRange;
import org.jruby.RubyString;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
/**
* @author Chris Williams
*/
@JRubyClass(name="Editor")
public class Editor extends RubyObject {
private static final long serialVersionUID = 3459594505705212000L;
private static RubyClass __clazz;
private static RubyClass createClass(Ruby runtime) {
if (__clazz == null) {
RubyClass clazz = runtime.defineClass("Editor", runtime.getObject(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
clazz.defineAnnotatedMethods(Editor.class);
__clazz = clazz;
}
return __clazz;
}
private IEditorPart _editor;
public Editor(Ruby runtime, IEditorPart editor) {
super(runtime, createClass(runtime));
this._editor = editor;
}
/**
* getDocument
*
* @return IDocument
*/
private IDocument getDocument() {
ITextEditor editor = getTextEditor();
IDocumentProvider dp = editor.getDocumentProvider();
IDocument doc = dp.getDocument(editor.getEditorInput());
return doc;
}
/**
* Get the _editor
*
* @return _editor
*/
public ITextEditor getTextEditor() {
IEditorPart part = this._editor;
ITextEditor result = null;
if (part instanceof ITextEditor) {
result = (ITextEditor) part;
}
return result;
}
/**
* getSource
*
* @return RubyString
*/
@JRubyMethod(name = "source")
public RubyString getSource() {
return getRuntime().newString(this.getDocument().get());
}
/**
* getSelectionRange
*
* @return Object
*/
@JRubyMethod(name = "selection_range", alias = "selectionRange")
public IRubyObject getSelectionRange() {
ITextSelection ts = (ITextSelection) getTextEditor().getSelectionProvider().getSelection();
RubyRange range = RubyRange.newRange(getRuntime(), getRuntime().getCurrentContext(), RubyFixnum.newFixnum(getRuntime(), ts.getOffset()), RubyFixnum.newFixnum(getRuntime(), ts.getOffset() + ts.getLength()), false);
return range;
}
/**
* applyEdit
*
* @param offset
* @param deleteLength
* @param insertText
* @throws BadLocationException
*/
@JRubyMethod(name= "apply_edit", alias = "applyEdit", required = 3)
public IRubyObject applyEdit(ThreadContext context, IRubyObject offset, IRubyObject deleteLength, IRubyObject insertText) throws BadLocationException {
IEditorPart part = this._editor;
if (part != null && part instanceof ITextEditor) {
// get document
IDocument doc = getDocument();
try {
doc.replace(RubyNumeric.num2int(offset), RubyNumeric.num2int(deleteLength), insertText.convertToString().toString());
}
catch (BadLocationException e) {
throw e;
}
}
return getRuntime().getTrue();
}
/**
* getLineDelimiter
*
* @return String
*/
@JRubyMethod(name = "line_delimeter", alias = "lineDelimeter")
public RubyString getLineDelimiter() {
IDocument document = this.getDocument();
RubyString result = getRuntime().newString("\n");
if (document != null) {
String[] delims = document.getLegalLineDelimiters();
if (delims.length > 0) {
result = getRuntime().newString(delims[0]);
}
}
return result;
}
/**
* close
*
* @param save
*/
@JRubyMethod(name = "close", required = 1)
public RubyBoolean close(ThreadContext context, IRubyObject saveObj) {
ITextEditor editor = this.getTextEditor();
boolean save = false;
if (saveObj instanceof RubyBoolean)
{
save = ((RubyBoolean) saveObj).isTrue();
}
if (editor != null) {
editor.close(save);
return getRuntime().getTrue();
}
return getRuntime().getFalse();
}
/**
* save
*/
@JRubyMethod(name = "save")
public RubyBoolean save() {
if (this._editor != null) {
this._editor.doSave(null);
return getRuntime().getTrue();
}
return getRuntime().getFalse();
}
/**
* getId
*
* @return String
*/
@JRubyMethod(name = "id")
public RubyString getId() {
RubyString result = getRuntime().newString(StringUtils.EMPTY);
if (this._editor != null) {
result = getRuntime().newString(this._editor.getSite().getId());
}
return result;
}
/**
* getSourceLength
*
* @return Scriptable
*/
@JRubyMethod(name = "source_length", alias = "sourceLength")
public RubyFixnum getSourceLength() {
return getRuntime().newFixnum(this.getDocument().getLength());
}
/**
* getCurrentOffset
*
* @return int
*/
@JRubyMethod(name = "current_offset", alias = "currentOffset")
public RubyFixnum getCurrentOffset() {
/**
* ResultRef
*/
class ResultRef {
public int result = -1;
}
final IWorkbench workbench = PlatformUI.getWorkbench();
Display display = workbench.getDisplay();
final ResultRef result = new ResultRef();
display.syncExec(new Runnable() {
public void run() {
ITextSelection ts = (ITextSelection) getTextEditor().getSelectionProvider().getSelection();
result.result = ts.getOffset();
}
});
return getRuntime().newFixnum(result.result);
}
/**
* @param roffset
* @param rlength
*/
@JRubyMethod(name = "select_and_reveal", alias = "selectAndReveal", required = 2)
public RubyBoolean selectAndReveal(ThreadContext context, final IRubyObject offset, final IRubyObject length) {
final IWorkbench workbench = PlatformUI.getWorkbench();
Display display = workbench.getDisplay();
display.asyncExec(new Runnable() {
public void run() {
ITextEditor editor = getTextEditor();
editor.selectAndReveal(RubyNumeric.num2int(offset), RubyNumeric.num2int(length));
}
});
return getRuntime().getTrue();
}
}