Skip to content

Commit

Permalink
Merge pull request #30 from edimoral/localization
Browse files Browse the repository at this point in the history
Adds localization feature from #29
  • Loading branch information
gaborbata authored Mar 4, 2024
2 parents 1ad189a + 52bd004 commit 2a1f5f9
Show file tree
Hide file tree
Showing 14 changed files with 497 additions and 111 deletions.
3 changes: 3 additions & 0 deletions src/main/config/jpass.properties
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,6 @@ date.format=yyyy-MM-dd
# Directory to be used for file chooser dialogs. (default: ./)
# Leave that property empty to use the system default directory.
file.chooser.directory=./

# Locale ID to set the program language
language.languageSetting=en-US
23 changes: 15 additions & 8 deletions src/main/java/jpass/ui/EntryDetailsTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@
import jpass.util.DateUtils;
import jpass.xml.bind.Entry;

import static jpass.ui.JPassFrame.getLocalizedMessages;
import static jpass.util.Constants.VIEW_WINDOW_CREATED;
import static jpass.util.Constants.VIEW_WINDOW_MODIFIED;
import static jpass.util.Constants.VIEW_WINDOW_TITLE;
import static jpass.util.Constants.VIEW_WINDOW_URL;
import static jpass.util.Constants.VIEW_WINDOW_USER;

