/* * Created on 13.10.2006 * * Copyright (c) 2006, PMD for Eclipse Development Team * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The end-user documentation included with the redistribution, if * any, must include the following acknowledgement: * "This product includes software developed in part by support from * the Defense Advanced Research Project Agency (DARPA)" * * Neither the name of "PMD for Eclipse Development Team" nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package net.sourceforge.pmd.eclipse.ui.views.cpd; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import net.sourceforge.pmd.cpd.Mark; import net.sourceforge.pmd.cpd.Match; import net.sourceforge.pmd.eclipse.plugin.PMDPlugin; import net.sourceforge.pmd.eclipse.runtime.PMDRuntimeConstants; import net.sourceforge.pmd.eclipse.ui.nls.StringKeys; import org.eclipse.jface.viewers.TreeNode; import org.eclipse.jface.viewers.TreeNodeContentProvider; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.ui.IPropertyListener; import org.eclipse.ui.IViewSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.ViewPart; /** * A class for showing the Copy / Paste Detection View. * * @author Sven * */ public class CPDView extends ViewPart implements IPropertyListener { private TreeViewer treeViewer; private TreeNodeContentProvider contentProvider; private CPDViewLabelProvider labelProvider; private CPDViewDoubleClickEventListener doubleClickListener; private CPDViewTooltipListener tooltipListener; private static final int MAX_MATCHES = 100; /* * @see org.eclipse.ui.ViewPart#init(org.eclipse.ui.IViewSite) */ @Override public void init(IViewSite site) throws PartInitException { super.init(site); contentProvider = new TreeNodeContentProvider(); labelProvider = new CPDViewLabelProvider(); doubleClickListener = new CPDViewDoubleClickEventListener(this); tooltipListener = new CPDViewTooltipListener(this); } /* * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) */ @Override public void createPartControl(Composite parent) { int treeStyle = SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION; treeViewer = new TreeViewer(parent, treeStyle); treeViewer.setUseHashlookup(true); Tree tree = treeViewer.getTree(); tree.setHeaderVisible(true); tree.setLinesVisible(true); treeViewer.setContentProvider(contentProvider); treeViewer.setLabelProvider(labelProvider); treeViewer.addDoubleClickListener(doubleClickListener); tooltipListener.initialize(); tree.addListener(SWT.Dispose, tooltipListener); tree.addListener(SWT.KeyDown, tooltipListener); tree.addListener(SWT.MouseMove, tooltipListener); tree.addListener(SWT.MouseHover, tooltipListener); createColumns(tree); } /** * Creates the columns of the tree. * @param tree Tree from the treeViewer */ private void createColumns(Tree tree) { // the "+"-sign for expanding packages final TreeColumn plusColumn = new TreeColumn(tree, SWT.RIGHT); plusColumn.setWidth(20); // plusColumn.setResizable(false); // shows the image TreeColumn imageColumn = new TreeColumn(tree, SWT.CENTER); imageColumn.setWidth(20); // imageColumn.setResizable(false); // shows the message TreeColumn messageColumn = new TreeColumn(tree, SWT.LEFT); messageColumn.setText(getString(StringKeys.VIEW_COLUMN_MESSAGE)); messageColumn.setWidth(300); // shows the class TreeColumn classColumn = new TreeColumn(tree, SWT.LEFT); classColumn.setText(getString(StringKeys.VIEW_COLUMN_CLASS)); classColumn.setWidth(300); } /** * @return the tree viewer. */ public TreeViewer getTreeViewer() { return treeViewer; } /** * Helper method to return an NLS string from its key */ private String getString(String key) { return PMDPlugin.getDefault().getStringTable().getString(key); } /* * @see org.eclipse.ui.part.WorkbenchPart#setFocus() */ @Override public void setFocus() { treeViewer.getTree().setFocus(); } /** * Sets input for the table. * @param matches CPD Command that contain the matches from the CPD */ public void setData(Iterator<Match> matches) { List<TreeNode> elements = new ArrayList<TreeNode>(); if (matches != null) { // iterate the matches for (int count = 0; matches.hasNext() && count < MAX_MATCHES; count++) { Match match = matches.next(); // create a treenode for the match and add to the list TreeNode matchNode = new TreeNode(match); // NOPMD by Sven on 02.11.06 11:27 elements.add(matchNode); // create the children of the match TreeNode[] children = new TreeNode[match.getMarkCount()]; // NOPMD by Sven on 02.11.06 11:28 Iterator<Mark> entryIterator = match.getMarkSet().iterator(); for (int j=0; entryIterator.hasNext(); j++) { final Mark entry = entryIterator.next(); children[j] = new TreeNode(entry); // NOPMD by Sven on 02.11.06 11:28 children[j].setParent(matchNode); } matchNode.setChildren(children); } } // set the children of the rootnode: the matches treeViewer.setInput(elements.toArray(new TreeNode[elements.size()])); } /** * After the CPD command is executed, it will trigger an propertyChanged event. */ public void propertyChanged(Object source, int propId) { if (propId == PMDRuntimeConstants.PROPERTY_CPD && source instanceof Iterator<?>) { Iterator<Match> iter = (Iterator<Match>) source; // after setdata(iter) iter.hasNext will always return false boolean hasResults = iter.hasNext(); setData(iter); if (!hasResults) { // no entries MessageBox box = new MessageBox(this.treeViewer.getControl().getShell()); box.setText(getString(StringKeys.DIALOG_CPD_NORESULTS_HEADER)); box.setMessage(getString(StringKeys.DIALOG_CPD_NORESULTS_BODY)); box.open(); } } } }