From b1571c0f5a978c5473d9288da3812f676befce6e Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Wed, 7 Jul 2010 16:56:45 +0800 Subject: [PATCH] Update to r505 Refactor the way connection notification works --- AndroidManifest.xml | 12 +- res/values-af/strings.xml | 461 +++++++++++++++++++ res/values-be/strings.xml | 461 +++++++++++++++++++ res/values-bg/strings.xml | 2 + res/values-ca/strings.xml | 2 + res/values-cs/strings.xml | 4 +- res/values-da/strings.xml | 4 +- res/values-de/strings.xml | 4 +- res/values-es/strings.xml | 6 +- res/values-eu/strings.xml | 2 + res/values-fi/strings.xml | 2 + res/values-fr/strings.xml | 4 +- res/values-gl/strings.xml | 2 + res/values-hu/strings.xml | 4 +- res/values-id/strings.xml | 2 + res/values-it/strings.xml | 4 +- res/values-ja/strings.xml | 2 + res/values-ko/strings.xml | 461 +++++++++++++++++++ res/values-lt/strings.xml | 2 + res/values-nb/strings.xml | 2 + res/values-nl/strings.xml | 12 +- res/values-oc/strings.xml | 461 +++++++++++++++++++ res/values-pl/strings.xml | 2 + res/values-pt-rBR/strings.xml | 28 +- res/values-pt/strings.xml | 2 + res/values-ru/strings.xml | 4 +- res/values-sk/strings.xml | 2 + res/values-sl/strings.xml | 461 +++++++++++++++++++ res/values-sv/strings.xml | 2 + res/values-tr/strings.xml | 2 + res/values-uk/strings.xml | 461 +++++++++++++++++++ res/values-vi/strings.xml | 2 + res/values-zh-rCN/strings.xml | 2 + res/values-zh-rTW/strings.xml | 154 +++---- res/values/arrays.xml | 2 + res/values/strings.xml | 2 + src/org/connectbot/ConsoleActivity.java | 367 ++++++++------- src/org/connectbot/GeneratePubkeyActivity.java | 2 +- src/org/connectbot/HostEditorActivity.java | 8 +- src/org/connectbot/HostListActivity.java | 6 +- src/org/connectbot/PortForwardListActivity.java | 14 +- src/org/connectbot/PubkeyListActivity.java | 8 +- src/org/connectbot/TerminalView.java | 27 +- src/org/connectbot/WizardActivity.java | 2 +- src/org/connectbot/service/BackupAgent.java | 73 +++ src/org/connectbot/service/BackupWrapper.java | 71 +++ src/org/connectbot/service/ConnectionNotifier.java | 17 +- .../connectbot/service/ConnectivityReceiver.java | 154 +++++++ src/org/connectbot/service/PromptHelper.java | 6 +- src/org/connectbot/service/TerminalBridge.java | 486 +++----------------- .../connectbot/service/TerminalKeyListener.java | 506 +++++++++++++++++++++ src/org/connectbot/service/TerminalManager.java | 268 ++++++++--- src/org/connectbot/transport/AbsTransport.java | 5 + src/org/connectbot/transport/Local.java | 8 + src/org/connectbot/transport/SSH.java | 16 +- src/org/connectbot/transport/Telnet.java | 8 + src/org/connectbot/util/HostDatabase.java | 4 +- src/org/connectbot/util/OnDbWrittenListener.java | 26 ++ src/org/connectbot/util/PreferenceConstants.java | 6 + src/org/connectbot/util/UberColorPickerDialog.java | 25 - 60 files changed, 4308 insertions(+), 847 deletions(-) create mode 100644 res/values-af/strings.xml create mode 100644 res/values-be/strings.xml create mode 100644 res/values-ko/strings.xml create mode 100644 res/values-oc/strings.xml create mode 100644 res/values-sl/strings.xml create mode 100644 res/values-uk/strings.xml create mode 100644 src/org/connectbot/service/BackupAgent.java create mode 100644 src/org/connectbot/service/BackupWrapper.java create mode 100644 src/org/connectbot/service/ConnectivityReceiver.java create mode 100644 src/org/connectbot/service/TerminalKeyListener.java create mode 100644 src/org/connectbot/util/OnDbWrittenListener.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 803e2a4..21139ff 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,13 +1,17 @@ + android:versionName="1.7.0-rc1" + android:versionCode="302" + android:installLocation="auto"> + android:description="@string/app_desc" + android:allowBackup="true" + android:backupAgent=".service.BackupAgent" + android:killAfterRestore="true"> @@ -50,7 +54,7 @@ - + diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml new file mode 100644 index 0000000..24b2556 --- /dev/null +++ b/res/values-af/strings.xml @@ -0,0 +1,461 @@ + + + + Simple, powerful, open-source SSH client. + + + Gashere + + Publieke Sleutels + + Poort aansturings + + Redigeer Gasheer + + Hulp + + Kleure + + Verbind + + Gather Entropy + + Voeg Gasheer by + Verwyder Gasheer + Voorkeure + + Please select a topic below for more information on a particular subject. + Aangaande ConnectBot + Sleutelbord + + Genereer + Voer in + Verwyder sleutel + + Versamel Ewekansigheid + Raak hierdie boks om ewekansigheid te versamel: %1$d%% voltooi + Om ewekansigheid te verseker gedurende die sleutel generering, beweeg u vinger ewekansig oor die boks hieronder. + Generating key pair... + Dupliseer privaat sleutel + Dupliseer publieke sleutel + + Tap "Menu" to create\nor import key pairs. + Onbekende formaat + Verander wagwoord + Kies van /sdcard + Problem parsing imported private key + Ontsluit sleutel + Bad password for key \'%1$s\'. Authentication failed. + Laai na geheue + Unload from memory + Load key on start + + Bevestig voor gebruik + + + Tap "Menu" to create\nport forwards. + Redigeer poort aansturing + Verwyder poort aanstuur + + Bynaam: + + My work key + + Oorsprong poort: + + Bestemming: + Ou wagwoord: + Wagwoord: + + (again) + + Tipe: + Nota: wagwoord kan leeg gelos word + + Bits: + + + Password for key \'%1$s\' + + + Allow remote host to\nuse key \'%1$s\'? + + + WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! + + IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\nSomeone could be eavesdropping on you right now (man-in-the-middle attack)!\nIt is also possible that the host key has just been changed. + + + Host has disconnected.\nClose session? + + Are you sure you want\nto continue connecting? + + + The authenticity of host \'%1$s\' can\'t be established. + + Host %1$s key fingerprint is %2$s + + Passwords do not match! + Wrong password! + Private key appears corrupt! + SD card is not inserted! + + + Add + + Change + + Generate Key + + Resize + + Connection Lost + + Copyright © 2007-2008 Kenny Root http://the-b.org/, Jeffrey Sharkey http://jsharkey.org/ + + + Terminal emulation + + + Emulation mode + + Terminal emulation mode to use for PTY connections + + + Scrollback size + + Size of scrollback buffer to keep in memory for each console + + + User interface + + + Rotation mode + + How to change rotation when keyboard popped in/out + + + Full screen + + Hide status bar while in console + + + Remember keys in memory + + Keep unlocked keys in memory until backend service is terminated + + + Update check + + Set the maximum frequency to check for ConnectBot updates + + + Persist connections + + Force connections to stay connected while in background + + + Directory shortcuts + + Select how to use Alt for \'/\' and Shift for Tab + + + Camera shortcut + + Select which shortcut to trigger when the camera button is pushed + + + Keep screen awake + + Prevent the screen from turning off when working in a console + + + Keep Wi-Fi active + + Prevent Wi-Fi from turning off when a session is active + + + Bumpy arrows + + Vibrate when sending arrow keys from trackball; useful for laggy connections + + + Terminal bell + + + Audible bell + + + Bell volume + + + Vibrate on bell + + + Background notifications + + Send notification when a terminal running in the background sounds a bell. + + + Use right-side keys + + Use left-side keys + + Disable + + + Do not use keys + + Use any unlocked key + + + Daily + + Weekly + + Never + + + Nickname + + + Color category + + + Font size (pt) + + + Use pubkey authentication + + + Use SSH auth agent + + + Post-login automation + + Commands to run on remote server once authenticated + + + Compression + + This may help with slower networks + + + Start shell session + + Disable this preference to only use port forwards + + + Stay connected + + Try to reconnect to host if disconnected + + + DEL Key + + The key code sent when DEL key is pressed + + + Encoding + + Character encoding for the host + + + Connection settings + + + Username + + + Host + + + Port + + + Never connected + + %1$s minutes ago + + %1$s hours ago + + %1$s days ago + + + Copied %1$d bytes to clipboard + + Touch and drag\nor use directional pad\nto select area to copy + + + Close + + Copy + + Paste + + Port Forwards + + Force Size + + URL Scan + + + Local + + Remote + + Dynamic (SOCKS) + + Create port forward + + Successfully created port forward + Problem creating port forward, maybe you\'re using ports under 1024 or port is already used? + + Add port forward + + + user@hostname + + + Use the format "%1$s" + + + username + + hostname + + port + + Manage Pubkeys + + Sort by color + + Sort by name + Settings + + Disconnect + Edit host + Edit port forwards + Delete host + + Use the quick-connect box\nbelow to connect to a host. + + + Default + Force landscape + Force portrait + + Automatic + + + Ctrl+A then Space + + Ctrl+A + + Esc + + Esc+A + + None + + + Backspace + + Delete + + Are you sure you want to delete \'%1$s\'? + Yes, delete + Cancel + + + Agree + + Next + + Back + + No hosts currently connected + + + Connecting to %1$s:%2$d via %3$s + + + Verified host \'%1$s\' key: %2$s + Host key verification failed. + + + Server-to-client algorithm: %1$s %2$s + + Client-to-server algorithm: %1$s %2$s + + Using algorithm: %1$s %2$s + + Trying to authenticate + + Attempting \'password\' authentication + Authentication method \'password\' failed + + Attempting \'publickey\' authentication with any in-memory public keys + Selected public key is invalid, try reselecting key in host editor + Attempting \'publickey\' authentication with a specific public key + Authentication method \'publickey\' with key \'%1$s\' failed + + Attempting \'keyboard-interactive\' authentication + Authentication method \'keyboard-interactive\' failed + + [Your host doesn\'t support \'password\' or \'keyboard-interactive\' authentication.] + + Session will not be started due to host preference. + Enable port forward: %1$s + + Failure! Local shell is unavailable on this phone. + + + %1$s wants your attention. + + + New version + + Yes, upgrade + + Not right now + + + No + + With confirmation + + Yes + + + It appears ConnectBot had a problem last time it ran. Submit error report to ConnectBot developers? + + + Reset + + + ConnectBot is running + + red + green + blue + gray + diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml new file mode 100644 index 0000000..e799704 --- /dev/null +++ b/res/values-be/strings.xml @@ -0,0 +1,461 @@ + + + + Simple, powerful, open-source SSH client. + + + Hosts + + Pubkeys + + Port forwards + + Edit Host + + Help + + Colors + + Connect + + Gather Entropy + + Add Host + Delete Host + Preferences + + Please select a topic below for more information on a particular subject. + About ConnectBot + Keyboard + + Generate + Import + Delete key + + Gathering Entropy + Touch this box to gather randomness: %1$d%% done + In order to assure randomness during the key generation, move your finger randomly over the box below. + Generating key pair... + Copy private key + Copy public key + + Tap "Menu" to create\nor import key pairs. + Unknown format + Change password + Pick from /sdcard + Problem parsing imported private key + Unlock key + Bad password for key \'%1$s\'. Authentication failed. + Load into memory + Unload from memory + Load key on start + + Confirm before use + + + Tap "Menu" to create\nport forwards. + Edit port forward + Delete port forward + + Nickname: + + My work key + + Source port: + + Destination: + Old password: + Password: + + (again) + + Type: + Note: password can be blank + + Bits: + + + Password for key \'%1$s\' + + + Allow remote host to\nuse key \'%1$s\'? + + + WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! + + IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\nSomeone could be eavesdropping on you right now (man-in-the-middle attack)!\nIt is also possible that the host key has just been changed. + + + Host has disconnected.\nClose session? + + Are you sure you want\nto continue connecting? + + + The authenticity of host \'%1$s\' can\'t be established. + + Host %1$s key fingerprint is %2$s + + Passwords do not match! + Wrong password! + Private key appears corrupt! + SD card is not inserted! + + + Add + + Change + + Generate Key + + Resize + + Connection Lost + + Copyright © 2007-2008 Kenny Root http://the-b.org/, Jeffrey Sharkey http://jsharkey.org/ + + + Terminal emulation + + + Emulation mode + + Terminal emulation mode to use for PTY connections + + + Scrollback size + + Size of scrollback buffer to keep in memory for each console + + + User interface + + + Rotation mode + + How to change rotation when keyboard popped in/out + + + Full screen + + Hide status bar while in console + + + Remember keys in memory + + Keep unlocked keys in memory until backend service is terminated + + + Update check + + Set the maximum frequency to check for ConnectBot updates + + + Persist connections + + Force connections to stay connected while in background + + + Directory shortcuts + + Select how to use Alt for \'/\' and Shift for Tab + + + Camera shortcut + + Select which shortcut to trigger when the camera button is pushed + + + Keep screen awake + + Prevent the screen from turning off when working in a console + + + Keep Wi-Fi active + + Prevent Wi-Fi from turning off when a session is active + + + Bumpy arrows + + Vibrate when sending arrow keys from trackball; useful for laggy connections + + + Terminal bell + + + Audible bell + + + Bell volume + + + Vibrate on bell + + + Background notifications + + Send notification when a terminal running in the background sounds a bell. + + + Use right-side keys + + Use left-side keys + + Disable + + + Do not use keys + + Use any unlocked key + + + Daily + + Weekly + + Never + + + Nickname + + + Color category + + + Font size (pt) + + + Use pubkey authentication + + + Use SSH auth agent + + + Post-login automation + + Commands to run on remote server once authenticated + + + Compression + + This may help with slower networks + + + Start shell session + + Disable this preference to only use port forwards + + + Stay connected + + Try to reconnect to host if disconnected + + + DEL Key + + The key code sent when DEL key is pressed + + + Encoding + + Character encoding for the host + + + Connection settings + + + Username + + + Host + + + Port + + + Never connected + + %1$s minutes ago + + %1$s hours ago + + %1$s days ago + + + Copied %1$d bytes to clipboard + + Touch and drag\nor use directional pad\nto select area to copy + + + Close + + Copy + + Paste + + Port Forwards + + Force Size + + URL Scan + + + Local + + Remote + + Dynamic (SOCKS) + + Create port forward + + Successfully created port forward + Problem creating port forward, maybe you\'re using ports under 1024 or port is already used? + + Add port forward + + + user@hostname + + + Use the format "%1$s" + + + username + + hostname + + port + + Manage Pubkeys + + Sort by color + + Sort by name + Settings + + Disconnect + Edit host + Edit port forwards + Delete host + + Use the quick-connect box\nbelow to connect to a host. + + + Default + Force landscape + Force portrait + + Automatic + + + Ctrl+A then Space + + Ctrl+A + + Esc + + Esc+A + + None + + + Backspace + + Delete + + Are you sure you want to delete \'%1$s\'? + Yes, delete + Cancel + + + Agree + + Next + + Back + + No hosts currently connected + + + Connecting to %1$s:%2$d via %3$s + + + Verified host \'%1$s\' key: %2$s + Host key verification failed. + + + Server-to-client algorithm: %1$s %2$s + + Client-to-server algorithm: %1$s %2$s + + Using algorithm: %1$s %2$s + + Trying to authenticate + + Attempting \'password\' authentication + Authentication method \'password\' failed + + Attempting \'publickey\' authentication with any in-memory public keys + Selected public key is invalid, try reselecting key in host editor + Attempting \'publickey\' authentication with a specific public key + Authentication method \'publickey\' with key \'%1$s\' failed + + Attempting \'keyboard-interactive\' authentication + Authentication method \'keyboard-interactive\' failed + + [Your host doesn\'t support \'password\' or \'keyboard-interactive\' authentication.] + + Session will not be started due to host preference. + Enable port forward: %1$s + + Failure! Local shell is unavailable on this phone. + + + %1$s wants your attention. + + + New version + + Yes, upgrade + + Not right now + + + No + + With confirmation + + Yes + + + It appears ConnectBot had a problem last time it ran. Submit error report to ConnectBot developers? + + + Reset + + + ConnectBot is running + + red + green + blue + gray + diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index df1e459..5ffb3c0 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A None diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 9790323..7fbd716 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A Res diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index f683b7a..982b589 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -35,7 +35,7 @@ Připojit - Gather Entropy + Získat entropii Přidat hostitele Smazat hostitele @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A Nic diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index f6c1eca..0ba418a 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A Ingen @@ -450,7 +452,7 @@ Nulstil - ConnectBot is running + ConnectBot kører rød grøn diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index afa4d95..9cccbfd 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -370,6 +370,8 @@ Strg+A Esc + + Esc+A Nichts @@ -450,7 +452,7 @@ Zurücksetzen - ConnectBot is running + ConnectBot läuft rot grün diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 2ccc5cd..ebff578 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -192,7 +192,7 @@ Prevenir que la red inálambrica se apague mientras haya una conexión activa - Bumpy arrows + Cursor con vibración Vibrar al recibir las teclas del cursor desde el trackball; útil para conexiones con retardos @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A Ninguno @@ -450,7 +452,7 @@ Restablecer - ConnectBot is running + ConnectBot está ejecutándose rojo verde diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 97d98fe..c902ed0 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A None diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index 139e97b..1682486 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A None diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index a8d7253..b992822 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Echap + + Esc+A aucun @@ -450,7 +452,7 @@ Réinitialiser - ConnectBot is running + ConnectBot est en cours rouge vert diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index afaffff..c87792f 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A None diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index a376106..792b10f 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A Semmit @@ -450,7 +452,7 @@ Visszaállít - ConnectBot is running + ConnectBot már fut piros zöld diff --git a/res/values-id/strings.xml b/res/values-id/strings.xml index 8d2d173..a7a0f2d 100644 --- a/res/values-id/strings.xml +++ b/res/values-id/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A Kosong diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 5b4405a..389f862 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -239,7 +239,7 @@ Categoria colore - Font size (pt) + Dimensione caratteri (pt) Usa autenticazione a chiave pubblica @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A Niente diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index cb26100..bc9aee6 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A なし diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml new file mode 100644 index 0000000..18d289e --- /dev/null +++ b/res/values-ko/strings.xml @@ -0,0 +1,461 @@ + + + + 간단하고, 강력한, 오픈소스 SSH 클라이언트. + + + 호스트 + + 공개키 + + 포트 포워딩 목록 + + 호스트 편집 + + 도움말 + + 색상 + + 접속 + + Gather Entropy + + Add Host + Delete Host + Preferences + + Please select a topic below for more information on a particular subject. + About ConnectBot + Keyboard + + Generate + Import + Delete key + + Gathering Entropy + Touch this box to gather randomness: %1$d%% done + In order to assure randomness during the key generation, move your finger randomly over the box below. + Generating key pair... + Copy private key + Copy public key + + Tap "Menu" to create\nor import key pairs. + Unknown format + Change password + Pick from /sdcard + Problem parsing imported private key + Unlock key + Bad password for key \'%1$s\'. Authentication failed. + Load into memory + Unload from memory + Load key on start + + Confirm before use + + + Tap "Menu" to create\nport forwards. + Edit port forward + Delete port forward + + Nickname: + + My work key + + Source port: + + Destination: + Old password: + Password: + + (again) + + Type: + Note: password can be blank + + Bits: + + + Password for key \'%1$s\' + + + Allow remote host to\nuse key \'%1$s\'? + + + WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! + + IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\nSomeone could be eavesdropping on you right now (man-in-the-middle attack)!\nIt is also possible that the host key has just been changed. + + + Host has disconnected.\nClose session? + + Are you sure you want\nto continue connecting? + + + The authenticity of host \'%1$s\' can\'t be established. + + Host %1$s key fingerprint is %2$s + + Passwords do not match! + Wrong password! + Private key appears corrupt! + SD card is not inserted! + + + Add + + Change + + Generate Key + + Resize + + Connection Lost + + Copyright © 2007-2008 Kenny Root http://the-b.org/, Jeffrey Sharkey http://jsharkey.org/ + + + Terminal emulation + + + Emulation mode + + Terminal emulation mode to use for PTY connections + + + Scrollback size + + Size of scrollback buffer to keep in memory for each console + + + User interface + + + Rotation mode + + How to change rotation when keyboard popped in/out + + + Full screen + + Hide status bar while in console + + + Remember keys in memory + + Keep unlocked keys in memory until backend service is terminated + + + Update check + + Set the maximum frequency to check for ConnectBot updates + + + Persist connections + + Force connections to stay connected while in background + + + Directory shortcuts + + Select how to use Alt for \'/\' and Shift for Tab + + + Camera shortcut + + Select which shortcut to trigger when the camera button is pushed + + + Keep screen awake + + Prevent the screen from turning off when working in a console + + + Keep Wi-Fi active + + Prevent Wi-Fi from turning off when a session is active + + + Bumpy arrows + + Vibrate when sending arrow keys from trackball; useful for laggy connections + + + Terminal bell + + + Audible bell + + + Bell volume + + + Vibrate on bell + + + Background notifications + + Send notification when a terminal running in the background sounds a bell. + + + Use right-side keys + + Use left-side keys + + Disable + + + Do not use keys + + Use any unlocked key + + + Daily + + Weekly + + Never + + + Nickname + + + Color category + + + Font size (pt) + + + Use pubkey authentication + + + Use SSH auth agent + + + Post-login automation + + Commands to run on remote server once authenticated + + + Compression + + This may help with slower networks + + + Start shell session + + Disable this preference to only use port forwards + + + Stay connected + + Try to reconnect to host if disconnected + + + DEL Key + + The key code sent when DEL key is pressed + + + Encoding + + Character encoding for the host + + + Connection settings + + + Username + + + Host + + + Port + + + Never connected + + %1$s minutes ago + + %1$s hours ago + + %1$s days ago + + + Copied %1$d bytes to clipboard + + Touch and drag\nor use directional pad\nto select area to copy + + + Close + + Copy + + Paste + + Port Forwards + + Force Size + + URL Scan + + + Local + + Remote + + Dynamic (SOCKS) + + Create port forward + + Successfully created port forward + Problem creating port forward, maybe you\'re using ports under 1024 or port is already used? + + Add port forward + + + user@hostname + + + Use the format "%1$s" + + + username + + hostname + + port + + Manage Pubkeys + + Sort by color + + Sort by name + Settings + + Disconnect + Edit host + Edit port forwards + Delete host + + Use the quick-connect box\nbelow to connect to a host. + + + Default + Force landscape + Force portrait + + Automatic + + + Ctrl+A then Space + + Ctrl+A + + Esc + + Esc+A + + None + + + Backspace + + Delete + + Are you sure you want to delete \'%1$s\'? + Yes, delete + Cancel + + + Agree + + Next + + Back + + No hosts currently connected + + + Connecting to %1$s:%2$d via %3$s + + + Verified host \'%1$s\' key: %2$s + Host key verification failed. + + + Server-to-client algorithm: %1$s %2$s + + Client-to-server algorithm: %1$s %2$s + + Using algorithm: %1$s %2$s + + Trying to authenticate + + Attempting \'password\' authentication + Authentication method \'password\' failed + + Attempting \'publickey\' authentication with any in-memory public keys + Selected public key is invalid, try reselecting key in host editor + Attempting \'publickey\' authentication with a specific public key + Authentication method \'publickey\' with key \'%1$s\' failed + + Attempting \'keyboard-interactive\' authentication + Authentication method \'keyboard-interactive\' failed + + [Your host doesn\'t support \'password\' or \'keyboard-interactive\' authentication.] + + Session will not be started due to host preference. + Enable port forward: %1$s + + Failure! Local shell is unavailable on this phone. + + + %1$s wants your attention. + + + New version + + Yes, upgrade + + Not right now + + + No + + With confirmation + + Yes + + + It appears ConnectBot had a problem last time it ran. Submit error report to ConnectBot developers? + + + Reset + + + ConnectBot is running + + red + green + blue + gray + diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index 43338b6..fe15cc0 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A None diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index ab62918..7815a10 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A Ingen diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index be5d760..cd882ac 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -167,9 +167,9 @@ Stel de maximale frequentie in om te controleren voor ConnectBot updates - Persist connections + Behoud verbindingen - Force connections to stay connected while in background + Forceer dat de verbindingen actief blijven op de achtergrond Folder snelkoppelingen @@ -239,7 +239,7 @@ Kleur catogorie - Font size (pt) + Lettergrootte Gebruik pubkey authenticatie @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A Geen @@ -447,10 +449,10 @@ Het lijkt erop dat ConnectBot een probleem had de laatste keer dat het gebruikt werd. Wilt u een foutenrapport naar de ConnectBot ontwikkelaars sturen? - Reset + Terug naar standaardinstellingen - ConnectBot is running + ConnectBot werkt (Connecties zijn actief) rood groen diff --git a/res/values-oc/strings.xml b/res/values-oc/strings.xml new file mode 100644 index 0000000..86fb29a --- /dev/null +++ b/res/values-oc/strings.xml @@ -0,0 +1,461 @@ + + + + Un client SSH simple, open-source e poderós. + + + Òstes + + Claus publicas + + Redireccions de pòrts + + Modificar lo servidor + + Ajuda + + Colors + + Connexion + + Generacion d\'aleatòri + + Apondre un servidor + Supprimir lo servidor + Preferéncias + + Seleccionatz un subjècte çaijós per mai d\'entresenhas. + A prepaus de ConnectBot + Clavièr + + Generar + Importar + Suprimir la clau + + Generacion d\'aleatòri + Tocatz aquesta bóstia per recuperar un nombre aleatòri : %1$d%% fach + In order to assure randomness during the key generation, move your finger randomly over the box below. + Generating key pair... + Copy private key + Copy public key + + Tap "Menu" to create\nor import key pairs. + Unknown format + Modificar lo senhal + Recuperar dempuèi /sdcard + Problem parsing imported private key + Unlock key + Bad password for key \'%1$s\'. Authentication failed. + Load into memory + Unload from memory + Load key on start + + Confirm before use + + + Tap "Menu" to create\nport forwards. + Edit port forward + Delete port forward + + Escais : + + My work key + + Source port: + + Destination: + Old password: + Senhal : + + (encara) + + Tipe : + Note: password can be blank + + Bits : + + + Password for key \'%1$s\' + + + Allow remote host to\nuse key \'%1$s\'? + + + WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! + + IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\nSomeone could be eavesdropping on you right now (man-in-the-middle attack)!\nIt is also possible that the host key has just been changed. + + + Host has disconnected.\nClose session? + + Are you sure you want\nto continue connecting? + + + The authenticity of host \'%1$s\' can\'t be established. + + Host %1$s key fingerprint is %2$s + + Passwords do not match! + Wrong password! + Private key appears corrupt! + SD card is not inserted! + + + Add + + Change + + Generate Key + + Resize + + Connection Lost + + Copyright © 2007-2008 Kenny Root http://the-b.org/, Jeffrey Sharkey http://jsharkey.org/ + + + Terminal emulation + + + Emulation mode + + Terminal emulation mode to use for PTY connections + + + Scrollback size + + Size of scrollback buffer to keep in memory for each console + + + User interface + + + Rotation mode + + How to change rotation when keyboard popped in/out + + + Full screen + + Hide status bar while in console + + + Remember keys in memory + + Keep unlocked keys in memory until backend service is terminated + + + Update check + + Set the maximum frequency to check for ConnectBot updates + + + Persist connections + + Force connections to stay connected while in background + + + Directory shortcuts + + Select how to use Alt for \'/\' and Shift for Tab + + + Camera shortcut + + Select which shortcut to trigger when the camera button is pushed + + + Keep screen awake + + Prevent the screen from turning off when working in a console + + + Keep Wi-Fi active + + Prevent Wi-Fi from turning off when a session is active + + + Bumpy arrows + + Vibrate when sending arrow keys from trackball; useful for laggy connections + + + Terminal bell + + + Audible bell + + + Bell volume + + + Vibrate on bell + + + Background notifications + + Send notification when a terminal running in the background sounds a bell. + + + Use right-side keys + + Use left-side keys + + Disable + + + Do not use keys + + Use any unlocked key + + + Daily + + Weekly + + Never + + + Nickname + + + Color category + + + Font size (pt) + + + Use pubkey authentication + + + Use SSH auth agent + + + Post-login automation + + Commands to run on remote server once authenticated + + + Compression + + This may help with slower networks + + + Start shell session + + Disable this preference to only use port forwards + + + Stay connected + + Try to reconnect to host if disconnected + + + DEL Key + + The key code sent when DEL key is pressed + + + Encoding + + Character encoding for the host + + + Connection settings + + + Username + + + Host + + + Port + + + Never connected + + %1$s minutes ago + + %1$s hours ago + + %1$s days ago + + + Copied %1$d bytes to clipboard + + Touch and drag\nor use directional pad\nto select area to copy + + + Close + + Copy + + Paste + + Port Forwards + + Force Size + + URL Scan + + + Local + + Remote + + Dynamic (SOCKS) + + Create port forward + + Successfully created port forward + Problem creating port forward, maybe you\'re using ports under 1024 or port is already used? + + Add port forward + + + user@hostname + + + Use the format "%1$s" + + + username + + hostname + + port + + Manage Pubkeys + + Sort by color + + Sort by name + Settings + + Disconnect + Edit host + Edit port forwards + Delete host + + Use the quick-connect box\nbelow to connect to a host. + + + Default + Force landscape + Force portrait + + Automatic + + + Ctrl+A then Space + + Ctrl+A + + Esc + + Esc+A + + None + + + Backspace + + Delete + + Are you sure you want to delete \'%1$s\'? + Yes, delete + Cancel + + + Agree + + Next + + Back + + No hosts currently connected + + + Connecting to %1$s:%2$d via %3$s + + + Verified host \'%1$s\' key: %2$s + Host key verification failed. + + + Server-to-client algorithm: %1$s %2$s + + Client-to-server algorithm: %1$s %2$s + + Using algorithm: %1$s %2$s + + Trying to authenticate + + Attempting \'password\' authentication + Authentication method \'password\' failed + + Attempting \'publickey\' authentication with any in-memory public keys + Selected public key is invalid, try reselecting key in host editor + Attempting \'publickey\' authentication with a specific public key + Authentication method \'publickey\' with key \'%1$s\' failed + + Attempting \'keyboard-interactive\' authentication + Authentication method \'keyboard-interactive\' failed + + [Your host doesn\'t support \'password\' or \'keyboard-interactive\' authentication.] + + Session will not be started due to host preference. + Enable port forward: %1$s + + Failure! Local shell is unavailable on this phone. + + + %1$s wants your attention. + + + New version + + Yes, upgrade + + Not right now + + + No + + With confirmation + + Yes + + + It appears ConnectBot had a problem last time it ran. Submit error report to ConnectBot developers? + + + Reset + + + ConnectBot is running + + red + green + blue + gray + diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 22ef630..cff46f7 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A Żaden diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index c709087..7a520a5 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -131,12 +131,12 @@ Copyright © 2007-2008 Kenny Root http://the-b.org/, Jeffrey Sharkey http://jsharkey.org/ - Terminal emulation + Emulação de Terminal - Emulation mode + Modo De Emulação - Terminal emulation mode to use for PTY connections + Modo de emulação de terminal para usar em conexões PTY Scrollback size @@ -144,50 +144,50 @@ Size of scrollback buffer to keep in memory for each console - User interface + Interface do usuário - Rotation mode + Modo de Rotação How to change rotation when keyboard popped in/out - Full screen + Tela cheia Hide status bar while in console - Remember keys in memory + Lembrar as chaves na memória Keep unlocked keys in memory until backend service is terminated - Update check + Verificar Atualização Set the maximum frequency to check for ConnectBot updates Persist connections - Force connections to stay connected while in background + Força as conexões para ficarem conectadas enquanto estão em segundo plano - Directory shortcuts + Atalhos dos Diretórios Select how to use Alt for \'/\' and Shift for Tab - Camera shortcut + Atalho para Câmera Select which shortcut to trigger when the camera button is pushed - Keep screen awake + Manter a tela ativa Prevent the screen from turning off when working in a console - Keep Wi-Fi active + Manter WI-FI ativo Prevent Wi-Fi from turning off when a session is active @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A None diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index b1975d8..8279e3d 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A None diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index f1f94cd..0ead3b6 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A Нет @@ -450,7 +452,7 @@ Сбросить - ConnectBot is running + ConnectBot запущен красный зелёный diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 708b291..0fe9282 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A Žiadny diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml new file mode 100644 index 0000000..7b75dce --- /dev/null +++ b/res/values-sl/strings.xml @@ -0,0 +1,461 @@ + + + + Enostaven, močan, odprtokodni SSH odjemalec + + + Gostitelji + + Pubkeys + + Port forwards + + Uredi gostitelja + + Pomoč + + Barve + + Poveži + + Gather Entropy + + Dodaj gostitelja + Odstrani gostitelja + Možnosti + + Please select a topic below for more information on a particular subject. + Vizitka + Tipkovnica + + Generate + Uvozi javni ključ + Zbriši ključ + + Pridobivanje entropije + Touch this box to gather randomness: %1$d%% done + In order to assure randomness during the key generation, move your finger randomly over the box below. + Generating key pair... + Copy private key + Copy public key + + Tap "Menu" to create\nor import key pairs. + Unknown format + Change password + Pick from /sdcard + Problem parsing imported private key + Unlock key + Bad password for key \'%1$s\'. Authentication failed. + Load into memory + Unload from memory + Load key on start + + Confirm before use + + + Tap "Menu" to create\nport forwards. + Edit port forward + Delete port forward + + Nickname: + + My work key + + Source port: + + Destination: + Old password: + Password: + + (again) + + Type: + Note: password can be blank + + Bits: + + + Password for key \'%1$s\' + + + Allow remote host to\nuse key \'%1$s\'? + + + WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! + + IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\nSomeone could be eavesdropping on you right now (man-in-the-middle attack)!\nIt is also possible that the host key has just been changed. + + + Host has disconnected.\nClose session? + + Are you sure you want\nto continue connecting? + + + The authenticity of host \'%1$s\' can\'t be established. + + Host %1$s key fingerprint is %2$s + + Passwords do not match! + Wrong password! + Private key appears corrupt! + SD card is not inserted! + + + Add + + Change + + Generate Key + + Resize + + Connection Lost + + Copyright © 2007-2008 Kenny Root http://the-b.org/, Jeffrey Sharkey http://jsharkey.org/ + + + Terminal emulation + + + Emulation mode + + Terminal emulation mode to use for PTY connections + + + Scrollback size + + Size of scrollback buffer to keep in memory for each console + + + User interface + + + Rotation mode + + How to change rotation when keyboard popped in/out + + + Full screen + + Hide status bar while in console + + + Remember keys in memory + + Keep unlocked keys in memory until backend service is terminated + + + Update check + + Set the maximum frequency to check for ConnectBot updates + + + Persist connections + + Force connections to stay connected while in background + + + Directory shortcuts + + Select how to use Alt for \'/\' and Shift for Tab + + + Camera shortcut + + Select which shortcut to trigger when the camera button is pushed + + + Keep screen awake + + Prevent the screen from turning off when working in a console + + + Keep Wi-Fi active + + Prevent Wi-Fi from turning off when a session is active + + + Bumpy arrows + + Vibrate when sending arrow keys from trackball; useful for laggy connections + + + Terminal bell + + + Audible bell + + + Bell volume + + + Vibrate on bell + + + Background notifications + + Send notification when a terminal running in the background sounds a bell. + + + Use right-side keys + + Use left-side keys + + Disable + + + Do not use keys + + Use any unlocked key + + + Daily + + Weekly + + Never + + + Nickname + + + Color category + + + Font size (pt) + + + Use pubkey authentication + + + Use SSH auth agent + + + Post-login automation + + Commands to run on remote server once authenticated + + + Compression + + This may help with slower networks + + + Start shell session + + Disable this preference to only use port forwards + + + Stay connected + + Try to reconnect to host if disconnected + + + DEL Key + + The key code sent when DEL key is pressed + + + Encoding + + Character encoding for the host + + + Connection settings + + + Username + + + Host + + + Port + + + Never connected + + %1$s minutes ago + + %1$s hours ago + + %1$s days ago + + + Copied %1$d bytes to clipboard + + Touch and drag\nor use directional pad\nto select area to copy + + + Close + + Copy + + Paste + + Port Forwards + + Force Size + + URL Scan + + + Local + + Remote + + Dynamic (SOCKS) + + Create port forward + + Successfully created port forward + Problem creating port forward, maybe you\'re using ports under 1024 or port is already used? + + Add port forward + + + user@hostname + + + Use the format "%1$s" + + + username + + hostname + + port + + Manage Pubkeys + + Sort by color + + Sort by name + Settings + + Disconnect + Edit host + Edit port forwards + Delete host + + Use the quick-connect box\nbelow to connect to a host. + + + Default + Force landscape + Force portrait + + Automatic + + + Ctrl+A then Space + + Ctrl+A + + Esc + + Esc+A + + None + + + Backspace + + Delete + + Are you sure you want to delete \'%1$s\'? + Yes, delete + Cancel + + + Agree + + Next + + Back + + No hosts currently connected + + + Connecting to %1$s:%2$d via %3$s + + + Verified host \'%1$s\' key: %2$s + Host key verification failed. + + + Server-to-client algorithm: %1$s %2$s + + Client-to-server algorithm: %1$s %2$s + + Using algorithm: %1$s %2$s + + Trying to authenticate + + Attempting \'password\' authentication + Authentication method \'password\' failed + + Attempting \'publickey\' authentication with any in-memory public keys + Selected public key is invalid, try reselecting key in host editor + Attempting \'publickey\' authentication with a specific public key + Authentication method \'publickey\' with key \'%1$s\' failed + + Attempting \'keyboard-interactive\' authentication + Authentication method \'keyboard-interactive\' failed + + [Your host doesn\'t support \'password\' or \'keyboard-interactive\' authentication.] + + Session will not be started due to host preference. + Enable port forward: %1$s + + Failure! Local shell is unavailable on this phone. + + + %1$s wants your attention. + + + New version + + Yes, upgrade + + Not right now + + + No + + With confirmation + + Yes + + + It appears ConnectBot had a problem last time it ran. Submit error report to ConnectBot developers? + + + Reset + + + ConnectBot is running + + red + green + blue + gray + diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index caf4b8c..47152cc 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A Ingen diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index e5cc4e5..e11ad7f 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A None diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml new file mode 100644 index 0000000..a5ba3ab --- /dev/null +++ b/res/values-uk/strings.xml @@ -0,0 +1,461 @@ + + + + Простий та потужний SSH клієнт з відкритим кодом + + + Вузли + + Відкриті ключі + + Переадресація портів + + Змінити вузол + + Допомога + + Кольори + + Підключитись + + Gather Entropy + + Додати вузол + Вилучити вузол + Налаштування + + Для додаткової інформації виберіть топік + Про ConnectBot + Клавіатура + + Генерувати + Імпортувати + Вилучити ключ + + Gathering Entropy + Touch this box to gather randomness: %1$d%% done + In order to assure randomness during the key generation, move your finger randomly over the box below. + Generating key pair... + Copy private key + Copy public key + + Tap "Menu" to create\nor import key pairs. + Unknown format + Змінити пароль + Завантажити з SD карти + Problem parsing imported private key + Розблокувати ключ + Bad password for key \'%1$s\'. Authentication failed. + Load into memory + Unload from memory + Load key on start + + Confirm before use + + + Tap "Menu" to create\nport forwards. + Edit port forward + Delete port forward + + Nickname: + + My work key + + Source port: + + Destination: + Old password: + Password: + + (again) + + Type: + Note: password can be blank + + Bits: + + + Password for key \'%1$s\' + + + Allow remote host to\nuse key \'%1$s\'? + + + WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! + + IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\nSomeone could be eavesdropping on you right now (man-in-the-middle attack)!\nIt is also possible that the host key has just been changed. + + + Host has disconnected.\nClose session? + + Are you sure you want\nto continue connecting? + + + The authenticity of host \'%1$s\' can\'t be established. + + Host %1$s key fingerprint is %2$s + + Passwords do not match! + Wrong password! + Private key appears corrupt! + SD card is not inserted! + + + Add + + Change + + Generate Key + + Resize + + Connection Lost + + Copyright © 2007-2008 Kenny Root http://the-b.org/, Jeffrey Sharkey http://jsharkey.org/ + + + Terminal emulation + + + Emulation mode + + Terminal emulation mode to use for PTY connections + + + Scrollback size + + Size of scrollback buffer to keep in memory for each console + + + User interface + + + Rotation mode + + How to change rotation when keyboard popped in/out + + + Full screen + + Hide status bar while in console + + + Remember keys in memory + + Keep unlocked keys in memory until backend service is terminated + + + Update check + + Set the maximum frequency to check for ConnectBot updates + + + Persist connections + + Force connections to stay connected while in background + + + Directory shortcuts + + Select how to use Alt for \'/\' and Shift for Tab + + + Camera shortcut + + Select which shortcut to trigger when the camera button is pushed + + + Keep screen awake + + Prevent the screen from turning off when working in a console + + + Keep Wi-Fi active + + Prevent Wi-Fi from turning off when a session is active + + + Bumpy arrows + + Vibrate when sending arrow keys from trackball; useful for laggy connections + + + Terminal bell + + + Audible bell + + + Bell volume + + + Vibrate on bell + + + Background notifications + + Send notification when a terminal running in the background sounds a bell. + + + Use right-side keys + + Use left-side keys + + Disable + + + Do not use keys + + Use any unlocked key + + + Daily + + Weekly + + Never + + + Nickname + + + Color category + + + Font size (pt) + + + Use pubkey authentication + + + Use SSH auth agent + + + Post-login automation + + Commands to run on remote server once authenticated + + + Compression + + This may help with slower networks + + + Start shell session + + Disable this preference to only use port forwards + + + Stay connected + + Try to reconnect to host if disconnected + + + DEL Key + + The key code sent when DEL key is pressed + + + Encoding + + Character encoding for the host + + + Connection settings + + + Username + + + Host + + + Port + + + Never connected + + %1$s minutes ago + + %1$s hours ago + + %1$s days ago + + + Copied %1$d bytes to clipboard + + Touch and drag\nor use directional pad\nto select area to copy + + + Close + + Copy + + Paste + + Port Forwards + + Force Size + + URL Scan + + + Local + + Remote + + Dynamic (SOCKS) + + Create port forward + + Successfully created port forward + Problem creating port forward, maybe you\'re using ports under 1024 or port is already used? + + Add port forward + + + user@hostname + + + Use the format "%1$s" + + + username + + hostname + + port + + Manage Pubkeys + + Sort by color + + Sort by name + Settings + + Disconnect + Edit host + Edit port forwards + Delete host + + Use the quick-connect box\nbelow to connect to a host. + + + Default + Force landscape + Force portrait + + Automatic + + + Ctrl+A then Space + + Ctrl+A + + Esc + + Esc+A + + None + + + Backspace + + Delete + + Are you sure you want to delete \'%1$s\'? + Yes, delete + Cancel + + + Agree + + Next + + Back + + No hosts currently connected + + + Connecting to %1$s:%2$d via %3$s + + + Verified host \'%1$s\' key: %2$s + Host key verification failed. + + + Server-to-client algorithm: %1$s %2$s + + Client-to-server algorithm: %1$s %2$s + + Using algorithm: %1$s %2$s + + Trying to authenticate + + Attempting \'password\' authentication + Authentication method \'password\' failed + + Attempting \'publickey\' authentication with any in-memory public keys + Selected public key is invalid, try reselecting key in host editor + Attempting \'publickey\' authentication with a specific public key + Authentication method \'publickey\' with key \'%1$s\' failed + + Attempting \'keyboard-interactive\' authentication + Authentication method \'keyboard-interactive\' failed + + [Your host doesn\'t support \'password\' or \'keyboard-interactive\' authentication.] + + Session will not be started due to host preference. + Enable port forward: %1$s + + Failure! Local shell is unavailable on this phone. + + + %1$s wants your attention. + + + New version + + Yes, upgrade + + Not right now + + + No + + With confirmation + + Yes + + + It appears ConnectBot had a problem last time it ran. Submit error report to ConnectBot developers? + + + Reset + + + ConnectBot is running + + red + green + blue + gray + diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 8254294..8ed8b84 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A None diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index d31f426..f99c47d 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -370,6 +370,8 @@ Ctrl+A Esc + + Esc+A 无 diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index f6ecff1..083b85a 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -255,86 +255,86 @@ 壓縮 - This may help with slower networks + 此選項對低速網絡會有幫助 - Start shell session + 開始Shell會話 - Disable this preference to only use port forwards + 僅僅對端口轉發禁用偏好設置 - Stay connected + 保持連接 - Try to reconnect to host if disconnected + 斷線後自動重新連接到主機 - DEL Key + DEL鍵 - The key code sent when DEL key is pressed + 當DEL按下時觸發的按鍵 - Encoding + 編碼 - Character encoding for the host + 主機的字符編碼 - Connection settings + 連接設置 - 使用者名稱 + 用戶名 - Host + 主機 端口 - Never connected + 從未連接 - %1$s分鐘前 + 已連接 %1$s 分鐘 - %1$s小時以前 + 已連接 %1$s 小時 - %1$s天前 + 已連接 %1$s 天 - %1$d字節複製到剪貼簿 + 復制 %1$d 字節到剪貼板 - Touch and drag\nor use directional pad\nto select area to copy + 滑動手指\n或使用軌跡球\n選擇要復制的區域 - Close + 關閉 - Copy + 復制 - Paste + 粘貼 - Port Forwards + 端口轉發 - Force Size + 字體大小 - URL Scan + URL 地址掃描 - Local + 本地 - Remote + 遠端 - Dynamic (SOCKS) + 動態套接字(SOCKS) - Create port forward + 創建端口轉發 - Successfully created port forward + 成功創建端口轉發 Problem creating port forward, maybe you\'re using ports under 1024 or port is already used? - Add port forward + 添加端口轉發 用戶名@主機名 - Use the format "%1$s" + 使用"%1$s"格式 用戶名 @@ -343,76 +343,78 @@ 端口 - Manage Pubkeys + 管理公鑰 - Sort by color + 使用顏色排序 - Sort by name - Settings + 按名字排序 + 設置 - 斷線 - Edit host - Edit port forwards + 斷開連接 + 編輯主機 + 編輯端口轉發 刪除主機 - Use the quick-connect box\nbelow to connect to a host. + 使用下面的快速連接框連接主機 - Default - Force landscape - Force portrait + 默認 + 強制橫屏顯示 + 強制竪屏顯示 - Automatic + 自動 - Ctrl+A then Space + Ctrl+A 然後 Space Ctrl+A Esc + + Esc+A - None + 無 Backspace - Delete + 刪除 - 您是否確實要刪除「%1$s」? - 是的,刪除 - Cancel + Are you sure you want to delete \'%1$s\'? + 是,刪除 + 取消 - Agree + 同意 - Next + 下一頁 - Back + 返回 - No hosts currently connected + 當前沒有已連接主機 - Connecting to %1$s:%2$d via %3$s + 連接到 %1$s:%2$d,通過 %3$s Verified host \'%1$s\' key: %2$s - Host key verification failed. + 主機驗證失敗 - Server-to-client algorithm: %1$s %2$s + 服務器到客戶端算法:%1$s %2$s - Client-to-server algorithm: %1$s %2$s + 客戶端到服務器算法:%1$s %2$s - Using algorithm: %1$s %2$s + 使用算法:%1$s %2$s - Trying to authenticate + 嘗試驗證 Attempting \'password\' authentication Authentication method \'password\' failed Attempting \'publickey\' authentication with any in-memory public keys - Selected public key is invalid, try reselecting key in host editor + 所選擇的公鑰無法使用,請在主機編輯中嘗試重新選擇 Attempting \'publickey\' authentication with a specific public key Authentication method \'publickey\' with key \'%1$s\' failed @@ -421,39 +423,39 @@ [Your host doesn\'t support \'password\' or \'keyboard-interactive\' authentication.] - Session will not be started due to host preference. - Enable port forward: %1$s + 因為主機的相關設置,不會啓動會話。 + 啓用端口轉發:%1$s - Failure! Local shell is unavailable on this phone. + 失敗! 本地Shell在該手機上不可用 - %1$s希望你注意 + %1$s 需要你的註意 - New version + 新版本 - Yes, upgrade + 是,昇級 - Not right now + 暫時不 - No + 不 - With confirmation + 已確認過 - Yes + 是 - It appears ConnectBot had a problem last time it ran. Submit error report to ConnectBot developers? + 似乎ConnectBot在最後運行時出現異常. 請回報給ConnectBot開發者 - Reset + 重設 ConnectBot is running - 紅色 - 綠色 - 藍色 - 灰色 + 紅 + 綠 + 藍 + 灰 diff --git a/res/values/arrays.xml b/res/values/arrays.xml index 91eb8c5..cae8121 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -46,6 +46,7 @@ @string/list_camera_ctrlaspace @string/list_camera_ctrla @string/list_camera_esc + @string/list_camera_esc_a @string/list_camera_none @@ -53,6 +54,7 @@ Ctrl+A then Space Ctrl+A Esc + Esc+A None diff --git a/res/values/strings.xml b/res/values/strings.xml index 0f09a42..b649c0e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -371,6 +371,8 @@ Ctrl+A Esc + + Esc+A None diff --git a/src/org/connectbot/ConsoleActivity.java b/src/org/connectbot/ConsoleActivity.java index 76a1d2e..0240131 100644 --- a/src/org/connectbot/ConsoleActivity.java +++ b/src/org/connectbot/ConsoleActivity.java @@ -20,8 +20,6 @@ package org.connectbot; import java.lang.ref.WeakReference; import java.util.List; -import org.connectbot.bean.HostBean; -import org.connectbot.bean.PortForwardBean; import org.connectbot.bean.SelectionArea; import org.connectbot.service.PromptHelper; import org.connectbot.service.TerminalBridge; @@ -90,6 +88,10 @@ public class ConsoleActivity extends Activity { private static final float MAX_CLICK_DISTANCE = 25f; private static final int KEYBOARD_DISPLAY_TIME = 1250; + // Direction to shift the ViewFlipper + private static final int SHIFT_LEFT = 0; + private static final int SHIFT_RIGHT = 1; + protected ViewFlipper flip = null; protected TerminalManager bound = null; protected LayoutInflater inflater = null; @@ -141,27 +143,17 @@ public class ConsoleActivity extends Activity { // clear out any existing bridges and record requested index flip.removeAllViews(); - String requestedNickname = (requested != null) ? requested.getFragment() : null; - int requestedIndex = 0; - // first check if we need to create a new session for requested - boolean found = false; - for (TerminalBridge bridge : bound.bridges) { - String nick = bridge.host.getNickname(); - if (nick == null) - continue; + final String requestedNickname = (requested != null) ? requested.getFragment() : null; + int requestedIndex = 0; - if (nick.equals(requestedNickname)) { - found = true; - break; - } - } + TerminalBridge requestedBridge = bound.getConnectedBridge(requestedNickname); // If we didn't find the requested connection, try opening it - if (!found) { + if (requestedNickname != null && requestedBridge == null) { try { Log.d(TAG, String.format("We couldnt find an existing bridge with URI=%s (nickname=%s), so creating one now", requested.toString(), requestedNickname)); - bound.openConnection(requested); + requestedBridge = bound.openConnection(requested); } catch(Exception e) { Log.e(TAG, "Problem while trying to create new requested bridge from URI", e); } @@ -170,46 +162,22 @@ public class ConsoleActivity extends Activity { // create views for all bridges on this service for (TerminalBridge bridge : bound.bridges) { - // let them know about our prompt handler services - bridge.promptHelper.setHandler(promptHandler); - bridge.refreshKeymode(); - - // inflate each terminal view - RelativeLayout view = (RelativeLayout)inflater.inflate(R.layout.item_terminal, flip, false); - - // set the terminal overlay text - TextView overlay = (TextView)view.findViewById(R.id.terminal_overlay); - overlay.setText(bridge.host.getNickname()); - - // and add our terminal view control, using index to place behind overlay - TerminalView terminal = new TerminalView(ConsoleActivity.this, bridge); - terminal.setId(R.id.console_flip); - view.addView(terminal, 0); - - // finally attach to the flipper - flip.addView(view); + final int currentIndex = addNewTerminalView(bridge); // check to see if this bridge was requested - if (bridge.host.getNickname().equals(requestedNickname)) - requestedIndex = flip.getChildCount() - 1; + if (bridge == requestedBridge) + requestedIndex = currentIndex; } - try { - // show the requested bridge if found, also fade out overlay - flip.setDisplayedChild(requestedIndex); - flip.getCurrentView().findViewById(R.id.terminal_overlay).startAnimation(fade_out_delayed); - } catch (NullPointerException npe) { - Log.d(TAG, "View went away when we were about to display it", npe); - } - - updatePromptVisible(); - updateEmptyVisible(); + setDisplayedTerminal(requestedIndex); } public void onServiceDisconnected(ComponentName className) { // tell each bridge to forget about our prompt handler - for(TerminalBridge bridge : bound.bridges) - bridge.promptHelper.setHandler(null); + synchronized (bound.bridges) { + for(TerminalBridge bridge : bound.bridges) + bridge.promptHelper.setHandler(null); + } flip.removeAllViews(); updateEmptyVisible(); @@ -242,57 +210,33 @@ public class ConsoleActivity extends Activity { /** * @param bridge */ - private void closeBridge(TerminalBridge bridge) { - for(int i = 0; i < flip.getChildCount(); i++) { - View child = flip.getChildAt(i).findViewById(R.id.console_flip); + private void closeBridge(final TerminalBridge bridge) { + synchronized (flip) { + final int flipIndex = getFlipIndex(bridge); - if (!(child instanceof TerminalView)) continue; - - TerminalView terminal = (TerminalView) child; - - if (terminal.bridge.equals(bridge)) { - // we've found the terminal to remove - // shift something into its place if currently visible - if(flip.getDisplayedChild() == i) - shiftLeft(); - flip.removeViewAt(i); + if (flipIndex >= 0) { + if (flip.getDisplayedChild() == flipIndex) { + shiftCurrentTerminal(SHIFT_LEFT); + } + flip.removeViewAt(flipIndex); /* TODO Remove this workaround when ViewFlipper is fixed to listen * to view removals. Android Issue 1784 */ final int numChildren = flip.getChildCount(); if (flip.getDisplayedChild() >= numChildren && - numChildren > 0) + numChildren > 0) { flip.setDisplayedChild(numChildren - 1); + } updateEmptyVisible(); - break; } - } - - // If we just closed the last bridge, go back to the previous activity. - if (flip.getChildCount() == 0) { - finish(); - } - } - - // TODO review use (apparently unused) - protected void createPortForward(TerminalView target, String nickname, String type, String source, String dest) { - String summary = getString(R.string.portforward_problem); - try { - long hostId = target.bridge.host.getId(); - - PortForwardBean pfb = new PortForwardBean(hostId, nickname, type, source, dest); - target.bridge.addPortForward(pfb); - if (target.bridge.enablePortForward(pfb)) { - summary = getString(R.string.portforward_done); + // If we just closed the last bridge, go back to the previous activity. + if (flip.getChildCount() == 0) { + finish(); } - } catch(Exception e) { - Log.e(TAG, "Problem trying to create portForward", e); } - - Toast.makeText(ConsoleActivity.this, summary, Toast.LENGTH_LONG).show(); } protected View findCurrentView(int id) { @@ -301,13 +245,6 @@ public class ConsoleActivity extends Activity { return view.findViewById(id); } - // TODO review use (apparently unused) - protected HostBean getCurrentHost() { - View view = findCurrentView(R.id.console_flip); - if(!(view instanceof TerminalView)) return null; - return ((TerminalView)view).bridge.host; - } - protected PromptHelper getCurrentPromptHelper() { View view = findCurrentView(R.id.console_flip); if(!(view instanceof TerminalView)) return null; @@ -345,7 +282,7 @@ public class ConsoleActivity extends Activity { // handle requested console from incoming intent requested = getIntent().getData(); - inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); + inflater = LayoutInflater.from(this); flip = (ViewFlipper)findViewById(R.id.console_flip); empty = (TextView)findViewById(android.R.id.empty); @@ -429,20 +366,20 @@ public class ConsoleActivity extends Activity { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - float distx = e2.getRawX() - e1.getRawX(); - float disty = e2.getRawY() - e1.getRawY(); - int goalwidth = flip.getWidth() / 2; + final float distx = e2.getRawX() - e1.getRawX(); + final float disty = e2.getRawY() - e1.getRawY(); + final int goalwidth = flip.getWidth() / 2; // need to slide across half of display to trigger console change // make sure user kept a steady hand horizontally - if(Math.abs(disty) < 100) { - if(distx > goalwidth) { - shiftRight(); + if (Math.abs(disty) < (flip.getHeight() / 4)) { + if (distx > goalwidth) { + shiftCurrentTerminal(SHIFT_RIGHT); return true; } - if(distx < -goalwidth) { - shiftLeft(); + if (distx < -goalwidth) { + shiftCurrentTerminal(SHIFT_LEFT); return true; } @@ -463,12 +400,12 @@ public class ConsoleActivity extends Activity { return false; // if releasing then reset total scroll - if(e2.getAction() == MotionEvent.ACTION_UP) { + if (e2.getAction() == MotionEvent.ACTION_UP) { totalY = 0; } // activate consider if within x tolerance - if(Math.abs(e1.getX() - e2.getX()) < ViewConfiguration.getTouchSlop() * 4) { + if (Math.abs(e1.getX() - e2.getX()) < ViewConfiguration.getTouchSlop() * 4) { View flip = findCurrentView(R.id.console_flip); if(flip == null) return false; @@ -477,11 +414,11 @@ public class ConsoleActivity extends Activity { // estimate how many rows we have scrolled through // accumulate distance that doesn't trigger immediate scroll totalY += distanceY; - int moved = (int)(totalY / terminal.bridge.charHeight); + final int moved = (int)(totalY / terminal.bridge.charHeight); // consume as scrollback only if towards right half of screen - if (e2.getX() > flip.getWidth() / 2.0) { - if(moved != 0) { + if (e2.getX() > flip.getWidth() / 2) { + if (moved != 0) { int base = terminal.bridge.buffer.getWindowBase(); terminal.bridge.buffer.setWindowBase(base + moved); totalY = 0; @@ -489,12 +426,12 @@ public class ConsoleActivity extends Activity { } } else { // otherwise consume as pgup/pgdown for every 5 lines - if(moved > 5) { + if (moved > 5) { ((vt320)terminal.bridge.buffer).keyPressed(vt320.KEY_PAGE_DOWN, ' ', 0); terminal.bridge.tryKeyVibrate(); totalY = 0; return true; - } else if(moved < -5) { + } else if (moved < -5) { ((vt320)terminal.bridge.buffer).keyPressed(vt320.KEY_PAGE_UP, ' ', 0); terminal.bridge.tryKeyVibrate(); totalY = 0; @@ -841,11 +778,6 @@ public class ConsoleActivity extends Activity { // connect with manager service to find all bridges // when connected it will insert all views bindService(new Intent(this, TerminalManager.class), connection, Context.BIND_AUTO_CREATE); - - // make sure we dont let the screen fall asleep - // this also keeps the wifi chipset from disconnecting us - if(wakelock != null && prefs.getBoolean(PreferenceConstants.KEEP_ALIVE, true)) - wakelock.acquire(); } @Override @@ -853,6 +785,10 @@ public class ConsoleActivity extends Activity { super.onPause(); Log.d(TAG, "onPause called"); + // Allow the screen to dim and fall asleep. + if (wakelock != null && wakelock.isHeld()) + wakelock.release(); + if (forcedOrientation && bound != null) bound.setResizeAllowed(false); } @@ -862,77 +798,106 @@ public class ConsoleActivity extends Activity { super.onResume(); Log.d(TAG, "onResume called"); + // Make sure we don't let the screen fall asleep. + // This also keeps the Wi-Fi chipset from disconnecting us. + if (wakelock != null && prefs.getBoolean(PreferenceConstants.KEEP_ALIVE, true)) + wakelock.acquire(); + configureOrientation(); if (forcedOrientation && bound != null) bound.setResizeAllowed(true); } + /* (non-Javadoc) + * @see android.app.Activity#onNewIntent(android.content.Intent) + */ @Override - public void onStop() { - super.onStop(); + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); - unbindService(connection); + Log.d(TAG, "onNewIntent called"); - // allow the screen to dim and fall asleep - if(wakelock != null && wakelock.isHeld()) - wakelock.release(); - } + requested = intent.getData(); - protected void shiftLeft() { - View overlay; - boolean shouldAnimate = flip.getChildCount() > 1; - - // Only show animation if there is something else to go to. - if (shouldAnimate) { - // keep current overlay from popping up again - overlay = findCurrentView(R.id.terminal_overlay); - if (overlay != null) - overlay.startAnimation(fade_stay_hidden); - - flip.setInAnimation(slide_left_in); - flip.setOutAnimation(slide_left_out); - flip.showNext(); + if (requested == null) { + Log.e(TAG, "Got null intent data in onNewIntent()"); + return; + } + + if (bound == null) { + Log.e(TAG, "We're not bound in onNewIntent()"); + return; } - ConsoleActivity.this.updateDefault(); + TerminalBridge requestedBridge = bound.getConnectedBridge(requested.getFragment()); + int requestedIndex = 0; + + synchronized (flip) { + if (requestedBridge == null) { + // If we didn't find the requested connection, try opening it - if (shouldAnimate) { - // show overlay on new slide and start fade - overlay = findCurrentView(R.id.terminal_overlay); - if (overlay != null) - overlay.startAnimation(fade_out_delayed); + try { + Log.d(TAG, String.format("We couldnt find an existing bridge with URI=%s (nickname=%s),"+ + "so creating one now", requested.toString(), requested.getFragment())); + requestedBridge = bound.openConnection(requested); + } catch(Exception e) { + Log.e(TAG, "Problem while trying to create new requested bridge from URI", e); + } + + requestedIndex = addNewTerminalView(requestedBridge); + } else { + final int flipIndex = getFlipIndex(requestedBridge); + if (flipIndex > requestedIndex) { + requestedIndex = flipIndex; + } + } + + setDisplayedTerminal(requestedIndex); } + } - updatePromptVisible(); + @Override + public void onStop() { + super.onStop(); + + unbindService(connection); } - protected void shiftRight() { + protected void shiftCurrentTerminal(final int direction) { View overlay; - boolean shouldAnimate = flip.getChildCount() > 1; - - // Only show animation if there is something else to go to. - if (shouldAnimate) { - // keep current overlay from popping up again - overlay = findCurrentView(R.id.terminal_overlay); - if (overlay != null) - overlay.startAnimation(fade_stay_hidden); - - flip.setInAnimation(slide_right_in); - flip.setOutAnimation(slide_right_out); - flip.showPrevious(); - } + synchronized (flip) { + boolean shouldAnimate = flip.getChildCount() > 1; + + // Only show animation if there is something else to go to. + if (shouldAnimate) { + // keep current overlay from popping up again + overlay = findCurrentView(R.id.terminal_overlay); + if (overlay != null) + overlay.startAnimation(fade_stay_hidden); + + if (direction == SHIFT_LEFT) { + flip.setInAnimation(slide_left_in); + flip.setOutAnimation(slide_left_out); + flip.showNext(); + } else if (direction == SHIFT_RIGHT) { + flip.setInAnimation(slide_right_in); + flip.setOutAnimation(slide_right_out); + flip.showPrevious(); + } + } - ConsoleActivity.this.updateDefault(); + ConsoleActivity.this.updateDefault(); - if (shouldAnimate) { - // show overlay on new slide and start fade - overlay = findCurrentView(R.id.terminal_overlay); - if (overlay != null) - overlay.startAnimation(fade_out_delayed); - } + if (shouldAnimate) { + // show overlay on new slide and start fade + overlay = findCurrentView(R.id.terminal_overlay); + if (overlay != null) + overlay.startAnimation(fade_out_delayed); + } - updatePromptVisible(); + updatePromptVisible(); + } } /** @@ -1039,6 +1004,80 @@ public class ConsoleActivity extends Activity { bound.setResizeAllowed(false); else bound.setResizeAllowed(true); + + bound.hardKeyboardHidden = (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES); + } + } + + /** + * Adds a new TerminalBridge to the current set of views in our ViewFlipper. + * + * @param bridge TerminalBridge to add to our ViewFlipper + * @return the child index of the new view in the ViewFlipper + */ + private int addNewTerminalView(TerminalBridge bridge) { + // let them know about our prompt handler services + bridge.promptHelper.setHandler(promptHandler); + + // inflate each terminal view + RelativeLayout view = (RelativeLayout)inflater.inflate(R.layout.item_terminal, flip, false); + + // set the terminal overlay text + TextView overlay = (TextView)view.findViewById(R.id.terminal_overlay); + overlay.setText(bridge.host.getNickname()); + + // and add our terminal view control, using index to place behind overlay + TerminalView terminal = new TerminalView(ConsoleActivity.this, bridge); + terminal.setId(R.id.console_flip); + view.addView(terminal, 0); + + synchronized (flip) { + // finally attach to the flipper + flip.addView(view); + return flip.getChildCount() - 1; + } + } + + private int getFlipIndex(TerminalBridge bridge) { + synchronized (flip) { + final int children = flip.getChildCount(); + for (int i = 0; i < children; i++) { + final View view = flip.getChildAt(i).findViewById(R.id.console_flip); + + if (view == null || !(view instanceof TerminalView)) { + // How did that happen? + continue; + } + + final TerminalView tv = (TerminalView) view; + + if (tv.bridge == bridge) { + return i; + } + } + } + + return -1; + } + + /** + * Displays the child in the ViewFlipper at the requestedIndex and updates the prompts. + * + * @param requestedIndex the index of the terminal view to display + */ + private void setDisplayedTerminal(int requestedIndex) { + synchronized (flip) { + try { + // show the requested bridge if found, also fade out overlay + flip.setDisplayedChild(requestedIndex); + flip.getCurrentView().findViewById(R.id.terminal_overlay) + .startAnimation(fade_out_delayed); + } catch (NullPointerException npe) { + Log.d(TAG, "View went away when we were about to display it", npe); + } + + updatePromptVisible(); + updateEmptyVisible(); } } } diff --git a/src/org/connectbot/GeneratePubkeyActivity.java b/src/org/connectbot/GeneratePubkeyActivity.java index 061af84..089e485 100644 --- a/src/org/connectbot/GeneratePubkeyActivity.java +++ b/src/org/connectbot/GeneratePubkeyActivity.java @@ -99,7 +99,7 @@ public class GeneratePubkeyActivity extends Activity implements OnEntropyGathere save = (Button) findViewById(R.id.save); - inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); + inflater = LayoutInflater.from(this); nickname.addTextChangedListener(textChecker); password1.addTextChangedListener(textChecker); diff --git a/src/org/connectbot/HostEditorActivity.java b/src/org/connectbot/HostEditorActivity.java index e8202e2..95d04cc 100644 --- a/src/org/connectbot/HostEditorActivity.java +++ b/src/org/connectbot/HostEditorActivity.java @@ -240,13 +240,7 @@ public class HostEditorActivity extends PreferenceActivity implements OnSharedPr public void onServiceConnected(ComponentName className, IBinder service) { TerminalManager bound = ((TerminalManager.TerminalBinder) service).getService(); - for (TerminalBridge bridge: bound.bridges) { - if (bridge.host.equals(host)) { - hostBridge = bridge; - Log.d(TAG, "Found host bridge; charset updates will be made live"); - break; - } - } + hostBridge = bound.getConnectedBridge(host); } public void onServiceDisconnected(ComponentName name) { diff --git a/src/org/connectbot/HostListActivity.java b/src/org/connectbot/HostListActivity.java index c477a58..f65c069 100644 --- a/src/org/connectbot/HostListActivity.java +++ b/src/org/connectbot/HostListActivity.java @@ -252,7 +252,7 @@ public class HostListActivity extends ListActivity { }); transportSpinner.setAdapter(transportSelection); - this.inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); + this.inflater = LayoutInflater.from(this); } @Override @@ -330,7 +330,7 @@ public class HostListActivity extends ListActivity { // edit, disconnect, delete MenuItem connect = menu.add(R.string.list_host_disconnect); - final TerminalBridge bridge = bound.findBridge(host); + final TerminalBridge bridge = bound.getConnectedBridge(host); connect.setEnabled((bridge != null)); connect.setOnMenuItemClickListener(new OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { @@ -473,7 +473,7 @@ public class HostListActivity extends ListActivity { if (this.manager == null) return STATE_UNKNOWN; - if (manager.findBridge(host) != null) + if (manager.getConnectedBridge(host) != null) return STATE_CONNECTED; if (manager.disconnected.contains(host)) diff --git a/src/org/connectbot/PortForwardListActivity.java b/src/org/connectbot/PortForwardListActivity.java index 2cb5dbc..e5c6d21 100644 --- a/src/org/connectbot/PortForwardListActivity.java +++ b/src/org/connectbot/PortForwardListActivity.java @@ -132,16 +132,8 @@ public class PortForwardListActivity extends ListActivity { public void onServiceConnected(ComponentName className, IBinder service) { TerminalManager bound = ((TerminalManager.TerminalBinder) service).getService(); - for (TerminalBridge bridge: bound.bridges) { - if (bridge.host.equals(host)) { - hostBridge = bridge; - updateHandler.sendEmptyMessage(-1); - Log.d(TAG, "Found host bridge; using that instead of database"); - break; - } - } - - + hostBridge = bound.getConnectedBridge(host); + updateHandler.sendEmptyMessage(-1); } public void onServiceDisconnected(ComponentName name) { @@ -171,7 +163,7 @@ public class PortForwardListActivity extends ListActivity { } }); - this.inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); + this.inflater = LayoutInflater.from(this); } @Override diff --git a/src/org/connectbot/PubkeyListActivity.java b/src/org/connectbot/PubkeyListActivity.java index b445d18..9106e1a 100644 --- a/src/org/connectbot/PubkeyListActivity.java +++ b/src/org/connectbot/PubkeyListActivity.java @@ -172,7 +172,7 @@ public class PubkeyListActivity extends ListActivity implements EventListener { clipboard = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE); - inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); + inflater = LayoutInflater.from(this); } /** @@ -292,10 +292,8 @@ public class PubkeyListActivity extends ListActivity implements EventListener { Log.d(TAG, String.format("Unlocked key '%s'", pubkey.getNickname())); - // save this key in-memory if option enabled - if(bound.isSavingKeys()) { - bound.addKey(pubkey, trileadKey); - } + // save this key in memory + bound.addKey(pubkey, trileadKey); updateHandler.sendEmptyMessage(-1); } diff --git a/src/org/connectbot/TerminalView.java b/src/org/connectbot/TerminalView.java index 4e1fefc..35a3c56 100644 --- a/src/org/connectbot/TerminalView.java +++ b/src/org/connectbot/TerminalView.java @@ -20,6 +20,7 @@ package org.connectbot; import org.connectbot.bean.SelectionArea; import org.connectbot.service.FontSizeChangedListener; import org.connectbot.service.TerminalBridge; +import org.connectbot.service.TerminalKeyListener; import android.app.Activity; import android.content.Context; @@ -110,7 +111,7 @@ public class TerminalView extends View implements FontSizeChangedListener { bridge.addFontSizeChangedListener(this); // connect our view up to the bridge - setOnKeyListener(bridge); + setOnKeyListener(bridge.getKeyHandler()); } public void destroy() { @@ -149,14 +150,18 @@ public class TerminalView extends View implements FontSizeChangedListener { // also draw cursor if visible if (bridge.buffer.isCursorVisible()) { int cursorColumn = bridge.buffer.getCursorColumn(); - int columns = bridge.buffer.getColumns(); + final int cursorRow = bridge.buffer.getCursorRow(); + + final int columns = bridge.buffer.getColumns(); if (cursorColumn == columns) cursorColumn = columns - 1; + if (cursorColumn < 0 || cursorRow < 0) + return; + int currentAttribute = bridge.buffer.getAttributes( - cursorColumn, - bridge.buffer.getCursorRow()); + cursorColumn, cursorRow); boolean onWideCharacter = (currentAttribute & VDUBuffer.FULLWIDTH) != 0; int x = cursorColumn * bridge.charWidth; @@ -176,21 +181,21 @@ public class TerminalView extends View implements FontSizeChangedListener { // Make sure we scale our decorations to the correct size. canvas.concat(scaleMatrix); - int metaState = bridge.getMetaState(); + int metaState = bridge.getKeyHandler().getMetaState(); - if ((metaState & TerminalBridge.META_SHIFT_ON) != 0) + if ((metaState & TerminalKeyListener.META_SHIFT_ON) != 0) canvas.drawPath(shiftCursor, cursorStrokePaint); - else if ((metaState & TerminalBridge.META_SHIFT_LOCK) != 0) + else if ((metaState & TerminalKeyListener.META_SHIFT_LOCK) != 0) canvas.drawPath(shiftCursor, cursorPaint); - if ((metaState & TerminalBridge.META_ALT_ON) != 0) + if ((metaState & TerminalKeyListener.META_ALT_ON) != 0) canvas.drawPath(altCursor, cursorStrokePaint); - else if ((metaState & TerminalBridge.META_ALT_LOCK) != 0) + else if ((metaState & TerminalKeyListener.META_ALT_LOCK) != 0) canvas.drawPath(altCursor, cursorPaint); - if ((metaState & TerminalBridge.META_CTRL_ON) != 0) + if ((metaState & TerminalKeyListener.META_CTRL_ON) != 0) canvas.drawPath(ctrlCursor, cursorStrokePaint); - else if ((metaState & TerminalBridge.META_CTRL_LOCK) != 0) + else if ((metaState & TerminalKeyListener.META_CTRL_LOCK) != 0) canvas.drawPath(ctrlCursor, cursorPaint); // Restore previous clip region diff --git a/src/org/connectbot/WizardActivity.java b/src/org/connectbot/WizardActivity.java index cbad106..35a60ca 100644 --- a/src/org/connectbot/WizardActivity.java +++ b/src/org/connectbot/WizardActivity.java @@ -46,7 +46,7 @@ public class WizardActivity extends Activity { this.flipper = (ViewFlipper) findViewById(R.id.wizard_flipper); // inflate the layout for EULA step - LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + LayoutInflater inflater = LayoutInflater.from(this); this.flipper.addView(inflater.inflate(R.layout.wiz_eula, this.flipper, false)); // Add a view for each help topic we want the user to see. diff --git a/src/org/connectbot/service/BackupAgent.java b/src/org/connectbot/service/BackupAgent.java new file mode 100644 index 0000000..1e3bd81 --- /dev/null +++ b/src/org/connectbot/service/BackupAgent.java @@ -0,0 +1,73 @@ +/* + * ConnectBot: simple, powerful, open-source SSH client for Android + * Copyright 2010 Kenny Root, Jeffrey Sharkey + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.connectbot.service; + +import java.io.IOException; + +import org.connectbot.util.HostDatabase; +import org.connectbot.util.PreferenceConstants; +import org.connectbot.util.PubkeyDatabase; + +import android.app.backup.BackupAgentHelper; +import android.app.backup.BackupDataInput; +import android.app.backup.BackupDataOutput; +import android.app.backup.FileBackupHelper; +import android.app.backup.SharedPreferencesBackupHelper; +import android.os.ParcelFileDescriptor; +import android.util.Log; + +/** + * @author kroot + * + */ +public class BackupAgent extends BackupAgentHelper { + @Override + public void onCreate() { + Log.d("ConnectBot.BackupAgent", "onCreate called"); + + SharedPreferencesBackupHelper prefs = new SharedPreferencesBackupHelper(this, getPackageName() + "_preferences"); + addHelper(PreferenceConstants.BACKUP_PREF_KEY, prefs); + + FileBackupHelper hosts = new FileBackupHelper(this, "../databases/" + HostDatabase.DB_NAME); + addHelper(HostDatabase.DB_NAME, hosts); + + FileBackupHelper pubkeys = new FileBackupHelper(this, "../databases/" + PubkeyDatabase.DB_NAME); + addHelper(PubkeyDatabase.DB_NAME, pubkeys); + + } + + @Override + public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, + ParcelFileDescriptor newState) throws IOException { + synchronized (HostDatabase.dbLock) { + super.onBackup(oldState, data, newState); + } + } + + @Override + public void onRestore(BackupDataInput data, int appVersionCode, + ParcelFileDescriptor newState) throws IOException { + Log.d("ConnectBot.BackupAgent", "onRestore called"); + + synchronized (HostDatabase.dbLock) { + Log.d("ConnectBot.BackupAgent", "onRestore in-lock"); + + super.onRestore(data, appVersionCode, newState); + } + } +} diff --git a/src/org/connectbot/service/BackupWrapper.java b/src/org/connectbot/service/BackupWrapper.java new file mode 100644 index 0000000..bfc7535 --- /dev/null +++ b/src/org/connectbot/service/BackupWrapper.java @@ -0,0 +1,71 @@ +/* + * ConnectBot: simple, powerful, open-source SSH client for Android + * Copyright 2010 Kenny Root, Jeffrey Sharkey + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.connectbot.service; + +import org.connectbot.util.PreferenceConstants; + +import android.app.backup.BackupManager; +import android.content.Context; + +/** + * @author kroot + * + */ +public abstract class BackupWrapper { + public static BackupWrapper getInstance() { + if (PreferenceConstants.PRE_FROYO) + return PreFroyo.Holder.sInstance; + else + return FroyoAndBeyond.Holder.sInstance; + } + + public abstract void onDataChanged(Context context); + + private static class PreFroyo extends BackupWrapper { + private static class Holder { + private static final PreFroyo sInstance = new PreFroyo(); + } + + @Override + public void onDataChanged(Context context) { + // do nothing for now + } + } + + private static class FroyoAndBeyond extends BackupWrapper { + private static class Holder { + private static final FroyoAndBeyond sInstance = new FroyoAndBeyond(); + } + + private static BackupManager mBackupManager; + + @Override + public void onDataChanged(Context context) { + checkBackupManager(context); + if (mBackupManager != null) { + mBackupManager.dataChanged(); + } + } + + private void checkBackupManager(Context context) { + if (mBackupManager == null) { + mBackupManager = new BackupManager(context); + } + } + } +} diff --git a/src/org/connectbot/service/ConnectionNotifier.java b/src/org/connectbot/service/ConnectionNotifier.java index 0a2594a..a7e3f8b 100644 --- a/src/org/connectbot/service/ConnectionNotifier.java +++ b/src/org/connectbot/service/ConnectionNotifier.java @@ -1,6 +1,6 @@ /* * ConnectBot: simple, powerful, open-source SSH client for Android - * Copyright 2007 Kenny Root, Jeffrey Sharkey + * Copyright 2010 Kenny Root, Jeffrey Sharkey * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ package org.connectbot.service; import org.connectbot.ConsoleActivity; import org.connectbot.R; import org.connectbot.bean.HostBean; +import org.connectbot.util.HostDatabase; import org.connectbot.util.PreferenceConstants; import android.app.Notification; @@ -29,6 +30,7 @@ import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.res.Resources; +import android.graphics.Color; /** * @author Kenny Root @@ -77,6 +79,19 @@ public abstract class ConnectionNotifier { notification.flags = Notification.FLAG_AUTO_CANCEL; + notification.flags |= Notification.DEFAULT_LIGHTS; + if (HostDatabase.COLOR_RED.equals(host.getColor())) + notification.ledARGB = Color.RED; + else if (HostDatabase.COLOR_GREEN.equals(host.getColor())) + notification.ledARGB = Color.GREEN; + else if (HostDatabase.COLOR_BLUE.equals(host.getColor())) + notification.ledARGB = Color.BLUE; + else + notification.ledARGB = Color.WHITE; + notification.ledOnMS = 300; + notification.ledOffMS = 1000; + notification.flags |= Notification.FLAG_SHOW_LIGHTS; + return notification; } diff --git a/src/org/connectbot/service/ConnectivityReceiver.java b/src/org/connectbot/service/ConnectivityReceiver.java new file mode 100644 index 0000000..908298f --- /dev/null +++ b/src/org/connectbot/service/ConnectivityReceiver.java @@ -0,0 +1,154 @@ +/** + * + */ +package org.connectbot.service; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.NetworkInfo.State; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiManager.WifiLock; +import android.util.Log; + +/** + * @author kroot + * + */ +public class ConnectivityReceiver extends BroadcastReceiver { + private static final String TAG = "ConnectBot.ConnectivityManager"; + + private boolean mIsConnected = false; + + final private TerminalManager mTerminalManager; + + final private WifiLock mWifiLock; + + private int mNetworkRef = 0; + + private boolean mLockingWifi; + + private Object[] mLock = new Object[0]; + + public ConnectivityReceiver(TerminalManager manager, boolean lockingWifi) { + mTerminalManager = manager; + + final ConnectivityManager cm = + (ConnectivityManager) manager.getSystemService(Context.CONNECTIVITY_SERVICE); + + final WifiManager wm = (WifiManager) manager.getSystemService(Context.WIFI_SERVICE); + mWifiLock = wm.createWifiLock(TAG); + + final NetworkInfo info = cm.getActiveNetworkInfo(); + if (info != null) { + mIsConnected = (info.getState() == State.CONNECTED); + } + + mLockingWifi = lockingWifi; + + final IntentFilter filter = new IntentFilter(); + filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + manager.registerReceiver(this, filter); + } + + /* (non-Javadoc) + * @see android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent) + */ + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + + if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { + Log.w(TAG, "onReceived() called: " + intent); + return; + } + + boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); + boolean isFailover = intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false); + + Log.d(TAG, "onReceived() called; noConnectivity? " + noConnectivity + "; isFailover? " + isFailover); + + if (noConnectivity && !isFailover && mIsConnected) { + mIsConnected = false; + mTerminalManager.onConnectivityLost(); + } else if (!mIsConnected) { + NetworkInfo info = (NetworkInfo) intent.getExtras() + .get(ConnectivityManager.EXTRA_NETWORK_INFO); + + if (mIsConnected = (info.getState() == State.CONNECTED)) { + mTerminalManager.onConnectivityRestored(); + } + } + } + + /** + * + */ + public void cleanup() { + if (mWifiLock.isHeld()) + mWifiLock.release(); + + mTerminalManager.unregisterReceiver(this); + } + + /** + * Increase the number of things using the network. Acquire a Wi-Fi lock + * if necessary. + */ + public void incRef() { + synchronized (mLock) { + acquireWifiLockIfNecessaryLocked(); + + mNetworkRef += 1; + } + } + + /** + * Decrease the number of things using the network. Release the Wi-Fi lock + * if necessary. + */ + public void decRef() { + synchronized (mLock) { + mNetworkRef -= 1; + + releaseWifiLockIfNecessaryLocked(); + } + } + + /** + * @param mLockingWifi + */ + public void setWantWifiLock(boolean lockingWifi) { + synchronized (mLock) { + mLockingWifi = lockingWifi; + + if (mLockingWifi) { + acquireWifiLockIfNecessaryLocked(); + } else { + releaseWifiLockIfNecessaryLocked(); + } + } + } + + private void acquireWifiLockIfNecessaryLocked() { + if (mLockingWifi && mNetworkRef > 0 && !mWifiLock.isHeld()) { + mWifiLock.acquire(); + } + } + + private void releaseWifiLockIfNecessaryLocked() { + if (mNetworkRef == 0 && mWifiLock.isHeld()) { + mWifiLock.release(); + } + } + + /** + * @return whether we're connected to a network + */ + public boolean isConnected() { + return mIsConnected; + } +} diff --git a/src/org/connectbot/service/PromptHelper.java b/src/org/connectbot/service/PromptHelper.java index 41082c7..f0a37be 100644 --- a/src/org/connectbot/service/PromptHelper.java +++ b/src/org/connectbot/service/PromptHelper.java @@ -66,6 +66,9 @@ public class PromptHelper { */ public void setResponse(Object value) { response = value; + promptRequested = null; + promptInstructions = null; + promptHint = null; promptResponse.release(); } @@ -101,9 +104,6 @@ public class PromptHelper { // acquire lock until user passes back value promptResponse.acquire(); - promptInstructions = null; - promptHint = null; - promptRequested = null; response = popResponse(); } finally { diff --git a/src/org/connectbot/service/TerminalBridge.java b/src/org/connectbot/service/TerminalBridge.java index c748046..e9e69ca 100644 --- a/src/org/connectbot/service/TerminalBridge.java +++ b/src/org/connectbot/service/TerminalBridge.java @@ -32,10 +32,8 @@ import org.connectbot.bean.SelectionArea; import org.connectbot.transport.AbsTransport; import org.connectbot.transport.TransportFactory; import org.connectbot.util.HostDatabase; -import org.connectbot.util.PreferenceConstants; import android.content.Context; -import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; @@ -45,10 +43,6 @@ import android.graphics.Bitmap.Config; import android.graphics.Paint.FontMetrics; import android.text.ClipboardManager; import android.util.Log; -import android.view.KeyCharacterMap; -import android.view.KeyEvent; -import android.view.View; -import android.view.View.OnKeyListener; import de.mud.terminal.VDUBuffer; import de.mud.terminal.VDUDisplay; import de.mud.terminal.vt320; @@ -63,10 +57,11 @@ import de.mud.terminal.vt320; * This class also provides SSH hostkey verification prompting, and password * prompting. */ -public class TerminalBridge implements VDUDisplay, OnKeyListener { +public class TerminalBridge implements VDUDisplay { public final static String TAG = "ConnectBot.TerminalBridge"; public final static int DEFAULT_FONT_SIZE = 10; + private final static int FONT_SIZE_STEP = 2; public Integer[] color; @@ -77,7 +72,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener { public HostBean host; - private AbsTransport transport; + /* package */ AbsTransport transport; final Paint defaultPaint; @@ -92,26 +87,6 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener { private TerminalView parent = null; private final Canvas canvas = new Canvas(); - private int metaState = 0; - - public final static int META_CTRL_ON = 0x01; - public final static int META_CTRL_LOCK = 0x02; - public final static int META_ALT_ON = 0x04; - public final static int META_ALT_LOCK = 0x08; - public final static int META_SHIFT_ON = 0x10; - public final static int META_SHIFT_LOCK = 0x20; - public final static int META_SLASH = 0x40; - public final static int META_TAB = 0x80; - - // The bit mask of momentary and lock states for each - public final static int META_CTRL_MASK = META_CTRL_ON | META_CTRL_LOCK; - public final static int META_ALT_MASK = META_ALT_ON | META_ALT_LOCK; - public final static int META_SHIFT_MASK = META_SHIFT_ON | META_SHIFT_LOCK; - - // All the transient key codes - public final static int META_TRANSIENT = META_CTRL_ON | META_ALT_ON - | META_SHIFT_ON; - private boolean disconnected = false; private boolean awaitingClose = false; @@ -119,16 +94,12 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener { private int columns; private int rows; - private String keymode = null; - - private boolean hardKeyboard = false; + /* package */ final TerminalKeyListener keyListener; private boolean selectingForCopy = false; private final SelectionArea selectionArea; private ClipboardManager clipboard; - protected KeyCharacterMap keymap = KeyCharacterMap.load(KeyCharacterMap.BUILT_IN_KEYBOARD); - public int charWidth = -1; public int charHeight = -1; private int charTop = -1; @@ -179,6 +150,8 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener { fontSizeChangedListeners = new LinkedList(); transport = null; + + keyListener = new TerminalKeyListener(manager, this, buffer, null); } /** @@ -187,7 +160,6 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener { * and password authentication. */ public TerminalBridge(final TerminalManager manager, final HostBean host) throws IOException { - this.manager = manager; this.host = host; @@ -270,8 +242,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener { selectionArea = new SelectionArea(); - hardKeyboard = (manager.res.getConfiguration().keyboard - == Configuration.KEYBOARD_QWERTY); + keyListener = new TerminalKeyListener(manager, this, buffer, host.getEncoding()); } public PromptHelper getPromptHelper() { @@ -336,6 +307,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener { public void setCharset(String encoding) { if (relay != null) relay.setCharset(encoding); + keyListener.setCharset(encoding); } /** @@ -455,8 +427,12 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener { if (disconnectListener != null) disconnectListener.onDisconnected(TerminalBridge.this); } else { + { + final String line = manager.res.getString(R.string.alert_disconnect_msg); + ((vt320) buffer).putString("\r\n" + line + "\r\n"); + } if (host.getStayConnected()) { - startConnection(); + manager.requestReconnect(this); return; } Thread disconnectPromptThread = new Thread(new Runnable() { @@ -478,394 +454,6 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener { } } - public void refreshKeymode() { - keymode = manager.getKeyMode(); - } - - /** - * Handle onKey() events coming down from a {@link TerminalView} above us. - * Modify the keys to make more sense to a host then pass it to the transport. - */ - public boolean onKey(View v, int keyCode, KeyEvent event) { - try { - - boolean hardKeyboardHidden = - manager.res.getConfiguration().hardKeyboardHidden == - Configuration.HARDKEYBOARDHIDDEN_YES; - - // Ignore all key-up events except for the special keys - if (event.getAction() == KeyEvent.ACTION_UP) { - // There's nothing here for virtual keyboard users. - if (!hardKeyboard || (hardKeyboard && hardKeyboardHidden)) - return false; - - // skip keys if we aren't connected yet or have been disconnected - if (disconnected || transport == null) - return false; - - if (PreferenceConstants.KEYMODE_RIGHT.equals(keymode)) { - if (keyCode == KeyEvent.KEYCODE_ALT_RIGHT - && (metaState & META_SLASH) != 0) { - metaState &= ~(META_SLASH | META_TRANSIENT); - transport.write('/'); - return true; - } else if (keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT - && (metaState & META_TAB) != 0) { - metaState &= ~(META_TAB | META_TRANSIENT); - transport.write(0x09); - return true; - } - } else if (PreferenceConstants.KEYMODE_LEFT.equals(keymode)) { - if (keyCode == KeyEvent.KEYCODE_ALT_LEFT - && (metaState & META_SLASH) != 0) { - metaState &= ~(META_SLASH | META_TRANSIENT); - transport.write('/'); - return true; - } else if (keyCode == KeyEvent.KEYCODE_SHIFT_LEFT - && (metaState & META_TAB) != 0) { - metaState &= ~(META_TAB | META_TRANSIENT); - transport.write(0x09); - return true; - } - } - - return false; - } - - // check for terminal resizing keys - if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { - forcedSize = false; - setFontSize(fontSize + 2); - return true; - } else if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { - forcedSize = false; - setFontSize(fontSize - 2); - return true; - } - - // skip keys if we aren't connected yet or have been disconnected - if (disconnected || transport == null) - return false; - - // if we're in scrollback, scroll to bottom of window on input - if (buffer.windowBase != buffer.screenBase) - buffer.setWindowBase(buffer.screenBase); - - boolean printing = (keymap.isPrintingKey(keyCode) || keyCode == KeyEvent.KEYCODE_SPACE); - - // otherwise pass through to existing session - // print normal keys - if (printing) { - int curMetaState = event.getMetaState(); - - metaState &= ~(META_SLASH | META_TAB); - - if ((metaState & META_SHIFT_MASK) != 0) { - curMetaState |= KeyEvent.META_SHIFT_ON; - metaState &= ~META_SHIFT_ON; - redraw(); - } - - if ((metaState & META_ALT_MASK) != 0) { - curMetaState |= KeyEvent.META_ALT_ON; - metaState &= ~META_ALT_ON; - redraw(); - } - - int key = keymap.get(keyCode, curMetaState); - - if ((metaState & META_CTRL_MASK) != 0) { - metaState &= ~META_CTRL_ON; - redraw(); - - if ((!hardKeyboard || (hardKeyboard && hardKeyboardHidden)) - && sendFunctionKey(keyCode)) - return true; - - // Support CTRL-a through CTRL-z - if (key >= 0x61 && key <= 0x7A) - key -= 0x60; - // Support CTRL-A through CTRL-_ - else if (key >= 0x41 && key <= 0x5F) - key -= 0x40; - else if (key == 0x20) - key = 0x00; - else if (key == 0x3F) - key = 0x7F; - } - - // handle pressing f-keys - if ((hardKeyboard && !hardKeyboardHidden) - && (curMetaState & KeyEvent.META_SHIFT_ON) != 0 - && sendFunctionKey(keyCode)) - return true; - - if (key < 0x80) - transport.write(key); - else - // TODO write encoding routine that doesn't allocate each time - transport.write(new String(Character.toChars(key)) - .getBytes(host.getEncoding())); - - return true; - } - - if (keyCode == KeyEvent.KEYCODE_UNKNOWN && - event.getAction() == KeyEvent.ACTION_MULTIPLE) { - byte[] input = event.getCharacters().getBytes(host.getEncoding()); - transport.write(input); - return true; - } - - // try handling keymode shortcuts - if (hardKeyboard && !hardKeyboardHidden && - event.getRepeatCount() == 0) { - if (PreferenceConstants.KEYMODE_RIGHT.equals(keymode)) { - switch (keyCode) { - case KeyEvent.KEYCODE_ALT_RIGHT: - metaState |= META_SLASH; - return true; - case KeyEvent.KEYCODE_SHIFT_RIGHT: - metaState |= META_TAB; - return true; - case KeyEvent.KEYCODE_SHIFT_LEFT: - metaPress(META_SHIFT_ON); - return true; - case KeyEvent.KEYCODE_ALT_LEFT: - metaPress(META_ALT_ON); - return true; - } - } else if (PreferenceConstants.KEYMODE_LEFT.equals(keymode)) { - switch (keyCode) { - case KeyEvent.KEYCODE_ALT_LEFT: - metaState |= META_SLASH; - return true; - case KeyEvent.KEYCODE_SHIFT_LEFT: - metaState |= META_TAB; - return true; - case KeyEvent.KEYCODE_SHIFT_RIGHT: - metaPress(META_SHIFT_ON); - return true; - case KeyEvent.KEYCODE_ALT_RIGHT: - metaPress(META_ALT_ON); - return true; - } - } else { - switch (keyCode) { - case KeyEvent.KEYCODE_ALT_LEFT: - case KeyEvent.KEYCODE_ALT_RIGHT: - metaPress(META_ALT_ON); - return true; - case KeyEvent.KEYCODE_SHIFT_LEFT: - case KeyEvent.KEYCODE_SHIFT_RIGHT: - metaPress(META_SHIFT_ON); - return true; - } - } - } - - // look for special chars - switch(keyCode) { - case KeyEvent.KEYCODE_CAMERA: - - // check to see which shortcut the camera button triggers - String camera = manager.prefs.getString( - PreferenceConstants.CAMERA, - PreferenceConstants.CAMERA_CTRLA_SPACE); - if(PreferenceConstants.CAMERA_CTRLA_SPACE.equals(camera)) { - transport.write(0x01); - transport.write(' '); - } else if(PreferenceConstants.CAMERA_CTRLA.equals(camera)) { - transport.write(0x01); - } else if(PreferenceConstants.CAMERA_ESC.equals(camera)) { - ((vt320)buffer).keyTyped(vt320.KEY_ESCAPE, ' ', 0); - } - - break; - - case KeyEvent.KEYCODE_DEL: - ((vt320) buffer).keyPressed(vt320.KEY_BACK_SPACE, ' ', - getStateForBuffer()); - metaState &= ~META_TRANSIENT; - return true; - case KeyEvent.KEYCODE_ENTER: - ((vt320)buffer).keyTyped(vt320.KEY_ENTER, ' ', 0); - metaState &= ~META_TRANSIENT; - return true; - - case KeyEvent.KEYCODE_DPAD_LEFT: - if (selectingForCopy) { - selectionArea.decrementColumn(); - redraw(); - } else { - ((vt320) buffer).keyPressed(vt320.KEY_LEFT, ' ', - getStateForBuffer()); - metaState &= ~META_TRANSIENT; - tryKeyVibrate(); - } - return true; - - case KeyEvent.KEYCODE_DPAD_UP: - if (selectingForCopy) { - selectionArea.decrementRow(); - redraw(); - } else { - ((vt320) buffer).keyPressed(vt320.KEY_UP, ' ', - getStateForBuffer()); - metaState &= ~META_TRANSIENT; - tryKeyVibrate(); - } - return true; - - case KeyEvent.KEYCODE_DPAD_DOWN: - if (selectingForCopy) { - selectionArea.incrementRow(); - redraw(); - } else { - ((vt320) buffer).keyPressed(vt320.KEY_DOWN, ' ', - getStateForBuffer()); - metaState &= ~META_TRANSIENT; - tryKeyVibrate(); - } - return true; - - case KeyEvent.KEYCODE_DPAD_RIGHT: - if (selectingForCopy) { - selectionArea.incrementColumn(); - redraw(); - } else { - ((vt320) buffer).keyPressed(vt320.KEY_RIGHT, ' ', - getStateForBuffer()); - metaState &= ~META_TRANSIENT; - tryKeyVibrate(); - } - return true; - - case KeyEvent.KEYCODE_DPAD_CENTER: - if (selectingForCopy) { - if (selectionArea.isSelectingOrigin()) - selectionArea.finishSelectingOrigin(); - else { - if (parent != null && clipboard != null) { - // copy selected area to clipboard - String copiedText = selectionArea.copyFrom(buffer); - - clipboard.setText(copiedText); - parent.notifyUser(parent.getContext().getString( - R.string.console_copy_done, - copiedText.length())); - - selectingForCopy = false; - selectionArea.reset(); - } - } - } else { - if ((metaState & META_CTRL_ON) != 0) { - ((vt320)buffer).keyTyped(vt320.KEY_ESCAPE, ' ', 0); - metaState &= ~META_CTRL_ON; - } else - metaState |= META_CTRL_ON; - } - - redraw(); - - return true; - } - - } catch (IOException e) { - Log.e(TAG, "Problem while trying to handle an onKey() event", e); - try { - transport.flush(); - } catch (IOException ioe) { - Log.d(TAG, "Our transport was closed, dispatching disconnect event"); - dispatchDisconnect(false); - } - } catch (NullPointerException npe) { - Log.d(TAG, "Input before connection established ignored."); - return true; - } - - return false; - } - - /** - * @param key - * @return successful - */ - private boolean sendFunctionKey(int keyCode) { - switch (keyCode) { - case KeyEvent.KEYCODE_1: - ((vt320) buffer).keyPressed(vt320.KEY_F1, ' ', 0); - return true; - case KeyEvent.KEYCODE_2: - ((vt320) buffer).keyPressed(vt320.KEY_F2, ' ', 0); - return true; - case KeyEvent.KEYCODE_3: - ((vt320) buffer).keyPressed(vt320.KEY_F3, ' ', 0); - return true; - case KeyEvent.KEYCODE_4: - ((vt320) buffer).keyPressed(vt320.KEY_F4, ' ', 0); - return true; - case KeyEvent.KEYCODE_5: - ((vt320) buffer).keyPressed(vt320.KEY_F5, ' ', 0); - return true; - case KeyEvent.KEYCODE_6: - ((vt320) buffer).keyPressed(vt320.KEY_F6, ' ', 0); - return true; - case KeyEvent.KEYCODE_7: - ((vt320) buffer).keyPressed(vt320.KEY_F7, ' ', 0); - return true; - case KeyEvent.KEYCODE_8: - ((vt320) buffer).keyPressed(vt320.KEY_F8, ' ', 0); - return true; - case KeyEvent.KEYCODE_9: - ((vt320) buffer).keyPressed(vt320.KEY_F9, ' ', 0); - return true; - case KeyEvent.KEYCODE_0: - ((vt320) buffer).keyPressed(vt320.KEY_F10, ' ', 0); - return true; - default: - return false; - } - } - - /** - * Handle meta key presses where the key can be locked on. - *

- * 1st press: next key to have meta state
- * 2nd press: meta state is locked on
- * 3rd press: disable meta state - * - * @param code - */ - private void metaPress(int code) { - if ((metaState & (code << 1)) != 0) { - metaState &= ~(code << 1); - } else if ((metaState & code) != 0) { - metaState &= ~code; - metaState |= code << 1; - } else - metaState |= code; - redraw(); - } - - public int getMetaState() { - return metaState; - } - - private int getStateForBuffer() { - int bufferState = 0; - - if ((metaState & META_CTRL_MASK) != 0) - bufferState |= vt320.KEY_CONTROL; - if ((metaState & META_SHIFT_MASK) != 0) - bufferState |= vt320.KEY_SHIFT; - if ((metaState & META_ALT_MASK) != 0) - bufferState |= vt320.KEY_ALT; - - return bufferState; - } - public void setSelectingForCopy(boolean selectingForCopy) { this.selectingForCopy = selectingForCopy; } @@ -886,7 +474,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener { * Request a different font size. Will make call to parentChanged() to make * sure we resize PTY if needed. */ - private final void setFontSize(float size) { + /* package */ final void setFontSize(float size) { if (size <= 0.0) return; @@ -911,6 +499,8 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener { host.setFontSize((int) fontSize); manager.hostdb.updateFontSize(host); + + forcedSize = false; } /** @@ -946,14 +536,15 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener { } this.parent = parent; - int width = parent.getWidth(); - int height = parent.getHeight(); + final int width = parent.getWidth(); + final int height = parent.getHeight(); // Something has gone wrong with our layout; we're 0 width or height! if (width <= 0 || height <= 0) return; clipboard = (ClipboardManager) parent.getContext().getSystemService(Context.CLIPBOARD_SERVICE); + keyListener.setClipboardManager(clipboard); if (!forcedSize) { // recalculate buffer size @@ -1203,10 +794,10 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener { if (direction > 0) size -= step; - forcedSize = true; this.columns = cols; this.rows = rows; setFontSize(size); + forcedSize = true; } private int fontSizeCompare(float size, int cols, int rows, int width, int height) { @@ -1348,4 +939,41 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener { return urls; } + + /** + * @return + */ + public boolean isUsingNetwork() { + return transport.usesNetwork(); + } + + /** + * @return + */ + public TerminalKeyListener getKeyHandler() { + return keyListener; + } + + /** + * + */ + public void resetScrollPosition() { + // if we're in scrollback, scroll to bottom of window on input + if (buffer.windowBase != buffer.screenBase) + buffer.setWindowBase(buffer.screenBase); + } + + /** + * + */ + public void increaseFontSize() { + setFontSize(fontSize + FONT_SIZE_STEP); + } + + /** + * + */ + public void decreaseFontSize() { + setFontSize(fontSize - FONT_SIZE_STEP); + } } diff --git a/src/org/connectbot/service/TerminalKeyListener.java b/src/org/connectbot/service/TerminalKeyListener.java new file mode 100644 index 0000000..deba880 --- /dev/null +++ b/src/org/connectbot/service/TerminalKeyListener.java @@ -0,0 +1,506 @@ +/* + * ConnectBot: simple, powerful, open-source SSH client for Android + * Copyright 2010 Kenny Root, Jeffrey Sharkey + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.connectbot.service; + +import java.io.IOException; + +import org.connectbot.TerminalView; +import org.connectbot.bean.SelectionArea; +import org.connectbot.util.PreferenceConstants; + +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.content.res.Configuration; +import android.preference.PreferenceManager; +import android.text.ClipboardManager; +import android.util.Log; +import android.view.KeyCharacterMap; +import android.view.KeyEvent; +import android.view.View; +import android.view.View.OnKeyListener; +import de.mud.terminal.VDUBuffer; +import de.mud.terminal.vt320; + +/** + * @author kenny + * + */ +public class TerminalKeyListener implements OnKeyListener, OnSharedPreferenceChangeListener { + private static final String TAG = "ConnectBot.OnKeyListener"; + + public final static int META_CTRL_ON = 0x01; + public final static int META_CTRL_LOCK = 0x02; + public final static int META_ALT_ON = 0x04; + public final static int META_ALT_LOCK = 0x08; + public final static int META_SHIFT_ON = 0x10; + public final static int META_SHIFT_LOCK = 0x20; + public final static int META_SLASH = 0x40; + public final static int META_TAB = 0x80; + + // The bit mask of momentary and lock states for each + public final static int META_CTRL_MASK = META_CTRL_ON | META_CTRL_LOCK; + public final static int META_ALT_MASK = META_ALT_ON | META_ALT_LOCK; + public final static int META_SHIFT_MASK = META_SHIFT_ON | META_SHIFT_LOCK; + + // All the transient key codes + public final static int META_TRANSIENT = META_CTRL_ON | META_ALT_ON + | META_SHIFT_ON; + + private final TerminalManager manager; + private final TerminalBridge bridge; + private final VDUBuffer buffer; + + protected KeyCharacterMap keymap = KeyCharacterMap.load(KeyCharacterMap.BUILT_IN_KEYBOARD); + + private String keymode = null; + private boolean hardKeyboard = false; + + private int metaState = 0; + + private ClipboardManager clipboard = null; + private boolean selectingForCopy = false; + private final SelectionArea selectionArea; + + private String encoding; + + private final SharedPreferences prefs; + + public TerminalKeyListener(TerminalManager manager, + TerminalBridge bridge, + VDUBuffer buffer, + String encoding) { + this.manager = manager; + this.bridge = bridge; + this.buffer = buffer; + this.encoding = encoding; + + selectionArea = new SelectionArea(); + + prefs = PreferenceManager.getDefaultSharedPreferences(manager); + prefs.registerOnSharedPreferenceChangeListener(this); + + hardKeyboard = (manager.res.getConfiguration().keyboard + == Configuration.KEYBOARD_QWERTY); + + updateKeymode(); + } + + /** + * Handle onKey() events coming down from a {@link TerminalView} above us. + * Modify the keys to make more sense to a host then pass it to the transport. + */ + public boolean onKey(View v, int keyCode, KeyEvent event) { + try { + final boolean hardKeyboardHidden = manager.hardKeyboardHidden; + + // Ignore all key-up events except for the special keys + if (event.getAction() == KeyEvent.ACTION_UP) { + // There's nothing here for virtual keyboard users. + if (!hardKeyboard || (hardKeyboard && hardKeyboardHidden)) + return false; + + // skip keys if we aren't connected yet or have been disconnected + if (bridge.isDisconnected() || bridge.transport == null) + return false; + + if (PreferenceConstants.KEYMODE_RIGHT.equals(keymode)) { + if (keyCode == KeyEvent.KEYCODE_ALT_RIGHT + && (metaState & META_SLASH) != 0) { + metaState &= ~(META_SLASH | META_TRANSIENT); + bridge.transport.write('/'); + return true; + } else if (keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT + && (metaState & META_TAB) != 0) { + metaState &= ~(META_TAB | META_TRANSIENT); + bridge.transport.write(0x09); + return true; + } + } else if (PreferenceConstants.KEYMODE_LEFT.equals(keymode)) { + if (keyCode == KeyEvent.KEYCODE_ALT_LEFT + && (metaState & META_SLASH) != 0) { + metaState &= ~(META_SLASH | META_TRANSIENT); + bridge.transport.write('/'); + return true; + } else if (keyCode == KeyEvent.KEYCODE_SHIFT_LEFT + && (metaState & META_TAB) != 0) { + metaState &= ~(META_TAB | META_TRANSIENT); + bridge.transport.write(0x09); + return true; + } + } + + return false; + } + + // check for terminal resizing keys + if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { + bridge.increaseFontSize(); + return true; + } else if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { + bridge.decreaseFontSize(); + return true; + } + + // skip keys if we aren't connected yet or have been disconnected + if (bridge.isDisconnected() || bridge.transport == null) + return false; + + bridge.resetScrollPosition(); + + boolean printing = (keymap.isPrintingKey(keyCode) || keyCode == KeyEvent.KEYCODE_SPACE); + + // otherwise pass through to existing session + // print normal keys + if (printing) { + int curMetaState = event.getMetaState(); + + metaState &= ~(META_SLASH | META_TAB); + + if ((metaState & META_SHIFT_MASK) != 0) { + curMetaState |= KeyEvent.META_SHIFT_ON; + metaState &= ~META_SHIFT_ON; + bridge.redraw(); + } + + if ((metaState & META_ALT_MASK) != 0) { + curMetaState |= KeyEvent.META_ALT_ON; + metaState &= ~META_ALT_ON; + bridge.redraw(); + } + + int key = keymap.get(keyCode, curMetaState); + + if ((metaState & META_CTRL_MASK) != 0) { + metaState &= ~META_CTRL_ON; + bridge.redraw(); + + if ((!hardKeyboard || (hardKeyboard && hardKeyboardHidden)) + && sendFunctionKey(keyCode)) + return true; + + // Support CTRL-a through CTRL-z + if (key >= 0x61 && key <= 0x7A) + key -= 0x60; + // Support CTRL-A through CTRL-_ + else if (key >= 0x41 && key <= 0x5F) + key -= 0x40; + else if (key == 0x20) + key = 0x00; + else if (key == 0x3F) + key = 0x7F; + } + + // handle pressing f-keys + if ((hardKeyboard && !hardKeyboardHidden) + && (curMetaState & KeyEvent.META_SHIFT_ON) != 0 + && sendFunctionKey(keyCode)) + return true; + + if (key < 0x80) + bridge.transport.write(key); + else + // TODO write encoding routine that doesn't allocate each time + bridge.transport.write(new String(Character.toChars(key)) + .getBytes(encoding)); + + return true; + } + + if (keyCode == KeyEvent.KEYCODE_UNKNOWN && + event.getAction() == KeyEvent.ACTION_MULTIPLE) { + byte[] input = event.getCharacters().getBytes(encoding); + bridge.transport.write(input); + return true; + } + + // try handling keymode shortcuts + if (hardKeyboard && !hardKeyboardHidden && + event.getRepeatCount() == 0) { + if (PreferenceConstants.KEYMODE_RIGHT.equals(keymode)) { + switch (keyCode) { + case KeyEvent.KEYCODE_ALT_RIGHT: + metaState |= META_SLASH; + return true; + case KeyEvent.KEYCODE_SHIFT_RIGHT: + metaState |= META_TAB; + return true; + case KeyEvent.KEYCODE_SHIFT_LEFT: + metaPress(META_SHIFT_ON); + return true; + case KeyEvent.KEYCODE_ALT_LEFT: + metaPress(META_ALT_ON); + return true; + } + } else if (PreferenceConstants.KEYMODE_LEFT.equals(keymode)) { + switch (keyCode) { + case KeyEvent.KEYCODE_ALT_LEFT: + metaState |= META_SLASH; + return true; + case KeyEvent.KEYCODE_SHIFT_LEFT: + metaState |= META_TAB; + return true; + case KeyEvent.KEYCODE_SHIFT_RIGHT: + metaPress(META_SHIFT_ON); + return true; + case KeyEvent.KEYCODE_ALT_RIGHT: + metaPress(META_ALT_ON); + return true; + } + } else { + switch (keyCode) { + case KeyEvent.KEYCODE_ALT_LEFT: + case KeyEvent.KEYCODE_ALT_RIGHT: + metaPress(META_ALT_ON); + return true; + case KeyEvent.KEYCODE_SHIFT_LEFT: + case KeyEvent.KEYCODE_SHIFT_RIGHT: + metaPress(META_SHIFT_ON); + return true; + } + } + } + + // look for special chars + switch(keyCode) { + case KeyEvent.KEYCODE_CAMERA: + + // check to see which shortcut the camera button triggers + String camera = manager.prefs.getString( + PreferenceConstants.CAMERA, + PreferenceConstants.CAMERA_CTRLA_SPACE); + if(PreferenceConstants.CAMERA_CTRLA_SPACE.equals(camera)) { + bridge.transport.write(0x01); + bridge.transport.write(' '); + } else if(PreferenceConstants.CAMERA_CTRLA.equals(camera)) { + bridge.transport.write(0x01); + } else if(PreferenceConstants.CAMERA_ESC.equals(camera)) { + ((vt320)buffer).keyTyped(vt320.KEY_ESCAPE, ' ', 0); + } else if(PreferenceConstants.CAMERA_ESC_A.equals(camera)) { + ((vt320)buffer).keyTyped(vt320.KEY_ESCAPE, ' ', 0); + bridge.transport.write('a'); + } + + break; + + case KeyEvent.KEYCODE_DEL: + ((vt320) buffer).keyPressed(vt320.KEY_BACK_SPACE, ' ', + getStateForBuffer()); + metaState &= ~META_TRANSIENT; + return true; + case KeyEvent.KEYCODE_ENTER: + ((vt320)buffer).keyTyped(vt320.KEY_ENTER, ' ', 0); + metaState &= ~META_TRANSIENT; + return true; + + case KeyEvent.KEYCODE_DPAD_LEFT: + if (selectingForCopy) { + selectionArea.decrementColumn(); + bridge.redraw(); + } else { + ((vt320) buffer).keyPressed(vt320.KEY_LEFT, ' ', + getStateForBuffer()); + metaState &= ~META_TRANSIENT; + bridge.tryKeyVibrate(); + } + return true; + + case KeyEvent.KEYCODE_DPAD_UP: + if (selectingForCopy) { + selectionArea.decrementRow(); + bridge.redraw(); + } else { + ((vt320) buffer).keyPressed(vt320.KEY_UP, ' ', + getStateForBuffer()); + metaState &= ~META_TRANSIENT; + bridge.tryKeyVibrate(); + } + return true; + + case KeyEvent.KEYCODE_DPAD_DOWN: + if (selectingForCopy) { + selectionArea.incrementRow(); + bridge.redraw(); + } else { + ((vt320) buffer).keyPressed(vt320.KEY_DOWN, ' ', + getStateForBuffer()); + metaState &= ~META_TRANSIENT; + bridge.tryKeyVibrate(); + } + return true; + + case KeyEvent.KEYCODE_DPAD_RIGHT: + if (selectingForCopy) { + selectionArea.incrementColumn(); + bridge.redraw(); + } else { + ((vt320) buffer).keyPressed(vt320.KEY_RIGHT, ' ', + getStateForBuffer()); + metaState &= ~META_TRANSIENT; + bridge.tryKeyVibrate(); + } + return true; + + case KeyEvent.KEYCODE_DPAD_CENTER: + if (selectingForCopy) { + if (selectionArea.isSelectingOrigin()) + selectionArea.finishSelectingOrigin(); + else { + if (clipboard != null) { + // copy selected area to clipboard + String copiedText = selectionArea.copyFrom(buffer); + + clipboard.setText(copiedText); + // XXX STOPSHIP +// manager.notifyUser(manager.getString( +// R.string.console_copy_done, +// copiedText.length())); + + selectingForCopy = false; + selectionArea.reset(); + } + } + } else { + if ((metaState & META_CTRL_ON) != 0) { + ((vt320)buffer).keyTyped(vt320.KEY_ESCAPE, ' ', 0); + metaState &= ~META_CTRL_ON; + } else + metaState |= META_CTRL_ON; + } + + bridge.redraw(); + + return true; + } + + } catch (IOException e) { + Log.e(TAG, "Problem while trying to handle an onKey() event", e); + try { + bridge.transport.flush(); + } catch (IOException ioe) { + Log.d(TAG, "Our transport was closed, dispatching disconnect event"); + bridge.dispatchDisconnect(false); + } + } catch (NullPointerException npe) { + Log.d(TAG, "Input before connection established ignored."); + return true; + } + + return false; + } + + + /** + * @param key + * @return successful + */ + private boolean sendFunctionKey(int keyCode) { + switch (keyCode) { + case KeyEvent.KEYCODE_1: + ((vt320) buffer).keyPressed(vt320.KEY_F1, ' ', 0); + return true; + case KeyEvent.KEYCODE_2: + ((vt320) buffer).keyPressed(vt320.KEY_F2, ' ', 0); + return true; + case KeyEvent.KEYCODE_3: + ((vt320) buffer).keyPressed(vt320.KEY_F3, ' ', 0); + return true; + case KeyEvent.KEYCODE_4: + ((vt320) buffer).keyPressed(vt320.KEY_F4, ' ', 0); + return true; + case KeyEvent.KEYCODE_5: + ((vt320) buffer).keyPressed(vt320.KEY_F5, ' ', 0); + return true; + case KeyEvent.KEYCODE_6: + ((vt320) buffer).keyPressed(vt320.KEY_F6, ' ', 0); + return true; + case KeyEvent.KEYCODE_7: + ((vt320) buffer).keyPressed(vt320.KEY_F7, ' ', 0); + return true; + case KeyEvent.KEYCODE_8: + ((vt320) buffer).keyPressed(vt320.KEY_F8, ' ', 0); + return true; + case KeyEvent.KEYCODE_9: + ((vt320) buffer).keyPressed(vt320.KEY_F9, ' ', 0); + return true; + case KeyEvent.KEYCODE_0: + ((vt320) buffer).keyPressed(vt320.KEY_F10, ' ', 0); + return true; + default: + return false; + } + } + + /** + * Handle meta key presses where the key can be locked on. + *

+ * 1st press: next key to have meta state
+ * 2nd press: meta state is locked on
+ * 3rd press: disable meta state + * + * @param code + */ + private void metaPress(int code) { + if ((metaState & (code << 1)) != 0) { + metaState &= ~(code << 1); + } else if ((metaState & code) != 0) { + metaState &= ~code; + metaState |= code << 1; + } else + metaState |= code; + bridge.redraw(); + } + + public void setTerminalKeyMode(String keymode) { + this.keymode = keymode; + } + + private int getStateForBuffer() { + int bufferState = 0; + + if ((metaState & META_CTRL_MASK) != 0) + bufferState |= vt320.KEY_CONTROL; + if ((metaState & META_SHIFT_MASK) != 0) + bufferState |= vt320.KEY_SHIFT; + if ((metaState & META_ALT_MASK) != 0) + bufferState |= vt320.KEY_ALT; + + return bufferState; + } + + public int getMetaState() { + return metaState; + } + + public void setClipboardManager(ClipboardManager clipboard) { + this.clipboard = clipboard; + } + + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, + String key) { + if (PreferenceConstants.KEYMODE.equals(key)) { + updateKeymode(); + } + } + + private void updateKeymode() { + keymode = prefs.getString(PreferenceConstants.KEYMODE, PreferenceConstants.KEYMODE_RIGHT); + } + + public void setCharset(String encoding) { + this.encoding = encoding; + } +} diff --git a/src/org/connectbot/service/TerminalManager.java b/src/org/connectbot/service/TerminalManager.java index 438636e..521ce4b 100644 --- a/src/org/connectbot/service/TerminalManager.java +++ b/src/org/connectbot/service/TerminalManager.java @@ -18,6 +18,7 @@ package org.connectbot.service; import java.io.IOException; +import java.lang.ref.WeakReference; import java.security.PrivateKey; import java.security.PublicKey; import java.util.Arrays; @@ -44,14 +45,12 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.res.AssetFileDescriptor; +import android.content.res.Configuration; import android.content.res.Resources; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; import android.net.Uri; -import android.net.wifi.WifiManager; import android.os.Binder; import android.os.Handler; import android.os.IBinder; @@ -73,6 +72,11 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen public final static String TAG = "ConnectBot.TerminalManager"; public List bridges = new LinkedList(); + public Map> mHostBridgeMap = + new HashMap>(); + public Map> mNicknameBridgeMap = + new HashMap>(); + public TerminalBridge defaultBridge = null; public List disconnected = new LinkedList(); @@ -88,10 +92,9 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen protected SharedPreferences prefs; - private final IBinder binder = new TerminalBinder(); + final private IBinder binder = new TerminalBinder(); - private ConnectivityManager connectivityManager; - private WifiManager.WifiLock wifilock; + private ConnectivityReceiver connectivityManager; private MediaPlayer mediaPlayer; @@ -108,6 +111,13 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen private boolean resizeAllowed = true; + private boolean savingKeys; + + protected List> mPendingReconnect + = new LinkedList>(); + + public boolean hardKeyboardHidden; + @Override public void onCreate() { Log.i(TAG, "Starting background service"); @@ -139,29 +149,31 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen } } - connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); - - WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE); - wifilock = manager.createWifiLock(TAG); - vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); wantKeyVibration = prefs.getBoolean(PreferenceConstants.BUMPY_ARROWS, true); wantBellVibration = prefs.getBoolean(PreferenceConstants.BELL_VIBRATE, true); enableMediaPlayer(); + + hardKeyboardHidden = (res.getConfiguration().hardKeyboardHidden == + Configuration.HARDKEYBOARDHIDDEN_YES); + + final boolean lockingWifi = prefs.getBoolean(PreferenceConstants.WIFI_LOCK, true); + + connectivityManager = new ConnectivityReceiver(this, lockingWifi); + + updateSavingKeys(); + } + + private void updateSavingKeys() { + savingKeys = prefs.getBoolean(PreferenceConstants.MEMKEYS, true); } @Override public void onDestroy() { Log.i(TAG, "Destroying background service"); - if (bridges.size() > 0) { - TerminalBridge[] tmpBridges = bridges.toArray(new TerminalBridge[bridges.size()]); - - // disconnect and dispose of any existing bridges - for (int i = 0; i < tmpBridges.length; i++) - tmpBridges[i].dispatchDisconnect(true); - } + disconnectAll(true); if(hostdb != null) { hostdb.close(); @@ -180,8 +192,7 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen pubkeyTimer.cancel(); } - if (wifilock != null && wifilock.isHeld()) - wifilock.release(); + connectivityManager.cleanup(); ConnectionNotifier.getInstance().hideRunningNotification(this); @@ -189,30 +200,60 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen } /** + * Disconnect all currently connected bridges. + */ + private void disconnectAll(final boolean immediate) { + TerminalBridge[] tmpBridges = null; + + synchronized (bridges) { + if (bridges.size() > 0) { + tmpBridges = bridges.toArray(new TerminalBridge[bridges.size()]); + } + } + + if (tmpBridges != null) { + // disconnect and dispose of any existing bridges + for (int i = 0; i < tmpBridges.length; i++) + tmpBridges[i].dispatchDisconnect(immediate); + } + } + + /** * Open a new SSH session using the given parameters. */ - private void openConnection(HostBean host) throws IllegalArgumentException, IOException { + private TerminalBridge openConnection(HostBean host) throws IllegalArgumentException, IOException { // throw exception if terminal already open - if (findBridge(host) != null) { + if (getConnectedBridge(host) != null) { throw new IllegalArgumentException("Connection already open for that nickname"); } TerminalBridge bridge = new TerminalBridge(this, host); bridge.setOnDisconnectedListener(this); bridge.startConnection(); - bridges.add(bridge); - // Add a reference to the WifiLock - NetworkInfo info = connectivityManager.getActiveNetworkInfo(); - if (isLockingWifi() && - info != null && - info.getType() == ConnectivityManager.TYPE_WIFI) { - Log.d(TAG, "Acquiring WifiLock"); - wifilock.acquire(); + synchronized (bridges) { + bridges.add(bridge); + WeakReference wr = new WeakReference(bridge); + mHostBridgeMap.put(bridge.host, wr); + mNicknameBridgeMap.put(bridge.host.getNickname(), wr); + } + + synchronized (disconnected) { + disconnected.remove(bridge.host); + } + + if (bridge.isUsingNetwork()) { + connectivityManager.incRef(); + } + + if (prefs.getBoolean(PreferenceConstants.CONNECTION_PERSIST, true)) { + ConnectionNotifier.getInstance().showRunningNotification(this); } // also update database with new connected time touchHost(host); + + return bridge; } public String getEmulation() { @@ -228,29 +269,17 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen return scrollback; } - public boolean isSavingKeys() { - return prefs.getBoolean(PreferenceConstants.MEMKEYS, true); - } - - public String getKeyMode() { - return prefs.getString(PreferenceConstants.KEYMODE, PreferenceConstants.KEYMODE_RIGHT); // "Use right-side keys" - } - - public boolean isLockingWifi() { - return prefs.getBoolean(PreferenceConstants.WIFI_LOCK, true); - } - /** * Open a new connection by reading parameters from the given URI. Follows * format specified by an individual transport. */ - public void openConnection(Uri uri) throws Exception { + public TerminalBridge openConnection(Uri uri) throws Exception { HostBean host = TransportFactory.findHost(hostdb, uri); if (host == null) host = TransportFactory.getTransport(uri.getScheme()).createHost(uri); - openConnection(host); + return openConnection(host); } /** @@ -262,35 +291,72 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen } /** - * Find the {@link TerminalBridge} with the given nickname. + * Find a connected {@link TerminalBridge} with the given HostBean. + * + * @param host the HostBean to search for + * @return TerminalBridge that uses the HostBean */ - public TerminalBridge findBridge(HostBean host) { - // find the first active bridge with given nickname - for(TerminalBridge bridge : bridges) { - if (bridge.host.equals(host)) - return bridge; + public TerminalBridge getConnectedBridge(HostBean host) { + WeakReference wr = mHostBridgeMap.get(host); + if (wr != null) { + return wr.get(); + } else { + return null; + } + } + + /** + * Find a connected {@link TerminalBridge} using its nickname. + * + * @param nickname + * @return TerminalBridge that matches nickname + */ + public TerminalBridge getConnectedBridge(final String nickname) { + if (nickname == null) { + return null; + } + WeakReference wr = mNicknameBridgeMap.get(nickname); + if (wr != null) { + return wr.get(); + } else { + return null; } - return null; } /** * Called by child bridge when somehow it's been disconnected. */ public void onDisconnected(TerminalBridge bridge) { - // remove this bridge from our list - bridges.remove(bridge); + boolean shouldHideRunningNotification = false; + + synchronized (bridges) { + // remove this bridge from our list + bridges.remove(bridge); + + mHostBridgeMap.remove(bridge.host); + mNicknameBridgeMap.remove(bridge.host.getNickname()); + + if (bridge.isUsingNetwork()) { + connectivityManager.decRef(); + } + + if (bridges.size() == 0 && + mPendingReconnect.size() == 0) { + shouldHideRunningNotification = true; + } + } - if (bridges.size() == 0 && wifilock.isHeld()) { - Log.d(TAG, "WifiLock was held, releasing"); - wifilock.release(); + synchronized (disconnected) { + disconnected.add(bridge.host); } - disconnected.add(bridge.host); + if (shouldHideRunningNotification) { + ConnectionNotifier.getInstance().hideRunningNotification(this); + } // pass notification back up to gui if (disconnectHandler != null) Message.obtain(disconnectHandler, -1, bridge).sendToTarget(); - } public boolean isKeyLoaded(String nickname) { @@ -298,6 +364,9 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen } public void addKey(PubkeyBean pubkey, Object trileadKey) { + if (!savingKeys) + return; + removeKey(pubkey.getNickname()); byte[] sshPubKey = PubkeyUtils.extractOpenSSHPublic(trileadKey); @@ -410,8 +479,6 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen setResizeAllowed(true); - ConnectionNotifier.getInstance().hideRunningNotification(this); - stopIdleTimer(); // Make sure we stay running to maintain the bridges @@ -426,8 +493,6 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen setResizeAllowed(true); - ConnectionNotifier.getInstance().hideRunningNotification(this); - Log.i(TAG, "Someone rebound to TerminalManager"); stopIdleTimer(); @@ -441,13 +506,6 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen if (bridges.size() == 0) { stopWithDelay(); - } else { - /* If user wants the connections to stay alive at all costs, - * set the service to be "foreground." - */ - if (prefs.getBoolean(PreferenceConstants.CONNECTION_PERSIST, true)) { - ConnectionNotifier.getInstance().showRunningNotification(this); - } } return true; @@ -510,7 +568,7 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen vibrate(); } - class BeepListener implements OnCompletionListener { + private static class BeepListener implements OnCompletionListener { public void onCompletion(MediaPlayer mp) { mp.seekTo(0); } @@ -555,6 +613,11 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen } else if (PreferenceConstants.BUMPY_ARROWS.equals(key)) { wantKeyVibration = sharedPreferences.getBoolean( PreferenceConstants.BUMPY_ARROWS, true); + } else if (PreferenceConstants.WIFI_LOCK.equals(key)) { + final boolean lockingWifi = prefs.getBoolean(PreferenceConstants.WIFI_LOCK, true); + connectivityManager.setWantWifiLock(lockingWifi); + } else if (PreferenceConstants.MEMKEYS.equals(key)) { + updateSavingKeys(); } } @@ -570,9 +633,72 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen return resizeAllowed; } - public class KeyHolder { + public static class KeyHolder { public PubkeyBean bean; public Object trileadKey; public byte[] openSSHPubkey; } + + /** + * Called when connectivity to the network is lost and it doesn't appear + * we'll be getting a different connection any time soon. + */ + public void onConnectivityLost() { + final Thread t = new Thread() { + @Override + public void run() { + disconnectAll(false); + } + }; + t.setName("Disconnector"); + t.start(); + } + + /** + * Called when connectivity to the network is restored. + */ + public void onConnectivityRestored() { + final Thread t = new Thread() { + @Override + public void run() { + reconnectPending(); + } + }; + t.setName("Reconnector"); + t.start(); + } + + /** + * Insert request into reconnect queue to be executed either immediately + * or later when connectivity is restored depending on whether we're + * currently connected. + * + * @param bridge the TerminalBridge to reconnect when possible + */ + public void requestReconnect(TerminalBridge bridge) { + synchronized (mPendingReconnect) { + mPendingReconnect.add(new WeakReference(bridge)); + if (!bridge.isUsingNetwork() || + connectivityManager.isConnected()) { + reconnectPending(); + } + } + } + + /** + * Reconnect all bridges that were pending a reconnect when connectivity + * was lost. + */ + private void reconnectPending() { + synchronized (mPendingReconnect) { + for (WeakReference ref : mPendingReconnect) { + TerminalBridge bridge = ref.get(); + if (bridge == null) { + continue; + } + bridge.startConnection(); + } + mPendingReconnect.clear(); + } + } } diff --git a/src/org/connectbot/transport/AbsTransport.java b/src/org/connectbot/transport/AbsTransport.java index fbd4655..18397ea 100644 --- a/src/org/connectbot/transport/AbsTransport.java +++ b/src/org/connectbot/transport/AbsTransport.java @@ -246,4 +246,9 @@ public abstract class AbsTransport { public static String getFormatHint(Context context) { return "???"; } + + /** + * @return + */ + public abstract boolean usesNetwork(); } diff --git a/src/org/connectbot/transport/Local.java b/src/org/connectbot/transport/Local.java index 46903b2..5ace1b0 100644 --- a/src/org/connectbot/transport/Local.java +++ b/src/org/connectbot/transport/Local.java @@ -208,4 +208,12 @@ public class Local extends AbsTransport { public static String getFormatHint(Context context) { return context.getString(R.string.hostpref_nickname_title); } + + /* (non-Javadoc) + * @see org.connectbot.transport.AbsTransport#usesNetwork() + */ + @Override + public boolean usesNetwork() { + return false; + } } diff --git a/src/org/connectbot/transport/SSH.java b/src/org/connectbot/transport/SSH.java index 11e0659..8a90f72 100644 --- a/src/org/connectbot/transport/SSH.java +++ b/src/org/connectbot/transport/SSH.java @@ -299,7 +299,7 @@ public class SSH extends AbsTransport implements ConnectionMonitor, InteractiveC Log.d(TAG, String.format("Found unlocked key '%s' already in-memory", pubkey.getNickname())); if (pubkey.isConfirmUse()) { - if (promptForPubkeyUse(pubkey.getNickname())) + if (!promptForPubkeyUse(pubkey.getNickname())) return false; } @@ -342,10 +342,8 @@ public class SSH extends AbsTransport implements ConnectionMonitor, InteractiveC Log.d(TAG, String.format("Unlocked key '%s'", pubkey.getNickname())); - // save this key in-memory if option enabled - if(manager.isSavingKeys()) { - manager.addKey(pubkey, trileadKey); - } + // save this key in memory + manager.addKey(pubkey, trileadKey); } return tryPublicKey(host.getUsername(), pubkey.getNickname(), trileadKey); @@ -944,4 +942,12 @@ public class SSH extends AbsTransport implements ConnectionMonitor, InteractiveC agentLockPassphrase = lockPassphrase; return true; } + + /* (non-Javadoc) + * @see org.connectbot.transport.AbsTransport#usesNetwork() + */ + @Override + public boolean usesNetwork() { + return true; + } } diff --git a/src/org/connectbot/transport/Telnet.java b/src/org/connectbot/transport/Telnet.java index b7388ad..5fde2f6 100644 --- a/src/org/connectbot/transport/Telnet.java +++ b/src/org/connectbot/transport/Telnet.java @@ -319,4 +319,12 @@ public class Telnet extends AbsTransport { context.getString(R.string.format_hostname), context.getString(R.string.format_port)); } + + /* (non-Javadoc) + * @see org.connectbot.transport.AbsTransport#usesNetwork() + */ + @Override + public boolean usesNetwork() { + return true; + } } diff --git a/src/org/connectbot/util/HostDatabase.java b/src/org/connectbot/util/HostDatabase.java index bd567ce..b0dce6d 100644 --- a/src/org/connectbot/util/HostDatabase.java +++ b/src/org/connectbot/util/HostDatabase.java @@ -134,14 +134,12 @@ public class HostDatabase extends RobustSQLiteOpenHelper { addIndexName(TABLE_COLOR_DEFAULTS + FIELD_COLOR_SCHEME + "index"); } - private Object dbLock; + public static final Object[] dbLock = new Object[0]; public HostDatabase(Context context) { super(context, DB_NAME, null, DB_VERSION); getWritableDatabase().close(); - - dbLock = new Object(); } @Override diff --git a/src/org/connectbot/util/OnDbWrittenListener.java b/src/org/connectbot/util/OnDbWrittenListener.java new file mode 100644 index 0000000..ef33797 --- /dev/null +++ b/src/org/connectbot/util/OnDbWrittenListener.java @@ -0,0 +1,26 @@ +/* + * ConnectBot: simple, powerful, open-source SSH client for Android + * Copyright 2010 Kenny Root, Jeffrey Sharkey + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.connectbot.util; + +/** + * @author kroot + * + */ +public interface OnDbWrittenListener { + public void onDbWritten(); +} diff --git a/src/org/connectbot/util/PreferenceConstants.java b/src/org/connectbot/util/PreferenceConstants.java index 261152a..37e1871 100644 --- a/src/org/connectbot/util/PreferenceConstants.java +++ b/src/org/connectbot/util/PreferenceConstants.java @@ -25,6 +25,8 @@ import android.os.Build; */ public class PreferenceConstants { public static final boolean PRE_ECLAIR = (Integer.parseInt(Build.VERSION.SDK) <= 4); + public static final boolean PRE_FROYO = PRE_ECLAIR ? true : + (Build.VERSION.SDK_INT <= 7); public static final String MEMKEYS = "memkeys"; public static final String UPDATE = "update"; @@ -58,6 +60,7 @@ public class PreferenceConstants { public static final String CAMERA_CTRLA_SPACE = "Ctrl+A then Space"; public static final String CAMERA_CTRLA = "Ctrl+A"; public static final String CAMERA_ESC = "Esc"; + public static final String CAMERA_ESC_A = "Esc+A"; public static final String KEEP_ALIVE = "keepalive"; @@ -76,4 +79,7 @@ public class PreferenceConstants { public static final float DEFAULT_BELL_VOLUME = 0.25f; public static final String CONNECTION_PERSIST = "connPersist"; + + /* Backup identifiers */ + public static final String BACKUP_PREF_KEY = "prefs"; } diff --git a/src/org/connectbot/util/UberColorPickerDialog.java b/src/org/connectbot/util/UberColorPickerDialog.java index 923a027..e12307e 100644 --- a/src/org/connectbot/util/UberColorPickerDialog.java +++ b/src/org/connectbot/util/UberColorPickerDialog.java @@ -571,17 +571,6 @@ public class UberColorPickerDialog extends Dialog { } /** - * Convert a slider position in the range [0,PALETTE_DIM] to a byte value in the range [0,255]. - * @param sliderPos in the range [0,PALETTE_DIM]. - * @return - */ - public int sliderPosTo255(int sliderPos) { - int int255 = (int)(255.0f * ((float)sliderPos / (float)PALETTE_DIM)); - int255 = pinToByte(int255); - return int255; - } - - /** * Wrap Math.round(). I'm not a Java expert. Is this the only way to avoid writing "(int)Math.round" everywhere? * @param x * @return @@ -591,20 +580,6 @@ public class UberColorPickerDialog extends Dialog { } /** - * Limit a value to a min and max range. - * @param n - * @return - */ - private int pinToByte(int n) { - if (n < 0) { - n = 0; - } else if (n > 255) { - n = 255; - } - return n; - } - - /** * Limit a value to the range [0,1]. * @param n * @return -- 2.11.0