package org.openslx.dozmod.gui.control; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import javax.swing.BoxLayout; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.RowFilter; import javax.swing.UIManager; import javax.swing.border.TitledBorder; import org.apache.log4j.Logger; import org.openslx.bwlp.thrift.iface.ImageSummaryRead; import org.openslx.bwlp.thrift.iface.UserInfo; import org.openslx.dozmod.gui.Gui; import org.openslx.dozmod.gui.control.table.ImageTable; import org.openslx.dozmod.gui.control.table.ListTable.ListModel; import org.openslx.dozmod.gui.control.table.QScrollPane; import org.openslx.dozmod.gui.helper.GridManager; import org.openslx.dozmod.gui.helper.TextChangeListener; import org.openslx.dozmod.permissions.ImagePerms; import org.openslx.dozmod.thrift.Session; import org.openslx.dozmod.thrift.cache.ImageCache; import org.openslx.dozmod.thrift.cache.UserCache; import org.openslx.util.QuickTimer; import org.openslx.util.QuickTimer.Task; @SuppressWarnings("serial") public class ImageListViewer extends QLabel { private static final Logger LOGGER = Logger.getLogger(ImageListViewer.class); // search/filter components protected JTextField txtSearch; protected JComboBox cboFilter; protected JLabel imageCountLabel; // image table protected ImageTable imageTable; private final RowFilter, Integer> filterOwn = new RowFilter, Integer>() { public boolean include(Entry, ? extends Integer> entry) { ImageSummaryRead img = imageTable.getModelRow(entry.getIdentifier()); return ImagePerms.canAdmin(img) || img.ownerId.equals(Session.getUserId()); } }; private final RowFilter, Integer> filterUsable = new RowFilter, Integer>() { public boolean include(Entry, ? extends Integer> entry) { ImageSummaryRead img = imageTable.getModelRow(entry.getIdentifier()); return ImagePerms.canLink(img) && img.isValid; } }; private final RowFilter, Integer> filterEditable = new RowFilter, Integer>() { @Override public boolean include(Entry, ? extends Integer> entry) { return ImagePerms.canEdit(imageTable.getModelRow(entry.getIdentifier())); } }; private final RowFilter, Integer> filterTemplate = new RowFilter, Integer>() { public boolean include(Entry, ? extends Integer> entry) { return imageTable.getModelRow(entry.getIdentifier()).isTemplate; } }; private Pattern searchFieldPattern = null; private final RowFilter, Integer> filterSearchTerm = new RowFilter, Integer>() { public boolean include(Entry, ? extends Integer> entry) { ImageSummaryRead image = imageTable.getModelRow(entry.getIdentifier()); if (searchFieldPattern.matcher(image.imageName).find()) return true; UserInfo user = UserCache.find(image.ownerId); if (user == null) return false; if (searchFieldPattern.matcher(user.firstName).find()) return true; if (searchFieldPattern.matcher(user.lastName).find()) return true; if (searchFieldPattern.matcher(user.eMail).find()) return true; return false; } }; public static enum FilterType { ALL("Alle anzeigen"), OWN("Nur eigene/zugewiesene anzeigen"), USABLE("Nur verwendbare/linkbare anzeigen"), EDITABLE("Nur editierbare anzeigen"), TEMPLATES("Nur Vorlagen zeigen"); private final String name; private FilterType(String name) { this.name = name; } @Override public String toString() { return name; } } public ImageListViewer(FilterType defaultFilter) { super(); GridManager grid = new GridManager(this, 1); // -------------------------------------- // the panel for the table and search field // the search field and filter combo box JPanel filterPanel = new JPanel(); filterPanel.setBorder(new TitledBorder("Suchen")); filterPanel.setLayout(new BoxLayout(filterPanel, BoxLayout.LINE_AXIS)); txtSearch = new JTextField(); cboFilter = new JComboBox(); for (FilterType s : FilterType.values()) { cboFilter.addItem(s); } filterPanel.add(txtSearch); filterPanel.add(cboFilter); // Panel for itemCount JPanel imageCountPanel = new JPanel(); imageCountLabel = new JLabel(); imageCountPanel.add(new JLabel("Sichtbar:")); imageCountPanel.add(imageCountLabel); filterPanel.add(imageCountPanel); grid.add(filterPanel).fill(true, false).expand(true, false); grid.nextRow(); // the actual image table imageTable = new ImageTable(); QScrollPane jsp = new QScrollPane(imageTable); jsp.setBackground(UIManager.getColor("Table.background")); grid.add(jsp).fill(true, true).expand(true, true); grid.finish(false); /** * ActionListeners */ // filter the objects in the table depending on the search field txtSearch.getDocument().addDocumentListener(new TextChangeListener() { @Override public void changed() { String str = txtSearch.getText(); if (str == null || str.isEmpty()) { searchFieldPattern = null; } else { try { searchFieldPattern = Pattern.compile(str, Pattern.CASE_INSENSITIVE); txtSearch.setForeground(UIManager.getColor("TextField.foreground")); } catch (PatternSyntaxException ex) { txtSearch.setForeground(Color.RED); } } applyFilterOnTable(); } }); cboFilter.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { applyFilterOnTable(); } }); cboFilter.setSelectedItem(defaultFilter == null ? FilterType.USABLE : defaultFilter); } /** * Filters the image list according to the filter text entered by the user */ private void applyFilterOnTable() { // List for filters List, Integer>> filters = new ArrayList<>(); // string for text in filter text field if (searchFieldPattern != null) { filters.add(filterSearchTerm); } FilterType filterType = (FilterType) cboFilter.getSelectedItem(); switch (filterType) { case ALL: // all.... break; case OWN: // filter for owner filters.add(filterOwn); break; case USABLE: filters.add(filterUsable); break; case EDITABLE: // filter for editable filters.add(filterEditable); break; case TEMPLATES: // show only templates filters.add(filterTemplate); default: break; } // for using multiple filters RowFilter, Integer> andFilters = RowFilter.andFilter(filters); imageTable.getRowSorter().setRowFilter(andFilters); setImageCountLabel(imageTable.getRowCount()); } /** * Refreshes the image list in the table * * @param forceRefresh true to force a refresh, false to use the cached list */ public void refreshList(final boolean forceRefresh, int delay) { QuickTimer.scheduleOnce(new Task() { @Override public void fire() { final List imageList = ImageCache.get(forceRefresh); // Hide virtualizer icon if we only have VMs of one type String virtId = null; boolean m = false; for (ImageSummaryRead isr : imageList) { if (virtId == null) { virtId = isr.virtId; } else if (!virtId.equals(isr.virtId)) { m = true; break; } } final boolean showVirt = m; Gui.asyncExec(new Runnable() { @Override public void run() { imageTable.setData(imageList, true); imageTable.setColumnVisible(ImageTable.COL_HYPERVISOR, showVirt); setImageCountLabel(imageTable.getRowCount()); } }); } }, delay); } public ImageTable getImageTable() { return imageTable; } protected void setImageCountLabel(int i) { imageCountLabel.setText(Integer.toString(i)); } }