diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c5f3f6b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive" +} \ No newline at end of file diff --git a/BackupManager-1.0-SNAPSHOT-jar-with-dependencies.jar b/BackupManager-1.0-SNAPSHOT-jar-with-dependencies.jar new file mode 100644 index 0000000..f2b211b Binary files /dev/null and b/BackupManager-1.0-SNAPSHOT-jar-with-dependencies.jar differ diff --git a/pom.xml b/pom.xml index 6242a5f..ec025ab 100644 --- a/pom.xml +++ b/pom.xml @@ -10,13 +10,19 @@ 19 - + com.googlecode.json-simple json-simple 1.1.1 + + com.google.code.gson + gson + 2.8.9 + + junit @@ -42,6 +48,11 @@ + + com.formdev + flatlaf-intellij-themes + 3.5.2 + com.formdev flatlaf diff --git a/src/main/java/com/mycompany/autobackupprogram/BackupOperations.java b/src/main/java/com/mycompany/autobackupprogram/BackupOperations.java index 6cc0619..347ce5e 100644 --- a/src/main/java/com/mycompany/autobackupprogram/BackupOperations.java +++ b/src/main/java/com/mycompany/autobackupprogram/BackupOperations.java @@ -1,8 +1,9 @@ package com.mycompany.autobackupprogram; -import static com.mycompany.autobackupprogram.BackupManagerGUI.OpenExceptionMessage; -import static com.mycompany.autobackupprogram.BackupManagerGUI.dateForfolderNameFormatter; -import static com.mycompany.autobackupprogram.BackupManagerGUI.formatter; +import static com.mycompany.autobackupprogram.GUI.BackupManagerGUI.OpenExceptionMessage; +import static com.mycompany.autobackupprogram.GUI.BackupManagerGUI.dateForfolderNameFormatter; +import static com.mycompany.autobackupprogram.GUI.BackupManagerGUI.formatter; + import java.awt.TrayIcon; import java.io.File; import java.io.FileOutputStream; @@ -26,6 +27,13 @@ import javax.swing.JToggleButton; import javax.swing.SwingUtilities; +import com.mycompany.autobackupprogram.Entities.Backup; +import com.mycompany.autobackupprogram.Enums.ConfigKey; +import com.mycompany.autobackupprogram.Enums.TranslationLoaderEnum.TranslationCategory; +import com.mycompany.autobackupprogram.Enums.TranslationLoaderEnum.TranslationKey; +import com.mycompany.autobackupprogram.GUI.BackupManagerGUI; +import com.mycompany.autobackupprogram.GUI.BackupProgressGUI; +import com.mycompany.autobackupprogram.Entities.TimeInterval; import com.mycompany.autobackupprogram.Logger.LogLevel; public class BackupOperations{ @@ -62,7 +70,7 @@ public static void SingleBackup(Backup backup, TrayIcon trayIcon, BackupProgress zipDirectory(path1, path2+".zip", backup, trayIcon, progressBar, singleBackupBtn, autoBackupBtn); } catch (IOException e) { Logger.logMessage("Error during the backup operation: the initial path is incorrect!", Logger.LogLevel.WARN); - JOptionPane.showMessageDialog(null, "Error during the backup operation: the initial path is incorrect!", "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_MESSAGE_FOR_INCORRECT_INITIAL_PATH), TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_GENERIC_TITLE), JOptionPane.ERROR_MESSAGE); if (singleBackupBtn != null) singleBackupBtn.setEnabled(true); if (autoBackupBtn != null) autoBackupBtn.setEnabled(true); } catch (Exception ex) { @@ -109,15 +117,15 @@ private static void updateAfterBackup(String path1, String path2, Backup backup, updateBackup(backups, backup); - if (trayIcon != null) { - trayIcon.displayMessage("Backup Manager", "Backup: "+ backup.getBackupName() +"\nThe backup was successfully completed:\nFrom: " + path1 + "\nTo: " + path2, TrayIcon.MessageType.INFO); + if (trayIcon != null) { + trayIcon.displayMessage(TranslationCategory.GENERAL.getTranslation(TranslationKey.APP_NAME), TranslationCategory.GENERAL.getTranslation(TranslationKey.BACKUP) + ": " + backup.getBackupName() + TranslationCategory.TRAY_ICON.getTranslation(TranslationKey.SUCCESS_MESSAGE) + "\n" + TranslationCategory.GENERAL.getTranslation(TranslationKey.FROM) + ": " + path1 + "\n" + TranslationCategory.GENERAL.getTranslation(TranslationKey.TO) + ": " + path2, TrayIcon.MessageType.INFO); } } catch (IllegalArgumentException ex) { Logger.logMessage("An error occurred: " + ex.getMessage(), Logger.LogLevel.ERROR, ex); OpenExceptionMessage(ex.getMessage(), Arrays.toString(ex.getStackTrace())); } catch (Exception e) { Logger.logMessage("Error saving file", Logger.LogLevel.WARN); - JOptionPane.showMessageDialog(null, "Error saving file", "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_MESSAGE_SAVING_FILE), TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_GENERIC_TITLE), JOptionPane.ERROR_MESSAGE); } } @@ -125,11 +133,11 @@ public static boolean CheckInputCorrect(String backupName, String path1, String //check if inputs are null if(path1.length() == 0 || path2.length() == 0) { Logger.logMessage("Input Missing!", Logger.LogLevel.WARN); - - if (trayIcon != null){ - trayIcon.displayMessage("Backup Manager", "Backup: "+ backupName +"\nError during automatic backup.\nInput Missing!", TrayIcon.MessageType.ERROR); + + if (trayIcon != null) { + trayIcon.displayMessage(TranslationCategory.GENERAL.getTranslation(TranslationKey.APP_NAME), TranslationCategory.GENERAL.getTranslation(TranslationKey.BACKUP) + ": " + backupName + TranslationCategory.TRAY_ICON.getTranslation(TranslationKey.ERROR_MESSAGE_INPUT_MISSING), TrayIcon.MessageType.ERROR); } else { - JOptionPane.showMessageDialog(null, "Input Missing!", "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_MESSAGE_INPUT_MISSING_GENERIC), TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_GENERIC_TITLE), JOptionPane.ERROR_MESSAGE); } return false; } @@ -138,9 +146,9 @@ public static boolean CheckInputCorrect(String backupName, String path1, String Logger.logMessage("Input Error! One or both paths do not exist.", Logger.LogLevel.WARN); if (trayIcon != null) { - trayIcon.displayMessage("Backup Manager", "Backup: "+ backupName +"\nError during automatic backup.\nOne or both paths do not exist!", TrayIcon.MessageType.ERROR); + trayIcon.displayMessage(TranslationCategory.GENERAL.getTranslation(TranslationKey.APP_NAME), TranslationCategory.GENERAL.getTranslation(TranslationKey.BACKUP) + ": " + backupName + TranslationCategory.TRAY_ICON.getTranslation(TranslationKey.ERROR_MESSAGE_FILES_NOT_EXISTING), TrayIcon.MessageType.ERROR); } else { - JOptionPane.showMessageDialog(null, "One or both paths do not exist!", "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_MESSAGE_PATH_NOT_EXISTING), TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_GENERIC_TITLE), JOptionPane.ERROR_MESSAGE); } return false; } @@ -149,9 +157,9 @@ public static boolean CheckInputCorrect(String backupName, String path1, String Logger.logMessage("The initial path and destination path cannot be the same. Please choose different paths", Logger.LogLevel.WARN); if (trayIcon != null) { - trayIcon.displayMessage("Backup Manager", "Backup: "+ backupName +"\nError during automatic backup.\nThe initial path and destination path cannot be the same. Please choose different paths!", TrayIcon.MessageType.ERROR); + trayIcon.displayMessage(TranslationCategory.GENERAL.getTranslation(TranslationKey.APP_NAME), TranslationCategory.GENERAL.getTranslation(TranslationKey.BACKUP) + ": " + backupName + TranslationCategory.TRAY_ICON.getTranslation(TranslationKey.ERROR_MESSAGE_SAME_PATHS), TrayIcon.MessageType.ERROR); } else { - JOptionPane.showMessageDialog(null, "The initial path and destination path cannot be the same. Please choose different paths!", "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_MESSAGE_SAME_PATHS_GENERIC), TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_GENERIC_TITLE), JOptionPane.ERROR_MESSAGE); } return false; } diff --git a/src/main/java/com/mycompany/autobackupprogram/BackupService.java b/src/main/java/com/mycompany/autobackupprogram/BackupService.java index 3081aa8..6c1d00a 100644 --- a/src/main/java/com/mycompany/autobackupprogram/BackupService.java +++ b/src/main/java/com/mycompany/autobackupprogram/BackupService.java @@ -13,10 +13,14 @@ import java.util.concurrent.TimeUnit; import javax.swing.JFrame; +import com.mycompany.autobackupprogram.Entities.Backup; +import com.mycompany.autobackupprogram.Enums.ConfigKey; +import com.mycompany.autobackupprogram.GUI.BackupManagerGUI; + public class BackupService { private ScheduledExecutorService scheduler; private final JSONAutoBackup json = new JSONAutoBackup(); - private final JSONConfigReader jsonConfig = new JSONConfigReader(ConfigKey.CONFIG_FILE_STRING.getValue(), ConfigKey.RES_DIRECTORY_STRING.getValue()); + private final JSONConfigReader jsonConfig = new JSONConfigReader(ConfigKey.CONFIG_FILE_STRING.getValue(), ConfigKey.CONFIG_DIRECTORY_STRING.getValue()); private TrayIcon trayIcon = null; private BackupManagerGUI guiInstance = null; diff --git a/src/main/java/com/mycompany/autobackupprogram/Dialogs/PreferencesDialog.form b/src/main/java/com/mycompany/autobackupprogram/Dialogs/PreferencesDialog.form new file mode 100644 index 0000000..ca18cce --- /dev/null +++ b/src/main/java/com/mycompany/autobackupprogram/Dialogs/PreferencesDialog.form @@ -0,0 +1,124 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/java/com/mycompany/autobackupprogram/Dialogs/PreferencesDialog.java b/src/main/java/com/mycompany/autobackupprogram/Dialogs/PreferencesDialog.java new file mode 100644 index 0000000..c74aae7 --- /dev/null +++ b/src/main/java/com/mycompany/autobackupprogram/Dialogs/PreferencesDialog.java @@ -0,0 +1,203 @@ +package com.mycompany.autobackupprogram.Dialogs; + +import com.formdev.flatlaf.FlatIntelliJLaf; +import com.mycompany.autobackupprogram.Entities.Preferences; +import com.mycompany.autobackupprogram.Enums.ConfigKey; +import com.mycompany.autobackupprogram.Enums.LanguagesEnum; +import com.mycompany.autobackupprogram.Enums.ThemesEnum; +import com.mycompany.autobackupprogram.Enums.TranslationLoaderEnum; +import com.mycompany.autobackupprogram.Enums.TranslationLoaderEnum.TranslationCategory; +import com.mycompany.autobackupprogram.Enums.TranslationLoaderEnum.TranslationKey; +import com.mycompany.autobackupprogram.Managers.ThemeManager; + +import static com.mycompany.autobackupprogram.GUI.BackupManagerGUI.OpenExceptionMessage; +import java.awt.Image; +import java.io.IOException; +import java.util.Arrays; +import javax.swing.ImageIcon; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +import org.json.simple.parser.ParseException; + +public class PreferencesDialog extends javax.swing.JDialog { + + private boolean isApply = false; + + public PreferencesDialog(java.awt.Frame parent, boolean modal) { + super(parent, modal); + initComponents(); + + // logo application + Image icon = new ImageIcon(this.getClass().getResource(ConfigKey.LOGO_IMG.getValue())).getImage(); + this.setIconImage(icon); + + ThemeManager.updateThemeDialog(this); + setLanguages(); + setThemes(); + setTranslations(); + } + + public void changeTheme() { + + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + languagesComboBox = new javax.swing.JComboBox<>(); + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + themesComboBox = new javax.swing.JComboBox<>(); + applyBtn = new javax.swing.JButton(); + closeBtn = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle("Preferences"); + setAlwaysOnTop(true); + setResizable(false); + + languagesComboBox.setToolTipText(""); + + jLabel1.setText("Language"); + + jLabel2.setText("Theme"); + + themesComboBox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + themesComboBoxActionPerformed(evt); + } + }); + + applyBtn.setText("Apply"); + applyBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + applyBtnActionPerformed(evt); + } + }); + + closeBtn.setText("Close"); + closeBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + closeBtnActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(layout.createSequentialGroup() + .addContainerGap(223, Short.MAX_VALUE) + .addComponent(applyBtn) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(closeBtn)) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addGap(22, 22, 22) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, 345, Short.MAX_VALUE) + .addComponent(themesComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(languagesComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addContainerGap(13, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(20, 20, 20) + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(languagesComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(themesComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 109, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(applyBtn) + .addComponent(closeBtn)) + .addGap(14, 14, 14)) + ); + + pack(); + setLocationRelativeTo(null); + }// //GEN-END:initComponents + + private void themesComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_themesComboBoxActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_themesComboBoxActionPerformed + + private void applyBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applyBtnActionPerformed + isApply = true; + try { + // translactions + Preferences.setLanguage((String) languagesComboBox.getSelectedItem()); + TranslationLoaderEnum.loadTranslations(ConfigKey.LANGUAGES_DIRECTORY_STRING.getValue() + Preferences.getLanguage().getFileName()); + setTranslations(); + + // theme + Preferences.setTheme((String) themesComboBox.getSelectedItem()); + ThemeManager.updateThemeDialog(this); + } catch (IOException | ParseException e) { + e.printStackTrace(); + } + }//GEN-LAST:event_applyBtnActionPerformed + + private void closeBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeBtnActionPerformed + this.dispose(); + }//GEN-LAST:event_closeBtnActionPerformed + + private void setLanguages() { + languagesComboBox.addItem(LanguagesEnum.ENG.getLanguageName()); + languagesComboBox.addItem(LanguagesEnum.ITA.getLanguageName()); + languagesComboBox.addItem(LanguagesEnum.ESP.getLanguageName()); + languagesComboBox.addItem(LanguagesEnum.DEU.getLanguageName()); + languagesComboBox.addItem(LanguagesEnum.FRA.getLanguageName()); + + languagesComboBox.setSelectedItem(Preferences.getLanguage().getLanguageName()); + } + + private void setThemes() { + themesComboBox.addItem(ThemesEnum.INTELLIJ.getThemeName()); + themesComboBox.addItem(ThemesEnum.DRACULA.getThemeName()); + themesComboBox.addItem(ThemesEnum.CARBON.getThemeName()); + themesComboBox.addItem(ThemesEnum.ARC_ORAGE.getThemeName()); + themesComboBox.addItem(ThemesEnum.ARC_DARK_ORANGE.getThemeName()); + themesComboBox.addItem(ThemesEnum.CYAN_LIGHT.getThemeName()); + themesComboBox.addItem(ThemesEnum.NORD.getThemeName()); + themesComboBox.addItem(ThemesEnum.HIGH_CONTRAST.getThemeName()); + themesComboBox.addItem(ThemesEnum.SOLARIZED_DARK.getThemeName()); + themesComboBox.addItem(ThemesEnum.SOLARIZED_LIGHT.getThemeName()); + + themesComboBox.setSelectedItem(Preferences.getTheme().getThemeName()); + } + + private void setTranslations() { + setTitle(TranslationCategory.PREFERENCES_DIALOG.getTranslation(TranslationKey.PREFERENCES_TITLE)); + applyBtn.setText(TranslationCategory.GENERAL.getTranslation(TranslationKey.APPLY_BUTTON)); + closeBtn.setText(TranslationCategory.GENERAL.getTranslation(TranslationKey.CLOSE_BUTTON)); + jLabel1.setText(TranslationCategory.PREFERENCES_DIALOG.getTranslation(TranslationKey.LANGUAGE)); + jLabel2.setText(TranslationCategory.PREFERENCES_DIALOG.getTranslation(TranslationKey.THEME)); + } + + public boolean isApply() { + return isApply; + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton applyBtn; + private javax.swing.JButton closeBtn; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JComboBox languagesComboBox; + private javax.swing.JComboBox themesComboBox; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/com/mycompany/autobackupprogram/TimePicker.form b/src/main/java/com/mycompany/autobackupprogram/Dialogs/TimePicker.form similarity index 100% rename from src/main/java/com/mycompany/autobackupprogram/TimePicker.form rename to src/main/java/com/mycompany/autobackupprogram/Dialogs/TimePicker.form diff --git a/src/main/java/com/mycompany/autobackupprogram/TimePicker.java b/src/main/java/com/mycompany/autobackupprogram/Dialogs/TimePicker.java similarity index 87% rename from src/main/java/com/mycompany/autobackupprogram/TimePicker.java rename to src/main/java/com/mycompany/autobackupprogram/Dialogs/TimePicker.java index 097f1f6..1dd39ef 100644 --- a/src/main/java/com/mycompany/autobackupprogram/TimePicker.java +++ b/src/main/java/com/mycompany/autobackupprogram/Dialogs/TimePicker.java @@ -1,7 +1,14 @@ -package com.mycompany.autobackupprogram; +package com.mycompany.autobackupprogram.Dialogs; import com.formdev.flatlaf.FlatIntelliJLaf; -import static com.mycompany.autobackupprogram.BackupManagerGUI.OpenExceptionMessage; +import com.mycompany.autobackupprogram.Enums.ConfigKey; +import com.mycompany.autobackupprogram.Enums.TranslationLoaderEnum.TranslationCategory; +import com.mycompany.autobackupprogram.Enums.TranslationLoaderEnum.TranslationKey; +import com.mycompany.autobackupprogram.Managers.ThemeManager; +import com.mycompany.autobackupprogram.Entities.TimeInterval; + +import static com.mycompany.autobackupprogram.GUI.BackupManagerGUI.OpenExceptionMessage; + import java.awt.Image; import java.util.Arrays; import javax.swing.ImageIcon; @@ -30,6 +37,8 @@ public TimePicker(java.awt.Frame parent, TimeInterval timeInterval, boolean moda // logo application Image icon = new ImageIcon(this.getClass().getResource(ConfigKey.LOGO_IMG.getValue())).getImage(); this.setIconImage(icon); + + setTranslations(); } public TimeInterval getTimeInterval() { @@ -248,7 +257,7 @@ private void btnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:e this.dispose(); } else { - JOptionPane.showMessageDialog(null, "The time interval is not correct", "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_WRONG_TIME_INTERVAL), TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_GENERIC_TITLE), JOptionPane.ERROR_MESSAGE); } }//GEN-LAST:event_btnOkActionPerformed @@ -269,26 +278,17 @@ private void minutesSpinnerStateChanged(javax.swing.event.ChangeEvent evt) {//GE minutesIntervalSpinnerChange(); }//GEN-LAST:event_minutesSpinnerStateChanged - public static void main(String args[]) { - try { - UIManager.setLookAndFeel(new FlatIntelliJLaf()); - } catch (UnsupportedLookAndFeelException ex) { - System.err.println("Exception (main) --> " + ex); - OpenExceptionMessage(ex.getMessage(), Arrays.toString(ex.getStackTrace())); - } - - java.awt.EventQueue.invokeLater(new Runnable() { - public void run() { - TimePicker dialog = new TimePicker(new javax.swing.JFrame(), null, true); - dialog.addWindowListener(new java.awt.event.WindowAdapter() { - @Override - public void windowClosing(java.awt.event.WindowEvent e) { - System.exit(0); - } - }); - dialog.setVisible(true); - } - }); + private void setTranslations() { + setTitle(TranslationCategory.TIME_PICKER_DIALOG.getTranslation(TranslationKey.TIME_INTERVAL_TITLE)); + jTextArea1.setText(TranslationCategory.TIME_PICKER_DIALOG.getTranslation(TranslationKey.DESCRIPTION)); + daysSpinner.setToolTipText(TranslationCategory.TIME_PICKER_DIALOG.getTranslation(TranslationKey.SPINNER_TOOLTIP)); + hoursSpinner.setToolTipText(TranslationCategory.TIME_PICKER_DIALOG.getTranslation(TranslationKey.SPINNER_TOOLTIP)); + minutesSpinner.setToolTipText(TranslationCategory.TIME_PICKER_DIALOG.getTranslation(TranslationKey.SPINNER_TOOLTIP)); + btnOk.setText(TranslationCategory.TIME_PICKER_DIALOG.getTranslation(TranslationKey.OK_BUTTON)); + jButton2.setText(TranslationCategory.GENERAL.getTranslation(TranslationKey.CANCEL_BUTTON)); + jLabel1.setText(TranslationCategory.TIME_PICKER_DIALOG.getTranslation(TranslationKey.DAYS)); + jLabel2.setText(TranslationCategory.TIME_PICKER_DIALOG.getTranslation(TranslationKey.HOURS)); + jLabel3.setText(TranslationCategory.TIME_PICKER_DIALOG.getTranslation(TranslationKey.MINUTES)); } // Variables declaration - do not modify//GEN-BEGIN:variables diff --git a/src/main/java/com/mycompany/autobackupprogram/Backup.java b/src/main/java/com/mycompany/autobackupprogram/Entities/Backup.java similarity index 98% rename from src/main/java/com/mycompany/autobackupprogram/Backup.java rename to src/main/java/com/mycompany/autobackupprogram/Entities/Backup.java index f1fc903..9d06e08 100644 --- a/src/main/java/com/mycompany/autobackupprogram/Backup.java +++ b/src/main/java/com/mycompany/autobackupprogram/Entities/Backup.java @@ -1,7 +1,8 @@ -package com.mycompany.autobackupprogram; +package com.mycompany.autobackupprogram.Entities; import java.time.LocalDateTime; + public class Backup { private String _backupName; diff --git a/src/main/java/com/mycompany/autobackupprogram/Entities/Preferences.java b/src/main/java/com/mycompany/autobackupprogram/Entities/Preferences.java new file mode 100644 index 0000000..30fa9b4 --- /dev/null +++ b/src/main/java/com/mycompany/autobackupprogram/Entities/Preferences.java @@ -0,0 +1,113 @@ +package com.mycompany.autobackupprogram.Entities; + +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.mycompany.autobackupprogram.Logger; +import com.mycompany.autobackupprogram.Logger.LogLevel; +import com.mycompany.autobackupprogram.Enums.ConfigKey; +import com.mycompany.autobackupprogram.Enums.LanguagesEnum; +import com.mycompany.autobackupprogram.Enums.ThemesEnum; + +public class Preferences { + private static LanguagesEnum language = LanguagesEnum.ENG; + private static ThemesEnum theme = ThemesEnum.INTELLIJ; + + public static void loadPreferencesFromJSON() { + try (FileReader reader = new FileReader(ConfigKey.CONFIG_DIRECTORY_STRING.getValue() + ConfigKey.PREFERENCES_FILE_STRING.getValue())) { + JsonElement jsonElement = JsonParser.parseReader(reader); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + + // Map the "Language" JSON value to the LanguagesEnum + String languageFileName = jsonObject.get("Language").getAsString(); + for (LanguagesEnum lang : LanguagesEnum.values()) { + if (lang.getFileName().equals(languageFileName)) { + language = lang; + break; + } + } + + // Map the "Theme" JSON value to the ThemesEnum + String themeName = jsonObject.get("Theme").getAsString(); + for (ThemesEnum t : ThemesEnum.values()) { + if (t.getThemeName().equals(themeName)) { + theme = t; + break; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void updatePreferencesToJSON() { + try (FileWriter writer = new FileWriter(ConfigKey.CONFIG_DIRECTORY_STRING.getValue() + ConfigKey.PREFERENCES_FILE_STRING.getValue())) { + JsonObject jsonObject = new JsonObject(); + + jsonObject.addProperty("Language", language.getFileName()); + jsonObject.addProperty("Theme", theme.getThemeName()); + + // Convert JsonObject to JSON string using Gson + Gson gson = new Gson(); + gson.toJson(jsonObject, writer); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static LanguagesEnum getLanguage() { + return language; + } + public static ThemesEnum getTheme() { + return theme; + } + public static void setLanguage(LanguagesEnum language) { + Preferences.language = language; + } + public static void setTheme(ThemesEnum theme) { + Preferences.theme = theme; + } + public static void setLanguage(String selectedLanguage) { + try { + for (LanguagesEnum lang : LanguagesEnum.values()) { + if (lang.getLanguageName().equalsIgnoreCase(selectedLanguage)) { + language = lang; + Logger.logMessage("Language set to: " + language.getLanguageName(), LogLevel.INFO); + return; + } + } + Logger.logMessage("Invalid language name: " + selectedLanguage, LogLevel.ERROR); + } catch (Exception e) { + e.printStackTrace(); + } + } + public static void setTheme(String selectedTheme) { + try { + for (ThemesEnum t : ThemesEnum.values()) { + if (t.getThemeName().equalsIgnoreCase(selectedTheme)) { + theme = t; + Logger.logMessage("Theme set to: " + theme.getThemeName(), LogLevel.INFO); + return; + } + } + Logger.logMessage("Invalid theme name: " + selectedTheme, LogLevel.ERROR); + } catch (Exception e) { + e.printStackTrace(); + } + } + + // for test + public static void main(String[] args) { + String CONFIG = "src/main/resources/res/config/config.json"; + ConfigKey.loadFromJson(CONFIG); + loadPreferencesFromJSON(); + updatePreferencesToJSON(); + } + +} diff --git a/src/main/java/com/mycompany/autobackupprogram/TimeInterval.java b/src/main/java/com/mycompany/autobackupprogram/Entities/TimeInterval.java similarity index 98% rename from src/main/java/com/mycompany/autobackupprogram/TimeInterval.java rename to src/main/java/com/mycompany/autobackupprogram/Entities/TimeInterval.java index 62ea30a..1ffa3b9 100644 --- a/src/main/java/com/mycompany/autobackupprogram/TimeInterval.java +++ b/src/main/java/com/mycompany/autobackupprogram/Entities/TimeInterval.java @@ -1,4 +1,4 @@ -package com.mycompany.autobackupprogram; +package com.mycompany.autobackupprogram.Entities; public class TimeInterval { private int days; diff --git a/src/main/java/com/mycompany/autobackupprogram/ConfigKey.java b/src/main/java/com/mycompany/autobackupprogram/Enums/ConfigKey.java similarity index 89% rename from src/main/java/com/mycompany/autobackupprogram/ConfigKey.java rename to src/main/java/com/mycompany/autobackupprogram/Enums/ConfigKey.java index 1b7185f..3a53b85 100644 --- a/src/main/java/com/mycompany/autobackupprogram/ConfigKey.java +++ b/src/main/java/com/mycompany/autobackupprogram/Enums/ConfigKey.java @@ -1,4 +1,4 @@ -package com.mycompany.autobackupprogram; +package com.mycompany.autobackupprogram.Enums; import java.io.FileReader; import java.io.IOException; @@ -12,7 +12,10 @@ public enum ConfigKey { LOG_FILE_STRING, BACKUP_FILE_STRING, CONFIG_FILE_STRING, + PREFERENCES_FILE_STRING, RES_DIRECTORY_STRING, + LANGUAGES_DIRECTORY_STRING, + CONFIG_DIRECTORY_STRING, DONATE_PAGE_LINK, ISSUE_PAGE_LINK, INFO_PAGE_LINK, diff --git a/src/main/java/com/mycompany/autobackupprogram/Enums/LanguagesEnum.java b/src/main/java/com/mycompany/autobackupprogram/Enums/LanguagesEnum.java new file mode 100644 index 0000000..5386edd --- /dev/null +++ b/src/main/java/com/mycompany/autobackupprogram/Enums/LanguagesEnum.java @@ -0,0 +1,25 @@ +package com.mycompany.autobackupprogram.Enums; + +public enum LanguagesEnum { + ITA("Italiano", "ita.json"), + ENG("English", "eng.json"), + DEU("Deutsch", "deu.json"), + ESP("Español", "esp.json"), + FRA("Français", "fra.json"); + + private final String languageName; + private final String fileName; + + LanguagesEnum(String languageName, String fileName) { + this.languageName = languageName; + this.fileName = fileName; + } + + public String getLanguageName() { + return languageName; + } + + public String getFileName() { + return fileName; + } +} \ No newline at end of file diff --git a/src/main/java/com/mycompany/autobackupprogram/MenuItems.java b/src/main/java/com/mycompany/autobackupprogram/Enums/MenuItems.java similarity index 73% rename from src/main/java/com/mycompany/autobackupprogram/MenuItems.java rename to src/main/java/com/mycompany/autobackupprogram/Enums/MenuItems.java index c325e78..2ea6bc0 100644 --- a/src/main/java/com/mycompany/autobackupprogram/MenuItems.java +++ b/src/main/java/com/mycompany/autobackupprogram/Enums/MenuItems.java @@ -1,7 +1,8 @@ -package com.mycompany.autobackupprogram; +package com.mycompany.autobackupprogram.Enums; public enum MenuItems { BugReport, + Preferences, Clear, Donate, History, diff --git a/src/main/java/com/mycompany/autobackupprogram/Enums/ThemesEnum.java b/src/main/java/com/mycompany/autobackupprogram/Enums/ThemesEnum.java new file mode 100644 index 0000000..3a3ba27 --- /dev/null +++ b/src/main/java/com/mycompany/autobackupprogram/Enums/ThemesEnum.java @@ -0,0 +1,24 @@ +package com.mycompany.autobackupprogram.Enums; + +public enum ThemesEnum { + INTELLIJ("Light"), + DRACULA("Dark"), + CARBON("Carbon"), + ARC_ORAGE("Arc - Orange"), + ARC_DARK_ORANGE("Arc Dark - Orange"), + CYAN_LIGHT("Cyan light"), + NORD("Nord"), + HIGH_CONTRAST("High contrast"), + SOLARIZED_DARK("Solarized dark"), + SOLARIZED_LIGHT("Solarized light"); + + private final String themeName; + + ThemesEnum(String themeName) { + this.themeName = themeName; + } + + public String getThemeName() { + return themeName; + } +} \ No newline at end of file diff --git a/src/main/java/com/mycompany/autobackupprogram/Enums/TranslationLoaderEnum.java b/src/main/java/com/mycompany/autobackupprogram/Enums/TranslationLoaderEnum.java new file mode 100644 index 0000000..6a0a9e8 --- /dev/null +++ b/src/main/java/com/mycompany/autobackupprogram/Enums/TranslationLoaderEnum.java @@ -0,0 +1,296 @@ +package com.mycompany.autobackupprogram.Enums; + +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class TranslationLoaderEnum { + + public enum TranslationCategory { + GENERAL("General"), + MENU("Menu"), + TABBED_FRAMES("TabbedFrames"), + BACKUP_ENTRY("BackupEntry"), + BACKUP_LIST("BackupList"), + TIME_PICKER_DIALOG("TimePickerDialog"), + PREFERENCES_DIALOG("PreferencesDialog"), + PROGRESS_BACKUP_FRAME("ProgressBackupFrame"), + TRAY_ICON("TrayIcon"), + DIALOGS("Dialogs"); + + private final String categoryName; + private final Map translations = new HashMap<>(); + + TranslationCategory(String categoryName) { + this.categoryName = categoryName; + } + + public String getCategoryName() { + return categoryName; + } + + public void addTranslation(TranslationKey key, String value) { + translations.put(key, value); + } + + // Updated getTranslation method + public String getTranslation(TranslationKey key) { + return translations.getOrDefault(key, key.getDefaultValue()); + } + } + + public enum TranslationKey { + // General + APP_NAME("AppName", "Backup Manager"), + VERSION("Version", "Version"), + BACKUP("Backup", "Backup"), + FROM("From", "From"), + TO("To", "To"), + CLOSE_BUTTON("CloseButton", "Close"), + OK_BUTTON("OkButton", "Ok"), + CANCEL_BUTTON("CancelButton", "Cancel"), + APPLY_BUTTON("ApplyButton", "Apply"), + + // Menu + FILE("File", "File"), + OPTIONS("Options", "Options"), + ABOUT("About", "About"), + HELP("Help", "Help"), + BUG_REPORT("BugReport", "Report a bug"), + CLEAR("Clear", "Clear"), + DONATE("Donate", "Donate"), + HISTORY("History", "History"), + INFO_PAGE("InfoPage", "Info"), + NEW("New", "New"), + QUIT("Quit", "Quit"), + SAVE("Save", "Save"), + SAVE_WITH_NAME("SaveWithName", "Save with name"), + SHARE("Share", "Share"), + SUPPORT("Support", "Support"), + WEBSITE("Website", "Website"), + + // TabbedFrames + BACKUP_ENTRY("BackupEntry", "Backup Entry"), + BACKUP_LIST("BackupList", "Backup List"), + + // BackupEntry + PAGE_TITLE("PageTitle", "Backup Entry"), + CURRENT_FILE("CurrentFile", "Current file"), + NOTES("Notes", "Notes"), + LAST_BACKUP("LastBackup", "Last backup"), + SINGLE_BACKUP_BUTTON("SingleBackupButton", "Single Backup"), + AUTO_BACKUP_BUTTON("AutoBackupButton", "Auto Backup"), + AUTO_BACKUP_BUTTON_ON("AutoBackupButtonON", "Auto Backup (ON)"), + AUTO_BACKUP_BUTTON_OFF("AutoBackupButtonOFF", "Auto Backup (OFF)"), + INITIAL_PATH_PLACEHOLDER("InitialPathPlaceholder", "Initial path"), + DESTINATION_PATH_PLACEHOLDER("DestinationPathPlaceholder", "Destination path"), + INITIAL_PATH_TOOLTIP("InitialPathTooltip", "(Required) Initial path"), + DESTINATION_PATH_TOOLTIP("DestinationPathTooltip", "(Required) Destination path"), + INITIAL_FILE_CHOOSER_TOOLTIP("InitialFileChooserTooltip", "Open file explorer"), + DESTINATION_FILE_CHOOSER_TOOLTIP("DestinationFileChooserTooltip", "Open file explorer"), + NOTES_TOOLTIP("NotesTooltip", "(Optional) Backup description"), + SINGLE_BACKUP_TOOLTIP("SingleBackupTooltip", "Perform the backup"), + AUTO_BACKUP_TOOLTIP("AutoBackupTooltip", "Enable/Disable automatic backup"), + TIME_PICKER_TOOLTIP("TimePickerTooltip", "Time picker"), + + // BackupList + BACKUP_NAME_COLUMN("BackupNameColumn", "Backup Name"), + INITIAL_PATH_COLUMN("InitialPathColumn", "Initial Path"), + DESTINATION_PATH_COLUMN("DestinationPathColumn", "Destination Path"), + LAST_BACKUP_COLUMN("LastBackupColumn", "Last Backup"), + AUTOMATIC_BACKUP_COLUMN("AutomaticBackupColumn", "Automatic Backup"), + NEXT_BACKUP_DATE_COLUMN("NextBackupDateColumn", "Next Backup Date"), + TIME_INTERVAL_COLUMN("TimeIntervalColumn", "Time Interval"), + BACKUP_NAME_DETAIL("BackupNameDetail", "BackupName"), + INITIAL_PATH_DETAIL("InitialPathDetail", "InitialPath"), + DESTINATION_PATH_DETAIL("DestinationPathDetail", "DestinationPath"), + LAST_BACKUP_DETAIL("LastBackupDetail", "LastBackup"), + NEXT_BACKUP_DATE_DETAIL("NextBackupDateDetail", "NextBackup"), + TIME_INTERVAL_DETAIL("TimeIntervalDetail", "TimeInterval"), + CREATION_DATE_DETAIL("CreationDateDetail", "CreationDate"), + LAST_UPDATE_DATE_DETAIL("LastUpdateDateDetail", "LastUpdateDate"), + BACKUP_COUNT_DETAIL("BackupCountDetail", "BackupCount"), + NOTES_DETAIL("NotesDetail", "Notes"), + ADD_BACKUP_TOOLTIP("AddBackupTooltip", "Add new backup"), + RESEARCH_BAR_TOOLTIP("ResearchBarTooltip", "Research bar"), + RESEARCH_BAR_PLACEHOLDER("ResearchBarPlaceholder", "Search..."), + EDIT_POPUP("EditPopup", "Edit"), + DELETE_POPUP("DeletePopup", "Delete"), + DUPLICATE_POPUP("DuplicatePopup", "Duplicate"), + RENAME_BACKUP_POPUP("RenameBackupPopup", "Rename backup"), + OPEN_INITIAL_FOLDER_POPUP("OpenInitialFolderPopup", "Open initial path"), + OPEN_DESTINATION_FOLDER_POPUP("OpenDestinationFolderPopup", "Open destination path"), + BACKUP_POPUP("BackupPopup", "Backup"), + SINGLE_BACKUP_POPUP("SingleBackupPopup", "Run single backup"), + AUTO_BACKUP_POPUP("AutoBackupPopup", "Auto backup"), + COPY_TEXT_POPUP("CopyTextPopup", "Copy text"), + COPY_BACKUP_NAME_POPUP("CopyBackupNamePopup", "Copy backup name"), + COPY_INITIAL_PATH_POPUP("CopyInitialPathPopup", "Copy initial path"), + COPY_DESTINATION_PATH_BACKUP("CopyDestinationPathPopup", "Copy destination path"), + + // TimePickerDialog + TIME_INTERVAL_TITLE("TimeIntervalTitle", "Time interval for auto backup"), + DESCRIPTION("Description", "Select how often to perform the automatic backup by choosing the frequency in days, hours, and minutes."), + DAYS("Days", "Days"), + HOURS("Hours", "Hours"), + MINUTES("Minutes", "Minutes"), + SPINNER_TOOLTIP("SpinnerTooltip", "Mouse wheel to adjust the value"), + + // PreferencesDialog + PREFERENCES_TITLE("PreferencesTitle", "Preferences"), + LANGUAGE("Language", "Language"), + THEME("Theme", "Theme"), + + // ProgressBackupFrame + PROGRESS_BACKUP_TITLE("ProgressBackupTitle", "Backup in progress"), + STATUS_COMPLETED("StatusCompleted", "Backup completed!"), + STATUS_LOADING("StatusLoading", "Loading..."), + + // TrayIcon + TRAY_TOOLTIP("TrayTooltip", "Backup Service"), + SUCCESS_MESSAGE("SuccessMessage", "\nThe backup was successfully completed:"), + ERROR_MESSAGE_INPUT_MISSING("ErrorMessageInputMissing", "\nError during automatic backup.\nInput Missing!"), + ERROR_MESSAGE_FILES_NOT_EXISTING("ErrorMessageFilesNotExisting", "\nError during automatic backup.\nOne or both paths do not exist!"), + ERROR_MESSAGE_SAME_PATHS("ErrorMessageSamePaths", "\nError during automatic backup.\nThe initial path and destination path cannot be the same. Please choose different paths!"), + + // Dialogs + ERROR_GENERIC_TITLE("ErrorGenericTitle", "Error"), + ERROR_MESSAGE_FOR_FOLDER_NOT_EXISTING("ErrorMessageForFolderNotExisting", "The folder does not exist or is invalid"), + ERROR_MESSAGE_FOR_SAVING_FILE_WITH_PATHS_EMPTY("ErrorMessageForSavingFileWithPathsEmpty", "Unable to save the file. Both the initial and destination paths must be specified and cannot be empty"), + BACKUP_SAVED_CORRECTLY_TITLE("BackupSavedCorrectlyTitle", "Backup saved"), + BACKUP_SAVED_CORRECTLY_MESSAGE("BackupSavedCorrectlyMessage", "saved successfully!"), + ERROR_SAVING_BACKUP_MESSAGE("ErrorSavingBackupMessage", "Error saving backup"), + BACKUP_NAME_INPUT("BackupNameInput", "Name of the backup"), + CONFIRMATION_REQUIRED_TITLE("ConfirmationRequiredTitle", "Confirmation required"), + DUPLICATED_BACKUP_NAME_MESSAGE("DuplicatedBackupNameMessage", "A backup with the same name already exists, do you want to overwrite it?"), + BACKUP_NAME_ALREADY_USED_MESSAGE("BackupNameAlreadyUsedMessage", "Backup name already used!"), + ERROR_MESSAGE_FOR_INCORRECT_INITIAL_PATH("ErrorMessageForIncorrectInitialPath", "Error during the backup operation: the initial path is incorrect!"), + EXCEPTION_MESSAGE_TITLE("ExceptionMessageTitle", "Error..."), + EXCEPTION_MESSAGE_CLIPBOARD_MESSAGE("ExceptionMessageClipboardMessage", "Error text has been copied to the clipboard."), + EXCEPTION_MESSAGE_CLIPBOARD_BUTTON("ExceptionMessageClipboardButton", "Copy to clipboard"), + EXCEPTION_MESSAGE_REPORT_BUTTON("ExceptionMessageReportButton", "Report the Problem"), + EXCEPTION_MESSAGE_REPORT_MESSAGE("ExceptionMessageReportMessage", "Please report this error, either with an image of the screen or by copying the following error text (it is appreciable to provide a description of the operations performed before the error):"), + ERROR_MESSAGE_OPENING_WEBSITE("ErrorMessageOpeningWebsite", "Failed to open the web page. Please try again."), + CONFIRMATION_MESSAGE_FOR_CLEAR("ConfirmationMessageForClear", "Are you sure you want to clean the fields?"), + CONFIRMATION_MESSAGE_FOR_UNSAVED_CHANGES("ConfirmationMessageForUnsavedChanges", "There are unsaved changes, do you want to save them before moving to another backup?"), + ERROR_MESSAGE_OPEN_HISTORY_FILE("ErrorMessageOpenHistoryFile", "Error opening history file."), + CONFIRMATION_MESSAGE_BEFORE_DELETE_BACKUP("ConfirmationMessageBeforeDeleteBackup", "Are you sure you want to delete this item? Please note, this action cannot be undone"), + SHARE_LINK_COPIED_MESSAGE("ShareLinkCopiedMessage", "Share link copied to clipboard!"), + CONFIRMATION_MESSAGE_CANCEL_AUTO_BACKUP("ConfirmationMessageCancelAutoBackup", "Are you sure you want to cancel automatic backups for this entry?"), + CONFIRMATION_MESSAGE_CANCEL_SINGLE_BACKUP("ConfirmationMessageCancelSingleBackup", "Are you sure you want to cancel this backup?"), + CONFIRMATION_MESSAGE_BEFORE_EXIT("ConfirmationMessageBeforeExit", "Are you sure you want to exit?"), + ERROR_MESSAGE_UNEXPECTED("ErrorMessageUnexpected", "An unexpected error has occurred!"), + ERROR_MESSAGE_PATHS_CANNOT_BE_SAME("ErrorMessagePathsCannotBeSame", "The initial path and destination path cannot be the same!"), + ERROR_MESSAGE_PATHS_ARE_EMPTY("ErrorMessagePathsAreEmpty", "The initial path and destination path cannot be empty!"), + ERROR_MESSAGE_INVALID_PATH("ErrorMessageInvalidPath", "The selected path is invalid!"), + ERROR_MESSAGE_NOT_SUPPORTED_EMAIL("ErrorMessageNotSupportedEmail", "Your system does not support sending emails directly from this application."), + ERROR_MESSAGE_NOT_SUPPORTED_EMAIL_GENERIC("ErrorMessageNotSupportedEmailGeneric", "Your system does not support sending emails."), + ERROR_WRONG_TIME_INTERVAL("ErrorWrongTimeInterval", "The time interval is not correct"), + AUTO_BACKUP_ACTIVATED_MESSAGE("AutoBackupActivatedMessage", "Auto Backup has been activated"), + SETTED_EVERY_MESSAGE("SettedEveryMessage", "\nIs setted every"), + DAYS_MESSAGE("DaysMessage", " days"), + ERROR_MESSAGE_UNABLE_TO_SEND_EMAIL("ErrorMessageUnableToSendEmail", "Unable to send email. Please try again later."), + INTERRUPT_BACKUP_PROCESS_MESSAGE("InterruptBackupProcessMessage", "Are you sure you want to stop this backup?"), + ERROR_MESSAGE_INPUT_MISSING_GENERIC("ErrorMessageInputMissingGeneric", "Input Missing!"), + ERROR_MESSAGE_SAVING_FILE("ErrorMessageForSavingFile", "Error saving file"), + ERROR_MESSAGE_PATH_NOT_EXISTING("ErrorMessageForPathNotExisting", "One or both paths do not exist!"), + ERROR_MESSAGE_SAME_PATHS_GENERIC("ErrorMessageForSamePaths", "The initial path and destination path cannot be the same. Please choose different paths!"), + + // InfoPage + INFO_PAGE_DESCRIPTION("InfoPageDescription", "Backup automatic system for files with the option to schedule and make backups regularly."), + INFO_PAGE_FEATURES_TITLE("InfoPageFeaturesTitle", "Features"), + INFO_PAGE_FEATURES_DESCRIPTION("InfoPageFeaturesDescription", "Backup files quickly and easily with automatic scheduling and periodic backups"), + INFO_PAGE_BUTTON_TITLE("InfoPageButtonTitle", "OK"), + INFO_PAGE_VERSION("InfoPageVersion", "Version: "), + INFO_PAGE_DEVELOPER("InfoPageDeveloper", "Developer: "), + INFO_PAGE_CREDITS("InfoPageCredits", "Credits"), + INFO_PAGE_LICENSE("InfoPageLicense", "License"); + + private final String keyName; + private final String defaultValue; + + private static final Map lookup = new HashMap<>(); + + static { + for (TranslationKey key : TranslationKey.values()) { + lookup.put(key.keyName, key); + } + } + + // Constructor to assign both key and default value + TranslationKey(String keyName, String defaultValue) { + this.keyName = keyName; + this.defaultValue = defaultValue; + } + + public String getKeyName() { + return keyName; + } + + public String getDefaultValue() { + return defaultValue; + } + + // Lookup by keyName (JSON key) + public static TranslationKey fromKeyName(String keyName) { + return lookup.get(keyName); + } + + @Override + public String toString() { + return keyName; + } + } + + public static void loadTranslations(String filePath) throws IOException, ParseException { + JSONParser parser = new JSONParser(); + + try (FileReader reader = new FileReader(filePath)) { + JSONObject jsonObject = (JSONObject) parser.parse(reader); + + for (TranslationCategory category : TranslationCategory.values()) { + JSONObject categoryTranslations = (JSONObject) jsonObject.get(category.getCategoryName()); + + if (categoryTranslations != null) { + for (Object keyObj : categoryTranslations.keySet()) { + String key = (String) keyObj; + String value = (String) categoryTranslations.get(key); + + // Use fromKeyName to get the TranslationKey from the JSON key + TranslationKey translationKey = TranslationKey.fromKeyName(key); + if (translationKey != null) { + // If value is null or empty, fall back to the default value from the enum + String translationValue = (value != null && !value.isEmpty()) ? value : translationKey.getDefaultValue(); + category.addTranslation(translationKey, translationValue); + } else { + // If the key is not recognized in the enum, log it and use the default value + System.err.println("Warning: Unrecognized key in JSON: " + key + ", using default value."); + category.addTranslation(translationKey, translationKey.getDefaultValue()); + } + } + } + } + } + } + + public static String getTranslation(TranslationCategory category, TranslationKey key) { + return category.translations.getOrDefault(key, key.getDefaultValue()); // Use default value if not found + } + + // only for test + public static void main(String[] args) { + try { + loadTranslations("src/main/resources/res/languages/ita.json"); + + System.out.println(TranslationCategory.MENU.getTranslation(TranslationKey.FILE)); + System.out.println(TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_GENERIC_TITLE)); + + } catch (IOException | ParseException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/mycompany/autobackupprogram/BackupManagerGUI.form b/src/main/java/com/mycompany/autobackupprogram/GUI/BackupManagerGUI.form similarity index 97% rename from src/main/java/com/mycompany/autobackupprogram/BackupManagerGUI.form rename to src/main/java/com/mycompany/autobackupprogram/GUI/BackupManagerGUI.form index 9882f6e..9245087 100644 --- a/src/main/java/com/mycompany/autobackupprogram/BackupManagerGUI.form +++ b/src/main/java/com/mycompany/autobackupprogram/GUI/BackupManagerGUI.form @@ -165,6 +165,9 @@ + + + @@ -203,15 +206,15 @@ - + - + - + - + @@ -235,6 +238,28 @@ + + + + + + + + + + + + + + + + + + + + + + @@ -257,17 +282,6 @@ - - - - - - - - - - - @@ -275,15 +289,15 @@ - + - + - + - + @@ -328,10 +342,10 @@ - - - - + + + + @@ -339,9 +353,9 @@ - + - + diff --git a/src/main/java/com/mycompany/autobackupprogram/BackupManagerGUI.java b/src/main/java/com/mycompany/autobackupprogram/GUI/BackupManagerGUI.java similarity index 80% rename from src/main/java/com/mycompany/autobackupprogram/BackupManagerGUI.java rename to src/main/java/com/mycompany/autobackupprogram/GUI/BackupManagerGUI.java index 96ae520..71e831d 100644 --- a/src/main/java/com/mycompany/autobackupprogram/BackupManagerGUI.java +++ b/src/main/java/com/mycompany/autobackupprogram/GUI/BackupManagerGUI.java @@ -1,7 +1,22 @@ -package com.mycompany.autobackupprogram; +package com.mycompany.autobackupprogram.GUI; +import com.mycompany.autobackupprogram.Entities.TimeInterval; import com.formdev.flatlaf.FlatClientProperties; -import com.formdev.flatlaf.FlatIntelliJLaf; +import com.mycompany.autobackupprogram.BackupOperations; +import com.mycompany.autobackupprogram.Dialogs.PreferencesDialog; +import com.mycompany.autobackupprogram.JSONAutoBackup; +import com.mycompany.autobackupprogram.JSONConfigReader; +import com.mycompany.autobackupprogram.Logger; +import com.mycompany.autobackupprogram.Dialogs.TimePicker; +import com.mycompany.autobackupprogram.Entities.Backup; +import com.mycompany.autobackupprogram.Entities.Preferences; +import com.mycompany.autobackupprogram.Enums.ConfigKey; +import com.mycompany.autobackupprogram.Enums.MenuItems; +import com.mycompany.autobackupprogram.Enums.TranslationLoaderEnum; +import com.mycompany.autobackupprogram.Enums.TranslationLoaderEnum.TranslationCategory; +import com.mycompany.autobackupprogram.Enums.TranslationLoaderEnum.TranslationKey; +import com.mycompany.autobackupprogram.Managers.ThemeManager; + import java.awt.Color; import java.awt.Component; import java.awt.Desktop; @@ -29,13 +44,14 @@ import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.SwingUtilities; -import javax.swing.UIManager; -import javax.swing.UnsupportedLookAndFeelException; import javax.swing.filechooser.FileSystemView; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumnModel; + +import org.json.simple.parser.ParseException; + import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; @@ -56,13 +72,13 @@ public class BackupManagerGUI extends javax.swing.JFrame { private boolean saveChanged; private Integer selectedRow; - private String backupOnText = "Auto Backup (ON)"; - private String backupOffText = "Auto Backup (OFF)"; + private String backupOnText; + private String backupOffText; + + private final String current_version = "2.0.3"; public BackupManagerGUI() { - try { - UIManager.setLookAndFeel(new FlatIntelliJLaf()); - } catch (UnsupportedLookAndFeelException ex) {} + ThemeManager.updateThemeFrame(this); initComponents(); @@ -75,15 +91,6 @@ public BackupManagerGUI() { saveChanged = true; toggleAutoBackup.setText(toggleAutoBackup.isSelected() ? backupOnText : backupOffText); - - try { - backups = JSON.ReadBackupListFromJSON(ConfigKey.BACKUP_FILE_STRING.getValue(), ConfigKey.RES_DIRECTORY_STRING.getValue()); - displayBackupList(backups); - } catch (IOException ex) { - backups = null; - Logger.logMessage("An error occurred: " + ex.getMessage(), Logger.LogLevel.ERROR, ex); - OpenExceptionMessage(ex.getMessage(), Arrays.toString(ex.getStackTrace())); - } File file = new File(System.getProperty("os.name").toLowerCase().contains("win") ? "C:\\Windows\\System32" : "/root"); if (file.canWrite()) { @@ -95,8 +102,9 @@ public BackupManagerGUI() { customListeners(); // load Menu items - JSONConfigReader config = new JSONConfigReader(ConfigKey.CONFIG_FILE_STRING.getValue(), ConfigKey.RES_DIRECTORY_STRING.getValue()); + JSONConfigReader config = new JSONConfigReader(ConfigKey.CONFIG_FILE_STRING.getValue(), ConfigKey.CONFIG_DIRECTORY_STRING.getValue()); MenuBugReport.setVisible(config.isMenuItemEnabled(MenuItems.BugReport.name())); + MenuPreferences.setVisible(config.isMenuItemEnabled(MenuItems.Preferences.name())); MenuClear.setVisible(config.isMenuItemEnabled(MenuItems.Clear.name())); MenuDonate.setVisible(config.isMenuItemEnabled(MenuItems.Donate.name())); MenuHistory.setVisible(config.isMenuItemEnabled(MenuItems.History.name())); @@ -109,13 +117,11 @@ public BackupManagerGUI() { MenuSupport.setVisible(config.isMenuItemEnabled(MenuItems.Support.name())); MenuWebsite.setVisible(config.isMenuItemEnabled(MenuItems.Website.name())); - // place holder - researchField.putClientProperty(FlatClientProperties.PLACEHOLDER_TEXT, "search..."); - startPathField.putClientProperty(FlatClientProperties.PLACEHOLDER_TEXT, "Initial path"); - destinationPathField.putClientProperty(FlatClientProperties.PLACEHOLDER_TEXT, "Destination path"); - // icons researchField.putClientProperty(FlatClientProperties.TEXT_FIELD_LEADING_ICON, new javax.swing.ImageIcon(getClass().getResource("/res/img/search.png"))); + + // translations + setTranslations(); } public void showWindow() { @@ -130,6 +136,32 @@ private TimeInterval openTimePicker(TimeInterval time) { return picker.getTimeInterval(); } + private void openPreferences() { + PreferencesDialog prefs = new PreferencesDialog(this, true); + prefs.setVisible(true); + + // reload preferences + if (prefs.isApply()) { + Preferences.updatePreferencesToJSON(); + reloadPreferences(); + } + + } + + private void reloadPreferences() { + // load language + try { + TranslationLoaderEnum.loadTranslations(ConfigKey.LANGUAGES_DIRECTORY_STRING.getValue() + Preferences.getLanguage().getFileName()); + setTranslations(); + } catch (IOException | ParseException e) { + e.printStackTrace(); + } + + // load theme + ThemeManager.updateThemeFrame(this); + ThemeManager.refreshPopup(TablePopup); + } + private void renameBackup(Backup backup) { Logger.logMessage("Event --> backup renaming", Logger.LogLevel.INFO); @@ -165,7 +197,8 @@ private void OpenFolder(String path) { } } else { Logger.logMessage("The folder does not exist or is invalid", Logger.LogLevel.WARN); - JOptionPane.showMessageDialog(null, "The folder does not exist or is invalid", "Error", JOptionPane.ERROR_MESSAGE); + + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_MESSAGE_FOR_FOLDER_NOT_EXISTING), TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_GENERIC_TITLE), JOptionPane.ERROR_MESSAGE); } } @@ -225,7 +258,8 @@ public boolean AutomaticBackup() { btnTimePicker.setEnabled(true); Logger.logMessage("Event --> Next date backup setted to " + nextDateBackup, Logger.LogLevel.INFO); - JOptionPane.showMessageDialog(null, "Auto Backup has been activated\n\tFrom: " + startPathField.getText() + "\n\tTo: " + destinationPathField.getText() + "\nIs setted every " + timeInterval.toString() + " days", "AutoBackup", 1); + + openBackupActivationMessage(timeInterval); } currentBackup.setInitialPath(GetStartPathField()); @@ -265,7 +299,8 @@ public boolean AutomaticBackup(Backup backup) { btnTimePicker.setEnabled(true); Logger.logMessage("Event --> Next date backup setted to " + nextDateBackup, Logger.LogLevel.INFO); - JOptionPane.showMessageDialog(null, "Auto Backup has been activated\n\tFrom: " + backup.getInitialPath() + "\n\tTo: " + backup.getDestinationPath() + "\nIs setted every " + timeInterval.toString() + " days", "AutoBackup", 1); + + openBackupActivationMessage(timeInterval); } for (Backup b : backups) { @@ -282,13 +317,29 @@ public boolean AutomaticBackup(Backup backup) { BackupOperations.updateBackupList(backups); return true; } + + private void openBackupActivationMessage(TimeInterval timeInterval) { + if (timeInterval == null) + throw new IllegalArgumentException("Time interval cannot be null"); + + String from = TranslationCategory.GENERAL.getTranslation(TranslationKey.FROM); + String to = TranslationCategory.GENERAL.getTranslation(TranslationKey.TO); + String activated = TranslationCategory.DIALOGS.getTranslation(TranslationKey.AUTO_BACKUP_ACTIVATED_MESSAGE); + String setted = TranslationCategory.DIALOGS.getTranslation(TranslationKey.SETTED_EVERY_MESSAGE); + String days = TranslationCategory.DIALOGS.getTranslation(TranslationKey.DAYS_MESSAGE); + + JOptionPane.showMessageDialog(null, + activated + "\n\t" + from + ": " + startPathField.getText() + "\n\t" + to + ": " + + destinationPathField.getText() + setted + " " + timeInterval.toString() + days, + "AutoBackup", 1); + } private void SaveWithName() { Logger.logMessage("Event --> save with name", Logger.LogLevel.INFO); if (startPathField.getText().length() == 0 || destinationPathField.getText().length() == 0) { - Logger.logMessage("Unable to save the file. Both the initial and destination paths must be specified and cannot be empty", Logger.LogLevel.WARN); - JOptionPane.showMessageDialog(null, "Unable to save the file. Both the initial and destination paths must be specified and cannot be empty", "Error", JOptionPane.ERROR_MESSAGE); + Logger.logMessage("Unable to save the file. Both the initial and destination paths must be specified and cannot be empty", Logger.LogLevel.WARN); + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_MESSAGE_FOR_SAVING_FILE_WITH_PATHS_EMPTY), TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_GENERIC_TITLE), JOptionPane.ERROR_MESSAGE); return; } @@ -317,24 +368,25 @@ private void SaveWithName() { BackupOperations.updateBackupList(backups); Logger.logMessage("Backup '" + currentBackup.getBackupName() + "' saved successfully!", Logger.LogLevel.INFO); - JOptionPane.showMessageDialog(this, "Backup '" + currentBackup.getBackupName() + "' saved successfully!", "Backup saved", JOptionPane.INFORMATION_MESSAGE); + JOptionPane.showMessageDialog(this, "Backup '" + currentBackup.getBackupName() + "' " + TranslationCategory.DIALOGS.getTranslation(TranslationKey.BACKUP_SAVED_CORRECTLY_MESSAGE), TranslationCategory.DIALOGS.getTranslation(TranslationKey.BACKUP_SAVED_CORRECTLY_TITLE), JOptionPane.INFORMATION_MESSAGE); savedChanges(true); } catch (IllegalArgumentException ex) { Logger.logMessage("An error occurred: " + ex.getMessage(), Logger.LogLevel.ERROR, ex); OpenExceptionMessage(ex.getMessage(), Arrays.toString(ex.getStackTrace())); } catch (HeadlessException ex) { Logger.logMessage("Error saving backup", Logger.LogLevel.WARN); - JOptionPane.showMessageDialog(null, "Error saving backup", "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_SAVING_BACKUP_MESSAGE), TranslationCategory.GENERAL.getTranslation(TranslationKey.ERROR_GENERIC_TITLE), JOptionPane.ERROR_MESSAGE); } } private String getBackupName(boolean canOverwrite) { String backup_name; do { - backup_name = JOptionPane.showInputDialog(null, "Name of the backup"); // pop-up message + + backup_name = JOptionPane.showInputDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.BACKUP_NAME_INPUT)); // pop-up message for (Backup backup : backups) { if (backup.getBackupName().equals(backup_name) && canOverwrite) { - int response = JOptionPane.showConfirmDialog(null, "A backup with the same name already exists, do you want to overwrite it?", "Confimation required", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); + int response = JOptionPane.showConfirmDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.DUPLICATED_BACKUP_NAME_MESSAGE), TranslationCategory.DIALOGS.getTranslation(TranslationKey.CONFIRMATION_REQUIRED_TITLE), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); if (response == JOptionPane.YES_OPTION) { backups.remove(backup); break; @@ -343,7 +395,7 @@ private String getBackupName(boolean canOverwrite) { } } else if (backup.getBackupName().equals(backup_name)) { Logger.logMessage("Error saving backup", Logger.LogLevel.WARN); - JOptionPane.showConfirmDialog(null, "Backup name already used!", "Error", JOptionPane.OK_OPTION, JOptionPane.ERROR_MESSAGE); + JOptionPane.showConfirmDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.BACKUP_NAME_ALREADY_USED_MESSAGE), TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_GENERIC_TITLE), JOptionPane.OK_OPTION, JOptionPane.ERROR_MESSAGE); } } if (backup_name == null) return null; @@ -399,12 +451,12 @@ public void SingleBackup(String path1, String path2) { } catch (IOException e) { Logger.logMessage("Error during the backup operation: the initial path is incorrect!", Logger.LogLevel.WARN); - JOptionPane.showMessageDialog(null, "Error during the backup operation: the initial path is incorrect!", "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_MESSAGE_FOR_INCORRECT_INITIAL_PATH), TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_GENERIC_TITLE), JOptionPane.ERROR_MESSAGE); } } private void setCurrentBackupName(String name) { - currentFileLabel.setText("Current File: " + name); + currentFileLabel.setText(TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.CURRENT_FILE) + ": " + name); } private void setCurrentBackupNotes(String notes) { @@ -414,7 +466,7 @@ private void setCurrentBackupNotes(String notes) { public void setStringToText() { try { String last_date = LocalDateTime.now().format(formatter); - lastBackupLabel.setText("last backup: " + last_date); + lastBackupLabel.setText(TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.LAST_BACKUP) + last_date); } catch(Exception ex) { Logger.logMessage("An error occurred: " + ex.getMessage(), Logger.LogLevel.ERROR, ex); OpenExceptionMessage(ex.getMessage(), Arrays.toString(ex.getStackTrace())); @@ -493,20 +545,20 @@ public void SetDestinationPathField(String text) { public void SetLastBackupLabel(LocalDateTime date) { if (date != null) { String dateStr = date.format(formatter); - dateStr = "last backup: " + dateStr; + dateStr = TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.LAST_BACKUP) + ": " + dateStr; lastBackupLabel.setText(dateStr); } else lastBackupLabel.setText(""); } public static void OpenExceptionMessage(String errorMessage, String stackTrace) { - Object[] options = {"Close", "Copy to clipboard", "Report the Problem"}; + Object[] options = {TranslationCategory.GENERAL.getTranslation(TranslationKey.CLOSE_BUTTON), TranslationCategory.DIALOGS.getTranslation(TranslationKey.EXCEPTION_MESSAGE_CLIPBOARD_BUTTON), TranslationCategory.DIALOGS.getTranslation(TranslationKey.EXCEPTION_MESSAGE_REPORT_BUTTON)}; if (errorMessage == null) { errorMessage = ""; } stackTrace = !errorMessage.isEmpty() ? errorMessage + "\n" + stackTrace : errorMessage + stackTrace; - String stackTraceMessage = "Please report this error, either with an image of the screen or by copying the following error text (it is appreciable to provide a description of the operations performed before the error): \n" + stackTrace; + String stackTraceMessage = TranslationCategory.DIALOGS.getTranslation(TranslationKey.EXCEPTION_MESSAGE_REPORT_MESSAGE) + "\n" + stackTrace; int choice; @@ -535,13 +587,14 @@ public static void OpenExceptionMessage(String errorMessage, String stackTrace) scrollPane.setPreferredSize(new Dimension(MAX_WIDTH, 300)); // Display the option dialog with the JScrollPane + String error = TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_GENERIC_TITLE); choice = JOptionPane.showOptionDialog( null, scrollPane, // The JScrollPane containing the error message - "Error...", // The error message/title + error, // The error message/title JOptionPane.DEFAULT_OPTION, // Option type (default option type) JOptionPane.ERROR_MESSAGE, // Message type (error message icon) - null, // Icon (null means default icon) + null, // Icon (null means default icon) options, // The options for the buttons options[0] // The default option (Close) ); @@ -550,7 +603,7 @@ public static void OpenExceptionMessage(String errorMessage, String stackTrace) StringSelection selection = new StringSelection(stackTrace); Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, null); Logger.logMessage("Error text has been copied to the clipboard", Logger.LogLevel.INFO); - JOptionPane.showMessageDialog(null, "Error text has been copied to the clipboard."); + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.EXCEPTION_MESSAGE_CLIPBOARD_MESSAGE)); } else if (choice == 2) { openWebSite(ConfigKey.ISSUE_PAGE_LINK.getValue()); } @@ -567,12 +620,19 @@ private static void openWebSite(String reportUrl) { } } catch (IOException | URISyntaxException e) { Logger.logMessage("Failed to open the web page. Please try again", Logger.LogLevel.WARN); - JOptionPane.showMessageDialog(null, "Failed to open the web page. Please try again.", "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_MESSAGE_OPENING_WEBSITE), TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_GENERIC_TITLE), JOptionPane.ERROR_MESSAGE); } } private void displayBackupList(List backups) { - model = new DefaultTableModel(new Object[]{"Backup Name", "Initial Path", "Destination Path", "Last Backup", "Automatic Backup", "Next Backup Date", "Time Interval"}, 0) { + String backupName = TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.BACKUP_NAME_COLUMN); + String initialPath = TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.INITIAL_PATH_COLUMN); + String destinationPath = TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.DESTINATION_PATH_COLUMN); + String lastBackup = TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.LAST_BACKUP_COLUMN); + String automaticBackup = TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.AUTOMATIC_BACKUP_COLUMN); + String nextBackupDate = TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.NEXT_BACKUP_DATE_COLUMN); + String timeInterval = TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.TIME_INTERVAL_COLUMN); + model = new DefaultTableModel(new Object[]{backupName, initialPath, destinationPath, lastBackup, automaticBackup, nextBackupDate, timeInterval}, 0) { @Override public Class getColumnClass(int columnIndex) { @@ -674,13 +734,13 @@ private static String encodeURI(String value) { } } - public void Clear() { + public boolean Clear() { Logger.logMessage("Event --> clear", Logger.LogLevel.INFO); if ((!saveChanged && !currentBackup.getBackupName().isEmpty()) || (!startPathField.getText().isEmpty() || !destinationPathField.getText().isEmpty() || !backupNoteTextArea.getText().isEmpty())) { - int response = JOptionPane.showConfirmDialog(null, "Are you sure you want to clean the fields?", "Confimation required", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); + int response = JOptionPane.showConfirmDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.CONFIRMATION_MESSAGE_FOR_CLEAR), TranslationCategory.DIALOGS.getTranslation(TranslationKey.CONFIRMATION_REQUIRED_TITLE), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (response != JOptionPane.YES_OPTION) { - return; + return false; } } @@ -690,6 +750,8 @@ public void Clear() { destinationPathField.setText(""); lastBackupLabel.setText(""); backupNoteTextArea.setText(""); + + return true; } private void RemoveBackup(String backupName) { @@ -711,7 +773,7 @@ private void saveFile() { if (startPathField.getText().length() == 0 || destinationPathField.getText().length() == 0) { Logger.logMessage("Unable to save the file. Both the initial and destination paths must be specified and cannot be empty", Logger.LogLevel.WARN); - JOptionPane.showMessageDialog(null, "Unable to save the file. Both the initial and destination paths must be specified and cannot be empty", "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_MESSAGE_FOR_SAVING_FILE_WITH_PATHS_EMPTY), TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_GENERIC_TITLE), JOptionPane.ERROR_MESSAGE); return; } @@ -745,7 +807,7 @@ private void OpenBackup(String backupName) { Logger.logMessage("Event --> opening backup", Logger.LogLevel.INFO); if (!saveChanged) { - int response = JOptionPane.showConfirmDialog(null, "There are unsaved changes, do you want to save them before moving to another file?", "Confimation required", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); + int response = JOptionPane.showConfirmDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.CONFIRMATION_MESSAGE_FOR_UNSAVED_CHANGES), TranslationCategory.DIALOGS.getTranslation(TranslationKey.CONFIRMATION_REQUIRED_TITLE), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); if (response == JOptionPane.YES_OPTION) { saveFile(); } else if (response == JOptionPane.CANCEL_OPTION) { @@ -834,8 +896,8 @@ private void updateCurrentFiedsByBackup(Backup backup) { private void NewBackup() { Logger.logMessage("Event --> new backup", Logger.LogLevel.INFO); - if (!saveChanged) { - int response = JOptionPane.showConfirmDialog(null, "There are unsaved changes, do you want to save them before moving to another backup?", "Confimation required", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); + if (!saveChanged) { + int response = JOptionPane.showConfirmDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.CONFIRMATION_MESSAGE_FOR_UNSAVED_CHANGES), TranslationCategory.DIALOGS.getTranslation(TranslationKey.CONFIRMATION_REQUIRED_TITLE), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); if (response == JOptionPane.YES_OPTION) { saveFile(); } else if (response == JOptionPane.CANCEL_OPTION) { @@ -843,7 +905,9 @@ private void NewBackup() { } } - Clear(); + if (!Clear()) { + return; + } currentBackup = new Backup(); currentBackup.setAutoBackup(false); currentBackup.setBackupName(""); @@ -931,14 +995,15 @@ private void initComponents() { MenuClear = new javax.swing.JMenuItem(); MenuHistory = new javax.swing.JMenuItem(); jMenu2 = new javax.swing.JMenu(); - MenuBugReport = new javax.swing.JMenuItem(); + MenuPreferences = new javax.swing.JMenuItem(); MenuQuit = new javax.swing.JMenuItem(); jMenu3 = new javax.swing.JMenu(); + MenuWebsite = new javax.swing.JMenuItem(); + MenuInfoPage = new javax.swing.JMenuItem(); MenuShare = new javax.swing.JMenuItem(); MenuDonate = new javax.swing.JMenuItem(); - MenuInfoPage = new javax.swing.JMenuItem(); jMenu5 = new javax.swing.JMenu(); - MenuWebsite = new javax.swing.JMenuItem(); + MenuBugReport = new javax.swing.JMenuItem(); MenuSupport = new javax.swing.JMenuItem(); EditPoputItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/img/pen.png"))); // NOI18N @@ -1380,6 +1445,7 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { }); jMenu1.add(MenuSave); + MenuSaveWithName.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/img/save.png"))); // NOI18N MenuSaveWithName.setText("Save with name"); MenuSaveWithName.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -1411,14 +1477,14 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { jMenu2.setText("Options"); - MenuBugReport.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/img/bug.png"))); // NOI18N - MenuBugReport.setText("Report a bug"); - MenuBugReport.addActionListener(new java.awt.event.ActionListener() { + MenuPreferences.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/img/cogwheel.png"))); // NOI18N + MenuPreferences.setText("Preferences"); + MenuPreferences.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - MenuBugReportActionPerformed(evt); + MenuPreferencesActionPerformed(evt); } }); - jMenu2.add(MenuBugReport); + jMenu2.add(MenuPreferences); MenuQuit.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F4, java.awt.event.InputEvent.ALT_DOWN_MASK)); MenuQuit.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/img/remove.png"))); // NOI18N @@ -1434,6 +1500,24 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { jMenu3.setText("About"); + MenuWebsite.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/img/website.png"))); // NOI18N + MenuWebsite.setText("Website"); + MenuWebsite.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + MenuWebsiteActionPerformed(evt); + } + }); + jMenu3.add(MenuWebsite); + + MenuInfoPage.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/img/information.png"))); // NOI18N + MenuInfoPage.setText("Info"); + MenuInfoPage.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + MenuInfoPageActionPerformed(evt); + } + }); + jMenu3.add(MenuInfoPage); + MenuShare.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/img/share.png"))); // NOI18N MenuShare.setText("Share"); MenuShare.addActionListener(new java.awt.event.ActionListener() { @@ -1452,27 +1536,18 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { }); jMenu3.add(MenuDonate); - MenuInfoPage.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/img/info.png"))); // NOI18N - MenuInfoPage.setText("Info"); - MenuInfoPage.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - MenuInfoPageActionPerformed(evt); - } - }); - jMenu3.add(MenuInfoPage); - jMenuBar1.add(jMenu3); jMenu5.setText("Help"); - MenuWebsite.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/img/website.png"))); // NOI18N - MenuWebsite.setText("Website"); - MenuWebsite.addActionListener(new java.awt.event.ActionListener() { + MenuBugReport.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/img/bug.png"))); // NOI18N + MenuBugReport.setText("Report a bug"); + MenuBugReport.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - MenuWebsiteActionPerformed(evt); + MenuBugReportActionPerformed(evt); } }); - jMenu5.add(MenuWebsite); + jMenu5.add(MenuBugReport); MenuSupport.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/img/help-desk.png"))); // NOI18N MenuSupport.setText("Support"); @@ -1492,18 +1567,18 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(TabbedPane, javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 66, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(TabbedPane, javax.swing.GroupLayout.PREFERRED_SIZE, 636, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 19, Short.MAX_VALUE) + .addGap(18, 18, 18) .addComponent(jLabel3) - .addContainerGap()) + .addContainerGap(7, Short.MAX_VALUE)) ); pack(); @@ -1521,7 +1596,7 @@ private void MenuHistoryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-F new ProcessBuilder("notepad.exe", ConfigKey.RES_DIRECTORY_STRING.getValue() + ConfigKey.LOG_FILE_STRING.getValue()).start(); } catch (IOException e) { Logger.logMessage("Error opening history file.", Logger.LogLevel.WARN); - JOptionPane.showMessageDialog(null, "Error opening history file.", "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_MESSAGE_OPEN_HISTORY_FILE), TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_GENERIC_TITLE), JOptionPane.ERROR_MESSAGE); } }//GEN-LAST:event_MenuHistoryActionPerformed @@ -1557,7 +1632,7 @@ private void DeletePopupItemActionPerformed(java.awt.event.ActionEvent evt) {//G Logger.logMessage("Event --> deleting backup", Logger.LogLevel.INFO); if (selectedRow != -1) { - int response = JOptionPane.showConfirmDialog(null, "Are you sure you want to delete this item? Please note, this action cannot be undone", "Confirmation required", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); + int response = JOptionPane.showConfirmDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.CONFIRMATION_MESSAGE_BEFORE_DELETE_BACKUP), TranslationCategory.DIALOGS.getTranslation(TranslationKey.CONFIRMATION_REQUIRED_TITLE), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (response == JOptionPane.YES_OPTION) { RemoveBackup(backups.get(selectedRow).getBackupName()); } @@ -1596,17 +1671,28 @@ else if (SwingUtilities.isLeftMouseButton(evt) && evt.getClickCount() == 2) { // Handling single left mouse button click else if (SwingUtilities.isLeftMouseButton(evt)) { + String backupName = TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.BACKUP_NAME_DETAIL); + String initialPath = TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.INITIAL_PATH_DETAIL); + String destinationPath = TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.DESTINATION_PATH_DETAIL); + String lastBackup = TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.LAST_BACKUP_DETAIL); + String nextBackup = TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.NEXT_BACKUP_DATE_DETAIL); + String timeIntervalBackup = TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.TIME_INTERVAL_DETAIL); + String creationDate = TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.CREATION_DATE_DETAIL); + String lastUpdateDate = TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.LAST_UPDATE_DATE_DETAIL); + String backupCount = TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.BACKUP_COUNT_DETAIL); + String notes = TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.NOTES_DETAIL); + detailsLabel.setText( - "BackupName: " + backups.get(selectedRow).getBackupName() + ", " + - "InitialPath: " + backups.get(selectedRow).getInitialPath() + ", " + - "DestinationPath: " + backups.get(selectedRow).getDestinationPath() + ", " + - "LastBackup: " + (backups.get(selectedRow).getLastBackup() != null ? backups.get(selectedRow).getLastBackup().format(formatter) : "") + ", " + - "NextBackup: " + (backups.get(selectedRow).getNextDateBackup() != null ? backups.get(selectedRow).getNextDateBackup().format(formatter) : "_") + ", " + - "TimeIntervalBackup: " + (backups.get(selectedRow).getTimeIntervalBackup() != null ? backups.get(selectedRow).getTimeIntervalBackup().toString() : "_") + ", " + - "CreationDate: " + (backups.get(selectedRow).getCreationDate() != null ? backups.get(selectedRow).getCreationDate().format(formatter) : "_") + ", " + - "LastUpdateDate: " + (backups.get(selectedRow).getLastUpdateDate() != null ? backups.get(selectedRow).getLastUpdateDate().format(formatter) : "_") + ", " + - "BackupCount: " + (backups.get(selectedRow).getBackupCount()) + ", " + - "Notes: " + (backups.get(selectedRow).getNotes()) + + "" + backupName + ": " + backups.get(selectedRow).getBackupName() + ", " + + "" + initialPath + ": " + backups.get(selectedRow).getInitialPath() + ", " + + "" + destinationPath + ": " + backups.get(selectedRow).getDestinationPath() + ", " + + "" + lastBackup + ": " + (backups.get(selectedRow).getLastBackup() != null ? backups.get(selectedRow).getLastBackup().format(formatter) : "") + ", " + + "" + nextBackup + ": " + (backups.get(selectedRow).getNextDateBackup() != null ? backups.get(selectedRow).getNextDateBackup().format(formatter) : "_") + ", " + + "" + timeIntervalBackup + ": " + (backups.get(selectedRow).getTimeIntervalBackup() != null ? backups.get(selectedRow).getTimeIntervalBackup().toString() : "_") + ", " + + "" + creationDate + ": " + (backups.get(selectedRow).getCreationDate() != null ? backups.get(selectedRow).getCreationDate().format(formatter) : "_") + ", " + + "" + lastUpdateDate + ": " + (backups.get(selectedRow).getLastUpdateDate() != null ? backups.get(selectedRow).getLastUpdateDate().format(formatter) : "_") + ", " + + "" + backupCount + ": " + (backups.get(selectedRow).getBackupCount()) + ", " + + "" + notes + ": " + (backups.get(selectedRow).getNotes()) + "" ); } @@ -1723,7 +1809,7 @@ private void MenuShareActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIR Logger.logMessage("Event --> share", Logger.LogLevel.INFO); // pop-up message - JOptionPane.showMessageDialog(null, "Share link copied to clipboard!"); + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.SHARE_LINK_COPIED_MESSAGE)); // copy link to the clipboard StringSelection stringSelectionObj = new StringSelection(ConfigKey.SHARE_LINK.getValue()); @@ -1742,7 +1828,7 @@ private void toggleAutoBackupActionPerformed(java.awt.event.ActionEvent evt) {// return; } if (currentBackup.isAutoBackup()) { - int response = JOptionPane.showConfirmDialog(null, "Are you sure you want to cancel automatic backup?", "Confimation required", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); + int response = JOptionPane.showConfirmDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.CONFIRMATION_MESSAGE_CANCEL_AUTO_BACKUP), TranslationCategory.DIALOGS.getTranslation(TranslationKey.CONFIRMATION_REQUIRED_TITLE), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); if (response != JOptionPane.YES_OPTION) { toggleAutoBackup.setSelected(false); return; @@ -1788,15 +1874,15 @@ private void MenuSupportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-F desktop.mail(uri); } catch (IOException | URISyntaxException ex) { Logger.logMessage("Failed to send email: " + ex.getMessage(), Logger.LogLevel.ERROR, ex); - JOptionPane.showMessageDialog(null, "Unable to send email. Please try again later.", "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_MESSAGE_UNABLE_TO_SEND_EMAIL), TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_GENERIC_TITLE), JOptionPane.ERROR_MESSAGE); } } else { Logger.logMessage("Mail action is unsupported in your system's desktop environment.", Logger.LogLevel.WARN); - JOptionPane.showMessageDialog(null, "Your system does not support sending emails directly from this application.", "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_MESSAGE_NOT_SUPPORTED_EMAIL), TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_GENERIC_TITLE), JOptionPane.ERROR_MESSAGE); } } else { Logger.logMessage("Desktop integration is unsupported on this system.", Logger.LogLevel.WARN); - JOptionPane.showMessageDialog(null, "Your system does not support sending emails.", "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_MESSAGE_NOT_SUPPORTED_EMAIL_GENERIC), TranslationCategory.DIALOGS.getTranslation(TranslationKey.ERROR_GENERIC_TITLE), JOptionPane.ERROR_MESSAGE); } }//GEN-LAST:event_MenuSupportActionPerformed @@ -1836,9 +1922,91 @@ private void btnTimePickerActionPerformed(java.awt.event.ActionEvent evt) {//GEN } BackupOperations.updateBackupList(backups); - JOptionPane.showMessageDialog(null, "Auto Backup has been activated\n\tFrom: " + startPathField.getText() + "\n\tTo: " + destinationPathField.getText() + "\nIs setted every " + timeInterval.toString() + " days", "AutoBackup", 1); + openBackupActivationMessage(timeInterval); + }//GEN-LAST:event_btnTimePickerActionPerformed - + + private void MenuPreferencesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuPreferencesActionPerformed + openPreferences(); + }//GEN-LAST:event_MenuPreferencesActionPerformed + + private void setTranslations() { + try { + backups = JSON.ReadBackupListFromJSON(ConfigKey.BACKUP_FILE_STRING.getValue(), ConfigKey.RES_DIRECTORY_STRING.getValue()); + displayBackupList(backups); + } catch (IOException ex) { + backups = null; + Logger.logMessage("An error occurred: " + ex.getMessage(), Logger.LogLevel.ERROR, ex); + OpenExceptionMessage(ex.getMessage(), Arrays.toString(ex.getStackTrace())); + } + + backupOnText = TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.AUTO_BACKUP_BUTTON_ON); + backupOffText = TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.AUTO_BACKUP_BUTTON_OFF); + + // general + jLabel3.setText(TranslationCategory.GENERAL.getTranslation(TranslationKey.VERSION) + " " + current_version); + + // menu + jMenu1.setText(TranslationCategory.MENU.getTranslation(TranslationKey.FILE)); + jMenu2.setText(TranslationCategory.MENU.getTranslation(TranslationKey.OPTIONS)); + jMenu3.setText(TranslationCategory.MENU.getTranslation(TranslationKey.ABOUT)); + jMenu5.setText(TranslationCategory.MENU.getTranslation(TranslationKey.HELP)); + + // menu items + MenuBugReport.setText(TranslationCategory.MENU.getTranslation(TranslationKey.BUG_REPORT)); + MenuClear.setText(TranslationCategory.MENU.getTranslation(TranslationKey.CLEAR)); + MenuDonate.setText(TranslationCategory.MENU.getTranslation(TranslationKey.DONATE)); + MenuHistory.setText(TranslationCategory.MENU.getTranslation(TranslationKey.HISTORY)); + MenuInfoPage.setText(TranslationCategory.MENU.getTranslation(TranslationKey.INFO_PAGE)); + MenuNew.setText(TranslationCategory.MENU.getTranslation(TranslationKey.NEW)); + MenuQuit.setText(TranslationCategory.MENU.getTranslation(TranslationKey.QUIT)); + MenuSave.setText(TranslationCategory.MENU.getTranslation(TranslationKey.SAVE)); + MenuSaveWithName.setText(TranslationCategory.MENU.getTranslation(TranslationKey.SAVE_WITH_NAME)); + MenuShare.setText(TranslationCategory.MENU.getTranslation(TranslationKey.SHARE)); + MenuSupport.setText(TranslationCategory.MENU.getTranslation(TranslationKey.SUPPORT)); + MenuWebsite.setText(TranslationCategory.MENU.getTranslation(TranslationKey.WEBSITE)); + + // backup entry + TabbedPane.setTitleAt(0, TranslationCategory.TABBED_FRAMES.getTranslation(TranslationKey.BACKUP_ENTRY)); + TabbedPane.setTitleAt(1, TranslationCategory.TABBED_FRAMES.getTranslation(TranslationKey.BACKUP_LIST)); + btnPathSearch1.setToolTipText(TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.INITIAL_FILE_CHOOSER_TOOLTIP)); + btnPathSearch2.setToolTipText(TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.DESTINATION_FILE_CHOOSER_TOOLTIP)); + startPathField.setToolTipText(TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.INITIAL_PATH_TOOLTIP)); + destinationPathField.setToolTipText(TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.DESTINATION_PATH_TOOLTIP)); + backupNoteTextArea.setToolTipText(TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.NOTES_TOOLTIP)); + SingleBackup.setText(TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.SINGLE_BACKUP_BUTTON)); + SingleBackup.setToolTipText(TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.SINGLE_BACKUP_TOOLTIP)); + toggleAutoBackup.setText(TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.AUTO_BACKUP_BUTTON_OFF)); + toggleAutoBackup.setToolTipText(TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.AUTO_BACKUP_TOOLTIP)); + currentFileLabel.setText(TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.CURRENT_FILE) + ":"); + jLabel2.setText(TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.NOTES) + ":"); + lastBackupLabel.setText(TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.LAST_BACKUP) + ": "); + txtTitle.setText(TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.PAGE_TITLE)); + startPathField.putClientProperty(FlatClientProperties.PLACEHOLDER_TEXT, TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.INITIAL_PATH_PLACEHOLDER)); + destinationPathField.putClientProperty(FlatClientProperties.PLACEHOLDER_TEXT, TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.DESTINATION_PATH_PLACEHOLDER)); + btnTimePicker.setToolTipText(TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.TIME_PICKER_TOOLTIP)); + + // backup list + addBackupEntryButton.setToolTipText(TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.ADD_BACKUP_TOOLTIP)); + researchField.setToolTipText(TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.RESEARCH_BAR_TOOLTIP)); + researchField.putClientProperty(FlatClientProperties.PLACEHOLDER_TEXT, TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.RESEARCH_BAR_PLACEHOLDER)); + + // popup + CopyBackupNamePopupItem.setText(TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.COPY_BACKUP_NAME_POPUP)); + CopyDestinationPathPopupItem.setText(TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.COPY_DESTINATION_PATH_BACKUP)); + RunBackupPopupItem.setText(TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.SINGLE_BACKUP_POPUP)); + CopyInitialPathPopupItem.setText(TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.COPY_INITIAL_PATH_POPUP)); + DeletePopupItem.setText(TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.DELETE_POPUP)); + DuplicatePopupItem.setText(TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.DUPLICATE_POPUP)); + EditPoputItem.setText(TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.EDIT_POPUP)); + OpenInitialDestinationItem.setText(TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.OPEN_DESTINATION_FOLDER_POPUP)); + OpenInitialFolderItem.setText(TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.OPEN_INITIAL_FOLDER_POPUP)); + renamePopupItem.setText(TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.RENAME_BACKUP_POPUP)); + jMenu4.setText(TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.COPY_TEXT_POPUP)); + AutoBackupMenuItem.setText(TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.AUTO_BACKUP_POPUP)); + Backup.setText(TranslationCategory.BACKUP_LIST.getTranslation(TranslationKey.BACKUP_POPUP)); + } + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JCheckBoxMenuItem AutoBackupMenuItem; private javax.swing.JMenu Backup; @@ -1854,6 +2022,7 @@ private void btnTimePickerActionPerformed(java.awt.event.ActionEvent evt) {//GEN private javax.swing.JMenuItem MenuHistory; private javax.swing.JMenuItem MenuInfoPage; private javax.swing.JMenuItem MenuNew; + private javax.swing.JMenuItem MenuPreferences; private javax.swing.JMenuItem MenuQuit; private javax.swing.JMenuItem MenuSave; private javax.swing.JMenuItem MenuSaveWithName; diff --git a/src/main/java/com/mycompany/autobackupprogram/BackupProgressGUI.form b/src/main/java/com/mycompany/autobackupprogram/GUI/BackupProgressGUI.form similarity index 100% rename from src/main/java/com/mycompany/autobackupprogram/BackupProgressGUI.form rename to src/main/java/com/mycompany/autobackupprogram/GUI/BackupProgressGUI.form diff --git a/src/main/java/com/mycompany/autobackupprogram/BackupProgressGUI.java b/src/main/java/com/mycompany/autobackupprogram/GUI/BackupProgressGUI.java similarity index 86% rename from src/main/java/com/mycompany/autobackupprogram/BackupProgressGUI.java rename to src/main/java/com/mycompany/autobackupprogram/GUI/BackupProgressGUI.java index d11dea1..1cf9cfb 100644 --- a/src/main/java/com/mycompany/autobackupprogram/BackupProgressGUI.java +++ b/src/main/java/com/mycompany/autobackupprogram/GUI/BackupProgressGUI.java @@ -1,27 +1,16 @@ -package com.mycompany.autobackupprogram; +package com.mycompany.autobackupprogram.GUI; + +import com.mycompany.autobackupprogram.BackupOperations; +import com.mycompany.autobackupprogram.Enums.ConfigKey; +import com.mycompany.autobackupprogram.Enums.TranslationLoaderEnum.TranslationCategory; +import com.mycompany.autobackupprogram.Enums.TranslationLoaderEnum.TranslationKey; -import com.formdev.flatlaf.FlatIntelliJLaf; -import static com.mycompany.autobackupprogram.BackupManagerGUI.OpenExceptionMessage; import java.awt.Image; -import java.util.Arrays; import javax.swing.ImageIcon; import javax.swing.JOptionPane; -import javax.swing.UIManager; -import javax.swing.UnsupportedLookAndFeelException; import javax.swing.WindowConstants; public class BackupProgressGUI extends javax.swing.JFrame { - - private BackupProgressGUI() { - initComponents(); - - // logo application - Image icon = new ImageIcon(this.getClass().getResource(ConfigKey.LOGO_IMG.getValue())).getImage(); - this.setIconImage(icon); - - this.setAlwaysOnTop(false); - } - public BackupProgressGUI(String initialPath, String destinationPath) { initComponents(); @@ -35,6 +24,8 @@ public BackupProgressGUI(String initialPath, String destinationPath) { destinationPathLabel.setText(destinationPath); closeButton.setEnabled(false); + + setTranslations(); } public void UpdateProgressBar(int value) { @@ -42,7 +33,7 @@ public void UpdateProgressBar(int value) { percentageLabel.setText(value + " %"); if (value == 100) { - loadingMessageLabel.setText("backup completed!"); + loadingMessageLabel.setText(TranslationCategory.PROGRESS_BACKUP_FRAME.getTranslation(TranslationKey.STATUS_COMPLETED)); closeButton.setEnabled(true); CancelButton.setEnabled(false); this.setAlwaysOnTop(true); @@ -152,23 +143,18 @@ private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-F }//GEN-LAST:event_closeButtonActionPerformed private void CancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CancelButtonActionPerformed - int response = JOptionPane.showConfirmDialog(null, "Are you sure you want to stop this backup?", "Confimation required", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); + int response = JOptionPane.showConfirmDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.INTERRUPT_BACKUP_PROCESS_MESSAGE), TranslationCategory.DIALOGS.getTranslation(TranslationKey.CONFIRMATION_REQUIRED_TITLE), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (response == JOptionPane.YES_OPTION) { BackupOperations.StopCopyFiles(); this.dispose(); } }//GEN-LAST:event_CancelButtonActionPerformed - public static void main(String args[]) { - try { - UIManager.setLookAndFeel(new FlatIntelliJLaf()); - } catch (UnsupportedLookAndFeelException ex) { - OpenExceptionMessage(ex.getMessage(), Arrays.toString(ex.getStackTrace())); - } - - java.awt.EventQueue.invokeLater(() -> { - new BackupProgressGUI().setVisible(true); - }); + private void setTranslations() { + setTitle(TranslationCategory.PROGRESS_BACKUP_FRAME.getTranslation(TranslationKey.PROGRESS_BACKUP_TITLE)); + CancelButton.setText(TranslationCategory.GENERAL.getTranslation(TranslationKey.CANCEL_BUTTON)); + closeButton.setText(TranslationCategory.GENERAL.getTranslation(TranslationKey.CLOSE_BUTTON)); + loadingMessageLabel.setText(TranslationCategory.PROGRESS_BACKUP_FRAME.getTranslation(TranslationKey.STATUS_LOADING)); } // Variables declaration - do not modify//GEN-BEGIN:variables diff --git a/src/main/java/com/mycompany/autobackupprogram/IJSONAutoBackup.java b/src/main/java/com/mycompany/autobackupprogram/Interfaces/IJSONAutoBackup.java similarity index 78% rename from src/main/java/com/mycompany/autobackupprogram/IJSONAutoBackup.java rename to src/main/java/com/mycompany/autobackupprogram/Interfaces/IJSONAutoBackup.java index 699c0f6..cd081f8 100644 --- a/src/main/java/com/mycompany/autobackupprogram/IJSONAutoBackup.java +++ b/src/main/java/com/mycompany/autobackupprogram/Interfaces/IJSONAutoBackup.java @@ -1,8 +1,10 @@ -package com.mycompany.autobackupprogram; +package com.mycompany.autobackupprogram.Interfaces; import java.io.IOException; import java.util.List; +import com.mycompany.autobackupprogram.Entities.Backup; + public interface IJSONAutoBackup { public List ReadBackupListFromJSON(String filename, String directoryPath) throws IOException; public void UpdateBackupListJSON(String filename, String directoryPath, List backups); diff --git a/src/main/java/com/mycompany/autobackupprogram/JSONAutoBackup.java b/src/main/java/com/mycompany/autobackupprogram/JSONAutoBackup.java index f9540af..5214495 100644 --- a/src/main/java/com/mycompany/autobackupprogram/JSONAutoBackup.java +++ b/src/main/java/com/mycompany/autobackupprogram/JSONAutoBackup.java @@ -1,6 +1,7 @@ package com.mycompany.autobackupprogram; -import static com.mycompany.autobackupprogram.BackupManagerGUI.OpenExceptionMessage; +import static com.mycompany.autobackupprogram.GUI.BackupManagerGUI.OpenExceptionMessage; + import java.io.*; import java.time.LocalDateTime; import java.util.ArrayList; @@ -11,6 +12,10 @@ import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; +import com.mycompany.autobackupprogram.Entities.Backup; +import com.mycompany.autobackupprogram.Entities.TimeInterval; +import com.mycompany.autobackupprogram.Interfaces.IJSONAutoBackup; + public class JSONAutoBackup implements IJSONAutoBackup { @Override public List ReadBackupListFromJSON(String filename, String directoryPath) throws IOException { diff --git a/src/main/java/com/mycompany/autobackupprogram/Logger.java b/src/main/java/com/mycompany/autobackupprogram/Logger.java index c67074f..f1cb091 100644 --- a/src/main/java/com/mycompany/autobackupprogram/Logger.java +++ b/src/main/java/com/mycompany/autobackupprogram/Logger.java @@ -7,6 +7,8 @@ import java.util.List; import java.util.concurrent.locks.ReentrantLock; +import com.mycompany.autobackupprogram.Enums.ConfigKey; + public class Logger { private static String LOG_PATH = ConfigKey.RES_DIRECTORY_STRING.getValue() + ConfigKey.LOG_FILE_STRING.getValue(); diff --git a/src/main/java/com/mycompany/autobackupprogram/MainApp.java b/src/main/java/com/mycompany/autobackupprogram/MainApp.java index d4ec71f..9a1adaf 100644 --- a/src/main/java/com/mycompany/autobackupprogram/MainApp.java +++ b/src/main/java/com/mycompany/autobackupprogram/MainApp.java @@ -1,16 +1,35 @@ package com.mycompany.autobackupprogram; -import static com.mycompany.autobackupprogram.BackupManagerGUI.OpenExceptionMessage; +import static com.mycompany.autobackupprogram.GUI.BackupManagerGUI.OpenExceptionMessage; + import java.io.IOException; import java.util.Arrays; +import org.json.simple.parser.ParseException; + +import com.mycompany.autobackupprogram.Entities.Preferences; +import com.mycompany.autobackupprogram.Enums.ConfigKey; +import com.mycompany.autobackupprogram.Enums.TranslationLoaderEnum; +import com.mycompany.autobackupprogram.GUI.BackupManagerGUI; + public class MainApp { - private static final String CONFIG = "src/main/resources/res/config.json"; + private static final String CONFIG = "src/main/resources/res/config/config.json"; public static void main(String[] args) { + // load config keys ConfigKey.loadFromJson(CONFIG); - Logger.configReader = new JSONConfigReader(ConfigKey.CONFIG_FILE_STRING.getValue(), ConfigKey.RES_DIRECTORY_STRING.getValue()); - + Logger.configReader = new JSONConfigReader(ConfigKey.CONFIG_FILE_STRING.getValue(), ConfigKey.CONFIG_DIRECTORY_STRING.getValue()); + + // load preferred language + try { + Preferences.loadPreferencesFromJSON(); + TranslationLoaderEnum.loadTranslations(ConfigKey.LANGUAGES_DIRECTORY_STRING.getValue() + Preferences.getLanguage().getFileName()); + } catch (IOException e) { + e.printStackTrace(); + } catch (ParseException e) { + e.printStackTrace(); + } + boolean isBackgroundMode = args.length > 0 && args[0].equalsIgnoreCase("--background"); // check argument correction diff --git a/src/main/java/com/mycompany/autobackupprogram/Managers/ThemeManager.java b/src/main/java/com/mycompany/autobackupprogram/Managers/ThemeManager.java new file mode 100644 index 0000000..7030b24 --- /dev/null +++ b/src/main/java/com/mycompany/autobackupprogram/Managers/ThemeManager.java @@ -0,0 +1,99 @@ +package com.mycompany.autobackupprogram.Managers; + +import java.awt.Dialog; +import java.awt.Frame; + +import javax.swing.SwingUtilities; +import javax.swing.JPopupMenu; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +import com.formdev.flatlaf.FlatDarculaLaf; +import com.formdev.flatlaf.FlatIntelliJLaf; +import com.formdev.flatlaf.intellijthemes.FlatArcDarkOrangeIJTheme; +import com.formdev.flatlaf.intellijthemes.FlatArcOrangeIJTheme; +import com.formdev.flatlaf.intellijthemes.FlatCarbonIJTheme; +import com.formdev.flatlaf.intellijthemes.FlatCyanLightIJTheme; +import com.formdev.flatlaf.intellijthemes.FlatHighContrastIJTheme; +import com.formdev.flatlaf.intellijthemes.FlatNordIJTheme; +import com.formdev.flatlaf.intellijthemes.FlatSolarizedDarkIJTheme; +import com.formdev.flatlaf.intellijthemes.FlatSolarizedLightIJTheme; +import com.mycompany.autobackupprogram.Entities.Preferences; + +// https://www.formdev.com/flatlaf/#demo +// https://www.formdev.com/flatlaf/themes/ +// https://github.com/JFormDesigner/FlatLaf/tree/main/flatlaf-intellij-themes + +public class ThemeManager { + + public static void updateThemeFrame(Frame frame) { + updateTheme(); + + // Update all components and Revalidate and repaint + SwingUtilities.updateComponentTreeUI(frame); + frame.revalidate(); + frame.repaint(); + } + + public static void refreshPopup(JPopupMenu popup) { + // Update all components and Revalidate and repaint + SwingUtilities.updateComponentTreeUI(popup); + popup.revalidate(); + popup.repaint(); + } + + public static void updateThemeDialog(Dialog dialog) { + updateTheme(); + + // Update all components and Revalidate and repaint + SwingUtilities.updateComponentTreeUI(dialog); + dialog.revalidate(); + dialog.repaint(); + } + + private static void updateTheme() { + try { + String selectedTheme = Preferences.getTheme().getThemeName(); + + switch (selectedTheme.toLowerCase()) { + case "light": + UIManager.setLookAndFeel(new FlatIntelliJLaf()); + break; + case "dark": + UIManager.setLookAndFeel(new FlatDarculaLaf()); + break; + case "carbon": + UIManager.setLookAndFeel(new FlatCarbonIJTheme()); + break; + case "arc - orange": + UIManager.setLookAndFeel(new FlatArcOrangeIJTheme()); + break; + case "arc dark - orange": + UIManager.setLookAndFeel(new FlatArcDarkOrangeIJTheme()); + break; + case "cyan light": + UIManager.setLookAndFeel(new FlatCyanLightIJTheme()); + break; + case "nord": + UIManager.setLookAndFeel(new FlatNordIJTheme()); + break; + case "high contrast": + UIManager.setLookAndFeel(new FlatHighContrastIJTheme()); + break; + case "solarized dark": + UIManager.setLookAndFeel(new FlatSolarizedDarkIJTheme()); + break; + case "solarized light": + UIManager.setLookAndFeel(new FlatSolarizedLightIJTheme()); + break; + default: + // If no match, apply the default theme + UIManager.setLookAndFeel(new FlatIntelliJLaf()); + break; + } + + } catch (UnsupportedLookAndFeelException ex) { + System.err.println("Error setting LookAndFeel: " + ex.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/resources/res/backup_list.json b/src/main/resources/res/backup_list.json index 0637a08..90d87a1 100644 --- a/src/main/resources/res/backup_list.json +++ b/src/main/resources/res/backup_list.json @@ -1 +1 @@ -[] \ No newline at end of file +[{"time_interval_backup":"2.0:0","destination_path":"C:\\Users\\Utente\\Desktop","automatic_backup":true,"backup_name":"prova","notes":"","backup_count":4,"next_date_backup":"2024-11-19T20:49:21.617100500","start_path":"C:\\Users\\Utente\\Desktop\\AutoBackupProgram","creation_date":"2024-11-14T00:38:57.913908","last_backup":"2024-11-17T20:49:21.617100500","last_update_date":"2024-11-14T09:14:50.262976200"},{"time_interval_backup":null,"destination_path":"C:\\Users\\Utente\\Desktop","automatic_backup":false,"backup_name":"asd","notes":"","backup_count":3,"next_date_backup":null,"start_path":"C:\\Users\\Utente\\Desktop\\gg","creation_date":"2024-11-16T14:27:45.841538600","last_backup":"2024-11-17T22:08:01.249689600","last_update_date":"2024-11-17T22:12:25.156933700"}] \ No newline at end of file diff --git a/src/main/resources/res/config.json b/src/main/resources/res/config/config.json similarity index 84% rename from src/main/resources/res/config.json rename to src/main/resources/res/config/config.json index 49343e5..c506fcb 100644 --- a/src/main/resources/res/config.json +++ b/src/main/resources/res/config/config.json @@ -2,7 +2,10 @@ "LOG_FILE_STRING": "log_file", "BACKUP_FILE_STRING": "backup_list.json", "CONFIG_FILE_STRING": "config.json", + "PREFERENCES_FILE_STRING": "preferences.json", "RES_DIRECTORY_STRING": "src/main/resources/res/", + "LANGUAGES_DIRECTORY_STRING": "src/main/resources/res/languages/", + "CONFIG_DIRECTORY_STRING": "src/main/resources/res/config/", "DONATE_PAGE_LINK": "https://buymeacoffee.com/denno", "ISSUE_PAGE_LINK": "https://github.com/DennisTurco/BackupManager/issues", "INFO_PAGE_LINK": "https://github.com/DennisTurco/BackupManager", @@ -13,6 +16,7 @@ "MenuItems": { "BugReport": true, + "Preferences": true, "Clear": true, "Donate": false, "History": false, @@ -20,7 +24,7 @@ "New": true, "Quit": true, "Save": true, - "SavceWithName": true, + "SaveWithName": true, "Share": true, "Support": true, "Website": true diff --git a/src/main/resources/res/config/preferences.json b/src/main/resources/res/config/preferences.json new file mode 100644 index 0000000..7ef571d --- /dev/null +++ b/src/main/resources/res/config/preferences.json @@ -0,0 +1 @@ +{"Language":"eng.json","Theme":"Light"} \ No newline at end of file diff --git a/src/main/resources/res/img/cogwheel.png b/src/main/resources/res/img/cogwheel.png new file mode 100644 index 0000000..4bd0d65 Binary files /dev/null and b/src/main/resources/res/img/cogwheel.png differ diff --git a/src/main/resources/res/img/delete.png b/src/main/resources/res/img/delete.png deleted file mode 100644 index 8cda27b..0000000 Binary files a/src/main/resources/res/img/delete.png and /dev/null differ diff --git a/src/main/resources/res/img/info.png b/src/main/resources/res/img/info.png deleted file mode 100644 index e4b2329..0000000 Binary files a/src/main/resources/res/img/info.png and /dev/null differ diff --git a/src/main/resources/res/img/information.png b/src/main/resources/res/img/information.png new file mode 100644 index 0000000..28baaa9 Binary files /dev/null and b/src/main/resources/res/img/information.png differ diff --git a/src/main/resources/res/img/pencil.png b/src/main/resources/res/img/pencil.png deleted file mode 100644 index 06b3854..0000000 Binary files a/src/main/resources/res/img/pencil.png and /dev/null differ diff --git a/src/main/resources/res/img/research.png b/src/main/resources/res/img/research.png deleted file mode 100644 index 15d8463..0000000 Binary files a/src/main/resources/res/img/research.png and /dev/null differ diff --git a/src/main/resources/res/img/save.png b/src/main/resources/res/img/save.png new file mode 100644 index 0000000..5d0fad3 Binary files /dev/null and b/src/main/resources/res/img/save.png differ diff --git a/src/main/resources/res/img/share.png b/src/main/resources/res/img/share.png index bec77b6..eada534 100644 Binary files a/src/main/resources/res/img/share.png and b/src/main/resources/res/img/share.png differ diff --git a/src/main/resources/res/img/share_1.png b/src/main/resources/res/img/share_1.png deleted file mode 100644 index bec77b6..0000000 Binary files a/src/main/resources/res/img/share_1.png and /dev/null differ diff --git a/src/main/resources/res/img/view.png b/src/main/resources/res/img/view.png deleted file mode 100644 index 1aadbc9..0000000 Binary files a/src/main/resources/res/img/view.png and /dev/null differ diff --git a/src/main/resources/res/img/website.png b/src/main/resources/res/img/website.png index 2d6f836..08cbb40 100644 Binary files a/src/main/resources/res/img/website.png and b/src/main/resources/res/img/website.png differ diff --git a/src/main/resources/res/languages/deu.json b/src/main/resources/res/languages/deu.json new file mode 100644 index 0000000..f130187 --- /dev/null +++ b/src/main/resources/res/languages/deu.json @@ -0,0 +1,153 @@ +{ + "General": { + "AppName": "Backup Manager", + "Backup": "Backup", + "Version": "Version", + "From": "Von", + "To": "Nach", + "OkButton": "Ok", + "CancelButton": "Abbrechen", + "CloseButton": "Schließen", + "ApplyButton": "Anwenden" + }, + "Menu": { + "File": "Datei", + "Options": "Optionen", + "About": "Über", + "Help": "Hilfe", + "BugReport": "Fehler melden", + "Clear": "Löschen", + "Donate": "Spenden", + "History": "Verlauf", + "InfoPage": "Info", + "New": "Neu", + "Quit": "Beenden", + "Save": "Speichern", + "SaveWithName": "Speichern unter", + "Share": "Teilen", + "Support": "Support", + "Website": "Webseite" + }, + "TabbedFrames": { + "BackupEntry": "Backup-Eintrag", + "BackupList": "Backup-Liste" + }, + "BackupEntry": { + "PageTitle": "Backup-Eintrag", + "CurrentFile": "Aktuelle Datei", + "Notes": "Notizen", + "LastBackup": "Letztes Backup", + "SingleBackupButton": "Einzel-Backup", + "AutoBackupButton": "Auto-Backup", + "AutoBackupButtonON": "Auto-Backup (AN)", + "AutoBackupButtonOFF": "Auto-Backup (AUS)", + "InitialPathPlaceholder": "Anfangspfad", + "DestinationPathPlaceholder": "Zielpfad", + "InitialPathTooltip": "(Erforderlich) Anfangspfad", + "DestinationPathTooltip": "(Erforderlich) Zielpfad", + "InitialFileChooserTooltip": "Dateiexplorer öffnen", + "DestinationFileChooserTooltip": "Dateiexplorer öffnen", + "NotesTooltip": "(Optional) Backup-Beschreibung", + "SingleBackupTooltip": "Backup durchführen", + "AutoBackupTooltip": "Automatisches Backup aktivieren/deaktivieren", + "TimePickerTooltip": "Zeitwähler" + }, + "BackupList": { + "BackupNameColumn": "Backup-Name", + "InitialPathColumn": "Anfangspfad", + "DestinationPathColumn": "Zielpfad", + "LastBackupColumn": "Letztes Backup", + "AutomaticBackupColumn": "Automatisches Backup", + "NextBackupDateColumn": "Nächstes Backup-Datum", + "TimeIntervalColumn": "Zeitintervall", + "BackupNameDetail": "Backup-Name", + "InitialPathDetail": "Anfangspfad", + "DestinationPathDetail": "Zielpfad", + "LastBackupDetail": "Letztes Backup", + "NextBackupDateDetail": "Nächstes Backup", + "TimeIntervalDetail": "Zeitintervall", + "CreationDateDetail": "Erstellungsdatum", + "LastUpdateDateDetail": "Letzte Aktualisierung", + "BackupCountDetail": "Backup-Anzahl", + "NotesDetail": "Notizen", + "AddBackupTooltip": "Neues Backup hinzufügen", + "ResearchBarTooltip": "Suchleiste", + "ResearchBarPlaceholder": "Suchen...", + "EditPopup": "Bearbeiten", + "DeletePopup": "Löschen", + "DuplicatePopup": "Duplizieren", + "RenameBackupPopup": "Backup umbenennen", + "OpenInitialFolderPopup": "Anfangspfad öffnen", + "OpenDestinationFolderPopup": "Zielpfad öffnen", + "BackupPopup": "Backup", + "SingleBackupPopup": "Einzel-Backup ausführen", + "AutoBackupPopup": "Auto-Backup", + "CopyTextPopup": "Text kopieren", + "CopyBackupNamePopup": "Backup-Name kopieren", + "CopyInitialPathPopup": "Anfangspfad kopieren", + "CopyDestinationPathPopup": "Zielpfad kopieren" + }, + "TimePickerDialog": { + "TimeIntervalTitle": "Zeitintervall für Auto-Backup", + "Description": "Wählen Sie, wie oft das automatische Backup durchgeführt werden soll, \nindem Sie die Frequenz in Tagen, Stunden und Minuten festlegen.", + "Days": "Tage", + "Hours": "Stunden", + "Minutes": "Minuten", + "SpinnerTooltip": "Mausrad zum Anpassen des Wertes" + }, + "PreferencesDialog": { + "PreferencesTitle": "Einstellungen", + "Language": "Sprache", + "Theme": "Thema" + }, + "ProgressBackupFrame": { + "ProgressBackupTitle": "Backup läuft", + "StatusCompleted": "Backup abgeschlossen!", + "StatusLoading": "Lädt..." + }, + "TrayIcon": { + "TrayTooltip": "Backup-Dienst", + "SuccessMessage": "\nDas Backup wurde erfolgreich abgeschlossen:", + "ErrorMessageInputMissing": "\nFehler beim automatischen Backup.\nEingabe fehlt!", + "ErrorMessageFilesNotExisting": "\nFehler beim automatischen Backup.\nEin oder beide Pfade existieren nicht!", + "ErrorMessageSamePaths": "\nFehler beim automatischen Backup.\nDer Anfangspfad und der Zielpfad dürfen nicht gleich sein. Bitte wählen Sie unterschiedliche Pfade!" + }, + "Dialogs": { + "ErrorGenericTitle": "Fehler", + "ErrorMessageForFolderNotExisting": "Der Ordner existiert nicht oder ist ungültig", + "ErrorMessageForSavingFileWithPathsEmpty": "Die Datei konnte nicht gespeichert werden. Sowohl der Anfangs- als auch der Zielpfad müssen angegeben werden und dürfen nicht leer sein", + "BackupSavedCorrectlyTitle": "Backup gespeichert", + "BackupSavedCorrectlyMessage": "erfolgreich gespeichert!", + "ErrorSavingBackupMessage": "Fehler beim Speichern des Backups", + "BackupNameInput": "Name des Backups", + "ConfirmationRequiredTitle": "Bestätigung erforderlich", + "DuplicatedBackupNameMessage": "Ein Backup mit demselben Namen existiert bereits. Möchten Sie es überschreiben?", + "BackupNameAlreadyUsedMessage": "Backup-Name bereits verwendet!", + "ErrorMessageForIncorrectInitialPath": "Fehler beim Backup-Vorgang: Der Anfangspfad ist falsch!", + "ExceptionMessageTitle": "Fehler...", + "ExceptionMessageClipboardMessage": "Fehlertext wurde in die Zwischenablage kopiert.", + "ExceptionMessageClipboardButton": "In Zwischenablage kopieren", + "ExceptionMessageReportButton": "Problem melden", + "ExceptionMessageReportMessage": "Bitte melden Sie diesen Fehler, entweder mit einem Screenshot oder indem Sie den folgenden Fehlertext kopieren (es ist hilfreich, eine Beschreibung der durchgeführten Aktionen vor dem Fehler anzugeben):", + "ErrorMessageOpeningWebsite": "Die Webseite konnte nicht geöffnet werden. Bitte versuchen Sie es erneut.", + "ConfirmationMessageForClear": "Sind Sie sicher, dass Sie die Felder bereinigen möchten?", + "ConfirmationMessageForUnsavedChanges": "Es gibt nicht gespeicherte Änderungen. Möchten Sie sie speichern, bevor Sie zu einem anderen Backup wechseln?", + "ErrorMessageOpenHistoryFile": "Fehler beim Öffnen der Verlaufsdatei.", + "ConfirmationMessageBeforeDeleteBackup": "Sind Sie sicher, dass Sie dieses Element löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.", + "ShareLinkCopiedMessage": "Freigabelink wurde in die Zwischenablage kopiert!", + "ConfirmationMessageCancelAutoBackup": "Sind Sie sicher, dass Sie automatische Backups für diesen Eintrag deaktivieren möchten?", + "ErrorMessageUnableToSendEmail": "E-Mail konnte nicht gesendet werden. Bitte versuchen Sie es später erneut.", + "ErrorMessageNotSupportedEmail": "Ihr System unterstützt das Senden von E-Mails direkt aus dieser Anwendung nicht.", + "ErrorMessageNotSupportedEmailGeneric": "Ihr System unterstützt das Senden von E-Mails nicht.", + "ErrorWrongTimeInterval": "Das Zeitintervall ist nicht korrekt", + "AutoBackupActivatedMessage": "Auto-Backup wurde aktiviert", + "SettedEveryMessage": "\nWird eingestellt auf alle", + "DaysMessage": " Tage", + "InterruptBackupProcessMessage": "Sind Sie sicher, dass Sie dieses Backup abbrechen möchten?", + "ErrorMessageInputMissingGeneric": "Eingabe fehlt!", + "ErrorMessageForSavingFile": "Fehler beim Speichern der Datei", + "ErrorMessageForPathNotExisting": "Ein oder beide Pfade existieren nicht!", + "ErrorMessageForSamePaths": "Der Anfangspfad und der Zielpfad dürfen nicht gleich sein. Bitte wählen Sie unterschiedliche Pfade!" + } + } + \ No newline at end of file diff --git a/src/main/resources/res/languages/eng.json b/src/main/resources/res/languages/eng.json new file mode 100644 index 0000000..8568121 --- /dev/null +++ b/src/main/resources/res/languages/eng.json @@ -0,0 +1,152 @@ +{ + "General": { + "AppName": "Backup Manager", + "Backup": "Backup", + "Version": "Version", + "From": "From", + "To": "A", + "OkButton": "Ok", + "CancelButton": "Cancel", + "CloseButton":"Close", + "ApplyButton":"Apply" + }, + "Menu": { + "File": "File", + "Options": "Options", + "About": "About", + "Help": "Help", + "BugReport": "Report a bug", + "Clear": "Clear", + "Donate": "Donate", + "History": "History", + "InfoPage": "Info", + "New": "New", + "Quit": "Quit", + "Save": "Save", + "SaveWithName": "Save with name", + "Share": "Share", + "Support": "Support", + "Website": "Website" + }, + "TabbedFrames": { + "BackupEntry": "BackupEntry", + "BackupList": "BackupList" + }, + "BackupEntry": { + "PageTitle": "Backup Entry", + "CurrentFile": "Current file", + "Notes": "Notes", + "LastBackup": "Last backup", + "SingleBackupButton": "Single Backup", + "AutoBackupButton": "Auto Backup", + "AutoBackupButtonON": "Auto Backup (ON)", + "AutoBackupButtonOFF": "Auto Backup (OFF)", + "InitialPathPlaceholder": "Initial path", + "DestinationPathPlaceholder": "Destination path", + "InitialPathTooltip": "(Required) Initial path", + "DestinationPathTooltip": "(Required) Destination path", + "InitialFileChooserTooltip": "Open file explorer", + "DestinationFileChooserTooltip": "Open file explorer", + "NotesTooltip": "(Optional) Backup description", + "SingleBackupTooltip": "Perform the backup", + "AutoBackupTooltip": "Enable/Disable automatic backup", + "TimePickerTooltip": "Time picker" + }, + "BackupList": { + "BackupNameColumn": "Backup Name", + "InitialPathColumn": "Initial Path", + "DestinationPathColumn": "Destination Path", + "LastBackupColumn": "Last Backup", + "AutomaticBackupColumn": "Automatic Backup", + "NextBackupDateColumn": "Next Backup Date", + "TimeIntervalColumn": "Time Interval", + "BackupNameDetail": "BackupName", + "InitialPathDetail": "InitialPath", + "DestinationPathDetail": "DestinationPath", + "LastBackupDetail": "LastBackup", + "NextBackupDateDetail": "NextBackup", + "TimeIntervalDetail": "TimeInterval", + "CreationDateDetail": "CreationDate", + "LastUpdateDateDetail": "LastUpdateDate", + "BackupCountDetail": "BackupCount", + "NotesDetail": "Notes", + "AddBackupTooltip": "Add new backup", + "ResearchBarTooltip": "Research bar", + "ResearchBarPlaceholder": "Search...", + "EditPopup": "Edit", + "DeletePopup": "Delete", + "DuplicatePopup": "Duplicate", + "RenameBackupPopup": "Rename backup", + "OpenInitialFolderPopup": "Open initial path", + "OpenDestinationFolderPopup": "Open destination path", + "BackupPopup": "Backup", + "SingleBackupPopup": "Run single backup", + "AutoBackupPopup": "Auto backup", + "CopyTextPopup": "Copy text", + "CopyBackupNamePopup": "Copy backup name", + "CopyInitialPathPopup": "Copy initial path", + "CopyDestinationPathPopup": "Copy destination path" + }, + "TimePickerDialog": { + "TimeIntervalTitle": "Time interval for auto backup", + "Description": "Select how often to perform the automatic backup by \nchoosing the frequency in days, hours, and minutes.", + "Days": "Days", + "Hours": "Hours", + "Minutes": "Minutes", + "SpinnerTooltip": "Mouse wheel to adjust the value" + }, + "PreferencesDialog": { + "PreferencesTitle": "Preferences", + "Language": "Language", + "Theme": "Theme" + }, + "ProgressBackupFrame": { + "ProgressBackupTitle":"Backup in progress", + "StatusCompleted":"Backup completed!", + "StatusLoading":"Loading..." + }, + "TrayIcon": { + "TrayTooltip":"Backup Service", + "SuccessMessage":"\nThe backup was successfully completed:", + "ErrorMessageInputMissing":"\nError during automatic backup.\nInput Missing!", + "ErrorMessageFilesNotExisting":"\nError during automatic backup.\nOne or both paths do not exist!", + "ErrorMessageSamePaths":"\nError during automatic backup.\nThe initial path and destination path cannot be the same. Please choose different paths!" + }, + "Dialogs": { + "ErrorGenericTitle":"Error", + "ErrorMessageForFolderNotExisting":"The folder does not exist or is invalid", + "ErrorMessageForSavingFileWithPathsEmpty":"Unable to save the file. Both the initial and destination paths must be specified and cannot be empty", + "BackupSavedCorrectlyTitle":"Backup saved", + "BackupSavedCorrectlyMessage":"saved successfully!", + "ErrorSavingBackupMessage":"Error saving backup", + "BackupNameInput":"Name of the backup", + "ConfirmationRequiredTitle":"Confirmation required", + "DuplicatedBackupNameMessage":"A backup with the same name already exists, do you want to overwrite it?", + "BackupNameAlreadyUsedMessage":"Backup name already used!", + "ErrorMessageForIncorrectInitialPath":"Error during the backup operation: the initial path is incorrect!", + "ExceptionMessageTitle":"Error...", + "ExceptionMessageClipboardMessage":"Error text has been copied to the clipboard.", + "ExceptionMessageClipboardButton":"Copy to clipboard", + "ExceptionMessageReportButton":"Report the Problem", + "ExceptionMessageReportMessage":"Please report this error, either with an image of the screen or by copying the following error text (it is appreciable to provide a description of the operations performed before the error):", + "ErrorMessageOpeningWebsite":"Failed to open the web page. Please try again.", + "ConfirmationMessageForClear":"Are you sure you want to clean the fields?", + "ConfirmationMessageForUnsavedChanges":"There are unsaved changes, do you want to save them before moving to another backup?", + "ErrorMessageOpenHistoryFile":"Error opening history file.", + "ConfirmationMessageBeforeDeleteBackup":"Are you sure you want to delete this item? Please note, this action cannot be undone", + "ShareLinkCopiedMessage":"Share link copied to clipboard!", + "ConfirmationMessageCancelAutoBackup":"Are you sure you want to cancel automatic backups for this entry?", + "ErrorMessageUnableToSendEmail":"Unable to send email. Please try again later.", + "ErrorMessageNotSupportedEmail":"Your system does not support sending emails directly from this application.", + "ErrorMessageNotSupportedEmailGeneric":"Your system does not support sending emails.", + "ErrorWrongTimeInterval":"The time interval is not correct", + "AutoBackupActivatedMessage":"Auto Backup has been activated", + "SettedEveryMessage":"\nIs setted every", + "DaysMessage":" days", + "InterruptBackupProcessMessage":"Are you sure you want to stop this backup?", + "ErrorMessageInputMissingGeneric": "Input Missing!", + "ErrorMessageForSavingFile": "Error saving file", + "ErrorMessageForPathNotExisting": "One or both paths do not exist!", + "ErrorMessageForSamePaths": "The initial path and destination path cannot be the same. Please choose different paths!" + } +} \ No newline at end of file diff --git a/src/main/resources/res/languages/esp.json b/src/main/resources/res/languages/esp.json new file mode 100644 index 0000000..bec5a0b --- /dev/null +++ b/src/main/resources/res/languages/esp.json @@ -0,0 +1,153 @@ +{ + "General": { + "AppName": "Backup Manager", + "Backup": "Copia de Seguridad", + "Version": "Versión", + "From": "Desde", + "To": "A", + "OkButton": "Aceptar", + "CancelButton": "Cancelar", + "CloseButton": "Cerrar", + "ApplyButton": "Aplicar" + }, + "Menu": { + "File": "Archivo", + "Options": "Opciones", + "About": "Acerca de", + "Help": "Ayuda", + "BugReport": "Reportar un error", + "Clear": "Limpiar", + "Donate": "Donar", + "History": "Historial", + "InfoPage": "Información", + "New": "Nuevo", + "Quit": "Salir", + "Save": "Guardar", + "SaveWithName": "Guardar con nombre", + "Share": "Compartir", + "Support": "Soporte", + "Website": "Sitio web" + }, + "TabbedFrames": { + "BackupEntry": "Entrada de Copia de Seguridad", + "BackupList": "Lista de Copias de Seguridad" + }, + "BackupEntry": { + "PageTitle": "Entrada de Copia de Seguridad", + "CurrentFile": "Archivo actual", + "Notes": "Notas", + "LastBackup": "Última copia de seguridad", + "SingleBackupButton": "Copia de Seguridad Única", + "AutoBackupButton": "Copia de Seguridad Automática", + "AutoBackupButtonON": "Copia de Seguridad Automática (ACTIVADA)", + "AutoBackupButtonOFF": "Copia de Seguridad Automática (DESACTIVADA)", + "InitialPathPlaceholder": "Ruta inicial", + "DestinationPathPlaceholder": "Ruta de destino", + "InitialPathTooltip": "(Requerido) Ruta inicial", + "DestinationPathTooltip": "(Requerido) Ruta de destino", + "InitialFileChooserTooltip": "Abrir explorador de archivos", + "DestinationFileChooserTooltip": "Abrir explorador de archivos", + "NotesTooltip": "(Opcional) Descripción de la copia de seguridad", + "SingleBackupTooltip": "Realizar la copia de seguridad", + "AutoBackupTooltip": "Activar/Desactivar copia de seguridad automática", + "TimePickerTooltip": "Selector de tiempo" + }, + "BackupList": { + "BackupNameColumn": "Nombre de la Copia de Seguridad", + "InitialPathColumn": "Ruta Inicial", + "DestinationPathColumn": "Ruta de Destino", + "LastBackupColumn": "Última Copia de Seguridad", + "AutomaticBackupColumn": "Copia Automática", + "NextBackupDateColumn": "Próxima Fecha de Copia", + "TimeIntervalColumn": "Intervalo de Tiempo", + "BackupNameDetail": "Nombre de la Copia", + "InitialPathDetail": "Ruta Inicial", + "DestinationPathDetail": "Ruta de Destino", + "LastBackupDetail": "Última Copia", + "NextBackupDateDetail": "Próxima Fecha", + "TimeIntervalDetail": "Intervalo de Tiempo", + "CreationDateDetail": "Fecha de Creación", + "LastUpdateDateDetail": "Última Actualización", + "BackupCountDetail": "Número de Copias", + "NotesDetail": "Notas", + "AddBackupTooltip": "Agregar nueva copia de seguridad", + "ResearchBarTooltip": "Barra de búsqueda", + "ResearchBarPlaceholder": "Buscar...", + "EditPopup": "Editar", + "DeletePopup": "Eliminar", + "DuplicatePopup": "Duplicar", + "RenameBackupPopup": "Renombrar copia de seguridad", + "OpenInitialFolderPopup": "Abrir ruta inicial", + "OpenDestinationFolderPopup": "Abrir ruta de destino", + "BackupPopup": "Copia de seguridad", + "SingleBackupPopup": "Ejecutar copia única", + "AutoBackupPopup": "Copia automática", + "CopyTextPopup": "Copiar texto", + "CopyBackupNamePopup": "Copiar nombre de copia", + "CopyInitialPathPopup": "Copiar ruta inicial", + "CopyDestinationPathPopup": "Copiar ruta de destino" + }, + "TimePickerDialog": { + "TimeIntervalTitle": "Intervalo de tiempo para copias automáticas", + "Description": "Seleccione la frecuencia para realizar la copia automática \neligiendo los días, horas y minutos.", + "Days": "Días", + "Hours": "Horas", + "Minutes": "Minutos", + "SpinnerTooltip": "Rueda del ratón para ajustar el valor" + }, + "PreferencesDialog": { + "PreferencesTitle": "Preferencias", + "Language": "Idioma", + "Theme": "Tema" + }, + "ProgressBackupFrame": { + "ProgressBackupTitle": "Copia de Seguridad en Progreso", + "StatusCompleted": "¡Copia completada!", + "StatusLoading": "Cargando..." + }, + "TrayIcon": { + "TrayTooltip": "Servicio de Copias de Seguridad", + "SuccessMessage": "\nLa copia de seguridad se completó con éxito:", + "ErrorMessageInputMissing": "\nError en la copia automática.\n¡Faltan datos de entrada!", + "ErrorMessageFilesNotExisting": "\nError en la copia automática.\n¡Una o ambas rutas no existen!", + "ErrorMessageSamePaths": "\nError en la copia automática.\nLa ruta inicial y la de destino no pueden ser iguales. ¡Elija rutas diferentes!" + }, + "Dialogs": { + "ErrorGenericTitle": "Error", + "ErrorMessageForFolderNotExisting": "La carpeta no existe o no es válida", + "ErrorMessageForSavingFileWithPathsEmpty": "No se puede guardar el archivo. Tanto la ruta inicial como la de destino deben especificarse y no pueden estar vacías", + "BackupSavedCorrectlyTitle": "Copia Guardada", + "BackupSavedCorrectlyMessage": "guardada con éxito.", + "ErrorSavingBackupMessage": "Error al guardar la copia de seguridad", + "BackupNameInput": "Nombre de la copia", + "ConfirmationRequiredTitle": "Confirmación requerida", + "DuplicatedBackupNameMessage": "Ya existe una copia con el mismo nombre. ¿Desea sobrescribirla?", + "BackupNameAlreadyUsedMessage": "¡Nombre de copia ya en uso!", + "ErrorMessageForIncorrectInitialPath": "Error en la operación de copia: ¡la ruta inicial es incorrecta!", + "ExceptionMessageTitle": "Error...", + "ExceptionMessageClipboardMessage": "El texto del error se ha copiado al portapapeles.", + "ExceptionMessageClipboardButton": "Copiar al portapapeles", + "ExceptionMessageReportButton": "Informar del problema", + "ExceptionMessageReportMessage": "Por favor, informe de este error, ya sea con una captura de pantalla o copiando el siguiente texto del error (se agradece proporcionar una descripción de las acciones realizadas antes del error):", + "ErrorMessageOpeningWebsite": "No se pudo abrir la página web. Por favor, intente de nuevo.", + "ConfirmationMessageForClear": "¿Está seguro de que desea limpiar los campos?", + "ConfirmationMessageForUnsavedChanges": "Hay cambios no guardados. ¿Desea guardarlos antes de pasar a otra copia de seguridad?", + "ErrorMessageOpenHistoryFile": "Error al abrir el archivo de historial.", + "ConfirmationMessageBeforeDeleteBackup": "¿Está seguro de que desea eliminar este elemento? Tenga en cuenta que esta acción no se puede deshacer.", + "ShareLinkCopiedMessage": "¡Enlace de compartir copiado al portapapeles!", + "ConfirmationMessageCancelAutoBackup": "¿Está seguro de que desea cancelar las copias automáticas para esta entrada?", + "ErrorMessageUnableToSendEmail": "No se pudo enviar el correo electrónico. Por favor, intente de nuevo más tarde.", + "ErrorMessageNotSupportedEmail": "Su sistema no admite el envío de correos electrónicos directamente desde esta aplicación.", + "ErrorMessageNotSupportedEmailGeneric": "Su sistema no admite el envío de correos electrónicos.", + "ErrorWrongTimeInterval": "El intervalo de tiempo no es correcto", + "AutoBackupActivatedMessage": "La copia automática se ha activado", + "SettedEveryMessage": "\nSe establece cada", + "DaysMessage": " días", + "InterruptBackupProcessMessage": "¿Está seguro de que desea detener esta copia?", + "ErrorMessageInputMissingGeneric": "¡Faltan datos de entrada!", + "ErrorMessageForSavingFile": "Error al guardar el archivo", + "ErrorMessageForPathNotExisting": "¡Una o ambas rutas no existen!", + "ErrorMessageForSamePaths": "La ruta inicial y la de destino no pueden ser iguales. ¡Elija rutas diferentes!" + } + } + \ No newline at end of file diff --git a/src/main/resources/res/languages/fra.json b/src/main/resources/res/languages/fra.json new file mode 100644 index 0000000..8d7b449 --- /dev/null +++ b/src/main/resources/res/languages/fra.json @@ -0,0 +1,153 @@ +{ + "General": { + "AppName": "Backup Manager", + "Backup": "Sauvegarde", + "Version": "Version", + "From": "De", + "To": "À", + "OkButton": "OK", + "CancelButton": "Annuler", + "CloseButton": "Fermer", + "ApplyButton": "Appliquer" + }, + "Menu": { + "File": "Fichier", + "Options": "Options", + "About": "À propos", + "Help": "Aide", + "BugReport": "Signaler un bug", + "Clear": "Effacer", + "Donate": "Faire un don", + "History": "Historique", + "InfoPage": "Info", + "New": "Nouveau", + "Quit": "Quitter", + "Save": "Enregistrer", + "SaveWithName": "Enregistrer sous", + "Share": "Partager", + "Support": "Assistance", + "Website": "Site web" + }, + "TabbedFrames": { + "BackupEntry": "Entrée de Sauvegarde", + "BackupList": "Liste de Sauvegardes" + }, + "BackupEntry": { + "PageTitle": "Entrée de Sauvegarde", + "CurrentFile": "Fichier actuel", + "Notes": "Notes", + "LastBackup": "Dernière sauvegarde", + "SingleBackupButton": "Sauvegarde Unique", + "AutoBackupButton": "Sauvegarde Automatique", + "AutoBackupButtonON": "Sauvegarde Automatique (ACTIVÉE)", + "AutoBackupButtonOFF": "Sauvegarde Automatique (DÉSACTIVÉE)", + "InitialPathPlaceholder": "Chemin initial", + "DestinationPathPlaceholder": "Chemin de destination", + "InitialPathTooltip": "(Requis) Chemin initial", + "DestinationPathTooltip": "(Requis) Chemin de destination", + "InitialFileChooserTooltip": "Ouvrir l'explorateur de fichiers", + "DestinationFileChooserTooltip": "Ouvrir l'explorateur de fichiers", + "NotesTooltip": "(Optionnel) Description de la sauvegarde", + "SingleBackupTooltip": "Effectuer la sauvegarde", + "AutoBackupTooltip": "Activer/Désactiver la sauvegarde automatique", + "TimePickerTooltip": "Sélecteur de temps" + }, + "BackupList": { + "BackupNameColumn": "Nom de la Sauvegarde", + "InitialPathColumn": "Chemin Initial", + "DestinationPathColumn": "Chemin de Destination", + "LastBackupColumn": "Dernière Sauvegarde", + "AutomaticBackupColumn": "Sauvegarde Automatique", + "NextBackupDateColumn": "Prochaine Date de Sauvegarde", + "TimeIntervalColumn": "Intervalle de Temps", + "BackupNameDetail": "Nom de la Sauvegarde", + "InitialPathDetail": "Chemin Initial", + "DestinationPathDetail": "Chemin de Destination", + "LastBackupDetail": "Dernière Sauvegarde", + "NextBackupDateDetail": "Prochaine Sauvegarde", + "TimeIntervalDetail": "Intervalle de Temps", + "CreationDateDetail": "Date de Création", + "LastUpdateDateDetail": "Dernière Mise à Jour", + "BackupCountDetail": "Nombre de Sauvegardes", + "NotesDetail": "Notes", + "AddBackupTooltip": "Ajouter une nouvelle sauvegarde", + "ResearchBarTooltip": "Barre de recherche", + "ResearchBarPlaceholder": "Rechercher...", + "EditPopup": "Modifier", + "DeletePopup": "Supprimer", + "DuplicatePopup": "Dupliquer", + "RenameBackupPopup": "Renommer la sauvegarde", + "OpenInitialFolderPopup": "Ouvrir le chemin initial", + "OpenDestinationFolderPopup": "Ouvrir le chemin de destination", + "BackupPopup": "Sauvegarde", + "SingleBackupPopup": "Effectuer une sauvegarde unique", + "AutoBackupPopup": "Sauvegarde automatique", + "CopyTextPopup": "Copier le texte", + "CopyBackupNamePopup": "Copier le nom de la sauvegarde", + "CopyInitialPathPopup": "Copier le chemin initial", + "CopyDestinationPathPopup": "Copier le chemin de destination" + }, + "TimePickerDialog": { + "TimeIntervalTitle": "Intervalle de temps pour les sauvegardes automatiques", + "Description": "Sélectionnez la fréquence des sauvegardes automatiques en \nchoisissant le nombre de jours, d'heures et de minutes.", + "Days": "Jours", + "Hours": "Heures", + "Minutes": "Minutes", + "SpinnerTooltip": "Roulette de la souris pour ajuster la valeur" + }, + "PreferencesDialog": { + "PreferencesTitle": "Préférences", + "Language": "Langue", + "Theme": "Thème" + }, + "ProgressBackupFrame": { + "ProgressBackupTitle": "Sauvegarde en cours", + "StatusCompleted": "Sauvegarde terminée !", + "StatusLoading": "Chargement..." + }, + "TrayIcon": { + "TrayTooltip": "Service de Sauvegardes", + "SuccessMessage": "\nLa sauvegarde a été effectuée avec succès :", + "ErrorMessageInputMissing": "\nErreur lors de la sauvegarde automatique.\nEntrée manquante !", + "ErrorMessageFilesNotExisting": "\nErreur lors de la sauvegarde automatique.\nUn ou les deux chemins n'existent pas !", + "ErrorMessageSamePaths": "\nErreur lors de la sauvegarde automatique.\nLe chemin initial et le chemin de destination ne peuvent pas être identiques. Veuillez choisir des chemins différents !" + }, + "Dialogs": { + "ErrorGenericTitle": "Erreur", + "ErrorMessageForFolderNotExisting": "Le dossier n'existe pas ou est invalide", + "ErrorMessageForSavingFileWithPathsEmpty": "Impossible d'enregistrer le fichier. Les chemins initial et de destination doivent être spécifiés et ne peuvent pas être vides", + "BackupSavedCorrectlyTitle": "Sauvegarde Enregistrée", + "BackupSavedCorrectlyMessage": "enregistrée avec succès.", + "ErrorSavingBackupMessage": "Erreur lors de l'enregistrement de la sauvegarde", + "BackupNameInput": "Nom de la sauvegarde", + "ConfirmationRequiredTitle": "Confirmation requise", + "DuplicatedBackupNameMessage": "Une sauvegarde avec le même nom existe déjà. Voulez-vous l'écraser ?", + "BackupNameAlreadyUsedMessage": "Nom de sauvegarde déjà utilisé !", + "ErrorMessageForIncorrectInitialPath": "Erreur lors de l'opération de sauvegarde : le chemin initial est incorrect !", + "ExceptionMessageTitle": "Erreur...", + "ExceptionMessageClipboardMessage": "Le texte de l'erreur a été copié dans le presse-papiers.", + "ExceptionMessageClipboardButton": "Copier dans le presse-papiers", + "ExceptionMessageReportButton": "Signaler le problème", + "ExceptionMessageReportMessage": "Veuillez signaler cette erreur, soit avec une capture d'écran, soit en copiant le texte d'erreur suivant (il est recommandé de fournir une description des actions effectuées avant l'erreur) :", + "ErrorMessageOpeningWebsite": "Échec de l'ouverture de la page web. Veuillez réessayer.", + "ConfirmationMessageForClear": "Êtes-vous sûr de vouloir effacer les champs ?", + "ConfirmationMessageForUnsavedChanges": "Des modifications non enregistrées existent. Voulez-vous les enregistrer avant de passer à une autre sauvegarde ?", + "ErrorMessageOpenHistoryFile": "Erreur lors de l'ouverture du fichier d'historique.", + "ConfirmationMessageBeforeDeleteBackup": "Êtes-vous sûr de vouloir supprimer cet élément ? Cette action est irréversible.", + "ShareLinkCopiedMessage": "Lien de partage copié dans le presse-papiers !", + "ConfirmationMessageCancelAutoBackup": "Êtes-vous sûr de vouloir annuler les sauvegardes automatiques pour cette entrée ?", + "ErrorMessageUnableToSendEmail": "Impossible d'envoyer l'e-mail. Veuillez réessayer plus tard.", + "ErrorMessageNotSupportedEmail": "Votre système ne prend pas en charge l'envoi d'e-mails directement depuis cette application.", + "ErrorMessageNotSupportedEmailGeneric": "Votre système ne prend pas en charge l'envoi d'e-mails.", + "ErrorWrongTimeInterval": "L'intervalle de temps est incorrect", + "AutoBackupActivatedMessage": "La sauvegarde automatique a été activée", + "SettedEveryMessage": "\nEst défini tous les", + "DaysMessage": " jours", + "InterruptBackupProcessMessage": "Êtes-vous sûr de vouloir arrêter cette sauvegarde ?", + "ErrorMessageInputMissingGeneric": "Entrée manquante !", + "ErrorMessageForSavingFile": "Erreur lors de l'enregistrement du fichier", + "ErrorMessageForPathNotExisting": "Un ou les deux chemins n'existent pas !", + "ErrorMessageForSamePaths": "Le chemin initial et le chemin de destination ne peuvent pas être identiques. Veuillez choisir des chemins différents !" + } + } + \ No newline at end of file diff --git a/src/main/resources/res/languages/ita.json b/src/main/resources/res/languages/ita.json new file mode 100644 index 0000000..e2b2bf0 --- /dev/null +++ b/src/main/resources/res/languages/ita.json @@ -0,0 +1,152 @@ +{ + "General": { + "AppName": "Backup Manager", + "Backup": "Backup", + "Version": "Versione", + "From": "Da", + "To": "A", + "CloseButton": "Chiudi", + "OkButton": "Ok", + "CancelButton": "Annulla", + "ApplyButton":"Applica" + }, + "Menu": { + "File": "File", + "Options": "Opzioni", + "About": "Informazioni", + "Help": "Aiuto", + "BugReport": "Segnala un problema", + "Clear": "Pulisci", + "Donate": "Donazione", + "History": "Storico", + "InfoPage": "Info", + "New": "Nuovo", + "Quit": "Esci", + "Save": "Salva", + "SaveWithName": "Salva con nome", + "Share": "Condividi", + "Support": "Supporto", + "Website": "Sito web" + }, + "TabbedFrames": { + "BackupEntry": "VoceBackup", + "BackupList": "ListaBackup" + }, + "BackupEntry": { + "PageTitle": "Voce di Backup", + "CurrentFile": "File corrente", + "Notes": "Note", + "LastBackup": "Ultimo backup", + "SingleBackupButton": "Backup Singolo", + "AutoBackupButton": "Backup Automatico", + "AutoBackupButtonON": "Backup Automatico (ON)", + "AutoBackupButtonOFF": "Backup Automatico (OFF)", + "InitialPathPlaceholder": "Percorso iniziale", + "DestinationPathPlaceholder": "Percorso di destinazione", + "InitialPathTooltip": "(Obbligatorio) Percorso iniziale", + "DestinationPathTooltip": "(Obbligatorio) Percorso di destinazione", + "InitialFileChooserTooltip": "Apri esplora file", + "DestinationFileChooserTooltip": "Apri esplora file", + "NotesTooltip": "(Opzionale) Descrizione del backup", + "SingleBackupTooltip": "Esegui il backup", + "AutoBackupTooltip": "Attiva/Disattiva backup automatico", + "TimePickerTooltip": "Selettore orario" + }, + "BackupList": { + "BackupNameColumn": "Nome del Backup", + "InitialPathColumn": "Percorso Iniziale", + "DestinationPathColumn": "Percorso di Destinazione", + "LastBackupColumn": "Ultimo Backup", + "AutomaticBackupColumn": "Backup Automatico", + "NextBackupDateColumn": "Data del Prossimo Backup", + "TimeIntervalColumn": "Intervallo di Tempo", + "BackupNameDetail": "NomeBackup", + "InitialPathDetail": "PercorsoIniziale", + "DestinationPathDetail": "PercorsoDestinazione", + "LastBackupDetail": "UltimoBackup", + "NextBackupDateDetail": "ProssimoBackup", + "TimeIntervalDetail": "IntervalloDiTempo", + "CreationDateDetail": "DataCreazione", + "LastUpdateDateDetail": "DataUltimoAggiornamento", + "BackupCountDetail": "ConteggioBackup", + "NotesDetail": "Note", + "AddBackupTooltip": "Aggiungi nuovo backup", + "ResearchBarTooltip": "Barra di ricerca", + "ResearchBarPlaceholder": "cerca...", + "EditPopup": "Modifica", + "DeletePopup": "Elimina", + "DuplicatePopup": "Duplica", + "RenameBackupPopup": "Rinomina backup", + "OpenInitialFolderPopup": "Apri percorso iniziale", + "OpenDestinationFolderPopup": "Apri percorso di destinazione", + "BackupPopup": "Backup", + "SingleBackupPopup": "Esegui backup singolo", + "AutoBackupPopup": "Backup automatico", + "CopyTextPopup": "Copia testo", + "CopyBackupNamePopup": "Copia nome backup", + "CopyInitialPathPopup": "Copia percorso iniziale", + "CopyDestinationPathPopup": "Copia percorso di destinazione" + }, + "TimePickerDialog": { + "TimeIntervalTitle": "Intervallo di tempo per backup automatico", + "Description": "Seleziona la frequenza del backup automatico \nscegliendo la frequenza in giorni, ore e minuti.", + "Days": "Giorni", + "Hours": "Ore", + "Minutes": "Minuti", + "SpinnerTooltip": "Usa la rotellina per regolare il valore" + }, + "PreferencesDialog": { + "PreferencesTitle": "Preferenze", + "Language": "Lingua", + "Theme": "Tema" + }, + "ProgressBackupFrame": { + "ProgressBackupTitle": "Backup in corso", + "StatusCompleted": "Backup completato!", + "StatusLoading": "Caricamento..." + }, + "TrayIcon": { + "TrayTooltip": "Servizio di Backup", + "SuccessMessage": "\nIl backup è stato completato con successo:", + "ErrorMessageInputMissing": "\nErrore durante il backup automatico.\nPercorso mancante!", + "ErrorMessageFilesNotExisting": "\nErrore durante il backup automatico.\nUno o entrambi i percorsi non esistono!", + "ErrorMessageSamePaths": "\nErrore durante il backup automatico.\nIl percorso iniziale e il percorso di destinazione non possono essere uguali. Scegli percorsi diversi!" + }, + "Dialogs": { + "ErrorGenericTitle": "Errore", + "ErrorMessageForFolderNotExisting": "La cartella non esiste o non è valida", + "ErrorMessageForSavingFileWithPathsEmpty": "Impossibile salvare il file. Entrambi i percorsi iniziale e di destinazione devono essere specificati e non possono essere vuoti", + "BackupSavedCorrectlyTitle": "Backup salvato", + "BackupSavedCorrectlyMessage": "salvato con successo!", + "ErrorSavingBackupMessage": "Errore durante il salvataggio del backup", + "BackupNameInput": "Nome del backup", + "ConfirmationRequiredTitle": "Conferma richiesta", + "DuplicatedBackupNameMessage": "Esiste già un backup con lo stesso nome, vuoi sovrascriverlo?", + "BackupNameAlreadyUsedMessage": "Nome del backup già utilizzato!", + "ErrorMessageForIncorrectInitialPath": "Errore durante il backup: il percorso iniziale è errato!", + "ExceptionMessageTitle": "Errore...", + "ExceptionMessageClipboardMessage": "Il testo dell'errore è stato copiato negli appunti.", + "ExceptionMessageClipboardButton":"Copia negli appunti", + "ExceptionMessageReportButton":"Riporta il problema", + "ExceptionMessageReportMessage": "Si prega di segnalare questo errore, allegando un'immagine dello schermo o copiando il seguente testo dell'errore (è apprezzato fornire una descrizione delle operazioni eseguite prima dell'errore):", + "ErrorMessageOpeningWebsite": "Impossibile aprire la pagina web. Riprova.", + "ConfirmationMessageForClear": "Sei sicuro di voler pulire i campi?", + "ConfirmationMessageForUnsavedChanges": "Ci sono modifiche non salvate, vuoi salvarle prima di passare a un altro backup?", + "ErrorMessageOpenHistoryFile": "Errore durante l'apertura del file storico.", + "ConfirmationMessageBeforeDeleteBackup": "Sei sicuro di voler eliminare questo elemento? Nota: questa azione non può essere annullata.", + "ShareLinkCopiedMessage": "Link di condivisione copiato negli appunti!", + "ConfirmationMessageCancelAutoBackup": "Sei sicuro di voler annullare il backup automatico?", + "ErrorMessageUnableToSendEmail": "Impossibile inviare l'email. Riprova più tardi.", + "ErrorMessageNotSupportedEmail": "Il tuo sistema non supporta l'invio di email direttamente da questa applicazione.", + "ErrorMessageNotSupportedEmailGeneric": "Il tuo sistema non supporta l'invio di email.", + "ErrorWrongTimeInterval":"L'intervallo di tempo non è corretto", + "AutoBackupActivatedMessage": "Backup Automatico attivato", + "SettedEveryMessage": "\nImpostato ogni", + "DaysMessage": " giorni", + "InterruptBackupProcessMessage": "Sei sicuro di voler interrompere questo backup?", + "ErrorMessageInputMissingGeneric": "Input Mancanti!", + "ErrorMessageForSavingFile": "Errore nel salvataggio del file", + "ErrorMessageForPathNotExisting": "Uno o entrambi i percorsi non esistono!", + "ErrorMessageForSamePaths": "Il percorso iniziale e il percorso di destinazione non possono essere uguali. Si prega di scegliere percorsi diversi!" + } +} \ No newline at end of file diff --git a/src/test/java/test/TestBackupManagerGUI.java b/src/test/java/test/TestBackupManagerGUI.java index 1c01b6a..b0f4aa6 100644 --- a/src/test/java/test/TestBackupManagerGUI.java +++ b/src/test/java/test/TestBackupManagerGUI.java @@ -1,8 +1,9 @@ package test; -import com.mycompany.autobackupprogram.BackupManagerGUI; - import org.junit.jupiter.api.BeforeEach; + +import com.mycompany.autobackupprogram.GUI.BackupManagerGUI; + import org.junit.jupiter.api.AfterEach; public class TestBackupManagerGUI { diff --git a/src/test/java/test/TestConfigKey.java b/src/test/java/test/TestConfigKey.java index 45512b2..419ab71 100644 --- a/src/test/java/test/TestConfigKey.java +++ b/src/test/java/test/TestConfigKey.java @@ -1,14 +1,12 @@ package test; -import com.mycompany.autobackupprogram.ConfigKey; -import com.mycompany.autobackupprogram.Logger; +import com.mycompany.autobackupprogram.Enums.ConfigKey; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; import java.nio.file.Files; -import java.nio.file.StandardOpenOption; import java.io.File; import java.io.IOException; diff --git a/src/test/java/test/TestJSONAutoBackup.java b/src/test/java/test/TestJSONAutoBackup.java index d8bdcec..992f1d2 100644 --- a/src/test/java/test/TestJSONAutoBackup.java +++ b/src/test/java/test/TestJSONAutoBackup.java @@ -1,7 +1,7 @@ package test; -import com.mycompany.autobackupprogram.IJSONAutoBackup; import com.mycompany.autobackupprogram.JSONAutoBackup; +import com.mycompany.autobackupprogram.Interfaces.IJSONAutoBackup; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.AfterEach;