diff --git a/codan/org.eclipse.cdt.codan.checkers.ui/META-INF/MANIFEST.MF b/codan/org.eclipse.cdt.codan.checkers.ui/META-INF/MANIFEST.MF index 40701f828ce..6517ee023d0 100644 --- a/codan/org.eclipse.cdt.codan.checkers.ui/META-INF/MANIFEST.MF +++ b/codan/org.eclipse.cdt.codan.checkers.ui/META-INF/MANIFEST.MF @@ -10,9 +10,10 @@ Require-Bundle: org.eclipse.ui, org.eclipse.jface.text;bundle-version="3.5.0", org.eclipse.ui.editors;bundle-version="3.5.0", org.eclipse.core.resources;bundle-version="3.5.0", - org.eclipse.cdt.codan.checkers;bundle-version="1.0.0", + org.eclipse.cdt.codan.checkers, org.eclipse.cdt.ui, - org.eclipse.cdt.core + org.eclipse.cdt.core, + org.eclipse.cdt.codan.ui Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-Vendor: Eclipse CDT diff --git a/codan/org.eclipse.cdt.codan.checkers.ui/plugin.xml b/codan/org.eclipse.cdt.codan.checkers.ui/plugin.xml index bee18e15b55..407ee78644a 100644 --- a/codan/org.eclipse.cdt.codan.checkers.ui/plugin.xml +++ b/codan/org.eclipse.cdt.codan.checkers.ui/plugin.xml @@ -2,6 +2,7 @@ + + diff --git a/codan/org.eclipse.cdt.codan.checkers.ui/schema/codanMarkerResolution.exsd b/codan/org.eclipse.cdt.codan.checkers.ui/schema/codanMarkerResolution.exsd index 0c3f1e85cef..4cdbf233f09 100644 --- a/codan/org.eclipse.cdt.codan.checkers.ui/schema/codanMarkerResolution.exsd +++ b/codan/org.eclipse.cdt.codan.checkers.ui/schema/codanMarkerResolution.exsd @@ -7,6 +7,7 @@ Extension point to plugin quick fix for codan markers + @@ -98,7 +99,7 @@ - <extension + <extension point="org.eclipse.cdt.codan.checkers.ui.codanMarkerResolution"> <resolution class="org.eclipse.cdt.codan.internal.checkers.ui.quickfix.CatchByReferenceQuickFix" @@ -113,7 +114,8 @@ - [Enter API information here.] + Programmatically resolution can be added using CatchByReferenceQuickFix.addResolution method. +It is not API yet. @@ -122,7 +124,7 @@ - [Enter information about supplied implementation of this extension point.] + see CatchByReferenceQuickFix diff --git a/codan/org.eclipse.cdt.codan.examples/META-INF/MANIFEST.MF b/codan/org.eclipse.cdt.codan.examples/META-INF/MANIFEST.MF index ff72dae7e32..d230e8e3dee 100644 --- a/codan/org.eclipse.cdt.codan.examples/META-INF/MANIFEST.MF +++ b/codan/org.eclipse.cdt.codan.examples/META-INF/MANIFEST.MF @@ -9,6 +9,7 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.cdt.codan.core.cxx;bundle-version="1.0.0", org.eclipse.cdt.codan.core;bundle-version="1.0.0", org.eclipse.cdt.core, - org.eclipse.core.resources + org.eclipse.core.resources, + org.eclipse.cdt.codan.ui;bundle-version="1.0.0" Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ActivationPolicy: lazy diff --git a/codan/org.eclipse.cdt.codan.examples/plugin.xml b/codan/org.eclipse.cdt.codan.examples/plugin.xml index f9a68351b58..57ba95cf73b 100644 --- a/codan/org.eclipse.cdt.codan.examples/plugin.xml +++ b/codan/org.eclipse.cdt.codan.examples/plugin.xml @@ -19,4 +19,11 @@ + + + + diff --git a/codan/org.eclipse.cdt.codan.examples/src/org/eclipse/cdt/codan/examples/uicontrib/FlexlintHelpLink.java b/codan/org.eclipse.cdt.codan.examples/src/org/eclipse/cdt/codan/examples/uicontrib/FlexlintHelpLink.java new file mode 100644 index 00000000000..af2668969a9 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.examples/src/org/eclipse/cdt/codan/examples/uicontrib/FlexlintHelpLink.java @@ -0,0 +1,39 @@ +package org.eclipse.cdt.codan.examples.uicontrib; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.cdt.codan.ui.AbstractCodanProblemDetailsProvider; + +public class FlexlintHelpLink extends AbstractCodanProblemDetailsProvider { + @Override + public boolean isApplicable(String id) { + String helpId = parseHelpId(getProblemMessage()); + return helpId != null; + } + private Pattern messagePattern = Pattern.compile("(Warning|Error|Note|Info) #([0-9]+)"); //$NON-NLS-1$ + + private String parseHelpId(String problemMessage) { + // Warning #613: + // Note #613: + // Error #613: + String helpId = null; + Matcher matcher = messagePattern.matcher(problemMessage); + if (matcher.find()) { + helpId = matcher.group(2); + } + return helpId; + } + + @Override + public URL getHelpURL() { + String helpId = parseHelpId(getProblemMessage()); + try { + return new URL("http://www.gimpel-online.com/MsgRef.html#" + helpId); //$NON-NLS-1$ + } catch (MalformedURLException e) { + return null; + } + } +} diff --git a/codan/org.eclipse.cdt.codan.ui/META-INF/MANIFEST.MF b/codan/org.eclipse.cdt.codan.ui/META-INF/MANIFEST.MF index fec1699b2bf..25999a93377 100644 --- a/codan/org.eclipse.cdt.codan.ui/META-INF/MANIFEST.MF +++ b/codan/org.eclipse.cdt.codan.ui/META-INF/MANIFEST.MF @@ -16,5 +16,8 @@ Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.cdt.codan.internal.ui;x-friends:="org.eclipse.cdt.codan.ui.cxx", org.eclipse.cdt.codan.internal.ui.actions;x-friends:="org.eclipse.cdt.codan.ui.cxx", org.eclipse.cdt.codan.internal.ui.dialogs;x-friends:="org.eclipse.cdt.codan.ui.cxx", - org.eclipse.cdt.codan.internal.ui.preferences;x-friends:="org.eclipse.cdt.codan.ui.cxx" + org.eclipse.cdt.codan.internal.ui.preferences;x-friends:="org.eclipse.cdt.codan.ui.cxx", + org.eclipse.cdt.codan.internal.ui.views;x-internal:=true, + org.eclipse.cdt.codan.ui, + org.eclipse.cdt.codan.ui.handlers diff --git a/codan/org.eclipse.cdt.codan.ui/build.properties b/codan/org.eclipse.cdt.codan.ui/build.properties index 81723ae5646..0c5238c8284 100644 --- a/codan/org.eclipse.cdt.codan.ui/build.properties +++ b/codan/org.eclipse.cdt.codan.ui/build.properties @@ -3,4 +3,6 @@ output.. = bin/ bin.includes = plugin.xml,\ META-INF/,\ .,\ - OSGI-INF/l10n/bundle.properties + OSGI-INF/l10n/bundle.properties,\ + schema/,\ + icons/ diff --git a/codan/org.eclipse.cdt.codan.ui/icons/problemDetails.gif b/codan/org.eclipse.cdt.codan.ui/icons/problemDetails.gif new file mode 100644 index 00000000000..6ef4163d9a4 Binary files /dev/null and b/codan/org.eclipse.cdt.codan.ui/icons/problemDetails.gif differ diff --git a/codan/org.eclipse.cdt.codan.ui/icons/sample.gif b/codan/org.eclipse.cdt.codan.ui/icons/sample.gif deleted file mode 100644 index 34fb3c9d8cb..00000000000 Binary files a/codan/org.eclipse.cdt.codan.ui/icons/sample.gif and /dev/null differ diff --git a/codan/org.eclipse.cdt.codan.ui/plugin.xml b/codan/org.eclipse.cdt.codan.ui/plugin.xml index 74f74e8d492..df5c37f82a4 100644 --- a/codan/org.eclipse.cdt.codan.ui/plugin.xml +++ b/codan/org.eclipse.cdt.codan.ui/plugin.xml @@ -73,13 +73,13 @@ point="org.eclipse.ui.views"> - + + + + + + + + This extension point provides a mechanism to add extra details for a problem, which would +be displayed in Problem Details view. It can include extra locations, associated problems, +help link or extenal link. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + root element for extension. + + + + + + + Problem id for which extra details available. +If ommitted provider would be called for all problem kinds. + + + + + + + + + + + + + + + + + + + + + + + + + 1.0 + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + [Enter API information here.] + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + diff --git a/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/ui/views/ProblemDetails.java b/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/views/ProblemDetails.java similarity index 69% rename from codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/ui/views/ProblemDetails.java rename to codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/views/ProblemDetails.java index 3b9a8755f6f..55c63219a04 100644 --- a/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/ui/views/ProblemDetails.java +++ b/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/views/ProblemDetails.java @@ -1,5 +1,9 @@ -package org.eclipse.cdt.codan.ui.views; +package org.eclipse.cdt.codan.internal.ui.views; +import java.net.URL; +import java.util.Collection; + +import org.eclipse.cdt.codan.ui.AbstractCodanProblemDetailsProvider; import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.jface.action.Action; @@ -12,10 +16,13 @@ import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.Menu; import org.eclipse.ui.IActionBars; import org.eclipse.ui.ISelectionListener; @@ -27,20 +34,16 @@ import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.ViewPart; public class ProblemDetails extends ViewPart { - /** * The ID of the view as specified by the extension. */ - public static final String ID = "org.eclipse.cdt.codan.ui.views.ProblemDetails"; - + public static final String ID = "org.eclipse.cdt.codan.internal.ui.views.ProblemDetails"; private Composite area; private Action action1; - private Action action2; - private Action doubleClickAction; private Label description; - private Label location; + private Link helpLabel; /** * The constructor. @@ -59,24 +62,28 @@ public class ProblemDetails extends ViewPart { description = new Label(area, SWT.WRAP); description.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); location = new Label(area, SWT.WRAP); - - + helpLabel = new Link(area, SWT.WRAP); + helpLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + helpLabel.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + String link = e.text; + if (link != null && link.startsWith("http")) { + org.eclipse.swt.program.Program.launch(e.text); + } + } + }); // Create the help context id for the area's control //PlatformUI.getWorkbench().getHelpSystem().setHelp(area, "org.eclipse.cdt.codan.ui.viewer"); makeActions(); hookContextMenu(); - hookDoubleClickAction(); contributeToActionBars(); - ISelectionService ser = (ISelectionService) getSite().getService(ISelectionService.class); ser.addSelectionListener(new ISelectionListener() { - public void selectionChanged(IWorkbenchPart part, ISelection selection) { - if (part.getSite().getId().equals(processViewId)) { processSelection(selection); } - } }); ISelection selection = ser.getSelection(processViewId); @@ -84,7 +91,8 @@ public class ProblemDetails extends ViewPart { } protected void processSelection(ISelection selection) { - if (selection == null || selection.isEmpty()) return; + if (selection == null || selection.isEmpty()) + return; if (selection instanceof IStructuredSelection) { Object firstElement = ((IStructuredSelection) selection).getFirstElement(); IMarker marker = null; @@ -98,10 +106,43 @@ public class ProblemDetails extends ViewPart { description.setText(message); String loc = marker.getResource().getFullPath().toOSString(); //$NON-NLS-1$ int line = marker.getAttribute(IMarker.LINE_NUMBER, 0); - location.setText(loc+":"+line); //$NON-NLS-1$ + location.setText(loc + ":" + line); //$NON-NLS-1$ + queryProviders(marker); area.layout(); } + } + } + private void queryProviders(IMarker marker) { + cleanProversControl(); + String id = marker.getAttribute(IMarker.PROBLEM, "id"); //$NON-NLS-1$ + Collection providers = ProblemDetailsExtensions.getProviders(id); + for (AbstractCodanProblemDetailsProvider provider : providers) { + synchronized (provider) { + provider.setMarker(marker); + if (provider.isApplicable(id)) { + applyProvider(provider); + break; + } + } + } + } + + public void cleanProversControl() { + helpLabel.setText(""); + } + + private void applyProvider(AbstractCodanProblemDetailsProvider provider) { + String label = provider.getHelpLabel(); + final URL url = provider.getHelpURL(); + if (label != null) { + helpLabel.setText(label); + } + if (url != null) { + if (label == null) { + label = url.toString(); + } + helpLabel.setText("" + label + ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } } @@ -125,21 +166,16 @@ public class ProblemDetails extends ViewPart { } private void fillLocalPullDown(IMenuManager manager) { -// manager.add(action1); -// manager.add(new Separator()); -// manager.add(action2); + } - private void fillContextMenu(IMenuManager manager) { - manager.add(action1); - manager.add(action2); + private void fillContextMenu(IMenuManager manager) { // Other plug-ins can contribute there actions here manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); } private void fillLocalToolBar(IToolBarManager manager) { -// manager.add(action1); -// manager.add(action2); + } private void makeActions() { @@ -150,28 +186,8 @@ public class ProblemDetails extends ViewPart { }; action1.setText("Action 1"); action1.setToolTipText("Action 1 tooltip"); - action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor( - ISharedImages.IMG_OBJS_INFO_TSK)); + action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK)); - action2 = new Action() { - public void run() { - showMessage("Action 2 executed"); - } - }; - action2.setText("Action 2"); - action2.setToolTipText("Action 2 tooltip"); - action2.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor( - ISharedImages.IMG_OBJS_INFO_TSK)); - doubleClickAction = new Action() { - public void run() { - - showMessage("Double-click detected"); - } - }; - } - - private void hookDoubleClickAction() { - // todo } private void showMessage(String message) { diff --git a/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/views/ProblemDetailsExtensions.java b/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/views/ProblemDetailsExtensions.java new file mode 100644 index 00000000000..fa103ae35a5 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/views/ProblemDetailsExtensions.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * $QNXLicenseC: + * Copyright 2008, QNX Software Systems. All Rights Reserved. + * + * You must obtain a written license from and pay applicable license fees to QNX + * Software Systems before you may reproduce, modify or distribute this software, + * or any work that includes all or part of this software. Free development + * licenses are available for evaluation and non-commercial purposes. For more + * information visit http://licensing.qnx.com or email licensing@qnx.com. + * + * This file may contain contributions from others. Please review this entire + * file for other proprietary rights or license notices, as well as the QNX + * Development Suite License Guide at http://licensing.qnx.com/license-guide/ + * for other information. + * $ + *******************************************************************************/ +/* + * Created by: Elena Laskavaia + * Created on: 2010-04-28 + * Last modified by: $Author$ + */ +package org.eclipse.cdt.codan.internal.ui.views; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; + +import org.eclipse.cdt.codan.internal.ui.CodanUIActivator; +import org.eclipse.cdt.codan.ui.AbstractCodanProblemDetailsProvider; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.Platform; + +/** + * Class that can load extension for problemDetails + */ +public class ProblemDetailsExtensions { + private static final String ALL = "*";//$NON-NLS-1$ + private static final String EXTENSION_POINT_NAME = "codanProblemDetails"; //$NON-NLS-1$ + private static boolean extensionsLoaded; + private static HashMap> map = new HashMap>(); + + private static synchronized void readExtensions() { + if (extensionsLoaded) return; + IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint(CodanUIActivator.PLUGIN_ID, EXTENSION_POINT_NAME); + if (ep == null) + return; + try { + IConfigurationElement[] elements = ep.getConfigurationElements(); + // process categories + for (int i = 0; i < elements.length; i++) { + IConfigurationElement configurationElement = elements[i]; + processDetails(configurationElement); + } + } finally { + extensionsLoaded = true; + } + } + + /** + * @param configurationElement + */ + private static void processDetails(IConfigurationElement configurationElement) { + if (configurationElement.getName().equals("problemDetails")) { //$NON-NLS-1$ + String id = configurationElement.getAttribute("problemId"); //$NON-NLS-1$ + if (id == null) { + id = ALL; + } + addExtension(id, configurationElement); + } + } + + public static AbstractCodanProblemDetailsProvider resolveClass(IConfigurationElement configurationElement) { + AbstractCodanProblemDetailsProvider res; + try { + res = (AbstractCodanProblemDetailsProvider) configurationElement.createExecutableExtension("class");//$NON-NLS-1$ + } catch (CoreException e) { + CodanUIActivator.log(e); + return null; + } + return res; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + private static void addExtension(String id, IConfigurationElement configurationElement) { + Collection collection = getCollection(id); + collection.add(configurationElement); + } + + @SuppressWarnings("rawtypes") + public static void removeExtension(String id, Object el) { + Collection collection = getCollection(id); + collection.remove(el); + } + + @SuppressWarnings("rawtypes") + private static Collection getCollection(String id) { + Collection collection = map.get(id); + if (collection == null) { + collection = new ArrayList(); + map.put(id, collection); + } + return collection; + } + + public static Collection getProviders(String id) { + readExtensions(); + Collection providers = new ArrayList(); + Collection collection1 = getCollection(id); + Collection collection2 = getCollection(ALL); + providers.addAll(resolveProviders(collection1)); + providers.addAll(resolveProviders(collection2)); + return providers; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static Collection resolveProviders(Collection collection) { + Collection res = new ArrayList(collection); + for (Iterator iterator = res.iterator(); iterator.hasNext();) { + Object object = iterator.next(); + if (object instanceof IConfigurationElement) { + // resolve + collection.remove(object); + AbstractCodanProblemDetailsProvider provider = resolveClass((IConfigurationElement) object); + if (provider!=null) + collection.add(provider); + } + } + return collection; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static void addExtension(String id, AbstractCodanProblemDetailsProvider provider) { + Collection collection = getCollection(id); + collection.add(provider); + } +} diff --git a/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/ui/AbstractCodanProblemDetailsProvider.java b/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/ui/AbstractCodanProblemDetailsProvider.java new file mode 100644 index 00000000000..4c063ca4fc0 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/ui/AbstractCodanProblemDetailsProvider.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * $QNXLicenseC: + * Copyright 2008, QNX Software Systems. All Rights Reserved. + * + * You must obtain a written license from and pay applicable license fees to QNX + * Software Systems before you may reproduce, modify or distribute this software, + * or any work that includes all or part of this software. Free development + * licenses are available for evaluation and non-commercial purposes. For more + * information visit http://licensing.qnx.com or email licensing@qnx.com. + * + * This file may contain contributions from others. Please review this entire + * file for other proprietary rights or license notices, as well as the QNX + * Development Suite License Guide at http://licensing.qnx.com/license-guide/ + * for other information. + * $ + *******************************************************************************/ +/* + * Created by: Elena Laskavaia + * Created on: 2010-04-28 + * Last modified by: $Author$ + */ +package org.eclipse.cdt.codan.ui; + +import java.net.URL; + +import org.eclipse.core.resources.IMarker; + +/** + * Abstract class that provides stubs for problems details + */ +public abstract class AbstractCodanProblemDetailsProvider { + protected IMarker marker; + + public AbstractCodanProblemDetailsProvider() { + } + + /** + * sets the marker, called from framework to initialize provider + */ + public void setMarker(IMarker marker) { + this.marker = marker; + } + + public IMarker getMarker() { + return marker; + } + + protected String getProblemMessage(){ + String message = marker.getAttribute(IMarker.MESSAGE, ""); //$NON-NLS-1$ + return message; + } + + /** + * return true if provider can provide details for given marker (previously set by setMarker) + * @param id - id of the problem + * @return + */ + public abstract boolean isApplicable(String id); + + /** + * URL to external help for the problem, would be displayed as label, and as action + * will go to given URL is not null. If label is null (getHelpLabel) URL would be used as label. + */ + public URL getHelpURL() { + return null; + } + + /** + * Label text to use to navigate to a help. Would be shown as hyperlink. If helpURL is not + * null would open a browser with given URL. + */ + public String getHelpLabel() { + return null; + } + + /** + * Return help context id. Only one getHelpURL or getHelpContextId can be used. + * In case if help context id is not null hyperlink would open context help page. + */ + public String getHelpContextId() { + return null; + } +}