/**
* Copyright (c) 2005-2013 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
/*
* @author: fabioz
* Created: January 2004
*/
package org.python.pydev.editor.actions;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.swt.SWT;
import org.eclipse.ui.IEditorActionDelegate;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.texteditor.ITextEditor;
import org.python.pydev.core.docutils.PySelection;
import org.python.pydev.core.log.Log;
import org.python.pydev.editor.PyEdit;
import org.python.pydev.shared_ui.EditorUtils;
import org.python.pydev.shared_ui.actions.BaseAction;
import org.python.pydev.utils.Messages;
import org.python.pydev.utils.PyEditorMessages;
/**
* @author Fabio Zadrozny
*
* Superclass of all our actions. Contains utility functions.
*
* Subclasses should implement run(IAction action) method.
*/
public abstract class PyAction extends BaseAction implements IEditorActionDelegate {
protected PyAction() {
super();
}
protected PyAction(String text, int style) {
super(text, style);
}
public static String getDelimiter(IDocument doc) {
return PySelection.getDelimiter(doc);
}
/**
* @return python editor.
*/
protected PyEdit getPyEdit() {
if (targetEditor instanceof PyEdit) {
return (PyEdit) targetEditor;
} else {
throw new RuntimeException("Expecting PyEdit editor. Found:" + targetEditor.getClass().getName());
}
}
/**
* @return true if the contents of the editor may be changed. Clients MUST call this before actually
* modifying the editor.
*/
protected boolean canModifyEditor() {
ITextEditor editor = getTextEditor();
return BaseAction.canModifyEditor(editor);
}
/**
* Are we in the first char of the line with the offset passed?
* @param doc
* @param cursorOffset
*/
protected void isInFirstVisibleChar(IDocument doc, int cursorOffset) {
try {
IRegion region = doc.getLineInformationOfOffset(cursorOffset);
int offset = region.getOffset();
String src = doc.get(offset, region.getLength());
if ("".equals(src)) {
return;
}
int i = 0;
while (i < src.length()) {
if (!Character.isWhitespace(src.charAt(i))) {
break;
}
i++;
}
setCaretPosition(offset + i - 1);
} catch (BadLocationException e) {
beep(e);
return;
}
}
/**
* Returns the position of the last non whitespace char in the current line.
* @param doc
* @param cursorOffset
* @return position of the last character of the line (returned as an absolute
* offset)
*
* @throws BadLocationException
*/
protected int getLastCharPosition(IDocument doc, int cursorOffset) throws BadLocationException {
IRegion region;
region = doc.getLineInformationOfOffset(cursorOffset);
int offset = region.getOffset();
String src = doc.get(offset, region.getLength());
int i = src.length();
boolean breaked = false;
while (i > 0) {
i--;
//we have to break if we find a character that is not a whitespace or a tab.
if (Character.isWhitespace(src.charAt(i)) == false && src.charAt(i) != '\t') {
breaked = true;
break;
}
}
if (!breaked) {
i--;
}
return (offset + i);
}
/**
* Goes to first char of the line.
* @param doc
* @param cursorOffset
*/
protected void gotoFirstChar(IDocument doc, int cursorOffset) {
try {
IRegion region = doc.getLineInformationOfOffset(cursorOffset);
int offset = region.getOffset();
setCaretPosition(offset);
} catch (BadLocationException e) {
beep(e);
}
}
/**
* Goes to the first visible char.
* @param doc
* @param cursorOffset
*/
protected void gotoFirstVisibleChar(IDocument doc, int cursorOffset) {
try {
setCaretPosition(PySelection.getFirstCharPosition(doc, cursorOffset));
} catch (BadLocationException e) {
beep(e);
}
}
/**
* Goes to the first visible char.
* @param doc
* @param cursorOffset
*/
protected boolean isAtFirstVisibleChar(IDocument doc, int cursorOffset) {
try {
return PySelection.getFirstCharPosition(doc, cursorOffset) == cursorOffset;
} catch (BadLocationException e) {
return false;
}
}
//================================================================
// HELPER FOR DEBBUGING...
//================================================================
/*
* Beep...humm... yeah....beep....ehehheheh
*/
protected static void beep(Exception e) {
try {
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell().getDisplay().beep();
} catch (Throwable x) {
//ignore, workbench has still not been created
}
Log.log(e);
}
/**
*
*/
public static String getLineWithoutComments(String sel) {
return sel.replaceAll("#.*", "");
}
/**
*
*/
public static String getLineWithoutComments(PySelection ps) {
return getLineWithoutComments(ps.getCursorLineContents());
}
public static String lowerChar(String s, int pos) {
char[] ds = s.toCharArray();
ds[pos] = Character.toLowerCase(ds[pos]);
return new String(ds);
}
/**
* @param string
* @param j
* @return
*/
public static boolean stillInTok(String string, int j) {
char c = string.charAt(j);
return c != '\n' && c != '\r' && c != ' ' && c != '.' && c != '(' && c != ')' && c != ',' && c != ']'
&& c != '[' && c != '#' && c != '\'' && c != '"';
}
/**
* Maps the localized modifier name to a code in the same
* manner as #findModifier.
*
* @param modifierName the modifier name
* @return the SWT modifier bit, or <code>0</code> if no match was found
*/
public static int findLocalizedModifier(String modifierName) {
if (modifierName == null) {
return 0;
}
if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.CTRL))) {
return SWT.CTRL;
}
if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.SHIFT))) {
return SWT.SHIFT;
}
if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.ALT))) {
return SWT.ALT;
}
if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.COMMAND))) {
return SWT.COMMAND;
}
return 0;
}
/**
* Returns the modifier string for the given SWT modifier
* modifier bits.
*
* @param stateMask the SWT modifier bits
* @return the modifier string
*/
public static String getModifierString(int stateMask) {
String modifierString = ""; //$NON-NLS-1$
if ((stateMask & SWT.CTRL) == SWT.CTRL) {
modifierString = appendModifierString(modifierString, SWT.CTRL);
}
if ((stateMask & SWT.ALT) == SWT.ALT) {
modifierString = appendModifierString(modifierString, SWT.ALT);
}
if ((stateMask & SWT.SHIFT) == SWT.SHIFT) {
modifierString = appendModifierString(modifierString, SWT.SHIFT);
}
if ((stateMask & SWT.COMMAND) == SWT.COMMAND) {
modifierString = appendModifierString(modifierString, SWT.COMMAND);
}
return modifierString;
}
/**
* Appends to modifier string of the given SWT modifier bit
* to the given modifierString.
*
* @param modifierString the modifier string
* @param modifier an int with SWT modifier bit
* @return the concatenated modifier string
*/
private static String appendModifierString(String modifierString, int modifier) {
if (modifierString == null) {
modifierString = ""; //$NON-NLS-1$
}
String newModifierString = Action.findModifierString(modifier);
if (modifierString.length() == 0) {
return newModifierString;
}
return Messages.format(PyEditorMessages.EditorUtility_concatModifierStrings,
new String[] { modifierString, newModifierString });
}
/**
* @param ps the selection that contains the document
*/
protected void revealSelEndLine(PySelection ps) {
// Put cursor at the first area of the selection
int docLen = ps.getDoc().getLength() - 1;
IRegion endLine = ps.getEndLine();
if (endLine != null) {
int curOffset = endLine.getOffset();
getTextEditor().selectAndReveal(curOffset < docLen ? curOffset : docLen, 0);
}
}
/**
* @return a set with the currently opened files in the PyEdit editors.
*/
public static Set<IFile> getOpenFiles() {
Set<IFile> ret = new HashSet<IFile>();
IWorkbenchWindow activeWorkbenchWindow = EditorUtils.getActiveWorkbenchWindow();
if (activeWorkbenchWindow == null) {
return ret;
}
IWorkbenchPage[] pages = activeWorkbenchWindow.getPages();
for (int i = 0; i < pages.length; i++) {
IEditorReference[] editorReferences = pages[i].getEditorReferences();
for (int j = 0; j < editorReferences.length; j++) {
IEditorReference iEditorReference = editorReferences[j];
if (!PyEdit.EDITOR_ID.equals(iEditorReference.getId())) {
continue; //Only PyDev editors...
}
try {
IEditorInput editorInput = iEditorReference.getEditorInput();
if (editorInput == null) {
continue;
}
IFile file = (IFile) editorInput.getAdapter(IFile.class);
if (file != null) {
ret.add(file);
}
} catch (Exception e1) {
Log.log(e1);
}
}
}
return ret;
}
}