1 package com.stateofflow.eclipse.metrics.properties.exclusions;
2
3 import java.io.IOException;
4 import java.util.Iterator;
5
6 import org.apache.oro.text.regex.MalformedPatternException;
7 import org.eclipse.core.resources.IFile;
8 import org.eclipse.core.resources.IProject;
9 import org.eclipse.core.runtime.CoreException;
10 import org.eclipse.core.runtime.IStatus;
11 import org.eclipse.core.runtime.Status;
12 import org.eclipse.jface.dialogs.ErrorDialog;
13 import org.eclipse.jface.dialogs.IInputValidator;
14 import org.eclipse.jface.dialogs.InputDialog;
15 import org.eclipse.jface.viewers.ISelectionChangedListener;
16 import org.eclipse.jface.viewers.IStructuredSelection;
17 import org.eclipse.jface.viewers.SelectionChangedEvent;
18 import org.eclipse.jface.viewers.TableViewer;
19 import org.eclipse.jface.window.Window;
20 import org.eclipse.swt.SWT;
21 import org.eclipse.swt.layout.GridData;
22 import org.eclipse.swt.layout.GridLayout;
23 import org.eclipse.swt.widgets.Composite;
24 import org.eclipse.ui.dialogs.ResourceSelectionDialog;
25
26 import com.stateofflow.eclipse.metrics.MetricsPlugin;
27 import com.stateofflow.eclipse.metrics.properties.exclusions.table.TableViewerBuilder;
28
29 public final class View extends Composite {
30 private final ExcludedResources excludedResources;
31 private final TableViewer tableViewer;
32
33 public View(final Composite parent, final IProject project) throws IOException {
34 super(parent, SWT.NULL);
35 excludedResources = new ExcludedResources(project);
36
37 setLayout(new GridLayout());
38 setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));
39
40 tableViewer = new TableViewerBuilder().create(this, excludedResources);
41 final ButtonPanel buttons = new ButtonPanel(this);
42 addSelectionChangedListenerToTable(buttons);
43 }
44
45 void addExcludedFile() {
46 final ResourceSelectionDialog dialog = new ResourceSelectionDialog(getShell(), excludedResources.getProject(), "Select resources to exclude");
47 dialog.setInitialSelections(excludedResources.getFiles());
48 dialog.open();
49 final Object[] resources = dialog.getResult();
50 if (resources != null) {
51 addFilesToExcludedResources(resources);
52 }
53 }
54
55 private void addFilesToExcludedResources(final Object[] resources) {
56 excludedResources.clearFiles();
57 for (final Object resource : resources) {
58 if (resource instanceof IFile) {
59 excludedResources.addFile((IFile) resource);
60 }
61 }
62
63 tableViewer.refresh();
64 }
65
66 void addRegex() {
67 final InputDialog dialog = openRegexDialog("");
68 if (dialog.getReturnCode() == Window.OK) {
69 addRegex(dialog.getValue());
70 }
71 }
72
73 private void addRegex(final String regex) {
74 final String trimmedRegex = regex.trim();
75 if (trimmedRegex.length() == 0) {
76 return;
77 }
78
79 addTrimmedRegex(trimmedRegex);
80
81 tableViewer.refresh();
82 }
83
84 private void addSelectionChangedListenerToTable(final ButtonPanel buttons) {
85 tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
86 public void selectionChanged(final SelectionChangedEvent event) {
87 final boolean empty = event.getSelection().isEmpty();
88 buttons.selectionChanged(empty);
89 }
90 });
91 }
92
93 private void addTrimmedRegex(final String trimmedRegex) {
94 try {
95 excludedResources.addRegex(trimmedRegex);
96 } catch (final MalformedPatternException mpex) {
97 ErrorDialog.openError(getShell(), "Invalid regex", null, new Status(IStatus.ERROR, MetricsPlugin.PLUGIN_ID, IStatus.OK, "The string '" + trimmedRegex + "' is not a valid regex.", null));
98 }
99 }
100
101 private void editRegex(final String original) {
102 final InputDialog dialog = openRegexDialog(original);
103 if (dialog.getReturnCode() == Window.OK) {
104 excludedResources.removeRegex(original);
105 addRegex(dialog.getValue());
106 }
107 }
108
109 private void editResource(final Object firstSelectedItem) {
110 if (firstSelectedItem instanceof String) {
111 editRegex((String) firstSelectedItem);
112 } else {
113 addExcludedFile();
114 }
115 }
116
117 void editSelectedResource() {
118 final IStructuredSelection selection = (IStructuredSelection) tableViewer.getSelection();
119 if (selection.isEmpty()) {
120 return;
121 }
122
123 editResource(selection.getFirstElement());
124 }
125
126 public boolean isModified() {
127 return excludedResources.isModified();
128 }
129
130 private InputDialog openRegexDialog(final String initialValue) {
131 final InputDialog dialog = new InputDialog(getShell(), "Regex Entry", "Enter a regex", initialValue, new IInputValidator() {
132 public String isValid(final String regex) {
133 return excludedResources.isValidRegex(regex.trim()) ? null : (String) "Not a valid regex";
134 }
135 });
136 dialog.setBlockOnOpen(true);
137 dialog.open();
138 return dialog;
139 }
140
141 void removeSelectedExclusions() {
142 final IStructuredSelection selection = (IStructuredSelection) tableViewer.getSelection();
143 if (selection.isEmpty()) {
144 return;
145 }
146
147 removeSelectedExclusions(selection);
148 tableViewer.refresh();
149 }
150
151 private void removeSelectedExclusions(final IStructuredSelection selection) {
152 @SuppressWarnings("unchecked")
153 final Iterator<Object> iter = selection.iterator();
154 while (iter.hasNext()) {
155 final Object toRemove = iter.next();
156 if (toRemove instanceof String) {
157 excludedResources.removeRegex((String) toRemove);
158 } else {
159 excludedResources.removeFile((IFile) toRemove);
160 }
161 }
162 }
163
164 public void store() throws CoreException {
165 excludedResources.store();
166 }
167 }
168