Library Manager: added Type filter dropdown

This commit is contained in:
Federico Fissore 2015-03-26 10:40:58 +01:00
parent 6679393b7a
commit b0a357f5d3
10 changed files with 161 additions and 35 deletions

View File

@ -0,0 +1,24 @@
package cc.arduino.contributions.libraries.filters;
import cc.arduino.contributions.libraries.ContributedLibrary;
import com.google.common.base.Predicate;
public class TypePredicate implements Predicate<ContributedLibrary> {
private final String type;
public TypePredicate(String type) {
this.type = type;
}
@Override
public boolean apply(ContributedLibrary input) {
return input.getTypes() != null && input.getTypes().contains(type);
}
@Override
public boolean equals(Object obj) {
return obj instanceof TypePredicate && ((TypePredicate) obj).type.equals(type);
}
}

View File

@ -0,0 +1,25 @@
package cc.arduino.contributions.libraries.ui;
import cc.arduino.contributions.libraries.ContributedLibrary;
import cc.arduino.contributions.libraries.filters.CategoryPredicate;
import cc.arduino.contributions.libraries.filters.TypePredicate;
import cc.arduino.contributions.ui.DropdownItem;
import com.google.common.base.Predicate;
public class DropdownLibraryOfTypeItem implements DropdownItem<ContributedLibrary> {
private final String type;
public DropdownLibraryOfTypeItem(String type) {
this.type = type;
}
public String toString() {
return type;
}
@Override
public Predicate<ContributedLibrary> getFilterPredicate() {
return new TypePredicate(type);
}
}

View File

