Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModelTracker.java')
-rw-r--r--gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModelTracker.java232
1 files changed, 232 insertions, 0 deletions
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModelTracker.java b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModelTracker.java
new file mode 100644
index 0000000000..0eed8fdad5
--- /dev/null
+++ b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModelTracker.java
@@ -0,0 +1,232 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Red Hat, 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
+ *
+ * Contributors:
+ * Red Hat initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.gcov.view.annotatedsource;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.ui.CDTUITools;
+import org.eclipse.cdt.ui.ICEditor;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IPartListener2;
+import org.eclipse.ui.IWindowListener;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Keep track of windows/parts and listen for opened editors to add
+ * the annotation model.
+ */
+public class GcovAnnotationModelTracker {
+
+ private static GcovAnnotationModelTracker single;
+ private final IWorkbench workbench;
+ private final Map<IProject, IPath> trackedProjects = new HashMap<>();
+
+ /**
+ * Add/Remove a part listener to every window open/closed.
+ */
+ private IWindowListener windowListener = new IWindowListener() {
+ @Override
+ public void windowOpened(IWorkbenchWindow window) {
+ window.getPartService().addPartListener(partListener);
+ }
+
+ @Override
+ public void windowClosed(IWorkbenchWindow window) {
+ window.getPartService().removePartListener(partListener);
+ }
+
+ @Override
+ public void windowActivated(IWorkbenchWindow window) {}
+
+ @Override
+ public void windowDeactivated(IWorkbenchWindow window) {}
+ };
+
+ /**
+ * Add the GcovAnnotationModel to any part that contains an
+ * instance of ICEditor.
+ */
+ private IPartListener2 partListener = new IPartListener2() {
+ @Override
+ public void partOpened(IWorkbenchPartReference partref) {
+ annotateCEditor(partref);
+ }
+
+ @Override
+ public void partActivated(IWorkbenchPartReference partRef) {}
+
+ @Override
+ public void partBroughtToTop(IWorkbenchPartReference partRef) {}
+
+ @Override
+ public void partClosed(IWorkbenchPartReference partRef) {}
+
+ @Override
+ public void partDeactivated(IWorkbenchPartReference partRef) {}
+
+ @Override
+ public void partHidden(IWorkbenchPartReference partRef) {}
+
+ @Override
+ public void partVisible(IWorkbenchPartReference partRef) {}
+
+ @Override
+ public void partInputChanged(IWorkbenchPartReference partRef) {}
+ };
+
+ private GcovAnnotationModelTracker (IWorkbench workbench) {
+ this.workbench = workbench;
+
+ // Add part listener for current windows
+ for (IWorkbenchWindow w : workbench.getWorkbenchWindows()) {
+ w.getPartService().addPartListener(partListener);
+ }
+
+ // Add window listener to workbench for future windows
+ workbench.addWindowListener(windowListener);
+ }
+
+ public static GcovAnnotationModelTracker getInstance () {
+ if (single == null) {
+ single = new GcovAnnotationModelTracker(PlatformUI.getWorkbench());
+ }
+ return single;
+ }
+
+ public IPath getBinaryPath (IProject project) {
+ return trackedProjects.get(project);
+ }
+
+ public boolean containsProject (IProject project) {
+ return trackedProjects.containsKey(project);
+ }
+
+ public void addProject (IProject project, IPath binary) {
+ trackedProjects.put(project, binary);
+ }
+
+ public void dispose() {
+ workbench.removeWindowListener(windowListener);
+ for (IWorkbenchWindow w : workbench.getWorkbenchWindows()) {
+ w.getPartService().removePartListener(partListener);
+ }
+ }
+
+ public void annotateAllCEditors() {
+ for (IWorkbenchWindow w : workbench.getWorkbenchWindows()) {
+ for (IWorkbenchPage p : w.getPages()) {
+ for (IEditorReference e : p.getEditorReferences()) {
+ annotateCEditor(e);
+ }
+ }
+ }
+ }
+
+ private void annotateCEditor(IWorkbenchPartReference partref) {
+ IWorkbenchPart part = partref.getPart(false);
+ if (part instanceof ICEditor) {
+ ICEditor editor = (ICEditor) part;
+ ICElement element = CDTUITools.getEditorInputCElement(editor.getEditorInput());
+ IProject project = element.getCProject().getProject();
+
+ // Attach our annotation model to any compatible editor. (ICEditor)
+ GcovAnnotationModel.attach((ITextEditor) part);
+ // If a user triggers a build we will not render annotations.
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(
+ new ProjectBuildListener(project, editor),
+ IResourceChangeEvent.POST_BUILD);
+ }
+ }
+
+
+ private class ProjectBuildListener implements IResourceChangeListener {
+
+ // project to keep track of
+ private IProject project;
+ private ICEditor editor;
+
+ public ProjectBuildListener(IProject targetProject, ICEditor editor) {
+ this.editor = editor;
+ this.project = targetProject;
+ }
+
+ @Override
+ public void resourceChanged(IResourceChangeEvent event) {
+ if (project != null && isPostBuildEvent(event)) {
+
+ // find the project from event delta and delete its markers
+ IResourceDelta delta = event.getDelta();
+ IResourceDelta[] childrenDelta = delta.getAffectedChildren(IResourceDelta.CHANGED);
+ for (IResourceDelta childDelta : childrenDelta) {
+ if (isProjectDelta(childDelta, project)) {
+
+ // do not track this project and de-register this listener
+ GcovAnnotationModel.clear(editor);
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
+ trackedProjects.remove(project);
+ }
+ }
+ }
+ }
+
+ /**
+ * Check if {@link IResourceDelta} represents a change in the specified {@link IProject}..
+ *
+ * @param delta IResourceDelta resource delta to check
+ * @param project IProject project to compare against
+ * @return boolean true if IResourceDelta is a project and equals the
+ */
+ public boolean isProjectDelta(IResourceDelta delta, IProject project){
+ if(delta != null){
+ IResource resource = delta.getResource();
+ return delta.getKind() == IResourceDelta.CHANGED
+ && resource != null
+ && resource.getType() == IResource.PROJECT
+ && resource.equals(project);
+ }
+ return false;
+ }
+
+ /**
+ * Check if {@link IResourceChangeEvent} is a post-build event.
+ *
+ * @param event IResourceChangeEvent event to check
+ * @return boolean true if IResourceChangeEvent is a post-build event, false
+ * otherwise
+ */
+ public boolean isPostBuildEvent(IResourceChangeEvent event) {
+ if(event != null){
+ int buildKind = event.getBuildKind();
+ return event.getType() == IResourceChangeEvent.POST_BUILD
+ && (buildKind == IncrementalProjectBuilder.FULL_BUILD
+ || buildKind == IncrementalProjectBuilder.INCREMENTAL_BUILD
+ || buildKind == IncrementalProjectBuilder.CLEAN_BUILD);
+ }
+ return false;
+ }
+ }
+}

Back to the top