diff --git a/muon-app/pom.xml b/muon-app/pom.xml index c7ea71dc..5901c15c 100644 --- a/muon-app/pom.xml +++ b/muon-app/pom.xml @@ -7,7 +7,7 @@ muon muon - 0.0.1-SNAPSHOT + 1.2.0 muon-app muon-app @@ -144,7 +144,7 @@ com.hierynomus sshj - 0.28.0 + 0.31.0 @@ -172,7 +172,7 @@ - muon-${project.version} + muon_${project.version} org.apache.maven.plugins @@ -209,7 +209,7 @@ jar-with-dependencies false - muon-${project.version}-full + muon_${project.version} false @@ -229,6 +229,70 @@ + + jdeb + org.vafer + 1.7 + + + package + + jdeb + + + ${basedir}/src/deb/control + ${project.build.directory}/muon_${project.version}.deb + + + ${basedir}/src/deb/opt/muon/muon-logo.png + file + + perm + /opt/muon/muon-logo.png + loader + loader + 644 + + + + ${basedir}/src/deb/usr/share/applications/muon.desktop + file + + perm + /usr/share/applications + loader + loader + 644 + + + + ${basedir}/src/deb/usr/bin/muon + file + + perm + /usr/bin + loader + loader + 755 + + + + ${project.build.directory}/${project.build.finalName}.jar + file + muon.jar + + perm + /opt/muon + loader + loader + 644 + + + + + + + diff --git a/muon-app/src/deb/control/control b/muon-app/src/deb/control/control new file mode 100644 index 00000000..6a4d6cbe --- /dev/null +++ b/muon-app/src/deb/control/control @@ -0,0 +1,10 @@ +Package: muon +Version: 1.2.0 +Section: base +Priority: optional +Architecture: all +Depends: openjdk-11-jre +Maintainer: Subhra Das Gupta +Description: Muon is a modern graphical SSH client + Muon is a modern graphical SSH client which provides + simple easy to use GUI for common tasks diff --git a/muon-app/src/deb/opt/muon/muon-logo.png b/muon-app/src/deb/opt/muon/muon-logo.png new file mode 100644 index 00000000..ff9e660f Binary files /dev/null and b/muon-app/src/deb/opt/muon/muon-logo.png differ diff --git a/muon-app/src/deb/usr/bin/muon b/muon-app/src/deb/usr/bin/muon new file mode 100755 index 00000000..03401118 --- /dev/null +++ b/muon-app/src/deb/usr/bin/muon @@ -0,0 +1,2 @@ +#!/bin/sh +java -jar /opt/muon/muon.jar diff --git a/muon-app/src/deb/usr/share/applications/muon.desktop b/muon-app/src/deb/usr/share/applications/muon.desktop new file mode 100755 index 00000000..c4accb36 --- /dev/null +++ b/muon-app/src/deb/usr/share/applications/muon.desktop @@ -0,0 +1,5 @@ +[Desktop Entry] +Name=Muon SSH client +Exec=/usr/bin/muon +Icon=/opt/muon/muon-logo.png +Type=Application diff --git a/muon-app/src/main/java/muon/app/App.java b/muon-app/src/main/java/muon/app/App.java index 967e4aa1..fcf8537c 100644 --- a/muon-app/src/main/java/muon/app/App.java +++ b/muon-app/src/main/java/muon/app/App.java @@ -7,11 +7,7 @@ //import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.Security; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.UUID; +import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -41,6 +37,7 @@ import muon.app.ui.laf.AppSkinDark; import muon.app.ui.laf.AppSkinLight; import muon.app.updater.VersionEntry; +import util.Language; import util.PlatformUtils; import util.Win32DragHandler; @@ -79,9 +76,11 @@ public class App { public static final String APP_INSTANCE_ID = UUID.randomUUID().toString(); public static GraphicalHostKeyVerifier HOST_KEY_VERIFIER; + public static ResourceBundle bundle; public static void main(String[] args) throws UnsupportedLookAndFeelException { - + + Security.addProvider(new BouncyCastleProvider()); @@ -117,6 +116,16 @@ public static void main(String[] args) throws UnsupportedLookAndFeelException { System.out.println("Searching for known editors...done"); } + Language language= null; + if (settings.getLanguage() == null){ + language=Language.ENGLISH; + } else { + language=settings.getLanguage(); + } + Locale locale = new Locale(language.getLangAbbr()); + + bundle = ResourceBundle.getBundle("muon.app.common.i18n.Messages", locale); + SKIN = settings.isUseGlobalDarkTheme() ? new AppSkinDark() : new AppSkinLight(); UIManager.setLookAndFeel(SKIN.getLaf()); @@ -174,6 +183,23 @@ public synchronized static void loadSettings() { settings = new Settings(); } + public synchronized static Settings loadSettings2() { + File file = new File(CONFIG_DIR, CONFIG_DB_FILE); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + if (file.exists()) { + try { + settings = objectMapper.readValue(file, new TypeReference() { + }); + return settings; + } catch (IOException e) { + e.printStackTrace(); + } + } + settings = new Settings(); + return settings; + } + public synchronized static void saveSettings() { File file = new File(CONFIG_DIR, CONFIG_DB_FILE); ObjectMapper objectMapper = new ObjectMapper(); diff --git a/muon-app/src/main/java/muon/app/Settings.java b/muon-app/src/main/java/muon/app/Settings.java index d6562e69..e2774e73 100644 --- a/muon-app/src/main/java/muon/app/Settings.java +++ b/muon-app/src/main/java/muon/app/Settings.java @@ -11,6 +11,7 @@ import muon.app.ui.components.settings.DarkTerminalTheme; import muon.app.ui.components.settings.EditorEntry; import util.CollectionHelper; +import util.Language; public class Settings { private boolean usingMasterPassword = false; @@ -40,6 +41,7 @@ public class Settings { private boolean terminalBell = false; private String terminalFontName = "NotoMono-Regular"; private int terminalFontSize = 14; + private Language language = Language.ENGLISH; private String terminalTheme = "Dark"; private String terminalPalette = "xterm"; private int[] palleteColors = { 0x000000, 0xcd0000, 0x00cd00, 0xcdcd00, 0x1e90ff, 0xcd00cd, 0x00cdcd, 0xe5e5e5, @@ -402,6 +404,22 @@ public void setTerminalTheme(String terminalTheme) { this.terminalTheme = terminalTheme; } + /** + * + * @return Language + */ + public Language getLanguage() { + return language; + } + + /** + * + * @param language + */ + public void setLanguage(Language language) { + this.language = language; + } + /** * @return the terminalPalette */ diff --git a/muon-app/src/main/java/muon/app/common/FileInfo.java b/muon-app/src/main/java/muon/app/common/FileInfo.java index fb2d65bd..9daea201 100644 --- a/muon-app/src/main/java/muon/app/common/FileInfo.java +++ b/muon-app/src/main/java/muon/app/common/FileInfo.java @@ -7,10 +7,10 @@ import util.TimeUtils; -public class FileInfo implements Serializable, Comparable { +public class FileInfo implements Serializable { private static final Pattern USER_REGEX = Pattern .compile("^[^\\s]+\\s+[^\\s]+\\s+([^\\s]+)\\s+([^\\s]+)"); - private String name; + private final String name; private String path; private long size; private FileType type; @@ -24,9 +24,9 @@ public class FileInfo implements Serializable, Comparable { private boolean hidden; public FileInfo(String name, String path, long size, FileType type, - long lastModified, int permission, String protocol, - String permissionString, long created, String extra, - boolean hidden) { + long lastModified, int permission, String protocol, + String permissionString, long created, String extra, + boolean hidden) { super(); this.name = name; this.path = path; @@ -172,26 +172,7 @@ public void setHidden(boolean hidden) { this.hidden = hidden; } - @Override - public int compareTo(FileInfo o) { - if (getType() == FileType.Directory || getType() == FileType.DirLink) { - if (o.getType() == FileType.Directory - || o.getType() == FileType.DirLink) { - return getName().compareToIgnoreCase(o.getName()); - } else { - return 1; - } - } else { - if (o.getType() == FileType.Directory - || o.getType() == FileType.DirLink) { - return -1; - } else { - return getName().compareToIgnoreCase(o.getName()); - } - } -// if (o != null && o.getName() != null) { -// return getName().compareToIgnoreCase(o.getName()); -// } -// return 1; + public boolean isDirectory() { + return getType() == FileType.Directory || getType() == FileType.DirLink; } } diff --git a/muon-app/src/main/java/muon/app/common/i18n/Messages_en.java b/muon-app/src/main/java/muon/app/common/i18n/Messages_en.java new file mode 100644 index 00000000..fb987ccf --- /dev/null +++ b/muon-app/src/main/java/muon/app/common/i18n/Messages_en.java @@ -0,0 +1,270 @@ +package muon.app.common.i18n; + +import javax.swing.*; +import java.util.ListResourceBundle; + +public class Messages_en extends ListResourceBundle { + + @Override + protected Object[][] getContents() { + + return resources; + } + + private final Object[][] resources = { + + {"general", "General"}, + {"terminal", "Terminal"}, + {"editor", "Editor"}, + {"display", "Display"}, + {"security", "Security"}, + {"sessions", "Sessions"}, + {"settings", "Settings"}, + {"add", "Add"}, + {"chk_update", "Check updates"}, + {"new_site", "New site"}, + {"new_folder", "New folder"}, + {"duplicate", "Duplicate"}, + {"connect", "Connect"}, + {"cancel", "Cancel"}, + {"export", "Export"}, + {"import", "Import"}, + {"name", "Name"}, + {"connecting", "Connecting..."}, + {"import_from", "Import from"}, + {"import_sessions", "Import sessions"}, + {"save", "Save"}, + {"reset", "Reset"}, + {"remove", "Remove"}, + {"edit", "Edit"}, + {"generate", "Generate"}, + {"new_entry", "New entry"}, + {"connection", "Conexion"}, + {"directories", "Directorios"}, + {"proxy", "Proxy"}, + {"jump_hosts", "Jump Hosts"}, + {"port_forwarding", "Port Forwarding"}, + {"user", "User"}, + {"host", "Host"}, + {"port", "Port"}, + {"password", "Password"}, + {"local_folder", "Local folder"}, + {"remote_folder", "Remote folder"}, + {"browse", "Browse"}, + {"session_manager", "Session manager"}, + {"private_key_file", "Private key file"}, + {"proxy_type", "Proxy type"}, + {"proxy_host", "Proxy host"}, + {"proxy_port", "Proxy port"}, + {"proxy_user", "Proxy user"}, + {"proxy_password", "Proxy password"}, + {"warning_plain_text", " ( Warning: it will be saved in plain text! )"}, + {"overwrite", "Overwrite"}, + {"auto_rename", "Auto-rename"}, + {"skip", "Skip"}, + {"prompt", "Prompt"}, + {"settings_saved", "Settings have been reset,\nplease save and restart the app"}, + {"columns", "Columns"}, + {"rows", "Rows"}, + {"font_name", "Font name"}, + {"font_size", "Font size"}, + {"copy_like_putty", "PuTTY like copy paste (Copy on select and paste on right click)"}, + {"terminal_type", "Terminal type"}, + {"initial_terminal_type", "Initial terminal type"}, + {"sound", "Sound"}, + {"terminal_font", "Terminal font"}, + {"misc", "Misc"}, + {"terminal_colors", "Terminal colors and themes"}, + {"terminal_theme", "Terminal theme"}, + {"default_color", "Default color"}, + {"text", "Text"}, + {"background", "Background"}, + {"selection_color", "Selection color"}, + {"search_pattern", "Search pattern"}, + {"color_palette", "Color palette"}, + {"terminal_shortcuts", "Terminal shortcuts"}, + {"confirm_delete_files", "Confirm before deleting files"}, + {"confirm_move_files", "Confirm before moving or copying files"}, + {"show_hidden_files", "Show hidden files by default"}, + {"prompt_for_sudo", "Prompt for sudo if operation fails due to permission issues"}, + {"directory_caching", "Use directory caching"}, + {"current_folder", "Show current folder in path bar style"}, + {"show_banner", "Show banner"}, + {"word_wrap", "Word wrap on log viewer"}, + {"transfer_normally", "Transfer normally"}, + {"transfer_background", "Transfer in background"}, + {"transfer_mode", "Transfer mode"}, + {"conflict_action", "Conflict action"}, + {"add_editor", "+ Add editor"}, + {"remove_editor", "- Del editor"}, + {"editor_name", "Editor name"}, + {"add_editor2", "Add editor?"}, + {"zoom_text", "Zoom (Make application look small or big on screen)"}, + {"global_dark_theme", "Use global dark theme (Needs restart)"}, + {"zoom_percentage", "Zoom percentage"}, + {"new_master_password", "New master password"}, + {"reenter_master_password", "Re-enter master password"}, + {"master_password", "Master password"}, + {"use_master_password", "Use master password"}, + {"change_master_password", "Change master password"}, + {"change_password_failed", "Password change failed!"}, + {"error_operation", "Error encountered during operation"}, + {"password_aes", "Your save passwords are protected by AES encryption"}, + {"password_unprotected", "Your save passwords are unprotected now"}, + {"password_no_match", "Passwords do not match"}, + {"unsupported_key", "This key format is not supported, please convert it to OpenSSH format"}, + {"copy", "Copy"}, + {"paste", "Paste"}, + {"select_all", "Select All"}, + {"clear_buffer", "Clear buffer"}, + {"find", "Encontrar"}, + {"cut", "Cortar"}, + {"path_executable", "Path to executable"}, + {"file_browser", "File browser"}, + {"server_logs", "Server logs"}, + {"file_search", "File search"}, + {"diskspace", "Diskspace"}, + {"toolbox", "Toolbox"}, + {"processes", "Processes"}, + {"pid", "PID"}, + {"total_processes", "Total processes:"}, + {"last_updated", "Last updated:"}, + {"analize_folder", "Analize folder"}, + {"analize_volume", "Analize volume"}, + {"next", "Next"}, + {"back", "Back"}, + {"reload", "Reload"}, + {"modified", "Modified"}, + {"size", "Size"}, + {"type", "Type"}, + {"permission", "Permissions"}, + {"owner", "Owner"}, + {"show_hidden_files2", "Show hidden files"}, + {"bookmarks", "Bookmarks"}, + {"select_partition", "Please select a partition"}, + {"select_volume", "Please select a volume"}, + {"filesystem", "Filesystem"}, + {"total_size", "Total size"}, + {"used", "Used"}, + {"available", "Available"}, + {"percentage_use", "% used"}, + {"mount_point", "Mount point"}, + {"directory_usage", "Directory diskusage"}, + {"start_another_analysis", "Start another analysis"}, + {"delete", "Delete"}, + {"send_files", "Send files"}, + {"add_from_manager", "Add from session manager"}, + {"add_log", "Add log"}, + {"insert", "Insert"}, + {"open", "Open"}, + {"rename", "Rename"}, + {"new_file", "New file"}, + {"bookmark", "Bookmark"}, + {"open_new_tab", "Open in a new tab"}, + {"enter_new_name", "Please enter new name"}, + {"open_in_terminal", "Open in terminal"}, + {"copy_path", "Copy path"}, + {"searching", "Searching"}, + {"idle", "Idle"}, + {"in_filename", "In filename (like *.zip or R*ME.txt)"}, + {"in_filecontent", "In file contet"}, + {"in_compressed_files", "In compressed files"}, + {"search_for", "Search for"}, + {"search_in", "Search in"}, + {"any_time", "Any time"}, + {"this_week", "This week"}, + {"between", "Between"}, + {"from", "From"}, + {"to", "To"}, + {"ready", "Ready"}, + {"look_for", "Look for"}, + {"both_file_folder", "Both file and folder"}, + {"file_only", "Only file"}, + {"folder_only", "Only folder"}, + {"show_location", "Show location"}, + {"filename", "Filename"}, + {"path", "Path"}, + {"filter", "Filter"}, + {"clear", "Clear"}, + {"refresh", "Refresh"}, + {"kill", "Kill"}, + {"kill_sudo", "Kill using sudo"}, + {"change_priority", "Change priority"}, + {"change_priority_sudo", "Change priority with sudo"}, + {"copy_command", "Copy command"}, + {"kill_process", "Kill process"}, + {"system_info", "System info"}, + {"system_load", "System load"}, + {"services_systemd", "Services - systemd"}, + {"process_ports", "Process and ports"}, + {"ssh_keys", "SSH keys"}, + {"network_tools", "Network tools"}, + {"cpu_usage", "CPU usage"}, + {"memory_usage", "Memory usage"}, + {"swap_usage", "Swap usage"}, + {"used2", "Used"}, + {"generate_new_key", "Generate new key"}, + {"public_key_file", "Public key file:"}, + {"refresh_interval", "Refresh interval"}, + {"start", "Start"}, + {"stop", "Stop"}, + {"restart", "Restart"}, + {"reload", "Reload"}, + {"enable", "Enable"}, + {"disable", "Disable"}, + {"actions_sudo", "Do actions with super user (sudo)"}, + {"operation_failed", "Operation failed"}, + {"status", "Status"}, + {"state", "State"}, + {"description", "Description"}, + {"source_port", "Source port"}, + {"target_port", "Target port"}, + {"bind_host", "Bind host"}, + {"local", "Local"}, + {"remote", "Remote"}, + {"invalid_input", "Invalid input: all fields are mandatory"}, + {"host_ping", "Host ping"}, + {"host_name", "Host name"}, + {"port_number", "Port number"}, + {"tool_use", "Tool to use"}, + {"executed_errors", "Executed with errors"}, + {"configure_editor", "Configure editor"}, + {"open_log_viewer", "Open with log viewer"}, + {"open_in_tab", "Open in tab"}, + {"open_with", "Open with..."}, + {"send_another_server", "Send to another server"}, + {"send_over_ftp", "Send over ftp"}, + {"send_this_computer", "Send this computer"}, + {"run_in_terminal", "Run in terminal"}, + {"open_folder_terminal", "Open folder in terminal"}, + {"open_terminal_here", "Open terminal here"}, + {"run_file_in_terminal", "Run file in terminal"}, + {"run_file_in_background", "Run file in background"}, + {"edit_with", "Edit with"}, + {"properties", "Properties"}, + {"create_link", "Create link"}, + {"extract_here", "Extract here"}, + {"extract_to", "Extract to"}, + {"selec_target", "Select target folder to extract"}, + {"create_archive", "Create archive"}, + {"download_files", "Download selected files"}, + {"upload_here", "Upload here"}, + {"please_new_name", "Please enter the new name"}, + {"open_as_url", "Open as URL"}, + {"page_up", "Page up"}, + {"page_down", "Page down"}, + {"line_up", "Line up"}, + {"line_down", "Line down"}, + {"search", "Search"}, + {"no_entry_selected", "No entry has been selected"}, + {"authorized_keys", "Authorized keys"}, + {"local_computer", "Local Computer"}, + {"server", "Server"}, + {"language", "Language"}, + {"log_viewer_lines", "Log viewer lines per page" }, + {"log_viewer_font_size", "Log viewer font size"}, + {"system_refresh_interval", "System load refresh interval (sec) "} + + + }; +} diff --git a/muon-app/src/main/java/muon/app/common/i18n/Messages_es.java b/muon-app/src/main/java/muon/app/common/i18n/Messages_es.java new file mode 100644 index 00000000..4ad406f9 --- /dev/null +++ b/muon-app/src/main/java/muon/app/common/i18n/Messages_es.java @@ -0,0 +1,269 @@ +package muon.app.common.i18n; + +import javax.swing.*; +import java.util.ListResourceBundle; + +public class Messages_es extends ListResourceBundle { + + @Override + protected Object[][] getContents() { + + return resources; + } + + private final Object[][] resources = { + + {"general", "General"}, + {"terminal", "Terminal"}, + {"editor", "Editor"}, + {"display", "Pantalla"}, + {"security", "Seguridad"}, + {"sessions", "Sesiones"}, + {"settings", "Configuraciones"}, + {"add", "Agregar"}, + {"chk_update", "Revisar actualizaciones"}, + {"new_site", "Nuevo sitio"}, + {"new_folder", "Nueva carpeta"}, + {"duplicate", "Duplicar"}, + {"connect", "Conectar"}, + {"cancel", "Cancelar"}, + {"export", "Exportar"}, + {"import", "Importar"}, + {"name", "Nombre"}, + {"connecting", "Conectando..."}, + {"import_from", "Importar desde"}, + {"import_sessions", "Importar sesiones"}, + {"save", "Guardar"}, + {"reset", "Restaurar"}, + {"remove", "Eliminar"}, + {"edit", "Editar"}, + {"generate", "Generar"}, + {"new_entry", "Nueva entrada"}, + {"connection", "Conexion"}, + {"directories", "Directorios"}, + {"proxy", "Proxy"}, + {"jump_hosts", "Jump Hosts"}, + {"port_forwarding", "Port Forwarding"}, + {"user", "Usuario"}, + {"host", "Servidor"}, + {"port", "Puerto"}, + {"password", "Clave"}, + {"local_folder", "Carpeta local"}, + {"remote_folder", "Carpeta remota"}, + {"browse", "Buscar"}, + {"session_manager", "Administrador de sesiones"}, + {"private_key_file", "Archivo de llave privada"}, + {"proxy_type", "Tipo de proxy"}, + {"proxy_host", "Servidor proxy"}, + {"proxy_port", "Puerto proxy"}, + {"proxy_user", "Usuario proxy"}, + {"proxy_password", "Clave proxy"}, + {"warning_plain_text", " ( Advertencia: sera guardado en texto plano! )"}, + {"overwrite", "Sobreescribir"}, + {"auto_rename", "Auto-renombrar"}, + {"skip", "Ignorar"}, + {"prompt", "Preguntar"}, + {"settings_saved", "Se restablecieron los ajustes, \npor favor guarde y reinicie la aplicación"}, + {"columns", "Columnas"}, + {"rows", "Filas"}, + {"font_name", "Nombre fuente"}, + {"font_size", "Tamaño fuente"}, + {"copy_like_putty", "Copiar y pegar como PuTTY (copiar al seleccionar y pegar al hacer clic derecho)"}, + {"terminal_type", "Tipo de terminal"}, + {"initial_terminal_type", "Tamaño inicial de la terminal"}, + {"sound", "Sonido"}, + {"terminal_font", "Fuente Terminal"}, + {"misc", "Misc"}, + {"terminal_colors", "Colores y temas de la terminal"}, + {"terminal_theme", "Tema de la terminal"}, + {"default_color", "Color por defecto"}, + {"text", "Texto"}, + {"background", "Background"}, + {"selection_color", "Seleccion color"}, + {"search_pattern", "Patron de busqueda"}, + {"color_palette", "Paleta de Color"}, + {"terminal_shortcuts", "Atajos de terminal"}, + {"confirm_delete_files", "Confirmar antes de eliminar archivos"}, + {"confirm_move_files", "Confirmar antes de mover o copiar archivos"}, + {"show_hidden_files", "Mostrar archivos ocultos por defecto"}, + {"prompt_for_sudo", "Preguntar por sudo si la operacion falla debido a permisos"}, + {"directory_caching", "Usar caching de directorios"}, + {"current_folder", "Mostrar carpeta actual en la ruta de la barra"}, + {"show_banner", "Mostrar banner"}, + {"word_wrap", "Word wrap on log viewer"}, + {"transfer_normally", "Transferencia normal"}, + {"transfer_background", "Transferencia en background"}, + {"transfer_mode", "Modo de transferencia"}, + {"conflict_action", "Accion en conflicto"}, + {"add_editor", "+ Agregar editor"}, + {"remove_editor", "- Eliminar editor"}, + {"editor_name", "Nombre editor"}, + {"add_editor2", "Add editor?"}, + {"zoom_text", "Zoom (Hacer que la aplicacion parezca grande o pequeña en pantalla"}, + {"global_dark_theme", "Usar tema oscuro global (necesita reiniciar)"}, + {"zoom_percentage", "Porcentaje de Zoom"}, + {"new_master_password", "Nueva clave maestra"}, + {"reenter_master_password", "Reingrese la clave maestra"}, + {"master_password", "Clave maestra"}, + {"use_master_password", "Usar clave maestra"}, + {"change_master_password", "Cambiar clave maestra"}, + {"change_password_failed", "Cambio de clave fallo!"}, + {"error_operation", "Error durante la operacion"}, + {"password_aes", "Tus claves guardadas estan protegidas por el cifrado AES"}, + {"password_unprotected", "Tus claves ya no estan protegidas"}, + {"password_no_match", "Las claves no coinciden"}, + {"unsupported_key", "Este formato de clave no es compatible, conviértalo al formato OpenSSH"}, + {"copy", "Copiar"}, + {"paste", "Pegar"}, + {"select_all", "Seleccionar todo"}, + {"clear_buffer", "Limpiar buffer"}, + {"find", "Encontrar"}, + {"cut", "Cortar"}, + {"path_executable", "Ruta del ejecutable"}, + {"file_browser", "Buscador de archivo"}, + {"server_logs", "Logs servidor"}, + {"file_search", "Buscar archivo"}, + {"diskspace", "Espacio disco"}, + {"toolbox", "Herramientas"}, + {"processes", "Procesos"}, + {"pid", "PID"}, + {"total_processes", "Total procesos:"}, + {"last_updated", "Ultima actualizacion:"}, + {"analize_folder", "Analizar carpeta"}, + {"analize_volume", "Analizar volumen"}, + {"next", "Siguiente"}, + {"back", "Regresar"}, + {"reload", "Recargar"}, + {"modified", "Modificado"}, + {"size", "Tamaño"}, + {"type", "Tipo"}, + {"permission", "Permisos"}, + {"owner", "Dueño"}, + {"show_hidden_files2", "Mostrar archivos ocultos"}, + {"bookmarks", "Marcadores"}, + {"select_partition", "Por favor seleccione una particion"}, + {"select_volume", "Por favor seleccione un volumen"}, + {"filesystem", "Sistema archivos"}, + {"total_size", "Tamaño total"}, + {"used", "Uso"}, + {"available", "Disponible"}, + {"percentage_use", "% usado"}, + {"mount_point", "Punto montaje"}, + {"directory_usage", "Espacio utilizado por el directorio"}, + {"start_another_analysis", "Iniciar otro analisis"}, + {"delete", "Eliminar"}, + {"send_files", "Enviar archivos"}, + {"add_from_manager", "Agregar desde el administrador de sesiones"}, + {"add_log", "Agregar log"}, + {"insert", "Insertar"}, + {"open", "Abrir"}, + {"rename", "Renombrar"}, + {"new_file", "Nuevo archivo"}, + {"bookmark", "Marcador"}, + {"open_new_tab", "Abrir en una pestaña nueva"}, + {"enter_new_name", "Por favor ingrese el nuevo nombre"}, + {"open_in_terminal", "Abrir en terminal"}, + {"copy_path", "Copiar ruta"}, + {"searching", "Buscando"}, + {"idle", "Inactivo"}, + {"in_filename", "En nombre archivo (como *.zip o R*ME.txt)"}, + {"in_filecontent", "En el contenido del archivo"}, + {"in_compressed_files", "Buscar en archivos comprimidos"}, + {"search_for", "Buscar por"}, + {"search_in", "Buscar en"}, + {"any_time", "Cualquier momento"}, + {"this_week", "Esta semana"}, + {"between", "Entre"}, + {"from", "Desde"}, + {"to", "Hasta"}, + {"ready", "Listo"}, + {"look_for", "Buscar por"}, + {"both_file_folder", "Por archivo y carpeta"}, + {"file_only", "Solo archivo"}, + {"folder_only", "Solo carpeta"}, + {"show_location", "Mostrar ubicacion"}, + {"filename", "Nombre archivo"}, + {"path", "Ruta"}, + {"filter", "Filtro"}, + {"clear", "Limpiar"}, + {"refresh", "Actualizar"}, + {"kill", "Matar"}, + {"kill_sudo", "Matar usando sudo"}, + {"change_priority", "Cambiar prioridad"}, + {"change_priority_sudo", "Cambiar prioridad con sudo"}, + {"copy_command", "Comando copiar"}, + {"kill_process", "Matar proceso"}, + {"system_info", "Info. Sistema"}, + {"system_load", "Carga sistema"}, + {"services_systemd", "Servicios - systemd"}, + {"process_ports", "Procesos y puertos"}, + {"ssh_keys", "Llaves ssh"}, + {"network_tools", "Herramientas de red"}, + {"cpu_usage", "Uso cpu"}, + {"memory_usage", "Uso memoria"}, + {"swap_usage", "Uso swap"}, + {"used2", "Usado"}, + {"generate_new_key", "Generar nueva llave"}, + {"public_key_file", "Archivo de llave publica:"}, + {"refresh_interval", "Intervalo de actualizacion"}, + {"start", "Iniciar"}, + {"stop", "Detener"}, + {"restart", "Reiniciar"}, + {"reload", "Recargar"}, + {"enable", "Habilitar"}, + {"disable", "Deshabilitar"}, + {"actions_sudo", "Realizar acciones con super usuario (sudo)"}, + {"operation_failed", "Operacion fallida"}, + {"status", "Status"}, + {"state", "Estado"}, + {"description", "Descripcion"}, + {"source_port", "Puerto inicio"}, + {"target_port", "Puerto destino"}, + {"bind_host", "Servidor a unir"}, + {"local", "Local"}, + {"remote", "Remoto"}, + {"invalid_input", "Ingreso invalid: todos los campos son obligatorios"}, + {"host_ping", "Ping al servidor"}, + {"host_name", "Nombre del servidor"}, + {"port_number", "Numero de puerto"}, + {"tool_use", "Herramienta a usar"}, + {"executed_errors", "Ejecutado con errores"}, + {"configure_editor", "Editor de configuracion"}, + {"open_log_viewer", "Abrir con el visor de logs"}, + {"open_in_tab", "Abrir en nueva pestaña"}, + {"open_with", "Abrir con..."}, + {"send_another_server", "Enviar por otro servidor"}, + {"send_over_ftp", "Enviar por ftp"}, + {"send_this_computer", "Enviar a este computador"}, + {"run_in_terminal", "Ejecutar en terminal"}, + {"open_folder_terminal", "Abrir carpeta en terminal"}, + {"open_terminal_here", "Abri terminal aqui"}, + {"run_file_in_terminal", "Ejecutar archivo en terminal"}, + {"run_file_in_background", "Ejecutar archivo en background"}, + {"edit_with", "Edit con"}, + {"properties", "Propiedades"}, + {"create_link", "Crear vinculo"}, + {"extract_here", "Extraer aqui"}, + {"extract_to", "Extraer a"}, + {"selec_target", "Seleccion una carpeta de destino a extraer"}, + {"create_archive", "Crear archivo"}, + {"download_files", "Descargar archivos seleccionados"}, + {"upload_here", "Subir archivos aqui"}, + {"please_new_name", "Por favor ingrese el nuevo nombre"}, + {"open_as_url", "Abrir como url"}, + {"page_up", "Page up"}, + {"page_down", "Page down"}, + {"line_up", "Line up"}, + {"line_down", "Line down"}, + {"search", "Buscar"}, + {"no_entry_selected", "No se ha seleccionado ningun entrada"}, + {"authorized_keys", "Llaves autorizadas"}, + {"local_computer", "Llaves autorizadas"}, + {"server", "Servidor"}, + {"language", "Idioma"}, + {"log_viewer_lines", "Lineas por pagina para el visor de logs" }, + {"log_viewer_font_size", "Tamaño de fuente para visor de logs"}, + {"system_refresh_interval", "Intervalo de tiempo de refresco (seg) "} + + }; +} diff --git a/muon-app/src/main/java/muon/app/common/i18n/Messages_pt.java b/muon-app/src/main/java/muon/app/common/i18n/Messages_pt.java new file mode 100644 index 00000000..0d0b19ce --- /dev/null +++ b/muon-app/src/main/java/muon/app/common/i18n/Messages_pt.java @@ -0,0 +1,272 @@ +package muon.app.common.i18n; + +import javax.swing.*; +import java.util.ListResourceBundle; + +public class Messages_pt extends ListResourceBundle { + + @Override + protected Object[][] getContents() { + + return resources; + } + + private final Object[][] resources = { + + {"general", "Em geral"}, + {"terminal", "Terminal"}, + {"editor", "Editor"}, + {"display", "Display"}, + {"security", "Segurança"}, + {"sessions", "Sessões"}, + {"settings", "Definições"}, + {"add", "Adicionar"}, + {"chk_update", "Verificar atualizações"}, + {"new_site", "Novo site"}, + {"new_folder", "Nova pasta"}, + {"duplicate", "Dobro"}, + {"connect", "Ligar"}, + {"cancel", "Cancelar"}, + {"export", "Exportar"}, + {"import", "Importar"}, + {"name", "Nome"}, + {"connecting", "Conectando..."}, + {"import_from", "Importar a partir de"}, + {"import_sessions", "Importar sessões"}, + {"save", "Guarda"}, + {"reset", "Restaurar"}, + {"remove", "Retirar"}, + {"edit", "Editar"}, + {"generate", "Gerar"}, + {"new_entry", "Nova entrada"}, + {"connection", "Conexão"}, + {"directories", "Diretórios"}, + {"proxy", "Proxy"}, + {"jump_hosts", "Jump Hosts"}, + {"port_forwarding", "Port Forwarding"}, + {"user", "Do utilizador"}, + {"host", "Servidor"}, + {"port", "Porta"}, + {"password", "Chave"}, + {"local_folder", "Pasta local"}, + {"remote_folder", "Pasta remota"}, + {"browse", "Olhe para"}, + {"session_manager", "Administrador de sessão"}, + {"private_key_file", "Arquivo de chave privada"}, + {"proxy_type", "Tipo de proxy"}, + {"proxy_host", "Servidor proxy"}, + {"proxy_port", "Porta proxy"}, + {"proxy_user", "Usuário proxy"}, + {"proxy_password", "Chave proxy"}, + {"warning_plain_text", " ( Aviso: será salvo em texto simples! )"}, + {"overwrite", "Sobrescrever"}, + {"auto_rename", "Renomeação automática"}, + {"skip", "Ignorar"}, + {"prompt", "Perguntar"}, + {"settings_saved", "As configurações foram redefinidas, \nsalve e reinicie o aplicativo"}, + {"columns", "Colunas"}, + {"rows", "Linhas"}, + {"font_name", "Nome da fonte"}, + {"font_size", "Tamanho da fonte"}, + {"copy_like_putty", "Copie e cole como PuTTY (copie em, selecione e cole com o botão direito)"}, + {"terminal_type", "Tipo de terminal"}, + {"initial_terminal_type", "Tamanho inicial do terminal"}, + {"sound", "Som"}, + {"terminal_font", "Fonte Terminal"}, + {"misc", "Misc"}, + {"terminal_colors", "Cores e temas terminais"}, + {"terminal_theme", "Tema Terminal"}, + {"default_color", "Cor padrão"}, + {"text", "Texto"}, + {"background", "Background"}, + {"selection_color", "Seleção de cor"}, + {"search_pattern", "Padrão de pesquisa"}, + {"color_palette", "Paleta de cores"}, + {"terminal_shortcuts", "Atalhos de terminal"}, + {"confirm_delete_files", "Confirme antes de excluir arquivos"}, + {"confirm_move_files", "Confirme antes de mover ou copiar arquivos"}, + {"show_hidden_files", "Mostrar arquivos ocultos por padrão"}, + {"prompt_for_sudo", "Peça sudo se a operação falhar devido a permissões"}, + {"directory_caching", "Usar cache de diretório"}, + {"current_folder", "Mostra a pasta atual na barra de caminho"}, + {"show_banner", "Mostrar banner"}, + {"word_wrap", "Word wrap on log viewer"}, + {"transfer_normally", "Transferência normal"}, + {"transfer_background", "Transferir em background"}, + {"transfer_mode", "Modo de transferência"}, + {"conflict_action", "Ação em conflito"}, + {"add_editor", "+ Adicionar editor"}, + {"remove_editor", "- Excluir editor"}, + {"editor_name", "Nome do editor"}, + {"add_editor2", "Adicionar editor?"}, + {"zoom_text", "Zoom (Faça o aplicativo parecer grande ou pequeno na tela)"}, + {"global_dark_theme", "Use o tema escuro global (precisa reiniciar)"}, + {"zoom_percentage", "Porcentagem de zoom"}, + {"new_master_password", "Nova chave mestra"}, + {"reenter_master_password", "Digite novamente a senha mestra"}, + {"master_password", "Chave mestra"}, + {"use_master_password", "Use a chave mestra"}, + {"change_master_password", "Alterar senha mestre"}, + {"change_password_failed", "Falha na mudança de senha!"}, + {"error_operation", "Erro durante a operação"}, + {"password_aes", "Suas chaves salvas são protegidas por criptografia AES"}, + {"password_unprotected", "Suas senhas não estão mais protegidas"}, + {"password_no_match", "As chaves não coincidem"}, + {"unsupported_key", "Este formato de chave não é compatível, converta-o para o formato OpenSSH"}, + {"copy", "Cópia de"}, + {"paste", "Colar"}, + {"select_all", "Selecionar tudo"}, + {"clear_buffer", "Limpar buffer"}, + {"find", "Achar"}, + {"cut", "Cortar"}, + {"path_executable", "Caminho para o executável"}, + {"file_browser", "Localizador de arquivos"}, + {"server_logs", "Logs do servidor"}, + {"file_search", "Achar arquivo"}, + {"diskspace", "Espaço em disco"}, + {"toolbox", "Ferramentas"}, + {"processes", "Processos"}, + {"pid", "PID"}, + {"total_processes", "Processos totais:"}, + {"last_updated", "Última atualização:"}, + {"analize_folder", "Analisar pasta"}, + {"analize_volume", "Analisar o volume"}, + {"next", "Próximo"}, + {"back", "Para retornar"}, + {"reload", "Recarrega"}, + {"modified", "Modificado"}, + {"size", "Tamanho"}, + {"type", "Cara"}, + {"permission", "Permissões"}, + {"owner", "Proprietário"}, + {"show_hidden_files2", "Mostrar arquivos ocultos"}, + {"bookmarks", "Marcadores"}, + {"select_partition", "Selecione uma partição"}, + {"select_volume", "Selecione um volume"}, + {"filesystem", "Sistema de arquivo"}, + {"total_size", "Tamanho único"}, + {"used", "Usar"}, + {"available", "Disponível"}, + {"percentage_use", "% usado"}, + {"mount_point", "Ponto de montagem"}, + {"directory_usage", "Espaço de diretório"}, + {"start_another_analysis", "Iniciar outra varredura"}, + {"delete", "Retirar"}, + {"send_files", "Enviar arquivos"}, + {"add_from_manager", "Adicionar do gerenciador de sessão"}, + {"add_log", "Adicionar log"}, + {"insert", "Inserir"}, + {"open", "Abrir"}, + {"rename", "Renomear"}, + {"new_file", "Novo arquivo"}, + {"bookmark", "Marcador"}, + {"open_new_tab", "Abrir em uma nova guia"}, + {"enter_new_name", "Por favor insira o novo nome"}, + {"open_in_terminal", "Abrir no terminal"}, + {"copy_path", "Copiar caminho"}, + {"searching", "Procurando"}, + {"idle", "Inativo"}, + {"in_filename", "No nome do arquivo (como .zip ou RME.txt)"}, + {"in_filecontent", "No conteúdo do arquivo"}, + {"in_compressed_files", "Pesquisar arquivos compactados"}, + {"search_for", "Procurar"}, + {"search_in", "Procure em"}, + {"any_time", "Qualquer momento"}, + {"this_week", "Esta semana"}, + {"between", "Entre"}, + {"from", "A partir de"}, + {"to", "Até"}, + {"ready", "Preparar"}, + {"look_for", "Procurar"}, + {"both_file_folder", "Por arquivo e pasta"}, + {"file_only", "Único arquivo"}, + {"folder_only", "Apenas pasta"}, + {"show_location", "Mostrar localização"}, + {"filename", "Nome do arquivo"}, + {"path", "Rota"}, + {"filter", "Filtro"}, + {"clear", "Limpar"}, + {"refresh", "Atualizar"}, + {"kill", "Matar"}, + {"kill_sudo", "Mate usando sudo"}, + {"change_priority", "Alterar prioridade"}, + {"change_priority_sudo", "Alterar a prioridade com sudo"}, + {"copy_command", "Comando de cópia"}, + {"kill_process", "Processo de matar"}, + {"system_info", "Sistema de informações"}, + {"system_load", "Carga do sistema"}, + {"services_systemd", "Serviços - systemd"}, + {"process_ports", "Processos e portas"}, + {"ssh_keys", "Chaves Ssh"}, + {"network_tools", "Ferramentas de rede"}, + {"cpu_usage", "Uso de CPU"}, + {"memory_usage", "Uso de memória"}, + {"swap_usage", "Trocar uso"}, + {"used2", "Usado"}, + {"generate_new_key", "Gerar nova chave"}, + {"public_key_file", "Arquivo de chave pública:"}, + {"refresh_interval", "Intervalo de atualização"}, + {"start", "Começar"}, + {"stop", "Detener"}, + {"restart", "Reiniciar"}, + {"reload", "Recarrega"}, + {"enable", "Permitir"}, + {"disable", "Desabilitar"}, + {"actions_sudo", "Executar ações com superusuário (sudo)"}, + {"operation_failed", "Operação falhou"}, + {"status", "Status"}, + {"state", "Estado"}, + {"description", "Descrição"}, + {"source_port", "Iniciar porta"}, + {"target_port", "Puerto destino"}, + {"bind_host", "Servidor a unir"}, + {"local", "Local"}, + {"remote", "Remoto"}, + {"invalid_input", "Entrada inválida: todos os campos são obrigatórios"}, + {"host_ping", "Faça ping no servidor"}, + {"host_name", "Nome do servidor"}, + {"port_number", "Número da porta"}, + {"tool_use", "Ferramenta para usar"}, + {"executed_errors", "Executado com erros"}, + {"configure_editor", "Editor de configuração"}, + {"open_log_viewer", "Abra com o visualizador de log"}, + {"open_in_tab", "Abrir em nova aba"}, + {"open_with", "Abrir com..."}, + {"send_another_server", "Enviar por outro servidor"}, + {"send_over_ftp", "Enviar por ftp"}, + {"send_this_computer", "Envie para este computador"}, + {"run_in_terminal", "Executar no terminal"}, + {"open_folder_terminal", "Abrir pasta no terminal"}, + {"open_terminal_here", "Abra o terminal aqui"}, + {"run_file_in_terminal", "Executar arquivo no terminal"}, + {"run_file_in_background", "Executar arquivo em segundo plano"}, + {"edit_with", "Editar com"}, + {"properties", "Propriedades"}, + {"create_link", "Criar link"}, + {"extract_here", "Extrair aqui"}, + {"extract_to", "Extrair para"}, + {"selec_target", "Selecione uma pasta de destino para extrair"}, + {"create_archive", "Criar arquivo"}, + {"download_files", "Baixar arquivos selecionados"}, + {"upload_here", "Faça upload de arquivos aqui"}, + {"please_new_name", "Por favor insira o novo nome"}, + {"open_as_url", "Abrir como url"}, + {"page_up", "Page up"}, + {"page_down", "Page down"}, + {"line_up", "Line up"}, + {"line_down", "Line down"}, + {"search", "Olhe para"}, + {"no_entry_selected", "Nenhuma entrada foi selecionada"}, + {"authorized_keys", "Chaves autorizadas"}, + {"local_computer", "Chaves autorizadas"}, + {"server", "Servidor"}, + {"language", "Língua"}, + {"log_viewer_lines", "Linhas por página para o visualizador de log" }, + {"log_viewer_font_size", "Tamanho da fonte para visualizador de log"}, + {"system_refresh_interval", "Intervalo de tempo de atualização (segundos) "} + + + + + }; +} diff --git a/muon-app/src/main/java/muon/app/ssh/SshClient2.java b/muon-app/src/main/java/muon/app/ssh/SshClient2.java index 6b30c3fb..dbb751b0 100644 --- a/muon-app/src/main/java/muon/app/ssh/SshClient2.java +++ b/muon-app/src/main/java/muon/app/ssh/SshClient2.java @@ -1,5 +1,5 @@ /** - * + * */ package muon.app.ssh; @@ -42,18 +42,19 @@ * */ public class SshClient2 implements Closeable { - private AtomicBoolean closed = new AtomicBoolean(false); - private SessionInfo info; + //30000 ms + private static final int CONNECTION_TIMEOUT = 30000; + private final AtomicBoolean closed = new AtomicBoolean(false); + private final SessionInfo info; private SSHClient sshj; - private PasswordFinderDialog passwordFinder; - private InputBlocker inputBlocker; - private CachedCredentialProvider cachedCredentialProvider; + private final PasswordFinderDialog passwordFinder; + private final InputBlocker inputBlocker; + private final CachedCredentialProvider cachedCredentialProvider; private SshClient2 previousHop; private ServerSocket ss; - /** * O - * + * * @param info2 */ public SshClient2(SessionInfo info, InputBlocker inputBlocker, CachedCredentialProvider cachedCredentialProvider) { @@ -153,10 +154,10 @@ private void authPassoword() throws Exception { } try { sshj.authPassword(user, password); // provide - // password - // updater - // PasswordUpdateProvider - // net.schmizz.sshj.userauth.password.PasswordUpdateProvider + // password + // updater + // PasswordUpdateProvider + // net.schmizz.sshj.userauth.password.PasswordUpdateProvider return; } catch (Exception e) { e.printStackTrace(); @@ -177,7 +178,8 @@ private void connect(Deque hopStack) throws IOException, OperationCanc this.inputBlocker.blockInput(); try { sshj = new SSHClient(); - + sshj.setConnectTimeout(CONNECTION_TIMEOUT); + sshj.setTimeout(CONNECTION_TIMEOUT); if (hopStack.isEmpty()) { this.setupProxyAndSocketFactory(); this.sshj.addHostKeyVerifier(App.HOST_KEY_VERIFIER); @@ -237,38 +239,38 @@ private void connect(Deque hopStack) throws IOException, OperationCanc System.out.println("Trying auth method: " + authMethod); switch (authMethod) { - case "publickey": - try { - this.authPublicKey(); - authenticated.set(true); - } catch (OperationCancelledException e) { - disconnect(); - throw e; - } catch (Exception e) { - e.printStackTrace(); - } - break; - - case "keyboard-interactive": - try { - sshj.auth(promptUser(), new AuthKeyboardInteractive(new InteractiveResponseProvider())); - authenticated.set(true); - } catch (Exception e) { - e.printStackTrace(); - } - break; - - case "password": - try { - this.authPassoword(); - authenticated.set(true); - } catch (OperationCancelledException e) { - disconnect(); - throw e; - } catch (Exception e) { - e.printStackTrace(); - } - break; + case "publickey": + try { + this.authPublicKey(); + authenticated.set(true); + } catch (OperationCancelledException e) { + disconnect(); + throw e; + } catch (Exception e) { + e.printStackTrace(); + } + break; + + case "keyboard-interactive": + try { + sshj.auth(promptUser(), new AuthKeyboardInteractive(new InteractiveResponseProvider())); + authenticated.set(true); + } catch (Exception e) { + e.printStackTrace(); + } + break; + + case "password": + try { + this.authPassoword(); + authenticated.set(true); + } catch (OperationCancelledException e) { + disconnect(); + throw e; + } catch (Exception e) { + e.printStackTrace(); + } + break; } if (authenticated.get()) { diff --git a/muon-app/src/main/java/muon/app/ui/AppWindow.java b/muon-app/src/main/java/muon/app/ui/AppWindow.java index 0db6b738..3b8223d1 100644 --- a/muon-app/src/main/java/muon/app/ui/AppWindow.java +++ b/muon-app/src/main/java/muon/app/ui/AppWindow.java @@ -46,23 +46,27 @@ import muon.app.updater.UpdateChecker; import util.FontAwesomeContants; + +import static muon.app.App.bundle; /** * @author subhro * */ public class AppWindow extends JFrame { - private CardLayout sessionCard; - private JPanel cardPanel; + private final CardLayout sessionCard; + private final JPanel cardPanel; private SessionListPanel sessionListPanel; - private BackgroundTransferPanel uploadPanel, downloadPanel; + private final BackgroundTransferPanel uploadPanel; + private final BackgroundTransferPanel downloadPanel; private JLabel lblUploadCount, lblDownloadCount; private JPopupMenu popup; - private Component bottomPanel; + private final Component bottomPanel; private JLabel lblUpdate, lblUpdateText; public static final String HELP_URL = "https://github.com/subhra74/snowflake/wiki"; public static final String GITHUB_URL = "https://github.com/subhra74/snowflake"; + /** * */ @@ -126,9 +130,9 @@ public AppWindow() { } private JPanel createSessionPanel() { - JLabel lblSession = new JLabel("Sessions"); + JLabel lblSession = new JLabel(bundle.getString("sessions")); lblSession.setFont(App.SKIN.getDefaultFont().deriveFont(14.0f)); - JButton btnNew = new JButton("+ New"); + JButton btnNew = new JButton(bundle.getString("add")); btnNew.setFont(App.SKIN.getDefaultFont().deriveFont(12.0f)); btnNew.addActionListener(e -> { SessionInfo info = new NewSessionDlg(this).newSession(); @@ -220,7 +224,7 @@ public void mouseClicked(MouseEvent e) { // b1.setBorder(new EmptyBorder(5, 5, 5, 5)); - JLabel lblBrand = new JLabel("Muon SSH 1.0.4"); + JLabel lblBrand = new JLabel("Muon SSH 1.1.0"); lblBrand.addMouseListener(ml); lblBrand.setCursor(new Cursor(Cursor.HAND_CURSOR)); // lblBrand.setFont(App.SKIN.getDefaultFont().deriveFont(Font.PLAIN, @@ -230,7 +234,7 @@ public void mouseClicked(MouseEvent e) { b1.add(lblBrand); b1.add(Box.createRigidArea(new Dimension(10, 10))); - JLabel lblUrl = new JLabel("https://github.com/subhra74/snowflake"); + JLabel lblUrl = new JLabel("https://github.com/devlinx9/muon-ssh"); lblUrl.addMouseListener(ml); lblUrl.setCursor(new Cursor(Cursor.HAND_CURSOR)); // lblUrl.setFont(App.SKIN.getDefaultFont().deriveFont(Font.PLAIN, 14)); @@ -346,7 +350,7 @@ public void mouseClicked(MouseEvent e) { b1.add(Box.createRigidArea(new Dimension(5, 10))); - lblUpdateText = new JLabel("Check for update"); + lblUpdateText = new JLabel(bundle.getString("chk_update")); lblUpdateText.setCursor(new Cursor(Cursor.HAND_CURSOR)); lblUpdateText.addMouseListener(new MouseAdapter() { @Override diff --git a/muon-app/src/main/java/muon/app/ui/components/SkinnedTextArea.java b/muon-app/src/main/java/muon/app/ui/components/SkinnedTextArea.java index a38d42c2..918ca2d9 100644 --- a/muon-app/src/main/java/muon/app/ui/components/SkinnedTextArea.java +++ b/muon-app/src/main/java/muon/app/ui/components/SkinnedTextArea.java @@ -10,6 +10,8 @@ import javax.swing.JPopupMenu; import javax.swing.JTextArea; +import static muon.app.App.bundle; + /** * @author subhro * @@ -42,10 +44,10 @@ public void mouseClicked(MouseEvent e) { private JPopupMenu createPopup() { JPopupMenu popup = new JPopupMenu(); - JMenuItem mCut = new JMenuItem("Cut"); - JMenuItem mCopy = new JMenuItem("Copy"); - JMenuItem mPaste = new JMenuItem("Paste"); - JMenuItem mSelect = new JMenuItem("Select all"); + JMenuItem mCut = new JMenuItem(bundle.getString("cut")); + JMenuItem mCopy = new JMenuItem(bundle.getString("copy")); + JMenuItem mPaste = new JMenuItem(bundle.getString("paste")); + JMenuItem mSelect = new JMenuItem(bundle.getString("select_all")); popup.add(mCut); popup.add(mCopy); diff --git a/muon-app/src/main/java/muon/app/ui/components/SkinnedTextField.java b/muon-app/src/main/java/muon/app/ui/components/SkinnedTextField.java index 77cd8e6b..75dce4d1 100644 --- a/muon-app/src/main/java/muon/app/ui/components/SkinnedTextField.java +++ b/muon-app/src/main/java/muon/app/ui/components/SkinnedTextField.java @@ -10,6 +10,8 @@ import javax.swing.JPopupMenu; import javax.swing.JTextField; +import static muon.app.App.bundle; + /** * @author subhro * @@ -48,10 +50,10 @@ public void mouseClicked(MouseEvent e) { private JPopupMenu createPopup() { JPopupMenu popup = new JPopupMenu(); - JMenuItem mCut = new JMenuItem("Cut"); - JMenuItem mCopy = new JMenuItem("Copy"); - JMenuItem mPaste = new JMenuItem("Paste"); - JMenuItem mSelect = new JMenuItem("Select all"); + JMenuItem mCut = new JMenuItem(bundle.getString("cut")); + JMenuItem mCopy = new JMenuItem(bundle.getString("copy")); + JMenuItem mPaste = new JMenuItem(bundle.getString("paste")); + JMenuItem mSelect = new JMenuItem(bundle.getString("select_all")); popup.add(mCut); popup.add(mCopy); diff --git a/muon-app/src/main/java/muon/app/ui/components/session/ExternalEditorHandler.java b/muon-app/src/main/java/muon/app/ui/components/session/ExternalEditorHandler.java index 7f2886b4..d44e83e8 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/ExternalEditorHandler.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/ExternalEditorHandler.java @@ -46,17 +46,19 @@ import util.PlatformUtils; import util.TimeUtils; +import static muon.app.App.bundle; + /** * @author subhro * */ public class ExternalEditorHandler extends JDialog { - private JProgressBar progressBar; - private JLabel progressLabel; - private JButton btnCanel; - private JFrame frame; + private final JProgressBar progressBar; + private final JLabel progressLabel; + private final JButton btnCanel; + private final JFrame frame; private FileChangeWatcher fileWatcher; - private AtomicBoolean stopFlag = new AtomicBoolean(false); + private final AtomicBoolean stopFlag = new AtomicBoolean(false); /** * @@ -71,7 +73,7 @@ public ExternalEditorHandler(JFrame frame) { progressLabel = new JLabel("Transferring..."); progressLabel.setBorder(new EmptyBorder(0, 0, 20, 0)); progressLabel.setFont(App.SKIN.getDefaultFont().deriveFont(18.0f)); - btnCanel = new JButton("Cancel"); + btnCanel = new JButton(bundle.getString("cancel")); Box bottomBox = Box.createHorizontalBox(); bottomBox.add(Box.createHorizontalGlue()); bottomBox.add(btnCanel); diff --git a/muon-app/src/main/java/muon/app/ui/components/session/JumpHostPanel.java b/muon-app/src/main/java/muon/app/ui/components/session/JumpHostPanel.java index ef1d48a0..b7cdcdeb 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/JumpHostPanel.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/JumpHostPanel.java @@ -25,9 +25,11 @@ import muon.app.ui.components.SkinnedTextField; import util.FontAwesomeContants; +import static muon.app.App.bundle; + public class JumpHostPanel extends JPanel { - private DefaultListModel hopModel = new DefaultListModel(); - private JList hopList = new JList(hopModel); + private final DefaultListModel hopModel = new DefaultListModel(); + private final JList hopList = new JList(hopModel); private SessionInfo info; public JumpHostPanel() { @@ -163,7 +165,7 @@ private HopEntry addOrEditEntry(HopEntry e) { txtUser.setText(e.getUser()); if (e.getKeypath() != null) txtKeyFile.setText(e.getKeypath()); - spPort.setValue((Integer) e.getPort()); + spPort.setValue(e.getPort()); } btnBrowse.addActionListener(ev -> { @@ -176,7 +178,7 @@ private HopEntry addOrEditEntry(HopEntry e) { }); while (JOptionPane.showOptionDialog(this, - new Object[] { "Host", txtHost, "Port", spPort, "User", txtUser, "Password", txtPassword, "Private key", + new Object[] { bundle.getString("host"), txtHost, bundle.getString("port"), spPort, bundle.getString("user"), txtUser, bundle.getString("password"), txtPassword, bundle.getString("private_key_file"), txtKeyFile }, "Hop entry", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, null, null) == JOptionPane.OK_OPTION) { diff --git a/muon-app/src/main/java/muon/app/ui/components/session/NewSessionDlg.java b/muon-app/src/main/java/muon/app/ui/components/session/NewSessionDlg.java index 82c63926..6354050f 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/NewSessionDlg.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/NewSessionDlg.java @@ -6,10 +6,7 @@ import java.awt.Dimension; import java.awt.GridLayout; import java.awt.Window; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; +import java.awt.event.*; import java.io.File; import java.util.UUID; @@ -45,6 +42,8 @@ import muon.app.ui.components.SkinnedSplitPane; import muon.app.ui.components.SkinnedTextField; +import static muon.app.App.bundle; + public class NewSessionDlg extends JDialog implements ActionListener, TreeSelectionListener, TreeModelListener { private static final long serialVersionUID = -1182844921331289546L; @@ -89,7 +88,7 @@ public void windowClosing(WindowEvent e) { } }); - setTitle("Session manager"); + setTitle(bundle.getString("session_manager")); // List folders = SessionStore.getSharedInstance() // .getFolders(); @@ -112,49 +111,61 @@ public void windowClosing(WindowEvent e) { tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); tree.getSelectionModel().addTreeSelectionListener(this); // tree.setDragEnabled(true); + tree.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); + if (node == null || node.getAllowsChildren()) return; + connectClicked(); + } + } + }); + + tree.setEditable(false); jsp = new JScrollPane(tree); jsp.setBorder(new LineBorder(App.SKIN.getDefaultBorderColor(), 1)); // btnNewHost = new JButton(TextHolder.getString("session.newHost")); - btnNewHost = new JButton("New site"); + btnNewHost = new JButton(bundle.getString("new_site")); btnNewHost.addActionListener(this); btnNewHost.putClientProperty("button.name", "btnNewHost"); // btnNewHost.setFont(Utility.getFont(Constants.SMALL)); - btnNewFolder = new JButton("New folder");// new + btnNewFolder = new JButton(bundle.getString("new_folder"));// new // JButton(TextHolder.getString("session.newFolder")); btnNewFolder.addActionListener(this); btnNewFolder.putClientProperty("button.name", "btnNewFolder"); // btnNewFolder.setFont(Utility.getFont(Constants.SMALL)); - btnDel = new JButton("Remove");// new + btnDel = new JButton(bundle.getString("remove"));// new // JButton(TextHolder.getString("session.remove")); btnDel.addActionListener(this); btnDel.putClientProperty("button.name", "btnDel"); // btnDel.setFont(Utility.getFont(Constants.SMALL)); - btnDup = new JButton("Duplicate");// new + btnDup = new JButton(bundle.getString("duplicate"));// new // JButton(TextHolder.getString("session.duplicate")); btnDup.addActionListener(this); btnDup.putClientProperty("button.name", "btnDup"); // btnDup.setFont(Utility.getFont(Constants.SMALL)); - btnConnect = new JButton("Connect");// new + btnConnect = new JButton(bundle.getString("connect"));// new // JButton(TextHolder.getString("session.connect")); btnConnect.addActionListener(this); btnConnect.putClientProperty("button.name", "btnConnect"); // btnConnect.setFont(Utility.getFont(Constants.SMALL)); - btnCancel = new JButton("Cancel");// new + btnCancel = new JButton(bundle.getString("cancel"));// new // JButton(TextHolder.getString("session.cancel")); btnCancel.addActionListener(this); btnCancel.putClientProperty("button.name", "btnCancel"); - btnExport = new JButton("Export");// new + btnExport = new JButton(bundle.getString("export"));// new // JButton(TextHolder.getString("session.cancel")); btnExport.addActionListener(this); btnExport.putClientProperty("button.name", "btnExport"); - btnImport = new JButton("Import");// new + btnImport = new JButton(bundle.getString("import"));// new // JButton(TextHolder.getString("session.cancel")); btnImport.addActionListener(this); btnImport.putClientProperty("button.name", "btnImport"); @@ -217,7 +228,7 @@ public void windowClosing(WindowEvent e) { namePanel.setBorder(new EmptyBorder(10, 0, 0, 10)); - lblName = new JLabel("Name"); + lblName = new JLabel(bundle.getString("name")); lblName.setAlignmentX(Component.LEFT_ALIGNMENT); lblName.setHorizontalAlignment(JLabel.LEADING); lblName.setBorder(new EmptyBorder(0, 0, 5, 0)); @@ -263,7 +274,7 @@ private void updateName() { prgPanel = new JPanel(); - JLabel lbl = new JLabel("Connecting..."); + JLabel lbl = new JLabel(bundle.getString("connecting")); prgPanel.add(lbl); splitPane.setLeftComponent(treePane); @@ -292,7 +303,7 @@ private void loadTree(SavedSessionTree stree) { n = findFirstInfoNode(rootNode); if (n == null) { SessionInfo sessionInfo = new SessionInfo(); - sessionInfo.setName("New site"); + sessionInfo.setName(bundle.getString("new_site")); sessionInfo.setId(UUID.randomUUID().toString()); DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(sessionInfo); childNode.setUserObject(sessionInfo); @@ -407,7 +418,7 @@ public void actionPerformed(ActionEvent e) { obj = parentNode.getUserObject(); } SessionInfo sessionInfo = new SessionInfo(); - sessionInfo.setName("New site"); + sessionInfo.setName(bundle.getString("new_site")); sessionInfo.setId(UUID.randomUUID().toString()); // sessionInfo.setParentId(((SessionFolder) obj).getId()); DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(sessionInfo); @@ -429,7 +440,7 @@ public void actionPerformed(ActionEvent e) { objFolder = parentNode.getUserObject(); } SessionFolder folder = new SessionFolder(); - folder.setName("New folder"); + folder.setName(bundle.getString("new_folder")); DefaultMutableTreeNode childNode1 = new DefaultMutableTreeNode(folder); treeModel.insertNodeInto(childNode1, parentNode, parentNode.getChildCount()); tree.scrollPathToVisible(new TreePath(childNode1.getPath())); @@ -478,7 +489,7 @@ public void actionPerformed(ActionEvent e) { JComboBox cmbImports = new JComboBox<>( new String[] { "Putty", "WinSCP", "Snowflake session store" }); - if (JOptionPane.showOptionDialog(this, new Object[] { "Import from", cmbImports }, "Import sessions", + if (JOptionPane.showOptionDialog(this, new Object[] { bundle.getString("import_from"), cmbImports }, bundle.getString("import_sessions"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, null, null) == JOptionPane.OK_OPTION) { if (cmbImports.getSelectedIndex() < 2) { diff --git a/muon-app/src/main/java/muon/app/ui/components/session/PortForwardingPanel.java b/muon-app/src/main/java/muon/app/ui/components/session/PortForwardingPanel.java index d6d830d4..3836f9c1 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/PortForwardingPanel.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/PortForwardingPanel.java @@ -25,10 +25,12 @@ import muon.app.ui.components.session.PortForwardingRule.PortForwardingType; import util.FontAwesomeContants; +import static muon.app.App.bundle; + public class PortForwardingPanel extends JPanel { private SessionInfo info; - private PFTableModel model; - private JTable table; + private final PFTableModel model; + private final JTable table; public PortForwardingPanel() { super(new BorderLayout(10, 10)); @@ -101,8 +103,8 @@ public void setInfo(SessionInfo info) { private static class PFTableModel extends AbstractTableModel { - private String[] columns = { "Type", "Host", "Source Port", "Target Port", "Bind Host" }; - private List list = new ArrayList<>(); + private final String[] columns = { bundle.getString("type"), bundle.getString("host"), bundle.getString("source_port"), bundle.getString("target_port"), bundle.getString("bind_host") }; + private final List list = new ArrayList<>(); @Override public int getRowCount() { @@ -171,7 +173,7 @@ private PortForwardingRule get(int index) { } private PortForwardingRule addOrEditEntry(PortForwardingRule r) { - JComboBox cmbPFType = new JComboBox(new String[] { "Local", "Remote" }); + JComboBox cmbPFType = new JComboBox(new String[] { bundle.getString("local"), bundle.getString("remote") }); JTextField txtHost = new SkinnedTextField(30); @@ -183,8 +185,8 @@ private PortForwardingRule addOrEditEntry(PortForwardingRule r) { if (r != null) { txtHost.setText(r.getHost()); - spSourcePort.setValue((Integer) r.getSourcePort()); - spTargetPort.setValue((Integer) r.getTargetPort()); + spSourcePort.setValue(r.getSourcePort()); + spTargetPort.setValue(r.getTargetPort()); txtBindAddress.setText(r.getBindHost()); cmbPFType.setSelectedIndex(r.getType() == PortForwardingType.Local ? 0 : 1); } @@ -201,7 +203,7 @@ private PortForwardingRule addOrEditEntry(PortForwardingRule r) { String bindAddress = txtBindAddress.getText(); if (host.length() < 1 || bindAddress.length() < 1 || port1 <= 0 || port2 <= 0) { - JOptionPane.showMessageDialog(this, "Invalid input: all fields mandatory"); + JOptionPane.showMessageDialog(this, bundle.getString("invalid_input")); continue; } diff --git a/muon-app/src/main/java/muon/app/ui/components/session/SessionContentPanel.java b/muon-app/src/main/java/muon/app/ui/components/session/SessionContentPanel.java index 58cb00c1..9efb1588 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/SessionContentPanel.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/SessionContentPanel.java @@ -49,25 +49,25 @@ * */ public class SessionContentPanel extends JPanel implements PageHolder, CachedCredentialProvider { - private SessionInfo info; - private CardLayout cardLayout; - private JPanel cardPanel; + private final SessionInfo info; + private final CardLayout cardLayout; + private final JPanel cardPanel; private RemoteSessionInstance remoteSessionInstance; - private JRootPane rootPane; - private JPanel contentPane; - private DisabledPanel disabledPanel; - private TransferProgressPanel progressPanel = new TransferProgressPanel(); + private final JRootPane rootPane; + private final JPanel contentPane; + private final DisabledPanel disabledPanel; + private final TransferProgressPanel progressPanel = new TransferProgressPanel(); public final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor(); - private TabbedPage[] pages; - private FileBrowser fileBrowser; - private LogViewer logViewer; - private TerminalHolder terminalHolder; - private DiskspaceAnalyzer diskspaceAnalyzer; - private SearchPanel searchPanel; - private ProcessViewer processViewer; - private UtilityPage utilityPage; - private AtomicBoolean closed = new AtomicBoolean(false); - private Deque cachedSessions = new LinkedList<>(); + private final TabbedPage[] pages; + private final FileBrowser fileBrowser; + private final LogViewer logViewer; + private final TerminalHolder terminalHolder; + private final DiskspaceAnalyzer diskspaceAnalyzer; + private final SearchPanel searchPanel; + private final ProcessViewer processViewer; + private final UtilityPage utilityPage; + private final AtomicBoolean closed = new AtomicBoolean(false); + private final Deque cachedSessions = new LinkedList<>(); private ThreadPoolExecutor backgroundTransferPool; private char[] cachedPassword; private char[] cachedPassPhrase; @@ -100,7 +100,7 @@ public SessionContentPanel(SessionInfo info) { processViewer = new ProcessViewer(this); utilityPage = new UtilityPage(this); - Page[] pageArr = new Page[] { fileBrowser, terminalHolder, logViewer, searchPanel, diskspaceAnalyzer, + Page[] pageArr = new Page[] { terminalHolder, fileBrowser , logViewer, searchPanel, diskspaceAnalyzer, processViewer, utilityPage }; // JPanel[] panels = { diff --git a/muon-app/src/main/java/muon/app/ui/components/session/SessionInfoPanel.java b/muon-app/src/main/java/muon/app/ui/components/session/SessionInfoPanel.java index 4f029eb3..aff17c67 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/SessionInfoPanel.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/SessionInfoPanel.java @@ -33,6 +33,8 @@ import muon.app.ui.components.TabbedPanel; import muon.app.ui.components.session.SessionInfo.JumpType; +import static muon.app.App.bundle; + public class SessionInfoPanel extends JPanel { private static final long serialVersionUID = 6679029920589652547L; @@ -178,11 +180,11 @@ private void createUI() { setLayout(new BorderLayout()); setBorder(new EmptyBorder(10, 0, 10, 0)); tabs = new TabbedPanel(); - tabs.addTab("Connection", createConnectionPanel()); - tabs.addTab("Directories", createDirectoryPanel()); - tabs.addTab("Proxy", createProxyPanel()); - tabs.addTab("Jump Hosts", createJumpPanel()); - tabs.addTab("Port Forwarding", createPortForwardingPanel()); + tabs.addTab(bundle.getString("connection"), createConnectionPanel()); + tabs.addTab(bundle.getString("directories"), createDirectoryPanel()); + tabs.addTab(bundle.getString("proxy"), createProxyPanel()); + tabs.addTab(bundle.getString("jump_hosts"), createJumpPanel()); + tabs.addTab(bundle.getString("port_forwarding"), createPortForwardingPanel()); this.add(tabs); tabs.setSelectedIndex(0); } @@ -282,12 +284,12 @@ private JPanel createProxyPanel() { Insets noInset = new Insets(5, 10, 0, 10); // ----------- - lblProxyType = new JLabel("Proxy type"); - lblProxyHost = new JLabel("Proxy host"); + lblProxyType = new JLabel(bundle.getString("proxy_type")); + lblProxyHost = new JLabel(bundle.getString("proxy_host")); lblProxyHost.setHorizontalAlignment(JLabel.LEADING); - lblProxyPort = new JLabel("Proxy port"); - lblProxyUser = new JLabel("Proxy user"); - lblProxyPass = new JLabel("Proxy password" + " ( Warning: it will be saved in plain text! )"); + lblProxyPort = new JLabel(bundle.getString("proxy_port")); + lblProxyUser = new JLabel(bundle.getString("proxy_user")); + lblProxyPass = new JLabel(bundle.getString("proxy_password") + bundle.getString("warning_plain_text")); cmbProxy = new JComboBox<>(new String[] { "NONE", "HTTP", "SOCKS" }); cmbProxy.addActionListener(e -> { @@ -524,7 +526,7 @@ private void updateFolder() { } }); - inpLocalBrowse = new JButton("Browse"); + inpLocalBrowse = new JButton(bundle.getString("browse")); inpLocalBrowse.addActionListener(e -> { JFileChooser jfc = new JFileChooser(); jfc.setFileHidingEnabled(false); @@ -596,14 +598,14 @@ private JPanel createConnectionPanel() { Insets noInset = new Insets(5, 10, 0, 10); // setBackground(new Color(245,245,245)); - lblHost = new JLabel("Host"); + lblHost = new JLabel(bundle.getString("host")); lblHost.setHorizontalAlignment(JLabel.LEADING); - lblPort = new JLabel("Port"); - lblUser = new JLabel("User"); - lblPass = new JLabel("Password"); - lblLocalFolder = new JLabel("Local folder"); - lblRemoteFolder = new JLabel("Remote folder"); - lblKeyFile = new JLabel("Private key file"); + lblPort = new JLabel(bundle.getString("port")); + lblUser = new JLabel(bundle.getString("user")); + lblPass = new JLabel(bundle.getString("password")); + lblLocalFolder = new JLabel(bundle.getString("local_folder") ); + lblRemoteFolder = new JLabel(bundle.getString("remote_folder")); + lblKeyFile = new JLabel(bundle.getString("private_key_file")); inpHostName = new SkinnedTextField(10);// new JTextField(30); inpHostName.getDocument().addDocumentListener(new DocumentListener() { @@ -705,7 +707,7 @@ private void updateKeyFile() { } }); - inpKeyBrowse = new JButton("Browse");// new + inpKeyBrowse = new JButton(bundle.getString("browse"));// new // JButton(TextHolder.getString("host.browse")); inpKeyBrowse.addActionListener(e -> { JFileChooser jfc = new JFileChooser(); @@ -718,8 +720,8 @@ private void updateKeyFile() { String selectedFile = jfc.getSelectedFile().getAbsolutePath(); if (selectedFile.endsWith(".ppk")) { if (!isSupportedPuttyKeyFile(jfc.getSelectedFile())) { - JOptionPane.showMessageDialog(this, - "This key format is not supported, please convert it to OpenSSH format"); + JOptionPane.showMessageDialog(this,bundle.getString("unsupported_key") + ); return; } } diff --git a/muon-app/src/main/java/muon/app/ui/components/session/diskspace/DiskspaceAnalyzer.java b/muon-app/src/main/java/muon/app/ui/components/session/diskspace/DiskspaceAnalyzer.java index 4a36bceb..50bc92b9 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/diskspace/DiskspaceAnalyzer.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/diskspace/DiskspaceAnalyzer.java @@ -37,15 +37,17 @@ import util.FontAwesomeContants; import util.OptionPaneUtils; +import static muon.app.App.bundle; + /** * @author subhro * */ public class DiskspaceAnalyzer extends Page { - private CardLayout cardLayout; + private final CardLayout cardLayout; private PartitionTableModel model; private JTable table; - private SessionContentPanel holder; + private final SessionContentPanel holder; private JTree resultTree; private DefaultTreeModel treeModel; @@ -67,7 +69,7 @@ private Component createResultPanel() { resultTree = new JTree(treeModel); resultTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); - JButton btnStart = new JButton("Start another analysis"); + JButton btnStart = new JButton(bundle.getString("start_another_analysis")); btnStart.addActionListener(e -> { cardLayout.show(this, "firstPanel"); }); @@ -78,7 +80,7 @@ private Component createResultPanel() { resultBox.add(Box.createHorizontalStrut(10)); resultBox.add(btnStart); - JLabel resultTitle = new JLabel("Directory diskspace usage"); + JLabel resultTitle = new JLabel(bundle.getString("directory_usage")); resultTitle.setBorder(new EmptyBorder(10, 10, 10, 10)); JPanel resultPanel = new JPanel(new BorderLayout()); @@ -89,8 +91,8 @@ private Component createResultPanel() { } private Component createFirstPanel() { - JRadioButton radFolder = new JRadioButton("Analyze a folder"); - JRadioButton radVolume = new JRadioButton("Analyze volume"); + JRadioButton radFolder = new JRadioButton(bundle.getString("analize_folder")); + JRadioButton radVolume = new JRadioButton(bundle.getString("analize_volume")); radFolder.setFont(App.SKIN.getDefaultFont().deriveFont(14.0f)); radVolume.setFont(App.SKIN.getDefaultFont().deriveFont(14.0f)); radFolder.setHorizontalAlignment(JRadioButton.LEFT); @@ -98,7 +100,7 @@ private Component createFirstPanel() { JLabel lblIcon = new JLabel(); lblIcon.setFont(App.SKIN.getIconFont().deriveFont(128.0f)); lblIcon.setText(FontAwesomeContants.FA_HDD_O); - JButton btnNext = new JButton("Next"); + JButton btnNext = new JButton(bundle.getString("next")); btnNext.addActionListener(e -> { if (radVolume.isSelected()) { cardLayout.show(this, "volPanel"); @@ -155,9 +157,9 @@ private Component createVolumesPanel() { table.setSelectionForeground(App.SKIN.getDefaultSelectionForeground()); JScrollPane jsp = new SkinnedScrollPane(table); - JButton btnBack = new JButton("Back"); - JButton btnNext = new JButton("Next"); - JButton btnReload = new JButton("Reload"); + JButton btnBack = new JButton(bundle.getString("back")); + JButton btnNext = new JButton(bundle.getString("next")); + JButton btnReload = new JButton(bundle.getString("reload")); btnNext.addActionListener(e -> { int x = table.getSelectedRow(); @@ -166,7 +168,7 @@ private Component createVolumesPanel() { cardLayout.show(this, "resultPanel"); analyze(model.get(r).getMountPoint()); } else { - JOptionPane.showMessageDialog(this, "Please select a partition"); + JOptionPane.showMessageDialog(this, bundle.getString("select_partition")); return; } }); @@ -183,7 +185,7 @@ private Component createVolumesPanel() { bottomBox.add(btnNext); bottomBox.setBorder(new EmptyBorder(10, 10, 10, 10)); - JLabel lblTitle = new JLabel("Please select a volume to continue"); + JLabel lblTitle = new JLabel(bundle.getString("select_volume")); lblTitle.setBorder(new EmptyBorder(10, 10, 10, 10)); JPanel panel = new JPanel(new BorderLayout()); @@ -205,7 +207,7 @@ public String getIcon() { @Override public String getText() { - return "Diskspace"; + return bundle.getString("diskspace"); } private void listPartitions(AtomicBoolean stopFlag) { diff --git a/muon-app/src/main/java/muon/app/ui/components/session/diskspace/PartitionTableModel.java b/muon-app/src/main/java/muon/app/ui/components/session/diskspace/PartitionTableModel.java index bb7bed63..e384d8cf 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/diskspace/PartitionTableModel.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/diskspace/PartitionTableModel.java @@ -4,10 +4,12 @@ import java.util.ArrayList; import java.util.List; +import static muon.app.App.bundle; + public class PartitionTableModel extends AbstractTableModel { - private String columns[] = {"Filesystem", "Total size", "Used", "Available", "% used", "Mount point"}; + private final String[] columns = {bundle.getString("filesystem"), bundle.getString("total_size"), bundle.getString("used"), bundle.getString("available"), bundle.getString("percentage_use"), bundle.getString("mount_point")}; - private List list = new ArrayList<>(); + private final List list = new ArrayList<>(); public PartitionEntry get(int index) { return list.get(index); diff --git a/muon-app/src/main/java/muon/app/ui/components/session/files/FileBrowser.java b/muon-app/src/main/java/muon/app/ui/components/session/files/FileBrowser.java index 9c7029a9..5451ff41 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/files/FileBrowser.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/files/FileBrowser.java @@ -45,19 +45,21 @@ import muon.app.ui.components.session.files.transfer.FileTransfer.TransferMode; import muon.app.ui.components.session.files.view.DndTransferData; import util.FontAwesomeContants; +import static muon.app.App.bundle; public class FileBrowser extends Page { private FileTransfer ongoingFileTransfer; - private JSplitPane horizontalSplitter; - private ClosableTabbedPanel leftTabs, rightTabs; - private SessionContentPanel holder; - private SessionInfo info; - private Map> sshDirCache = new HashMap<>(); - private int activeSessionId; - private AtomicBoolean init = new AtomicBoolean(false); - private JPopupMenu popup; + private final JSplitPane horizontalSplitter; + private final ClosableTabbedPanel leftTabs; + private final ClosableTabbedPanel rightTabs; + private final SessionContentPanel holder; + private final SessionInfo info; + private final Map> sshDirCache = new HashMap<>(); + private final int activeSessionId; + private final AtomicBoolean init = new AtomicBoolean(false); + private final JPopupMenu popup; private boolean leftPopup = false; - private List viewList = new ArrayList<>(); + private final List viewList = new ArrayList<>(); private JLabel lblStat1; private Box statusBox; @@ -569,7 +571,7 @@ public String getIcon() { @Override public String getText() { - return "File browser"; + return bundle.getString("file_browser"); } /** diff --git a/muon-app/src/main/java/muon/app/ui/components/session/files/local/LocalMenuHandler.java b/muon-app/src/main/java/muon/app/ui/components/session/files/local/LocalMenuHandler.java index 515a9b22..169f23d4 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/files/local/LocalMenuHandler.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/files/local/LocalMenuHandler.java @@ -25,14 +25,16 @@ import util.PathUtils; import util.PlatformUtils; +import static muon.app.App.bundle; + public class LocalMenuHandler { private JMenuItem mOpenInNewTab, mRename, mDelete, mNewFile, mNewFolder, mCopy, mPaste, mCut, mAddToFav, mOpen, mOpenInFileExplorer; - private FileBrowser fileBrowser; + private final FileBrowser fileBrowser; private FolderView folderView; - private LocalFileOperations fileOperations; - private LocalFileBrowserView fileBrowserView; + private final LocalFileOperations fileOperations; + private final LocalFileBrowserView fileBrowserView; public LocalMenuHandler(FileBrowser fileBrowser, LocalFileBrowserView fileBrowserView) { this.fileBrowser = fileBrowser; @@ -48,14 +50,14 @@ public void initMenuHandler(FolderView folderView) { } private void initMenuItems() { - mOpen = new JMenuItem("Open"); + mOpen = new JMenuItem(bundle.getString("open")); mOpen.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { open(); } }); - mOpenInNewTab = new JMenuItem("Open in new tab"); + mOpenInNewTab = new JMenuItem(bundle.getString("open_new_tab")); mOpenInNewTab.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -79,7 +81,7 @@ public void actionPerformed(ActionEvent e) { } }); - mRename = new JMenuItem("Rename"); + mRename = new JMenuItem(bundle.getString("rename")); mRename.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -87,7 +89,7 @@ public void actionPerformed(ActionEvent e) { } }); - mDelete = new JMenuItem("Delete"); + mDelete = new JMenuItem(bundle.getString("delete")); mDelete.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -95,7 +97,7 @@ public void actionPerformed(ActionEvent e) { } }); - mNewFile = new JMenuItem("New file"); + mNewFile = new JMenuItem(bundle.getString("new_file")); mNewFile.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -103,7 +105,7 @@ public void actionPerformed(ActionEvent e) { } }); - mNewFolder = new JMenuItem("New folder"); + mNewFolder = new JMenuItem(bundle.getString("new_folder")); mNewFolder.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -111,7 +113,7 @@ public void actionPerformed(ActionEvent e) { } }); - mCopy = new JMenuItem("Copy"); + mCopy = new JMenuItem(bundle.getString("copy")); mCopy.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -119,7 +121,7 @@ public void actionPerformed(ActionEvent e) { } }); - mPaste = new JMenuItem("Paste"); + mPaste = new JMenuItem(bundle.getString("paste")); mPaste.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -133,7 +135,7 @@ public void actionPerformed(ActionEvent e) { } }); - mCut = new JMenuItem("Cut"); + mCut = new JMenuItem(bundle.getString("cut")); mCut.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -141,7 +143,7 @@ public void actionPerformed(ActionEvent e) { } }); - mAddToFav = new JMenuItem("Bookmark"); + mAddToFav = new JMenuItem(bundle.getString("bookmark")); mAddToFav.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -191,7 +193,7 @@ private void createBuitinItems2(int selectionCount, JPopupMenu popup) { } private void open() { - FileInfo files[] = folderView.getSelectedFiles(); + FileInfo[] files = folderView.getSelectedFiles(); if (files.length == 1) { FileInfo file = files[0]; if (file.getType() == FileType.FileLink || file.getType() == FileType.File) { @@ -201,7 +203,7 @@ private void open() { } private void openNewTab() { - FileInfo files[] = folderView.getSelectedFiles(); + FileInfo[] files = folderView.getSelectedFiles(); if (files.length == 1) { FileInfo file = files[0]; if (file.getType() == FileType.Directory || file.getType() == FileType.DirLink) { @@ -211,7 +213,7 @@ private void openNewTab() { } private void rename(FileInfo info, String baseFolder) { - String text = JOptionPane.showInputDialog("Please enter new name", info.getName()); + String text = JOptionPane.showInputDialog(bundle.getString("enter_new_name"), info.getName()); if (text != null && text.length() > 0) { renameAsync(info.getPath(), PathUtils.combineUnix(PathUtils.getParent(info.getPath()), text), baseFolder); } @@ -267,7 +269,7 @@ private void newFolder(String currentDirectory) { } private void addToFavourites() { - FileInfo arr[] = folderView.getSelectedFiles(); + FileInfo[] arr = folderView.getSelectedFiles(); if (arr.length > 0) { BookmarkManager.addEntry(null, @@ -293,10 +295,10 @@ private void addToFavourites() { public JPopupMenu createAddressPopup() { JPopupMenu popupMenu = new JPopupMenu(); - JMenuItem mOpenInNewTab = new JMenuItem("Open in new tab"); - JMenuItem mCopyPath = new JMenuItem("Copy path"); - JMenuItem mOpenInTerminal = new JMenuItem("Open in terminal"); - JMenuItem mBookmark = new JMenuItem("Bookmark"); + JMenuItem mOpenInNewTab = new JMenuItem(bundle.getString("open_new_tab")); + JMenuItem mCopyPath = new JMenuItem(bundle.getString("copy_path")); + JMenuItem mOpenInTerminal = new JMenuItem(bundle.getString("open_in_terminal")); + JMenuItem mBookmark = new JMenuItem(bundle.getString("bookmark")); popupMenu.add(mOpenInNewTab); popupMenu.add(mCopyPath); popupMenu.add(mOpenInTerminal); diff --git a/muon-app/src/main/java/muon/app/ui/components/session/files/remote2remote/Remote2RemoteTransferDialog.java b/muon-app/src/main/java/muon/app/ui/components/session/files/remote2remote/Remote2RemoteTransferDialog.java index 11dfc7df..5be08bab 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/files/remote2remote/Remote2RemoteTransferDialog.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/files/remote2remote/Remote2RemoteTransferDialog.java @@ -37,13 +37,15 @@ import muon.app.ui.components.session.SessionInfo; import util.FontAwesomeContants; +import static muon.app.App.bundle; + public class Remote2RemoteTransferDialog extends JDialog { - private DefaultListModel remoteHostModel; - private JList remoteHostList; - private SessionContentPanel session; - private FileInfo[] selectedFiles; - private String currentDirectory; - private List list = new ArrayList<>(); + private final DefaultListModel remoteHostModel; + private final JList remoteHostList; + private final SessionContentPanel session; + private final FileInfo[] selectedFiles; + private final String currentDirectory; + private final List list = new ArrayList<>(); public Remote2RemoteTransferDialog(JFrame frame, SessionContentPanel session, FileInfo[] selectedFiles, String currentDirectory) { @@ -73,11 +75,11 @@ public Remote2RemoteTransferDialog(JFrame frame, SessionContentPanel session, Fi } Box bottom = Box.createHorizontalBox(); - JButton btnAddKnown = new JButton("Add from session manager"); - JButton btnAdd = new JButton("Add"); - JButton btnRemove = new JButton("Delete"); - JButton btnEdit = new JButton("Edit"); - JButton btnSend = new JButton("Send Files"); + JButton btnAddKnown = new JButton(bundle.getString("add_from_manager")); + JButton btnAdd = new JButton(bundle.getString("add")); + JButton btnRemove = new JButton(bundle.getString("delete")); + JButton btnEdit = new JButton(bundle.getString("edit")); + JButton btnSend = new JButton(bundle.getString("send_files")); btnAddKnown.addActionListener(e -> { SessionInfo info = new NewSessionDlg(this).newSession(); diff --git a/muon-app/src/main/java/muon/app/ui/components/session/files/ssh/PropertiesDialog.java b/muon-app/src/main/java/muon/app/ui/components/session/files/ssh/PropertiesDialog.java index 43d4de83..0543c2e5 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/files/ssh/PropertiesDialog.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/files/ssh/PropertiesDialog.java @@ -28,28 +28,43 @@ import muon.app.ui.components.session.files.FileBrowser; import util.FormatUtils; +import static muon.app.App.bundle; + public class PropertiesDialog extends JDialog { private int permissions; - private JCheckBox chkPermissons[]; - private JLabel lblOwner, lblGroup, lblOther; - private String[] labels = new String[] { "read", "write", "execute" }; + private final JCheckBox[] chkPermissons; + private final JLabel lblOwner; + private final JLabel lblGroup; + private final JLabel lblOther; + private final String[] labels = new String[] { "read", "write", "execute" }; private int dialogResult = JOptionPane.CANCEL_OPTION; private FileInfo[] details; - private JTextField txtName, txtSize, txtType, txtOwner, txtGroup, - txtModified, txtCreated, txtPath, txtFileCount, txtFreeSpace; - private JButton btnCalculate1, btnCalculate2, btnGetDiskSpaceUsed; + private JTextField txtName; + private final JTextField txtSize; + private JTextField txtType; + private JTextField txtOwner; + private JTextField txtGroup; + private JTextField txtModified; + private JTextField txtCreated; + private JTextField txtPath; + private JTextField txtFileCount; + private final JTextField txtFreeSpace; + private JButton btnCalculate1; + private JButton btnCalculate2; + private final JButton btnGetDiskSpaceUsed; private static final String userGroupRegex = "^[^\\s]+\\s+[^\\s]+\\s+([^\\s]+)\\s+([^\\s]+)"; private Pattern pattern; - private FileBrowser fileBrowser; + private final FileBrowser fileBrowser; private static final Pattern duPattern = Pattern .compile("([\\d]+)\\s+(.+)"); private static final Pattern dfPattern = Pattern.compile( "[^\\s]+\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+%)\\s+[^\\s]+"); - private AtomicBoolean modified = new AtomicBoolean(false); - private JButton btnOK, btnCancel; + private final AtomicBoolean modified = new AtomicBoolean(false); + private final JButton btnOK; + private final JButton btnCancel; public PropertiesDialog(FileBrowser holder, Window window, boolean multimode) { @@ -184,7 +199,7 @@ public PropertiesDialog(FileBrowser holder, Window window, chmodAsync(getPermissions(), details); dispose(); }); - btnCancel = new JButton("Cancel"); + btnCancel = new JButton(bundle.getString("cancel")); btnCancel.addActionListener(e -> { dialogResult = JOptionPane.CANCEL_OPTION; dispose(); @@ -409,8 +424,8 @@ public void windowClosing(WindowEvent e) { } } - public void calcSize(FileInfo files[], BiConsumer biConsumer, - AtomicBoolean stopFlag) { + public void calcSize(FileInfo[] files, BiConsumer biConsumer, + AtomicBoolean stopFlag) { StringBuilder command = new StringBuilder(); command.append( "export POSIXLY_CORRECT=1; export BLOCKSIZE=512; du -s "); @@ -450,8 +465,8 @@ public void calcSize(FileInfo files[], BiConsumer biConsumer, }); } - public void calcFreeSpace(FileInfo files[], - BiConsumer biConsumer, AtomicBoolean stopFlag) { + public void calcFreeSpace(FileInfo[] files, + BiConsumer biConsumer, AtomicBoolean stopFlag) { StringBuilder command = new StringBuilder(); command.append( "export POSIXLY_CORRECT=1; export BLOCKSIZE=1024; df -P -k \"" @@ -478,7 +493,7 @@ public void calcFreeSpace(FileInfo files[], } } - String lines[] = output.toString().split("\n"); + String[] lines = output.toString().split("\n"); if (lines.length >= 2) { Matcher matcher = dfPattern.matcher(lines[1]); if (matcher.find()) { @@ -506,7 +521,7 @@ public void calcFreeSpace(FileInfo files[], }); } - private void chmodAsync(int perm, FileInfo paths[]) { + private void chmodAsync(int perm, FileInfo[] paths) { AtomicBoolean stopFlag = new AtomicBoolean(false); JDialog dlg = new JDialog(this); dlg.setModal(true); diff --git a/muon-app/src/main/java/muon/app/ui/components/session/files/ssh/SshMenuHandler.java b/muon-app/src/main/java/muon/app/ui/components/session/files/ssh/SshMenuHandler.java index 9382ed79..780e6291 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/files/ssh/SshMenuHandler.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/files/ssh/SshMenuHandler.java @@ -44,6 +44,8 @@ import muon.app.ui.components.settings.SettingsPageName; import util.PathUtils; +import static muon.app.App.bundle; + public class SshMenuHandler { private AbstractAction aOpenInTab, aOpen, aRename, aDelete, aNewFile, aNewFolder, aCopy, aPaste, aCut, aAddToFav, aChangePerm, aSendFiles, aUpload, aDownload, aCreateLink, aCopyPath; @@ -58,11 +60,11 @@ public class SshMenuHandler { private JMenu mEditWith, mSendTo; private Map extractCommands; - private FileBrowser fileBrowser; + private final FileBrowser fileBrowser; private FolderView folderView; - private SshFileOperations fileOperations; - private SshFileBrowserView fileBrowserView; - private ArchiveOperation archiveOperation; + private final SshFileOperations fileOperations; + private final SshFileBrowserView fileBrowserView; + private final ArchiveOperation archiveOperation; public SshMenuHandler(FileBrowser fileBrowser, SshFileBrowserView fileBrowserView) { this.fileBrowser = fileBrowser; @@ -80,7 +82,7 @@ public void initMenuHandler(FolderView folderView) { private void initMenuItems(InputMap map, ActionMap act) { ksOpenInTab = KeyStroke.getKeyStroke(KeyEvent.VK_T, ActionEvent.CTRL_MASK); - mOpenInTab = new JMenuItem("Open in new tab"); + mOpenInTab = new JMenuItem(bundle.getString("open_in_tab")); mOpenInTab.setAccelerator(ksOpenInTab); aOpenInTab = new AbstractAction() { @Override @@ -108,7 +110,7 @@ public void actionPerformed(ActionEvent e) { } }; ksOpen = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); - mOpen = new JMenuItem("Open"); + mOpen = new JMenuItem(bundle.getString("open")); mOpen.addActionListener(aOpen); map.put(ksOpen, "mOpen"); act.put("mOpen", aOpen); @@ -118,7 +120,7 @@ public void actionPerformed(ActionEvent e) { // mOpenWithDefApp.addActionListener(e -> openDefaultApp()); if (App.IS_WINDOWS) { - mOpenWithMenu = new JMenuItem("Open with..."); + mOpenWithMenu = new JMenuItem(bundle.getString("open_with")); mOpenWithMenu.addActionListener(e -> { FileInfo fileInfo = folderView.getSelectedFiles()[0]; try { @@ -135,13 +137,13 @@ public void actionPerformed(ActionEvent e) { // mOpenWthInternalEdit = new JMenuItem("Internal editor"); // mOpenWthInternalEdit.addActionListener(e -> openWithInternalEditor()); - mEditorConfig = new JMenuItem("Configure editor"); + mEditorConfig = new JMenuItem(bundle.getString("configure_editor")); mEditorConfig.addActionListener(e -> openEditorConfig()); - mOpenWithLogView = new JMenuItem("Open with Log viewer"); + mOpenWithLogView = new JMenuItem(bundle.getString("open_log_viewer")); mOpenWithLogView.addActionListener(e -> openLogViewer()); - mEditWith = new JMenu("Edit with"); + mEditWith = new JMenu(bundle.getString("edit_with")); // for (EditorEntry ent : App.getGlobalSettings().getEditors()) { // JMenuItem mEditorItem = new JMenuItem(ent.getName()); // mEditorItem.addActionListener(e -> openWithEditor(ent.getPath())); @@ -149,13 +151,13 @@ public void actionPerformed(ActionEvent e) { // } // mEditWith.add(mEditorConfig); - mSendTo = new JMenu("Send to another server"); + mSendTo = new JMenu(bundle.getString("send_another_server")); - JMenuItem mSendViaSSH = new JMenuItem("Send over SFTP (Direct)"); + JMenuItem mSendViaSSH = new JMenuItem(bundle.getString("send_over_ftp")); mSendViaSSH.addActionListener(e -> { this.sendFilesViaSSH(); }); - JMenuItem mSendViaLocal = new JMenuItem("Send via this computer"); + JMenuItem mSendViaLocal = new JMenuItem(bundle.getString("send_this_computer")); mSendViaLocal.addActionListener(e -> { this.sendFilesViaLocal(); }); @@ -168,27 +170,27 @@ public void actionPerformed(ActionEvent e) { // mEditWith.add(mOpenWthInternalEdit); // mEditWith.add(mOpenWithLogView); - mRunScriptInTerminal = new JMenuItem("Run in terminal"); + mRunScriptInTerminal = new JMenuItem(bundle.getString("run_in_terminal")); mRunScriptInTerminal.addActionListener(e -> { }); - mOpenFolderInTerminal = new JMenuItem("Open folder in terminal"); + mOpenFolderInTerminal = new JMenuItem(bundle.getString("open_folder_terminal")); mOpenFolderInTerminal.addActionListener(e -> { openFolderInTerminal(folderView.getSelectedFiles()[0].getPath()); }); - mOpenTerminalHere = new JMenuItem("Open terminal here"); + mOpenTerminalHere = new JMenuItem(bundle.getString("open_terminal_here")); mOpenTerminalHere.addActionListener(e -> { openFolderInTerminal(fileBrowserView.getCurrentDirectory()); }); - mRunScriptInTerminal = new JMenuItem("Run file in terminal"); + mRunScriptInTerminal = new JMenuItem(bundle.getString("run_file_in_terminal")); mRunScriptInTerminal.addActionListener(e -> { openRunInTerminal(fileBrowserView.getCurrentDirectory(), folderView.getSelectedFiles()[0].getPath()); }); - mRunScriptInBackground = new JMenuItem("Run file in background"); + mRunScriptInBackground = new JMenuItem(bundle.getString("run_file_in_background")); mRunScriptInBackground.addActionListener(e -> { openRunInBackground(fileBrowserView.getCurrentDirectory(), folderView.getSelectedFiles()[0].getPath()); }); @@ -200,7 +202,7 @@ public void actionPerformed(ActionEvent e) { } }; ksRename = KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0); - mRename = new JMenuItem("Rename"); + mRename = new JMenuItem(bundle.getString("rename")); mRename.addActionListener(aRename); map.put(ksRename, "mRename"); act.put("mRename", aRename); @@ -213,7 +215,7 @@ public void actionPerformed(ActionEvent e) { delete(folderView.getSelectedFiles(), fileBrowserView.getCurrentDirectory()); } }; - mDelete = new JMenuItem("Delete"); + mDelete = new JMenuItem(bundle.getString("delete")); mDelete.addActionListener(aDelete); map.put(ksDelete, "ksDelete"); act.put("ksDelete", aDelete); @@ -226,7 +228,7 @@ public void actionPerformed(ActionEvent e) { newFile(fileBrowserView.getCurrentDirectory(), folderView.getFiles()); } }; - mNewFile = new JMenuItem("New file"); + mNewFile = new JMenuItem(bundle.getString("new_file")); mNewFile.addActionListener(aNewFile); map.put(ksNewFile, "ksNewFile"); act.put("ksNewFile", aNewFile); @@ -239,7 +241,7 @@ public void actionPerformed(ActionEvent e) { newFolder(fileBrowserView.getCurrentDirectory(), folderView.getFiles()); } }; - mNewFolder = new JMenuItem("New folder"); + mNewFolder = new JMenuItem(bundle.getString("new_folder")); mNewFolder.addActionListener(aNewFolder); mNewFolder.setAccelerator(ksNewFolder); map.put(ksNewFolder, "ksNewFolder"); @@ -252,7 +254,7 @@ public void actionPerformed(ActionEvent e) { copyToClipboard(false); } }; - mCopy = new JMenuItem("Copy"); + mCopy = new JMenuItem(bundle.getString("copy")); mCopy.addActionListener(aCopy); map.put(ksCopy, "ksCopy"); act.put("ksCopy", aCopy); @@ -265,7 +267,7 @@ public void actionPerformed(ActionEvent e) { copyPathToClipboard(); } }; - mCopyPath = new JMenuItem("Copy path"); + mCopyPath = new JMenuItem(bundle.getString("copy_path")); mCopyPath.addActionListener(aCopyPath); map.put(ksCopyPath, "ksCopyPath"); act.put("ksCopyPath", aCopyPath); @@ -278,7 +280,7 @@ public void actionPerformed(ActionEvent e) { handlePaste(); } }; - mPaste = new JMenuItem("Paste"); + mPaste = new JMenuItem(bundle.getString("paste")); mPaste.addActionListener(aPaste); map.put(ksPaste, "ksPaste"); act.put("ksPaste", aPaste); @@ -291,7 +293,7 @@ public void actionPerformed(ActionEvent e) { copyToClipboard(true); } }; - mCut = new JMenuItem("Cut"); + mCut = new JMenuItem(bundle.getString("cut")); mCut.addActionListener(aCut); map.put(ksCut, "ksCut"); act.put("ksCut", aCut); @@ -304,7 +306,7 @@ public void actionPerformed(ActionEvent e) { addToFavourites(); } }; - mAddToFav = new JMenuItem("Bookmark"); + mAddToFav = new JMenuItem(bundle.getString("bookmark")); mAddToFav.addActionListener(aAddToFav); map.put(ksAddToFav, "ksAddToFav"); act.put("ksAddToFav", aAddToFav); @@ -317,7 +319,7 @@ public void actionPerformed(ActionEvent e) { changePermission(folderView.getSelectedFiles(), fileBrowserView.getCurrentDirectory()); } }; - mChangePerm = new JMenuItem("Properties"); + mChangePerm = new JMenuItem(bundle.getString("properties")); mChangePerm.addActionListener(aChangePerm); map.put(ksChangePerm, "ksChangePerm"); act.put("ksChangePerm", aChangePerm); @@ -330,22 +332,22 @@ public void actionPerformed(ActionEvent e) { createLink(fileBrowserView.getCurrentDirectory(), folderView.getSelectedFiles()); } }; - mCreateLink = new JMenuItem("Create link"); + mCreateLink = new JMenuItem(bundle.getString("create_link")); mCreateLink.addActionListener(aCreateLink); map.put(ksCreateLink, "ksCreateLink"); act.put("ksCreateLink", aCreateLink); mCreateLink.setAccelerator(ksCreateLink); - mExtractHere = new JMenuItem("Extract here"); + mExtractHere = new JMenuItem(bundle.getString("extract_here")); mExtractHere.addActionListener(e -> { extractArchive(folderView.getSelectedFiles()[0].getPath(), fileBrowserView.getCurrentDirectory(), fileBrowserView.getCurrentDirectory()); // openFolderInTerminal(folderView.getSelectedFiles()[0].getPath()); }); - mExtractTo = new JMenuItem("Extract to"); + mExtractTo = new JMenuItem(bundle.getString("extract_to")); mExtractTo.addActionListener(e -> { - String text = JOptionPane.showInputDialog("Select a target folder to extract", + String text = JOptionPane.showInputDialog(bundle.getString("selec_target"), fileBrowserView.getCurrentDirectory()); if (text == null || text.length() < 1) { return; @@ -354,7 +356,7 @@ public void actionPerformed(ActionEvent e) { // openFolderInTerminal(folderView.getSelectedFiles()[0].getPath()); }); - mCreateArchive = new JMenuItem("Create archive"); + mCreateArchive = new JMenuItem(bundle.getString("create_archive")); mCreateArchive.addActionListener(e -> { List files = new ArrayList<>(); for (FileInfo fileInfo : folderView.getSelectedFiles()) { @@ -363,12 +365,12 @@ public void actionPerformed(ActionEvent e) { createArchive(files, fileBrowserView.getCurrentDirectory(), fileBrowserView.getCurrentDirectory()); }); - mDownload = new JMenuItem("Download selected files"); + mDownload = new JMenuItem(bundle.getString("download_files")); mDownload.addActionListener(e -> { downloadFiles(folderView.getSelectedFiles(), fileBrowserView.getCurrentDirectory()); }); - mUpload = new JMenuItem("Upload files here"); + mUpload = new JMenuItem(bundle.getString("upload_here")); mUpload.addActionListener(e -> { try { uploadFiles(); @@ -569,7 +571,7 @@ private int createBuiltInItems2(int selectionCount, JPopupMenu popup, FileInfo[] } public void openNewTab() { - FileInfo files[] = folderView.getSelectedFiles(); + FileInfo[] files = folderView.getSelectedFiles(); if (files.length == 1) { FileInfo file = files[0]; if (file.getType() == FileType.Directory || file.getType() == FileType.DirLink) { @@ -581,7 +583,7 @@ public void openNewTab() { } private void rename(FileInfo info, String baseFolder) { - String text = JOptionPane.showInputDialog("Please enter new name", info.getName()); + String text = JOptionPane.showInputDialog(bundle.getString("please_new_name"), info.getName()); if (text != null && text.length() > 0) { renameAsync(info.getPath(), PathUtils.combineUnix(PathUtils.getParent(info.getPath()), text), baseFolder); } @@ -750,7 +752,7 @@ public void move(List files, String targetFolder) { } private void addToFavourites() { - FileInfo arr[] = folderView.getSelectedFiles(); + FileInfo[] arr = folderView.getSelectedFiles(); if (arr.length > 0) { BookmarkManager.addEntry(fileBrowser.getInfo().getId(), @@ -766,10 +768,10 @@ private void addToFavourites() { public JPopupMenu createAddressPopup() { JPopupMenu popupMenu = new JPopupMenu(); - JMenuItem mOpenInNewTab = new JMenuItem("Open in new tab"); - JMenuItem mCopyPath = new JMenuItem("Copy path"); - JMenuItem mOpenInTerminal = new JMenuItem("Open in terminal"); - JMenuItem mBookmark = new JMenuItem("Bookmark"); + JMenuItem mOpenInNewTab = new JMenuItem(bundle.getString("open_new_tab")); + JMenuItem mCopyPath = new JMenuItem(bundle.getString("copy_path")); + JMenuItem mOpenInTerminal = new JMenuItem(bundle.getString("open_in_terminal")); + JMenuItem mBookmark = new JMenuItem(bundle.getString("bookmark")); popupMenu.add(mOpenInNewTab); popupMenu.add(mCopyPath); popupMenu.add(mOpenInTerminal); diff --git a/muon-app/src/main/java/muon/app/ui/components/session/files/view/FolderView.java b/muon-app/src/main/java/muon/app/ui/components/session/files/view/FolderView.java index ad268a08..2b5caaec 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/files/view/FolderView.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/files/view/FolderView.java @@ -2,6 +2,7 @@ import javax.swing.*; import javax.swing.RowSorter.SortKey; +import javax.swing.event.RowSorterEvent; import javax.swing.border.LineBorder; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; @@ -28,18 +29,19 @@ public class FolderView extends JPanel { // private DefaultListModel listModel; // private ListView list; - private FolderViewTableModel folderViewModel; - private JTable table; - private JScrollPane tableScroller, listScroller; - private JList fileList; + private final FolderViewTableModel folderViewModel; + private final JTable table; + private final JScrollPane tableScroller; + private final JScrollPane listScroller; + private final JList fileList; // private TableRowSorter sorter; - private FolderViewEventListener listener; - private JPopupMenu popup; + private final FolderViewEventListener listener; + private final JPopupMenu popup; private boolean showHiddenFiles = false; // private int sortIndex = 2; // private boolean sortAsc = false; private List files; - private TableRowSorter sorter; + private final TableRowSorter sorter; public FolderView(FolderViewEventListener listener, Consumer statusCallback) { super(new BorderLayout()); @@ -76,15 +78,37 @@ public FolderView(FolderViewEventListener listener, Consumer statusCallb // table.setRowHeight(r.getPreferredHeight()); table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + final SortOrder[] sortingOrder = {null}; //Store main column sort order + sorter = new TableRowSorter<>(table.getModel()); + sorter.addRowSorterListener(e -> { + if (e.getType() == RowSorterEvent.Type.SORT_ORDER_CHANGED) { + final List sortKeys = e.getSource().getSortKeys(); + if (!sortKeys.isEmpty()) { + sortingOrder[0] = sortKeys.get(0).getSortOrder(); + } + } + }); // compare name sorter.setComparator(0, new Comparator<>() { @Override public int compare(Object o1, Object o2) { - FileInfo s1 = (FileInfo) o1; - FileInfo s2 = (FileInfo) o2; - return s1.compareTo(s2); + FileInfo fi1 = (FileInfo) o1; + FileInfo fi2 = (FileInfo) o2; + //Make sure folders are always before files with respect to current sort order + if (fi1.isDirectory()) { + if (!fi2.isDirectory()) { + return sortingOrder[0]==SortOrder.DESCENDING ? 1 : -1; + } + } + else { + if (fi2.isDirectory()) { + return sortingOrder[0]==SortOrder.DESCENDING ? -1 : 1; + } + } + + return fi1.getName().compareToIgnoreCase(fi2.getName()); } }); @@ -92,8 +116,22 @@ public int compare(Object o1, Object o2) { sorter.setComparator(2, new Comparator<>() { @Override public int compare(Object o1, Object o2) { - Long s1 = (Long) ((FileInfo) o1).getSize(); - Long s2 = (Long) ((FileInfo) o2).getSize(); + FileInfo fi1 = (FileInfo) o1; + FileInfo fi2 = (FileInfo) o2; + //Make sure folders are always before files with respect to current sort order + if (fi1.isDirectory()) { + if (!fi2.isDirectory()) { + return sortingOrder[0]==SortOrder.DESCENDING ? 1 : -1; + } + } + else { + if (fi2.isDirectory()) { + return sortingOrder[0]==SortOrder.DESCENDING ? -1 : 1; + } + } + + Long s1 = fi1.getSize(); + Long s2 = fi2.getSize(); return s1.compareTo(s2); } }); @@ -102,8 +140,8 @@ public int compare(Object o1, Object o2) { sorter.setComparator(3, new Comparator<>() { @Override public int compare(Object o1, Object o2) { - String s1 = (String) ((FileInfo) o1).getType().toString(); - String s2 = (String) ((FileInfo) o2).getType().toString(); + String s1 = ((FileInfo) o1).getType().toString(); + String s2 = ((FileInfo) o2).getType().toString(); return s1.compareTo(s2); } }); @@ -112,22 +150,21 @@ public int compare(Object o1, Object o2) { sorter.setComparator(1, new Comparator<>() { @Override public int compare(Object o1, Object o2) { - FileInfo s1 = (FileInfo) o1; - FileInfo s2 = (FileInfo) o2; - - if (s1.getType() == FileType.Directory || s1.getType() == FileType.DirLink) { - if (s2.getType() == FileType.Directory || s2.getType() == FileType.DirLink) { - return s1.getLastModified().compareTo(s2.getLastModified()); - } else { - return 1; + FileInfo fi1 = (FileInfo) o1; + FileInfo fi2 = (FileInfo) o2; + //Make sure folders are always before files with respect to current sort order + if (fi1.isDirectory()) { + if (!fi2.isDirectory()) { + return sortingOrder[0]==SortOrder.DESCENDING ? 1 : -1; } - } else { - if (s2.getType() == FileType.Directory || s2.getType() == FileType.DirLink) { - return -1; - } else { - return s1.getLastModified().compareTo(s2.getLastModified()); + } + else { + if (fi2.isDirectory()) { + return sortingOrder[0]==SortOrder.DESCENDING ? -1 : 1; } } + + return fi1.getLastModified().compareTo(fi2.getLastModified()); } }); @@ -135,8 +172,22 @@ public int compare(Object o1, Object o2) { sorter.setComparator(4, new Comparator<>() { @Override public int compare(Object o1, Object o2) { - String s1 = (String) ((FileInfo) o1).getPermissionString().toString(); - String s2 = (String) ((FileInfo) o2).getPermissionString().toString(); + FileInfo fi1 = (FileInfo) o1; + FileInfo fi2 = (FileInfo) o2; + //Make sure folders are always before files with respect to current sort order + if (fi1.isDirectory()) { + if (!fi2.isDirectory()) { + return sortingOrder[0]==SortOrder.DESCENDING ? 1 : -1; + } + } + else { + if (fi2.isDirectory()) { + return sortingOrder[0]==SortOrder.DESCENDING ? -1 : 1; + } + } + + String s1 = fi1.getPermissionString(); + String s2 = fi2.getPermissionString(); return s1.compareTo(s2); } }); @@ -145,8 +196,22 @@ public int compare(Object o1, Object o2) { sorter.setComparator(5, new Comparator<>() { @Override public int compare(Object o1, Object o2) { - String s1 = (String) ((FileInfo) o1).getPermissionString().toString(); - String s2 = (String) ((FileInfo) o2).getPermissionString().toString(); + FileInfo fi1 = (FileInfo) o1; + FileInfo fi2 = (FileInfo) o2; + //Make sure folders are always before files with respect to current sort order + if (fi1.isDirectory()) { + if (!fi2.isDirectory()) { + return sortingOrder[0]==SortOrder.DESCENDING ? 1 : -1; + } + } + else { + if (fi2.isDirectory()) { + return sortingOrder[0]==SortOrder.DESCENDING ? -1 : 1; + } + } + + String s1 = fi1.getUser(); + String s2 = fi2.getUser(); return s1.compareTo(s2); } }); @@ -340,7 +405,7 @@ public void actionPerformed(ActionEvent ae) { } int rc = table.getSelectedRowCount(); int tc = table.getRowCount(); - + String text = String.format("%d of %d selected", rc, tc); statusCallback.accept(text); }); @@ -552,8 +617,8 @@ private void selectListRow(MouseEvent e) { } public FileInfo[] getSelectedFiles() { - int indexes[] = table.getSelectedRows(); - FileInfo fs[] = new FileInfo[indexes.length]; + int[] indexes = table.getSelectedRows(); + FileInfo[] fs = new FileInfo[indexes.length]; int i = 0; for (int index : indexes) { FileInfo info = folderViewModel.getItemAt(table.convertRowIndexToModel(index)); @@ -574,7 +639,7 @@ public FileInfo[] getFiles() { if (this.files == null) { return new FileInfo[0]; } else { - FileInfo fs[] = new FileInfo[files.size()]; + FileInfo[] fs = new FileInfo[files.size()]; for (int i = 0; i < files.size(); i++) { fs[i] = files.get(i); } @@ -766,9 +831,9 @@ public boolean isSortAsc() { } /** - * + * * Sets view mode: list or details view - * + * * Note: caller must call revalidate and repaint after calling this method * */ diff --git a/muon-app/src/main/java/muon/app/ui/components/session/files/view/FolderViewTableModel.java b/muon-app/src/main/java/muon/app/ui/components/session/files/view/FolderViewTableModel.java index 93a3b145..ca156cfc 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/files/view/FolderViewTableModel.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/files/view/FolderViewTableModel.java @@ -12,16 +12,18 @@ import java.util.ArrayList; import java.util.List; +import static muon.app.App.bundle; + public class FolderViewTableModel extends AbstractTableModel implements ListModel { private static final long serialVersionUID = 7212506492710233442L; - private List files = new ArrayList<>(); + private final List files = new ArrayList<>(); protected EventListenerList listenerList = new EventListenerList(); // private String[] columns = { "Name", "Size", "Type", "Modified", // "Permission", "Owner" }; - private String[] columns = { "Name", "Modified", "Size", "Type", "Permission", "Owner" }; + private final String[] columns = { bundle.getString("name"), bundle.getString("modified"), bundle.getString("size"), bundle.getString("type"), bundle.getString("permission"), bundle.getString("owner") }; private boolean local = false; diff --git a/muon-app/src/main/java/muon/app/ui/components/session/files/view/OverflowMenuHandler.java b/muon-app/src/main/java/muon/app/ui/components/session/files/view/OverflowMenuHandler.java index 32de08cd..00b1cff9 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/files/view/OverflowMenuHandler.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/files/view/OverflowMenuHandler.java @@ -25,21 +25,27 @@ import muon.app.ui.components.session.files.local.LocalFileBrowserView; import util.PathUtils; +import static muon.app.App.bundle; + public class OverflowMenuHandler { - private JRadioButtonMenuItem mSortName, mSortSize, mSortModified, mSortAsc, mSortDesc; + private final JRadioButtonMenuItem mSortName; + private final JRadioButtonMenuItem mSortSize; + private final JRadioButtonMenuItem mSortModified; + private final JRadioButtonMenuItem mSortAsc; + private final JRadioButtonMenuItem mSortDesc; private FolderView folderView; - private JCheckBoxMenuItem mShowHiddenFiles; + private final JCheckBoxMenuItem mShowHiddenFiles; - private AtomicBoolean sortingChanging = new AtomicBoolean(false); - private KeyStroke ksHideShow; - private AbstractAction aHideShow; - private JPopupMenu popup; + private final AtomicBoolean sortingChanging = new AtomicBoolean(false); + private final KeyStroke ksHideShow; + private final AbstractAction aHideShow; + private final JPopupMenu popup; // private FileComponentHolder holder; - private AbstractFileBrowserView fileBrowserView; - private JMenu favouriteLocations; - private JMenu mSortMenu; - private FileBrowser fileBrowser; + private final AbstractFileBrowserView fileBrowserView; + private final JMenu favouriteLocations; + private final JMenu mSortMenu; + private final FileBrowser fileBrowser; public OverflowMenuHandler(AbstractFileBrowserView fileBrowserView, FileBrowser fileBrowser) { // this.holder = holder; @@ -47,7 +53,7 @@ public OverflowMenuHandler(AbstractFileBrowserView fileBrowserView, FileBrowser this.fileBrowser = fileBrowser; ksHideShow = KeyStroke.getKeyStroke(KeyEvent.VK_H, InputEvent.CTRL_DOWN_MASK); - mShowHiddenFiles = new JCheckBoxMenuItem("Show hidden files"); + mShowHiddenFiles = new JCheckBoxMenuItem(bundle.getString("show_hidden_files2")); mShowHiddenFiles.setSelected(App.getGlobalSettings().isShowHiddenFilesByDefault()); aHideShow = new AbstractAction() { @@ -77,7 +83,7 @@ public void actionPerformed(ActionEvent e) { mSortDesc = createSortMenuItem("Sort descending", 1, bg2); - this.favouriteLocations = new JMenu("Bookmarks"); + this.favouriteLocations = new JMenu(bundle.getString("bookmarks")); popup = new JPopupMenu(); mSortMenu = new JMenu("Sort"); diff --git a/muon-app/src/main/java/muon/app/ui/components/session/logviewer/LogViewer.java b/muon-app/src/main/java/muon/app/ui/components/session/logviewer/LogViewer.java index bd721a36..29953a67 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/logviewer/LogViewer.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/logviewer/LogViewer.java @@ -20,16 +20,18 @@ import util.FontAwesomeContants; import util.PathUtils; +import static muon.app.App.bundle; + /** * @author subhro * */ public class LogViewer extends Page { - private ClosableTabbedPanel tabs; - private StartPage startPage; - private JPanel content; - private SessionContentPanel sessionContent; - private Set openLogs = new LinkedHashSet<>(); + private final ClosableTabbedPanel tabs; + private final StartPage startPage; + private final JPanel content; + private final SessionContentPanel sessionContent; + private final Set openLogs = new LinkedHashSet<>(); /** * @@ -65,7 +67,7 @@ public String getIcon() { @Override public String getText() { - return "Server logs"; + return bundle.getString("server_logs"); } public void openLog(FileInfo remotePath) { diff --git a/muon-app/src/main/java/muon/app/ui/components/session/logviewer/StartPage.java b/muon-app/src/main/java/muon/app/ui/components/session/logviewer/StartPage.java index b795eb3c..9608e5a7 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/logviewer/StartPage.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/logviewer/StartPage.java @@ -31,19 +31,21 @@ import muon.app.ui.components.SkinnedTextField; import util.CollectionHelper; +import static muon.app.App.bundle; + /** * @author subhro * */ public class StartPage extends JPanel { - private DefaultListModel pinnedLogsModel; - private JList pinnedLogList; + private final DefaultListModel pinnedLogsModel; + private final JList pinnedLogList; private boolean hover = false; - private List finalPinnedLogs; + private final List finalPinnedLogs; private static final Cursor HAND_CURSOR = new Cursor(Cursor.HAND_CURSOR); private static final Cursor DEFAULT_CURSOR = new Cursor( Cursor.DEFAULT_CURSOR); - private String sessionId; + private final String sessionId; /** * @@ -68,8 +70,8 @@ public StartPage(Consumer callback, String sessionId) { JScrollPane jsp = new SkinnedScrollPane(pinnedLogList); jsp.setBorder(new EmptyBorder(0, 10, 0, 10)); this.add(jsp); - JButton btnAddLog = new JButton("Add log"); - JButton btnDelLog = new JButton("Delete"); + JButton btnAddLog = new JButton(bundle.getString("add_log")); + JButton btnDelLog = new JButton(bundle.getString("delete")); btnAddLog.addActionListener(e -> { String logPath = promptLogPath(); if (logPath != null) { diff --git a/muon-app/src/main/java/muon/app/ui/components/session/processview/ProcessListPanel.java b/muon-app/src/main/java/muon/app/ui/components/session/processview/ProcessListPanel.java index f851eb40..1b10b32f 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/processview/ProcessListPanel.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/processview/ProcessListPanel.java @@ -28,17 +28,20 @@ import muon.app.ui.components.SkinnedScrollPane; import muon.app.ui.components.SkinnedTextField; +import static muon.app.App.bundle; + public class ProcessListPanel extends JPanel { - private ProcessTableModel model; - private JTable table; - private JTextField txtFilter; + private final ProcessTableModel model; + private final JTable table; + private final JTextField txtFilter; private JButton btnKill, btnCopyArgs;// , btnStop; - private RowFilter rowFilter; + private final RowFilter rowFilter; private String filterText = ""; - private JPopupMenu killPopup, prioPopup; - private BiConsumer consumer; + private final JPopupMenu killPopup; + private final JPopupMenu prioPopup; + private final BiConsumer consumer; - private JLabel lblProcessCount; + private final JLabel lblProcessCount; public enum CommandMode { KILL_AS_ROOT, KILL_AS_USER, LIST_PROCESS @@ -66,7 +69,7 @@ public ProcessListPanel(BiConsumer consumer) { table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); table.getColumnModel().getColumn(0).setPreferredWidth(200); - lblProcessCount = new JLabel("Total processes: 0"); + lblProcessCount = new JLabel(bundle.getString("total_processes") + " 0"); rowFilter = new RowFilter() { @Override @@ -98,7 +101,7 @@ public boolean include( Box b1 = Box.createHorizontalBox(); // b1.setBorder(new EmptyBorder(5, 5, 5, 5)); - b1.add(new JLabel("Processes")); + b1.add(new JLabel(bundle.getString("processes"))); b1.add(Box.createHorizontalStrut(10)); txtFilter = new SkinnedTextField(30);// new JTextField(30); txtFilter.addActionListener(e -> { @@ -107,7 +110,7 @@ public boolean include( }); b1.add(txtFilter); b1.add(Box.createHorizontalStrut(5)); - JButton btnFilter = new JButton("Filter"); + JButton btnFilter = new JButton(bundle.getString("filter")); btnFilter.addActionListener(e -> { this.filterText = getProcessFilterText(); model.fireTableDataChanged(); @@ -115,7 +118,7 @@ public boolean include( b1.add(btnFilter); b1.add(Box.createHorizontalStrut(5)); - JButton btnClearFilter = new JButton("Clear"); + JButton btnClearFilter = new JButton(bundle.getString("clear")); b1.add(btnClearFilter); b1.add(Box.createHorizontalStrut(5)); btnClearFilter.addActionListener(e -> { @@ -124,7 +127,7 @@ public boolean include( model.fireTableDataChanged(); }); - JButton btnRefresh = new JButton("Refresh"); + JButton btnRefresh = new JButton(bundle.getString("refresh")); b1.add(btnRefresh); btnRefresh.addActionListener(e -> { this.consumer.accept(null, CommandMode.LIST_PROCESS); @@ -132,8 +135,8 @@ public boolean include( killPopup = new JPopupMenu(); - JMenuItem mKill = new JMenuItem("Kill"); - JMenuItem mKillAsRoot = new JMenuItem("Kill using sudo"); + JMenuItem mKill = new JMenuItem(bundle.getString("kill")); + JMenuItem mKillAsRoot = new JMenuItem(bundle.getString("kill_sudo")); mKill.addActionListener(e -> { int c = table.getSelectedRow(); @@ -165,8 +168,8 @@ public boolean include( killPopup.pack(); prioPopup = new JPopupMenu(); - JMenuItem mPrio = new JMenuItem("Change priority"); - JMenuItem mPrioAsRoot = new JMenuItem("Change priority using sudo"); + JMenuItem mPrio = new JMenuItem(bundle.getString("change_priority")); + JMenuItem mPrioAsRoot = new JMenuItem(bundle.getString("change_priority_sudo")); prioPopup.add(mPrio); prioPopup.add(mPrioAsRoot); prioPopup.pack(); @@ -178,7 +181,7 @@ public boolean include( Box b2 = Box.createHorizontalBox(); b2.add(lblProcessCount); - btnCopyArgs = new JButton("Copy command"); + btnCopyArgs = new JButton(bundle.getString("copy_command")); btnCopyArgs.addActionListener(e -> { int c = table.getSelectedRow(); if (c != -1) { @@ -189,7 +192,7 @@ public boolean include( } }); - btnKill = new JButton("Kill process"); + btnKill = new JButton(bundle.getString("kill_process")); btnKill.addActionListener(e -> { Dimension d = killPopup.getPreferredSize(); killPopup.show(btnKill, 0, -d.height); @@ -221,8 +224,8 @@ public String getProcessFilterText() { } public void setProcessList(List list) { - lblProcessCount.setText("Total processes: " + list.size() - + ", last updated: " + LocalDateTime.now().format( + lblProcessCount.setText(bundle.getString("total_processes") + " " + list.size() + + ", "+bundle.getString("last_updated")+" " + LocalDateTime.now().format( DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM))); int x = table.getSelectedRow(); int selectedPid = -1; diff --git a/muon-app/src/main/java/muon/app/ui/components/session/processview/ProcessViewer.java b/muon-app/src/main/java/muon/app/ui/components/session/processview/ProcessViewer.java index d9fdef48..0f8b94a1 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/processview/ProcessViewer.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/processview/ProcessViewer.java @@ -21,15 +21,17 @@ import util.ScriptLoader; import util.SudoUtils; +import static muon.app.App.bundle; + /** * @author subhro * */ public class ProcessViewer extends Page { - private SessionContentPanel holder; - private AtomicBoolean init = new AtomicBoolean(false); + private final SessionContentPanel holder; + private final AtomicBoolean init = new AtomicBoolean(false); private ProcessListPanel processListPanel; - private AtomicBoolean processListLoaded = new AtomicBoolean(false); + private final AtomicBoolean processListLoaded = new AtomicBoolean(false); /** * @@ -69,7 +71,7 @@ public String getIcon() { @Override public String getText() { - return "Processes"; + return bundle.getString("processes"); } private void updateProcessList(AtomicBoolean stopFlag) { @@ -147,14 +149,14 @@ public List getProcessList(RemoteSessionInstance instance, At private List parseProcessList(String text) { List list = new ArrayList<>(); - String lines[] = text.split("\n"); + String[] lines = text.split("\n"); boolean first = true; for (String line : lines) { if (first) { first = false; continue; } - String p[] = line.trim().split("\\s+"); + String[] p = line.trim().split("\\s+"); if (p.length < 8) { continue; } diff --git a/muon-app/src/main/java/muon/app/ui/components/session/search/SearchPanel.java b/muon-app/src/main/java/muon/app/ui/components/session/search/SearchPanel.java index bd62e846..02615856 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/search/SearchPanel.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/search/SearchPanel.java @@ -48,6 +48,8 @@ import util.PathUtils; import util.ScriptLoader; +import static muon.app.App.bundle; + /** * @author subhro * @@ -70,8 +72,8 @@ public class SearchPanel extends Page { private JCheckBox chkIncludeCompressed; private String searchScript; private JButton btnShowInBrowser, btnCopyPath; - private SessionContentPanel holder; - private AtomicBoolean init = new AtomicBoolean(false); + private final SessionContentPanel holder; + private final AtomicBoolean init = new AtomicBoolean(false); /** * @@ -208,7 +210,7 @@ private void find() { private void findAsync(StringBuilder scriptBuffer, AtomicBoolean stopFlag) { SwingUtilities.invokeLater(() -> { model.clear(); - lblStat.setText("Searching"); + lblStat.setText(bundle.getString("searching")); lblCount.setText(String.format("%d items", model.getRowCount())); disableButtons(); }); @@ -242,7 +244,7 @@ private void findAsync(StringBuilder scriptBuffer, AtomicBoolean stopFlag) { System.out.println("search output\n" + output); - String lines[] = output.toString().split("\n"); + String[] lines = output.toString().split("\n"); SwingUtilities.invokeLater(() -> { for (String line : lines) { if (line.length() > 0) { @@ -256,12 +258,12 @@ private void findAsync(StringBuilder scriptBuffer, AtomicBoolean stopFlag) { String.format("%d items", model.getRowCount())); }); - lblStat.setText("Idle"); + lblStat.setText(bundle.getString("idle")); } catch (Exception e) { e.printStackTrace(); } finally { SwingUtilities.invokeLater(() -> { - lblStat.setText("Idle"); + lblStat.setText(bundle.getString("idle")); lblCount.setText( String.format("%d items", model.getRowCount())); this.holder.enableUi(); @@ -315,16 +317,16 @@ public String getIcon() { @Override public String getText() { - return "File search"; + return bundle.getString("file_search"); } private void createUI() { setLayout(new BorderLayout()); - chkIncludeCompressed = new JCheckBox("Look inside compressed files"); + chkIncludeCompressed = new JCheckBox(bundle.getString("in_compressed_files")); chkIncludeCompressed.setAlignmentX(LEFT_ALIGNMENT); - radFileName = new JRadioButton("In filename (like *.zip or R*ME.txt)"); + radFileName = new JRadioButton(bundle.getString("in_filename")); radFileName.setAlignmentX(LEFT_ALIGNMENT); - radFileContents = new JRadioButton("In file content"); + radFileContents = new JRadioButton(bundle.getString("in_filecontent")); radFileContents.setAlignmentX(LEFT_ALIGNMENT); ButtonGroup bg = new ButtonGroup(); @@ -343,7 +345,7 @@ private void createUI() { // b1.setBorder(new EmptyBorder(10, 10, // 10, 10)); - JLabel lblName = new JLabel("Search for"); + JLabel lblName = new JLabel(bundle.getString("search_for")); lblName.setAlignmentX(LEFT_ALIGNMENT); txtName = new SkinnedTextField(20);// new JTextField(20); txtName.addActionListener(e -> { @@ -353,7 +355,7 @@ private void createUI() { txtName.setMaximumSize(pref); txtName.setAlignmentX(LEFT_ALIGNMENT); - JLabel lblFolder = new JLabel("Search in"); + JLabel lblFolder = new JLabel(bundle.getString("search_in")); lblFolder.setAlignmentX(LEFT_ALIGNMENT); txtFolder = new SkinnedTextField(20);// new JTextField(20); txtFolder.setPreferredSize(pref); @@ -368,7 +370,7 @@ private void createUI() { // txtFolder.setText(args[0]); // } - JLabel lblSize = new JLabel("Size"); + JLabel lblSize = new JLabel(bundle.getString("size")); lblSize.setAlignmentX(LEFT_ALIGNMENT); txtSize = new SkinnedTextField();// new JTextField(); @@ -386,15 +388,15 @@ private void createUI() { new Dimension(20, cmbSize.getPreferredSize().height)); cmbSize.setAlignmentX(LEFT_ALIGNMENT); - JLabel lblMtime = new JLabel("Modified"); + JLabel lblMtime = new JLabel(bundle.getString("modified")); lblMtime.setAlignmentX(LEFT_ALIGNMENT); ButtonGroup btnGroup1 = new ButtonGroup(); - radAny = new JRadioButton("Any time"); + radAny = new JRadioButton(bundle.getString("any_time")); radAny.setAlignmentX(LEFT_ALIGNMENT); - radWeek = new JRadioButton("This week"); + radWeek = new JRadioButton(bundle.getString("this_week")); radWeek.setAlignmentX(LEFT_ALIGNMENT); - radCust = new JRadioButton("Between"); + radCust = new JRadioButton(bundle.getString("between")); radCust.setAlignmentX(LEFT_ALIGNMENT); btnGroup1.add(radAny); @@ -431,9 +433,9 @@ public void actionPerformed(ActionEvent e) { radAny.setSelected(true); - JLabel lblFrom = new JLabel("From"); + JLabel lblFrom = new JLabel(bundle.getString("from")); lblFrom.setAlignmentX(LEFT_ALIGNMENT); - JLabel lblTo = new JLabel("To"); + JLabel lblTo = new JLabel(bundle.getString("to")); lblTo.setAlignmentX(LEFT_ALIGNMENT); SpinnerDateModel sm1 = new SpinnerDateModel(); @@ -458,15 +460,15 @@ public void actionPerformed(ActionEvent e) { spDate2.setEditor(new JSpinner.DateEditor(spDate2, "dd/MM/yyyy")); spDate2.setEnabled(false); - JLabel lblLookfor = new JLabel("Look for"); + JLabel lblLookfor = new JLabel(bundle.getString("look_for")); lblLookfor.setAlignmentX(LEFT_ALIGNMENT); ButtonGroup btnGroup2 = new ButtonGroup(); - radBoth = new JRadioButton("Both file and folder"); + radBoth = new JRadioButton(bundle.getString("both_file_folder")); radBoth.setAlignmentX(LEFT_ALIGNMENT); - radFile = new JRadioButton("File only"); + radFile = new JRadioButton(bundle.getString("file_only")); radFile.setAlignmentX(LEFT_ALIGNMENT); - radFolder = new JRadioButton("Folder only"); + radFolder = new JRadioButton(bundle.getString("folder_only")); radFolder.setAlignmentX(LEFT_ALIGNMENT); btnGroup2.add(radBoth); @@ -475,7 +477,7 @@ public void actionPerformed(ActionEvent e) { radBoth.setSelected(true); - btnSearch = new JButton("Search"); + btnSearch = new JButton(bundle.getString("search")); btnSearch.setAlignmentX(LEFT_ALIGNMENT); // btnSearch.setPreferredSize(pref); @@ -513,7 +515,7 @@ public void actionPerformed(ActionEvent e) { JScrollPane jsp = new SkinnedScrollPane(table); jsp.setBorder(null); - lblStat = new JLabel("Ready"); + lblStat = new JLabel(bundle.getString("ready")); lblCount = new JLabel(""); lblCount.setHorizontalAlignment(JLabel.RIGHT); @@ -606,8 +608,8 @@ public void actionPerformed(ActionEvent e) { new MatteBorder(1, 0, 0, 0, App.SKIN.getDefaultBorderColor())); // statBox.setBackground(UIManager.getColor("Panel.background")); - btnShowInBrowser = new JButton("Show location"); - btnCopyPath = new JButton("Copy path"); + btnShowInBrowser = new JButton(bundle.getString("show_location")); + btnCopyPath = new JButton(bundle.getString("copy_path")); disableButtons(); diff --git a/muon-app/src/main/java/muon/app/ui/components/session/search/SearchTableModel.java b/muon-app/src/main/java/muon/app/ui/components/session/search/SearchTableModel.java index d548a760..b6b56410 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/search/SearchTableModel.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/search/SearchTableModel.java @@ -3,14 +3,16 @@ import javax.swing.table.AbstractTableModel; import java.util.*; +import static muon.app.App.bundle; + public class SearchTableModel extends AbstractTableModel { private static final long serialVersionUID = 7212506492710233442L; - private List list = new ArrayList<>(); - private String[] columns = new String[]{ - "File name", - "Type", - "Path"}; + private final List list = new ArrayList<>(); + private final String[] columns = new String[]{ + bundle.getString("filename"), + bundle.getString("type"), + bundle.getString("path")}; @Override public Class getColumnClass(int columnIndex) { diff --git a/muon-app/src/main/java/muon/app/ui/components/session/terminal/snippets/SnippetPanel.java b/muon-app/src/main/java/muon/app/ui/components/session/terminal/snippets/SnippetPanel.java index dfd9bd29..5a674612 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/terminal/snippets/SnippetPanel.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/terminal/snippets/SnippetPanel.java @@ -18,12 +18,18 @@ import java.util.List; import java.util.function.Consumer; +import static muon.app.App.bundle; + public class SnippetPanel extends JPanel { - private DefaultListModel listModel = new DefaultListModel<>(); - private List snippetList = new ArrayList<>(); - private JList listView = new JList<>(listModel); - private JTextField searchTextField; - private JButton btnCopy, btnInsert, btnAdd, btnEdit, btnDel; + private final DefaultListModel listModel = new DefaultListModel<>(); + private final List snippetList = new ArrayList<>(); + private final JList listView = new JList<>(listModel); + private final JTextField searchTextField; + private final JButton btnCopy; + private final JButton btnInsert; + private final JButton btnAdd; + private final JButton btnEdit; + private final JButton btnDel; public SnippetPanel(Consumer callback, Consumer callback2) { super(new BorderLayout()); @@ -62,11 +68,11 @@ public void changedUpdate(DocumentEvent e) { listView.setCellRenderer(new SnippetListRenderer()); listView.setBackground(App.SKIN.getTableBackgroundColor()); - btnAdd = new JButton("Add"); - btnEdit = new JButton("Edit"); - btnDel = new JButton("Delete"); - btnInsert = new JButton("Insert"); - btnCopy = new JButton("Copy"); + btnAdd = new JButton(bundle.getString("add")); + btnEdit = new JButton(bundle.getString("edit")); + btnDel = new JButton(bundle.getString("delete")); + btnInsert = new JButton(bundle.getString("insert")); + btnCopy = new JButton(bundle.getString("copy")); btnAdd.addActionListener(e -> { JTextField txtName = new SkinnedTextField(30);// new diff --git a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/UtilityPage.java b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/UtilityPage.java index f4837c8c..dd1a11fc 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/UtilityPage.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/UtilityPage.java @@ -26,6 +26,8 @@ import util.FontAwesomeContants; import util.LayoutUtilities; +import static muon.app.App.bundle; + /** * @author subhro * @@ -33,8 +35,8 @@ public class UtilityPage extends Page { private CardLayout cardLayout; private JPanel cardPanel; - private AtomicBoolean init = new AtomicBoolean(false); - private SessionContentPanel holder; + private final AtomicBoolean init = new AtomicBoolean(false); + private final SessionContentPanel holder; /** * @@ -60,7 +62,7 @@ public String getIcon() { @Override public String getText() { - return "Toolbox"; + return bundle.getString("toolbox"); } /** @@ -69,22 +71,22 @@ public String getText() { private void createUI() { ButtonGroup bg = new ButtonGroup(); Box vbox = Box.createVerticalBox(); - UtilityPageButton b1 = new UtilityPageButton("System info", + UtilityPageButton b1 = new UtilityPageButton(bundle.getString("system_info"), FontAwesomeContants.FA_LINUX); - UtilityPageButton b2 = new UtilityPageButton("System load", + UtilityPageButton b2 = new UtilityPageButton(bundle.getString("system_load"), FontAwesomeContants.FA_AREA_CHART); - UtilityPageButton b3 = new UtilityPageButton("Services - systemd", + UtilityPageButton b3 = new UtilityPageButton(bundle.getString("services_systemd"), FontAwesomeContants.FA_SERVER); - UtilityPageButton b4 = new UtilityPageButton("Process and ports", + UtilityPageButton b4 = new UtilityPageButton(bundle.getString("process_ports"), FontAwesomeContants.FA_DATABASE); - UtilityPageButton b5 = new UtilityPageButton("SSH keys", + UtilityPageButton b5 = new UtilityPageButton(bundle.getString("ssh_keys"), FontAwesomeContants.FA_KEY); - UtilityPageButton b6 = new UtilityPageButton("Network tools", + UtilityPageButton b6 = new UtilityPageButton(bundle.getString("network_tools"), FontAwesomeContants.FA_WRENCH); LayoutUtilities.equalizeSize(b1, b2, b3, b4, b5, b6); diff --git a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/keys/KeyPage.java b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/keys/KeyPage.java index 57cd3596..6992f8cb 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/keys/KeyPage.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/keys/KeyPage.java @@ -17,6 +17,8 @@ import muon.app.ui.components.session.SessionInfo; import muon.app.ui.components.session.utilpage.UtilPageItemView; +import static muon.app.App.bundle; + /** * @author subhro * @@ -121,8 +123,8 @@ protected void createUI() { } }); }); - tabs.addTab("Server", remoteKeyPanel); - tabs.addTab("Local computer", localKeyPanel); + tabs.addTab(bundle.getString("server"), remoteKeyPanel); + tabs.addTab(bundle.getString("local_computer"), localKeyPanel); this.add(tabs); holder.EXECUTOR.submit(() -> { diff --git a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/keys/LocalKeyPanel.java b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/keys/LocalKeyPanel.java index 884044fa..0a986460 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/keys/LocalKeyPanel.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/keys/LocalKeyPanel.java @@ -11,12 +11,16 @@ import java.awt.*; import java.util.function.Consumer; +import static muon.app.App.bundle; + public class LocalKeyPanel extends JPanel { - private SessionInfo info; - private JTextField txtKeyFile; - private JButton btnGenNewKey, btnRefresh; - private JTextArea txtPubKey; - private Consumer callback1, callback2; + private final SessionInfo info; + private final JTextField txtKeyFile; + private final JButton btnGenNewKey; + private final JButton btnRefresh; + private final JTextArea txtPubKey; + private final Consumer callback1; + private final Consumer callback2; public LocalKeyPanel(SessionInfo info, Consumer callback1, Consumer callback2) { @@ -24,7 +28,7 @@ public LocalKeyPanel(SessionInfo info, Consumer callback1, this.info = info; this.callback1 = callback1; this.callback2 = callback2; - JLabel lblTitle = new JLabel("Public key file:"); + JLabel lblTitle = new JLabel(bundle.getString("public_key_file")); txtKeyFile = new SkinnedTextField(20);// new JTextField(20); txtKeyFile.setBackground(App.SKIN.getDefaultBackground()); txtKeyFile.setBorder(null); @@ -42,8 +46,8 @@ public LocalKeyPanel(SessionInfo info, Consumer callback1, JScrollPane jScrollPane = new JScrollPane(txtPubKey); add(jScrollPane); - btnGenNewKey = new JButton("Generate new key"); - btnRefresh = new JButton("Refresh"); + btnGenNewKey = new JButton(bundle.getString("generate_new_key")); + btnRefresh = new JButton(bundle.getString("refresh")); btnGenNewKey.addActionListener(e -> { callback1.accept(null); diff --git a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/keys/RemoteKeyPanel.java b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/keys/RemoteKeyPanel.java index 86a601d1..b3b0cd79 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/keys/RemoteKeyPanel.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/keys/RemoteKeyPanel.java @@ -12,15 +12,22 @@ import java.awt.*; import java.util.function.Consumer; +import static muon.app.App.bundle; + public class RemoteKeyPanel extends JPanel { private SessionInfo info; - private JTextField txtKeyFile; - private JButton btnGenNewKey, btnRefresh, btnAdd, btnRemove, btnEdit; - private JTextArea txtPubKey; - private Consumer callback1, callback2; + private final JTextField txtKeyFile; + private final JButton btnGenNewKey; + private final JButton btnRefresh; + private final JButton btnAdd; + private final JButton btnRemove; + private final JButton btnEdit; + private final JTextArea txtPubKey; + private final Consumer callback1; + private final Consumer callback2; private Consumer callback3; - private DefaultListModel model; - private JList jList; + private final DefaultListModel model; + private final JList jList; public RemoteKeyPanel(SessionInfo info, Consumer callback1, Consumer callback2, Consumer callback3) { @@ -30,7 +37,7 @@ public RemoteKeyPanel(SessionInfo info, Consumer callback1, this.callback1 = callback1; // this.callback2 = callback2; this.callback2 = callback3; - JLabel lblTitle = new JLabel("Public key file:"); + JLabel lblTitle = new JLabel(bundle.getString("public_key_file")); txtKeyFile = new SkinnedTextField(20);// new JTextField(20); txtKeyFile.setBorder(null); txtKeyFile.setBackground(App.SKIN.getDefaultBackground()); @@ -46,8 +53,8 @@ public RemoteKeyPanel(SessionInfo info, Consumer callback1, txtPubKey.setLineWrap(true); JScrollPane jScrollPane = new SkinnedScrollPane(txtPubKey); - btnGenNewKey = new JButton("Generate new key"); - btnRefresh = new JButton("Refresh"); + btnGenNewKey = new JButton(bundle.getString("generate_new_key")); + btnRefresh = new JButton(bundle.getString("generate")); btnGenNewKey.addActionListener(e -> { callback1.accept(null); @@ -73,12 +80,12 @@ public RemoteKeyPanel(SessionInfo info, Consumer callback1, jList = new JList<>(model); jList.setBackground(App.SKIN.getTextFieldBackground()); - btnAdd = new JButton("Add"); - btnEdit = new JButton("Edit"); - btnRemove = new JButton("Remove"); + btnAdd = new JButton(bundle.getString("add")); + btnEdit = new JButton(bundle.getString("edit")); + btnRemove = new JButton(); btnAdd.addActionListener(e -> { - String text = JOptionPane.showInputDialog(null, "New entry"); + String text = JOptionPane.showInputDialog(null, bundle.getString("new_entry")); if (text != null && text.length() > 0) { model.addElement(text); callback3.accept(getAuthorizedKeys()); @@ -88,11 +95,11 @@ public RemoteKeyPanel(SessionInfo info, Consumer callback1, btnEdit.addActionListener(e -> { int index = jList.getSelectedIndex(); if (index < 0) { - JOptionPane.showMessageDialog(null, "No entry is selected"); + JOptionPane.showMessageDialog(null, bundle.getString("no_entry_selected")); return; } String str = model.get(index); - String text = JOptionPane.showInputDialog(null, "New entry", str); + String text = JOptionPane.showInputDialog(null, bundle.getString("new_entry"), str); if (text != null && text.length() > 0) { model.set(index, text); callback3.accept(getAuthorizedKeys()); @@ -102,7 +109,7 @@ public RemoteKeyPanel(SessionInfo info, Consumer callback1, btnRemove.addActionListener(e -> { int index = jList.getSelectedIndex(); if (index < 0) { - JOptionPane.showMessageDialog(null, "No entry is selected"); + JOptionPane.showMessageDialog(null, bundle.getString("no_entry_selected")); return; } model.remove(index); @@ -120,7 +127,7 @@ public RemoteKeyPanel(SessionInfo info, Consumer callback1, Box hbox2 = Box.createHorizontalBox(); hbox2.setBorder(new EmptyBorder(10, 10, 10, 10)); - hbox2.add(new JLabel("Authorized keys")); + hbox2.add(new JLabel(bundle.getString("authorized_keys"))); hbox2.add(Box.createHorizontalStrut(10)); JPanel authorizedKeysPanel = new JPanel(new BorderLayout()); diff --git a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/nettools/NetworkToolsPage.java b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/nettools/NetworkToolsPage.java index 198a6435..2f67fb2e 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/nettools/NetworkToolsPage.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/nettools/NetworkToolsPage.java @@ -6,6 +6,7 @@ import java.awt.BorderLayout; import java.awt.GridLayout; import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; import java.util.concurrent.atomic.AtomicBoolean; import javax.swing.DefaultComboBoxModel; @@ -25,6 +26,8 @@ import muon.app.ui.components.session.SessionContentPanel; import muon.app.ui.components.session.utilpage.UtilPageItemView; +import static muon.app.App.bundle; + /** * @author subhro * @@ -65,7 +68,7 @@ protected void createUI() { btn1.addActionListener(e -> { if (JOptionPane.showOptionDialog(this, - new Object[] { "Host to ping", cmbHost }, "Ping", + new Object[] { bundle.getString("host_ping"), cmbHost }, "Ping", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, null, null) == JOptionPane.OK_OPTION) { executeAsync("ping -c 4 " + cmbHost.getSelectedItem()); @@ -74,7 +77,7 @@ protected void createUI() { btn2.addActionListener(e -> { if (JOptionPane.showOptionDialog(this, - new Object[] { "Host name", cmbHost, "Port number", + new Object[] { bundle.getString("host_name"), cmbHost, bundle.getString("port_number"), cmbPort }, "Port check", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, null, @@ -88,7 +91,7 @@ protected void createUI() { btn3.addActionListener(e -> { if (JOptionPane.showOptionDialog(this, - new Object[] { "Host name", cmbHost }, "Traceroute", + new Object[] { bundle.getString("host_name"), cmbHost }, "Traceroute", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, null, null) == JOptionPane.OK_OPTION) { executeAsync("traceroute " + cmbHost.getSelectedItem()); @@ -97,7 +100,7 @@ protected void createUI() { btn4.addActionListener(e -> { if (JOptionPane.showOptionDialog(this, - new Object[] { "Host name", cmbHost, "Tool to use", + new Object[] { bundle.getString("host_name"), cmbHost, bundle.getString("tool_use"), cmbDNSTool }, "DNS lookup", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, null, @@ -135,11 +138,11 @@ private void executeAsync(String cmd) { if (holder.getRemoteSessionInstance().execBin(cmd, stopFlag, bout, null) == 0) { outText.append( - new String(bout.toByteArray(), "utf-8") + "\n"); + bout.toString(StandardCharsets.UTF_8) + "\n"); System.out.println("Command stdout: " + outText); } else { JOptionPane.showMessageDialog(this, - "Error executed with errors"); + bundle.getString("executed_errors")); } } catch (Exception e) { e.printStackTrace(); diff --git a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/portview/PortViewer.java b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/portview/PortViewer.java index 21e92619..7576b208 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/portview/PortViewer.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/portview/PortViewer.java @@ -29,13 +29,15 @@ import muon.app.ui.components.session.utilpage.UtilPageItemView; import util.SudoUtils; +import static muon.app.App.bundle; + /** * @author subhro * */ public class PortViewer extends UtilPageItemView { private static final String SEPARATOR = UUID.randomUUID().toString(); - private SocketTableModel model = new SocketTableModel(); + private final SocketTableModel model = new SocketTableModel(); private JTable table; private JButton btnRefresh; @@ -144,9 +146,9 @@ protected void createUI() { table.setIntercellSpacing(new Dimension(0, 0)); table.setFillsViewportHeight(true); - JLabel lbl1 = new JLabel("Search"); + JLabel lbl1 = new JLabel(bundle.getString("search")); txtFilter = new SkinnedTextField(30);// new JTextField(30); - btnFilter = new JButton("Search"); + btnFilter = new JButton(bundle.getString("search")); Box b1 = Box.createHorizontalBox(); b1.add(lbl1); @@ -165,7 +167,7 @@ protected void createUI() { Box box = Box.createHorizontalBox(); box.setBorder(new EmptyBorder(10, 0, 0, 0)); - btnRefresh = new JButton("Refresh"); + btnRefresh = new JButton(bundle.getString("refresh")); btnRefresh.addActionListener(e -> { getListingSockets(); }); diff --git a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/portview/SocketTableModel.java b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/portview/SocketTableModel.java index 0ab0e64c..5d94f5c8 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/portview/SocketTableModel.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/portview/SocketTableModel.java @@ -4,9 +4,11 @@ import java.util.ArrayList; import java.util.List; +import static muon.app.App.bundle; + public class SocketTableModel extends AbstractTableModel { - private String columns[] = {"Process", "PID", "Host", "Port"}; - private List list = new ArrayList<>(); + private final String[] columns = {bundle.getString("processes"), bundle.getString("pid"), bundle.getString("host"), bundle.getString("port")}; + private final List list = new ArrayList<>(); public void addEntry(SocketEntry e) { list.add(e); diff --git a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/services/ServicePanel.java b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/services/ServicePanel.java index 2c0284ec..e8cc7602 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/services/ServicePanel.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/services/ServicePanel.java @@ -33,12 +33,14 @@ import muon.app.ui.components.session.utilpage.UtilPageItemView; import util.SudoUtils; +import static muon.app.App.bundle; + /** * @author subhro * */ public class ServicePanel extends UtilPageItemView { - private ServiceTableModel model = new ServiceTableModel(); + private final ServiceTableModel model = new ServiceTableModel(); private JTable table; private static final Pattern SERVICE_PATTERN = Pattern .compile("(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+([\\S]+.*)"); @@ -261,12 +263,12 @@ protected void createUI() { table.setIntercellSpacing(new Dimension(0, 0)); table.setFillsViewportHeight(true); - JLabel lbl1 = new JLabel("Search"); + JLabel lbl1 = new JLabel(bundle.getString("search")); txtFilter = new SkinnedTextField(30);// new JTextField(30); txtFilter.addActionListener(e -> { filter(); }); - btnFilter = new JButton("Search"); + btnFilter = new JButton(bundle.getString("search")); Box b1 = Box.createHorizontalBox(); b1.add(lbl1); @@ -285,16 +287,16 @@ protected void createUI() { Box box = Box.createHorizontalBox(); - btnStart = new JButton("Start"); - btnStop = new JButton("Stop"); - btnRestart = new JButton("Restart"); - btnReload = new JButton("Reload"); - btnEnable = new JButton("Enable"); - btnDisable = new JButton("Disable"); - btnRefresh = new JButton("Refresh"); + btnStart = new JButton(bundle.getString("start")); + btnStop = new JButton(bundle.getString("stop")); + btnRestart = new JButton(bundle.getString("restart")); + btnReload = new JButton(bundle.getString("reload")); + btnEnable = new JButton(bundle.getString("enable")); + btnDisable = new JButton(bundle.getString("disable")); + btnRefresh = new JButton(bundle.getString("refresh")); chkRunAsSuperUser = new JCheckBox( - "Perform actions as super user (sudo)"); + bundle.getString("actions_sudo")); box.add(chkRunAsSuperUser); box.add(Box.createHorizontalGlue()); @@ -410,7 +412,7 @@ private void performServiceAction(int option) { } if (!holder.isSessionClosed()) { JOptionPane.showMessageDialog(null, - "Operation failed"); + bundle.getString("operation_failed")); } // JOptionPane.showMessageDialog(null, "Operation // failed"); @@ -427,7 +429,7 @@ private void performServiceAction(int option) { } if (!holder.isSessionClosed()) { JOptionPane.showMessageDialog(null, - "Operation failed"); + bundle.getString("operation_failed")); } // JOptionPane.showMessageDialog(null, "Operation // failed"); } diff --git a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/services/ServiceTableModel.java b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/services/ServiceTableModel.java index 6bc46b53..5ec001f9 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/services/ServiceTableModel.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/services/ServiceTableModel.java @@ -8,13 +8,15 @@ import javax.swing.table.AbstractTableModel; +import static muon.app.App.bundle; + /** * @author subhro * */ public class ServiceTableModel extends AbstractTableModel { - private String columns[] = { "Name", "Status", "State", "Description" }; - private List list = new ArrayList<>(); + private final String[] columns = { bundle.getString("name"), bundle.getString("status"), bundle.getString("state"), bundle.getString("description") }; + private final List list = new ArrayList<>(); public void addEntry(ServiceEntry e) { list.add(e); diff --git a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/sysload/SysLoadPage.java b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/sysload/SysLoadPage.java index b2945ea3..edac1c20 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/sysload/SysLoadPage.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/sysload/SysLoadPage.java @@ -19,6 +19,8 @@ import muon.app.ui.components.session.SessionContentPanel; import muon.app.ui.components.session.utilpage.UtilPageItemView; +import static muon.app.App.bundle; + /** * @author subhro * @@ -26,7 +28,7 @@ public class SysLoadPage extends UtilPageItemView { private SystemLoadPanel systemLoadPanel; private JSpinner spInterval; - private AtomicInteger sleepInterval = new AtomicInteger(3); + private final AtomicInteger sleepInterval = new AtomicInteger(3); private Timer timer; private LinuxMetrics metrics; private String OS; @@ -139,7 +141,7 @@ protected void createUI() { topPanel.add(titleLabel); topPanel.add(Box.createHorizontalGlue()); - topPanel.add(new JLabel("Refresh interval")); + topPanel.add(new JLabel(bundle.getString("refresh_interval"))); topPanel.add(Box.createHorizontalStrut(5)); topPanel.add(spInterval); topPanel.add(Box.createHorizontalStrut(5)); diff --git a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/sysload/SystemLoadPanel.java b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/sysload/SystemLoadPanel.java index 2a83c448..d744614b 100644 --- a/muon-app/src/main/java/muon/app/ui/components/session/utilpage/sysload/SystemLoadPanel.java +++ b/muon-app/src/main/java/muon/app/ui/components/session/utilpage/sysload/SystemLoadPanel.java @@ -7,14 +7,20 @@ import java.awt.*; +import static muon.app.App.bundle; + public class SystemLoadPanel extends JPanel { - private LineGraph cpuGraph, memGraph, swpGraph; - private double cpuStats[] = new double[10]; - private double memStats[] = new double[10]; - private double swpStats[] = new double[10]; + private final LineGraph cpuGraph; + private final LineGraph memGraph; + private final LineGraph swpGraph; + private final double[] cpuStats = new double[10]; + private final double[] memStats = new double[10]; + private final double[] swpStats = new double[10]; private long totalMemory, usedMemory, totalSwap, usedSwap; private double cpuUsage, memoryUsage, swapUsage; - private JLabel cpuLabel, memoryLabel, swapLabel; + private final JLabel cpuLabel; + private final JLabel memoryLabel; + private final JLabel swapLabel; public SystemLoadPanel() { super(new BorderLayout(5, 5)); @@ -23,7 +29,7 @@ public SystemLoadPanel() { setPreferredSize(new Dimension(300, 400)); Box b1 = Box.createVerticalBox(); - cpuLabel = new JLabel("Cpu usage"); + cpuLabel = new JLabel(bundle.getString("cpu_usage")); cpuLabel.setBorder(new EmptyBorder(0, 0, 10, 0)); cpuLabel.setAlignmentX(Box.LEFT_ALIGNMENT); b1.add(cpuLabel); @@ -33,7 +39,7 @@ public SystemLoadPanel() { cpuGraph.setAlignmentX(Box.LEFT_ALIGNMENT); b1.add(cpuGraph); - memoryLabel = new JLabel("Memory usage"); + memoryLabel = new JLabel(bundle.getString("memory_usage")); memoryLabel.setBorder(new EmptyBorder(20, 0, 10, 0)); memoryLabel.setAlignmentX(Box.LEFT_ALIGNMENT); b1.add(memoryLabel); @@ -43,7 +49,7 @@ public SystemLoadPanel() { memGraph.setAlignmentX(Box.LEFT_ALIGNMENT); b1.add(memGraph); - swapLabel = new JLabel("Swap usage"); + swapLabel = new JLabel(bundle.getString("swap_usage")); swapLabel.setBorder(new EmptyBorder(20, 0, 10, 0)); swapLabel.setAlignmentX(Box.LEFT_ALIGNMENT); b1.add(swapLabel); @@ -99,25 +105,25 @@ public void setUsedSwap(long usedSwap) { public void refreshUi() { this.cpuLabel - .setText(String.format("Cpu usage: %.1f", cpuUsage) + "% "); - this.memoryLabel.setText(String.format("Memory usage: %.1f", + .setText(String.format(bundle.getString("cpu_usage") +": %.1f", cpuUsage) + "% "); + this.memoryLabel.setText(String.format(bundle.getString("memory_usage") +": %.1f", memoryUsage) + "%" + (totalMemory != 0 ? (", (Total: " + FormatUtils .humanReadableByteCount(totalMemory, true) - + ", Used: " + + ", "+bundle.getString("used2") +": " + FormatUtils.humanReadableByteCount(usedMemory, true) + ")") : "")); - this.swapLabel.setText(String.format("Swap usage: %.1f", swapUsage) + this.swapLabel.setText(String.format(bundle.getString("swap_usage") +": %.1f", swapUsage) + "% " + (totalSwap != 0 ? (", ( Total: " + FormatUtils.humanReadableByteCount(totalSwap, true) - + ", Used: " + FormatUtils + + ", "+bundle.getString("used2") +": " + FormatUtils .humanReadableByteCount(usedSwap, true) + ")") : "")); diff --git a/muon-app/src/main/java/muon/app/ui/components/settings/EditorTableModel.java b/muon-app/src/main/java/muon/app/ui/components/settings/EditorTableModel.java index 893d1bb4..0b529c8a 100644 --- a/muon-app/src/main/java/muon/app/ui/components/settings/EditorTableModel.java +++ b/muon-app/src/main/java/muon/app/ui/components/settings/EditorTableModel.java @@ -4,10 +4,10 @@ import java.util.List; import javax.swing.table.AbstractTableModel; - +import static muon.app.App.bundle; public class EditorTableModel extends AbstractTableModel { - private List list = new ArrayList<>(); - private String cols[] = { "Editor name", "Path to executable" }; + private final List list = new ArrayList<>(); + private final String[] cols = { bundle.getString("editor_name"), bundle.getString("path_executable")}; @Override public int getRowCount() { diff --git a/muon-app/src/main/java/muon/app/ui/components/settings/SettingsDialog.java b/muon-app/src/main/java/muon/app/ui/components/settings/SettingsDialog.java index a4526734..0ab72072 100644 --- a/muon-app/src/main/java/muon/app/ui/components/settings/SettingsDialog.java +++ b/muon-app/src/main/java/muon/app/ui/components/settings/SettingsDialog.java @@ -3,92 +3,68 @@ */ package muon.app.ui.components.settings; -import java.awt.BorderLayout; -import java.awt.CardLayout; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.GridLayout; -import java.io.File; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import javax.swing.Box; -import javax.swing.DefaultComboBoxModel; -import javax.swing.DefaultListModel; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JDialog; -import javax.swing.JFileChooser; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JList; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JPasswordField; -import javax.swing.JScrollPane; -import javax.swing.JSpinner; -import javax.swing.JTable; -import javax.swing.JTextField; -import javax.swing.ListCellRenderer; -import javax.swing.SpinnerNumberModel; -import javax.swing.border.CompoundBorder; -import javax.swing.border.EmptyBorder; -import javax.swing.border.MatteBorder; - import com.jediterm.terminal.emulator.ColorPalette; - import muon.app.App; import muon.app.PasswordStore; import muon.app.Settings; import muon.app.ui.components.KeyShortcutComponent; import muon.app.ui.components.SkinnedScrollPane; import muon.app.ui.components.SkinnedTextField; -import muon.app.ui.components.session.files.transfer.FileTransfer.ConflictAction; import muon.app.ui.components.session.files.transfer.FileTransfer.TransferMode; -import util.CollectionHelper; import util.FontUtils; +import util.Language; import util.LayoutUtilities; import util.OptionPaneUtils; +import javax.swing.*; +import javax.swing.border.CompoundBorder; +import javax.swing.border.EmptyBorder; +import javax.swing.border.MatteBorder; +import java.awt.*; +import java.io.File; +import java.util.*; +import java.util.List; + +import static muon.app.App.bundle; + /** * @author subhro * */ public class SettingsDialog extends JDialog { - private EditorTableModel editorModel = new EditorTableModel(); + private final EditorTableModel editorModel = new EditorTableModel(); private JSpinner spTermWidth, spTermHeight, spFontSize; private JCheckBox chkAudibleBell, chkPuttyLikeCopyPaste; - private JComboBox cmbFonts, cmbTermType, cmbTermPalette; + private JComboBox cmbFonts, cmbTermType, cmbTermPalette, cmbLanguage; private JComboBox cmbTermTheme; - private JButton btnSave, btnCancel, btnReset; + private final JButton btnSave; + private final JButton btnCancel; + private final JButton btnReset; private ColorSelectorButton[] paletteButtons; private ColorSelectorButton defaultColorFg, defaultColorBg, defaultSelectionFg, defaultSelectionBg, defaultFoundFg, defaultFoundBg; private JCheckBox chkConfirmBeforeDelete, chkConfirmBeforeMoveOrCopy, chkShowHiddenFilesByDefault, chkPromptForSudo, chkDirectoryCache, chkShowPathBar, chkConfirmBeforeTerminalClosing, chkShowMessagePrompt, chkUseGlobalDarkTheme; - private KeyShortcutComponent kcc[]; + private KeyShortcutComponent[] kcc; private JCheckBox chkLogWrap; private JSpinner spLogLinesPerPage, spLogFontSize; private JSpinner spSysLoadInterval; private JComboBox cmbTransferMode, cmbConflictAction; - private DefaultComboBoxModel conflictOptions = new DefaultComboBoxModel<>(); + private final DefaultComboBoxModel conflictOptions = new DefaultComboBoxModel<>(); + + private final List conflictOption1 = Arrays.asList(bundle.getString("overwrite"), bundle.getString("auto_rename"), bundle.getString("skip"), bundle.getString("prompt")); + private final List conflictOption2 = Arrays.asList(bundle.getString("overwrite"), bundle.getString("auto_rename"), bundle.getString("skip")); + - private List conflictOption1 = Arrays.asList("Overwrite", "Auto rename", "Skip", "Prompt"); - private List conflictOption2 = Arrays.asList("Overwrite", "Auto rename", "Skip"); private JTable editorTable; - private CardLayout cardLayout; - private JPanel cardPanel; - private JList navList; + private final CardLayout cardLayout; + private final JPanel cardPanel; + private final JList navList; private JCheckBox chkUseManualScaling; private JSpinner spScaleValue; @@ -101,7 +77,7 @@ public class SettingsDialog extends JDialog { */ public SettingsDialog(JFrame window) { super(window); - setTitle("Settings"); + setTitle(bundle.getString("settings")); setModal(true); setSize(800, 600); @@ -125,11 +101,12 @@ public SettingsDialog(JFrame window) { }); Map panelMap = new LinkedHashMap<>(); - panelMap.put(SettingsPageName.General.toString(), createGeneralPanel()); - panelMap.put(SettingsPageName.Terminal.toString(), createTerminalPanel()); - panelMap.put(SettingsPageName.Editor.toString(), createEditorPanel()); - panelMap.put(SettingsPageName.Display.toString(), createMiscPanel()); - panelMap.put(SettingsPageName.Security.toString(), createSecurityPanel()); + + panelMap.put(bundle.getString("general"), createGeneralPanel()); + panelMap.put(bundle.getString("terminal"), createTerminalPanel()); + panelMap.put(bundle.getString("editor"), createEditorPanel()); + panelMap.put(bundle.getString("display"), createMiscPanel()); + panelMap.put(bundle.getString("security"), createSecurityPanel()); for (String key : panelMap.keySet()) { navModel.addElement(key); @@ -144,9 +121,9 @@ public SettingsDialog(JFrame window) { bottomBox.setBorder(new CompoundBorder(new MatteBorder(1, 0, 0, 0, App.SKIN.getDefaultBorderColor()), new EmptyBorder(10, 10, 10, 10))); - btnCancel = new JButton("Cancel"); - btnSave = new JButton("Save"); - btnReset = new JButton("Reset"); + btnCancel = new JButton(bundle.getString("cancel")); + btnSave = new JButton(bundle.getString("save")); + btnReset = new JButton(bundle.getString("reset")); btnSave.addActionListener(e -> { applySettings(); @@ -158,7 +135,7 @@ public SettingsDialog(JFrame window) { btnReset.addActionListener(e -> { loadSettings(new Settings()); - JOptionPane.showMessageDialog(this, "Settings have been reset,\nplease save and restart the app"); + JOptionPane.showMessageDialog(this, bundle.getString("settings_saved")); }); bottomBox.add(btnReset); @@ -221,18 +198,18 @@ private Component createTerminalPanel() { spFontSize = new JSpinner(new SpinnerNumberModel(12, 1, Short.MAX_VALUE, 1)); resizeNumericSpinner(spFontSize); - Component boxTermSize = createRow(new JLabel("Columns"), Box.createRigidArea(new Dimension(10, 10)), - spTermWidth, Box.createRigidArea(new Dimension(20, 10)), new JLabel("Rows"), + Component boxTermSize = createRow(new JLabel(bundle.getString("columns")), Box.createRigidArea(new Dimension(10, 10)), + spTermWidth, Box.createRigidArea(new Dimension(20, 10)), new JLabel(bundle.getString("rows")), Box.createRigidArea(new Dimension(10, 10)), spTermHeight, Box.createHorizontalGlue(), - new JButton("Reset")); + new JButton(bundle.getString("reset"))); Component boxTermBell = createRow(chkAudibleBell); - Component boxFontRow = createRow(new JLabel("Font name"), Box.createRigidArea(new Dimension(10, 10)), cmbFonts, - Box.createRigidArea(new Dimension(20, 10)), new JLabel("Font size"), + Component boxFontRow = createRow(new JLabel(bundle.getString("font_name")), Box.createRigidArea(new Dimension(10, 10)), cmbFonts, + Box.createRigidArea(new Dimension(20, 10)), new JLabel(bundle.getString("font_size")), Box.createRigidArea(new Dimension(10, 10)), spFontSize); - chkPuttyLikeCopyPaste = new JCheckBox("PuTTY like copy paste (Copy on select and paste on right click)"); + chkPuttyLikeCopyPaste = new JCheckBox(bundle.getString("copy_like_putty")); cmbTermType = new JComboBox<>(new String[] { "xterm-256color", "xterm", "vt100" }); cmbTermType.setEditable(true); @@ -242,9 +219,25 @@ private Component createTerminalPanel() { cmbTermType.setMinimumSize(d); cmbTermType.setPreferredSize(d); - Component boxTermType = createRow(new JLabel("Terminal type"), Box.createRigidArea(new Dimension(10, 10)), + Component boxTermType = createRow(new JLabel(bundle.getString("terminal_type")), Box.createRigidArea(new Dimension(10, 10)), cmbTermType); + + cmbLanguage = new JComboBox(); + cmbLanguage.setModel(new DefaultComboBoxModel(Language.values())); + cmbLanguage.setEditable(true); + d = new Dimension(Math.max(100, cmbLanguage.getPreferredSize().width * 2), + cmbLanguage.getPreferredSize().height); + cmbLanguage.setMaximumSize(d); + cmbLanguage.setMinimumSize(d); + cmbLanguage.setPreferredSize(d); + Settings settings = App.loadSettings2(); + + cmbLanguage.setSelectedItem(settings.getLanguage()); + + Component boxLanguage = createRow(new JLabel(bundle.getString("language")), Box.createRigidArea(new Dimension(10, 10)), + cmbLanguage); + Component boxTermCopy = createRow(chkPuttyLikeCopyPaste); defaultColorFg = new ColorSelectorButton(); @@ -320,62 +313,70 @@ private Component createTerminalPanel() { LayoutUtilities.equalizeSize(labels[0], labels[1], labels[2], labels[3]); - Component kcPanels[] = { createRow(labels[0], kcc[0]), createRow(labels[1], kcc[1]), + Component[] kcPanels = { createRow(labels[0], kcc[0]), createRow(labels[1], kcc[1]), createRow(labels[2], kcc[2]), createRow(labels[3], kcc[3]) }; Box panel = Box.createVerticalBox(); panel.add(Box.createVerticalStrut(20)); - panel.add(createTitleLabel("Initial terminal size")); + panel.add(createTitleLabel(bundle.getString("initial_terminal_type"))); panel.add(Box.createVerticalStrut(10)); panel.add(boxTermSize); panel.add(Box.createVerticalStrut(30)); - panel.add(createTitleLabel("Sound")); + panel.add(createTitleLabel(bundle.getString("sound"))); panel.add(Box.createVerticalStrut(10)); panel.add(boxTermBell); panel.add(Box.createVerticalStrut(30)); - panel.add(createTitleLabel("Terminal font")); + panel.add(createTitleLabel(bundle.getString("terminal_font"))); panel.add(Box.createVerticalStrut(10)); panel.add(boxFontRow); panel.add(Box.createVerticalStrut(30)); - panel.add(createTitleLabel("Misc")); + panel.add(createTitleLabel(bundle.getString("misc"))); panel.add(Box.createVerticalStrut(10)); panel.add(boxTermCopy); panel.add(Box.createVerticalStrut(5)); panel.add(boxTermType); + + panel.add(Box.createVerticalStrut(30)); + panel.add(createTitleLabel(bundle.getString("language"))); + panel.add(Box.createVerticalStrut(10)); + panel.add(boxLanguage); + panel.add(Box.createVerticalStrut(5)); + panel.add(boxLanguage); + panel.add(Box.createVerticalStrut(30)); - panel.add(createTitleLabel("Terminal colors and theme")); + panel.add(createTitleLabel(bundle.getString("terminal_colors"))); panel.add(Box.createVerticalStrut(10)); - panel.add(createRow(new JLabel("Terminal theme"), Box.createRigidArea(new Dimension(10, 10)), cmbTermTheme)); + panel.add(createRow(new JLabel(bundle.getString("terminal_theme")), Box.createRigidArea(new Dimension(10, 10)), cmbTermTheme)); panel.add(Box.createVerticalStrut(20)); - panel.add(createRow(new JLabel("Default color"))); + panel.add(createRow(new JLabel(bundle.getString("default_color")))); panel.add(Box.createVerticalStrut(10)); - panel.add(createRow(new JLabel("Text"), Box.createRigidArea(new Dimension(10, 10)), defaultColorFg, - Box.createRigidArea(new Dimension(20, 10)), new JLabel("Background"), + panel.add(createRow(new JLabel(bundle.getString("text")), Box.createRigidArea(new Dimension(10, 10)), defaultColorFg, + Box.createRigidArea(new Dimension(20, 10)), new JLabel(bundle.getString("background")), Box.createRigidArea(new Dimension(10, 10)), defaultColorBg)); panel.add(Box.createVerticalStrut(10)); - panel.add(createRow(new JLabel("Selection color"))); + panel.add(createRow(new JLabel(bundle.getString("selection_color")))); panel.add(Box.createVerticalStrut(10)); - panel.add(createRow(new JLabel("Text"), Box.createRigidArea(new Dimension(10, 10)), defaultSelectionFg, - Box.createRigidArea(new Dimension(20, 10)), new JLabel("Background"), + panel.add(createRow(new JLabel(bundle.getString("text")), Box.createRigidArea(new Dimension(10, 10)), defaultSelectionFg, + Box.createRigidArea(new Dimension(20, 10)), new JLabel(bundle.getString("background")), Box.createRigidArea(new Dimension(10, 10)), defaultSelectionBg)); panel.add(Box.createVerticalStrut(10)); - panel.add(createRow(new JLabel("Search pattern"))); + panel.add(createRow(new JLabel(bundle.getString("search_pattern")))); panel.add(Box.createVerticalStrut(10)); - panel.add(createRow(new JLabel("Text"), Box.createRigidArea(new Dimension(10, 10)), defaultFoundFg, - Box.createRigidArea(new Dimension(20, 10)), new JLabel("Background"), + panel.add(createRow(new JLabel(bundle.getString("text")), Box.createRigidArea(new Dimension(10, 10)), defaultFoundFg, + Box.createRigidArea(new Dimension(20, 10)), new JLabel(bundle.getString("background")), Box.createRigidArea(new Dimension(10, 10)), defaultFoundBg)); panel.add(Box.createVerticalStrut(30)); - panel.add(createRow(new JLabel("Color palette"), Box.createRigidArea(new Dimension(10, 10)), cmbTermPalette)); + panel.add(createRow(new JLabel(bundle.getString("color_palette")), Box.createRigidArea(new Dimension(10, 10)), cmbTermPalette)); panel.add(Box.createVerticalStrut(10)); panel.add(paletteGrid); panel.add(Box.createVerticalStrut(30)); - panel.add(createTitleLabel("Terminal shortcuts")); + panel.add(createTitleLabel(bundle.getString("terminal_shortcuts"))); panel.add(Box.createVerticalStrut(10)); for (Component cc : kcPanels) { panel.add(cc); @@ -396,21 +397,21 @@ private Component createTerminalPanel() { public JPanel createGeneralPanel() { JPanel panel = new JPanel(new BorderLayout()); - chkConfirmBeforeDelete = new JCheckBox("Confirm before deleting files"); - chkConfirmBeforeMoveOrCopy = new JCheckBox("Confirm before moving or copying files"); - chkShowHiddenFilesByDefault = new JCheckBox("Show hidden files by default"); - chkPromptForSudo = new JCheckBox("Prompt for sudo if operation fails due to permission issues"); - chkDirectoryCache = new JCheckBox("Use directory caching"); - chkShowPathBar = new JCheckBox("Show current folder in path bar style"); - chkShowMessagePrompt = new JCheckBox("Show banner"); + chkConfirmBeforeDelete = new JCheckBox(bundle.getString("confirm_delete_files")); + chkConfirmBeforeMoveOrCopy = new JCheckBox(bundle.getString("confirm_move_files")); + chkShowHiddenFilesByDefault = new JCheckBox(bundle.getString("show_hidden_files")); + chkPromptForSudo = new JCheckBox(bundle.getString("prompt_for_sudo")); + chkDirectoryCache = new JCheckBox(bundle.getString("directory_caching")); + chkShowPathBar = new JCheckBox(bundle.getString("current_folder")); + chkShowMessagePrompt = new JCheckBox(bundle.getString("show_banner")); - chkLogWrap = new JCheckBox("Word wrap on log viewer"); + chkLogWrap = new JCheckBox(bundle.getString("word_wrap")); spLogLinesPerPage = new JSpinner(new SpinnerNumberModel(50, 10, 500, 1)); spLogFontSize = new JSpinner(new SpinnerNumberModel(14, 5, 500, 1)); spSysLoadInterval = new JSpinner(new SpinnerNumberModel(3, 1, Short.MAX_VALUE, 1)); - cmbTransferMode = new JComboBox<>(new String[] { "Transfer normally", "Transfer in background" }); + cmbTransferMode = new JComboBox<>(new String[] { bundle.getString("transfer_normally"), bundle.getString("transfer_background") }); cmbConflictAction = new JComboBox<>(conflictOptions); Dimension d1 = new Dimension(Math.max(200, cmbTransferMode.getPreferredSize().width * 2), @@ -471,8 +472,8 @@ public JPanel createGeneralPanel() { vbox.add(chkShowMessagePrompt); vbox.add(Box.createRigidArea(new Dimension(10, 20))); - JLabel lbl1 = new JLabel("Log viewer lines per page"), lbl2 = new JLabel("Log viewer font size"), - lbl3 = new JLabel("System load refresh interval (sec)"); + JLabel lbl1 = new JLabel(bundle.getString("log_viewer_lines")), lbl2 = new JLabel(bundle.getString("log_viewer_font_size")), + lbl3 = new JLabel(bundle.getString("system_refresh_interval")); // lbl1.setFont(font); // lbl2.setFont(font); @@ -489,9 +490,9 @@ public JPanel createGeneralPanel() { vbox.add(Box.createRigidArea(new Dimension(10, 10))); vbox.add(createRow(lbl3, Box.createHorizontalGlue(), spSysLoadInterval)); vbox.add(Box.createRigidArea(new Dimension(10, 10))); - vbox.add(createRow(new JLabel("Transfer mode"), Box.createHorizontalGlue(), cmbTransferMode)); + vbox.add(createRow(new JLabel(bundle.getString("transfer_mode")), Box.createHorizontalGlue(), cmbTransferMode)); vbox.add(Box.createRigidArea(new Dimension(10, 10))); - vbox.add(createRow(new JLabel("Conflict action"), Box.createHorizontalGlue(), cmbConflictAction)); + vbox.add(createRow(new JLabel(bundle.getString("conflict_action")), Box.createHorizontalGlue(), cmbConflictAction)); vbox.add(Box.createRigidArea(new Dimension(10, 10))); vbox.setBorder(new EmptyBorder(30, 10, 10, 10)); @@ -544,6 +545,7 @@ private void applySettings() { settings.setTerminalFontSize((int) this.spFontSize.getModel().getValue()); settings.setTerminalFontName(this.cmbFonts.getSelectedItem().toString()); settings.setTerminalType(this.cmbTermType.getSelectedItem().toString()); + settings.setLanguage((Language) this.cmbLanguage.getSelectedItem()); settings.setTerminalTheme(this.cmbTermTheme.getSelectedItem().toString()); settings.setTerminalPalette(this.cmbTermPalette.getSelectedItem().toString()); @@ -627,7 +629,7 @@ private void loadSettings(Settings settings) { this.cmbTermTheme.setSelectedItem(settings.getTerminalTheme()); - int colors[] = settings.getPalleteColors(); + int[] colors = settings.getPalleteColors(); for (int i = 0; i < paletteButtons.length; i++) { paletteButtons[i].setColor(new Color(colors[i])); @@ -674,7 +676,7 @@ private void loadSettings(Settings settings) { cmbTransferMode.setSelectedIndex(settings.getFileTransferMode() == TransferMode.Normal ? 0 : 1); // set initial values - conflictOptions.addAll(conflictOption1); + //conflictOptions.addAll(conflictOption1); switch (settings.getConflictAction()) { case OverWrite: @@ -721,8 +723,8 @@ public JPanel createEditorPanel() { editorTable = new JTable(editorModel); panel.add(new SkinnedScrollPane(editorTable)); Box box = Box.createHorizontalBox(); - JButton btnAddEditor = new JButton("+ Add editor"); - JButton btnDelEditor = new JButton("- Remove editor"); + JButton btnAddEditor = new JButton(bundle.getString("add_editor")); + JButton btnDelEditor = new JButton(bundle.getString("remove_editor")); box.add(Box.createHorizontalGlue()); box.add(btnAddEditor); box.add(Box.createHorizontalStrut(10)); @@ -735,7 +737,7 @@ public JPanel createEditorPanel() { File file = jfc.getSelectedFile(); JTextField txt = new SkinnedTextField(30); txt.setText(file.getName()); - String name = OptionPaneUtils.showInputDialog(this, "Editor name", file.getName(), "Add editor?"); + String name = OptionPaneUtils.showInputDialog(this, bundle.getString("editor_name"), file.getName(), bundle.getString("add_editor2")); if (name != null) { editorModel.addEntry(new EditorEntry(name, file.getAbsolutePath())); } @@ -753,18 +755,18 @@ public JPanel createEditorPanel() { private Component createMiscPanel() { JPanel panel = new JPanel(new BorderLayout()); - chkUseManualScaling = new JCheckBox("Zoom (Make application look small or big on screen)"); + chkUseManualScaling = new JCheckBox(bundle.getString("zoom_text")); spScaleValue = new JSpinner(new SpinnerNumberModel(1.0, 0.5, 100.0, 0.01)); resizeNumericSpinner(spScaleValue); - chkUseGlobalDarkTheme = new JCheckBox("Use global dark theme (Needs restart)"); + chkUseGlobalDarkTheme = new JCheckBox(bundle.getString("global_dark_theme")); chkUseGlobalDarkTheme.setAlignmentX(Box.LEFT_ALIGNMENT); Box vbox = Box.createVerticalBox(); chkUseManualScaling.setAlignmentX(Box.LEFT_ALIGNMENT); vbox.add(chkUseManualScaling); vbox.add(Box.createRigidArea(new Dimension(10, 10))); - vbox.add(createRow(new JLabel("Zoom percentage"), Box.createHorizontalGlue(), spScaleValue)); + vbox.add(createRow(new JLabel(bundle.getString("zoom_percentage")), Box.createHorizontalGlue(), spScaleValue)); vbox.add(Box.createRigidArea(new Dimension(10, 10))); vbox.add(chkUseGlobalDarkTheme); vbox.setBorder(new EmptyBorder(30, 10, 10, 10)); @@ -778,8 +780,8 @@ private Component createMiscPanel() { private Component createSecurityPanel() { JPanel panel = new JPanel(new BorderLayout()); - chkUseMasterPassword = new JCheckBox("Use master password"); - btnChangeMasterPassword = new JButton("Change master password"); + chkUseMasterPassword = new JCheckBox(bundle.getString("use_master_password")); + btnChangeMasterPassword = new JButton(bundle.getString("change_master_password")); chkUseMasterPassword.addActionListener(e -> { if (chkUseMasterPassword.isSelected()) { @@ -791,25 +793,25 @@ private Component createSecurityPanel() { } try { if(!PasswordStore.getSharedInstance().changeStorePassword(password)) { - throw new Exception("Password change failed!"); + throw new Exception(bundle.getString("change_password_failed")); } } catch (Exception e1) { e1.printStackTrace(); - JOptionPane.showMessageDialog(this, "Error encountered during operation"); + JOptionPane.showMessageDialog(this, bundle.getString("error_operation")); } App.getGlobalSettings().setUsingMasterPassword(true); App.saveSettings(); - JOptionPane.showMessageDialog(this, "Your save passwords are protected by AES encryption"); + JOptionPane.showMessageDialog(this, bundle.getString("password_aes")); } else { try { PasswordStore.getSharedInstance().changeStorePassword(new char[0]); } catch (Exception e1) { e1.printStackTrace(); - JOptionPane.showMessageDialog(this, "Error encountered during operation"); + JOptionPane.showMessageDialog(this, bundle.getString("error_operation")); } App.getGlobalSettings().setUsingMasterPassword(false); App.saveSettings(); - JOptionPane.showMessageDialog(this, "Your save passwords are unprotected now"); + JOptionPane.showMessageDialog(this, bundle.getString("password_unprotected")); } }); @@ -830,7 +832,7 @@ private char[] promptPassword() { JPasswordField pass1 = new JPasswordField(30); JPasswordField pass2 = new JPasswordField(30); while (JOptionPane.showOptionDialog(this, - new Object[] { "New master password", pass1, "Re-enter master password", pass2 }, "Master password", + new Object[] { bundle.getString("new_master_password"), pass1, bundle.getString("reenter_master_password"), pass2 }, bundle.getString("master_password"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, null, null) == JOptionPane.OK_OPTION) { char[] password1 = pass1.getPassword(); char[] password2 = pass2.getPassword(); @@ -843,12 +845,12 @@ private char[] promptPassword() { for (int i = 0; i < password1.length; i++) { if (password1[i] != password2[i]) { passwordOK = false; - reason = "Passwords do not match"; + reason = bundle.getString("password_no_match"); break; } } } else { - reason = "Passwords do not match"; + reason = bundle.getString("password_no_match"); } if (!passwordOK) { @@ -857,8 +859,8 @@ private char[] promptPassword() { return password1; } - pass1.setText(new String("")); - pass2.setText(new String("")); + pass1.setText(""); + pass2.setText(""); } return null; diff --git a/muon-app/src/main/java/muon/app/ui/components/settings/SettingsPageName.java b/muon-app/src/main/java/muon/app/ui/components/settings/SettingsPageName.java index 650d0b7f..11a1ee68 100644 --- a/muon-app/src/main/java/muon/app/ui/components/settings/SettingsPageName.java +++ b/muon-app/src/main/java/muon/app/ui/components/settings/SettingsPageName.java @@ -1,12 +1,15 @@ package muon.app.ui.components.settings; +import java.util.ResourceBundle; + public enum SettingsPageName { + General("General", 0), Terminal("Terminal", 1), Editor("Editor", 2), Display("Display", 3), Security("Security", 4); public final String name; public final int index; - private SettingsPageName(String name, int index) { + SettingsPageName(String name, int index) { this.name = name; this.index = index; } diff --git a/muon-app/src/main/java/util/Language.java b/muon-app/src/main/java/util/Language.java new file mode 100644 index 00000000..95d01792 --- /dev/null +++ b/muon-app/src/main/java/util/Language.java @@ -0,0 +1,27 @@ +package util; + +public enum Language { + ENGLISH("en", "English"), + SPANISH("es","Español"), + PORTUGUESE("pt", "Portuguese"); + private final String full; + private final String langAbbr; + + Language(String langAbbr, String full) { + this.full = full; + this.langAbbr = langAbbr; + } + + public String getFull() { + return full; + } + + public String getLangAbbr() { + return langAbbr; + } + + @Override + public String toString() { + return full; + } +} diff --git a/pom.xml b/pom.xml index 8e985cfe..7976b017 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 muon muon - 0.0.1-SNAPSHOT + 1.2.0 pom muon-app