package cz.cuni.mff.inetpaint;
import cz.cuni.mff.inetpaint.swing.PresenceModeComboBoxRenderer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.util.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.util.StringUtils;
/**
* Panel, který se zobrazí při prvním spuštění programu a pokaždé, když je potřeba
* přihlásit se na server. Poskytuje základní možnosti připojení a spouští připojování
* skrze {@link ConnectionManager}.
*
* @author Jindřich Helcl
* @see ConnectionManager
*/
public class LoginPanel extends JPanel {
private static final int IMAGE_WIDTH = 133;
private static final int IMAGE_HEIGHT = 177;
private JButton loginButton;
private JCheckBox savePassCheckBox;
private JCheckBox autoLoginCheckBox;
private JComboBox accounts;
private JComboBox statusComboBox;
private JLabel accountLabel;
private JLabel passwordLabel;
private JPanel imagePanel;
private JPasswordField passwordField;
private void initComponents() {
final ResourceBundle rb = ResourceBundle.getBundle(Program.LANGUAGE_RESOURCE_PATH, Program.locale);
final Collection<String> users = UserPreferences.getAllUsers();
// v pripade, ze lastAccount nebyl ulozen, nebo nebylo ulozeno jeho
// nastaveni se zobrazi prazdny radek.
String lastAccount = UserPreferences.getLastAccount();
UserPreferences.setUserNode(lastAccount);
//final Image background = new ImageIcon( getClass().getResource("/inetpaint/images/about.png") ).getImage();
final Image background = Program.getImage("about.png");
imagePanel = new JPanel() {
@Override public void paintComponent(Graphics gr) {
gr.drawImage(background , 0, 0, null);
}
};
imagePanel.setMinimumSize(new Dimension(IMAGE_WIDTH, IMAGE_HEIGHT));
imagePanel.setMaximumSize(new Dimension(IMAGE_WIDTH, IMAGE_HEIGHT));
accountLabel = new JLabel(rb.getString("accountLabel"));
passwordLabel = new JLabel(rb.getString("passwordLabel"));
savePassCheckBox = new JCheckBox(rb.getString("savePassLabel"), UserPreferences.getSavePassword());
savePassCheckBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
autoLoginCheckBox.setEnabled(savePassCheckBox.isSelected());
}
});
boolean autoLogin = UserPreferences.getAutoLogin();
autoLoginCheckBox = new JCheckBox(rb.getString("autoLoginLabel"), autoLogin);
autoLoginCheckBox.setEnabled(savePassCheckBox.isSelected());
// kdyz je autologin true tak se prihlasit (řešeno na konci funkce)
passwordField = new JPasswordField(UserPreferences.getPassword());
Presence.Mode[] presenceModes = { Presence.Mode.available,
Presence.Mode.away,
Presence.Mode.chat,
Presence.Mode.dnd,
Presence.Mode.xa };
statusComboBox = new JComboBox(presenceModes);
statusComboBox.setEditable(false);
statusComboBox.setRenderer(new PresenceModeComboBoxRenderer());
statusComboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
loginButton.requestFocus();
}
});
accounts = new JComboBox(users.toArray());
accounts.setEditable(true);
accounts.setSelectedItem(lastAccount);
accounts.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String JID = (String)accounts.getSelectedItem();
// jen kdyz existuje, tak to zmenim.
UserPreferences.setUserNode(JID);
passwordField.setText(UserPreferences.getPassword());
// zmena prezence
savePassCheckBox.setSelected(UserPreferences.getSavePassword());
autoLoginCheckBox.setSelected(UserPreferences.getAutoLogin());
autoLoginCheckBox.setEnabled(savePassCheckBox.isSelected());
}
});
loginButton = new JButton(rb.getString("loginButtonLabel"));
loginButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
login();
}
});
// následuje už jen čistě design
GroupLayout layout = new GroupLayout(this);
setLayout(layout);
layout.setHorizontalGroup( layout.createParallelGroup()
.addGroup(GroupLayout.Alignment.CENTER, layout.createSequentialGroup()
.addContainerGap(20, Short.MAX_VALUE)
.addComponent(imagePanel)
.addContainerGap(20, Short.MAX_VALUE) )
.addGap(30)
.addComponent(accountLabel)
.addComponent(accounts)
.addComponent(passwordLabel)
.addComponent(passwordField)
.addComponent(statusComboBox)
.addComponent(savePassCheckBox)
.addComponent(autoLoginCheckBox)
.addComponent(loginButton)
);
layout.setVerticalGroup( layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(imagePanel) )
.addComponent(accountLabel)
.addComponent(accounts, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(passwordLabel)
.addComponent(passwordField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(statusComboBox, GroupLayout.PREFERRED_SIZE, 25, GroupLayout.PREFERRED_SIZE)
.addComponent(savePassCheckBox)
.addComponent(autoLoginCheckBox)
.addComponent(loginButton)
);
layout.setAutoCreateContainerGaps(true);
layout.setAutoCreateGaps(true);
}
private void login() {
final ResourceBundle rb = Program.getStringsBundle();
// driv nez pristoupime k samotnemu prihlaseni k serveru:
// ucet zustane stejny pro vic resourcu. v pripade neudani resourcu pri loginu se pouzije
// bud posledni pouzity anebo implicitni.
// pokud ucet s takovym jmenem neexistuje:
// jestli je oznaceno "save password", zalozim ho.
// jinak hodim hlasku, jestli se ma ucet zalozit.
String password = new String(passwordField.getPassword());
String usernameEntered = (String) accounts.getSelectedItem();
// osetrit usernameEntered. musi splnovat regex:
if(usernameEntered.matches(Program.REGEX_VALID_JID))
{
String username = StringUtils.parseName(usernameEntered);
String resource = StringUtils.parseResource(usernameEntered);
String server = StringUtils.parseServer(usernameEntered);
Presence.Mode selectedStatus = (Presence.Mode) statusComboBox.getSelectedItem();
int result = ConnectionManager.getInstance().login(username, server, password, resource, selectedStatus);
if(result == Program.STATUS_OK)
{
//ok = login dopadl dobře. dodělám věci, který jsou zapotřebí při logování
//neznámý účet? save Passwd?, chce založit nový účet?
boolean savePass = savePassCheckBox.isSelected();
boolean autoLogin = autoLoginCheckBox.isSelected();
Collection<String> users = UserPreferences.getAllUsers();
String JID = username + "@" + server;
if(!users.contains(JID) && !savePass && JOptionPane.showOptionDialog(
LoginPanel.this,
rb.getString("questionNewAccount"),
rb.getString("questionTitle"),
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null, null, null) == JOptionPane.NO_OPTION)
UserPreferences.setDefaultUserNode();
else
UserPreferences.setUserNode(JID, true);
UserPreferences.setSavePassword(savePass);
UserPreferences.setAutoLogin(autoLogin);
UserPreferences.setPassword(savePass ? password : "");
UserPreferences.setLastResource(resource);
UserPreferences.setLastAcconunt(UserPreferences.userNode.name());
}
else if (result == Program.STATUS_BAD_LOGIN) {
passwordField.setText("");
accounts.requestFocus();
}
else {
accounts.requestFocus();
}
}
else
{
JOptionPane.showMessageDialog(LoginPanel.this, rb.getString("errorInvalidJID"),rb.getString("errorTitle"), JOptionPane.ERROR_MESSAGE);
accounts.requestFocus();
}
}
/**
* Updatuje panel. Volá se při opětovném zobrazení LoginPanelu, zejména při odhlašování.
* @see MainFrame#connectionStateChanged(int)
*/
public void updatePanel() {
// co se mohlo zmenit se musi aktualizovat...
String lastAccount = UserPreferences.getLastAccount();
UserPreferences.setUserNode(lastAccount);
accounts.setModel(new DefaultComboBoxModel(UserPreferences.getAllUsers().toArray()));
accounts.setSelectedItem(lastAccount);
}
/**
* Provede automatické přihlášení podle nastavnení uživatele.
*/
public void performAutoLogin () {
if(autoLoginCheckBox.isSelected()) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
loginButton.doClick();
}
});
}
}
/**
* Nastaví login tlačítko na defaultní tlačítko okna.
*/
public void setDefaultButton() {
getRootPane().setDefaultButton(loginButton);
}
/**
* Vytvoří novou instanci třídy LoginPanel.
*/
public LoginPanel() {
initComponents();
}
}