/* PersonaDialog.java A subclass of JDialog that allows switching among personas Created: 17 February 1999 Module By: Brian O'Mara ----------------------------------------------------------------------- Ganymede Directory Management System Copyright (C) 1996-2012 The University of Texas at Austin Ganymede is a registered trademark of The University of Texas at Austin Contact information Author Email: ganymede_author@arlut.utexas.edu Email mailing list: ganymede@arlut.utexas.edu US Mail: Computer Science Division Applied Research Laboratories The University of Texas at Austin PO Box 8029, Austin TX 78713-8029 Telephone: (512) 835-3200 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, see <http://www.gnu.org/licenses/>. */ package arlut.csd.ganymede.client; import java.awt.AWTEvent; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dialog; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowEvent; import java.util.Vector; import javax.swing.Box; import javax.swing.ButtonGroup; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JRadioButton; import javax.swing.JSeparator; import javax.swing.border.EmptyBorder; import javax.swing.border.EtchedBorder; import javax.swing.border.TitledBorder; import arlut.csd.JDialog.StandardDialog; import arlut.csd.JDialog.StringDialog; import arlut.csd.Util.TranslationService; /*------------------------------------------------------------------------------ class PersonaDialog ------------------------------------------------------------------------------*/ /** * Persona selection dialog * * @version $Id$ * @author Brian O'Mara */ public class PersonaDialog extends StandardDialog implements ActionListener { public final static boolean debug = false; /** * TranslationService object for handling string localization in the * Ganymede client. */ static final TranslationService ts = TranslationService.getTranslationService("arlut.csd.ganymede.client.PersonaDialog"); // --- Vector personae; JButton login; gclient gc; private JPasswordField password; ActionListener personaListener; ButtonGroup personaGroupRB; String my_username, currentPersonaString, newPersona; public boolean requirePassword = false; public boolean changedOK = false; /* -- */ public PersonaDialog(gclient gc, boolean requirePassword) { // "Choose Persona" super(gc, ts.l("init.title"), StandardDialog.ModalityType.DOCUMENT_MODAL); this.requirePassword = requirePassword; this.gc = gc; this.personae = gc.personae; this.personaListener = gc.personaListener; this.my_username = gc.my_username; this.currentPersonaString = gc.currentPersonaString; if (requirePassword) { enableEvents(AWTEvent.WINDOW_EVENT_MASK); } // Main dialog container JPanel pane = new JPanel(new BorderLayout()); this.setContentPane(pane); JPanel topPanel = new JPanel(new BorderLayout()); JPanel buttonPanel = new JPanel(); pane.add("Center", topPanel); // Personae go here. pane.add("South", buttonPanel); // "OK" button. // "OK" button login = new JButton(StringDialog.getDefaultOk()); buttonPanel.add(login); login.addActionListener(personaListener); login.addActionListener(this); // Panel to hold persona radiobuttons and pass field JPanel personaPanel = new JPanel(new BorderLayout()); // "Select Persona" personaPanel.setBorder(new TitledBorder(new EtchedBorder(), ts.l("init.border_title"), TitledBorder.LEFT, TitledBorder.TOP)); JLabel image = new JLabel(new ImageIcon(gc.personaIcon)); if (requirePassword) { image.setBorder(new EmptyBorder(new Insets(10,15,0,15))); image.setVerticalAlignment(JLabel.TOP); JPanel topPersonaPanel = new JPanel(new BorderLayout()); // "<html><br>The Ganymede server timed you out due to inactivity.<br><br>You will have to re-authenticate with your password in order to continue using Ganymede.</html>" JLabel explanation = new JLabel(ts.l("init.timed_out_msg")); explanation.setBorder(new EmptyBorder(new Insets(0,0,0,10))); topPersonaPanel.add("West", image); topPersonaPanel.add("Center", explanation); personaPanel.add("North", topPersonaPanel); } else { image.setBorder(new EmptyBorder(new Insets(10,15,0,0))); image.setVerticalAlignment(JLabel.TOP); personaPanel.add("West", image); } topPanel.add("Center", personaPanel); topPanel.add("South", new JSeparator()); password = new JPasswordField(10); password.addActionListener(this); JPanel passPanel = new JPanel(new BorderLayout()); // "Password:\ " passPanel.add("West", new JLabel(ts.l("init.password_field"))); passPanel.add("Center",password); Box personaBox = Box.createVerticalBox(); personaGroupRB = new ButtonGroup(); if (debug) { System.out.println("Adding persona stuff"); } // Build up persona list as radiobutton group for (int i= personae.size()-1;i >=0; i--) { String p = (String)personae.elementAt(i); JRadioButton rb = new JRadioButton(p); // Note that all strings (incl actionCommand) should be _compared_ as // lowercase. Since there is a need for caps to be displayed (title, etc), // I didn't just convert to lowercase. if (p.toLowerCase().equals(currentPersonaString.toLowerCase())) { rb.doClick(); // No actionListener yet, so just selects current username } rb.addActionListener(personaListener); personaGroupRB.add(rb); personaBox.add(rb); } // Give a little space b/t buttons and pass field personaBox.add(Box.createVerticalStrut(25)); personaBox.add(passPanel); personaPanel.add("Center", personaBox); pack(); pane.revalidate(); // Win95 browser fix?? updatePassField(currentPersonaString); } public void actionPerformed(ActionEvent e) { // Hitting enter after typing pass is like clicking OK. if (e.getSource() instanceof JPasswordField) { // do this so the PersonaListener gets it login.doClick(); } else { // Clicking OK hides the dialog, as long as // we aren't forcing a password if (requirePassword && getPasswordField().equals("")) { if (debug) { System.err.println("Rejecting actionPerformed.doClick() due to password"); } return; } setHidden(true); } } // intercept window closure, make sure we're ok protected void processWindowEvent(WindowEvent e) { if (!requirePassword || changedOK) { super.processWindowEvent(e); } else if (e.getID() == WindowEvent.WINDOW_CLOSING) { super.processWindowEvent(e); if (requirePassword && !changedOK) { gc.logout(); } } else { super.processWindowEvent(e); } } public void setHidden(boolean bool) { if (debug) { System.err.println("setHidden"); } bool = !bool; login.setEnabled(bool); password.setEnabled(bool); this.setVisible(bool); } public ButtonGroup getButtonGroup() { return personaGroupRB; } String getPasswordField() { return new String(password.getPassword()); } // updatePassField called when RadioButton is toggled. // Updates focus and textfield appropriately. void updatePassField(String newPersona) { this.newPersona = newPersona; // If still same persona or base user (no ":" in name) then disable password field if (!requirePassword && ((newPersona.toLowerCase()).equals(currentPersonaString.toLowerCase()) || (newPersona.indexOf(":") < 0))) { password.setText(""); password.setEditable(false); password.setBackground(Color.lightGray); password.requestFocus(); } else { password.setText(""); password.setEditable(true); password.setBackground(Color.white); password.requestFocus(); } } // Access to most recent RButton selection. String getNewPersona(){ return newPersona; } }