Skip to content

Commit 034f28a

Browse files
committed
Add new violation details dialog
This dialog can be opened from the problem view context menu. The same dialog is used for the marker properties view. The same dialog is opened from the outline view. Fixes #178
1 parent 98dd831 commit 034f28a

File tree

12 files changed

+419
-127
lines changed

12 files changed

+419
-127
lines changed

net.sourceforge.pmd.eclipse.plugin/messages.properties

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,6 @@ property.button.include_derived_files = Include derived files
1313
property.button.full_build_enabled = Full build enabled
1414
property.button.violations_as_errors = Handle high priority violations as Eclipse errors
1515

16-
# Marker Property Page
17-
markerPropertyPage.label.rulename = Rule:
18-
markerPropertyPage.label.category = Category:
19-
markerPropertyPage.label.priority = Priority:
20-
markerPropertyPage.label.message = Message:
21-
markerPropertyPage.label.description = Description:
22-
markerPropertyPage.label.externalInfoUrl = External Info URL:
23-
2416
# General preferences page
2517
preference.pmd.header = PMD-Plugin Options
2618
preference.pmd.title = PMD General Preferences
@@ -285,6 +277,17 @@ dialog.cpd.no_results.body = CPD has now finished with no matches.
285277

286278
dialog.preferences.add_new_property = Add new property
287279

280+
# Violation Details Dialog -> net.sourceforge.pmd.eclipse.ui.dialogs.ViolationDetailsDialogPage
281+
dialog.violation_details.title = PMD Plugin: Violation Details
282+
dialog.violation_details.location = Location:
283+
dialog.violation_details.examples = Examples:
284+
dialog.violation_details.rulename = Rule:
285+
dialog.violation_details.category = Category:
286+
dialog.violation_details.priority = Priority:
287+
dialog.violation_details.message = Message:
288+
dialog.violation_details.description = Description:
289+
dialog.violation_details.infourl = External Info URL:
290+
288291
# Monitor messages
289292
monitor.job_title = Checking Code with PMD
290293
monitor.begintask = PMD Processing...

net.sourceforge.pmd.eclipse.plugin/nl/fr/messages.properties

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,6 @@ property.button.include_derived_files = Inclure les fichiers d
1313
property.button.full_build_enabled = Full build enabled
1414
property.button.violations_as_errors = Traiter les violations de haute priorité comme des erreurs d'Eclipse
1515

16-
# Marker Property Page
17-
markerPropertyPage.label.rulename = Règle:
18-
markerPropertyPage.label.category = Catégorie:
19-
markerPropertyPage.label.priority = Priorité:
20-
markerPropertyPage.label.message = Message:
21-
markerPropertyPage.label.description = Description:
22-
markerPropertyPage.label.externalInfoUrl = URL d'information externe:
23-
2416
# General preferences page
2517
preference.pmd.header = Préférences Générales PMD
2618
preference.pmd.title = Préférences Générales PMD
@@ -285,6 +277,14 @@ dialog.cpd.no_results.body = CPD a fini son ex
285277

286278
dialog.preferences.add_new_property = Ajouter une propriété
287279

280+
# Violation Details Dialog -> net.sourceforge.pmd.eclipse.ui.dialogs.ViolationDetailsDialogPage
281+
dialog.violation_details.rulename = Règle:
282+
dialog.violation_details.category = Catégorie:
283+
dialog.violation_details.priority = Priorité:
284+
dialog.violation_details.message = Message:
285+
dialog.violation_details.description = Description:
286+
dialog.violation_details.infourl = URL d'information externe:
287+
288288
# Monitor messages
289289
monitor.job_title = Vérifier le code avec PMD
290290
monitor.begintask = PMD en cours...

net.sourceforge.pmd.eclipse.plugin/plugin.properties

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,6 @@ view.violation = PMD Violations
4343
view.outline = Violations Outline
4444
view.overview = Violations Overview
4545
view.dataflowview = Dataflow View
46-
view.cpd = CPD View
46+
view.cpd = CPD View
47+
48+
action.show_details = Show details...

net.sourceforge.pmd.eclipse.plugin/plugin.xml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,4 +830,50 @@
830830
</propertyTester>
831831
</extension>
832832

