/******************************************************************************* * Copyright (c) 2016 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.eclipse.cdt.arduino.ui.internal; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.cdt.arduino.core.internal.board.ArduinoLibrary; import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager; import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.viewers.BaseLabelProvider; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.ICheckStateProvider; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.ui.dialogs.FilteredTree; import org.eclipse.ui.dialogs.PatternFilter; public class LibraryTree extends FilteredTree { private static final String PLATFORMS = "Platform Libraries"; private static final String UNCATEGORIZED = "Others"; private boolean includePlatforms; private Set<ArduinoLibrary> checkedLibs = new HashSet<>(); private ArduinoManager manager = Activator.getService(ArduinoManager.class); private static class LibPatternFilter extends PatternFilter { @Override protected boolean isLeafMatch(Viewer viewer, Object element) { if (element instanceof String) { return wordMatches((String) element); } else if (element instanceof ArduinoLibrary) { ArduinoLibrary lib = (ArduinoLibrary) element; return wordMatches(lib.getName()) || wordMatches(lib.getSentence()) || wordMatches(lib.getParagraph()); } else { return false; } } } public class ContentProvider implements ITreeContentProvider { public Map<String, List<ArduinoLibrary>> categories = new HashMap<>(); public List<ArduinoLibrary> uncategorized; @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { if (newInput == null) { return; } @SuppressWarnings("unchecked") Collection<ArduinoLibrary> libraries = (Collection<ArduinoLibrary>) newInput; for (ArduinoLibrary library : libraries) { if (library.getPlatform() == null) { String category = library.getCategory(); if (category != null) { List<ArduinoLibrary> libs = categories.get(category); if (libs == null) { libs = new ArrayList<>(); categories.put(category, libs); } libs.add(library); } else { if (uncategorized == null) { uncategorized = new ArrayList<>(); } uncategorized.add(library); } } } } @Override public Object[] getElements(Object inputElement) { List<String> elements = new ArrayList<>(categories.keySet()); Collections.sort(elements, (o1, o2) -> o1.compareToIgnoreCase(o2)); if (uncategorized != null) { elements.add(UNCATEGORIZED); } if (includePlatforms) { elements.add(PLATFORMS); } return elements.toArray(); } @Override public Object[] getChildren(Object parentElement) { if (parentElement instanceof String) { if (parentElement == UNCATEGORIZED) { return uncategorized.toArray(); } else if (parentElement == PLATFORMS) { List<ArduinoPlatform> platforms = new ArrayList<>(); try { for (ArduinoPlatform platform : manager.getInstalledPlatforms()) { if (!platform.getLibraries().isEmpty()) { platforms.add(platform); } } } catch (CoreException e) { Activator.log(e); } Collections.sort(platforms, (o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName())); return platforms.toArray(); } else { String category = (String) parentElement; List<ArduinoLibrary> libs = categories.get(category); Collections.sort(libs, (o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName())); return libs.toArray(); } } else if (parentElement instanceof ArduinoPlatform) { try { List<ArduinoLibrary> libs = new ArrayList<>(((ArduinoPlatform) parentElement).getLibraries()); Collections.sort(libs, (o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName())); return libs.toArray(); } catch (CoreException e) { Activator.log(e); } } return null; } @Override public Object getParent(Object element) { if (element instanceof ArduinoLibrary) { ArduinoLibrary library = (ArduinoLibrary) element; ArduinoPlatform platform = library.getPlatform(); if (platform != null) { return platform; } String category = library.getCategory(); return category != null ? category : UNCATEGORIZED; } else if (element instanceof ArduinoPlatform) { return ((ArduinoPlatform) element).getName(); } return null; } @Override public boolean hasChildren(Object element) { return element instanceof String || element instanceof ArduinoPlatform; } } private static class LabelProvider extends BaseLabelProvider implements ITableLabelProvider { @Override public Image getColumnImage(Object element, int columnIndex) { return null; } @Override public String getColumnText(Object element, int columnIndex) { if (element instanceof String) { return columnIndex == 0 ? (String) element : null; } else if (element instanceof ArduinoPlatform) { return columnIndex == 0 ? ((ArduinoPlatform) element).getName() : null; } else if (element instanceof ArduinoLibrary) { ArduinoLibrary library = (ArduinoLibrary) element; switch (columnIndex) { case 0: return library.getName(); case 1: return library.getVersion(); case 2: return library.getSentence(); default: return null; } } else { return null; } } } public LibraryTree(Composite parent) { super(parent, SWT.CHECK | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL, new LibPatternFilter(), true); TreeViewer viewer = getViewer(); viewer.setContentProvider(new ContentProvider()); viewer.setLabelProvider(new LabelProvider()); Tree tree = viewer.getTree(); tree.setHeaderVisible(true); TreeColumn column1 = new TreeColumn(tree, SWT.LEFT); column1.setText("Library"); column1.setWidth(200); TreeColumn column2 = new TreeColumn(tree, SWT.LEFT); column2.setText("Version"); column2.setWidth(100); TreeColumn column3 = new TreeColumn(tree, SWT.LEFT); column3.setText("Description"); column3.setWidth(300); } public void setIncludePlatforms(boolean includePlatforms) { this.includePlatforms = includePlatforms; } public void setChecked(Collection<ArduinoLibrary> checkedLibs) { this.checkedLibs = new HashSet<>(checkedLibs); } public Collection<ArduinoLibrary> getChecked() { return checkedLibs; } @Override protected TreeViewer doCreateTreeViewer(Composite parent, int style) { CheckboxTreeViewer viewer = new CheckboxTreeViewer(parent, style); viewer.setCheckStateProvider(new ICheckStateProvider() { @Override public boolean isGrayed(Object element) { if (element instanceof String) { String category = (String) element; if (category == PLATFORMS) { for (ArduinoLibrary lib : checkedLibs) { if (lib.getPlatform() != null) { return true; } } } else if (category == UNCATEGORIZED) { for (ArduinoLibrary lib : checkedLibs) { if (lib.getPlatform() == null && lib.getCategory() == null) { return true; } } } else { for (ArduinoLibrary lib : checkedLibs) { if (element.equals(lib.getCategory())) { return true; } } } } else if (element instanceof ArduinoPlatform) { for (ArduinoLibrary lib : checkedLibs) { if (element == lib.getPlatform()) { return true; } } } return false; } @Override public boolean isChecked(Object element) { if (element instanceof ArduinoLibrary) { return checkedLibs.contains(element); } else { return isGrayed(element); } } }); viewer.addCheckStateListener(new ICheckStateListener() { @Override public void checkStateChanged(CheckStateChangedEvent event) { Object element = event.getElement(); if (element instanceof ArduinoLibrary) { if (event.getChecked()) { checkedLibs.add((ArduinoLibrary) element); } else { checkedLibs.remove(element); } } else if (element instanceof String) { if (!event.getChecked()) { for (ArduinoLibrary lib : new ArrayList<>(checkedLibs)) { if (element.equals(lib.getCategory())) { checkedLibs.remove(lib); } } } } } }); return viewer; } }