Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds localization feature from #29 #30

Merged
merged 6 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading