diff options
author | Simon Rettberg | 2018-11-26 15:51:31 +0100 |
---|---|---|
committer | Simon Rettberg | 2018-11-26 15:51:31 +0100 |
commit | a06c4dcb0ae2d829350c035d67b603c831088940 (patch) | |
tree | a23d632a9aa0af9861a2e844d13b28bc91caa04a /dozentenmodul | |
parent | [client] Add edit support to ListTable (diff) | |
download | tutor-module-a06c4dcb0ae2d829350c035d67b603c831088940.tar.gz tutor-module-a06c4dcb0ae2d829350c035d67b603c831088940.tar.xz tutor-module-a06c4dcb0ae2d829350c035d67b603c831088940.zip |
[client] Support predefined filters in LDAP editor
Diffstat (limited to 'dozentenmodul')
4 files changed, 269 insertions, 34 deletions
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/LdapFilterConfigurator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/LdapFilterConfigurator.java index 3727b50e..3ba9e74d 100755 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/LdapFilterConfigurator.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/LdapFilterConfigurator.java @@ -5,7 +5,9 @@ import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import javax.swing.BorderFactory; import javax.swing.JButton; @@ -23,10 +25,12 @@ import org.openslx.dozmod.gui.Gui; import org.openslx.dozmod.gui.changemonitor.DialogChangeMonitor; import org.openslx.dozmod.gui.control.QLabel; import org.openslx.dozmod.gui.control.WordWrapLabel; +import org.openslx.dozmod.gui.control.table.CheckListTable.Wrapper; import org.openslx.dozmod.gui.control.table.LectureLdapFilterTable; import org.openslx.dozmod.gui.control.table.QScrollPane; import org.openslx.dozmod.gui.helper.GridManager; import org.openslx.dozmod.gui.helper.MessageType; +import org.openslx.dozmod.thrift.cache.MetaDataCache; /** * Widget for network share configuration of lectures @@ -35,7 +39,6 @@ public class LdapFilterConfigurator extends LdapFilterConfiguratorLayout { private static final long serialVersionUID = -3336605759245603655L; private final static Logger LOGGER = Logger.getLogger(LdapFilterConfigurator.class); - private List<LdapFilter> filterList = null; public LdapFilterConfigurator() { @@ -51,15 +54,19 @@ public class LdapFilterConfigurator extends LdapFilterConfiguratorLayout { tblFilters.getSelectionModel().addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { - LdapFilter item = tblFilters.getSelectedItem(); + LdapFilter item = tblFilters.getSelectedItem2(); if (item == null) { clearInputFields(); return; } // share from the list is selected: fill bottom form and change "Add" to "Apply" - btnDel.setEnabled(true); + boolean editable = (item.filterId == 0); txtAttribute.setText(item.attribute); txtValue.setText(item.value); + txtAttribute.setEditable(editable); + txtValue.setEditable(editable); + btnAdd.setEnabled(editable); + btnDel.setEnabled(editable); btnAdd.setText("Ändern"); } }); @@ -81,21 +88,25 @@ public class LdapFilterConfigurator extends LdapFilterConfiguratorLayout { input.value = ""; } + Wrapper<LdapFilter> newEntry = new Wrapper<LdapFilter>(input, false); + List<Wrapper<LdapFilter>> oldList = tblFilters.getData(); + // either we delete the existing share from the data or we are // creating a new one, either way add it to the list and update // the table, if its not present already - if (filterList.contains(input)) { + if (oldList.contains(newEntry)) { Gui.showMessageBox("Eintrag bereits vorhanden", MessageType.ERROR, null, null); return; } // now decide whether to create a new entry or update existing one - LdapFilter oldEntry = tblFilters.getSelectedItem(); - if (oldEntry != null) { + Wrapper<LdapFilter> oldEntry = tblFilters.getSelectedItem(); + if (oldEntry != null && oldList.contains(oldEntry)) { // editing existing one, delete it from the internal data - filterList.remove(oldEntry); + oldList = new ArrayList<>(oldList); + oldList.remove(oldEntry); } - filterList.add(input); - tblFilters.setData(filterList, false); + oldList.add(newEntry); + tblFilters.setData(oldList, true); clearInputFields(); } }); @@ -104,19 +115,20 @@ public class LdapFilterConfigurator extends LdapFilterConfiguratorLayout { @Override public void actionPerformed(ActionEvent e) { // try to delete the selected share - LdapFilter selection = tblFilters.getSelectedItem(); + Wrapper<LdapFilter> selection = tblFilters.getSelectedItem(); if (selection == null) { return; } try { - if (!filterList.remove(selection)) { + List<Wrapper<LdapFilter>> oldList = tblFilters.getData(); + if (!oldList.remove(selection)) { // false if it was not found LOGGER.error("Could not remove non-existent filter '" + selection.toString() - + "' from the table data: " + filterList.toString()); + + "' from the table data: " + oldList.toString()); return; } // refresh table data - tblFilters.setData(filterList, false); + tblFilters.setData(oldList, true); } catch (Exception ex) { LOGGER.debug("Failed to remove " + selection.toString() + " from the table data.", ex); return; @@ -134,17 +146,49 @@ public class LdapFilterConfigurator extends LdapFilterConfiguratorLayout { } public List<LdapFilter> getState() { - return filterList; + List<Wrapper<LdapFilter>> current = tblFilters.getData(); + ArrayList<LdapFilter> ret = new ArrayList<>(current.size()); + for (Wrapper<LdapFilter> item : current) { + if (item.isChecked() || item.item.filterId == 0) { + ret.add(item.item); + } + } + return ret; } public boolean setState(List<LdapFilter> data) { if (data == null) return false; - if (filterList == null) { - filterList = new ArrayList<>(); + ArrayList<LdapFilter> filterList = new ArrayList<>(data); + List<LdapFilter> predef = MetaDataCache.getPredefinedLdapFilters(); + Set<LdapFilter> checked = new HashSet<>(); + for (LdapFilter item : data) { + if (item.filterId == 0) + continue; + // Item has a filterId (is predefined), so validate it's in there + // before marking it checked, or just uncheck it by removing the id + // so it becomes a custom entry. + boolean ok = false; + for (LdapFilter pd : predef) { + if (pd.filterId == item.filterId) { + checked.add(pd); + ok = true; + break; + } + } + // If it wasn't preselected, add to list now... + if (!ok) { + item.filterId = 0; + } + } + // Now add remaining filters + for (LdapFilter pd : predef) { + if (!checked.contains(pd)) { + filterList.add(pd); + LOGGER.info("Adding " + pd.filterId); + } } - filterList = data; - tblFilters.setData(filterList, false); + tblFilters.setData(filterList, checked, false); return true; } @@ -200,18 +244,17 @@ class LdapFilterConfiguratorLayout extends JPanel { grid.nextRow(); JPanel pnlNewShare = new JPanel(); - GridManager gridNewFilter = new GridManager(pnlNewShare, 2, true); - pnlNewShare.setBorder(BorderFactory.createTitledBorder("Filter definieren")); + GridManager gridNewFilter = new GridManager(pnlNewShare, 3, true); + pnlNewShare.setBorder(BorderFactory.createTitledBorder("Eignen Filter definieren")); gridNewFilter.add(new QLabel("Attribut")); txtAttribute = new JTextField(); - gridNewFilter.add(txtAttribute).fill(true, false).expand(true, false); + gridNewFilter.add(txtAttribute, 2).fill(true, false).expand(true, false); gridNewFilter.nextRow(); gridNewFilter.add(new QLabel("Wert")); txtValue = new JTextField(); gridNewFilter.add(txtValue).fill(true, false).expand(true, false); - gridNewFilter.nextRow(); btnAdd = new JButton("Hinzufügen"); - gridNewFilter.add(btnAdd, 2).anchor(GridBagConstraints.EAST); + gridNewFilter.add(btnAdd).anchor(GridBagConstraints.EAST); gridNewFilter.nextRow(); gridNewFilter.finish(false); grid.add(pnlNewShare).fill(true, false).expand(true, false); diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/table/CheckListTable.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/table/CheckListTable.java new file mode 100644 index 00000000..d9527612 --- /dev/null +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/table/CheckListTable.java @@ -0,0 +1,157 @@ +package org.openslx.dozmod.gui.control.table; + +import java.awt.Component; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Set; + +import javax.swing.Box; + +import org.apache.log4j.Logger; + +public abstract class CheckListTable<T> extends ListTable<CheckListTable.Wrapper<T>> { + + private static final long serialVersionUID = 5667297891670398732L; + + private static final Logger LOGGER = Logger.getLogger(CheckListTable.class); + + public static final ListTableColumn COL_CHECKBOX = new ListTableColumn("", Boolean.class, null, true); + + private static final Component LBL_EMPTY_CELL = Box.createHorizontalGlue(); + + public CheckListTable(ListTableColumn... columns) { + this(null, columns); + } + + public CheckListTable(final Comparator<T> itemComparator, ListTableColumn... columns) { + super(new Comparator<Wrapper<T>>() { + @Override + public int compare(Wrapper<T> o1, Wrapper<T> o2) { + if (o1 == null && o2 == null) + return 0; + if (o1 == null) + return -1; + if (o2 == null) + return 1; + return itemComparator.compare(o1.item, o2.item); + } + + }, copyColumns(columns)); + /* + this.setDefaultEditor(Boolean.class, new DefaultCellEditor { + public DefaultCellEditor(new JCheckBox()) { + JCheckBox checkBox = (JCheckBox)getComponent(); + checkBox.setHorizontalAlignment(JCheckBox.CENTER); + } + }); + /* + addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + int column = getSelectedColumn(); + if (column != 0) + return; + int row = getSelectedRow(); + if (row < 0 || row >= getRowCount()) + return; + getce + } + }); + */ + } + + private static ListTableColumn[] copyColumns(ListTableColumn[] columns) { + final ListTableColumn ncolumns[] = new ListTableColumn[columns.length + 1]; + ncolumns[0] = COL_CHECKBOX; + System.arraycopy(columns, 0, ncolumns, 1, columns.length); + return ncolumns; + } + + @Override + public void setValueAt(Object newValue, Wrapper<T> row, ListTableColumn column) { + if (column == COL_CHECKBOX && newValue != null && newValue.getClass() == Boolean.class) { + row.isChecked = (Boolean)newValue; + } + } + + @Override + protected final Object getValueAtInternal(Wrapper<T> row, ListTableColumn columnIndex) { + if (row.item == null) + return null; + if (columnIndex == COL_CHECKBOX) { + return row.isChecked; + } + return getValueAtInternal2(row.item, columnIndex); + } + + protected abstract Object getValueAtInternal2(T row, ListTableColumn columnIndex); + + @Override + public final Component prepareRenderHook(Component component, Wrapper<T> row, + ListTableColumn listTableColumn, boolean isSelected) { + if (listTableColumn == COL_CHECKBOX) { + if (row == null || row.item == null || !isItemCheckable(row.item)) { + return LBL_EMPTY_CELL; + } + } else if (row.item != null) { + component = prepareRenderHook2(component, row.item, listTableColumn, isSelected); + } + return component; + } + + public Component prepareRenderHook2(Component component, T row, + ListTableColumn listTableColumn, boolean isSelected) { + // Nothing + return component; + } + + public void setData(List<T> data, Set<T> preChecked, boolean sort) { + List<Wrapper<T>> list = new ArrayList<>(data.size()); + for (T item : data) { + list.add(new Wrapper<T>(item, preChecked != null && preChecked.contains(item))); + } + super.setData(list, sort); + } + + protected abstract boolean isItemCheckable(T item); + + public T getSelectedItem2() { + Wrapper<T> ret = getSelectedItem(); + if (ret == null) + return null; + return ret.item; + } + + public static class Wrapper<S> { + + protected boolean isChecked; + public final S item; + + public Wrapper(S item, boolean checked) { + this.item = item; + this.isChecked = checked; + } + + @Override + public boolean equals(Object obj) { + return item.equals(obj); + } + + @Override + public int hashCode() { + return item.hashCode(); + } + + @Override + public String toString() { + return "(" + item.hashCode() + "=" + isChecked + ")"; + } + + public boolean isChecked() { + return isChecked; + } + + } + +} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/table/LectureLdapFilterTable.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/table/LectureLdapFilterTable.java index ac5e8e0f..70d0291e 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/table/LectureLdapFilterTable.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/table/LectureLdapFilterTable.java @@ -1,24 +1,57 @@ package org.openslx.dozmod.gui.control.table; +import java.awt.Color; +import java.awt.Component; + +import javax.swing.UIManager; + import org.openslx.bwlp.thrift.iface.LdapFilter; +import org.openslx.dozmod.gui.helper.ColorUtil; @SuppressWarnings("serial") -public class LectureLdapFilterTable extends ListTable<LdapFilter> { +public class LectureLdapFilterTable extends CheckListTable<LdapFilter> { + public static final ListTableColumn COL_TITLE = new ListTableColumn("Name"); public static final ListTableColumn COL_ATTRIBUTE = new ListTableColumn("Attribut"); public static final ListTableColumn COL_VALUE = new ListTableColumn("Wert"); + + private final Color invalidColor; public LectureLdapFilterTable() { - super(COL_ATTRIBUTE, COL_VALUE); + super(COL_TITLE, COL_ATTRIBUTE, COL_VALUE); + Color fg = UIManager.getColor("Table.foreground"); + Color bg = UIManager.getColor("Table.background"); + invalidColor = ColorUtil.blend(fg, bg, .66f); } @Override - protected Object getValueAtInternal(LdapFilter item, ListTableColumn columnIndex) { + protected Object getValueAtInternal2(LdapFilter item, ListTableColumn columnIndex) { + if (columnIndex == COL_TITLE) { + if (item.filterId == 0) + return ""; + return item.title; + } if (columnIndex == COL_ATTRIBUTE) return item.attribute; if (columnIndex == COL_VALUE) return item.value; throw new IndexOutOfBoundsException(); } + + @Override + public Component prepareRenderHook2(Component component, LdapFilter row, + ListTableColumn listTableColumn, boolean isSelected) { + if (row.filterId == 0) { + component.setForeground(isSelected ? getSelectionForeground() : getForeground()); + } else { + component.setForeground(invalidColor); + } + return component; + } + + @Override + protected boolean isItemCheckable(LdapFilter item) { + return item.filterId > 0; + } } diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/TableColumnAdjuster.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/TableColumnAdjuster.java index 2066791f..e8e04237 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/TableColumnAdjuster.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/TableColumnAdjuster.java @@ -78,15 +78,17 @@ public class TableColumnAdjuster implements PropertyChangeListener, TableModelLi */ public void adjustColumn(final int column) { TableColumn tableColumn = table.getColumnModel().getColumn(column); - if (!tableColumn.getResizable()) return; - + int columnHeaderWidth = getColumnHeaderWidth(column); - int columnDataWidth = getColumnDataWidth(column); - int preferredWidth = Math.max(columnHeaderWidth, columnDataWidth); - - updateTableColumn(column, preferredWidth); + int columnDataWidth; + if (table.getColumnClass(column) == Boolean.class) { + columnDataWidth = 16; + } else { + columnDataWidth = getColumnDataWidth(column); + } + updateTableColumn(column, Math.max(columnHeaderWidth, columnDataWidth)); } /* @@ -115,7 +117,7 @@ public class TableColumnAdjuster implements PropertyChangeListener, TableModelLi private int getColumnDataWidth(int column) { if (!isColumnDataIncluded || table.getRowCount() == 0) return 0; - + int preferredWidth = 0; int maxWidth = table.getColumnModel().getColumn(column).getMaxWidth(); int[] colWidth = new int[table.getRowCount()]; @@ -170,7 +172,7 @@ public class TableColumnAdjuster implements PropertyChangeListener, TableModelLi // Don't shrink the column width - if (isOnlyAdjustLarger) { + if (isOnlyAdjustLarger && table.getColumnClass(column) != Boolean.class) { width = Math.max(width, tableColumn.getPreferredWidth()); } |