833+
<extension
834+
point="org.eclipse.ui.commands">
835+
<command
836+
id="net.sourceforge.pmd.eclipse.plugin.showViolationDetailsCommand"
837+
name="%action.show_details">
838+
</command>
839+
</extension>
840+
841+
<extension
842+
point="org.eclipse.ui.menus">
843+
<menuContribution
844+
allPopups="false"
845+
locationURI="popup:org.eclipse.ui.ide.MarkersView">
846+
<command
847+
commandId="net.sourceforge.pmd.eclipse.plugin.showViolationDetailsCommand"
848+
icon="icons/pmd-icon-32.gif"
849+
label="%action.show_details"
850+
style="push">
851+
</command>
852+
</menuContribution>
853+
</extension>
854+
<extension
855+
point="org.eclipse.ui.handlers">
856+
<handler
857+
class="net.sourceforge.pmd.eclipse.ui.views.actions.ShowViolationDetailsHandler"
858+
commandId="net.sourceforge.pmd.eclipse.plugin.showViolationDetailsCommand">
859+
<enabledWhen>
860+
<with
861+
variable="selection">
862+
<count
863+
value="1">
864+
</count>
865+
<iterate
866+
ifEmpty="false">
867+
<adapt
868+
type="org.eclipse.core.resources.IMarker">
869+
<test
870+
property="net.sourceforge.pmd.eclipse.plugin.isPMDMarker">
871+
</test>
872+
</adapt>
873+
</iterate>
874+
</with>
875+
</enabledWhen>
876+
</handler>
877+
</extension>
878+
833879
</plugin>
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3+
*/
4+
5+
package net.sourceforge.pmd.eclipse.ui.dialogs;
6+
7+
import org.eclipse.core.resources.IMarker;
8+
import org.eclipse.jface.dialogs.Dialog;
9+
import org.eclipse.jface.dialogs.IDialogConstants;
10+
import org.eclipse.jface.widgets.WidgetFactory;
11+
import org.eclipse.swt.SWT;
12+
import org.eclipse.swt.custom.ScrolledComposite;
13+
import org.eclipse.swt.layout.GridData;
14+
import org.eclipse.swt.layout.GridLayout;
15+
import org.eclipse.swt.widgets.Composite;
16+
import org.eclipse.swt.widgets.Control;
17+
import org.eclipse.swt.widgets.Shell;
18+
19+
import net.sourceforge.pmd.Rule;
20+
import net.sourceforge.pmd.eclipse.plugin.PMDPlugin;
21+
import net.sourceforge.pmd.eclipse.runtime.builder.MarkerUtil;
22+
import net.sourceforge.pmd.eclipse.ui.nls.StringKeys;
23+
24+
public class ViolationDetailsDialog extends Dialog {
25+
private final IMarker violation;
26+
27+
public ViolationDetailsDialog(Shell shell, IMarker selectedViolation) {
28+
super(shell);
29+
this.violation = selectedViolation;
30+
}
31+
32+
@Override
33+
protected void configureShell(Shell newShell) {
34+
super.configureShell(newShell);
35+
newShell.setText(PMDPlugin.getDefault().getStringTable().getString(StringKeys.DIALOG_VIOLATION_DETAILS_TITLE));
36+
}
37+
38+
@Override
39+
protected boolean isResizable() {
40+
return true;
41+
}
42+
43+
private Rule getSelectedViolationRule() {
44+
return PMDPlugin.getDefault().getPreferencesManager().getRuleSet()
45+
.getRuleByName(MarkerUtil.ruleNameFor(violation));
46+
}
47+
48+
@Override
49+
protected Control createDialogArea(Composite parent) {
50+
ScrolledComposite scroll = new ScrolledComposite((Composite) super.createDialogArea(parent),
51+
SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
52+
scroll.setLayout(new GridLayout());
53+
scroll.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));
54+
55+
Composite composite = WidgetFactory.composite(SWT.NONE).layout(new GridLayout())
56+
.layoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL))
57+
.create(scroll);
58+
scroll.setContent(composite);
59+
60+
ViolationDetailsDialogPage content = new ViolationDetailsDialogPage(violation, getSelectedViolationRule());
61+
content.createControl(composite);
62+
composite.setSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
63+
return scroll;
64+
}
65+
66+
@Override
67+
protected void createButtonsForButtonBar(Composite parent) {
68+
createButton(parent, IDialogConstants.CLOSE_ID, IDialogConstants.CLOSE_LABEL, true);
69+
}
70+
71+
@Override
72+
protected void buttonPressed(int buttonId) {
73+
okPressed();
74+
}
75+
}
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/*
2+
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3+
*/
4+
5+
package net.sourceforge.pmd.eclipse.ui.dialogs;
6+
7+
import java.net.MalformedURLException;
8+
import java.net.URL;
9+
10+
import org.eclipse.core.resources.IMarker;
11+
import org.eclipse.jface.dialogs.DialogPage;
12+
import org.eclipse.jface.resource.JFaceResources;
13+
import org.eclipse.jface.widgets.WidgetFactory;
14+
import org.eclipse.swt.SWT;
15+
import org.eclipse.swt.events.SelectionEvent;
16+
import org.eclipse.swt.events.SelectionListener;
17+
import org.eclipse.swt.graphics.Font;
18+
import org.eclipse.swt.layout.GridData;
19+
import org.eclipse.swt.layout.GridLayout;
20+
import org.eclipse.swt.widgets.Composite;
21+
import org.eclipse.swt.widgets.Label;
22+
import org.eclipse.swt.widgets.Link;
23+
import org.eclipse.swt.widgets.Text;
24+
import org.eclipse.ui.PartInitException;
25+
import org.eclipse.ui.PlatformUI;
26+
import org.eclipse.ui.browser.IWebBrowser;
27+
28+
import net.sourceforge.pmd.Rule;
29+
import net.sourceforge.pmd.eclipse.plugin.PMDPlugin;
30+
import net.sourceforge.pmd.eclipse.runtime.PMDRuntimeConstants;
31+
import net.sourceforge.pmd.eclipse.ui.nls.StringKeys;
32+
import net.sourceforge.pmd.eclipse.ui.nls.StringTable;
33+
34+
public class ViolationDetailsDialogPage extends DialogPage {
35+
private final IMarker violation;
36+
private final Rule rule;
37+
38+
public ViolationDetailsDialogPage(IMarker selectedViolation, Rule selectedRule) {
39+
this.violation = selectedViolation;
40+
this.rule = selectedRule;
41+
}
42+
43+
@Override
44+
public void createControl(Composite parent) {
45+
StringTable messages = PMDPlugin.getDefault().getStringTable();
46+
47+
GridLayout layout = new GridLayout(2, false);
48+
Composite composite = WidgetFactory.composite(SWT.NONE).layout(layout).create(parent);
49+
50+
createLabel(messages.getString(StringKeys.DIALOG_VIOLATION_DETAILS_MESSAGE), composite);
51+
createText(getViolationMessage(), composite);
52+
53+
createLabel(messages.getString(StringKeys.DIALOG_VIOLATION_DETAILS_LOCATION), composite);
54+
createText(getLocation(), composite);
55+
56+
createLabel(messages.getString(StringKeys.DIALOG_VIOLATION_DETAILS_RULENAME), composite);
57+
createText(rule.getName(), composite);
58+
59+
createLabel(messages.getString(StringKeys.DIALOG_VIOLATION_DETAILS_CATEGORY), composite);
60+
createText(rule.getRuleSetName(), composite);
61+
62+
createLabel(messages.getString(StringKeys.DIALOG_VIOLATION_DETAILS_PRIORITY), composite);
63+
createText(rule.getPriority().getName(), composite);
64+
65+
createTwoColumnLabel(messages.getString(StringKeys.DIALOG_VIOLATION_DETAILS_DESCRIPTION), composite);
66+
createTwoColumnMultiText(rule.getDescription(), composite);
67+
68+
createTwoColumnLabel(messages.getString(StringKeys.DIALOG_VIOLATION_DETAILS_EXAMPLES), composite);
69+
createTwoColumnMultiText(getExamples(), JFaceResources.getTextFont(), composite);
70+
71+
createLabel(messages.getString(StringKeys.DIALOG_VIOLATION_DETAILS_INFOURL), composite);
72+
createLink(rule.getExternalInfoUrl(), composite);
73+
}
74+
75+
private Label createLabel(String text, Composite parent) {
76+
return WidgetFactory.label(SWT.NONE).text(text).font(JFaceResources.getHeaderFont())
77+
.layoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)).create(parent);
78+
}
79+
80+
private Label createTwoColumnLabel(String text, Composite parent) {
81+
GridData gridData = new GridData();
82+
gridData.verticalAlignment = SWT.BEGINNING;
83+
gridData.horizontalSpan = 2;
84+
return WidgetFactory.label(SWT.NONE).text(text).font(JFaceResources.getHeaderFont())
85+
.layoutData(gridData).create(parent);
86+
}
87+
88+
private Text createText(String text, Composite parent) {
89+
return WidgetFactory.text(SWT.READ_ONLY | SWT.SINGLE)
90+
.background(parent.getBackground())
91+
.layoutData(new GridData(GridData.FILL_HORIZONTAL))
92+
.text(text)
93+
.create(parent);
94+
}
95+
96+
private Text createTwoColumnMultiText(String text, Composite parent) {
97+
return createTwoColumnMultiText(text, null, parent);
98+
}
99+
100+
private Text createTwoColumnMultiText(String text, Font font, Composite parent) {
101+
GridData gridData = new GridData(GridData.FILL_BOTH);
102+
gridData.horizontalSpan = 2;
103+
return WidgetFactory.text(SWT.READ_ONLY | SWT.MULTI | SWT.WRAP)
104+
.background(parent.getBackground())
105+
.layoutData(gridData)
106+
.text(text)
107+
.font(font)
108+
.create(parent);
109+
}
110+
111+
private Link createLink(String url, Composite parent) {
112+
Link link = new Link(parent, SWT.NONE);
113+
link.setText(String.format("<a href=\"%s\">%s</a>", url, url));
114+
link.addSelectionListener(new LinkClickListener());
115+
link.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
116+
return link;
117+
}
118+
119+
private String getViolationMessage() {
120+
String defaultMessage = violation.getAttribute(IMarker.MESSAGE, "");
121+
return violation.getAttribute(PMDRuntimeConstants.KEY_MARKERATT_MESSAGE, defaultMessage);
122+
}
123+
124+
private String getLocation() {
125+
String projectName = violation.getResource().getProject().getName();
126+
String path = violation.getResource().getProjectRelativePath().toString();
127+
int lineNumber = violation.getAttribute(IMarker.LINE_NUMBER, -1);
128+
129+
if (lineNumber != -1) {
130+
return String.format("%s: %s:%d", projectName, path, lineNumber);
131+
}
132+
return String.format("%s: %s", projectName, path);
133+
}
134+
135+
private String getExamples() {
136+
StringBuilder result = new StringBuilder();
137+
for (String example : rule.getExamples()) {
138+
result.append(example);
139+
result.append(System.lineSeparator());
140+
result.append(System.lineSeparator());
141+
}
142+
return result.toString();
143+
}
144+
145+
private static final class LinkClickListener implements SelectionListener {
146+
@Override
147+
public void widgetSelected(SelectionEvent e) {
148+
try {
149+
URL url = new URL(e.text);
150+
IWebBrowser browser = PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser();
151+
browser.openURL(url);
152+
} catch (MalformedURLException | PartInitException e1) {
153+
PMDPlugin.getDefault().logError(e1.getMessage(), e1);
154+
}
155+
}
156+
157+
@Override
158+
public void widgetDefaultSelected(SelectionEvent e) {
159+
widgetSelected(e);
160+
}
161+
}
162+
}