/**
* Table to display entry details.
*/
Expand All @@ -54,11 +61,11 @@ public class EntryDetailsTable extends JTable {
= DateUtils.createFormatter(Configuration.getInstance().get("date.format", "yyyy-MM-dd"));

private enum DetailType {
TITLE("Title", Entry::getTitle),
URL("URL", Entry::getUrl),
USER("User", Entry::getUser),
MODIFIED("Modified", entry -> DateUtils.formatIsoDateTime(entry.getLastModification(), FORMATTER)),
CREATED("Created", entry -> DateUtils.formatIsoDateTime(entry.getCreationDate(), FORMATTER));
TITLE(getLocalizedMessages().getString(VIEW_WINDOW_TITLE), Entry::getTitle),
URL(getLocalizedMessages().getString(VIEW_WINDOW_URL), Entry::getUrl),
USER(getLocalizedMessages().getString(VIEW_WINDOW_USER), Entry::getUser),
MODIFIED(getLocalizedMessages().getString(VIEW_WINDOW_MODIFIED), entry -> DateUtils.formatIsoDateTime(entry.getLastModification(), FORMATTER)),
CREATED(getLocalizedMessages().getString(VIEW_WINDOW_CREATED), entry -> DateUtils.formatIsoDateTime(entry.getCreationDate(), FORMATTER));

private final String description;
private final Function<Entry, String> valueMapper;
Expand All @@ -78,7 +85,7 @@ public String getValue(Entry entry) {
}

private static final Map<String, DetailType> DETAILS_BY_NAME = Arrays.stream(DetailType.values())
.collect(Collectors.toMap(detail -> detail.name(), Function.identity()));
.collect(Collectors.toMap(Enum::name, Function.identity()));

private static final String[] DEFAULT_DETAILS = {
DetailType.TITLE.name(),
Expand All @@ -92,14 +99,14 @@ public EntryDetailsTable() {
super();

detailsToDisplay = Arrays.stream(Configuration.getInstance().getArray("entry.details", DEFAULT_DETAILS))
.map(name -> DETAILS_BY_NAME.get(name))
.map(DETAILS_BY_NAME::get)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());

if (detailsToDisplay.isEmpty()) {
Arrays.stream(DEFAULT_DETAILS)
.map(name -> DETAILS_BY_NAME.get(name))
.map(DETAILS_BY_NAME::get)
.forEach(detailsToDisplay::add);
}

Expand Down
43 changes: 29 additions & 14 deletions src/main/java/jpass/ui/EntryDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,22 @@
import jpass.util.StringUtils;
import jpass.xml.bind.Entry;

import static jpass.ui.JPassFrame.getLocalizedMessages;
import static jpass.ui.helper.EntryHelper.copyEntryField;
import static jpass.util.Constants.BUTTON_MESSAGE_CANCEL;
import static jpass.util.Constants.BUTTON_MESSAGE_OK;
import static jpass.util.Constants.ENTRY_DIALOG_COPY_ENTRY;
import static jpass.util.Constants.ENTRY_DIALOG_FILL_TITLE_FIELD;
import static jpass.util.Constants.ENTRY_DIALOG_GENERATE_ENTRY;
import static jpass.util.Constants.ENTRY_DIALOG_SHOW_ENTRY;
import static jpass.util.Constants.ENTRY_DIALOG_TITLE_ALREADY_EXISTS;
import static jpass.util.Constants.PASSWORD_PASSWORDS_NOT_IDENTICAL;
import static jpass.util.Constants.VIEW_WINDOW_NOTES;
import static jpass.util.Constants.VIEW_WINDOW_PASSWORD;
import static jpass.util.Constants.VIEW_WINDOW_REPEAT;
import static jpass.util.Constants.VIEW_WINDOW_TITLE;
import static jpass.util.Constants.VIEW_WINDOW_URL;
import static jpass.util.Constants.VIEW_WINDOW_USER_NAME;

/**
* A dialog with the entry data.
Expand Down Expand Up @@ -114,15 +129,15 @@ public EntryDialog(JPassFrame parent, String title, Entry entry, boolean newEntr
this.originalEcho = this.passwordField.getEchoChar();
this.repeatField = TextComponentFactory.newPasswordField(true);

this.showButton = new JToggleButton("Show", MessageDialog.getIcon("show"));
this.showButton = new JToggleButton(getLocalizedMessages().getString(ENTRY_DIALOG_SHOW_ENTRY), MessageDialog.getIcon("show"));
this.showButton.setActionCommand("show_button");
this.showButton.setMnemonic(KeyEvent.VK_S);
this.showButton.addActionListener(this);
this.generateButton = new JButton("Generate", MessageDialog.getIcon("generate"));
this.generateButton = new JButton(getLocalizedMessages().getString(ENTRY_DIALOG_GENERATE_ENTRY), MessageDialog.getIcon("generate"));
this.generateButton.setActionCommand("generate_button");
this.generateButton.setMnemonic(KeyEvent.VK_G);
this.generateButton.addActionListener(this);
this.copyButton = new JButton("Copy", MessageDialog.getIcon("keyring"));
this.copyButton = new JButton(getLocalizedMessages().getString(ENTRY_DIALOG_COPY_ENTRY), MessageDialog.getIcon("keyring"));
this.copyButton.setActionCommand("copy_button");
this.copyButton.setMnemonic(KeyEvent.VK_P);
this.copyButton.addActionListener(this);
Expand All @@ -137,15 +152,15 @@ public EntryDialog(JPassFrame parent, String title, Entry entry, boolean newEntr
5, 0); // xPad, yPad

this.fieldPanel = new JPanel(new SpringLayout());
this.fieldPanel.add(new JLabel("Title:"));
this.fieldPanel.add(new JLabel(String.format("%s:", getLocalizedMessages().getString(VIEW_WINDOW_TITLE))));
this.fieldPanel.add(this.titleField);
this.fieldPanel.add(new JLabel("URL:"));
this.fieldPanel.add(new JLabel(String.format("%s:", getLocalizedMessages().getString(VIEW_WINDOW_URL))));
this.fieldPanel.add(this.urlField);
this.fieldPanel.add(new JLabel("User name:"));
this.fieldPanel.add(new JLabel(String.format("%s:", getLocalizedMessages().getString(VIEW_WINDOW_USER_NAME))));
this.fieldPanel.add(this.userField);
this.fieldPanel.add(new JLabel("Password:"));
this.fieldPanel.add(new JLabel(String.format("%s:", getLocalizedMessages().getString(VIEW_WINDOW_PASSWORD))));
this.fieldPanel.add(this.passwordField);
this.fieldPanel.add(new JLabel("Repeat:"));
this.fieldPanel.add(new JLabel(String.format("%s:", getLocalizedMessages().getString(VIEW_WINDOW_REPEAT))));
this.fieldPanel.add(this.repeatField);
this.fieldPanel.add(new JLabel(""));
this.fieldPanel.add(this.passwordButtonPanel);
Expand All @@ -161,15 +176,15 @@ public EntryDialog(JPassFrame parent, String title, Entry entry, boolean newEntr

this.notesPanel = new JPanel(new BorderLayout(5, 5));
this.notesPanel.setBorder(new EmptyBorder(0, 5, 0, 5));
this.notesPanel.add(new JLabel("Notes:"), BorderLayout.NORTH);
this.notesPanel.add(new JLabel(String.format("%s:", getLocalizedMessages().getString(VIEW_WINDOW_NOTES))), BorderLayout.NORTH);
this.notesPanel.add(new JScrollPane(this.notesField), BorderLayout.CENTER);

this.okButton = new JButton("OK", MessageDialog.getIcon("accept"));
this.okButton = new JButton(getLocalizedMessages().getString(BUTTON_MESSAGE_OK), MessageDialog.getIcon("accept"));
this.okButton.setActionCommand("ok_button");
this.okButton.setMnemonic(KeyEvent.VK_O);
this.okButton.addActionListener(this);

this.cancelButton = new JButton("Cancel", MessageDialog.getIcon("cancel"));
this.cancelButton = new JButton(getLocalizedMessages().getString(BUTTON_MESSAGE_CANCEL), MessageDialog.getIcon("cancel"));
this.cancelButton.setActionCommand("cancel_button");
this.cancelButton.setMnemonic(KeyEvent.VK_C);
this.cancelButton.addActionListener(this);
Expand Down Expand Up @@ -197,13 +212,13 @@ public void actionPerformed(ActionEvent e) {
this.repeatField.setEchoChar(this.showButton.isSelected() ? NULL_ECHO : this.originalEcho);
} else if ("ok_button".equals(command)) {
if (this.titleField.getText().trim().isEmpty()) {
MessageDialog.showWarningMessage(this, "Please fill the title field.");
MessageDialog.showWarningMessage(this, getLocalizedMessages().getString(ENTRY_DIALOG_FILL_TITLE_FIELD));
return;
} else if (!checkEntryTitle()) {
MessageDialog.showWarningMessage(this, "Title is already exists,\nplease enter a different title.");
MessageDialog.showWarningMessage(this, getLocalizedMessages().getString(ENTRY_DIALOG_TITLE_ALREADY_EXISTS));
return;
} else if (!Arrays.equals(this.passwordField.getPassword(), this.repeatField.getPassword())) {
MessageDialog.showWarningMessage(this, "Password and repeated passwords are not identical.");
MessageDialog.showWarningMessage(this, getLocalizedMessages().getString(PASSWORD_PASSWORDS_NOT_IDENTICAL));
return;
}
this.modifiedEntry = getEntryFromDialog();
Expand Down
44 changes: 30 additions & 14 deletions src/main/java/jpass/ui/GeneratePasswordDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,22 @@
import jpass.util.CryptUtils;
import jpass.util.SpringUtilities;

import static jpass.ui.JPassFrame.getLocalizedMessages;
import static jpass.util.Constants.BUTTON_MESSAGE_ACCEPT;
import static jpass.util.Constants.BUTTON_MESSAGE_CANCEL;
import static jpass.util.Constants.BUTTON_MESSAGE_CLOSE;
import static jpass.util.Constants.ENTRY_DIALOG_GENERATE_ENTRY;
import static jpass.util.Constants.PASSWORD_CAN_NOT_GENERATE_PASSWORD;
import static jpass.util.Constants.PASSWORD_GENERATED_PASSWORD;
import static jpass.util.Constants.PASSWORD_GENERATE_PASSWORD;
import static jpass.util.Constants.PASSWORD_GENERATE_PASSWORD_REQUEST;
import static jpass.util.Constants.PASSWORD_PASSWORD_LENGTH;
import static jpass.util.Constants.VIEW_WINDOW_CUSTOM_SYMBOLS;
import static jpass.util.Constants.VIEW_WINDOW_LOWER_CASE_LETTERS;
import static jpass.util.Constants.VIEW_WINDOW_NUMBERS;
import static jpass.util.Constants.VIEW_WINDOW_SETTINGS;
import static jpass.util.Constants.VIEW_WINDOW_UPPER_CASE_LETTERS;

/**
* Dialog for generating random passwords.
*
Expand All @@ -71,9 +87,9 @@ public final class GeneratePasswordDialog extends JDialog implements ActionListe
* Options for password generation.
*/
private static final String[][] PASSWORD_OPTIONS = {
{"Upper case letters (A-Z)", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"},
{"Lower case letters (a-z)", "abcdefghijklmnopqrstuvwxyz"},
{"Numbers (0-9)", "0123456789"}
{getLocalizedMessages().getString(VIEW_WINDOW_UPPER_CASE_LETTERS), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"},
{getLocalizedMessages().getString(VIEW_WINDOW_LOWER_CASE_LETTERS), "abcdefghijklmnopqrstuvwxyz"},
{getLocalizedMessages().getString(VIEW_WINDOW_NUMBERS), "0123456789"}
};

private JCheckBox[] checkBoxes;
Expand Down Expand Up @@ -128,12 +144,12 @@ public GeneratePasswordDialog(JDialog parent) {
*/
private void initDialog(final Component parent, final boolean showAcceptButton) {
setModal(true);
setTitle("Generate Password");
setTitle(getLocalizedMessages().getString(PASSWORD_GENERATE_PASSWORD));
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
this.generatedPassword = null;

this.lengthPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0));
this.lengthLabel = new JLabel("Password length:");
this.lengthLabel = new JLabel(String.format("%s:", getLocalizedMessages().getString(PASSWORD_PASSWORD_LENGTH)));
this.lengthPanel.add(this.lengthLabel);

int passwordGenerationLength = Configuration.getInstance().getInteger("default.password.generation.length", 14);
Expand All @@ -148,14 +164,14 @@ private void initDialog(final Component parent, final boolean showAcceptButton)
this.lengthPanel.add(this.lengthSpinner);

this.charactersPanel = new JPanel();
this.charactersPanel.setBorder(new TitledBorder("Settings"));
this.charactersPanel.setBorder(new TitledBorder(getLocalizedMessages().getString(VIEW_WINDOW_SETTINGS)));
this.charactersPanel.add(this.lengthPanel);
this.checkBoxes = new JCheckBox[PASSWORD_OPTIONS.length];
for (int i = 0; i < PASSWORD_OPTIONS.length; i++) {
this.checkBoxes[i] = new JCheckBox(PASSWORD_OPTIONS[i][0], true);
this.charactersPanel.add(this.checkBoxes[i]);
}
this.customSymbolsCheck = new JCheckBox("Custom symbols");
this.customSymbolsCheck = new JCheckBox(getLocalizedMessages().getString(VIEW_WINDOW_CUSTOM_SYMBOLS));
this.customSymbolsCheck.setActionCommand("custom_symbols_check");
this.customSymbolsCheck.addActionListener(this);
this.charactersPanel.add(this.customSymbolsCheck);
Expand All @@ -167,11 +183,11 @@ private void initDialog(final Component parent, final boolean showAcceptButton)
SpringUtilities.makeCompactGrid(this.charactersPanel, 6, 1, 5, 5, 5, 5);

this.passwordPanel = new JPanel(new BorderLayout());
this.passwordPanel.setBorder(new TitledBorder("Generated password"));
this.passwordPanel.setBorder(new TitledBorder(getLocalizedMessages().getString(PASSWORD_GENERATED_PASSWORD)));

this.passwordField = TextComponentFactory.newTextField();
this.passwordPanel.add(this.passwordField, BorderLayout.NORTH);
this.generateButton = new JButton("Generate", MessageDialog.getIcon("generate"));
this.generateButton = new JButton(getLocalizedMessages().getString(ENTRY_DIALOG_GENERATE_ENTRY), MessageDialog.getIcon("generate"));
this.generateButton.setActionCommand("generate_button");
this.generateButton.addActionListener(this);
this.generateButton.setMnemonic(KeyEvent.VK_G);
Expand All @@ -182,15 +198,15 @@ private void initDialog(final Component parent, final boolean showAcceptButton)
this.buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));

if (showAcceptButton) {
this.acceptButton = new JButton("Accept", MessageDialog.getIcon("accept"));
this.acceptButton = new JButton(getLocalizedMessages().getString(BUTTON_MESSAGE_ACCEPT), MessageDialog.getIcon("accept"));
this.acceptButton.setActionCommand("accept_button");
this.acceptButton.setMnemonic(KeyEvent.VK_A);
this.acceptButton.addActionListener(this);
this.buttonPanel.add(this.acceptButton);

this.cancelButton = new JButton("Cancel", MessageDialog.getIcon("cancel"));
this.cancelButton = new JButton(getLocalizedMessages().getString(BUTTON_MESSAGE_CANCEL), MessageDialog.getIcon("cancel"));
} else {
this.cancelButton = new JButton("Close", MessageDialog.getIcon("close"));
this.cancelButton = new JButton(getLocalizedMessages().getString(BUTTON_MESSAGE_CLOSE), MessageDialog.getIcon("close"));
}

this.cancelButton.setActionCommand("cancel_button");
Expand Down Expand Up @@ -231,7 +247,7 @@ public void actionPerformed(ActionEvent e) {
}

if (characterSet.isEmpty()) {
MessageDialog.showWarningMessage(this, "Cannot generate password.\nPlease select a character set.");
MessageDialog.showWarningMessage(this, getLocalizedMessages().getString(PASSWORD_CAN_NOT_GENERATE_PASSWORD));
return;
}

Expand All @@ -244,7 +260,7 @@ public void actionPerformed(ActionEvent e) {
} else if ("accept_button".equals(command)) {
this.generatedPassword = this.passwordField.getText();
if (this.generatedPassword.isEmpty()) {
MessageDialog.showWarningMessage(this, "Please generate a password.");
MessageDialog.showWarningMessage(this, getLocalizedMessages().getString(PASSWORD_GENERATE_PASSWORD_REQUEST));
return;
}
dispose();
Expand Down
Loading

0 comments on commit 2a1f5f9

Please sign in to comment.