diff options
author | Simon Rettberg | 2018-06-21 15:41:44 +0200 |
---|---|---|
committer | Simon Rettberg | 2018-06-21 15:41:44 +0200 |
commit | c0003a559a36dfca1bdc4add0034e67bd22824ed (patch) | |
tree | d0f03daa4eb8b94cbfb9472213a109eade52a0dc /dozentenmodul/src/main/java/org/openslx/dozmod/gui/control | |
parent | [client] Refactor change monitor classes, better error message handling (diff) | |
download | tutor-module-c0003a559a36dfca1bdc4add0034e67bd22824ed.tar.gz tutor-module-c0003a559a36dfca1bdc4add0034e67bd22824ed.tar.xz tutor-module-c0003a559a36dfca1bdc4add0034e67bd22824ed.zip |
[client] Sanitize class/var names, split up control package
All configurators have moved from *.control to *.configurator
*.control should be used for simple controls that feel like
they're really just one thing. The configurators are more like
a group of controls.
Diffstat (limited to 'dozentenmodul/src/main/java/org/openslx/dozmod/gui/control')
7 files changed, 2 insertions, 1744 deletions
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/ImageCustomPermissionManager.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/ImageCustomPermissionManager.java deleted file mode 100644 index 8dadbd71..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/ImageCustomPermissionManager.java +++ /dev/null @@ -1,201 +0,0 @@ -package org.openslx.dozmod.gui.control; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -import javax.swing.AbstractAction; -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JComponent; -import javax.swing.JPanel; -import javax.swing.KeyStroke; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; - -import org.apache.log4j.Logger; -import org.openslx.bwlp.thrift.iface.ImagePermissions; -import org.openslx.bwlp.thrift.iface.UserInfo; -import org.openslx.dozmod.gui.control.table.ImagePermissionTable; -import org.openslx.dozmod.gui.control.table.QScrollPane; -import org.openslx.dozmod.gui.control.table.ImagePermissionTable.UserImagePermissions; -import org.openslx.dozmod.gui.helper.GridManager; -import org.openslx.dozmod.gui.window.UserListWindow; -import org.openslx.dozmod.gui.window.UserListWindow.UserAddedCallback; -import org.openslx.dozmod.thrift.cache.UserCache; -import org.openslx.dozmod.util.FormatHelper; - -/** - * Panel including ImagePermissionTable and add/remove buttons for setting - * customImagePermissions. - */ -@SuppressWarnings("serial") -public class ImageCustomPermissionManager extends JPanel { - - protected ImagePermissionTable permissionTable; - - protected JButton btnAddUser; - protected JButton btnRemoveUser; - - private ImageCustomPermissionManager me; - - private String ownerId; - - private ArrayList<UserImagePermissions> permissionList = new ArrayList<UserImagePermissions>(); - private Map<String, ImagePermissions> newPermissionMap; - - private ImagePermissions defaultPermissions; - - private static final Logger LOGGER = Logger.getLogger(ImageCustomPermissionManager.class); - - public ImageCustomPermissionManager() { - super(); - me = this; - GridManager grid = new GridManager(this, 1); - - permissionTable = new ImagePermissionTable(); - - // Panel for the add- and remove buttons - JPanel userButtonPane = new JPanel(); - userButtonPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - userButtonPane.setLayout(new BoxLayout(userButtonPane, BoxLayout.LINE_AXIS)); - - btnAddUser = new JButton("Benutzer hinzufügen"); - userButtonPane.add(btnAddUser); - btnRemoveUser = new JButton("Benutzer entfernen"); - userButtonPane.add(btnRemoveUser); - userButtonPane.add(Box.createGlue()); - - // Put everything into the grid - QScrollPane jsp = new QScrollPane(permissionTable); - jsp.setBackground(UIManager.getColor("Table.background")); - grid.add(jsp).fill(true, true).expand(true, true); - grid.nextRow(); - grid.add(userButtonPane).fill(true, false).expand(true, false); - grid.nextRow(); - grid.finish(false); - - // add user button listener - btnAddUser.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - UserListWindow.open(SwingUtilities.getWindowAncestor(me), new UserAddedCallback() { - @Override - public void userAdded(final UserInfo newUser, UserListWindow window) { - // check if we have this user already - for (UserImagePermissions current : permissionList) { - if (current.userId.equals(newUser.userId)) { - LOGGER.debug("User already present in the list, skipping!"); - return; - } - } - // add it to the list with default permissions - permissionList.add(new UserImagePermissions(newUser.userId, new ImagePermissions( - defaultPermissions))); - permissionTable.setData(permissionList, false); - } - }, "Hinzufügen", ownerId); - } - }); - - // delete user button listener - btnRemoveUser.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - final UserImagePermissions selected = permissionTable.getSelectedItem(); - if (selected != null && !permissionList.remove(selected)) { - LOGGER.debug("Could not remove: " + selected); - } - permissionTable.setData(permissionList, false); - } - }); - - // keyboard shortcut - permissionTable.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put( - KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "delete"); - permissionTable.getActionMap().put("delete", new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ae) { - btnRemoveUser.doClick(); - } - }); - } - - /** - * Initialize the PermissionManager. Note that the given permissionMap and - * defaultPermissions reference - * will get changed when the user interacts with the controls. - * - * @param permissionMap the old permission, to initialize the table with, - * null creates empty table. - * @param defaultPermissions the permissions for a newly added user - * @param ownerId The user to exclude from the add user list. Can be null. - */ - public void initPanel(Map<String, ImagePermissions> permissionMap, - final ImagePermissions defaultPermissions, String ownerId) { - this.ownerId = ownerId; - this.newPermissionMap = permissionMap == null ? new HashMap<String, ImagePermissions>() - : permissionMap; - this.defaultPermissions = defaultPermissions; - - permissionList.clear(); - for (Entry<String, ImagePermissions> e : newPermissionMap.entrySet()) { - permissionList.add(new UserImagePermissions(e.getKey(), e.getValue())); - } - // lexicographic sort on the last names - Collections.sort(permissionList, new Comparator<UserImagePermissions>() { - @Override - public int compare(UserImagePermissions o1, UserImagePermissions o2) { - UserInfo u1 = UserCache.find(o1.userId); - UserInfo u2 = UserCache.find(o2.userId); - if (u1 != null && u2 != null) - return FormatHelper.userName(u1).compareTo(FormatHelper.userName(u2)); - else - return 0; - } - }); - permissionTable.setData(permissionList, false); - } - - /** - * Get map with the permissions set in the table of the manager. - * - * @return Map with new custom permissions, null if something went wrong - */ - public Map<String, ImagePermissions> updatePermissionReferences() { - if (permissionList == null) - return null; - - newPermissionMap.clear(); - - // put permissions of the list into the map - for (UserImagePermissions perm : permissionList) { - newPermissionMap.put(perm.userId, perm.permissions); - } - return newPermissionMap; - } - - /** - * Update the used default permissions of the manager. - * - * @param link - * @param download - * @param edit - * @param admin - */ - public void updateDefaultPermissions(boolean link, boolean download, boolean edit, boolean admin) { - this.defaultPermissions.link = link; - this.defaultPermissions.download = download; - this.defaultPermissions.edit = edit; - this.defaultPermissions.admin = admin; - } - -} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/LdapFilterConfigurator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/LdapFilterConfigurator.java deleted file mode 100755 index b4e5a4a8..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/LdapFilterConfigurator.java +++ /dev/null @@ -1,219 +0,0 @@ -package org.openslx.dozmod.gui.control; - -import java.awt.GridBagConstraints; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.ArrayList; -import java.util.List; - -import javax.swing.BorderFactory; -import javax.swing.JButton; -import javax.swing.JPanel; -import javax.swing.JTextField; -import javax.swing.event.ChangeListener; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; -import javax.swing.event.TableModelEvent; -import javax.swing.event.TableModelListener; - -import org.apache.log4j.Logger; -import org.openslx.bwlp.thrift.iface.LdapFilter; -import org.openslx.dozmod.gui.Gui; -import org.openslx.dozmod.gui.changemonitor.DialogChangeMonitor; -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; - -/** - * Widget for network share configuration of lectures - */ -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() { - - super(); - - tblFilters.getModel().addTableModelListener(new TableModelListener() { - @Override - public void tableChanged(TableModelEvent e) { - fireChangeEvent(); - } - }); - - tblFilters.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - @Override - public void valueChanged(ListSelectionEvent e) { - LdapFilter item = tblFilters.getSelectedItem(); - if (item == null) { - clearInputFields(); - return; - } - // share from the list is selected: fill bottom form and change "Add" to "Apply" - btnDel.setEnabled(true); - txtAttribute.setText(item.attribute); - txtValue.setText(item.value); - btnAdd.setText("Ändern"); - } - }); - - btnAdd.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - // check if we are editing an existing share entry or - // creating a new one, check for input either way - LdapFilter input = new LdapFilter(); - - input.attribute = txtAttribute.getText(); - if (input.attribute == null || input.attribute.isEmpty()) { - Gui.showMessageBox("Kein Attribut angegeben", MessageType.ERROR, null, null); - return; - } - input.value = txtValue.getText(); - if (input.value == null) { - input.value = ""; - } - - // 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)) { - 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) { - // editing existing one, delete it from the internal data - filterList.remove(oldEntry); - } - filterList.add(input); - tblFilters.setData(filterList, false); - clearInputFields(); - } - }); - - btnDel.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - // try to delete the selected share - LdapFilter selection = tblFilters.getSelectedItem(); - if (selection == null) { - return; - } - try { - if (!filterList.remove(selection)) { - // false if it was not found - LOGGER.error("Could not remove non-existent filter '" + selection.toString() - + "' from the table data: " + filterList.toString()); - return; - } - // refresh table data - tblFilters.setData(filterList, false); - } catch (Exception ex) { - LOGGER.debug("Failed to remove " + selection.toString() + " from the table data.", ex); - return; - } - } - }); - btnDel.setEnabled(false); - } - - private void clearInputFields() { - btnDel.setEnabled(false); - txtAttribute.setText(null); - txtValue.setText(null); - btnAdd.setText("Hinzufügen"); - } - - public List<LdapFilter> getState() { - return filterList; - } - - public boolean setState(List<LdapFilter> data) { - if (data == null) - return false; - if (filterList == null) { - filterList = new ArrayList<>(); - } - filterList = data; - tblFilters.setData(filterList, false); - return true; - } - - protected List<ChangeListener> listenerList = new ArrayList<>(); - - public void addLdapFilterListTableContentConfigurationChangeEventListener(ChangeListener listener) { - listenerList.add(listener); - } - - public void removeNetshareConfigurationChangeEventListener(ChangeListener listener) { - listenerList.remove(listener); - } - - void fireChangeEvent() { - for (ChangeListener listener : new ArrayList<>(listenerList)) { - listener.stateChanged(null); - } - } - - public void addToChangeMonitor(DialogChangeMonitor changeMonitor) { - changeMonitor.add(tblFilters); - } - -} - -/** - * Internal layout class for this widget - */ -class LdapFilterConfiguratorLayout extends JPanel { - - private static final long serialVersionUID = 6479838641542743622L; - - private final static String HELPTEXT = "Geben Sie hier LDAP Filter ein, die die Sichtbarkeit" - + " der Veranstaltung abhängig vom angemeldeten Benutzer einschränken. Eine Veranstaltung" - + " ist sichtbar, sobald einer der angegebenen Filter zutrifft. Zusätzliche Raumbeschränkungen" - + " greifen weiterhin."; - - protected final LectureLdapFilterTable tblFilters = new LectureLdapFilterTable(); - protected final JTextField txtAttribute, txtValue; - protected final JButton btnAdd, btnDel; - - public LdapFilterConfiguratorLayout() { - GridManager grid = new GridManager(this, 1, true, new Insets(3, 3, 3, 3)); - // top info panel - grid.add(new WordWrapLabel(HELPTEXT)).fill(true, false).expand(true, false); - grid.nextRow(); - // middle filter list - grid.add(new QScrollPane(tblFilters)).fill(true, true).expand(true, true); - grid.nextRow(); - - btnDel = new JButton("Entfernen"); - grid.add(btnDel).anchor(GridBagConstraints.EAST); - grid.nextRow(); - - JPanel pnlNewShare = new JPanel(); - GridManager gridNewFilter = new GridManager(pnlNewShare, 2, true); - pnlNewShare.setBorder(BorderFactory.createTitledBorder("Filter definieren")); - gridNewFilter.add(new QLabel("Attribut")); - txtAttribute = new JTextField(); - gridNewFilter.add(txtAttribute).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.nextRow(); - gridNewFilter.finish(false); - grid.add(pnlNewShare).fill(true, false).expand(true, false); - grid.nextRow(); - grid.finish(false); - } -} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/LectureCustomPermissionManager.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/LectureCustomPermissionManager.java deleted file mode 100644 index b853f7e2..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/LectureCustomPermissionManager.java +++ /dev/null @@ -1,236 +0,0 @@ -package org.openslx.dozmod.gui.control; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.util.ArrayList; -import java.util.EventListener; -import java.util.EventObject; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -import javax.swing.AbstractAction; -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JComponent; -import javax.swing.JPanel; -import javax.swing.KeyStroke; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; -import javax.swing.event.EventListenerList; - -import org.apache.log4j.Logger; -import org.openslx.bwlp.thrift.iface.LecturePermissions; -import org.openslx.bwlp.thrift.iface.UserInfo; -import org.openslx.dozmod.gui.control.table.LecturePermissionTable; -import org.openslx.dozmod.gui.control.table.LecturePermissionTable.UserLecturePermissions; -import org.openslx.dozmod.gui.control.table.QScrollPane; -import org.openslx.dozmod.gui.helper.GridManager; -import org.openslx.dozmod.gui.window.UserListWindow; -import org.openslx.dozmod.gui.window.UserListWindow.UserAddedCallback; - -/** - * Panel including LecturePermissionTable and add/remove buttons for setting - * customLecturePermissions. - */ -/** - * @author joe - * - */ -@SuppressWarnings("serial") -public class LectureCustomPermissionManager extends JPanel { - - /** - * Self reference - */ - private LectureCustomPermissionManager me; - - protected LecturePermissionTable permissionTable; - - protected JButton btnAddUser; - protected JButton btnRemoveUser; - - private final ArrayList<UserLecturePermissions> permissionList = new ArrayList<UserLecturePermissions>(); - - private LecturePermissions defaultPermissions; - - private String ownerId = null; - - private static final Logger LOGGER = Logger.getLogger(LectureCustomPermissionManager.class); - - public LectureCustomPermissionManager() { - super(); - me = this; - - GridManager grid = new GridManager(this, 1); - - permissionTable = new LecturePermissionTable(); - - // Panel for the add- and remove buttons - JPanel userButtonPane = new JPanel(); - userButtonPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - userButtonPane.setLayout(new BoxLayout(userButtonPane, BoxLayout.LINE_AXIS)); - - btnAddUser = new JButton("Benutzer hinzufügen"); - userButtonPane.add(btnAddUser); - btnRemoveUser = new JButton("Benutzer entfernen"); - userButtonPane.add(btnRemoveUser); - userButtonPane.add(Box.createGlue()); - - // Put everything into the grid - QScrollPane jsp = new QScrollPane(permissionTable); - jsp.setBackground(UIManager.getColor("Table.background")); - grid.add(jsp).fill(true, true).expand(true, true); - grid.nextRow(); - grid.add(userButtonPane).fill(true, false).expand(true, false); - grid.nextRow(); - grid.finish(false); - - // add user button listener - btnAddUser.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - UserListWindow.open(SwingUtilities.getWindowAncestor(me), new UserAddedCallback() { - @Override - public void userAdded(final UserInfo newUser, UserListWindow window) { - // check if we have this user already - for (UserLecturePermissions current : permissionList) { - if (current.userId.equals(newUser.userId)) { - LOGGER.debug("User already present in the list, skipping!"); - return; - } - } - // add it to the list with default permissions - permissionList.add(new UserLecturePermissions(newUser.userId, new LecturePermissions( - defaultPermissions))); - permissionTable.setData(permissionList, false); - fireUserChangeEvent(); - } - }, "Hinzufügen", ownerId); - } - }); - - // delete user button listener - btnRemoveUser.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - final UserLecturePermissions selected = permissionTable.getSelectedItem(); - if (selected != null && !permissionList.remove(selected)) { - LOGGER.debug("Could not remove: " + selected); - } - permissionTable.setData(permissionList, false); - fireUserChangeEvent(); - } - }); - - // keyboard shortcut - permissionTable.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put( - KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "delete"); - permissionTable.getActionMap().put("delete", new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ae) { - btnRemoveUser.doClick(); - } - }); - permissionTable.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - // TODO: This is stupid; permissionTable should fire an event - // if one of the check boxes changes. - fireUserChangeEvent(); - } - }); - } - - /** - * Initialise the PermissionManager - * - * @param permissionMap the old permission, to initialise the table with, - * null creates empty table. - * @param defaultPermissions the permissions for a newly added user - * @param ownerId The user to exclude in the list do add user. May be null. - */ - public void initPanel(Map<String, LecturePermissions> permissionMap, - final LecturePermissions defaultPermissions, String ownerId) { - this.ownerId = ownerId; - this.defaultPermissions = defaultPermissions; - permissionList.clear(); - if (permissionMap != null) { - for (Entry<String, LecturePermissions> e : permissionMap.entrySet()) { - permissionList.add(new UserLecturePermissions(e.getKey(), e.getValue())); - } - } - permissionTable.setData(permissionList, false); - } - - /** - * Get map with the permissions set in the table of the manager. - * - * @return Map with new custom permissions, null if something went wrong - */ - public Map<String, LecturePermissions> getPermissions() { - Map<String, LecturePermissions> newPermissionMap = new HashMap<>(permissionList.size()); - // put permissions of the list into the map - for (UserLecturePermissions perm : permissionList) { - newPermissionMap.put(perm.userId, perm.permissions); - } - return newPermissionMap; - } - - /** - * Update the default permissions used by the manager. - * - * @param admin - * @param edit - */ - public void updateDefaultPermissions(boolean admin, boolean edit) { - defaultPermissions.admin = admin; - defaultPermissions.edit = edit; - } - - - /** - * Custom event mechanism to detect changes to the user list - * (Mostly needed for the reactToChange() stuff in LectureDetailsWindow) - */ - protected EventListenerList listenerList = new EventListenerList(); - - /** - * Shared instance, since there is no data attached (yet) - */ - private static final UserChangeEvent CHANGE_EVENT = new UserChangeEvent(); - - public static class UserChangeEvent extends EventObject { - - public UserChangeEvent() { - super(new Object()); - } - } - - public interface UserChangeEventListener extends EventListener { - public void stateChanged(UserChangeEvent event); - } - - public void addUserChangeEventListener(UserChangeEventListener listener) { - listenerList.add(UserChangeEventListener.class, listener); - } - - public void removeUserChangeEventListener(UserChangeEventListener listener) { - listenerList.remove(UserChangeEventListener.class, listener); - } - - void fireUserChangeEvent() { - Object[] listeners = listenerList.getListenerList(); - for (int i = 0; i < listeners.length; i++) { - if (listeners[i] == UserChangeEventListener.class) { - ((UserChangeEventListener) listeners[i + 1]) - .stateChanged(CHANGE_EVENT); - } - } - } -} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/NetrulesConfigurator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/NetrulesConfigurator.java deleted file mode 100644 index 036f3726..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/NetrulesConfigurator.java +++ /dev/null @@ -1,449 +0,0 @@ -package org.openslx.dozmod.gui.control; - -import java.awt.Color; -import java.awt.Insets; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.EventListener; -import java.util.EventObject; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import javax.swing.BorderFactory; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextPane; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; -import javax.swing.event.EventListenerList; -import javax.swing.text.BadLocationException; -import javax.swing.text.DefaultStyledDocument; -import javax.swing.text.SimpleAttributeSet; -import javax.swing.text.StyleConstants; - -import org.apache.log4j.Logger; -import org.openslx.bwlp.thrift.iface.NetDirection; -import org.openslx.bwlp.thrift.iface.NetRule; -import org.openslx.dozmod.gui.Gui; -import org.openslx.dozmod.gui.helper.GridManager; -import org.openslx.dozmod.gui.helper.MessageType; -import org.openslx.dozmod.gui.helper.TextChangeListener; -import org.openslx.util.Util; - -/** - * Widget for netrules configuration of lectures - */ -public class NetrulesConfigurator extends NetrulesConfiguratorLayout { - - private static final long serialVersionUID = -3497629601818983994L; - private final static Logger LOGGER = Logger - .getLogger(NetrulesConfigurator.class); - - private String originalRawRuleText = null; - /** - * Character defining how the rules are parsed, e.g. for whitespace \\s - * Example: "8.8.8.8 80 in" would be split in -hostname "8.8.8.8" -port "80" - * -direction "in" - */ - private static final String FIELD_DELIMITER = "\\s+"; - - private static final Color FOREGROUND_TEXT_COLOR; - - static { - Color fgOrigColor = UIManager.getDefaults().getColor("ColorChooser.foreground"); - if (fgOrigColor == null) { - // use black as fallback - fgOrigColor = Color.BLACK; - } - FOREGROUND_TEXT_COLOR = fgOrigColor; - } - - public NetrulesConfigurator() { - super(); - - final TextChangeListener docListener = new TextChangeListener() { - @Override - public void changed() { - fireNetrulesConfigurationChangeEvent(new NetrulesConfigurationChangeEvent(NetrulesConfigurator.this)); - } - }; - final SimpleAttributeSet as = new SimpleAttributeSet(); - StyleConstants.setForeground(as, FOREGROUND_TEXT_COLOR); - tpNetworkRules.getDocument().addDocumentListener(docListener); - tpNetworkRules.addKeyListener(new KeyAdapter() { - @Override - public void keyTyped(KeyEvent e) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - int pos = tpNetworkRules.getCaretPosition(); - if (pos < 0) { - return; - } - // Odd: On windows, getText() returns the text with CRLF line breaks, - // regardless of what you put into the text box. - // The offsets passed to setCharAttrs() below and the caret position - // you get from getCaretPosition() however have to adhere to the - // text version with just LF, exactly how we created the document. - String text = tpNetworkRules.getText().replace("\r", ""); - if (pos >= text.length()) { - return; - } - int start = text.lastIndexOf('\n', pos == 0 ? 0 : pos - 1); - int end = text.indexOf('\n', pos); - if (start == -1) { - start = 0; - } - if (end == -1) { - end = text.length() - 1; - } - if (end <= start) { - return; - } - tpNetworkRules.getStyledDocument().setCharacterAttributes(start, end - start, as, true); - } - }); - } - }); - } - - public boolean hasChanged() { - return !originalRawRuleText.equalsIgnoreCase(tpNetworkRules.getText()); - } - - /** - * Gets the state of the widget as a list of netrules. Internally it first - * transforms the input text in a list of netrules. - * - * @return the list of rules as parsed by parseNetRules() - */ - public List<NetRule> getState(boolean silent) { - // cleanup the TextPane for network rules if needed - return parseNetRules(silent); - } - - /** - * Sets the state of this widget to the given list of netrules. This will - * internally transform the list to its string representation - * - * @param netrules - * as a list of NetRule to set the state to - */ - public void setState(final List<NetRule> netrules) { - // setText() blanks the text area if null is given, so no null checks - originalRawRuleText = decodeNetRulesToText(netrules); - this.tpNetworkRules.setText(originalRawRuleText); - } - - /** - * "Decodes" the given list of NetRule to a single String. This should be - * used to set the text in the TextPane for the network rules - * - * @param netRulesList - * list of NetRule to decode - * @return String representation of the list of rules - */ - public static String decodeNetRulesToText(final List<NetRule> netRulesList) { - if (netRulesList == null || netRulesList.isEmpty()) - return ""; - - String decodedRules = ""; - Iterator<NetRule> it = netRulesList.iterator(); - while (it.hasNext()) { - String currentLine = ""; - NetRule currentRule = it.next(); - // simple test for validity (since this comes from the server it - // should be correct anyways) - if (currentRule.host.isEmpty() || currentRule.port > 65535) { - LOGGER.error("Invalid rule! Ignoring: " + currentRule.host - + ":" + currentRule.port); - continue; - } - currentLine += currentRule.host + " \t "; - currentLine += currentRule.port + " \t "; - currentLine += currentRule.direction.name(); - decodedRules += currentLine - + (it.hasNext() ? "\n" : ""); - } - return decodedRules; - } - - /** - * Parses the given rawNetRules String to a list of NetRule - * - * @param rawNetRules - * the raw text to be parsed - * @return list of netrules if successful. If any errors occured while - * parsing, null is returned. - */ - public List<NetRule> parseNetRules(boolean silent) { - String rawNetRules = tpNetworkRules.getText().trim(); - List<NetRule> rulesList = new ArrayList<NetRule>(); - if (rawNetRules.isEmpty()) { - return rulesList; - } - - // split it line by line - boolean invalid = false; // True if the rules are invalid and null should be returned - DefaultStyledDocument newdoc = null; - if (!silent) { - newdoc = new DefaultStyledDocument(); // Used to build new document with colors - } - StringBuilder errors = new StringBuilder(); // Error messages to show (if not silent) - int lineNo = 0; // Show line numbers in error messages - Set<String> warnedHosts = new HashSet<>(); // Ask only once about each unknown host - for (String ruleLine : rawNetRules.split("[\r\n]+")) { - if (silent && invalid) - return null; - Color lineColor = null; - LOGGER.debug("Parsing rule: " + ruleLine); - // split the fields and check if we have 3 as expected. - String[] fields = ruleLine.trim().split(FIELD_DELIMITER); - if (fields.length != 3) { - lineNo += addLine(newdoc, ruleLine, Color.RED, true); - // log numbers for fields independently... - LOGGER.debug("Invalid number of fields! Expected 3, got: " + fields.length); - if (fields.length > 3) { - errors.append("Zeile " + lineNo + ": Zu viele Felder.\n"); - } else { - errors.append("Zeile " + lineNo + ": Zu wenig Felder.\n"); - } - invalid = true; - continue; - } - // Have 3 fields, pretty up - String ruleDirection = fields[2].toUpperCase(); - ruleLine = fields[0] + " \t " + fields[1] + " \t " + ruleDirection; - - // start to check fields one by one from the last to the first .... - // check net direction: accept either 'in' or 'out' (case - // insensitive) - // TODO support combined 'in/out' rules - if (!ruleDirection.equals("IN") && !ruleDirection.equals("OUT")) { - lineNo += addLine(newdoc, ruleLine, Color.RED, true); - LOGGER.debug("Invalid net direction! Expected 'in' or out'. Got: " + ruleDirection); - errors.append("Zeile " + lineNo + ": Ungültige Richtung. Bitte nutzen Sie 'IN' bzw. 'OUT'.\n"); - invalid = true; - continue; - } - // check port: accept if >= 0 and <= 65535 - int port = Util.parseInt(fields[1], -1); - - // port = 0 means match only host (all protocols and ports) - if (port < 0 || port > 65535) { - lineNo += addLine(newdoc, ruleLine, Color.RED, true); - LOGGER.debug("Invalid port! Got: " + port); - errors.append("Zeile " + lineNo + ": Ungültiger Port. Gültiger Bereich ist 0-65535.\n"); - invalid = true; - continue; - } - // check hostname: bit more to do here - // for IPs and/or resolvable hostnames we make use of java.net's - // InetAddress.getByName() method which checks the validity of - // an IP-Address represented by a string or if the given hostname - // is resolvable. If any of these happen, we have a valid hostname. - // Non-resolvable hostnames are handled differently, see after the - // try/catch-block - InetAddress ruleHost = null; - try { - // TODO: Find a way to reliably set a timeout (external DNS library?) - // Otherwise just remove this check - ruleHost = InetAddress.getByName(fields[0]); - } catch (UnknownHostException e) { - // might be good to see this exception in the log file - // LOGGER.debug("Invalid hostname (java.net): ", e); - } - if (ruleHost == null) { - // either invalid IP-Address or an invalid resolvable hostname - // however it might also be a non-resolvable hostname that would - // be valid in the actual pool-rooms, so lets check its syntax - // according to: http://tools.ietf.org/html/rfc1034#section-3.1 - LOGGER.debug("Invalid host/IP! Got: " + fields[0]); - String checkRes = checkHostnameSimple(fields[0]); - if (checkRes == null) { - if (!silent - && !warnedHosts.contains(fields[0]) - && !Gui.showMessageBox("Konnte '" + fields[0] - + "' nicht auflösen. Wollen Sie diesen Hostnamen trotzdem verwenden?", - MessageType.WARNING_RETRY, null, null)) { - invalid = true; - } - warnedHosts.add(fields[0]); - lineColor = Color.ORANGE; - } else { - lineNo += addLine(newdoc, ruleLine, Color.RED, true); - errors.append("Zeile " + lineNo + ": " + checkRes + "\n"); - invalid = true; - continue; - } - } - // Made it to here - line is valid - lineNo += addLine(newdoc, ruleLine, lineColor, false); - rulesList.add(new NetRule(NetDirection.valueOf(ruleDirection), fields[0], port)); - } - if (!silent && errors.length() != 0) { - Gui.showMessageBox("Fehler beim Auswerten der angegebenen Netzwerkregeln.\n\n" + errors.toString() - + "\nBitte geben Sie die Regeln zeilenweise im Format\n" - + "<host> <port> <IN|OUT>\n" - + "an.", - MessageType.ERROR, null, null); - } - if (newdoc != null) { - tpNetworkRules.setDocument(newdoc); - } - if (invalid) { - return null; - } - // Success - return rulesList; - } - - private int addLine(DefaultStyledDocument doc, String line, Color color, boolean bold) { - if (doc == null) - return 0; - if (color == null) { - color = FOREGROUND_TEXT_COLOR; - } - SimpleAttributeSet attrs = new SimpleAttributeSet(); - StyleConstants.setForeground(attrs, color); - StyleConstants.setBold(attrs, bold); - try { - doc.insertString(doc.getLength(), line + "\n", attrs); - } catch (BadLocationException e) { - LOGGER.warn("Cannot append to new textbox document", e); - } - return 1; - } - - /** - * Very simple hostname check for the given String. This will only check for - * some requirements of valid hostnames as stated in - * http://tools.ietf.org/html/rfc1034#section-3.1 To recap: max length of - * the whole hostname must be < 254 ASCII characters, all domain labels - * (between two dots) must be between 1 and 63 chars long and domain labels - * can only contain digits, letters and hyphen. (Note: we also accept - * forward slash to accept subnets!) - * - * @param hostname the hostname to check for syntactical validity - * @return null if valid, error string otherwise - */ - private String checkHostnameSimple(final String hostname) { - if (hostname.length() > 254) { - return "Hostname ist zu lang."; - } - // split by '.' to get domain levels - boolean allNumeric = true; - String[] domainLabels = hostname.split("\\."); - for (String domainLabel : domainLabels) { - if (domainLabel.length() > 63) { - // fail since domain level should be max 63 chars - return "Domain-Ebene '" + domainLabel + "' länger als 63 Zeichen."; - } - if (Util.parseInt(domainLabel, -1) == -1) { - allNumeric = false; - } - // checking for valid chars is pointless with punycode - } - if (allNumeric && domainLabels.length != 4) { - return "Unvollständige IP-Adresse."; - } - return null; - } - - /** - * Custom event mechanism to detect changes to the netrules list (Mostly - * needed for the reactToChange() stuff in LectureDetailsWindow) - */ - protected EventListenerList listenerList = new EventListenerList(); - - public class NetrulesConfigurationChangeEvent extends EventObject { - - private static final long serialVersionUID = -8779550754760035845L; - - public NetrulesConfigurationChangeEvent(Object source) { - super(source); - } - } - - public interface NetrulesConfigurationChangeEventListener extends - EventListener { - public void stateChanged(NetrulesConfigurationChangeEvent event); - } - - public void addNetrulesConfigurationChangeEventListener( - NetrulesConfigurationChangeEventListener listener) { - listenerList.add(NetrulesConfigurationChangeEventListener.class, - listener); - } - - public void removeNetrulesConfigurationChangeEventListener( - NetrulesConfigurationChangeEventListener listener) { - listenerList.remove(NetrulesConfigurationChangeEventListener.class, - listener); - } - - void fireNetrulesConfigurationChangeEvent( - NetrulesConfigurationChangeEvent evt) { - Object[] listeners = listenerList.getListenerList(); - for (int i = 0; i < listeners.length; i++) { - if (listeners[i] == NetrulesConfigurationChangeEventListener.class) { - ((NetrulesConfigurationChangeEventListener) listeners[i + 1]) - .stateChanged(evt); - } - } - } -} - -/** - * Internal layout class for this widget - */ -class NetrulesConfiguratorLayout extends JPanel { - - private static final long serialVersionUID = 5266120380443817325L; - private final static String txtNetworkOptionsTitle = "Netzwerk Einstellungen"; - private final static String txtNetworkOptionsDesc = "Wenn Sie den Internetzugriff deaktiviert haben," - + " können Sie hier Ausnahmen definieren (Whitelist)." - + " Bitte definieren Sie Ihre Regeln im Format\n<host> <port> <in|out>.\n" - + "Sie können Port 0 angeben, was sämtlichen TCP und UDP Ports eines Hosts entspricht.\n\n" - + "Wenn Sie Internetzugriff aktivieren, hat diese Liste den gegenteiligen Effekt"; - private final static String txtNetworkRulesTitle = "Netzwerkregeln"; - - private final JPanel pnlNetworkOptions; - protected final JTextPane tpNetworkRules; - - public NetrulesConfiguratorLayout() { - - GridManager grid = new GridManager(this, 1, true, - new Insets(5, 5, 5, 5)); - - // middle panel for network rules - pnlNetworkOptions = new JPanel(); - GridManager gridNetworkOptions = new GridManager(pnlNetworkOptions, 1, - true, new Insets(2, 2, 2, 2)); - pnlNetworkOptions.setBorder(BorderFactory - .createTitledBorder(txtNetworkOptionsTitle)); - tpNetworkRules = new JTextPane(); - - JScrollPane scpNetworkRules = new JScrollPane(tpNetworkRules, - JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, - JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - pnlNetworkOptions.setBorder(BorderFactory - .createTitledBorder(txtNetworkRulesTitle)); - gridNetworkOptions - .add(new WordWrapLabel(txtNetworkOptionsDesc)) - .fill(true, false).expand(true, false); - gridNetworkOptions.nextRow(); - gridNetworkOptions.add(scpNetworkRules).fill(true, true) - .expand(true, true); - gridNetworkOptions.finish(false); - - // build the final grid - grid.add(pnlNetworkOptions).fill(true, true).expand(true, true); - grid.finish(false); - } -} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/NetshareConfigurator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/NetshareConfigurator.java deleted file mode 100644 index d80ba8b3..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/NetshareConfigurator.java +++ /dev/null @@ -1,374 +0,0 @@ -package org.openslx.dozmod.gui.control; - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.util.ArrayList; -import java.util.EventListener; -import java.util.EventObject; -import java.util.List; - -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JPasswordField; -import javax.swing.JTextField; -import javax.swing.event.EventListenerList; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; -import javax.swing.event.TableModelEvent; -import javax.swing.event.TableModelListener; - -import org.apache.log4j.Logger; -import org.openslx.bwlp.thrift.iface.NetShare; -import org.openslx.bwlp.thrift.iface.NetShareAuth; -import org.openslx.dozmod.gui.Gui; -import org.openslx.dozmod.gui.changemonitor.DialogChangeMonitor; -import org.openslx.dozmod.gui.control.ComboBox.ComboBoxRenderer; -import org.openslx.dozmod.gui.control.table.NetshareTable; -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.util.FormatHelper; - -/** - * Widget for network share configuration of lectures - */ -public class NetshareConfigurator extends NetshareConfiguratorLayout { - - private static final long serialVersionUID = -3336605759245603655L; - private final static Logger LOGGER = Logger.getLogger(NetshareConfigurator.class); - private List<NetShare> tblNetshareData = null; - - // mount points / win drive letters - ideally, we would check whether the image is linux or windows based - // and either show a drive selection list like this one, or a textfield for a user-defined mount point... - private Character[] mountPoints = { 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', - 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; - - public NetshareConfigurator() { - super(); - tblNetshare.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - @Override - public void valueChanged(ListSelectionEvent e) { - NetShare item = tblNetshare.getSelectedItem(); - // ugly block-wise sets, but only one test needed compared to - // doing lots of item != null ? ... : ... - if (item == null) { - clearInputFields(); - return; - } - // share from the list is selected: fill bottom form and change "Add" to "Apply" - btnDel.setEnabled(true); - tfSharePath.setText(item.path); - tfShareName.setText(item.displayname); - tfUsername.setText(item.username); - tfPassword.setText(item.password); - cboNetshareAuth.setSelectedItem(item.auth); - cboNetshareMountPoint.setSelectedItem(Character.valueOf(item.mountpoint.charAt(0))); - btnAdd.setText("Ändern"); - } - }); - - cboNetshareMountPoint.setModel(new DefaultComboBoxModel<Character>(mountPoints)); - cboNetshareMountPoint.setSelectedItem(null); - - // combobox for share authentication types - cboNetshareAuth.setModel(new DefaultComboBoxModel<NetShareAuth>(NetShareAuth.values())); - cboNetshareAuth.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - NetShareAuth selectedAuth = cboNetshareAuth.getItemAt(cboNetshareAuth.getSelectedIndex()); - if (selectedAuth == null) - return; - boolean activate = selectedAuth == NetShareAuth.OTHER_USER; - // username field is needed to either special or guest user - tfUsername.setEnabled(activate); - lblUsername.setEnabled(activate); - tfPassword.setEnabled(activate); - lblPassword.setEnabled(activate); - chkShowPass.setEnabled(activate); - } - }); - cboNetshareAuth.setSelectedItem(null); - - btnAdd.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - // check if we are editing an existing share entry or - // creating a new one, check for input either way - NetShare input = new NetShare(); - - input.path = tfSharePath.getText(); - if (input.path == null || input.path.isEmpty()) { - lblError.setText("Kein Pfad angegeben!"); - return; - } - String inputShareName = tfShareName.getText(); - if (inputShareName.isEmpty()) { - lblError.setText("Kein Anzeigename angegeben!"); - return; - } - input.displayname = inputShareName; - - NetShareAuth inputNetShareAuth = cboNetshareAuth - .getItemAt(cboNetshareAuth.getSelectedIndex()); - if (inputNetShareAuth == null) { - lblError.setText("Kein Authentifizierungstyp angegeben!"); - return; - } - input.auth = inputNetShareAuth; - switch (inputNetShareAuth) { - case LOGIN_USER: - // this uses the bwLehrpool client's logged in user - // we don't need to have anything - break; - case OTHER_USER: - // save given username/password - input.username = tfUsername.getText(); - input.password = new String(tfPassword.getPassword()); - if (input.username.isEmpty()) { - lblError.setText("Kein Nutzername angegeben!"); - return; - } - break; - default: - input = null; - break; - } - if (input == null) { - lblError.setText("Fehlerhafte Eingabe"); - LOGGER.debug("Bad input, aborting."); - return; - } - // now check for optional mount path - Character inputMountPoint = cboNetshareMountPoint - .getItemAt(cboNetshareMountPoint.getSelectedIndex()); - if (inputMountPoint == null) { - lblError.setText("Kein Ziel angegeben!"); - return; - } - input.mountpoint = inputMountPoint.toString(); - // now decide whether to create a new entry or update existing one - NetShare oldEntry = tblNetshare.getSelectedItem(); - if (oldEntry != null) { - // editing existing one, delete it from the internal data - if (!tblNetshareData.remove(oldEntry)) { - lblError.setText("Änderung fehlgeschlagen!"); - LOGGER.debug("Failed to remove selected share for replacement: " + oldEntry); - return; - } - tblNetshare.setData(tblNetshareData, false); - } - // 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 (tblNetshareData.contains(input)) { - lblError.setText("Existiert bereits!"); - LOGGER.error("Network share already in the list, aborting."); - return; - } - // if a password is set, warn the user about its unsafe storage - // which we might want to implement one day... - if (input.password != null && !input.password.isEmpty()) { - if (!Gui.showMessageBox( - "Das eingebene Passwort wird im Klartext gespeichert " - + "und ist in der VM für jeden Nutzer sichtbar.\n" - + "Verwenden Sie auf keinen Fall sicherheitskritische Passwörter!" - + "\n\nMöchten Sie diesen Netzlaufwerk trotzdem hinzufügen?", - MessageType.QUESTION_YESNO, LOGGER, null)) { - return; - } - } - lblError.setText(null); - tblNetshareData.add(input); - tblNetshare.setData(tblNetshareData, false); - clearInputFields(); - } - }); - - btnDel.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - // try to delete the selected share - NetShare selection = tblNetshare.getSelectedItem(); - if (selection == null) { - return; - } - try { - if (!tblNetshareData.remove(selection)) { - // false if it was not found - LOGGER.error("Could not remove non-existant network share '" + selection.toString() - + "' from the table data: " + tblNetshareData.toString()); - return; - } - // refresh table data - tblNetshare.getModel().setData(tblNetshareData); - } catch (Exception ex) { - LOGGER.debug("Failed to remove " + selection.toString() + " from the table data.", ex); - return; - } - } - }); - - chkShowPass.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - if (e.getStateChange() != ItemEvent.SELECTED) { - tfPassword.setEchoChar('*'); - } else { - tfPassword.setEchoChar((char) 0); - } - } - }); - chkShowPass.setEnabled(false); - tfUsername.setEnabled(false); - lblUsername.setEnabled(false); - tfPassword.setEnabled(false); - lblPassword.setEnabled(false); - } - - private void clearInputFields() { - btnDel.setEnabled(false); - tfSharePath.setText(null); - tfShareName.setText(null); - tfUsername.setText(null); - tfPassword.setText(null); - cboNetshareAuth.setSelectedItem(null); - cboNetshareMountPoint.setSelectedItem(null); - btnAdd.setText("Hinzufügen"); - } - public List<NetShare> getState() { - return tblNetshareData; - } - - public boolean setState(List<NetShare> data) { - if (data == null) - return false; - if (tblNetshareData == null) { - tblNetshareData = new ArrayList<>(); - } - tblNetshareData = data; - tblNetshare.setData(tblNetshareData, false); - return true; - } - - public void addTableModelListener(TableModelListener listener) { - tblNetshare.getModel().addTableModelListener(listener); - } - - public void addToChangeMonitor(DialogChangeMonitor changeMonitor) { - changeMonitor.add(tblNetshare); - } -} - -/** - * Internal layout class for this widget - */ -class NetshareConfiguratorLayout extends JPanel { - - private static final long serialVersionUID = 6479525981542743622L; - - private final static String txtNetshareDesc = "<html>Hier können Sie Netzlaufwerke angeben," - + " die automatisch beim Start der Veranstaltung eingebunden werden sollen." - + " Der Platzhalter <em>%loginuser%</em> wird im Pfad durch den Loginnamen des Nutzers ersetzt.</html>"; - - protected final QLabel lblShareAuth, lblSharePath, lblShareName, lblMountPoint, lblUsername, lblPassword, - lblError; - protected final NetshareTable tblNetshare = new NetshareTable(); - protected final JTextField tfSharePath, tfShareName, tfUsername; - protected final JPasswordField tfPassword; - protected final JButton btnAdd, btnDel; - protected final JCheckBox chkShowPass; - protected final ComboBox<NetShareAuth> cboNetshareAuth = new ComboBox<>(new ComboBoxRenderer<NetShareAuth>() { - @Override - public String renderItem(NetShareAuth item) { - if (item == null) - return null; - return FormatHelper.netShareAuthName(item); - } - }); - protected final ComboBox<Character> cboNetshareMountPoint = new ComboBox<>(new ComboBoxRenderer<Character>() { - @Override - public String renderItem(Character letter) { - if (letter == null) - return null; - return letter.toString() + ":"; - } - }); - - public NetshareConfiguratorLayout() { - GridManager grid = new GridManager(this, 5, true, new Insets(3, 3, 3, 3)); - // top info panel - grid.add(new JLabel(txtNetshareDesc), 5).fill(true, false).expand(true, false); - grid.nextRow(); - // middle netshare list - grid.add(new QScrollPane(tblNetshare), 5).fill(true, true).expand(true, true); - grid.nextRow(); - - JPanel pnlNewShare = new JPanel(); - GridManager gridNewShare = new GridManager(pnlNewShare, 6, true); - pnlNewShare.setBorder(BorderFactory.createTitledBorder("Details")); - lblSharePath = new QLabel("Pfad"); - gridNewShare.add(lblSharePath); - tfSharePath = new JTextField(); - gridNewShare.add(tfSharePath, 5).fill(true, false).expand(true, false); - gridNewShare.nextRow(); - // bottom form to add a new share - lblShareName = new QLabel("Anzeigename"); - lblMountPoint = new QLabel("Ziel"); - tfShareName = new JTextField(); - // extra panel for fancy layout purposes... - JPanel pnlShareName = new JPanel(); - pnlShareName.setLayout(new BoxLayout(pnlShareName, BoxLayout.LINE_AXIS)); - pnlShareName.add(lblShareName); - pnlShareName.add(tfShareName); - pnlShareName.add(lblMountPoint); - pnlShareName.add(cboNetshareMountPoint); - gridNewShare.add(lblShareName); - gridNewShare.add(pnlShareName, 5).fill(true, false).expand(true, false); - gridNewShare.nextRow(); - lblShareAuth = new QLabel("Authentifizierung"); - gridNewShare.add(lblShareAuth); - gridNewShare.add(cboNetshareAuth, 5).fill(true, false).expand(true, false); - gridNewShare.nextRow(); - lblUsername = new QLabel("Username"); - gridNewShare.add(lblUsername); - tfUsername = new JTextField(20); - gridNewShare.add(tfUsername, 2).fill(true, false).expand(true, false); - lblPassword = new QLabel("Passwort"); - gridNewShare.add(lblPassword); - tfPassword = new JPasswordField(20); - gridNewShare.add(tfPassword, 2).fill(true, false).expand(true, false); - gridNewShare.nextRow(); - chkShowPass = new JCheckBox("Passwort anzeigen"); - JPanel pnlShowPass = new JPanel(); - pnlShowPass.setLayout(new BoxLayout(pnlShowPass, BoxLayout.LINE_AXIS)); - pnlShowPass.add(Box.createGlue()); - pnlShowPass.add(chkShowPass, BorderLayout.LINE_END); - gridNewShare.add(pnlShowPass, 6).fill(true, false).expand(true, false); - gridNewShare.nextRow(); - grid.add(pnlNewShare, 5).fill(true, false).expand(true, false); - grid.nextRow(); - // bottom panel for right-aligned button... - JPanel pnlButtonAdd = new JPanel(); - pnlButtonAdd.setLayout(new BoxLayout(pnlButtonAdd, BoxLayout.LINE_AXIS)); - btnAdd = new JButton("Hinzufügen"); - btnDel = new JButton("Entfernen"); - lblError = new QLabel(""); - lblError.setForeground(Color.RED); - pnlButtonAdd.add(lblError); - pnlButtonAdd.add(Box.createGlue()); - pnlButtonAdd.add(btnAdd, BorderLayout.LINE_END); - pnlButtonAdd.add(btnDel, BorderLayout.LINE_END); - grid.add(pnlButtonAdd, 5).fill(true, false).expand(true, false); - grid.finish(false); - } -} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/PersonLabel.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/PersonLabel.java index a0071824..7c53bf96 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/PersonLabel.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/PersonLabel.java @@ -11,7 +11,7 @@ import javax.swing.UIManager; import org.openslx.bwlp.thrift.iface.UserInfo; import org.openslx.dozmod.gui.helper.ColorUtil; import org.openslx.dozmod.util.FormatHelper; -import org.openslx.dozmod.util.OpenLinks; +import org.openslx.dozmod.util.DesktopEnvironment; /** * A label for displaying a {@link UserInfo} object. Supports a callback event @@ -91,7 +91,7 @@ public class PersonLabel extends QLabel { public void clicked(UserInfo user) { if (user == null || user.eMail == null) return; - OpenLinks.sendMail(user.eMail, null); + DesktopEnvironment.sendMail(user.eMail, null); } }; diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/RunscriptConfigurator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/RunscriptConfigurator.java deleted file mode 100644 index 3378294c..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/RunscriptConfigurator.java +++ /dev/null @@ -1,263 +0,0 @@ -package org.openslx.dozmod.gui.control; - -import java.awt.Color; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.StringReader; -import java.util.EventListener; -import java.util.EventObject; - -import javax.swing.Box; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; -import javax.swing.event.EventListenerList; - -import org.openslx.dozmod.gui.changemonitor.DialogChangeMonitor; -import org.openslx.dozmod.gui.control.ComboBox.ComboBoxRenderer; -import org.openslx.dozmod.gui.control.RunscriptConfigurator.RunscriptType; -import org.openslx.dozmod.gui.helper.GridManager; -import org.openslx.dozmod.gui.helper.TextChangeListener; - -/** - * Widget for advanced configuration options for lectures. This handles - * following options - Network rules - Runscript - USB - */ -public class RunscriptConfigurator extends RunscriptConfiguratorLayout { - - private static final long serialVersionUID = -3497629601818983994L; - - public static enum RunscriptType { - SHELL("Shellskript", "sh"), BATCH("Windows-Batch", "bat"); - - private final String displayName; - private final String extension; - - private RunscriptType(String name, String extension) { - this.displayName = name; - this.extension = extension; - } - - @Override - public String toString() { - return extension + " (" + displayName + ")"; - } - } - - public RunscriptConfigurator() { - super(); - - final TextChangeListener docListener = new TextChangeListener() { - @Override - public void changed() { - fireRunscriptConfigurationChangeEvent(new RunscriptConfigurationChangeEvent( - new Object())); - } - }; - taRunScript.getDocument().addDocumentListener(docListener); - cboRunscriptType.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - fireRunscriptConfigurationChangeEvent(new RunscriptConfigurationChangeEvent( - new Object())); - } - }); - cboRunscriptType.getEditor().getEditorComponent().addKeyListener(new KeyAdapter() { - @Override - public void keyReleased(KeyEvent e) { - fireRunscriptConfigurationChangeEvent(new RunscriptConfigurationChangeEvent( - new Object())); - } - }); - } - - private void setError(final String msg) { - lblError.setText(msg); - } - /** - * Gets the runscript as String. The chosen interpreter will get encoded as - * the first line of the script. - * - * @return runscript as String. If no text was entered, returns a empty - * string. - */ - public String getState() { - setError(""); // fill remove any prior errors, we'll reset them if needed - // handle user input, this is tricky since - // * either an item has been selected -> editorContent will be of our enum type - // * user typed its own interpreter into the box -> editorContent will be a castable String - String extension = null; - Object cboContent = cboRunscriptType.getEditor().getItem(); - if (cboContent instanceof RunscriptType) { - extension = ((RunscriptType) cboContent).extension; - } else if (cboContent instanceof String) { - extension = (String) cboContent; - } - String taInputText = taRunScript.getText(); - if (taInputText.isEmpty()) - return ""; - if (extension == null || extension.isEmpty()) { - // this should never happen, so return null to report this invalid state - setError("Fehlende Dateinamenerweiterung!"); - return null; - } - setError(""); - return "ext=" + extension + "\n" + taInputText; - } - - /** - * Sets the state of this widget to the given AdvancedConfiguration. Basicly - * this sets the content of the text areas to the corresponding network - * rules/runscript as given by the AdvancedConfiguration object - * - * @param config - * AdvancedConfiguration to set the state to - */ - public void setState(final String config) { - if (config == null || config.isEmpty()) { - cboRunscriptType.setSelectedItem(null); - taRunScript.setText(""); - return; - } - String extensionHeader = null; - try { - BufferedReader reader = new BufferedReader(new StringReader(config)); - extensionHeader = reader.readLine(); - reader.close(); - } catch (IOException e) { - // swallow ... - } - if (extensionHeader != null) { - // we should have following format: ext=<interpreter> - // e.g. ext=sh - extensionHeader = extensionHeader.replace("ext=", ""); - for (RunscriptType type : RunscriptType.values()) { - if (type.extension.equals(extensionHeader)) { - cboRunscriptType.setSelectedItem(type); - // mark that we found it by nulling the shebang... - extensionHeader = null; - continue; - } - } - if (extensionHeader != null) { - // user specific shebang, so just write the text to the cbo - cboRunscriptType.getEditor().setItem(extensionHeader); - } - } - // finished with the interpreter, remove that line from the given config - // before setting that text - taRunScript.setText(config.replaceFirst("^ext=.*\n", "")); - } - - /** - * Custom event mechanism to detect changes to the user list (Mostly needed - * for the reactToChange() stuff in LectureDetailsWindow) - */ - protected EventListenerList listenerList = new EventListenerList(); - - public class RunscriptConfigurationChangeEvent extends EventObject { - - private static final long serialVersionUID = -8779550754760035845L; - - public RunscriptConfigurationChangeEvent(Object source) { - super(source); - } - } - - public interface RunscriptConfigurationChangeEventListener extends - EventListener { - public void stateChanged(RunscriptConfigurationChangeEvent event); - } - - public void addRunscriptConfigurationChangeEventListener( - RunscriptConfigurationChangeEventListener listener) { - listenerList.add(RunscriptConfigurationChangeEventListener.class, - listener); - } - - public void removeRunscriptConfigurationChangeEventListener( - RunscriptConfigurationChangeEventListener listener) { - listenerList.remove(RunscriptConfigurationChangeEventListener.class, - listener); - } - - void fireRunscriptConfigurationChangeEvent( - RunscriptConfigurationChangeEvent evt) { - Object[] listeners = listenerList.getListenerList(); - for (int i = 0; i < listeners.length; i++) { - if (listeners[i] == RunscriptConfigurationChangeEventListener.class) { - ((RunscriptConfigurationChangeEventListener) listeners[i + 1]) - .stateChanged(evt); - } - } - } - - public void addToChangeMonitor(DialogChangeMonitor changeMonitor) { - changeMonitor.add(taRunScript); - changeMonitor.addEditableCombo(cboRunscriptType, null); - } - -} - -/** - * Internal layout class for the advanced configurator (to keep it clean even - * for widgets) - */ -class RunscriptConfiguratorLayout extends JPanel { - - private static final long serialVersionUID = 648729071828404053L; - - private final static String txtRunScriptDesc = "Ein hier eingetragenes Skript wird nach dem Start dieser VM automatisch ausgeführt."; - protected final QLabel lblError; - protected final JTextArea taRunScript; - protected final ComboBox<RunscriptType> cboRunscriptType; - - public RunscriptConfiguratorLayout() { - - GridManager grid = new GridManager(this, 2, true, new Insets(5, 5, 5, 5)); - taRunScript = new JTextArea("", 5, 20); - JScrollPane scpRunScript = new JScrollPane(taRunScript, - JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, - JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - taRunScript.setLineWrap(true); - taRunScript.setWrapStyleWord(true); - grid.add(new WordWrapLabel(txtRunScriptDesc, false, true), 2) - .fill(true, false).expand(true, false); - grid.nextRow(); - cboRunscriptType = new ComboBox<RunscriptType>( - new ComboBoxRenderer<RunscriptType>() { - @Override - public String renderItem(RunscriptType item) { - if (item == null) - return null; - return item.toString(); - } - }); - cboRunscriptType.setModel(new DefaultComboBoxModel<RunscriptType>( - RunscriptType.values())); - ; - cboRunscriptType.setEditable(true); - grid.add(new QLabel("Dateinamenserweiterung: ")).fill(false, false) - .expand(false, false); - grid.add(cboRunscriptType).fill(true, false) - .expand(true, false); - grid.nextRow(); - grid.add(scpRunScript, 2).fill(true, true).expand(true, true); - grid.nextRow(); - lblError = new QLabel(""); - lblError.setForeground(Color.RED); - JPanel pnlError = new JPanel(); - pnlError.add(Box.createGlue()); - pnlError.add(lblError); - pnlError.add(Box.createGlue()); - grid.add(pnlError, 2).fill(true, false).expand(true, false); - grid.finish(false); - - } -} |