net.sourceforge.pmd.eclipse.plugin/src/main/java/net/sourceforge/pmd/eclipse/ui/nls/StringKeys.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,16 @@ public final class StringKeys {
251251
public static final String VIEW_MENU_PACKFILES = "view.menu.show_pack_files";
252252
public static final String VIEW_MENU_PRESENTATION_TYPE = "view.menu.show_type";
253253

254+
public static final String DIALOG_VIOLATION_DETAILS_TITLE = "dialog.violation_details.title";
255+
public static final String DIALOG_VIOLATION_DETAILS_LOCATION = "dialog.violation_details.location";
256+
public static final String DIALOG_VIOLATION_DETAILS_EXAMPLES = "dialog.violation_details.examples";
257+
public static final String DIALOG_VIOLATION_DETAILS_MESSAGE = "dialog.violation_details.message";
258+
public static final String DIALOG_VIOLATION_DETAILS_RULENAME = "dialog.violation_details.rulename";
259+
public static final String DIALOG_VIOLATION_DETAILS_CATEGORY = "dialog.violation_details.category";
260+
public static final String DIALOG_VIOLATION_DETAILS_PRIORITY = "dialog.violation_details.priority";
261+
public static final String DIALOG_VIOLATION_DETAILS_DESCRIPTION = "dialog.violation_details.description";
262+
public static final String DIALOG_VIOLATION_DETAILS_INFOURL = "dialog.violation_details.infourl";
263+
254264
public static final String DIALOG_PREFS_ADD_NEW_PROPERTY = "dialog.preferences.add_new_property";
255265

256266
public static final String RULEEDIT_LABEL_MIN = "preference.ruleedit.label.min";

0 commit comments

Comments
 (0)