From fb427ef483d5d05be0b8ff3a755ba16b791bb6f0 Mon Sep 17 00:00:00 2001 From: Cole Peterson Date: Thu, 9 Sep 2021 14:01:30 -0500 Subject: [PATCH] Added support for additional view elements -Added a workbenchGazeHandler to recursively keep track of editors and views and their respective gaze handlers. -Added a projectExplorerGazeHandler -Additional views types can now be tracked and managed inside the workbenchGazeHandler --- src/org/itrace/ControlView.java | 30 ++--- src/org/itrace/ITrace.java | 49 ++++---- .../itrace/gaze/handlers/IGazeHandler.java | 10 +- .../handlers/ProjectExplorerGazeHandler.java | 63 ++++++++++ .../gaze/handlers/StyledTextGazeHandler.java | 21 +++- .../gaze/handlers/WorkbenchGazeHandler.java | 114 ++++++++++++++++++ 6 files changed, 239 insertions(+), 48 deletions(-) create mode 100644 src/org/itrace/gaze/handlers/ProjectExplorerGazeHandler.java create mode 100644 src/org/itrace/gaze/handlers/WorkbenchGazeHandler.java diff --git a/src/org/itrace/ControlView.java b/src/org/itrace/ControlView.java index 542f02f..0fc874d 100644 --- a/src/org/itrace/ControlView.java +++ b/src/org/itrace/ControlView.java @@ -15,10 +15,9 @@ import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IPartListener2; -import org.eclipse.ui.IViewSite; -import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewReference; import org.eclipse.ui.IWorkbenchPartReference; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.ViewPart; @@ -112,11 +111,8 @@ public void setFocus() { public void partActivated(IWorkbenchPartReference partRef) { if(partRef.getPart(false) instanceof IEditorPart) { ITrace.getDefault().setActiveEditor((IEditorPart)partRef.getPart(false)); - IEditorPart ep = (IEditorPart)partRef.getPart(true); - ITrace.getDefault().setLineManager(ep.getEditorSite().getActionBars().getStatusLineManager()); - } else { - IWorkbenchPart ep = partRef.getPart(true); - ITrace.getDefault().setLineManager(((IViewSite) ep.getSite()).getActionBars().getStatusLineManager()); + } else if(partRef instanceof IViewReference) { + ITrace.getDefault().setActiveViewPart((IViewPart)partRef.getPart(false)); } } @@ -124,23 +120,17 @@ public void partActivated(IWorkbenchPartReference partRef) { public void partBroughtToTop(IWorkbenchPartReference partRef) { if(partRef.getPart(false) instanceof IEditorPart) { ITrace.getDefault().setActiveEditor((IEditorPart)partRef.getPart(false)); - IEditorPart ep = (IEditorPart)partRef.getPart(true); - ITrace.getDefault().setLineManager(ep.getEditorSite().getActionBars().getStatusLineManager()); - } else { - IWorkbenchPart ep = partRef.getPart(true); - ITrace.getDefault().setLineManager(((IViewSite) ep.getSite()).getActionBars().getStatusLineManager()); + } else if(partRef instanceof IViewReference) { + ITrace.getDefault().setActiveViewPart((IViewPart)partRef.getPart(false)); } } @Override public void partClosed(IWorkbenchPartReference partRef) { - if(partRef instanceof IEditorReference){ - ITrace.getDefault().setActionBars(getViewSite().getActionBars()); - IEditorPart editorPart = (IEditorPart)partRef.getPart(true); - ITrace.getDefault().removeEditor(editorPart); - - IEditorPart activeEditor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); - ITrace.getDefault().setActiveEditor(activeEditor); + if(partRef.getPart(false) instanceof IEditorPart) { + ITrace.getDefault().removeEditor((IEditorPart)partRef.getPart(false)); + } else if(partRef instanceof IViewReference) { + ITrace.getDefault().removeViewPart((IViewPart)partRef.getPart(false)); } } diff --git a/src/org/itrace/ITrace.java b/src/org/itrace/ITrace.java index 7c8c0cb..de6afa3 100644 --- a/src/org/itrace/ITrace.java +++ b/src/org/itrace/ITrace.java @@ -5,13 +5,13 @@ import org.eclipse.e4.core.services.events.IEventBroker; import org.eclipse.jface.action.IStatusLineManager; import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IViewPart; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; @@ -19,8 +19,7 @@ import org.osgi.service.event.EventHandler; import org.itrace.gaze.IGazeResponse; -import org.itrace.gaze.handlers.IGazeHandler; -import org.itrace.gaze.handlers.StyledTextGazeHandler; +import org.itrace.gaze.handlers.WorkbenchGazeHandler; import org.itrace.solvers.XMLGazeExportSolver; /** @@ -37,7 +36,7 @@ public class ITrace extends AbstractUIPlugin implements EventHandler { private static ITrace plugin; private IEditorPart activeEditor; private HashMap tokenHighlighters = new HashMap(); - private HashMap editorHandlers = new HashMap(); + private WorkbenchGazeHandler workbenchGazeHandler; private boolean showTokenHighlights = false; private volatile boolean isConnected; @@ -63,9 +62,9 @@ public ITrace() { StyledText styledText = (StyledText) editorPart.getAdapter(Control.class); if (styledText != null) { tokenHighlighters.put(editorPart, new TokenHighlighter(editorPart, showTokenHighlights)); - editorHandlers.put(editorPart, new StyledTextGazeHandler(styledText, editorPart)); } } + connectionManager = new ConnectionManager(); // iTrace invokes the events to the Eventbroker and these events are subscribed // in an order. @@ -118,6 +117,9 @@ public Shell getRootShell() { public void setRootShell(Shell shell) { rootShell = shell; + if(workbenchGazeHandler == null) { + workbenchGazeHandler = new WorkbenchGazeHandler(PlatformUI.getWorkbench()); + } } public void setActionBars(IActionBars bars) { @@ -220,19 +222,26 @@ public void setActiveEditor(IEditorPart editorPart) { if (!tokenHighlighters.containsKey(editorPart)) { tokenHighlighters.put(editorPart, new TokenHighlighter(editorPart, showTokenHighlights)); } - if (!editorHandlers.containsKey(editorPart)) { - StyledText styledText = (StyledText) editorPart.getAdapter(Control.class); - if (styledText != null) { - editorHandlers.put(editorPart, new StyledTextGazeHandler(styledText, editorPart)); - } - } + setLineManager(editorPart.getEditorSite().getActionBars().getStatusLineManager()); + workbenchGazeHandler.addEditor(editorPart); } } + + public void setActiveViewPart(IViewPart viewPart) { + setLineManager(viewPart.getViewSite().getActionBars().getStatusLineManager()); + workbenchGazeHandler.addViewPart(viewPart); + } public void removeEditor(IEditorPart editorPart) { tokenHighlighters.remove(editorPart); - editorHandlers.remove(editorPart); + workbenchGazeHandler.removeEditor(editorPart); } + + public void removeViewPart(IViewPart viewPart) { + workbenchGazeHandler.removeViewPart(viewPart); + + } + public void activateHighlights() { showTokenHighlights = !showTokenHighlights; @@ -258,21 +267,11 @@ public void clearTokenHighlights() { * is not handled. */ private IGazeResponse handleGaze(int screenX, int screenY, Gaze gaze) { + if(workbenchGazeHandler.containsGaze(screenX, screenY)) { + return workbenchGazeHandler.handleGaze(screenX, screenY, gaze); + } // Look at all editors and find an active one that contains the point // Returns the result of the editor's handleGaze method - for (IEditorPart editor : editorHandlers.keySet()) { - Control editorControl = editor.getAdapter(Control.class); - Rectangle editorScreenBounds = editorControl.getBounds(); - Point screenPos = editorControl.toDisplay(0, 0); - editorScreenBounds.x = screenPos.x; - editorScreenBounds.y = screenPos.y; - - if (editorControl.isVisible() && editorScreenBounds.contains(screenX, screenY)) { - IGazeHandler handler = editorHandlers.get(editor); - return handler.handleGaze(screenX, screenY, screenX - editorScreenBounds.x, - screenY - editorScreenBounds.y, gaze); - } - } return null; } diff --git a/src/org/itrace/gaze/handlers/IGazeHandler.java b/src/org/itrace/gaze/handlers/IGazeHandler.java index e50bc12..7224eb0 100644 --- a/src/org/itrace/gaze/handlers/IGazeHandler.java +++ b/src/org/itrace/gaze/handlers/IGazeHandler.java @@ -11,12 +11,18 @@ */ public interface IGazeHandler { + /** + * Determines whether the gaze is within the boundaries of the + * target object. Return value will be true if the gaze is contained + * within the target object + */ + public boolean containsGaze(int absoluteX, int absoluteY); + /** * Handles the specified gaze at the specified x and y coordinates relative * to the target object. Return value may be null if the gaze is not * meaningful to the target. */ - public IGazeResponse handleGaze(int absoluteX, int absoluteY, - int relativeX, int relativeY, Gaze gaze); + public IGazeResponse handleGaze(int absoluteX, int absoluteY, Gaze gaze); } diff --git a/src/org/itrace/gaze/handlers/ProjectExplorerGazeHandler.java b/src/org/itrace/gaze/handlers/ProjectExplorerGazeHandler.java new file mode 100644 index 0000000..ea4fc85 --- /dev/null +++ b/src/org/itrace/gaze/handlers/ProjectExplorerGazeHandler.java @@ -0,0 +1,63 @@ +package org.itrace.gaze.handlers; + +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.IViewPart; +import org.itrace.Gaze; +import org.itrace.gaze.IGazeResponse; + +public class ProjectExplorerGazeHandler implements IGazeHandler { + private String name; + private Tree tree; + + public ProjectExplorerGazeHandler(Tree target, IViewPart partRef) { + this.name = partRef.getTitle(); + this.tree = (Tree) target; + } + + @Override + public boolean containsGaze(int absoluteX, int absoluteY) { + Rectangle viewScreenBounds = tree.getBounds(); + Point screenPos = tree.toDisplay(0, 0); + viewScreenBounds.x = screenPos.x; + viewScreenBounds.y = screenPos.y; + + if (tree.isVisible() && viewScreenBounds.contains(absoluteX, absoluteY)) { + return true; + } + else { + return false; + } + } + + @Override + public IGazeResponse handleGaze(int absoluteX, int absoluteY, final Gaze gaze) { + int relativeX = absoluteX - tree.toDisplay(0, 0).x; + int relativeY = absoluteY - tree.toDisplay(0, 0).y; + + tree.getItem(new Point(relativeX, relativeY)); + return new IGazeResponse() { + @Override + public String getName() { + return name; + } + + @Override + public Gaze getGaze() { + return gaze; + } + + @Override + public IGazeHandler getGazeHandler() { + return ProjectExplorerGazeHandler.this; + } + + @Override + public String getGazeType() { + // TODO Auto-generated method stub + return "view_part"; + } + }; + } +} \ No newline at end of file diff --git a/src/org/itrace/gaze/handlers/StyledTextGazeHandler.java b/src/org/itrace/gaze/handlers/StyledTextGazeHandler.java index 480519a..2a92fb7 100644 --- a/src/org/itrace/gaze/handlers/StyledTextGazeHandler.java +++ b/src/org/itrace/gaze/handlers/StyledTextGazeHandler.java @@ -7,6 +7,7 @@ //import org.eclipse.jface.text.source.projection.ProjectionViewer; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IFileEditorInput; import org.itrace.Gaze; @@ -28,9 +29,24 @@ public StyledTextGazeHandler(Object target, IEditorPart editor) { this.editor = editor; projectionViewer = (ProjectionViewer) editor.getAdapter(ITextOperationTarget.class); } + + @Override + public boolean containsGaze(int absoluteX, int absoluteY) { + Rectangle viewScreenBounds = targetStyledText.getBounds(); + Point screenPos = targetStyledText.toDisplay(0, 0); + viewScreenBounds.x = screenPos.x; + viewScreenBounds.y = screenPos.y; + + if (targetStyledText.isVisible() && viewScreenBounds.contains(absoluteX, absoluteY)) { + return true; + } + else { + return false; + } + } @Override - public IStyledTextGazeResponse handleGaze(int absoluteX, int absoluteY, int relativeX, int relativeY, final Gaze gaze) { + public IStyledTextGazeResponse handleGaze(int absoluteX, int absoluteY, final Gaze gaze) { final int lineIndex; final int col; final Point absoluteLineAnchorPosition; @@ -40,6 +56,9 @@ public IStyledTextGazeResponse handleGaze(int absoluteX, int absoluteY, int rela final String path; try { + int relativeX = absoluteX - targetStyledText.toDisplay(0, 0).x; + int relativeY = absoluteY - targetStyledText.toDisplay(0, 0).y; + // Get the actual offset of the current line from the top // Allows code folding to be taken into account int foldedLineIndex = targetStyledText.getLineIndex(relativeY); diff --git a/src/org/itrace/gaze/handlers/WorkbenchGazeHandler.java b/src/org/itrace/gaze/handlers/WorkbenchGazeHandler.java new file mode 100644 index 0000000..452465b --- /dev/null +++ b/src/org/itrace/gaze/handlers/WorkbenchGazeHandler.java @@ -0,0 +1,114 @@ +package org.itrace.gaze.handlers; + +import java.util.HashMap; + +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.navigator.resources.ProjectExplorer; +import org.itrace.Gaze; +import org.itrace.ITrace; +import org.itrace.gaze.IGazeResponse; + +public class WorkbenchGazeHandler implements IGazeHandler { + protected IWorkbench workbench; + + protected HashMap partHandlers = new HashMap(); + + public WorkbenchGazeHandler(IWorkbench workbench) { + this.workbench = workbench; + + IWorkbenchPage page = this.workbench.getActiveWorkbenchWindow().getActivePage(); + for(IViewReference viewRef : page.getViewReferences()) { + IViewPart viewPart = (IViewPart)viewRef.getPart(true); + if(viewPart != null) { + this.addViewPart(viewPart); + } + } + for(IEditorReference editorRef : page.getEditorReferences()) { + IEditorPart editorPart = (IEditorPart)editorRef.getPart(true); + if(editorPart != null) { + this.addEditor(editorPart); + } + } + } + + @Override + public boolean containsGaze(int absoluteX, int absoluteY) { + Rectangle viewScreenBounds = workbench.getActiveWorkbenchWindow().getShell().getBounds(); + Point screenPos = workbench.getActiveWorkbenchWindow().getShell().toDisplay(0, 0); + viewScreenBounds.x = screenPos.x; + viewScreenBounds.y = screenPos.y; + + if (workbench.getActiveWorkbenchWindow().getShell().isVisible() && viewScreenBounds.contains(absoluteX, absoluteY)) { + return true; + } + else { + // Needed to handle the case of a workbench part being in a different shell + // A simple bounds check of the root shell fails to find it + for(IWorkbenchPart part : this.partHandlers.keySet()) { + if(this.partHandlers.get(part).containsGaze(absoluteX, absoluteY)) { + return true; + } + } + return false; + } + } + + @Override + public IGazeResponse handleGaze(int absoluteX, int absoluteY, final Gaze gaze) { + for(IWorkbenchPart part : this.partHandlers.keySet()) { + if(this.partHandlers.get(part).containsGaze(absoluteX, absoluteY)) { + return this.partHandlers.get(part).handleGaze(absoluteX, absoluteY, gaze); + } + } + + return null; + } + + + public void addEditor(IEditorPart editorPart) { + if (!partHandlers.containsKey(editorPart)) { + StyledText styledText = (StyledText) editorPart.getAdapter(Control.class); + if (styledText != null) { + partHandlers.put(editorPart, new StyledTextGazeHandler(styledText, editorPart)); + } + } + } + + public void removeEditor(IEditorPart editorPart) { + partHandlers.remove(editorPart); + ITrace.getDefault().removeEditor(editorPart); + } + + public void addViewPart(IViewPart viewPart) { + if(!partHandlers.containsKey(viewPart)) { + if(viewPart instanceof ProjectExplorer) { + ProjectExplorer projectExplorerPart = (ProjectExplorer)viewPart; + Tree target = (Tree) projectExplorerPart.getCommonViewer().getControl(); + partHandlers.put(viewPart, new ProjectExplorerGazeHandler(target, viewPart)); + } + } + } + + public void removeViewPart(IViewPart viewPart) { + partHandlers.remove(viewPart); + } + + public void dispose() { + for(IWorkbenchPart part : partHandlers.keySet()) { + if(part instanceof IEditorPart) { + ITrace.getDefault().removeEditor((IEditorPart)part); + } + } + } +} \ No newline at end of file