@ -34,6 +34,7 @@ import cc.arduino.contributions.packages.ContributedPlatform;
import cc.arduino.contributions.VersionComparator;
import cc.arduino.contributions.ui.FilteredAbstractTableModel;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import java.util.*;
@ -137,8 +138,8 @@ public class LibrariesIndexTableModel extends FilteredAbstractTableModel<Contrib
Predicate<ContributedLibrary> selectedCategoryFilter = null;
String selectedFilters[] = null;
public void updateIndexFilter(Predicate<ContributedLibrary> categoryFilter, String filters[]) {
selectedCategoryFilter = categoryFilter;
public void updateIndexFilter(String filters[], Predicate<ContributedLibrary>... additionalFilters) {
selectedCategoryFilter = Predicates.and(additionalFilters);
selectedFilters = filters;
update();
}

View File

@ -33,17 +33,23 @@ import cc.arduino.contributions.libraries.LibrariesIndexer;
import cc.arduino.contributions.packages.ui.InstallerJDialogUncaughtExceptionHandler;
import cc.arduino.contributions.ui.*;
import cc.arduino.utils.Progress;
import com.google.common.base.Predicate;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Collection;
import static processing.app.I18n._;
@SuppressWarnings("serial")
public class LibraryManagerUI extends InstallerJDialog {
public class LibraryManagerUI extends InstallerJDialog<ContributedLibrary> {
private LibrariesIndexer indexer;
private final JComboBox typeChooser;
private Predicate<ContributedLibrary> typeFilter;
@Override
protected FilteredAbstractTableModel createContribModel() {
@ -80,11 +86,46 @@ public class LibraryManagerUI extends InstallerJDialog {
public LibraryManagerUI(Frame parent) {
super(parent, "Library Manager", Dialog.ModalityType.APPLICATION_MODAL, _("No internet connection available, the list of available libraries is not complete. You will be able to manage only the libraries you've already installed."));
filtersContainer.add(new JLabel(_("Category:")), 1);
filtersContainer.remove(2);
typeChooser = new JComboBox();
typeChooser.setMaximumRowCount(20);
typeChooser.setEnabled(false);
filtersContainer.add(Box.createHorizontalStrut(5), 0);
filtersContainer.add(new JLabel(_("Type:")), 1);
filtersContainer.add(typeChooser, 2);
}
protected final ActionListener typeChooserActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
DropdownItem<ContributedLibrary> selected = (DropdownItem<ContributedLibrary>) typeChooser.getSelectedItem();
if (typeFilter == null || !typeFilter.equals(selected)) {
typeFilter = selected.getFilterPredicate();
if (contribTable.getCellEditor() != null) {
contribTable.getCellEditor().stopCellEditing();
}
updateIndexFilter(filters, categoryFilter, typeFilter);
}
}
};
@Override
public void updateIndexFilter(String[] filters, Predicate<ContributedLibrary>... additionalFilters) {
if (additionalFilters.length == 1) {
additionalFilters = new Predicate[] { additionalFilters[0], typeFilter };
}
super.updateIndexFilter(filters, additionalFilters);
}
public void setIndexer(LibrariesIndexer indexer) {
this.indexer = indexer;
categoryChooser.removeActionListener(categoryChooserActionListener);
typeChooser.removeActionListener(typeChooserActionListener);
// TODO: Remove setIndexer and make getContribModel
// return a FilteredAbstractTableModel
@ -93,8 +134,6 @@ public class LibraryManagerUI extends InstallerJDialog {
categoryFilter = null;
categoryChooser.removeAllItems();
categoryChooser.addActionListener(categoryChooserActionListener);
// Load categories
categoryChooser.addItem(new DropdownAllItem());
categoryChooser.addItem(new DropdownInstalledContributionItem());
@ -104,9 +143,21 @@ public class LibraryManagerUI extends InstallerJDialog {
categoryChooser.addItem(new DropdownLibraryOfCategoryItem(category));
}
// Enable categories combo only if there are two or more choices
int count = categoryChooser.getItemCount();
categoryChooser.setEnabled(count > 1);
categoryChooser.setEnabled(categoryChooser.getItemCount() > 1);
categoryChooser.addActionListener(categoryChooserActionListener);
categoryChooser.setSelectedIndex(0);
typeFilter = null;
typeChooser.removeAllItems();
typeChooser.addItem(new DropdownAllItem());
Collection<String> types = indexer.getIndex().getTypes();
for (String type : types) {
typeChooser.addItem(new DropdownLibraryOfTypeItem(type));
}
typeChooser.setEnabled(typeChooser.getItemCount() > 1);
typeChooser.addActionListener(typeChooserActionListener);
typeChooser.setSelectedIndex(1);
filterField.setEnabled(contribModel.getRowCount() > 0);

View File

@ -33,6 +33,7 @@ import cc.arduino.contributions.packages.ContributedPlatform;
import cc.arduino.contributions.packages.ContributionsIndex;
import cc.arduino.contributions.ui.FilteredAbstractTableModel;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import java.util.ArrayList;
import java.util.LinkedList;
@ -136,11 +137,12 @@ public class ContributionIndexTableModel extends FilteredAbstractTableModel<Cont
index = _index;
}
public void updateIndexFilter(Predicate<ContributedPlatform> categoryFilter, String filters[]) {
public void updateIndexFilter(String filters[], Predicate<ContributedPlatform>... additionalFilters) {
contributions.clear();
Predicate<ContributedPlatform> filter = Predicates.and(additionalFilters);
for (ContributedPackage pack : index.getPackages()) {
for (ContributedPlatform platform : pack.getPlatforms()) {
if (!categoryFilter.apply(platform)) {
if (!filter.apply(platform)) {
continue;
}
if (!stringContainsAll(platform.getName(), filters))

View File

@ -34,6 +34,6 @@ import javax.swing.table.AbstractTableModel;
public abstract class FilteredAbstractTableModel<T> extends AbstractTableModel {
abstract public void updateIndexFilter(Predicate<T> categoryFilter, String[] filters);
abstract public void updateIndexFilter(String[] filters, Predicate<T>... additionalFilters);
}

View File

@ -28,8 +28,11 @@
*/
package cc.arduino.contributions.ui;
import cc.arduino.contributions.packages.ui.ContributionIndexTableModel;
import cc.arduino.contributions.ui.listeners.AbstractKeyListener;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import processing.app.Base;
import processing.app.Theme;
@ -42,6 +45,9 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import static cc.arduino.contributions.packages.ui.ContributionIndexTableModel.DESCRIPTION_COL;
import static processing.app.I18n._;
@ -50,13 +56,10 @@ public abstract class InstallerJDialog<T> extends JDialog {
// Toolbar on top of the window:
// - Categories drop-down menu
protected final JLabel categoryLabel;
protected final JComboBox categoryChooser;
protected final Component categoryStrut1;
protected final Component categoryStrut2;
protected final Component categoryStrut3;
// - Search text-field
protected final FilterJTextField filterField;
protected final JPanel filtersContainer;
// Currently selected category and filters
protected Predicate<T> categoryFilter;
protected String[] filters;
@ -65,7 +68,7 @@ public abstract class InstallerJDialog<T> extends JDialog {
// Real contribution table
protected JTable contribTable;
// Model behind the table
protected FilteredAbstractTableModel contribModel;
protected FilteredAbstractTableModel<T> contribModel;
abstract protected FilteredAbstractTableModel createContribModel();
@ -90,12 +93,6 @@ public abstract class InstallerJDialog<T> extends JDialog {
pane.setLayout(new BorderLayout());
{
categoryStrut1 = Box.createHorizontalStrut(5);
categoryStrut2 = Box.createHorizontalStrut(5);
categoryStrut3 = Box.createHorizontalStrut(5);
categoryLabel = new JLabel(_("Category:"));
categoryChooser = new JComboBox();
categoryChooser.setMaximumRowCount(20);
categoryChooser.setEnabled(false);
@ -107,20 +104,20 @@ public abstract class InstallerJDialog<T> extends JDialog {
if (contribTable.getCellEditor() != null) {
contribTable.getCellEditor().stopCellEditing();
}
contribModel.updateIndexFilter(categoryFilter, filters);
updateIndexFilter(filters, categoryFilter);
}
};
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.add(categoryStrut1);
panel.add(categoryLabel);
panel.add(categoryStrut2);
panel.add(categoryChooser);
panel.add(categoryStrut3);
panel.add(filterField);
panel.setBorder(new EmptyBorder(7, 7, 7, 7));
pane.add(panel, BorderLayout.NORTH);
filtersContainer = new JPanel();
filtersContainer.setLayout(new BoxLayout(filtersContainer, BoxLayout.X_AXIS));
filtersContainer.add(Box.createHorizontalStrut(5));
filtersContainer.add(new JLabel(_("Type:")));
filtersContainer.add(Box.createHorizontalStrut(5));
filtersContainer.add(categoryChooser);
filtersContainer.add(Box.createHorizontalStrut(5));
filtersContainer.add(filterField);
filtersContainer.setBorder(new EmptyBorder(7, 7, 7, 7));
pane.add(filtersContainer, BorderLayout.NORTH);
}
contribModel = createContribModel();
@ -216,7 +213,7 @@ public abstract class InstallerJDialog<T> extends JDialog {
}
setProgressVisible(false, "");
setMinimumSize(new Dimension(600, 450));
setMinimumSize(new Dimension(800, 450));
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
@ -235,6 +232,11 @@ public abstract class InstallerJDialog<T> extends JDialog {
});
}
public void updateIndexFilter(String[] filters, Predicate<T>... additionalFilters) {
Collection<Predicate<T>> notNullAdditionalFilters = Collections2.filter(Arrays.asList(additionalFilters), Predicates.notNull());
contribModel.updateIndexFilter(filters, notNullAdditionalFilters.toArray(new Predicate[notNullAdditionalFilters.size()]));
}
public void setErrorMessage(String message) {
errorMessage.setText("<html><body>" + message + "</body></html>");
errorMessageBox.setVisible(true);
@ -273,7 +275,7 @@ public abstract class InstallerJDialog<T> extends JDialog {
if (contribTable.getCellEditor() != null) {
contribTable.getCellEditor().stopCellEditing();
}
contribModel.updateIndexFilter(categoryFilter, filters);
updateIndexFilter(filters, categoryFilter);
}
}
};

View File

@ -62,6 +62,8 @@ public abstract class ContributedLibrary extends DownloadableContribution {
public abstract List<String> getArchitectures();
public abstract List<String> getTypes();
public abstract List<ContributedLibraryReference> getRequires();
private boolean readOnly;

View File

@ -62,4 +62,18 @@ public abstract class LibrariesIndex {
return categories;
}
public List<String> getTypes() {
Collection<String> typesAccumulator = new HashSet<String>();
for (ContributedLibrary lib : getLibraries()) {
if (lib.getTypes() != null) {
typesAccumulator.addAll(lib.getTypes());
}
}
List<String> types = new LinkedList<String>(typesAccumulator);
Collections.sort(types);
return types;
}
}

View File

@ -190,6 +190,11 @@ public class UserLibrary extends ContributedLibrary {
return category;
}
@Override
public List<String> getTypes() {
return Arrays.asList("Contributed");
}
@Override
public String getLicense() {
return license;