User preferences.
This commit is contained in:
parent
16cdcda94b
commit
8f7faa9e4e
@ -41,7 +41,7 @@ public enum MPResultType {
|
||||
/**
|
||||
* 16: pg^VMAUBk5x3p%HP%i4=
|
||||
*/
|
||||
GeneratedMaximum( "maximum", "20 characters, contains symbols.", //
|
||||
GeneratedMaximum( "maximum", "Maximum Security", "pg^VMAUBk5x3p%HP%i4=", "20 characters, contains symbols.", //
|
||||
ImmutableList.of( new MPTemplate( "anoxxxxxxxxxxxxxxxxx" ),
|
||||
new MPTemplate( "axxxxxxxxxxxxxxxxxno" ) ), //
|
||||
MPResultTypeClass.Template, 0x0 ),
|
||||
@ -49,7 +49,7 @@ public enum MPResultType {
|
||||
/**
|
||||
* 17: BiroYena8:Kixa
|
||||
*/
|
||||
GeneratedLong( "long", "Copy-friendly, 14 characters, contains symbols.", //
|
||||
GeneratedLong( "long", "Long Password", "BiroYena8:Kixa", "Copy-friendly, 14 characters, contains symbols.", //
|
||||
ImmutableList.of( new MPTemplate( "CvcvnoCvcvCvcv" ), new MPTemplate( "CvcvCvcvnoCvcv" ),
|
||||
new MPTemplate( "CvcvCvcvCvcvno" ), new MPTemplate( "CvccnoCvcvCvcv" ),
|
||||
new MPTemplate( "CvccCvcvnoCvcv" ), new MPTemplate( "CvccCvcvCvcvno" ),
|
||||
@ -66,7 +66,7 @@ public enum MPResultType {
|
||||
/**
|
||||
* 18: BirSuj0-
|
||||
*/
|
||||
GeneratedMedium( "medium", "Copy-friendly, 8 characters, contains symbols.", //
|
||||
GeneratedMedium( "medium", "Medium Password", "BirSuj0-", "Copy-friendly, 8 characters, contains symbols.", //
|
||||
ImmutableList.of( new MPTemplate( "CvcnoCvc" ),
|
||||
new MPTemplate( "CvcCvcno" ) ), //
|
||||
MPResultTypeClass.Template, 0x2 ),
|
||||
@ -74,14 +74,14 @@ public enum MPResultType {
|
||||
/**
|
||||
* 19: Bir8
|
||||
*/
|
||||
GeneratedShort( "short", "Copy-friendly, 4 characters, no symbols.", //
|
||||
GeneratedShort( "short", "Short Password", "Bir8", "Copy-friendly, 4 characters, no symbols.", //
|
||||
ImmutableList.of( new MPTemplate( "Cvcn" ) ), //
|
||||
MPResultTypeClass.Template, 0x3 ),
|
||||
|
||||
/**
|
||||
* 20: pO98MoD0
|
||||
*/
|
||||
GeneratedBasic( "basic", "8 characters, no symbols.", //
|
||||
GeneratedBasic( "basic", "Basic Password", "pO98MoD0", "8 characters, no symbols.", //
|
||||
ImmutableList.of( new MPTemplate( "aaanaaan" ),
|
||||
new MPTemplate( "aannaaan" ),
|
||||
new MPTemplate( "aaannaaa" ) ), //
|
||||
@ -90,21 +90,21 @@ public enum MPResultType {
|
||||
/**
|
||||
* 21: 2798
|
||||
*/
|
||||
GeneratedPIN( "pin", "4 numbers.", //
|
||||
GeneratedPIN( "pin", "PIN Code", "2798", "4 numbers.", //
|
||||
ImmutableList.of( new MPTemplate( "nnnn" ) ), //
|
||||
MPResultTypeClass.Template, 0x5 ),
|
||||
|
||||
/**
|
||||
* 30: birsujano
|
||||
*/
|
||||
GeneratedName( "name", "9 letter name.", //
|
||||
GeneratedName( "name", "Name", "birsujano", "9 letter name.", //
|
||||
ImmutableList.of( new MPTemplate( "cvccvcvcv" ) ), //
|
||||
MPResultTypeClass.Template, 0xE ),
|
||||
|
||||
/**
|
||||
* 31: bir yennoquce fefi
|
||||
*/
|
||||
GeneratedPhrase( "phrase", "20 character sentence.", //
|
||||
GeneratedPhrase( "phrase", "Phrase", "bir yennoquce fefi", "20 character sentence.", //
|
||||
ImmutableList.of( new MPTemplate( "cvcc cvc cvccvcv cvc" ),
|
||||
new MPTemplate( "cvc cvccvcvcv cvcv" ),
|
||||
new MPTemplate( "cv cvccv cvc cvcvccv" ) ), //
|
||||
@ -113,37 +113,44 @@ public enum MPResultType {
|
||||
/**
|
||||
* 1056: Custom saved password.
|
||||
*/
|
||||
StoredPersonal( "personal", "AES-encrypted, exportable.", //
|
||||
StoredPersonal( "personal", "Saved Password", null, "AES-encrypted, exportable.", //
|
||||
ImmutableList.<MPTemplate>of(), //
|
||||
MPResultTypeClass.Stateful, 0x0, MPSiteFeature.ExportContent ),
|
||||
|
||||
/**
|
||||
* 2081: Custom saved password that should not be exported from the device.
|
||||
*/
|
||||
StoredDevicePrivate( "device", "AES-encrypted, not exported.", //
|
||||
StoredDevicePrivate( "device", "Private Password", null, "AES-encrypted, not exported.", //
|
||||
ImmutableList.<MPTemplate>of(), //
|
||||
MPResultTypeClass.Stateful, 0x1, MPSiteFeature.DevicePrivate ),
|
||||
|
||||
/**
|
||||
* 4160: Derive a unique binary key.
|
||||
*/
|
||||
DeriveKey( "key", "Encryption key.", //
|
||||
DeriveKey( "key", "Binary Key", null, "Encryption key.", //
|
||||
ImmutableList.<MPTemplate>of(), //
|
||||
MPResultTypeClass.Derive, 0x0, MPSiteFeature.Alternative );
|
||||
|
||||
static final Logger logger = Logger.get( MPResultType.class );
|
||||
|
||||
private final String shortName;
|
||||
private final String longName;
|
||||
|
||||
@Nullable
|
||||
private final String sample;
|
||||
private final String description;
|
||||
private final List<MPTemplate> templates;
|
||||
private final MPResultTypeClass typeClass;
|
||||
private final int typeIndex;
|
||||
private final ImmutableSet<MPSiteFeature> typeFeatures;
|
||||
|
||||
MPResultType(final String shortName, final String description, final List<MPTemplate> templates,
|
||||
MPResultType(final String shortName, final String longName, @Nullable final String sample, final String description,
|
||||
final List<MPTemplate> templates,
|
||||
final MPResultTypeClass typeClass, final int typeIndex, final MPSiteFeature... typeFeatures) {
|
||||
|
||||
this.shortName = shortName;
|
||||
this.longName = longName;
|
||||
this.sample = sample;
|
||||
this.description = description;
|
||||
this.templates = templates;
|
||||
this.typeClass = typeClass;
|
||||
@ -160,6 +167,15 @@ public enum MPResultType {
|
||||
return shortName;
|
||||
}
|
||||
|
||||
public String getLongName() {
|
||||
return longName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getSample() {
|
||||
return sample;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
|
||||
return description;
|
||||
|
@ -2,6 +2,7 @@ package com.lyndir.masterpassword.gui.util;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
@ -14,17 +15,24 @@ import javax.swing.event.ListSelectionListener;
|
||||
@SuppressWarnings("serial")
|
||||
public class CollectionListModel<E> extends AbstractListModel<E> implements ComboBoxModel<E>, ListSelectionListener {
|
||||
|
||||
private final List<E> model = new LinkedList<>();
|
||||
private final List<E> model = new LinkedList<>();
|
||||
@Nullable
|
||||
private E selectedItem;
|
||||
private JList<E> list;
|
||||
private E selectedItem;
|
||||
private JList<E> list;
|
||||
@Nullable
|
||||
private Consumer<E> selectionConsumer;
|
||||
|
||||
public CollectionListModel() {
|
||||
@SafeVarargs
|
||||
public static <E> CollectionListModel<E> copy(final E... elements) {
|
||||
return copy( Arrays.asList( elements ) );
|
||||
}
|
||||
|
||||
public CollectionListModel(final Collection<E> model) {
|
||||
this.model.addAll( model );
|
||||
fireIntervalAdded( this, 0, model.size() );
|
||||
public static <E> CollectionListModel<E> copy(final Collection<E> elements) {
|
||||
CollectionListModel<E> model = new CollectionListModel<>();
|
||||
model.model.addAll( elements );
|
||||
model.fireIntervalAdded( model, 0, model.model.size() );
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -79,11 +87,14 @@ public class CollectionListModel<E> extends AbstractListModel<E> implements Comb
|
||||
public synchronized void setSelectedItem(@Nullable final Object newSelectedItem) {
|
||||
if (!Objects.equals( selectedItem, newSelectedItem ) && model.contains( newSelectedItem )) {
|
||||
selectedItem = (E) newSelectedItem;
|
||||
fireContentsChanged( this, -1, -1 );
|
||||
|
||||
fireContentsChanged( this, -1, -1 );
|
||||
//noinspection ObjectEquality
|
||||
if ((list != null) && (list.getModel() == this))
|
||||
list.setSelectedValue( selectedItem, true );
|
||||
|
||||
if (selectionConsumer != null)
|
||||
selectionConsumer.accept( selectedItem );
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,6 +114,17 @@ public class CollectionListModel<E> extends AbstractListModel<E> implements Comb
|
||||
this.list.setModel( this );
|
||||
}
|
||||
|
||||
public CollectionListModel<E> selection(@Nullable final E selectedItem, @Nullable final Consumer<E> selectionConsumer) {
|
||||
this.selectionConsumer = null;
|
||||
setSelectedItem( selectedItem );
|
||||
|
||||
this.selectionConsumer = selectionConsumer;
|
||||
if (this.selectionConsumer != null)
|
||||
this.selectionConsumer.accept( selectedItem );
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void valueChanged(final ListSelectionEvent event) {
|
||||
//noinspection ObjectEquality
|
||||
|
@ -20,6 +20,8 @@ package com.lyndir.masterpassword.gui.util;
|
||||
|
||||
import com.lyndir.masterpassword.gui.Res;
|
||||
import java.awt.*;
|
||||
import java.util.Collection;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.swing.*;
|
||||
@ -30,15 +32,20 @@ import javax.swing.border.CompoundBorder;
|
||||
/**
|
||||
* @author lhunath, 2014-06-08
|
||||
*/
|
||||
@SuppressWarnings("SerializableStoresNonSerializable")
|
||||
public abstract class Components {
|
||||
|
||||
public static final float TEXT_SIZE_HEADING = 19f;
|
||||
public static final float TEXT_SIZE_CONTROL = 13f;
|
||||
public static final int SIZE_MARGIN = 20;
|
||||
public static final int SIZE_MARGIN = 12;
|
||||
public static final int SIZE_PADDING = 8;
|
||||
|
||||
public static GradientPanel boxPanel(final int axis, final Component... components) {
|
||||
GradientPanel container = gradientPanel( null, null );
|
||||
public static GradientPanel panel(final int axis, final Component... components) {
|
||||
return panel( axis, null, components );
|
||||
}
|
||||
|
||||
public static GradientPanel panel(final int axis, @Nullable final Color background, final Component... components) {
|
||||
GradientPanel container = gradientPanel( background, null );
|
||||
container.setLayout( new BoxLayout( container, axis ) );
|
||||
for (final Component component : components)
|
||||
container.add( component );
|
||||
@ -46,20 +53,24 @@ public abstract class Components {
|
||||
return container;
|
||||
}
|
||||
|
||||
public static GradientPanel borderPanel(@Nullable final Border border, final Component... components) {
|
||||
return borderPanel( border, null, components );
|
||||
public static GradientPanel borderPanel(final int axis, final Component... components) {
|
||||
return borderPanel( marginBorder(), null, axis, components );
|
||||
}
|
||||
|
||||
public static GradientPanel borderPanel(@Nullable final Border border, @Nullable final Color background,
|
||||
final Component... components) {
|
||||
GradientPanel box = boxPanel( BoxLayout.LINE_AXIS, components );
|
||||
public static GradientPanel borderPanel(@Nullable final Border border, final int axis, final Component... components) {
|
||||
return borderPanel( border, null, axis, components );
|
||||
}
|
||||
|
||||
public static GradientPanel borderPanel(@Nullable final Color background, final int axis, final Component... components) {
|
||||
return borderPanel( marginBorder(), background, axis, components );
|
||||
}
|
||||
|
||||
public static GradientPanel borderPanel(@Nullable final Border border, @Nullable final Color background, final int axis,
|
||||
final Component... components) {
|
||||
GradientPanel box = panel( axis, background, components );
|
||||
if (border != null)
|
||||
box.setBorder( border );
|
||||
|
||||
if (background != null)
|
||||
box.setBackground( background );
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
@ -69,11 +80,39 @@ public abstract class Components {
|
||||
setOpaque( color != null );
|
||||
setBackground( color );
|
||||
setAlignmentX( LEFT_ALIGNMENT );
|
||||
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static JDialog showDialog(@Nullable final Component owner, @Nullable final String title, final JOptionPane pane) {
|
||||
JDialog dialog = pane.createDialog( owner, title );
|
||||
dialog.setModalityType( Dialog.ModalityType.DOCUMENT_MODAL );
|
||||
|
||||
return showDialog( dialog );
|
||||
}
|
||||
|
||||
public static JDialog showDialog(@Nullable final Component owner, @Nullable final String title, final Container content) {
|
||||
JDialog dialog = new JDialog( (owner != null)? SwingUtilities.windowForComponent( owner ): null,
|
||||
title, Dialog.ModalityType.DOCUMENT_MODAL );
|
||||
dialog.setMinimumSize( new Dimension( 320, 0 ) );
|
||||
dialog.setLocationRelativeTo( owner );
|
||||
dialog.setLocationByPlatform( true );
|
||||
dialog.setContentPane( content );
|
||||
|
||||
return showDialog( dialog );
|
||||
}
|
||||
|
||||
private static JDialog showDialog(final JDialog dialog) {
|
||||
// OpenJDK does not correctly implement this setting in native code.
|
||||
dialog.getRootPane().putClientProperty( "apple.awt.documentModalSheet", Boolean.TRUE );
|
||||
dialog.getRootPane().putClientProperty( "Window.style", "small" );
|
||||
dialog.pack();
|
||||
|
||||
dialog.setVisible( true );
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static JTextField textField() {
|
||||
return new JTextField() {
|
||||
{
|
||||
@ -81,7 +120,6 @@ public abstract class Components {
|
||||
BorderFactory.createEmptyBorder( 4, 4, 4, 4 ) ) );
|
||||
setFont( Res.fonts().valueFont( TEXT_SIZE_CONTROL ) );
|
||||
setAlignmentX( LEFT_ALIGNMENT );
|
||||
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -97,7 +135,6 @@ public abstract class Components {
|
||||
setBorder( BorderFactory.createCompoundBorder( BorderFactory.createLineBorder( Res.colors().controlBorder(), 1, true ),
|
||||
BorderFactory.createEmptyBorder( 4, 4, 4, 4 ) ) );
|
||||
setAlignmentX( LEFT_ALIGNMENT );
|
||||
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -126,7 +163,6 @@ public abstract class Components {
|
||||
}
|
||||
} );
|
||||
setAlignmentX( LEFT_ALIGNMENT );
|
||||
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -141,22 +177,21 @@ public abstract class Components {
|
||||
{
|
||||
setBorder( BorderFactory.createLineBorder( Res.colors().controlBorder(), 1, true ) );
|
||||
setAlignmentX( LEFT_ALIGNMENT );
|
||||
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static JButton button(final String label) {
|
||||
return button( label, null );
|
||||
}
|
||||
|
||||
public static JButton button(final String label, @Nullable final Action action) {
|
||||
return new JButton( label ) {
|
||||
{
|
||||
setFont( Res.fonts().controlFont( TEXT_SIZE_CONTROL ) );
|
||||
setAlignmentX( LEFT_ALIGNMENT );
|
||||
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMaximumSize() {
|
||||
return new Dimension( 20, getPreferredSize().height );
|
||||
if (action != null)
|
||||
setAction( action );
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -169,7 +204,6 @@ public abstract class Components {
|
||||
Dimension studDimension = new Dimension( size, size );
|
||||
Box.Filler rigidArea = new Box.Filler( studDimension, studDimension, studDimension );
|
||||
rigidArea.setAlignmentX( Component.LEFT_ALIGNMENT );
|
||||
rigidArea.setAlignmentY( Component.BOTTOM_ALIGNMENT );
|
||||
rigidArea.setBackground( Color.red );
|
||||
return rigidArea;
|
||||
}
|
||||
@ -194,7 +228,6 @@ public abstract class Components {
|
||||
BorderFactory.createEmptyBorder( 4, 4, 4, 4 ) );
|
||||
((DefaultEditor) getEditor()).getTextField().setBorder( editorBorder );
|
||||
setAlignmentX( LEFT_ALIGNMENT );
|
||||
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||
setBorder( null );
|
||||
}
|
||||
|
||||
@ -231,7 +264,6 @@ public abstract class Components {
|
||||
{
|
||||
setFont( Res.fonts().controlFont( TEXT_SIZE_HEADING ).deriveFont( Font.BOLD ) );
|
||||
setAlignmentX( LEFT_ALIGNMENT );
|
||||
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -267,7 +299,6 @@ public abstract class Components {
|
||||
{
|
||||
setFont( Res.fonts().controlFont( TEXT_SIZE_CONTROL ) );
|
||||
setAlignmentX( LEFT_ALIGNMENT );
|
||||
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -283,7 +314,6 @@ public abstract class Components {
|
||||
setFont( Res.fonts().controlFont( TEXT_SIZE_CONTROL ) );
|
||||
setBackground( null );
|
||||
setAlignmentX( LEFT_ALIGNMENT );
|
||||
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -293,6 +323,16 @@ public abstract class Components {
|
||||
return comboBox( new DefaultComboBoxModel<>( values ), valueTransformer );
|
||||
}
|
||||
|
||||
public static <E> JComboBox<E> comboBox(final E[] values, final Function<E, String> valueTransformer, final E selectedItem,
|
||||
@Nullable final Consumer<E> selectionConsumer) {
|
||||
return comboBox( CollectionListModel.copy( values ).selection( selectedItem, selectionConsumer ), valueTransformer );
|
||||
}
|
||||
|
||||
public static <E> JComboBox<E> comboBox(final Collection<E> values, final Function<E, String> valueTransformer, final E selectedItem,
|
||||
@Nullable final Consumer<E> selectionConsumer) {
|
||||
return comboBox( CollectionListModel.copy( values ).selection( selectedItem, selectionConsumer ), valueTransformer );
|
||||
}
|
||||
|
||||
public static <E> JComboBox<E> comboBox(final ComboBoxModel<E> model, final Function<E, String> valueTransformer) {
|
||||
return new JComboBox<E>( model ) {
|
||||
{
|
||||
@ -311,8 +351,8 @@ public abstract class Components {
|
||||
list, valueTransformer.apply( (E) value ), index, isSelected, cellHasFocus );
|
||||
}
|
||||
} );
|
||||
putClientProperty( "JComboBox.isPopDown", Boolean.TRUE );
|
||||
setAlignmentX( LEFT_ALIGNMENT );
|
||||
setAlignmentY( BOTTOM_ALIGNMENT );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,13 +1,16 @@
|
||||
package com.lyndir.masterpassword.gui.view;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.lyndir.masterpassword.MPAlgorithm;
|
||||
import com.lyndir.masterpassword.MPResultType;
|
||||
import com.lyndir.masterpassword.gui.Res;
|
||||
import com.lyndir.masterpassword.gui.util.CollectionListModel;
|
||||
import com.lyndir.masterpassword.gui.util.Components;
|
||||
import com.lyndir.masterpassword.model.MPUser;
|
||||
import com.lyndir.masterpassword.model.impl.MPFileUser;
|
||||
import com.lyndir.masterpassword.model.impl.MPFileUserManager;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.*;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import javax.annotation.Nullable;
|
||||
@ -17,14 +20,16 @@ import javax.swing.*;
|
||||
/**
|
||||
* @author lhunath, 2018-07-14
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class FilesPanel extends JPanel implements ItemListener {
|
||||
|
||||
private final Collection<Listener> listeners = new CopyOnWriteArraySet<>();
|
||||
|
||||
private final JLabel avatarLabel = new JLabel();
|
||||
private final CollectionListModel<MPUser<?>> usersModel = new CollectionListModel<>();
|
||||
private final JComboBox<MPUser<?>> userField =
|
||||
private final JLabel avatarLabel = new JLabel();
|
||||
private final CollectionListModel<MPUser<?>> usersModel = new CollectionListModel<>();
|
||||
private final JComboBox<MPUser<?>> userField =
|
||||
Components.comboBox( usersModel, user -> (user != null)? user.getFullName(): null );
|
||||
private final JButton preferencesButton = Components.button( "..." );
|
||||
|
||||
protected FilesPanel() {
|
||||
setOpaque( false );
|
||||
@ -41,10 +46,34 @@ public class FilesPanel extends JPanel implements ItemListener {
|
||||
avatarLabel.setToolTipText( "The avatar for your user. Click to change it." );
|
||||
|
||||
// -
|
||||
add( Components.strut( 20 ) );
|
||||
add( Components.strut( Components.margin() ) );
|
||||
|
||||
// User Selection
|
||||
add( userField );
|
||||
add( Components.panel( BoxLayout.LINE_AXIS, userField, preferencesButton ) );
|
||||
preferencesButton.setAction( new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
MPUser<?> user = usersModel.getSelectedItem();
|
||||
if (user == null)
|
||||
return;
|
||||
MPFileUser fileUser = (user instanceof MPFileUser)? (MPFileUser) user: null;
|
||||
|
||||
ImmutableList.Builder<Component> components = ImmutableList.builder();
|
||||
if (fileUser != null)
|
||||
components.add( Components.label( "Default Password Type:" ),
|
||||
Components.comboBox( MPResultType.values(), MPResultType::getLongName,
|
||||
fileUser.getDefaultType(), fileUser::setDefaultType ),
|
||||
Components.strut() );
|
||||
|
||||
components.add( Components.label( "Default Algorithm:" ),
|
||||
Components.comboBox( MPAlgorithm.Version.values(), MPAlgorithm.Version::name,
|
||||
user.getAlgorithm().version(),
|
||||
version -> user.setAlgorithm( version.getAlgorithm() ) ) );
|
||||
|
||||
Components.showDialog( preferencesButton, user.getFullName(), new JOptionPane( Components.panel(
|
||||
BoxLayout.PAGE_AXIS, components.build().toArray( new Component[0] ) ) ) );
|
||||
}
|
||||
} );
|
||||
userField.addItemListener( this );
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.BevelBorder;
|
||||
|
||||
|
||||
/**
|
||||
@ -29,24 +30,23 @@ public class MasterPasswordFrame extends JFrame implements FilesPanel.Listener,
|
||||
super( "Master Password" );
|
||||
|
||||
setDefaultCloseOperation( DISPOSE_ON_CLOSE );
|
||||
setContentPane( root = Components.gradientPanel( Res.colors().frameBg(), new FlowLayout() ) );
|
||||
root.setLayout( new BoxLayout( root, BoxLayout.PAGE_AXIS ) );
|
||||
root.setBorder( Components.marginBorder() );
|
||||
|
||||
setContentPane( root = Components.borderPanel( Res.colors().frameBg(), BoxLayout.PAGE_AXIS ) );
|
||||
root.add( filesPanel );
|
||||
root.add( new JSeparator( SwingConstants.HORIZONTAL ) );
|
||||
root.add( Components.strut() );
|
||||
root.add( Components.borderPanel( BorderFactory.createRaisedBevelBorder(), Res.colors().controlBg(), userPanel ) );
|
||||
root.add( Components.borderPanel(
|
||||
BorderFactory.createBevelBorder( BevelBorder.RAISED, Res.colors().controlBorder(), Res.colors().frameBg() ),
|
||||
Res.colors().controlBg(), BoxLayout.PAGE_AXIS, userPanel ) );
|
||||
|
||||
filesPanel.addListener( this );
|
||||
filesPanel.reload();
|
||||
|
||||
addComponentListener(this );
|
||||
addComponentListener( this );
|
||||
setPreferredSize( new Dimension( 640, 480 ) );
|
||||
pack();
|
||||
|
||||
setLocationByPlatform( true );
|
||||
setLocationRelativeTo( null );
|
||||
setLocationByPlatform( true );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -10,6 +10,8 @@ import com.lyndir.masterpassword.gui.Res;
|
||||
import com.lyndir.masterpassword.gui.util.CollectionListModel;
|
||||
import com.lyndir.masterpassword.gui.util.Components;
|
||||
import com.lyndir.masterpassword.model.*;
|
||||
import com.lyndir.masterpassword.model.impl.MPFileSite;
|
||||
import com.lyndir.masterpassword.model.impl.MPFileUser;
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
@ -129,7 +131,7 @@ public class UserPanel extends Components.GradientPanel implements MPUser.Listen
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
updateIdenticon();
|
||||
|
||||
|
||||
char[] masterPassword = masterPasswordField.getPassword();
|
||||
Res.job( () -> {
|
||||
try {
|
||||
@ -223,6 +225,7 @@ public class UserPanel extends Components.GradientPanel implements MPUser.Listen
|
||||
add( queryLabel );
|
||||
queryLabel.setText( strf( "%s's password for:", user.getFullName() ) );
|
||||
add( queryField );
|
||||
queryField.putClientProperty( "JTextField.variant", "search" );
|
||||
queryField.addActionListener( this );
|
||||
queryField.addKeyListener( this );
|
||||
queryField.getDocument().addDocumentListener( this );
|
||||
@ -236,10 +239,14 @@ public class UserPanel extends Components.GradientPanel implements MPUser.Listen
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
showSiteResult( sitesList.getSelectedValue(), result -> {
|
||||
MPSite<?> site = sitesList.getSelectedValue();
|
||||
showSiteResult( site, result -> {
|
||||
if (result == null)
|
||||
return;
|
||||
|
||||
if (site instanceof MPFileSite)
|
||||
((MPFileSite) site).use();
|
||||
|
||||
Transferable clipboardContents = new StringSelection( result );
|
||||
Toolkit.getDefaultToolkit().getSystemClipboard().setContents( clipboardContents, null );
|
||||
|
||||
|
@ -95,6 +95,8 @@ public class MPFileSite extends MPBasicSite<MPFileQuestion> {
|
||||
uses++;
|
||||
lastUsed = new Instant();
|
||||
user.use();
|
||||
|
||||
setChanged();
|
||||
}
|
||||
|
||||
public String getResult()
|
||||
|
Loading…
Reference in New Issue
Block a user