/* * Contributions to FindBugs * Copyright (C) 2010, Andrei Loskutov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package de.tobject.findbugs.properties; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.ICheckStateProvider; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Widget; import de.tobject.findbugs.builder.FindBugsWorker; abstract class PathsProvider extends SelectionAdapter implements IStructuredContentProvider, ICheckStateProvider { private static IPath lastUsedPath; protected final List<IPathElement> paths; private final Control control; private final TableViewer viewer; protected final FindbugsPropertyPage propertyPage; private final ListenerList listeners; protected PathsProvider(TableViewer viewer, FindbugsPropertyPage propertyPage) { this.propertyPage = propertyPage; this.paths = new ArrayList<IPathElement>(); this.viewer = viewer; if(viewer instanceof CheckboxTableViewer) { CheckboxTableViewer tv = (CheckboxTableViewer) viewer; tv.setCheckStateProvider(this); tv.addCheckStateListener(new ICheckStateListener() { public void checkStateChanged(CheckStateChangedEvent event) { boolean checked = event.getChecked(); IPathElement element = (IPathElement) event.getElement(); element.setEnabled(checked); handleContendChanged(); } }); } this.control = viewer.getTable(); listeners = new ListenerList(); viewer.setContentProvider(this); } static void setLastUsedPath(IPath lastUsed) { // TODO write to preferences lastUsedPath = lastUsed; } static IPath getLastUsedPath() { // TODO read from preferences return lastUsedPath; } void setFilters(List<IPathElement> filterFiles) { paths.clear(); paths.addAll(filterFiles); if(viewer instanceof CheckboxTableViewer) { CheckboxTableViewer tv = (CheckboxTableViewer) viewer; List<IPathElement> checked = new ArrayList<IPathElement>(); for (IPathElement pe : paths) { if(pe.isEnabled()) { checked.add(pe); } } tv.setCheckedElements(checked.toArray(new IPathElement[checked.size()])); } } @Override public void widgetSelected(SelectionEvent e) { Widget widget = e.widget; String buttonId = widget.getData() + ""; if (buttonId.equals("add")) { addFiles(e.display.getActiveShell()); } else { Iterator<?> selectionIter = ((IStructuredSelection) viewer.getSelection()).iterator(); while (selectionIter.hasNext()) { remove((IPathElement) selectionIter.next()); } } } public void addListener(Listener listener) { listeners.add(listener); } public void addFiles(Shell parentShell) { FileDialog dialog = createFileDialog(parentShell); // The validator checks to see if the user's selection // is valid given the type of the object selected (e.g. // it can't be a folder) and the objects that have // already been selected String pathStr = openFileDialog(dialog); if (pathStr == null) { return; } addSelectedPaths(dialog); handleContendChanged(); } private FileDialog createFileDialog(Shell parentShell) { FileDialog dialog = new FileDialog(parentShell, SWT.OPEN | SWT.MULTI); configureDialog(dialog); IPath lastUsed = getLastUsedPath(); String filterPath = null; if (lastUsed != null && lastUsed.toFile().isDirectory()) { filterPath = lastUsed.toOSString(); dialog.setFilterPath(filterPath); } return dialog; } abstract protected void configureDialog(FileDialog dialog); protected String openFileDialog(FileDialog dialog) { return dialog.open(); } protected String[] getFileNames(FileDialog dialog) { return dialog.getFileNames(); } protected String getFilePath(FileDialog dialog) { return dialog.getFilterPath(); } private void addSelectedPaths(FileDialog dialog) { String[] names = getFileNames(dialog); String filterPath = getFilePath(dialog); Path baseDir = new Path(filterPath); setLastUsedPath(baseDir); for (String fileName : names) { IPath path = baseDir.append(fileName); PathElement pathElt = new PathElement(path, Status.OK_STATUS); if (!paths.contains(pathElt)) { paths.add(pathElt); } } } public void dispose() { // } public void inputChanged(Viewer viewer1, Object oldInput, Object newInput) { // } public Object[] getElements(Object inputElement) { return paths.toArray(); } public boolean isChecked(Object element) { if(element instanceof IPathElement) { IPathElement elt = (IPathElement) element; return elt.isEnabled(); } return false; } public boolean isGrayed(Object element) { return false; } boolean contains(Object o) { return paths.contains(o); } void setControlEnabled(boolean enabled) { control.setEnabled(enabled); } void refresh() { IStatus status = validate(); if (status != null) { propertyPage.setErrorMessage(status.getMessage()); } viewer.setSelection(null); viewer.setInput(new Object()); viewer.refresh(true); } abstract protected IStatus validate(); public void remove(IPathElement holder) { paths.remove(holder); handleContendChanged(); } private void handleContendChanged() { applyToPreferences(); for (Object object : listeners.getListeners()) { ((Listener) object).handleEvent(null); } } protected void applyToPreferences() { IStatus status = validate(); if (status != null) { propertyPage.setErrorMessage(status.getMessage()); } } protected Map<String, Boolean> pathsToStrings() { IProject project = propertyPage.getProject(); Map<String, Boolean> result = new TreeMap<String, Boolean>(); for (IPathElement path : paths) { IPath filterPath = FindBugsWorker.toFilterPath(path.getPath(), project); result.put(filterPath.toPortableString(), Boolean.valueOf(path.isEnabled())); } return result; } }