From 5f0367ad29ca6fc388d21a087178f248ae15c474 Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Fri, 3 Apr 2015 12:12:12 -0400 Subject: [PATCH] Support for deleting sites from the Java GUI. --- .idea/encodings.xml | 3 +- .../masterpassword/gui/IncognitoUser.java | 4 + .../lyndir/masterpassword/gui/ModelSite.java | 4 + .../lyndir/masterpassword/gui/ModelUser.java | 14 ++- .../masterpassword/gui/PasswordFrame.java | 94 ++++++++++++------- .../com/lyndir/masterpassword/gui/User.java | 2 + .../lyndir/masterpassword/model/MPUser.java | 4 + 7 files changed, 85 insertions(+), 40 deletions(-) mode change 100644 => 100755 .idea/encodings.xml mode change 100644 => 100755 MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/IncognitoUser.java mode change 100644 => 100755 MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/ModelSite.java mode change 100644 => 100755 MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/ModelUser.java mode change 100644 => 100755 MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/PasswordFrame.java mode change 100644 => 100755 MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/User.java mode change 100644 => 100755 MasterPassword/Java/masterpassword-model/src/main/java/com/lyndir/masterpassword/model/MPUser.java diff --git a/.idea/encodings.xml b/.idea/encodings.xml old mode 100644 new mode 100755 index 4c94b2e6..89d1938b --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -7,4 +7,5 @@ - \ No newline at end of file + + diff --git a/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/IncognitoUser.java b/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/IncognitoUser.java old mode 100644 new mode 100755 index ccd10af2..d4f4c7e4 --- a/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/IncognitoUser.java +++ b/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/IncognitoUser.java @@ -41,4 +41,8 @@ public class IncognitoUser extends User { @Override public void addSite(final Site site) { } + + @Override + public void deleteSite(Site site) { + } } diff --git a/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/ModelSite.java b/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/ModelSite.java old mode 100644 new mode 100755 index c49a054d..614e1456 --- a/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/ModelSite.java +++ b/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/ModelSite.java @@ -16,6 +16,10 @@ public class ModelSite extends Site { this.model = result.getSite(); } + public MPSite getModel() { + return model; + } + public String getSiteName() { return model.getSiteName(); } diff --git a/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/ModelUser.java b/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/ModelUser.java old mode 100644 new mode 100755 index d2009c6e..84d20393 --- a/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/ModelUser.java +++ b/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/ModelUser.java @@ -42,7 +42,7 @@ public class ModelUser extends User { } public void setAvatar(final int avatar) { - model.setAvatar( avatar % Res.avatars() ); + model.setAvatar(avatar % Res.avatars()); MPUserFileManager.get().save(); } @@ -67,8 +67,8 @@ public class ModelUser extends User { return FluentIterable.from( model.findSitesByName( query ) ).transform( new Function() { @Nullable @Override - public Site apply(@Nullable final MPSiteResult result) { - return new ModelSite( Preconditions.checkNotNull( result ) ); + public Site apply(@Nullable final MPSiteResult site) { + return new ModelSite( Preconditions.checkNotNull( site ) ); } } ); } @@ -80,6 +80,14 @@ public class ModelUser extends User { MPUserFileManager.get().save(); } + @Override + public void deleteSite(Site site) { + if (site instanceof ModelSite) { + model.deleteSite(((ModelSite) site).getModel()); + MPUserFileManager.get().save(); + } + } + public boolean keySaved() { // TODO return false; diff --git a/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/PasswordFrame.java b/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/PasswordFrame.java old mode 100644 new mode 100755 index aa03a72a..2b17e313 --- a/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/PasswordFrame.java +++ b/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/PasswordFrame.java @@ -1,9 +1,13 @@ package com.lyndir.masterpassword.gui; +import static com.lyndir.lhunath.opal.system.util.ObjectUtils.ifNotNullElse; import static com.lyndir.lhunath.opal.system.util.StringUtils.*; +import com.google.common.collect.FluentIterable; import com.google.common.collect.Iterables; import com.google.common.util.concurrent.*; +import com.lyndir.lhunath.opal.system.util.NNSupplier; +import com.lyndir.lhunath.opal.system.util.PredicateNN; import com.lyndir.masterpassword.*; import com.lyndir.masterpassword.gui.util.Components; import java.awt.*; @@ -24,7 +28,7 @@ public class PasswordFrame extends JFrame implements DocumentListener { private final User user; private final Components.GradientPanel root; private final JTextField siteNameField; - private final JButton siteAddButton; + private final JButton siteActionButton; private final JComboBox siteTypeField; private final JComboBox siteVersionField; private final JSpinner siteCounterField; @@ -33,8 +37,10 @@ public class PasswordFrame extends JFrame implements DocumentListener { private final JCheckBox maskPasswordField; private final char passwordEchoChar; private final Font passwordEchoFont; - private boolean updatingUI; + + @Nullable private Site currentSite; + private boolean updatingUI; public PasswordFrame(User user) throws HeadlessException { @@ -58,45 +64,48 @@ public class PasswordFrame extends JFrame implements DocumentListener { sitePanel.add( Components.stud() ); // Site Name - sitePanel.add( Components.label( "Site Name:" ) ); + sitePanel.add(Components.label("Site Name:")); JComponent siteControls = Components.boxLayout( BoxLayout.LINE_AXIS, // siteNameField = Components.textField(), Components.stud(), - siteAddButton = Components.button( "Add Site" ) ); - siteNameField.getDocument().addDocumentListener( this ); - siteNameField.addActionListener( new ActionListener() { + siteActionButton = Components.button( "Add Site" ) ); + siteNameField.getDocument().addDocumentListener(this); + siteNameField.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { - Futures.addCallback( updatePassword(), new FutureCallback() { + Futures.addCallback(updatePassword(true), new FutureCallback() { @Override public void onSuccess(@Nullable final String sitePassword) { - StringSelection clipboardContents = new StringSelection( sitePassword ); - Toolkit.getDefaultToolkit().getSystemClipboard().setContents( clipboardContents, null ); + StringSelection clipboardContents = new StringSelection(sitePassword); + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(clipboardContents, null); - SwingUtilities.invokeLater( new Runnable() { + SwingUtilities.invokeLater(new Runnable() { @Override public void run() { - passwordField.setText( null ); - siteNameField.setText( null ); + passwordField.setText(null); + siteNameField.setText(null); - dispatchEvent( new WindowEvent( PasswordFrame.this, WindowEvent.WINDOW_CLOSING ) ); + dispatchEvent(new WindowEvent(PasswordFrame.this, WindowEvent.WINDOW_CLOSING)); } - } ); + }); } @Override public void onFailure(final Throwable t) { } - } ); + }); } - } ); - siteAddButton.setVisible( false ); - siteAddButton.addActionListener( new ActionListener() { + }); + siteActionButton.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { - PasswordFrame.this.user.addSite( currentSite ); - siteAddButton.setVisible( false ); + if (currentSite instanceof ModelSite) + PasswordFrame.this.user.deleteSite(currentSite); + else + PasswordFrame.this.user.addSite(currentSite); + + updatePassword(true); } - } ); + }); sitePanel.add( siteControls ); sitePanel.add( Components.stud() ); @@ -115,7 +124,7 @@ public class PasswordFrame extends JFrame implements DocumentListener { siteTypeField.addItemListener( new ItemListener() { @Override public void itemStateChanged(final ItemEvent e) { - updatePassword(); + updatePassword(true); } } ); @@ -125,7 +134,7 @@ public class PasswordFrame extends JFrame implements DocumentListener { siteVersionField.addItemListener( new ItemListener() { @Override public void itemStateChanged(final ItemEvent e) { - updatePassword(); + updatePassword(true); } } ); @@ -134,7 +143,7 @@ public class PasswordFrame extends JFrame implements DocumentListener { siteCounterField.addChangeListener( new ChangeListener() { @Override public void stateChanged(final ChangeEvent e) { - updatePassword(); + updatePassword(true); } } ); @@ -186,25 +195,33 @@ public class PasswordFrame extends JFrame implements DocumentListener { } @Nonnull - private ListenableFuture updatePassword() { + private ListenableFuture updatePassword(boolean allowNameCompletion) { final String siteNameQuery = siteNameField.getText(); if (updatingUI) return Futures.immediateCancelledFuture(); if (siteNameQuery == null || siteNameQuery.isEmpty() || !user.isKeyAvailable()) { + siteActionButton.setVisible(false); tipLabel.setText( null ); passwordField.setText( null ); return Futures.immediateCancelledFuture(); } - final MPSiteType siteType = siteTypeField.getModel().getElementAt( siteTypeField.getSelectedIndex() ); - final MasterKey.Version siteVersion = siteVersionField.getItemAt( siteVersionField.getSelectedIndex() ); + final MPSiteType siteType = siteTypeField.getModel().getElementAt(siteTypeField.getSelectedIndex()); + final MasterKey.Version siteVersion = siteVersionField.getItemAt(siteVersionField.getSelectedIndex()); final int siteCounter = (Integer) siteCounterField.getValue(); - final Site site = currentSite != null && currentSite.getSiteName().equals( siteNameQuery )? currentSite - : Iterables.getFirst( user.findSitesByName( siteNameQuery ), - new IncognitoSite( siteNameQuery, siteType, siteCounter, siteVersion ) ); - assert site != null; - if (site == currentSite) { + + Iterable siteResults = user.findSitesByName(siteNameQuery); + if (!allowNameCompletion) + siteResults = FluentIterable.from(siteResults).filter(new PredicateNN() { + @Override + public boolean apply(Site input) { + return siteNameQuery.equals(input.getSiteName()); + } + }); + final Site site = Iterables.getFirst(siteResults, + new IncognitoSite(siteNameQuery, siteType, siteCounter, siteVersion) ); + if (currentSite != null && site.getSiteName().equals(currentSite.getSiteName())) { site.setSiteType( siteType ); site.setAlgorithmVersion( siteVersion ); site.setSiteCounter( siteCounter ); @@ -226,8 +243,12 @@ public class PasswordFrame extends JFrame implements DocumentListener { public void run() { updatingUI = true; currentSite = site; - siteAddButton.setVisible( user instanceof ModelUser && !(currentSite instanceof ModelSite) ); - siteTypeField.setSelectedItem( currentSite.getSiteType() ); + siteActionButton.setVisible(user instanceof ModelUser); + if (currentSite instanceof ModelSite) + siteActionButton.setText("Delete Site"); + else + siteActionButton.setText("Add Site"); + siteTypeField.setSelectedItem(currentSite.getSiteType()); siteVersionField.setSelectedItem( currentSite.getAlgorithmVersion() ); siteCounterField.setValue( currentSite.getSiteCounter() ); siteNameField.setText( currentSite.getSiteName() ); @@ -251,15 +272,16 @@ public class PasswordFrame extends JFrame implements DocumentListener { @Override public void insertUpdate(final DocumentEvent e) { - updatePassword(); + updatePassword(true); } @Override public void removeUpdate(final DocumentEvent e) { + updatePassword(false); } @Override public void changedUpdate(final DocumentEvent e) { - updatePassword(); + updatePassword(true); } } diff --git a/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/User.java b/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/User.java old mode 100644 new mode 100755 index 0f62e3d3..e1703876 --- a/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/User.java +++ b/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/gui/User.java @@ -62,6 +62,8 @@ public abstract class User { public abstract void addSite(final Site site); + public abstract void deleteSite(final Site site); + @Override public boolean equals(final Object obj) { return this == obj || obj instanceof User && Objects.equals( getFullName(), ((User) obj).getFullName() ); diff --git a/MasterPassword/Java/masterpassword-model/src/main/java/com/lyndir/masterpassword/model/MPUser.java b/MasterPassword/Java/masterpassword-model/src/main/java/com/lyndir/masterpassword/model/MPUser.java old mode 100644 new mode 100755 index fac7d8a2..51222b2a --- a/MasterPassword/Java/masterpassword-model/src/main/java/com/lyndir/masterpassword/model/MPUser.java +++ b/MasterPassword/Java/masterpassword-model/src/main/java/com/lyndir/masterpassword/model/MPUser.java @@ -59,6 +59,10 @@ public class MPUser implements Comparable { sites.add( site ); } + public void deleteSite(final MPSite site) { + sites.remove( site ); + } + public String getFullName() { return fullName; }