/* Soot - a J*va Optimization Framework
* Copyright (C) 2003 Jennifer Lhotak
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
package ca.mcgill.sable.soot.attributes;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ResourceBundle;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jdt.core.*;
import org.eclipse.jface.text.*;
import org.eclipse.jface.text.source.*;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IMarkerResolution;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.texteditor.*;
import ca.mcgill.sable.soot.editors.JimpleEditor;
import ca.mcgill.sable.soot.ui.PopupListSelector;
import ca.mcgill.sable.soot.*;
public abstract class SootAttributeSelectAction extends ResourceAction {
AbstractTextEditor editor;
AbstractTextEditor linkToEditor;
IVerticalRulerInfo rulerInfo;
AbstractMarkerAnnotationModel model;
int lineNumber;
/**
* @param bundle
* @param prefix
*/
public SootAttributeSelectAction(ResourceBundle bundle, String prefix, ITextEditor editor, IVerticalRulerInfo rulerInfo) {
super(bundle, prefix);
setEditor((AbstractTextEditor)editor);
setRulerInfo(rulerInfo);
}
public IResource getResource(AbstractTextEditor textEditor) {
IEditorInput input= textEditor.getEditorInput();
return (IResource) ((IAdaptable) input).getAdapter(IResource.class);
}
protected IDocument getDocument() {
IDocumentProvider provider= getEditor().getDocumentProvider();
return provider.getDocument(getEditor().getEditorInput());
}
public void run() {
// need to get list of texts
IAnnotationModel model = getEditor().getDocumentProvider().getAnnotationModel(getEditor().getEditorInput());
if (model instanceof AbstractMarkerAnnotationModel){
setModel((AbstractMarkerAnnotationModel)model);
}
int markerLine = getRulerInfo().getLineOfLastMouseButtonActivity();
IResource rec = getResource(getEditor());
try {
IMarker [] markers = rec.findMarkers("ca.mcgill.sable.soot.sootattributemarker", true, IResource.DEPTH_INFINITE);
for (int i = 0; i < markers.length; i++){
if (getModel().getMarkerPosition(markers[i]) == null) continue;
setLineNumber(getDocument().getLineOfOffset(getModel().getMarkerPosition(markers[i]).getOffset()));
if (getLineNumber() == markerLine){
ArrayList links = getMarkerLinks();
Iterator lit = links.iterator();
String [] list = getMarkerLabels(links);
if ((list == null) || (list.length == 0)) {
// show no links
}
else {
IWorkbenchWindow window = SootPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage().getWorkbenchWindow();
PopupListSelector popup = new PopupListSelector(window.getShell());
popup.setItems(list);
int listWidth = getListWidth(list);
if (getEditor() instanceof JimpleEditor){
int topIndex = ((JimpleEditor)getEditor()).getViewer().getTopIndex();
Rectangle rect = new Rectangle(320, (getLineNumber()+1-topIndex), listWidth, 45 );
popup.open(rect);
}
else {
int topIndex = ((ITextViewer)((AbstractTextEditor)getEditor()).getAdapter(ITextOperationTarget.class)).getTopIndex();
int pos = getModel().getMarkerPosition(markers[i]).getOffset();
pos = pos / getLineNumber();
Rectangle rect = new Rectangle(320, getLineNumber()+1-topIndex, listWidth, 45 );
popup.open(rect);
}
handleSelection(popup.getSelected(), links);
}
}
}
}
catch(CoreException e){
}
catch (BadLocationException e1){
}
}
public int getListWidth(String[] list){
int width = 0;
for (int i = 0; i < list.length; i++){
String next = list[i];
width = next.length() > width ? next.length() : width;
}
return width * 6;
}
public void handleSelection(String selected, ArrayList links){
if (selected == null) return;
try {
int toShow = 0;
String className;
Iterator it = links.iterator();
while (it.hasNext()){
LinkAttribute la = (LinkAttribute)it.next();
if (la.getLabel().equals(selected)){
toShow = getLinkLine(la) - 1;//.getJimpleLink() - 1;
className = la.getClassName();
findClass(className);
}
}
int selOffset = getLinkToEditor().getDocumentProvider().getDocument(getLinkToEditor().getEditorInput()).getLineOffset(toShow);
if ((selOffset != -1) && (selOffset != 0)){
if (getLinkToEditor() instanceof JimpleEditor){
((JimpleEditor)getLinkToEditor()).getViewer().setRangeIndication(selOffset, 1, true);
SootPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage().activate(getLinkToEditor());
}
else {
SootPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage().activate(getLinkToEditor());
((AbstractTextEditor)SootPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor()).selectAndReveal(selOffset, 0);
((AbstractTextEditor)SootPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor()).setHighlightRange(selOffset, 1, true);
}
}
}
catch(BadLocationException e){
System.out.println(e.getMessage());
}
}
protected abstract int getLinkLine(LinkAttribute la);
public abstract void findClass(String className);
public String removeExt(String fileName){
return fileName.substring(0, fileName.lastIndexOf("."));
}
public abstract ArrayList getMarkerLinks();
public String [] getMarkerLabels(ArrayList links){
if ((links == null) || (links.size() == 0)) return null;
ArrayList list = new ArrayList();
String [] attributeTexts = new String[links.size()];
Iterator it = links.iterator();
while (it.hasNext()){
list.add(((LinkAttribute)it.next()).getLabel());
}
list.toArray(attributeTexts);
return attributeTexts;
}
public String [] fixLabels(String [] at){
for (int i = 0; i < at.length; i++){
String temp = at[i];
temp.replaceAll("<", "<");
temp.replaceAll(">", ">");
at[i] = temp;
}
return at;
}
public void getMarkerResolutions(IMarker marker){
SootAttributeResolutionGenerator sarg = new SootAttributeResolutionGenerator();
if (sarg.hasResolutions(marker)){
IMarkerResolution [] res = sarg.getResolutions(marker);
for (int i = 0; i < res.length; i++){
//System.out.println("res: "+res[i].getLabel());
}
}
}
/**
* @return
*/
public AbstractTextEditor getEditor() {
return editor;
}
/**
* @param editor
*/
public void setEditor(AbstractTextEditor editor) {
this.editor = editor;
}
/**
* @return
*/
public IVerticalRulerInfo getRulerInfo() {
return rulerInfo;
}
/**
* @param info
*/
public void setRulerInfo(IVerticalRulerInfo info) {
rulerInfo = info;
}
/**
* @return
*/
public AbstractMarkerAnnotationModel getModel() {
return model;
}
/**
* @param model
*/
public void setModel(AbstractMarkerAnnotationModel model) {
this.model = model;
}
/**
* @return
*/
public int getLineNumber() {
return lineNumber;
}
/**
* @param i
*/
public void setLineNumber(int i) {
lineNumber = i;
}
/**
* @return
*/
public AbstractTextEditor getLinkToEditor() {
return linkToEditor;
}
/**
* @param editor
*/
public void setLinkToEditor(AbstractTextEditor editor) {
linkToEditor = editor;
}
}