2
0

Delete users + window resize fix.

[ADDED]     Java: support for deleting users.
[FIXED]     Java: Password window resizing issue.
This commit is contained in:
Maarten Billemont 2015-04-01 08:09:48 -04:00
parent 645b6c5f54
commit 6819a2ace5
7 changed files with 86 additions and 12 deletions

View File

@ -1,5 +1,7 @@
package com.lyndir.masterpassword.gui; package com.lyndir.masterpassword.gui;
import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.*; import com.google.common.collect.*;
@ -53,14 +55,14 @@ public class ModelAuthenticationPanel extends AuthenticationPanel implements Ite
userField.setFont( Res.valueFont().deriveFont( 12f ) ); userField.setFont( Res.valueFont().deriveFont( 12f ) );
userField.addItemListener( this ); userField.addItemListener( this );
userField.addActionListener( this ); userField.addActionListener( this );
userField.setEditor(new MetalComboBoxEditor() { userField.setEditor( new MetalComboBoxEditor() {
@Override @Override
protected JTextField createEditorComponent() { protected JTextField createEditorComponent() {
JTextField editorComponents = Components.textField(); JTextField editorComponents = Components.textField();
editorComponents.setForeground(Color.red); editorComponents.setForeground( Color.red );
return editorComponents; return editorComponents;
} }
}); } );
add( userField ); add( userField );
add( Components.stud() ); add( Components.stud() );
@ -128,13 +130,36 @@ public class ModelAuthenticationPanel extends AuthenticationPanel implements Ite
} ); } );
setToolTipText( "Add a new user to the list." ); setToolTipText( "Add a new user to the list." );
} }
}, new JButton( Res.iconDelete() ) {
{
addActionListener( new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
ModelUser deleteUser = getSelectedUser();
if (deleteUser == null)
return;
if (JOptionPane.showConfirmDialog( ModelAuthenticationPanel.this, //
strf( "Are you sure you want to delete the user and sites remembered for:\n%s.",
deleteUser.getFullName() ), //
"Delete User", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE ) == JOptionPane.CANCEL_OPTION)
return;
MPUserFileManager.get().deleteUser( deleteUser.getModel() );
userField.setModel( new DefaultComboBoxModel<>( readConfigUsers() ) );
updateUser( true );
}
} );
setToolTipText( "Delete the selected user." );
}
}, new JButton( Res.iconQuestion() ) { }, new JButton( Res.iconQuestion() ) {
{ {
addActionListener( new ActionListener() { addActionListener( new ActionListener() {
@Override @Override
public void actionPerformed(final ActionEvent e) { public void actionPerformed(final ActionEvent e) {
JOptionPane.showMessageDialog( ModelAuthenticationPanel.this, // JOptionPane.showMessageDialog( ModelAuthenticationPanel.this, //
"Reads users and sites from the directory at ~/.mpw.d.", // strf( "Reads users and sites from the directory at:\n%s",
MPUserFileManager.get().getPath().getAbsolutePath() ), //
"Help", JOptionPane.INFORMATION_MESSAGE ); "Help", JOptionPane.INFORMATION_MESSAGE );
} }
} ); } );

View File

@ -42,7 +42,8 @@ public class PasswordFrame extends JFrame implements DocumentListener {
this.user = user; this.user = user;
setDefaultCloseOperation( DISPOSE_ON_CLOSE ); setDefaultCloseOperation( DISPOSE_ON_CLOSE );
setContentPane( root = Components.gradientPanel( new BorderLayout( 20, 20 ), Res.colors().frameBg() ) ); setContentPane( root = Components.gradientPanel( new FlowLayout(), Res.colors().frameBg() ) );
root.setLayout( new BoxLayout( root, BoxLayout.PAGE_AXIS ) );
root.setBorder( BorderFactory.createEmptyBorder( 20, 20, 20, 20 ) ); root.setBorder( BorderFactory.createEmptyBorder( 20, 20, 20, 20 ) );
// Site // Site
@ -50,7 +51,7 @@ public class PasswordFrame extends JFrame implements DocumentListener {
sitePanel.setOpaque( true ); sitePanel.setOpaque( true );
sitePanel.setBackground( Res.colors().controlBg() ); sitePanel.setBackground( Res.colors().controlBg() );
sitePanel.setBorder( BorderFactory.createEmptyBorder( 20, 20, 20, 20 ) ); sitePanel.setBorder( BorderFactory.createEmptyBorder( 20, 20, 20, 20 ) );
add( Components.borderPanel( sitePanel, BorderFactory.createRaisedBevelBorder(), Res.colors().frameBg() ), BorderLayout.CENTER ); root.add( Components.borderPanel( sitePanel, BorderFactory.createRaisedBevelBorder(), Res.colors().frameBg() ) );
// User // User
sitePanel.add( Components.label( strf( "Generating passwords for: %s", user.getFullName() ), SwingConstants.CENTER ) ); sitePanel.add( Components.label( strf( "Generating passwords for: %s", user.getFullName() ), SwingConstants.CENTER ) );
@ -163,12 +164,13 @@ public class PasswordFrame extends JFrame implements DocumentListener {
// Tip // Tip
tipLabel = Components.label( " ", SwingConstants.CENTER ); tipLabel = Components.label( " ", SwingConstants.CENTER );
tipLabel.setAlignmentX( Component.CENTER_ALIGNMENT ); tipLabel.setAlignmentX( Component.CENTER_ALIGNMENT );
JPanel passwordContainer = Components.boxLayout( BoxLayout.PAGE_AXIS, maskPasswordField, passwordField, tipLabel ); JPanel passwordContainer = Components.boxLayout( BoxLayout.PAGE_AXIS, maskPasswordField, Box.createGlue(), passwordField, Box.createGlue(), tipLabel );
passwordContainer.setOpaque( true ); passwordContainer.setOpaque( true );
passwordContainer.setBackground( Color.white ); passwordContainer.setBackground( Color.white );
passwordContainer.setBorder( BorderFactory.createEmptyBorder( 8, 8, 8, 8 ) ); passwordContainer.setBorder( BorderFactory.createEmptyBorder( 8, 8, 8, 8 ) );
add( Components.borderPanel( passwordContainer, BorderFactory.createLoweredSoftBevelBorder(), Res.colors().frameBg() ), root.add( Box.createVerticalStrut( 8 ) );
BorderLayout.SOUTH ); root.add( Components.borderPanel( passwordContainer, BorderFactory.createLoweredSoftBevelBorder(), Res.colors().frameBg() ),
BorderLayout.SOUTH );
pack(); pack();
setMinimumSize( new Dimension( Math.max( 600, getPreferredSize().width ), Math.max( 300, getPreferredSize().height ) ) ); setMinimumSize( new Dimension( Math.max( 600, getPreferredSize().width ), Math.max( 300, getPreferredSize().height ) ) );

View File

@ -85,6 +85,10 @@ public abstract class Res {
return new RetinaIcon( Resources.getResource( "media/icon_add@2x.png" ) ); return new RetinaIcon( Resources.getResource( "media/icon_add@2x.png" ) );
} }
public static Icon iconDelete() {
return new RetinaIcon( Resources.getResource( "media/icon_delete@2x.png" ) );
}
public static Icon iconQuestion() { public static Icon iconQuestion() {
return new RetinaIcon( Resources.getResource( "media/icon_question@2x.png" ) ); return new RetinaIcon( Resources.getResource( "media/icon_question@2x.png" ) );
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -5,6 +5,7 @@ import com.google.common.collect.*;
import com.google.common.io.CharSink; import com.google.common.io.CharSink;
import com.lyndir.lhunath.opal.system.logging.Logger; import com.lyndir.lhunath.opal.system.logging.Logger;
import java.io.*; import java.io.*;
import java.util.SortedSet;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -15,7 +16,7 @@ public class MPUserFileManager extends MPUserManager {
@SuppressWarnings("UnusedDeclaration") @SuppressWarnings("UnusedDeclaration")
private static final Logger logger = Logger.get( MPUserFileManager.class ); private static final Logger logger = Logger.get( MPUserFileManager.class );
private static final File mpwd = new File( System.getProperty( "user.home" ), ".mpw.d" ); private static final File mpwd = new File( System.getProperty( "user.home" ), ".mpw.d" );
private static final MPUserFileManager instance; private static final MPUserFileManager instance;
static { static {
@ -70,19 +71,53 @@ public class MPUserFileManager extends MPUserManager {
} ).filter( Predicates.notNull() ); } ).filter( Predicates.notNull() );
} }
@Override
public void addUser(final MPUser user) {
super.addUser( user );
save();
}
@Override
public void deleteUser(final MPUser user) {
super.deleteUser( user );
save();
}
/**
* Write the current user state to disk.
*/
public void save() { public void save() {
// Save existing users.
for (final MPUser user : getUsers()) for (final MPUser user : getUsers())
try { try {
new CharSink() { new CharSink() {
@Override @Override
public Writer openStream() public Writer openStream()
throws IOException { throws IOException {
return new FileWriter( new File(userFilesDirectory, user.getFullName() + ".mpsites" ) ); return new FileWriter( new File( userFilesDirectory, user.getFullName() + ".mpsites" ) );
} }
}.write( MPSiteMarshaller.marshallSafe( user ).getExport() ); }.write( MPSiteMarshaller.marshallSafe( user ).getExport() );
} }
catch (IOException e) { catch (IOException e) {
logger.err( e, "Unable to save sites for user: %s", user ); logger.err( e, "Unable to save sites for user: %s", user );
} }
// Remove deleted users.
for (File userFile : userFilesDirectory.listFiles( new FilenameFilter() {
@Override
public boolean accept(final File dir, final String name) {
return name.endsWith( ".mpsites" );
}
} ))
if (getUserNamed( userFile.getName().replaceFirst( "\\.mpsites$", "" ) ) == null)
if (!userFile.delete())
logger.err( "Couldn't delete file: %s", userFile );
}
/**
* @return The location on the file system where the user models are stored.
*/
public File getPath() {
return mpwd;
} }
} }

View File

@ -18,14 +18,22 @@ public abstract class MPUserManager {
protected MPUserManager(final Iterable<MPUser> users) { protected MPUserManager(final Iterable<MPUser> users) {
for (MPUser user : users) for (MPUser user : users)
addUser( user ); usersByName.put( user.getFullName(), user );
} }
public SortedSet<MPUser> getUsers() { public SortedSet<MPUser> getUsers() {
return FluentIterable.from( usersByName.values() ).toSortedSet( Ordering.natural() ); return FluentIterable.from( usersByName.values() ).toSortedSet( Ordering.natural() );
} }
public MPUser getUserNamed(String fullName) {
return usersByName.get( fullName );
}
public void addUser(final MPUser user) { public void addUser(final MPUser user) {
usersByName.put( user.getFullName(), user ); usersByName.put( user.getFullName(), user );
} }
public void deleteUser(final MPUser user) {
usersByName.remove( user.getFullName() );
}
} }