/* *------------------------------------------------------------------------------ * Copyright (C) 2006-2015 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.agents.metadata.editor; import java.awt.FlowLayout; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Image; 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.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.openmicroscopy.shoola.util.CommonsLangUtils; import org.openmicroscopy.shoola.agents.metadata.IconManager; import org.openmicroscopy.shoola.agents.metadata.MetadataViewerAgent; import org.openmicroscopy.shoola.agents.metadata.util.UploadPictureDialog; import org.openmicroscopy.shoola.agents.util.EditorUtil; import org.openmicroscopy.shoola.agents.util.browser.DataNode; import org.openmicroscopy.shoola.agents.util.ui.PermissionsPane; import org.openmicroscopy.shoola.env.data.login.UserCredentials; import org.openmicroscopy.shoola.env.data.model.AdminObject; import org.openmicroscopy.shoola.env.ui.UserNotifier; import org.openmicroscopy.shoola.util.image.geom.Factory; import org.openmicroscopy.shoola.util.ui.Selectable; import org.openmicroscopy.shoola.util.ui.SelectableComboBoxModel; import org.openmicroscopy.shoola.util.ui.UIUtilities; import omero.gateway.model.ExperimenterData; import omero.gateway.model.GroupData; /** * Component displaying the user details. * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author Donald MacDonald      * <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a> * @version 3.0 * @since OME3.0 */ class UserProfile extends JPanel implements ActionListener, ChangeListener, DocumentListener, PropertyChangeListener { /** Text of the label in front of the new password area. */ private static final String PASSWORD_OLD = "Old password"; /** Text of the label in front of the new password area. */ private static final String PASSWORD_NEW = "New password"; /** Text of the label in front of the confirmation password area. */ private static final String PASSWORD_CONFIRMATION = "Confirm password"; /** The title of the dialog displayed if a problem occurs. */ private static final String PASSWORD_CHANGE_TITLE = "Change Password"; /** The default user's photo.*/ private static final Image USER_PHOTO; static { IconManager icons = IconManager.getInstance(); USER_PHOTO = icons.getImageIcon(IconManager.USER_PHOTO_32).getImage(); } /** The items that can be edited. */ private Map<String, JTextField> items; /** UI component displaying the groups, the user is a member of. */ private JComboBox groupsBox; /** Password field to enter the new password. */ private JPasswordField passwordNew; /** Password field to confirm the new password. */ private JPasswordField passwordConfirm; /** Hosts the old password. */ private JPasswordField oldPassword; /** Modify password. */ private JButton passwordButton; /** Button to add the user to group. */ private JButton manageButton; /** Box to make the selected user an administrator. */ private JCheckBox adminBox; /** Box to make the user active or not. */ private JCheckBox activeBox; /** Box to make the selected user the owner of the group is a member of. */ private JCheckBox ownerBox; /** Reference to the Model. */ private EditorModel model; /** Reference to the Model. */ private EditorUI view; /** The user's details. */ private Map<String, String> details; /** Flag indicating that the selected user is an owner of the group. */ private boolean groupOwner; /** Indicates that the user is an administrator. */ private boolean admin; /** Indicates that the user is active or not. */ private boolean active; /** Component displaying the permissions status. */ private PermissionsPane permissionsPane; /** The field hosting the login name. */ private JTextField loginArea; /** Component displaying the photo of the user. */ private UserProfileCanvas userPicture; /** Component used to change the user's photo.*/ private JLabel changePhoto; /** Component used to delete the user's photo.*/ private JButton deletePhoto; /** Save the changes.*/ private JButton saveButton; /** The component hosting the password controls.*/ private JPanel passwordPanel; /** Modifies the existing password. */ private void changePassword() { UserNotifier un; if (!oldPassword.isVisible()) { StringBuffer buf = new StringBuffer(); buf.append(passwordNew.getPassword()); String newPass = buf.toString(); if (CommonsLangUtils.isBlank(newPass)) { un = MetadataViewerAgent.getRegistry().getUserNotifier(); un.notifyInfo(PASSWORD_CHANGE_TITLE, "Please enter the new password."); passwordNew.requestFocus(); return; } passwordNew.setText(""); model.resetPassword(newPass); return; } StringBuffer buf = new StringBuffer(); buf.append(passwordNew.getPassword()); String newPass = buf.toString(); String pass = buf.toString(); buf = new StringBuffer(); buf.append(passwordConfirm.getPassword()); String confirm = buf.toString(); buf = new StringBuffer(); buf.append(oldPassword.getPassword()); String old = buf.toString(); if (CommonsLangUtils.isBlank(old)) { un = MetadataViewerAgent.getRegistry().getUserNotifier(); un.notifyInfo(PASSWORD_CHANGE_TITLE, "Please enter your old password."); oldPassword.requestFocus(); return; } if (CommonsLangUtils.isBlank(newPass)) { un = MetadataViewerAgent.getRegistry().getUserNotifier(); un.notifyInfo(PASSWORD_CHANGE_TITLE, "Please enter your new password."); passwordNew.requestFocus(); return; } if (old.equals(newPass)) { un = MetadataViewerAgent.getRegistry().getUserNotifier(); un.notifyInfo(PASSWORD_CHANGE_TITLE, "Your new and old passwords are the same.\n" + "Please enter a new password."); passwordNew.setText(""); passwordConfirm.setText(""); passwordNew.requestFocus(); return; } if (pass == null || CommonsLangUtils.isBlank(confirm) || !pass.equals(confirm)) { un = MetadataViewerAgent.getRegistry().getUserNotifier(); un.notifyInfo(PASSWORD_CHANGE_TITLE, "The passwords entered do not match.\n" + "Please try again."); passwordNew.setText(""); passwordConfirm.setText(""); passwordNew.requestFocus(); return; } model.changePassword(old, confirm); } /** * Loads the collection of existing groups and * select where to add the user to or remove the user from. */ private void manageGroup() { } /** * Returns <code>true</code> if the user can modify the photo, * <code></code> otherwise. * * @return See above. */ private boolean canModifyPhoto() { Object object = model.getRefObject(); if (!(object instanceof ExperimenterData)) return false; ExperimenterData exp = (ExperimenterData) object; ExperimenterData user = MetadataViewerAgent.getUserDetails(); return exp.getId() == user.getId(); } /** Initializes the components composing this display. */ private void initComponents() { admin = false; active = false; groupOwner = false; userPicture = new UserProfileCanvas(); userPicture.setBackground(UIUtilities.BACKGROUND_COLOR); IconManager icons = IconManager.getInstance(); changePhoto = new JLabel("Change Photo"); changePhoto.setToolTipText("Upload your photo."); changePhoto.setForeground(UIUtilities.HYPERLINK_COLOR); Font font = changePhoto.getFont(); changePhoto.setFont(font.deriveFont(font.getStyle(), font.getSize()-2)); changePhoto.setBackground(UIUtilities.BACKGROUND_COLOR); deletePhoto = new JButton(icons.getIcon(IconManager.DELETE_12)); boolean b = canModifyPhoto(); changePhoto.setVisible(b); deletePhoto.setToolTipText("Delete the photo."); deletePhoto.setBackground(UIUtilities.BACKGROUND_COLOR); UIUtilities.unifiedButtonLookAndFeel(deletePhoto); deletePhoto.setVisible(false); loginArea = new JTextField(); boolean a = MetadataViewerAgent.isAdministrator(); loginArea.setEnabled(a); loginArea.setEditable(a); adminBox = new JCheckBox(); adminBox.setVisible(false); adminBox.setBackground(UIUtilities.BACKGROUND_COLOR); ownerBox = new JCheckBox(); ownerBox.setBackground(UIUtilities.BACKGROUND_COLOR); activeBox = new JCheckBox(); activeBox.setBackground(UIUtilities.BACKGROUND_COLOR); activeBox.setVisible(false); passwordButton = new JButton("Change password"); passwordButton.setEnabled(false); passwordButton.setBackground(UIUtilities.BACKGROUND_COLOR); passwordButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { changePassword(); } }); saveButton = new JButton("Save"); saveButton.setEnabled(false); saveButton.setBackground(UIUtilities.BACKGROUND_COLOR); saveButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { GroupData g = getSelectedGroup(); ExperimenterData exp = (ExperimenterData) model.getRefObject(); if (exp.getDefaultGroup().getId() != g.getId()) model.fireAdminSaving(g, true); view.saveData(true); } }); manageButton = new JButton("Group"); manageButton.setEnabled(false); manageButton.setBackground(UIUtilities.BACKGROUND_COLOR); manageButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { manageGroup(); } }); passwordPanel = new JPanel(); passwordPanel.setBackground(UIUtilities.BACKGROUND_COLOR); passwordNew = new JPasswordField(); passwordNew.setBackground(UIUtilities.BACKGROUND_COLOR); passwordConfirm = new JPasswordField(); passwordConfirm.setBackground(UIUtilities.BACKGROUND_COLOR); oldPassword = new JPasswordField(); oldPassword.setBackground(UIUtilities.BACKGROUND_COLOR); items = new HashMap<String, JTextField>(); ExperimenterData user = (ExperimenterData) model.getRefObject(); Collection<GroupData> groups = user.getGroups(); GroupData defaultGroup = user.getDefaultGroup(); groupsBox = new JComboBox(); SelectableComboBoxModel m = new SelectableComboBoxModel(); Iterator<GroupData> i = groups.iterator(); GroupData g; Selectable<DataNode> node, selected = null; while (i.hasNext()) { g = i.next(); if (!model.isSystemGroup(g.getId(), GroupData.USER)) { node = new Selectable<DataNode>(new DataNode(g), true); if (g.getId() == defaultGroup.getId()) selected = node; m.addElement(node); } } groupsBox.setModel(m); if (selected != null) groupsBox.setSelectedItem(selected); groupsBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { hasDataToSave(); } }); permissionsPane = new PermissionsPane(defaultGroup.getPermissions(), UIUtilities.BACKGROUND_COLOR, model.isAdministrator()); permissionsPane.disablePermissions(); ExperimenterData logUser = model.getCurrentUser(); if (MetadataViewerAgent.isAdministrator()) { //Check that the user is not the one currently logged. oldPassword.setVisible(false); adminBox.setVisible(true); activeBox.setVisible(true); adminBox.addChangeListener(this); active = user.isActive(); activeBox.setSelected(active); activeBox.setEnabled(!model.isSelf() && !model.isSystemUser(user.getId())); activeBox.addChangeListener(this); //indicate if the user is an administrator admin = isUserAdministrator(); adminBox.setSelected(admin); adminBox.setEnabled(!model.isSelf() && !model.isSystemUser(user.getId())); ownerBox.addChangeListener(this); ownerBox.setEnabled(!model.isSystemUser(user.getId())); } else { ownerBox.setEnabled(false); passwordConfirm.getDocument().addDocumentListener( new DocumentListener() { /** * Allows the user to interact with the password controls * depending on the value entered. * @see DocumentListener#removeUpdate(DocumentEvent) */ public void removeUpdate(DocumentEvent e) { handlePasswordEntered(); } /** * Allows the user to interact with the password controls * depending on the value entered. * @see DocumentListener#insertUpdate(DocumentEvent) */ public void insertUpdate(DocumentEvent e) { handlePasswordEntered(); } /** * Required by the {@link DocumentListener} I/F but * no-operation implementation in our case. * @see DocumentListener#changedUpdate(DocumentEvent) */ public void changedUpdate(DocumentEvent e) {} }); } passwordNew.getDocument().addDocumentListener( new DocumentListener() { /** * Allows the user to interact with the password controls * depending on the value entered. * @see DocumentListener#removeUpdate(DocumentEvent) */ public void removeUpdate(DocumentEvent e) { handlePasswordEntered(); } /** * Allows the user to interact with the password controls * depending on the value entered. * @see DocumentListener#insertUpdate(DocumentEvent) */ public void insertUpdate(DocumentEvent e) { handlePasswordEntered(); } /** * Required by the {@link DocumentListener} I/F but * no-operation implementation in our case. * @see DocumentListener#changedUpdate(DocumentEvent) */ public void changedUpdate(DocumentEvent e) {} }); if (user.getId() == logUser.getId()) { MouseAdapter adapter = new MouseAdapter() { /** Brings up a chooser to load the user image. */ public void mouseReleased(MouseEvent e) { uploadPicture(); } }; changePhoto.addMouseListener(adapter); deletePhoto.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { model.deletePicture(); setUserPhoto(null); } }); if (groups.size() > 1) { groupsBox.addActionListener(new ActionListener() { /** * Listens to the change of default group. */ public void actionPerformed(ActionEvent evt) { GroupData g = getSelectedGroup(); //update the default group permissionsPane.resetPermissions(g.getPermissions()); permissionsPane.disablePermissions(); setGroupOwner(g); ExperimenterData exp = (ExperimenterData) model.getRefObject(); saveButton.setEnabled( exp.getDefaultGroup().getId() != g.getId()); } }); } } } /** * Returns the selected group. * * @return See above. */ private GroupData getSelectedGroup() { Selectable<?> item = (Selectable<?>) groupsBox.getSelectedItem(); DataNode node = (DataNode) item.getObject(); return (GroupData) node.getDataObject(); } /** * Returns <code>true</code> if the user is an administrator, * <code>false</code> otherwise. * * @return See above. */ private boolean isUserAdministrator() { ExperimenterData user = (ExperimenterData) model.getRefObject(); ExperimenterData loggedInUser = MetadataViewerAgent.getUserDetails(); if (user.getId() == loggedInUser.getId()) return MetadataViewerAgent.isAdministrator(); List<GroupData> groups = user.getGroups(); Iterator<GroupData> i = groups.iterator(); GroupData g; while (i.hasNext()) { g = i.next(); if (model.isSystemGroup(g.getId(), GroupData.SYSTEM)) return true; } return false; } /** * Sets the enabled flag of some password controls depending on the * text entered. */ private void handlePasswordEntered() { char[] values = passwordNew.getPassword(); if (oldPassword.isVisible()) { char[] oldValues = oldPassword.getPassword(); char[] confirmValues = passwordConfirm.getPassword(); if (values != null && oldValues != null && confirmValues != null) { passwordButton.setEnabled(values.length > 0 && oldValues.length > 0 && confirmValues.length == values.length); } } else { passwordButton.setEnabled(values != null && values.length > 0); } } /** Brings up the dialog to choose the photo to upload. */ private void uploadPicture() { UploadPictureDialog d = new UploadPictureDialog( MetadataViewerAgent.getRegistry().getTaskBar().getFrame()); d.addPropertyChangeListener(this); d.pack(); UIUtilities.centerAndShow(d); } /** * Selects or not the {@link #ownerBox} if the selected user * is an owner. Returns <code>true</code> if the currently logged in * user is an owner of the group. * * @param group The group to handle. */ private boolean setGroupOwner(GroupData group) { Object refObject = model.getRefObject(); if (!(refObject instanceof ExperimenterData)) return false; ExperimenterData ref = (ExperimenterData) refObject; long userID = MetadataViewerAgent.getUserDetails().getId(); Set<ExperimenterData> leaders = group.getLeaders(); ExperimenterData exp; boolean isOwner = false; if (leaders != null) { Iterator<ExperimenterData> i = leaders.iterator(); while (i.hasNext()) { exp = (ExperimenterData) i.next(); if (exp.getId() == ref.getId()) { groupOwner = true; ownerBox.setSelected(true); } if (exp.getId() == userID) isOwner = true; } } return isOwner; } /** * Returns the component displayed the user photo. * * @return See above. */ private JPanel buildProfileCanvas() { JPanel p = new JPanel(); p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); p.add(userPicture); p.setBackground(UIUtilities.BACKGROUND_COLOR); JPanel bar = new JPanel(); bar.setBackground(UIUtilities.BACKGROUND_COLOR); bar.setLayout(new FlowLayout(FlowLayout.LEFT)); bar.add(changePhoto); bar.add(deletePhoto); p.add(bar); return p; } /** * Builds the panel hosting the user's details. * * @return See above. */ private JPanel buildContentPanel() { ExperimenterData user = (ExperimenterData) model.getRefObject(); boolean editable = model.isUserOwner(user); if (!editable) editable = MetadataViewerAgent.isAdministrator(); details = EditorUtil.convertExperimenter(user); JPanel content = new JPanel(); content.setBorder(BorderFactory.createTitledBorder("User")); content.setBackground(UIUtilities.BACKGROUND_COLOR); Entry<String, String> entry; Iterator<Entry<String, String>> i = details.entrySet().iterator(); JComponent label; JTextField area; String key, value; content.setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(0, 2, 2, 0); //Add log in name but cannot edit. c.gridx = 0; c.gridy = 0; c.gridwidth = GridBagConstraints.REMAINDER;//end row c.fill = GridBagConstraints.HORIZONTAL; content.add(buildProfileCanvas(), c); c.gridy++; c.gridx = 0; label = EditorUtil.getLabel(EditorUtil.DISPLAY_NAME, true); label.setBackground(UIUtilities.BACKGROUND_COLOR); c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last c.fill = GridBagConstraints.NONE;//reset to default c.weightx = 0.0; content.add(label, c); c.gridx++; content.add(Box.createHorizontalStrut(5), c); c.gridx++; c.gridwidth = GridBagConstraints.REMAINDER;//end row c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; loginArea.setText(user.getUserName()); loginArea.setEnabled(false); loginArea.setEditable(false); if (MetadataViewerAgent.isAdministrator() && !model.isSystemUser(user.getId()) && !model.isSelf()) { loginArea.setEnabled(true); loginArea.getDocument().addDocumentListener(this); } content.add(loginArea, c); while (i.hasNext()) { ++c.gridy; c.gridx = 0; entry = i.next(); key = entry.getKey(); value = entry.getValue(); label = EditorUtil.getLabel(key, EditorUtil.FIRST_NAME.equals(key) || EditorUtil.LAST_NAME.equals(key)); area = new JTextField(value); area.setBackground(UIUtilities.BACKGROUND_COLOR); area.setEditable(editable); area.setEnabled(editable); if (editable) area.getDocument().addDocumentListener(this); items.put(key, area); label.setBackground(UIUtilities.BACKGROUND_COLOR); c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last c.fill = GridBagConstraints.NONE;//reset to default c.weightx = 0.0; content.add(label, c); c.gridx++; content.add(Box.createHorizontalStrut(5), c); c.gridx++; c.gridwidth = GridBagConstraints.REMAINDER;//end row c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; content.add(area, c); } c.gridx = 0; c.gridy++; label = EditorUtil.getLabel(EditorUtil.DEFAULT_GROUP, false); c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last c.fill = GridBagConstraints.NONE;//reset to default c.weightx = 0.0; content.add(label, c); c.gridx++; content.add(Box.createHorizontalStrut(5), c); c.gridx++; c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; content.add(groupsBox, c); c.gridy++; content.add(permissionsPane, c); c.gridx = 0; c.gridy++; label = EditorUtil.getLabel(EditorUtil.GROUP_OWNER, false); c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last c.fill = GridBagConstraints.NONE; //reset to default c.weightx = 0.0; content.add(label, c); c.gridx++; content.add(Box.createHorizontalStrut(5), c); c.gridx++; c.gridwidth = GridBagConstraints.REMAINDER; //end row c.fill = GridBagConstraints.NONE; c.weightx = 1.0; content.add(ownerBox, c); if (activeBox.isVisible()) { c.gridx = 0; c.gridy++; label = EditorUtil.getLabel(EditorUtil.ACTIVE, false); c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last c.fill = GridBagConstraints.NONE; c.weightx = 0.0; content.add(label, c); c.gridx++; content.add(Box.createHorizontalStrut(5), c); c.gridx++; c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.NONE; c.weightx = 1.0; content.add(activeBox, c); } if (adminBox.isVisible()) { c.gridx = 0; c.gridy++; label = EditorUtil.getLabel(EditorUtil.ADMINISTRATOR, false); c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last c.fill = GridBagConstraints.NONE; c.weightx = 0.0; content.add(label, c); c.gridx++; content.add(Box.createHorizontalStrut(5), c); c.gridx++; c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.NONE; c.weightx = 1.0; content.add(adminBox, c); } c.gridx = 0; c.gridy++; content.add(Box.createHorizontalStrut(10), c); c.gridy++; label = UIUtilities.setTextFont(EditorUtil.MANDATORY_DESCRIPTION, Font.ITALIC); label.setForeground(UIUtilities.REQUIRED_FIELDS_COLOR); c.weightx = 0.0; content.add(label, c); return content; } /** * Builds the UI component hosting the UI component used to modify * the password. * * @param ldap * @return See above. */ private JPanel buildPasswordPanel(String ldap) { passwordPanel.removeAll(); if (CommonsLangUtils.isNotBlank(ldap)) { passwordPanel.setBorder( BorderFactory.createTitledBorder("LDAP")); passwordPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); passwordPanel.add(new JLabel(ldap)); return passwordPanel; } JPanel content = new JPanel(); content.setBackground(UIUtilities.BACKGROUND_COLOR); content.setBorder( BorderFactory.createTitledBorder("Change Password")); content.setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(0, 2, 2, 0); c.gridx = 0; c.gridy = 0; c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last c.fill = GridBagConstraints.NONE; c.weightx = 0.0; if (MetadataViewerAgent.isAdministrator()) { content.add(UIUtilities.setTextFont(PASSWORD_NEW), c); c.gridx++; c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; content.add(passwordNew, c); } else { content.add(UIUtilities.setTextFont(PASSWORD_OLD), c); c.gridx++; c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; content.add(oldPassword, c); c.gridy++; c.gridx = 0; c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last c.fill = GridBagConstraints.NONE; c.weightx = 0.0; content.add(UIUtilities.setTextFont(PASSWORD_NEW), c); c.gridx++; c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; content.add(passwordNew, c); c.gridy++; c.gridx = 0; c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last c.fill = GridBagConstraints.NONE; c.weightx = 0.0; content.add(UIUtilities.setTextFont(PASSWORD_CONFIRMATION), c); c.gridx++; c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; content.add(passwordConfirm, c); c.gridy++; c.gridx = 0; } passwordPanel = new JPanel(); passwordPanel.setBackground(UIUtilities.BACKGROUND_COLOR); passwordPanel.setLayout(new BoxLayout(passwordPanel, BoxLayout.Y_AXIS)); passwordPanel.add(content); JPanel buttonPanel = UIUtilities.buildComponentPanel(passwordButton); buttonPanel.setBackground(UIUtilities.BACKGROUND_COLOR); passwordPanel.add(buttonPanel); return passwordPanel; } /** Message displayed when one of the required fields is left blank. */ private void showRequiredField() { UserNotifier un = MetadataViewerAgent.getRegistry().getUserNotifier(); un.notifyInfo("Edit User settings", "The required fields cannot be left blank."); return; } /** * Creates a new instance. * * @param model Reference to the model. Mustn't be <code>null</code>. * @param view Reference to the control. Mustn't be <code>null</code>. */ UserProfile(EditorModel model, EditorUI view) { if (model == null) throw new IllegalArgumentException("No model."); if (view == null) throw new IllegalArgumentException("No view."); this.view = view; this.model = model; setBackground(UIUtilities.BACKGROUND_COLOR); } /** Builds and lays out the UI. */ void buildGUI() { removeAll(); initComponents(); setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(0, 2, 2, 0); c.gridx = 0; c.gridy = 0; c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last c.weightx = 1.0; add(buildContentPanel(), c); if (model.isUserOwner(model.getRefObject()) || MetadataViewerAgent.isAdministrator()) { c.gridy++; JPanel buttonPanel = UIUtilities.buildComponentPanel(saveButton); buttonPanel.setBackground(UIUtilities.BACKGROUND_COLOR); add(buttonPanel, c); c.gridy++; add(Box.createVerticalStrut(5), c); c.gridy++; boolean ldap = model.isLDAP(); loginArea.setEnabled(!ldap); loginArea.setEditable(!ldap); if (ldap) { model.fireLDAPDetailsLoading(); } else { buildPasswordPanel(null); } add(passwordPanel, c); } ExperimenterData exp = (ExperimenterData) model.getRefObject(); BufferedImage photo = model.getUserPhoto(exp.getId()); if (photo == null) setUserPhoto(null); else setUserPhoto(photo); deletePhoto.setVisible(photo != null && canModifyPhoto()); } /** Clears the password fields. */ void passwordChanged() { oldPassword.setText(""); passwordNew.setText(""); passwordConfirm.setText(""); } /** * Returns <code>true</code> if data to save, <code>false</code> * otherwise. * * @return See above. */ boolean hasDataToSave() { saveButton.setEnabled(false); String text = loginArea.getText(); if (CommonsLangUtils.isBlank(text)) return false; text = text.trim(); ExperimenterData original = (ExperimenterData) model.getRefObject(); if (!text.equals(original.getUserName())) { saveButton.setEnabled(true); return true; } if (original.getDefaultGroup().getId() != getSelectedGroup().getId()) { saveButton.setEnabled(true); return true; } //if (selectedIndex != originalIndex) return true; if (details == null) return false; Entry<String, String> entry; Iterator<Entry<String, String>> i = details.entrySet().iterator(); String key; String value; JTextField field; String v; if (items.size() > 0) { i = details.entrySet().iterator(); while (i.hasNext()) { entry = i.next(); key = entry.getKey(); field = items.get(key); if (field != null) { v = field.getText(); if (CommonsLangUtils.isBlank(v)) { if (EditorUtil.FIRST_NAME.equals(key) || EditorUtil.LAST_NAME.equals(key)) { return false; } } } } i = details.entrySet().iterator(); while (i.hasNext()) { entry = i.next(); key = entry.getKey(); field = items.get(key); if (field != null) { v = field.getText(); if (v != null) { v = v.trim(); value = (String) entry.getValue(); if (value == null) value = ""; if (!v.equals(value)) { saveButton.setEnabled(true); return true; } } } } } Boolean b = ownerBox.isSelected(); if (b.compareTo(groupOwner) != 0) { saveButton.setEnabled(true); return true; } if (adminBox.isVisible()) { b = adminBox.isSelected(); if (b.compareTo(admin) != 0) { saveButton.setEnabled(true); return true; } } if (activeBox.isVisible()) { b = activeBox.isSelected(); if (b.compareTo(active) != 0) { saveButton.setEnabled(true); return true; } } return false; } /** * Returns the experimenter to save. * * @return See above. */ Object getExperimenterToSave() { ExperimenterData original = (ExperimenterData) model.getRefObject(); //Required fields first String v = loginArea.getText(); if (v == null || v.trim().length() == 0) showRequiredField(); JTextField f = items.get(EditorUtil.EMAIL); v = f.getText(); if (v == null || v.trim().length() == 0) v = ""; original.setEmail(v); f = items.get(EditorUtil.INSTITUTION); v = f.getText(); if (v == null) v = ""; original.setInstitution(v.trim()); f = items.get(EditorUtil.LAST_NAME); v = f.getText(); if (v == null) v = ""; original.setLastName(v.trim()); f = items.get(EditorUtil.FIRST_NAME); v = f.getText(); if (v == null) v = ""; original.setFirstName(v.trim()); f = items.get(EditorUtil.MIDDLE_NAME); v = f.getText(); if (v == null) v = ""; original.setMiddleName(v.trim()); //set the groups GroupData g = null; String value = loginArea.getText().trim(); UserCredentials uc = new UserCredentials(value, ""); Boolean b = ownerBox.isSelected(); boolean a = false; if (b.compareTo(groupOwner) != 0) { a = true; uc.setOwner(b); Object parent = model.getParentRootObject(); if (parent instanceof GroupData) { Map<GroupData, Boolean> map = new HashMap<GroupData, Boolean>(); map.put((GroupData) parent, b); uc.setGroupsOwner(map); } } if (adminBox.isVisible()) { b = adminBox.isSelected(); if (b.compareTo(admin) != 0) { a = true; uc.setAdministrator(b); } } if (activeBox.isVisible()) { b = activeBox.isSelected(); if (b.compareTo(active) != 0) { a = true; uc.setActive(b); } } if (!original.getUserName().equals(value)) a = true; //if admin if (MetadataViewerAgent.isAdministrator()) a = true; if (a) { Map<ExperimenterData, UserCredentials> m = new HashMap<ExperimenterData, UserCredentials>(); m.put(original, uc); AdminObject object = new AdminObject(g, m, AdminObject.UPDATE_EXPERIMENTER); return object; } return original;//newOne; } /** * Sets the photo of the user. * * @param image The image to set. */ void setUserPhoto(BufferedImage image) { if (image == null) { userPicture.setImage(USER_PHOTO); deletePhoto.setVisible(false); return; } BufferedImage img = Factory.scaleBufferedImage(image, UserProfileCanvas.WIDTH); userPicture.setImage(img); deletePhoto.setVisible(canModifyPhoto()); repaint(); } /** Sets the parent of the node. */ void setParentRootObject() { Object parentRootObject = model.getParentRootObject(); if (parentRootObject instanceof GroupData) { setGroupOwner((GroupData) parentRootObject); } } /** Displays the LDAP details for the user.*/ void setLDAPDetails(String ldap) { loginArea.setEnabled(false); loginArea.setEditable(false); loginArea.getDocument().removeDocumentListener(this); buildPasswordPanel(ldap); revalidate(); repaint(); } /** * Fires a property change event when a index is selected. * @see ActionListener#actionPerformed(ActionEvent) */ public void actionPerformed(ActionEvent e) { buildGUI(); firePropertyChange(EditorControl.SAVE_PROPERTY, Boolean.valueOf(false), Boolean.valueOf(true)); } /** * Fires property indicating that some text has been entered. * @see DocumentListener#insertUpdate(DocumentEvent) */ public void insertUpdate(DocumentEvent e) { firePropertyChange(EditorControl.SAVE_PROPERTY, Boolean.valueOf(false), Boolean.valueOf(true)); } /** * Fires property indicating that some text has been entered. * @see DocumentListener#removeUpdate(DocumentEvent) */ public void removeUpdate(DocumentEvent e) { firePropertyChange(EditorControl.SAVE_PROPERTY, Boolean.valueOf(false), Boolean.valueOf(true)); } /** * Fires property indicating that some values have changed. * @see ChangeListener#stateChanged(ChangeEvent) */ public void stateChanged(ChangeEvent e) { firePropertyChange(EditorControl.SAVE_PROPERTY, Boolean.valueOf(false), Boolean.valueOf(true)); } /** * Uploads the photo. * @see PropertyChangeListener#propertyChange(PropertyChangeEvent) */ public void propertyChange(PropertyChangeEvent evt) { String name = evt.getPropertyName(); if (UploadPictureDialog.UPLOAD_PHOTO_PROPERTY.equals(name)) { List l = (List) evt.getNewValue(); if (l == null || l.size() != 2) return; File f = (File) l.get(0); if (f == null) return; model.uploadPicture(f, (String) l.get(1)); } } /** * Required by the {@link DocumentListener} I/F but no-operation * implementation in our case. * @see DocumentListener#changedUpdate(DocumentEvent) */ public void changedUpdate(DocumentEvent e) {} }