Delete users + window resize fix.
[ADDED] Java: support for deleting users. [FIXED] Java: Password window resizing issue.
This commit is contained in:
parent
645b6c5f54
commit
6819a2ace5
@ -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 );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
@ -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,11 +164,12 @@ 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 ) );
|
||||||
|
root.add( Components.borderPanel( passwordContainer, BorderFactory.createLoweredSoftBevelBorder(), Res.colors().frameBg() ),
|
||||||
BorderLayout.SOUTH );
|
BorderLayout.SOUTH );
|
||||||
|
|
||||||
pack();
|
pack();
|
||||||
|
@ -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 |
@ -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;
|
||||||
|
|
||||||
|
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user