From 1658a9bc00a3bd692908dcd5b9eb550a49f8f5ec Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Tue, 3 Mar 2009 14:04:29 -0800 Subject: auto import from //depot/cupcake/@132589 --- assets/plugins/gears-0.5.11.0/dummy | 1 + assets/plugins/gears-0.5.12.0/dummy | 1 - assets/plugins/gears.so | Bin 1196880 -> 1234788 bytes res/drawable/gears_file_audio.png | Bin 0 -> 2211 bytes res/drawable/gears_file_image.png | Bin 0 -> 1849 bytes res/drawable/gears_file_unknown.png | Bin 0 -> 1072 bytes res/drawable/gears_file_video.png | Bin 0 -> 2044 bytes res/drawable/gears_folder.png | Bin 0 -> 2235 bytes res/layout/gears_dialog_filepicker.xml | 61 ++ res/layout/gears_dialog_filepicker_cell.xml | 44 + res/layout/gears_dialog_shortcut.xml | 103 +++ res/values-cs/strings.xml | 11 +- res/values-de/strings.xml | 11 +- res/values-es/strings.xml | 27 +- res/values-fr/strings.xml | 51 +- res/values-it/strings.xml | 23 +- res/values-ja/strings.xml | 11 +- res/values-ko/strings.xml | 11 +- res/values-nb/strings.xml | 47 +- res/values-nl/strings.xml | 13 +- res/values-pl/strings.xml | 39 +- res/values-ru/strings.xml | 11 +- res/values-zh-rCN/strings.xml | 11 +- res/values-zh-rTW/strings.xml | 11 +- res/values/colors.xml | 3 + res/values/strings.xml | 4 +- res/xml/searchable.xml | 1 - src/com/android/browser/BrowserActivity.java | 30 +- src/com/android/browser/BrowserHistoryPage.java | 61 +- .../android/browser/BrowserHomepagePreference.java | 4 +- .../android/browser/BrowserPreferencesPage.java | 3 +- src/com/android/browser/FindDialog.java | 17 +- src/com/android/browser/GearsFilePickerDialog.java | 930 +++++++++++++++++++++ src/com/android/browser/GearsNativeDialog.java | 42 +- src/com/android/browser/GearsShortcutDialog.java | 151 ++++ 35 files changed, 1498 insertions(+), 235 deletions(-) create mode 100644 assets/plugins/gears-0.5.11.0/dummy delete mode 100644 assets/plugins/gears-0.5.12.0/dummy create mode 100755 res/drawable/gears_file_audio.png create mode 100755 res/drawable/gears_file_image.png create mode 100755 res/drawable/gears_file_unknown.png create mode 100755 res/drawable/gears_file_video.png create mode 100755 res/drawable/gears_folder.png create mode 100644 res/layout/gears_dialog_filepicker.xml create mode 100644 res/layout/gears_dialog_filepicker_cell.xml create mode 100644 res/layout/gears_dialog_shortcut.xml create mode 100644 src/com/android/browser/GearsFilePickerDialog.java create mode 100644 src/com/android/browser/GearsShortcutDialog.java diff --git a/assets/plugins/gears-0.5.11.0/dummy b/assets/plugins/gears-0.5.11.0/dummy new file mode 100644 index 00000000..50f9ab94 --- /dev/null +++ b/assets/plugins/gears-0.5.11.0/dummy @@ -0,0 +1 @@ +This file is used to ensure this subdirectory is created. diff --git a/assets/plugins/gears-0.5.12.0/dummy b/assets/plugins/gears-0.5.12.0/dummy deleted file mode 100644 index 50f9ab94..00000000 --- a/assets/plugins/gears-0.5.12.0/dummy +++ /dev/null @@ -1 +0,0 @@ -This file is used to ensure this subdirectory is created. diff --git a/assets/plugins/gears.so b/assets/plugins/gears.so index d575b147..6cc5b754 100644 Binary files a/assets/plugins/gears.so and b/assets/plugins/gears.so differ diff --git a/res/drawable/gears_file_audio.png b/res/drawable/gears_file_audio.png new file mode 100755 index 00000000..ce897b66 Binary files /dev/null and b/res/drawable/gears_file_audio.png differ diff --git a/res/drawable/gears_file_image.png b/res/drawable/gears_file_image.png new file mode 100755 index 00000000..b140f844 Binary files /dev/null and b/res/drawable/gears_file_image.png differ diff --git a/res/drawable/gears_file_unknown.png b/res/drawable/gears_file_unknown.png new file mode 100755 index 00000000..23386f49 Binary files /dev/null and b/res/drawable/gears_file_unknown.png differ diff --git a/res/drawable/gears_file_video.png b/res/drawable/gears_file_video.png new file mode 100755 index 00000000..d876afbc Binary files /dev/null and b/res/drawable/gears_file_video.png differ diff --git a/res/drawable/gears_folder.png b/res/drawable/gears_folder.png new file mode 100755 index 00000000..ed31ba58 Binary files /dev/null and b/res/drawable/gears_folder.png differ diff --git a/res/layout/gears_dialog_filepicker.xml b/res/layout/gears_dialog_filepicker.xml new file mode 100644 index 00000000..68268f1a --- /dev/null +++ b/res/layout/gears_dialog_filepicker.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/res/layout/gears_dialog_filepicker_cell.xml b/res/layout/gears_dialog_filepicker_cell.xml new file mode 100644 index 00000000..369fc6a7 --- /dev/null +++ b/res/layout/gears_dialog_filepicker_cell.xml @@ -0,0 +1,44 @@ + + + + + + + + + + diff --git a/res/layout/gears_dialog_shortcut.xml b/res/layout/gears_dialog_shortcut.xml new file mode 100644 index 00000000..28f93d0e --- /dev/null +++ b/res/layout/gears_dialog_shortcut.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index bc1597a8..e301545e 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -27,7 +27,7 @@ "Přihlásit se" "Zrušit" "OK" - " shod" + "shod" "Ne" "Informace o stránce" "Zobrazit informace o stránce" @@ -75,7 +75,7 @@ "Adresa URL není platná." "Smazat" "Přidat poslední zobrazenou stránku do záložek" - "od " + "od" "Záložka %s bude smazána." "Otevřít v novém okně" "Nové okno" @@ -235,8 +235,7 @@ "Žádná karta SD není dostupná." "Na kartu SD je třeba stáhnout soubor %s." "Karta SD není dostupná" - - + "Karta SD je zaneprázdněná. Chcete-li povolit stahování, přejděte na Plochu > Nastavení > Karta SD a paměť telefonu a zrušte zaškrtnutí políčka Použít jako paměťové zařízení USB." "Nebyla nalezena žádná aplikace, ve které lze tento soubor otevřít." "Zkusit znovu" "Historie stahování je prázdná." @@ -263,7 +262,7 @@ - + @@ -294,7 +293,7 @@ - + diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 8e1ee229..3a4bb6da 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -27,7 +27,7 @@ "Anmelden" "Abbrechen" "OK" - " Treffer" + "Treffer" "Nein" "Seiten-Info" "Seiten-Info anzeigen" @@ -75,7 +75,7 @@ "URL ist nicht gültig." "Löschen" "Lesezeichen für zuletzt besuchte Seite" - "von " + "von" "Lesezeichen \"%s\" wird gelöscht." "In neuem Fenster öffnen" "Neues Fenster" @@ -235,8 +235,7 @@ "Keine SD-Karte" "Zum Download von %s ist eine SD-Karte erforderlich." "SD-Karte nicht verfügbar" - - + "Die SD-Karte ist ausgelastet. Um Downloads zuzulassen, gehen Sie zur Startseite > Einstellungen > SD-Karte & Telefonspeicher und deaktivieren Sie das Kontrollkästchen \"Für USB-Speicher verwenden\"." "Es kann keine Anwendung gefunden werden, um diese Datei zu öffnen." "Wiederholen" "Downloadverlauf ist leer." @@ -263,7 +262,7 @@ - + @@ -294,7 +293,7 @@ - + diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index fb1b083c..7032535f 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -15,7 +15,7 @@ --> - "Navegador" + "Navegador web" "Marcadores" "Más visitados" "Historial" @@ -27,7 +27,7 @@ "Acceder" "Cancelar" "Aceptar" - " coincidencias" + "coincidencias" "No" "Información de página" "Ver información de página" @@ -75,7 +75,7 @@ "La URL no es válida." "Suprimir" "Marcar como última página vista" - "de " + "de" "Se eliminará el marcador \"%s\"." "Abrir en ventana nueva" "Nueva ventana" @@ -83,7 +83,7 @@ "Buscar en la página" "Seleccionar texto" "Visión general de ventanas" - "Ventanas" + "Windows" "Ventanas actuales" "Ver" "Nueva ventana" @@ -104,7 +104,7 @@ "Copiar URL de enlace" "Guardar imagen" "Ver imagen" - "Llamar…" + "Marcar…" "Añadir contacto" "Enviar mensaje de correo electrónico" "Mapa" @@ -126,7 +126,7 @@ "Borrar caché" "Eliminar todo el contenido de la página almacenado en caché" "Se borrará la caché." - "Borrar los datos de cookies" + "Borrar todos los datos de cookies" "Borrar todas las cookies del navegador" "Se borrarán todas las cookies." "Borrar historial" @@ -142,14 +142,14 @@ "Recordar contraseñas" "Guardar nombres de usuario y contraseñas de sitios web" "Recordar datos de formulario" - "Recordar datos introducidos en formularios" + "Recordar datos introducidos en formularios para utilizarlos más adelante" "Mostrar advertencias de seguridad" "Mostrar advertencia si hay algún problema con la seguridad del sitio" "Aceptar cookies" "Permitir que los sitios guarden y lean datos de cookies" "Establecer tamaño de texto" - "Muy pequeño" + "Tiny" "Pequeño" "Normal" "Grande" @@ -199,7 +199,7 @@ "Esta página web se ha redirigido a otra ubicación. ¿Quieres enviar los datos del formulario cumplimentado a la nueva ubicación?" "Problema de conectividad de datos" "Problema con archivo" - "OK" + "Confirmar" "La página que intentas ver contiene datos que ya se han enviado (\"POSTDATA\"). Si reenvías los datos, se repetirá cualquier acción realizada por el formulario de la página (como las búsquedas o las compras online)." "Sin conexión de red" "La página seguirá cargándose una vez que se restablezca la conexión." @@ -232,11 +232,10 @@ "Sin espacio" "No se ha podido descargar el archivo %s."\n"Libera espacio en el teléfono e inténtalo de nuevo." "Descarga incorrecta" - "Falta la tarjeta SD" + "Ninguna tarjeta SD" "Para descargar %s se necesita una tarjeta SD." "Tarjeta SD no disponible" - - + "La tarjeta SD está ocupada. Para permitir descargas, accede a \"Página principal > Configuración > Almacenamiento en teléfono y en tarjeta SD\" y desactiva la casilla de verificación \"Utilizar para almacenamiento USB\"." "No se ha encontrado ninguna aplicación que permita abrir este archivo." "Reintentar" "El historial de descargas está vacío." @@ -263,7 +262,7 @@ - + @@ -294,7 +293,7 @@ - + diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 5a2ec4d8..0b2df36b 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -17,7 +17,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Navigateur" "Favoris" - "Les + visités" + "Les plus consultés" "Historique" "Ajouté aux favoris" "Supprimé des favoris" @@ -27,7 +27,7 @@ "Se connecter" "Annuler" "OK" - " résultat(s) correspondant(s )" + "résultats correspondants" "Non" "Infos sur la page" "Afficher les infos sur la page" @@ -64,7 +64,7 @@ "http://" "Favori" "Modifier le favori" - "Raccourci sur la page d\'accueil" + "Ajouter un raccourci sur la page d\'accueil" "Ouverture" "Supprimer le favori" "Supprimer de l\'historique" @@ -74,19 +74,19 @@ "Impossible de créer un favori vide." "L\'URL est incorrecte." "Supprimer" - "Ajouter la dernière page consultée" - "de " + "Dernière page de favori consultée" + "de" "Le favori \"%s\" sera supprimé." - "Nouvelle fenêtre" + "Ouvrir dans une nouvelle fenêtre" "Nouvelle fenêtre" - "Recherche" + "OK" "Rechercher sur la page" "Sélectionner le texte" "Vue d\'ensemble des fenêtres" - "Fenêtres" + "Windows" "Fenêtres actuelles" "Afficher" - "Nouv. fenêtre" + "Nouvelle fenêtre" "Fermer" "Favori" "Partager le lien" @@ -115,24 +115,24 @@ "Paramètres du contenu de la page" "Charger les images" "Afficher les images des pages Web" - "Bloquer les pop-up" + "Bloquer les fenêtres pop-up" "Activer JavaScript" - "Ouvrir en arrière-plan" + "Ouvrir à l\'arrière-plan" "Les nouvelles fenêtres s\'ouvrent derrière la fenêtre actuelle" "Configurer la page d\'accueil" - "Redimensionner les pages" + "Ajustement automatique des pages" "Configurer les pages Web pour qu\'elles s\'ajustent à l\'écran" "Paramètres de confidentialité" "Effacer le cache" "Supprimer tout le contenu de la page en cache" "Le cache sera effacé." - "Effacer tous les cookies" + "Effacer toutes les données de cookies" "Effacer tous les cookies du navigateur" "Tous les cookies seront effacés." "Effacer l\'historique" "Effacer l\'historique du navigateur" "L\'historique du navigateur sera effacé." - "Effacer données formulaire" + "Effacer les données du formulaire" "Effacer toutes les données de formulaire enregistrées" "Toutes les données de formulaire enregistrées seront effacées." "Effacer les mots de passe" @@ -141,9 +141,9 @@ "Paramètres de sécurité" "Mémoriser les mots de passe" "Enregistrer les noms d\'utilisateur et les mots de passe pour les sites Web" - "Mémoriser données formulaire" + "Mémoriser les données de formulaire" "Mémoriser les données saisies dans les formulaires pour les utiliser ultérieurement" - "Avertissements de sécurité" + "Afficher les avertissements de sécurité" "Afficher un avertissement en cas de problème de sécurité d\'un site" "Accepter les cookies" "Autoriser les sites à enregistrer et lire les données \"cookie\"" @@ -163,7 +163,7 @@ "Liste des plug-ins" "Aucun plug-in installé." "Applications étendant les fonctionnalités du navigateur" - "Rétablir valeurs par défaut" + "Rétablir les valeurs par défaut" "Effacer toutes les données du navigateur et rétablir les paramètres par défaut" "Toutes les données du navigateur seront effacées et les paramètres par défaut rétablis." "Rétablir les valeurs par défaut" @@ -200,7 +200,7 @@ "Problème de connectivité des données" "Problème de fichier" "Confirmer" - "La page que vous tentez d\'afficher contient des données qui ont déjà été envoyées (\"POSTDATA\"). Si vous renvoyez les données, toute action effectuée par le formulaire sur la page exécutée (notamment les lancements de recherche ou les achats en ligne) sera répétée." + "La page que vous tentez d\'afficher contient des données qui ont déjà été envoyées (\"POSTDATA\"). Si vous renvoyez les données, toute action effectuée par le formulaire sur la page exécutée (notamment les lancements de recherche ou les achats en ligne) seront répétés." "Aucune connexion réseau" "Une fois la connexion rétablie, le chargement de la page reprendra." "Effacer l\'historique" @@ -235,14 +235,13 @@ "Aucune carte SD" "Le téléchargement de %s requiert une carte SD." "Carte SD non disponible" - - + "La carte SD est occupée. Pour permettre les téléchargements, allez sur Page d\'accueil > Paramètres > Carte SD et stockage téléphone et décochez la case \"Utiliser pour le stockage USB\"." "Impossible de trouver une application permettant d\'ouvrir ce fichier." "Réessayer" "L\'historique de téléchargement est vide." "Échec du téléchargement" "Téléchargement de %s terminé." - "Téléchargement..." + "Téléchargement en cours..." "Début du téléchargement..." "En attente d\'une connexion de données..." "En attente d\'une connexion de données..." @@ -253,9 +252,9 @@ "Téléchargement interrompu. Impossible de reprendre le téléchargement." "Testeur de navigateur" "Recherche Google" - "Lecture de l\'historique du navigateur et des favoris" + "lire l\'historique du navigateur et les favoris" "Permet à l\'application de lire toutes les URL visitées par le navigateur et tous les favoris." - "Enregistrement de l\'historique du navigateur et des favoris" + "écrire l\'historique du navigateur et les favoris" "Permet à une application de modifier l\'historique du navigateur ou les favoris enregistrés sur votre téléphone. Des applications malveillantes peuvent utiliser cette fonction pour effacer ou modifier les données de votre navigateur." @@ -263,7 +262,7 @@ - + @@ -275,7 +274,7 @@ "Paramètres Google Gears" - "Lisez les règles de confidentialité du site pour voir comment votre emplacement sera utilisé." + "Lisez la politique de confidentialité du site pour voir comment votre emplacement sera utilisé." @@ -294,7 +293,7 @@ - + diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 593c4f4b..4b30d3ba 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -27,7 +27,7 @@ "Accedi" "Annulla" "OK" - " corrispondenze" + "corrispondenze" "No" "Info pagina" "Visualizza info pagina" @@ -59,23 +59,23 @@ "Avanti" "OK" "Annulla" - "URL" + "Posizione" "Nome" "http://" "Segnalibro" "Modifica segnalibro" - "Aggiungi scorciatoia Home" + "Aggiungi collegamento a Home" "Apri" "Elimina segnalibro" "Rimuovi da cronologia" "Salvato nei segnalibri." "Inserisci un nome per il segnalibro." - "Inserisci un URL per il segnalibro." + "Inserisci una posizione per il segnalibro." "Impossibile creare un segnalibro vuoto." "URL non valido." "Elimina" "Aggiungi ultima pagina visualizzata in segnalibri" - "da " + "da" "Il segnalibro \"%s\" verrà eliminato." "Apri in nuova finestra" "Nuova finestra" @@ -235,8 +235,7 @@ "Nessuna scheda SD" "Per scaricare %s occorre una scheda SD." "Scheda SD non disponibile" - - + "La scheda SD è già in uso. Per consentire i download, vai a Home > Impostazioni > Scheda SD e archiviazione telefono e deseleziona la casella \"Usa per archiviazione USB\"." "Impossibile trovare un\'applicazione in cui aprire questo file." "Riprova" "La cronologia download è vuota." @@ -247,15 +246,15 @@ "In attesa di connessione dati..." "In attesa di connessione dati..." "Download annullato." - "Impossibile effettuare il download. I contenuti non sono supportati dal telefono." + "Impossibile effettuare il download. Il contenuto non è supportato dal telefono." "Impossibile terminare il download. Spazio insufficiente." "Impossibile effettuare il download. Impossibile determinare le dimensioni dell\'elemento." "Download interrotto. Impossibile ripristinarlo." "Browser Test Runner" "Cerca su Google" - "lettura cronologia e segnalibri del browser" + "leggere cronologia e segnalibri del browser" "Consente all\'applicazione di leggere tutti gli URL visitati e tutti i segnalibri del browser." - "creazione cronologia e segnalibri del browser" + "creare cronologia e segnalibri del browser" "Consente a un\'applicazione di modificare la cronologia o i segnalibri del browser memorizzati sul telefono. Le applicazioni dannose possono sfruttare questa possibilità per cancellare o modificare i dati del browser." @@ -263,7 +262,7 @@ - + @@ -294,7 +293,7 @@ - + diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index b83cfce9..6c62bb9a 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -27,7 +27,7 @@ "ログイン" "キャンセル" "OK" - " 件一致" + "件一致" "いいえ" "ページ情報" "ページ情報を表示" @@ -75,7 +75,7 @@ "無効なURLです。" "削除" "最後に表示したページをブックマークする" - "ブックマークするページ " + "ブックマークするページ" "ブックマーク「%s」を削除します。" "新しいウィンドウで開く" "新規ウィンドウ" @@ -235,8 +235,7 @@ "SDカードがありません" "%sをダウンロードするにはSDカードが必要です。" "SDカードは利用できません" - - + "SDカードはビジーです。ダウンロードできるようにするには、[ホーム]>[設定]>[SDカードと携帯電話のメモリ]の順に選択して[USBメモリに使用]をオフにします。" "このファイルを開くアプリケーションがありません。" "やり直す" "ダウンロード履歴はありません。" @@ -263,7 +262,7 @@ - + @@ -294,7 +293,7 @@ - + diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index 90ba10a4..42db9231 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -27,7 +27,7 @@ "로그인" "취소" "확인" - " 개 일치" + "개 일치" "없음" "페이지 정보" "페이지 정보 보기" @@ -75,7 +75,7 @@ "URL이 올바르지 않습니다." "삭제" "마지막으로 본 페이지를 북마크 설정" - "북마크할 페이지 " + "북마크할 페이지" "\'%s\' 북마크가 삭제됩니다." "새 창에서 열기" "새 창" @@ -235,8 +235,7 @@ "SD 카드 없음" "%s을(를) 다운로드하려면 SD 카드가 필요합니다." "SD 카드를 사용할 수 없음" - - + "SD 카드가 사용 중입니다. 다운로드를 허용하려면 홈 > 설정 > SD 카드 및 전화기 저장공간으로 이동하여 \'USB 저장에 사용\' 확인란을 선택취소하세요." "파일을 열 수 있는 응용프로그램이 없습니다." "다시 시도" "다운로드 기록이 비어 있습니다." @@ -263,7 +262,7 @@ - + @@ -294,7 +293,7 @@ - + diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index d356f7d8..34f268e2 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -21,13 +21,13 @@ "Historie" "Lagt til bokmerker" "Fjernet fra bokmerker" - "Logg inn på %s1 \"%s2\"" + "Logg inn på %s1 \\\\\\\"%s2\\\\\\\"" "Brukernavn" "Passord" "Logg inn" "Avbryt" "OK" - " treff" + "treff" "Ingen" "Sideinformasjon" "Vis sideinformasjon" @@ -75,8 +75,8 @@ "Adressen er ikke gyldig." "Slett" "Legg til bokmerke for sist sette side" - "Gjeldende side: " - "Bokmerket \"%s\" vil bli slettet." + "Gjeldende side:" + "Bokmerket \\\\\\\"%s\\\\\\\" vil bli slettet." "Åpne i nytt vindu" "Nytt vindu" "Gå til URL" @@ -200,7 +200,7 @@ "Tilkoblingsproblem" "Problem med fil" "Bekreft" - "Siden du prøver å se, inneholder data som allerede er blitt sendt inn (\"POSTDATA\"). Hvis du sender dataene på nytt, kan det skjemaet på siden gjorde bli gjort på nytt." + "Siden du prøver å se, inneholder data som allerede er blitt sendt inn (\\\\\\\"POSTDATA\\\\\\\"). Hvis du sender dataene på nytt, kan det skjemaet på siden gjorde bli gjort på nytt." "Ingen nettverkstilkobling" "Siden vil fortsette å laste etter at tilkoblingen er blitt gjenopprettet." "Slett logg" @@ -235,8 +235,7 @@ "Mangler minnekort" "Du trenger et minnekort for å laste ned %s." "Minnekort utilgjengelig" - - + "Minnekortet er opptatt. For å tillatte nedlastinger, gå til Hjem > Innstillinger > Minnekort og telefonlagring, og fjern haken ved \\\\\\\"Bruk for USB-lagring\\\\\\\"-boksen." "Fant ingen applikasjon som kunne åpne denne filen." "Prøv igjen" "Nedlastingsloggen er tom." @@ -253,21 +252,25 @@ "Nedlastingen ble avbrutt. Den kan ikke fortsettes." "Browser Test Runner" "Søk på Google" - "read Browser\'s history and bookmarks" - "Allows the application to read all the URLs that the Browser has visited, and all of the Browser\'s bookmarks." - "write Browser\'s history and bookmarks" - "Allows an application to modify the Browser\'s history or bookmarks stored on your phone. Malicious applications can use this to erase or modify your Browser\'s data." + "read Browser\\\\\\\'s history and bookmarks" + "Allows the application to read all the URLs that the Browser has visited, and all of the Browser\\\\\\\'s bookmarks." + "write Browser\\\\\\\'s history and bookmarks" + "Allows an application to modify the Browser\\\\\\\'s history or bookmarks stored on your phone. Malicious applications can use this to erase or modify your Browser\\\\\\\'s data." - "Nettsiden under ønsker å lagre informasjon på datamaskinen ved hjelp av Gears." + + - "Nettsiden under ønsker å finne ut hvor du er ved hjelp av Gears." + + - "Denne nettsiden ønsker å lage en snarvei på datamaskinen. Ønsker du å tillate dette?" + + "Tabellen under viser rettighetent du har gitt til hver side som har prøvd å bruke Gears." - "Gears filplukker" + + "Gears-innstillinger" @@ -290,7 +293,7 @@ - + @@ -302,10 +305,14 @@ - "Aldri tillat for denne siden" - "Tillat" - "Nekt" - "Aldri tillat denne snarveien" + + + + + + + + "OK" "Avbryt" "Bruk" diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 7f45a44f..e548ea7e 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -27,7 +27,7 @@ "Aanmelden" "Annuleren" "OK" - " overeenkomsten" + "overeenkomsten" "Nee" "Pagina-informatie" "Pagina-informatie weergeven" @@ -75,7 +75,7 @@ "URL is ongeldig." "Verwijderen" "Bladwijzer maken voor de laatst weergegeven pagina" - "van " + "van" "Bladwijzer \'%s\' wordt verwijderd." "Openen in een nieuw venster" "Nieuw venster" @@ -200,7 +200,7 @@ "Probleem met gegevensverbinding" "Probleem met bestand" "Bevestigen" - "De pagina die u probeert te openen, bevat gegevens die al verzonden zijn (\'POSTDATA\'). Als u de gegevens opnieuw verzendt, wordt elke actie herhaald die het formulier op de pagina heeft uitgevoerd (zoals een zoekopdracht of online aanschaf)." + "De pagina die u probeert te openen, bevat gegevens die al verzonden zijn (\'POSTDATA\'). Als u de gegevens opnieuw verzendt, wordt elke actie herhaald die het formulier op de pagina heeft uitgevoerd (zoals een zoekopdracht of online aankoop)." "Geen netwerkverbinding" "De pagina wordt verder geladen zodra de verbinding is hersteld." "Geschiedenis wissen" @@ -235,8 +235,7 @@ "Geen SD-kaart" "Een SD-kaart is vereist om %s te kunnen downloaden." "SD-kaart niet beschikbaar" - - + "De SD-kaart is in gebruik. Als u downloads wilt toestaan, gaat u naar de spartpagina en selecteert u \'Instellingen\' > \'SD-kaart en telefoongeheugen\' en verwijdert u het vinkje uit het selectievakje \'Gebruiken voor USB-opslag\'." "Er is geen toepassing gevonden waarmee dit bestand kan worden geopend." "Opnieuw proberen" "Downloadgeschiedenis is leeg." @@ -263,7 +262,7 @@ - + @@ -294,7 +293,7 @@ - + diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 6523df1a..f113a893 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -15,7 +15,7 @@ --> - "Internet" + "Przeglądarka" "Zakładki" "Najczęściej odwiedzane" "Historia" @@ -27,13 +27,13 @@ "Zaloguj się" "Anuluj" "OK" - " dopasowania" + "dopasowania" "Nie" "Informacje o stronie" "Informacje o stronie" "Adres:" "Są problemy z certyfikatem zabezpieczeń tej strony." - "Dalej" + "Kontynuuj" "Ostrzeżenie zabezpieczeń" "Wyświetl certyfikat" "Ten certyfikat nie pochodzi od zaufanego urzędu." @@ -75,15 +75,15 @@ "Adres URL jest nieprawidłowy." "Usuń" "Dodaj do zakładek ostatnio wyświetlaną stronę" - "z " + "z" "Zakładka „%s” zostanie usunięta." "Otwórz w nowym oknie" "Nowe okno" "Idź" "Znajdź na stronie" - "Zaznacz tekst" + "Wybierz tekst" "Przegląd okien" - "Okna" + "Windows" "Bieżące okna" "Wyświetl" "Nowe okno" @@ -115,18 +115,18 @@ "Ustawienia zawartości stron" "Wczytuj obrazy" "Wyświetlaj obrazy na stronach WWW" - "Blokuj wyskakujące okna" + "Blokuj okienka wyskakujące" "Włącz skrypty JavaScript" "Otwórz w tle" - "Nowe okna są otwierane w tle" + "Nowe okna są otwierane za bieżącym" "Ustaw stronę główną" - "Autodopasowanie stron" + "Automatycznie dopasowuj strony" "Formatuj strony WWW, aby mieściły się na ekranie" "Ustawienia prywatności" "Wyczyść pamięć podręczną" "Usuń całą zawartość stron z pamięci podręcznej" "Pamięć podręczna zostanie wyczyszczona." - "Wyczyść wszystkie cookies" + "Wyczyść wszystkie dane plików cookie" "Wyczyść pliki cookie przeglądarki" "Wszystkie pliki cookie zostaną usunięte." "Wyczyść historię" @@ -141,9 +141,9 @@ "Ustawienia zabezpieczeń" "Zapamiętuj hasła" "Zapamiętuj nazwy użytkownika i hasła do stron WWW" - "Zapamiętuj wpisane dane" + "Zapamiętaj dane formularza" "Zapamiętuj do późniejszego użycia dane, które wpisuję w formularzach" - "Wyświetlaj ostrzeżenia" + "Wyświetlaj ostrzeżenia zabezpieczeń" "Wyświetl ostrzeżenie w razie problemów z zabezpieczeniami strony" "Akceptuj pliki cookie" "Zezwalaj witrynom na zapis i odczyt danych plików „cookie”." @@ -159,12 +159,12 @@ "Ustawienia zaawansowane" "Włącz technologię Gears" "Aplikacje rozszerzające zakres funkcji przeglądarki" - "Gears – ustawienia" + "Gears — ustawienia" "Lista dodatków plug-in" "Brak zainstalowanych dodatków plug-in." "Aplikacje rozszerzające zakres funkcji przeglądarki" "Przywróć wartości domyślne" - "Wyczyść wszystkie dane przeglądarki i przywróć wszystkie ustawienia domyślne" + "Wyczyść wszystkie dane przeglądarki i przywróć wszystkie ustawienia do wartości domyślnych" "Wszystkie dane przeglądarki zostaną wyczyszczone, a ustawienia powrócą do wartości domyślnych." "Przywróć wartości domyślne" "Debugowanie" @@ -209,7 +209,7 @@ "Dodaj do zakładek..." "Brak bazy danych!" "Wpisz adres WWW" - "Otwórz" + "Idź" "Uwaga" "Ta strona próbuje otworzyć okienko wyskakujące." "Zezwól" @@ -235,8 +235,7 @@ "Brak karty SD" "Do pobrania pliku %s potrzebna jest karta SD." "Karta SD jest niedostępna" - - + "Karta SD jest zajęta. Aby zezwolić na pobieranie, przejdź do Strona główna > Ustawienia > Karta SD i pamięć telefonu, a następnie usuń zaznaczenie pola wyboru „Użyj dla pamięci USB”." "Nie można znaleźć pliku do otwarcia tego programu." "Spróbuj ponownie" "Historia pobierania jest pusta." @@ -263,7 +262,7 @@ - + @@ -274,7 +273,7 @@ - "Gears – ustawienia" + "Gears — ustawienia" "Przeczytaj zasady zachowania poufności informacji witryny, aby dowiedzieć się, jak będą użyte informacje o twojej lokalizacji." @@ -294,7 +293,7 @@ - + diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 4b4b677b..01f8dc36 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -27,7 +27,7 @@ "Войти" "Отмена" "ОК" - " совпадений(я)" + "совпадений(я)" "Нет" "Сведения о странице" "Просмотреть сведения о странице" @@ -75,7 +75,7 @@ "URL недействителен." "Удаление" "Добавить в закладки последнюю просмотренную страницу" - "из " + "из" "Закладка \"%s\" будет удалена." "Открыть в новом окне" "Новое окно" @@ -235,8 +235,7 @@ "Нет карты SD" "Для загрузки файла %s нужна карта SD." "Карта SD недоступна" - - + "Карта SD занята. Чтобы разрешить загрузки, выберите Главный экран > Настройки > Карта SD > Хранилище телефона и снимите флажок \"Использовать в качестве USB-хранилища\"." "Не удалось найти приложение для открытия этого файла." "Повторить" "История загрузок пуста." @@ -263,7 +262,7 @@ - + @@ -294,7 +293,7 @@ - + diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index a55556b0..9838012b 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -27,7 +27,7 @@ "登录" "取消" "确定" - " 匹配项" + "匹配项" "否" "页面信息" "查看页面信息" @@ -75,7 +75,7 @@ "网址无效。" "删除" "将上次查看过的页面加为书签" - "来源 " + "来源" "会删除书签“%s”。" "在新窗口中打开" "新窗口" @@ -235,8 +235,7 @@ "无 SD 卡" "需要 SD 卡才能下载 %s。" "SD 卡不可用" - - + "SD 卡正忙。要允许下载,请访问“主页”>“设置”>“SD 卡和手机存储”,然后取消选中“用于 USB 存储”复选框。" "无法找到可打开此文件的应用程序。" "重试" "下载历史记录为空。" @@ -263,7 +262,7 @@ - + @@ -294,7 +293,7 @@ - + diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 3dd3ec78..7ae43552 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -27,7 +27,7 @@ "登入" "取消" "確定" - " 個符合項目" + "個符合項目" "否" "頁面資訊" "檢視頁面資訊" @@ -75,7 +75,7 @@ "網址無效。" "刪除" "最後瀏覽的書籤頁面" - "來源 " + "來源" "%s" "在新視窗開啟" "新視窗" @@ -235,8 +235,7 @@ "沒有 SD 卡" "需要 SD 卡下載 %s。" "無法使用 SD 卡" - - + "SD 卡忙碌中。若要允許下載,請前往 [首頁] > [設定] > [SD 卡和電話儲存空間],然後清除 [使用作為 USB 儲存空間] 核取方塊。" "找不到可以開啟這個檔案的應用程式。" "重試" "下載記錄是空的。" @@ -263,7 +262,7 @@ - + @@ -294,7 +293,7 @@ - + diff --git a/res/values/colors.xml b/res/values/colors.xml index f34b6404..4426ec96 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -37,6 +37,9 @@ #f1cc1d #faefb8 + #e8e8e8 + #f8f8f8 + #ff7a00 #ff0000ff diff --git a/res/values/strings.xml b/res/values/strings.xml index d6056576..78ce3060 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -527,7 +527,7 @@ - The SD card is busy. To allow downloads, select \"Turn off USB storage\" in the notification. + The SD card is busy. To allow downloads, go to Home > Settings > SD card & phone storage and clear the \"Use for USB storage\" check box. @@ -585,8 +585,6 @@ Google http://www.google.com/ - Picasa Web Albums - http://picasaweb.google.com/m/viewer?source=androidclient Yahoo! http://www.yahoo.com/ MSN diff --git a/res/xml/searchable.xml b/res/xml/searchable.xml index bb578c62..d7ef7788 100644 --- a/res/xml/searchable.xml +++ b/res/xml/searchable.xml @@ -25,7 +25,6 @@ android:searchMode="queryRewriteFromData" android:voiceSearchMode="showVoiceSearchButton|launchWebSearch" android:inputType="textUri" - android:imeOptions="actionGo" android:searchSuggestAuthority="browser" android:searchSuggestSelection="url LIKE ?" diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java index 6179da21..0ca4248e 100644 --- a/src/com/android/browser/BrowserActivity.java +++ b/src/com/android/browser/BrowserActivity.java @@ -1950,17 +1950,15 @@ public class BrowserActivity extends Activity public void run() { // Remove the AnimatingView. mContentView.removeView(view); - if (mTabOverview != null) { - // Make newIndex visible. - mTabOverview.setCurrentIndex(newIndex); - // Restore the listener. - mTabOverview.setListener(mTabListener); - // Change the menu to TAB_MENU if the - // ImageGrid is interactive. - if (mTabOverview.isLive()) { - mMenuState = R.id.TAB_MENU; - mTabOverview.requestFocus(); - } + // Make newIndex visible. + mTabOverview.setCurrentIndex(newIndex); + // Restore the listener. + mTabOverview.setListener(mTabListener); + // Change the menu to TAB_MENU if the + // ImageGrid is interactive. + if (mTabOverview.isLive()) { + mMenuState = R.id.TAB_MENU; + mTabOverview.requestFocus(); } // If a remove was requested, remove the tab. if (remove) { @@ -1978,12 +1976,10 @@ public class BrowserActivity extends Activity if (currentTab != tab) { mTabControl.setCurrentTab(currentTab); } - if (mTabOverview != null) { - mTabOverview.remove(newIndex); - // Make the current tab visible. - mTabOverview.setCurrentIndex( - mTabControl.getCurrentIndex()); - } + mTabOverview.remove(newIndex); + // Make the current tab visible. + mTabOverview.setCurrentIndex( + mTabControl.getCurrentIndex()); } } }); diff --git a/src/com/android/browser/BrowserHistoryPage.java b/src/com/android/browser/BrowserHistoryPage.java index 42ca8480..c529fe83 100644 --- a/src/com/android/browser/BrowserHistoryPage.java +++ b/src/com/android/browser/BrowserHistoryPage.java @@ -115,18 +115,11 @@ public class BrowserHistoryPage extends ExpandableListActivity { addContentView(v, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); list.setEmptyView(v); - // Do not post the runnable if there is nothing in the list. - if (list.getExpandableListAdapter().getGroupCount() > 0) { - list.post(new Runnable() { - public void run() { - // In case the history gets cleared before this event - // happens. - if (list.getExpandableListAdapter().getGroupCount() > 0) { - list.expandGroup(0); - } - } - }); - } + list.post(new Runnable() { + public void run() { + list.expandGroup(0); + } + }); mMaxTabsOpen = getIntent().getBooleanExtra("maxTabsOpen", false); CombinedBookmarkHistoryActivity.getIconListenerSet(getContentResolver()) .addListener(mIconReceiver); @@ -265,12 +258,9 @@ public class BrowserHistoryPage extends ExpandableListActivity { private class HistoryAdapter implements ExpandableListAdapter { - // Array for each of our bins. Each entry represents how many items are - // in that bin. + // Map of items. Negative values are labels, positive values + // and zero are cursor offsets. int mItemMap[]; - // This is our GroupCount. We will have at most DateSorter.DAY_COUNT - // bins, less if the user has no items in one or more bins. - int mNumberOfBins; Vector mObservers; Cursor mCursor; @@ -305,14 +295,12 @@ public class BrowserHistoryPage extends ExpandableListActivity { for (int j = 0; j < DateSorter.DAY_COUNT; j++) { array[j] = 0; } - mNumberOfBins = 0; int dateIndex = -1; if (mCursor.moveToFirst() && mCursor.getCount() > 0) { while (!mCursor.isAfterLast()) { long date = mCursor.getLong(Browser.HISTORY_PROJECTION_DATE_INDEX); int index = mDateSorter.getIndex(date); if (index > dateIndex) { - mNumberOfBins++; if (index == DateSorter.DAY_COUNT - 1) { // We are already in the last bin, so it will // include all the remaining items @@ -328,37 +316,9 @@ public class BrowserHistoryPage extends ExpandableListActivity { } mItemMap = array; } - - // This translates from a group position in the Adapter to a position in - // our array. This is necessary because some positions in the array - // have no history items, so we simply do not present those positions - // to the Adapter. - private int groupPositionToArrayPosition(int groupPosition) { - if (groupPosition < 0 || groupPosition >= DateSorter.DAY_COUNT) { - throw new AssertionError("group position out of range"); - } - if (DateSorter.DAY_COUNT == mNumberOfBins || 0 == mNumberOfBins) { - // In the first case, we have exactly the same number of bins - // as our maximum possible, so there is no need to do a - // conversion - // The second statement is in case this method gets called when - // the array is empty, in which case the provided groupPosition - // will do fine. - return groupPosition; - } - int arrayPosition = -1; - while (groupPosition > -1) { - arrayPosition++; - if (mItemMap[arrayPosition] != 0) { - groupPosition--; - } - } - return arrayPosition; - } - + public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { - groupPosition = groupPositionToArrayPosition(groupPosition); HistoryItem item; if (null == convertView || !(convertView instanceof HistoryItem)) { item = new HistoryItem(BrowserHistoryPage.this); @@ -387,7 +347,6 @@ public class BrowserHistoryPage extends ExpandableListActivity { } public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { - groupPosition = groupPositionToArrayPosition(groupPosition); TextView item; if (null == convertView || !(convertView instanceof TextView)) { LayoutInflater factory = @@ -410,11 +369,11 @@ public class BrowserHistoryPage extends ExpandableListActivity { } public int getGroupCount() { - return mNumberOfBins; + return DateSorter.DAY_COUNT; } public int getChildrenCount(int groupPosition) { - return mItemMap[groupPositionToArrayPosition(groupPosition)]; + return mItemMap[groupPosition]; } public Object getGroup(int groupPosition) { diff --git a/src/com/android/browser/BrowserHomepagePreference.java b/src/com/android/browser/BrowserHomepagePreference.java index d4708c30..bc211433 100644 --- a/src/com/android/browser/BrowserHomepagePreference.java +++ b/src/com/android/browser/BrowserHomepagePreference.java @@ -48,10 +48,8 @@ public class BrowserHomepagePreference extends EditTextPreference implements AlertDialog dialog = (AlertDialog) getDialog(); // This callback is called before the dialog has been fully constructed if (dialog != null) { - String url = s.toString(); dialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled( - url.length() == 0 || url.equals("about:blank") || - Regex.WEB_URL_PATTERN.matcher(url).matches()); + Regex.WEB_URL_PATTERN.matcher(s.toString()).matches()); } } diff --git a/src/com/android/browser/BrowserPreferencesPage.java b/src/com/android/browser/BrowserPreferencesPage.java index 5d6795ba..b23f750b 100644 --- a/src/com/android/browser/BrowserPreferencesPage.java +++ b/src/com/android/browser/BrowserPreferencesPage.java @@ -83,7 +83,8 @@ public class BrowserPreferencesPage extends PreferenceActivity if (needUpdate) { value = value.trim().replace(" ", "%20"); } - if (value.length() != 0 && Uri.parse(value).getScheme() == null) { + Uri path = Uri.parse(value); + if (path.getScheme() == null) { value = "http://" + value; needUpdate = true; } diff --git a/src/com/android/browser/FindDialog.java b/src/com/android/browser/FindDialog.java index 43cd1c40..44109ffe 100644 --- a/src/com/android/browser/FindDialog.java +++ b/src/com/android/browser/FindDialog.java @@ -17,7 +17,6 @@ package com.android.browser; import android.app.Dialog; -import android.content.Context; import android.content.res.Configuration; import android.os.Bundle; import android.os.Handler; @@ -31,7 +30,6 @@ import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; -import android.view.inputmethod.InputMethodManager; import android.webkit.WebView; import android.widget.EditText; import android.widget.TextView; @@ -68,19 +66,9 @@ import android.widget.TextView; throw new AssertionError("No WebView for FindDialog::onClick"); } mWebView.findNext(false); - hideSoftInput(); } }; - - /* - * Remove the soft keyboard from the screen. - */ - private void hideSoftInput() { - InputMethodManager imm = (InputMethodManager) - mBrowserActivity.getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0); - } - + private void disableButtons() { mPrevButton.setEnabled(false); mNextButton.setEnabled(false); @@ -169,9 +157,8 @@ import android.widget.TextView; throw new AssertionError("No WebView for FindDialog::findNext"); } mWebView.findNext(true); - hideSoftInput(); } - + public void show() { super.show(); mEditText.requestFocus(); diff --git a/src/com/android/browser/GearsFilePickerDialog.java b/src/com/android/browser/GearsFilePickerDialog.java new file mode 100644 index 00000000..10cc03f3 --- /dev/null +++ b/src/com/android/browser/GearsFilePickerDialog.java @@ -0,0 +1,930 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * 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 com.android.browser; + +import android.app.Activity; +import android.content.Context; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.net.Uri; +import android.os.Environment; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.provider.MediaStore; +import android.provider.MediaStore.Images.Media; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.BaseAdapter; +import android.widget.GridView; +import android.widget.ImageView; +import android.widget.TextView; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Vector; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Gears FilePicker dialog + */ +class GearsFilePickerDialog extends GearsBaseDialog + implements View.OnTouchListener { + + private static final String TAG = "Gears FilePicker"; + private static Bitmap mDirectoryIcon; + private static Bitmap mDefaultIcon; + private static Bitmap mImageIcon; + private static Bitmap mBackIcon; + + private static String MULTIPLE_FILES = "MULTIPLE_FILES"; + private static String SINGLE_FILE = "SINGLE_FILE"; + + private static ImagesLoad mImagesLoader; + private static SystemThumbnails mSystemThumbnails; + private FilePickerAdapter mAdapter; + private String mSelectionMode; + private boolean mMultipleSelection; + private String mCurrentPath; + + // Disable saving thumbnails until this is refactored to fit into + // existing schemes. + private static final boolean enableSavedThumbnails = false; + + public GearsFilePickerDialog(Activity activity, + Handler handler, + String arguments) { + super (activity, handler, arguments); + mAdapter = new FilePickerAdapter(activity); + parseArguments(); + } + + public void parseArguments() { + mSelectionMode = MULTIPLE_FILES; + try { + JSONObject json = new JSONObject(mDialogArguments); + + if (json.has("mode")) { + mSelectionMode = json.getString("mode"); + } + } catch (JSONException e) { + Log.e(TAG, "exc: " + e); + } + if (mSelectionMode.equalsIgnoreCase(SINGLE_FILE)) { + mMultipleSelection = false; + } else { + mMultipleSelection = true; + } + } + + public void setup() { + inflate(R.layout.gears_dialog_filepicker, R.id.panel_content); + setupButtons(0, + R.string.filepicker_button_allow, + R.string.filepicker_button_deny); + setupDialog(); + + TextView textViewPath = (TextView) findViewById(R.id.path_name); + if (textViewPath != null) { + textViewPath.setText(R.string.filepicker_path); + } + + GridView view = (GridView) findViewById(R.id.files_list); + view.setAdapter(mAdapter); + view.setOnTouchListener(this); + + showView(null, R.id.selection); + setSelectionText(); + + mImagesLoader = new ImagesLoad(mAdapter); + mImagesLoader.setAdapterView(view); + Thread imagesLoaderThread = new Thread(mImagesLoader); + imagesLoaderThread.setPriority(Thread.MIN_PRIORITY); + imagesLoaderThread.start(); + + mSystemThumbnails = new SystemThumbnails(); + Thread systemThumbnailsThread = new Thread(mSystemThumbnails); + systemThumbnailsThread.setPriority(Thread.MIN_PRIORITY); + systemThumbnailsThread.start(); + } + + public void setSelectionText() { + Vector elements = mAdapter.selectedElements(); + if (elements == null) + return; + TextView info = (TextView) findViewById(R.id.selection); + int nbElements = elements.size(); + if (nbElements == 0) { + info.setText(R.string.filepicker_no_files_selected); + } else if (nbElements == 1) { + info.setText(R.string.filepicker_one_file_selected); + } else { + info.setText(nbElements + " " + + mActivity.getString( + R.string.filepicker_some_files_selected)); + } + } + + public void setCurrentPath(String path) { + if (path != null) { + mCurrentPath = path; + TextView textViewPath = (TextView) findViewById(R.id.current_path); + if (textViewPath != null) { + textViewPath.setText(path); + } + } + } + + public void setupDialog(TextView message, ImageView icon) { + message.setText(R.string.filepicker_message); + message.setTextSize(24); + icon.setImageResource(R.drawable.ic_dialog_menu_generic); + } + + public boolean onTouch(View v, MotionEvent event) { + mImagesLoader.pauseIconRequest(); + return false; + } + + /** + * Utility class encapsulating thumbnails information + * for a file (file image id and magic number) + */ + class SystemThumbnailInfo { + private long mID; + private long mMagicNumber; + SystemThumbnailInfo(long anID, long magicNumber) { + mID = anID; + mMagicNumber = magicNumber; + } + public long getID() { + return mID; + } + public long getMagicNumber() { + return mMagicNumber; + } + } + + /** + * Utility class to pre-fetch the thumbnails information + */ + class SystemThumbnails implements Runnable { + private Map mThumbnails; + + SystemThumbnails() { + mThumbnails = Collections.synchronizedMap(new HashMap()); + } + + public void run() { + Uri query = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + Cursor cursor = mActivity.managedQuery(query, + new String[] { "_id", "mini_thumb_magic", "_data" }, + null, null, null); + + if (cursor != null) { + int count = cursor.getCount(); + for (int i = 0; i < count; i++) { + cursor.moveToPosition(i); + SystemThumbnailInfo info = new SystemThumbnailInfo(cursor.getLong(0), + cursor.getLong(1)); + mThumbnails.put(cursor.getString(2), info); + } + } + } + + public SystemThumbnailInfo getThumb(String path) { + SystemThumbnailInfo ret = mThumbnails.get(path); + if (ret == null) { + Uri query = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + Cursor cursor = mActivity.managedQuery(query, + new String[] { "_id", "mini_thumb_magic", "_data" }, + "_data = ?", new String[] { path }, null); + if (cursor != null && cursor.moveToFirst()) { + long longid = cursor.getLong(0); + long miniThumbMagic = cursor.getLong(1); + ret = new SystemThumbnailInfo(longid, miniThumbMagic); + mThumbnails.put(path, ret); + } + } + return ret; + } + } + + /** + * Utility class to load and generate thumbnails + * for image files + */ + class ImagesLoad implements Runnable { + private Vector mImagesPath; + private BaseAdapter mAdapter; + private AdapterView mAdapterView; + private Vector mElements; + private Handler mLoaderHandler; + // We use the same value as in Camera.app's ImageManager.java + private static final int BYTES_PER_MINI_THUMB = 10000; + private final byte[] mMiniThumbData = new byte[BYTES_PER_MINI_THUMB]; + private final int MINI_THUMB_DATA_FILE_VERSION = 3; + private final int THUMBNAIL_SIZE = 128; + private Map mThumbFiles; + + ImagesLoad(BaseAdapter adapter) { + mAdapter = adapter; + mThumbFiles = Collections.synchronizedMap(new HashMap()); + } + + public void signalChanges() { + Message message = mHandler.obtainMessage(GearsBaseDialog.NEW_ICON, + mAdapter); + mHandler.sendMessage(message); + } + + private String getMiniThumbFileFromUri(Uri uri) { + if (uri == null) { + return null; + } + String directoryName = + Environment.getExternalStorageDirectory().toString() + + "/dcim/.thumbnails"; + String path = directoryName + "/.thumbdata" + + MINI_THUMB_DATA_FILE_VERSION + "-" + uri.hashCode(); + return path; + } + + private Bitmap getMiniThumbFor(Uri uri, long longid, long magic) { + RandomAccessFile thumbFile = mThumbFiles.get(uri); + try { + if (thumbFile == null) { + String path = getMiniThumbFileFromUri(uri); + File f = new File(path); + if (f.exists()) { + thumbFile = new RandomAccessFile(f, "rw"); + mThumbFiles.put(uri, thumbFile); + } + } + } catch (IOException ex) { + } + if (thumbFile == null) { + return null; + } + byte[] data = getMiniThumbFromFile(thumbFile, longid, + mMiniThumbData, magic); + if (data != null) { + return BitmapFactory.decodeByteArray(data, 0, data.length); + } + return null; + } + + private byte [] getMiniThumbFromFile(RandomAccessFile r, + long id, + byte [] data, + long magicCheck) { + if (r == null) + return null; + long pos = id * BYTES_PER_MINI_THUMB; + RandomAccessFile f = r; + synchronized (f) { + try { + f.seek(pos); + if (f.readByte() == 1) { + long magic = f.readLong(); + if (magic != magicCheck) { + return null; + } + int length = f.readInt(); + f.read(data, 0, length); + return data; + } else { + return null; + } + } catch (IOException ex) { + long fileLength; + try { + fileLength = f.length(); + } catch (IOException ex1) { + fileLength = -1; + } + return null; + } + } + } + + /* + * Returns a thumbnail saved by the Camera application + * We pre-cached the information (image id and magic number) + * when starting the filepicker. + */ + public Bitmap getSystemThumbnail(FilePickerElement elem) { + if (elem.askedForSystemThumbnail() == false) { + elem.setAskedForSystemThumbnail(true); + String path = elem.getPath(); + SystemThumbnailInfo thumbInfo = mSystemThumbnails.getThumb(path); + if (thumbInfo != null) { + Uri query = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + Bitmap bmp = getMiniThumbFor(query, thumbInfo.getID(), + thumbInfo.getMagicNumber()); + if (bmp != null) { + return bmp; + } + } + } + return null; + } + + /* + * Generate a thumbnail for a given element + */ + public Bitmap generateImage(FilePickerElement elem) { + String path = elem.getPath(); + Bitmap finalImage = null; + try { + + // First we try to get the thumbnail from the system + // (created by the Camera application) + + finalImage = getSystemThumbnail(elem); + if (finalImage != null) { + return finalImage; + } + + // No thumbnail was found, so we have to create one + // + // First we get the image information and + // determine the sampleSize + + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inJustDecodeBounds = true; + BitmapFactory.decodeFile(path, options); + + int width = options.outWidth; + int height = options.outHeight; + int sampleSize = 1; + if (width > THUMBNAIL_SIZE || height > THUMBNAIL_SIZE) { + sampleSize = 2; + while ((width / sampleSize > 2*THUMBNAIL_SIZE) + || (height / sampleSize > 2*THUMBNAIL_SIZE)) { + sampleSize += 2; + } + } + options.inJustDecodeBounds = false; + options.inSampleSize = sampleSize; + Bitmap originalImage = BitmapFactory.decodeFile(path, options); + if (originalImage == null) { + return null; + } + + // Let's rescale the image to a THUMBNAIL_SIZE + + width = originalImage.getWidth(); + height = originalImage.getHeight(); + + if (width > height) { + width = (int) (width * (THUMBNAIL_SIZE / (double) height)); + height = THUMBNAIL_SIZE; + } else { + height = (int) (height * (THUMBNAIL_SIZE / (double) width)); + width = THUMBNAIL_SIZE; + } + originalImage = Bitmap.createScaledBitmap(originalImage, + width, height, true); + + // We can now crop the image to a THUMBNAIL_SIZE rectangle + + width = originalImage.getWidth(); + height = originalImage.getHeight(); + int d = 0; + if (width > height) { + d = (width - height) / 2; + finalImage = Bitmap.createBitmap(originalImage, d, 0, + THUMBNAIL_SIZE, THUMBNAIL_SIZE); + } else { + d = (height - width) / 2; + finalImage = Bitmap.createBitmap(originalImage, 0, d, + THUMBNAIL_SIZE, THUMBNAIL_SIZE); + } + + originalImage.recycle(); + } catch (java.lang.OutOfMemoryError e) { + Log.e(TAG, "Intercepted OOM ", e); + } + return finalImage; + } + + public void pauseIconRequest() { + Message message = Message.obtain(mLoaderHandler, + GearsBaseDialog.PAUSE_REQUEST_ICON); + mLoaderHandler.sendMessageAtFrontOfQueue(message); + } + + public void clearIconRequests() { + Message message = Message.obtain(mLoaderHandler, + GearsBaseDialog.CLEAR_REQUEST_ICON); + mLoaderHandler.sendMessageAtFrontOfQueue(message); + } + + public void postIconRequest(FilePickerElement item, + int position, + boolean front) { + if (item == null) { + return; + } + if (item.isImage() && (item.getThumbnail() == null)) { + Message message = mLoaderHandler.obtainMessage( + GearsBaseDialog.REQUEST_ICON, position, 0, item); + if (front) { + mLoaderHandler.sendMessageAtFrontOfQueue(message); + } else { + mLoaderHandler.sendMessage(message); + } + } + } + + public boolean generateIcon(FilePickerElement elem) { + if (elem.isImage()) { + if (elem.getThumbnail() == null) { + Bitmap image = generateImage(elem); + if (image != null) { + elem.setThumbnail(image); + return true; + } + } + } + return false; + } + + public void setAdapterView(AdapterView view) { + mAdapterView = view; + } + + public void run() { + Looper.prepare(); + mLoaderHandler = new Handler() { + public void handleMessage(Message msg) { + if (msg.what == GearsBaseDialog.CLEAR_REQUEST_ICON) { + mLoaderHandler.removeMessages( + GearsBaseDialog.PAUSE_REQUEST_ICON); + mLoaderHandler.removeMessages( + GearsBaseDialog.REQUEST_ICON); + } else if (msg.what == GearsBaseDialog.PAUSE_REQUEST_ICON) { + try { + // We are busy (likely) scrolling the view, + // so we just pause the loading. + Thread.sleep(1000); + mLoaderHandler.removeMessages( + GearsBaseDialog.PAUSE_REQUEST_ICON); + } catch (InterruptedException e) { + Log.e(TAG, "InterruptedException ", e); + } + } else if (msg.what == GearsBaseDialog.REQUEST_ICON) { + FilePickerElement elem = (FilePickerElement) msg.obj; + if (generateIcon(elem)) { + signalChanges(); + } + try { + Thread.sleep(50); + } catch (InterruptedException e) { + Log.e(TAG, "InterruptedException ", e); + } + } + } + }; + Looper.loop(); + } + } + + /** + * Utility class representing an element displayed in the + * file picker, associated with an icon and/or thumbnail + */ + class FilePickerElement { + private File mPath; + private String mName; + private Bitmap mIcon; + private boolean mIsSelected; + private Vector mChildren; + private FilePickerElement mParent; + private boolean mIsParent; + private BaseAdapter mAdapter; + private String mExtension; + private Bitmap mThumbnail; + private boolean mIsImage; + private boolean mAskedForSystemThumbnail; + + public FilePickerElement(String name, BaseAdapter adapter) { + this(name, adapter, null); + } + + public FilePickerElement(String path, String name, BaseAdapter adapter) { + this(path, name, adapter, null); + } + + public FilePickerElement(String name, + BaseAdapter adapter, + FilePickerElement parent) { + mName = name; + mAdapter = adapter; + mParent = parent; + mIsSelected = false; + mChildren = null; + mAskedForSystemThumbnail = false; + } + + public FilePickerElement(String path, + String name, + BaseAdapter adapter, + FilePickerElement parent) { + mPath = new File(path); + mName = name; + mIsSelected = false; + mChildren = null; + mParent = parent; + mAdapter = adapter; + mExtension = null; + mAskedForSystemThumbnail = false; + + setIcons(); + } + + public void setAskedForSystemThumbnail(boolean value) { + mAskedForSystemThumbnail = value; + } + + public boolean askedForSystemThumbnail() { + return mAskedForSystemThumbnail; + } + + public void setIcons() { + if (mPath.isDirectory()) { + if (mDirectoryIcon == null) { + mDirectoryIcon = BitmapFactory.decodeResource( + getResources(), R.drawable.gears_folder); + } + mIcon = mDirectoryIcon; + + } else { + if (isImage()) { + if (mImageIcon == null) { + mImageIcon = BitmapFactory.decodeResource( + getResources(), R.drawable.gears_file_image); + } + mIcon = mImageIcon; + } else if (isAudio()) { + mIcon = BitmapFactory.decodeResource( + getResources(), R.drawable.gears_file_audio); + } else if (isVideo()) { + mIcon = BitmapFactory.decodeResource( + getResources(), R.drawable.gears_file_video); + } else { + if (mDefaultIcon == null) { + mDefaultIcon = BitmapFactory.decodeResource( + getResources(), R.drawable.gears_file_unknown); + } + mIcon = mDefaultIcon; + } + } + if (mBackIcon == null) { + mBackIcon = BitmapFactory.decodeResource(getResources(), + com.android.internal.R.drawable.ic_menu_back); + } + } + + public boolean isImage() { + if (mIsImage) return mIsImage; + String extension = getExtension(); + if (extension != null) { + if (extension.equalsIgnoreCase("jpg") || + extension.equalsIgnoreCase("jpeg") || + extension.equalsIgnoreCase("png") || + extension.equalsIgnoreCase("gif")) { + mIsImage = true; + return true; + } + } + return false; + } + + public boolean isAudio() { + String extension = getExtension(); + if (extension != null) { + if (extension.equalsIgnoreCase("mp3") || + extension.equalsIgnoreCase("wav") || + extension.equalsIgnoreCase("aac")) { + return true; + } + } + return false; + } + + public boolean isVideo() { + String extension = getExtension(); + if (extension != null) { + if (extension.equalsIgnoreCase("mpg") || + extension.equalsIgnoreCase("mpeg") || + extension.equalsIgnoreCase("mpe") || + extension.equalsIgnoreCase("divx") || + extension.equalsIgnoreCase("3gpp") || + extension.equalsIgnoreCase("avi")) { + return true; + } + } + return false; + } + + public void setParent(boolean isParent) { + mIsParent = isParent; + } + + public boolean isDirectory() { + return mPath.isDirectory(); + } + + public String getExtension() { + if (isDirectory()) { + return null; + } + if (mExtension == null) { + String path = getPath(); + int index = path.lastIndexOf("."); + if ((index != -1) && (index != path.length() - 1)){ + // if we find a dot that is not the last character + mExtension = path.substring(index+1); + return mExtension; + } + } + return mExtension; + } + + public void refresh() { + mChildren = null; + Vector children = getChildren(); + mImagesLoader.clearIconRequests(); + } + + public Vector getChildren() { + if (isDirectory()) { + if (mChildren == null) { + mChildren = new Vector(); + File[] files = mPath.listFiles(); + if (mParent != null) { + mChildren.add(mParent); + mParent.setParent(true); + } + for (int i = 0; i < files.length; i++) { + String name = files[i].getName(); + String fpath = files[i].getPath(); + if (!name.startsWith(".")) { // hide dotfiles + FilePickerElement elem = new FilePickerElement(fpath, name, + mAdapter, this); + elem.setParent(false); + mChildren.add(elem); + } + } + } + } + return mChildren; + } + + public FilePickerElement getChild(int position) { + Vector children = getChildren(); + if (children != null) { + FilePickerElement elem = (FilePickerElement) children.get(position); + return elem; + } + return null; + } + + /* + * Depending on the type, we return either + * the icon (mIcon) or the back icon (mBackIcon). + * If we can load a system thumbnail we do this + * synchronously and return it, else we ask the + * mImagesLoader to generate a thumbnail for us. + */ + public Bitmap getIcon(int position) { + if (mIsParent) { + return mBackIcon; + } + if (isImage()) { + if (mThumbnail != null) { + return mThumbnail; + } else { + Bitmap image = mImagesLoader.getSystemThumbnail(this); + if (image != null) { + mThumbnail = image; + return mThumbnail; + } + mImagesLoader.postIconRequest(this, position, true); + } + } + return mIcon; + } + + public Bitmap getThumbnail() { + return mThumbnail; + } + + public void setThumbnail(Bitmap icon) { + mThumbnail = icon; + } + + public String getName() { + return mName; + } + + public String getPath() { + return mPath.getPath(); + } + + public void toggleSelection() { + mIsSelected = !mIsSelected; + } + + public boolean isSelected() { + return mIsSelected; + } + + } + + /** + * Adapter for the GridView + */ + class FilePickerAdapter extends BaseAdapter { + private Context mContext; + private Map mImagesMap; + private Map mImagesSelected; + + private Vector mImages; + private Vector mFiles; + + private FilePickerElement mRootElement; + private FilePickerElement mCurrentElement; + + public FilePickerAdapter(Context context) { + mContext = context; + mImages = new Vector(); + mFiles = new Vector(); + + mImagesMap = Collections.synchronizedMap(new HashMap()); + mImagesSelected = new HashMap(); + + String startingPath = Environment.getExternalStorageDirectory().getPath(); + mRootElement = new FilePickerElement(startingPath, "SD Card", this); + mCurrentElement = mRootElement; + } + + public void addImage(String path) { + mImages.add(path); + Bitmap image = BitmapFactory.decodeResource( + getResources(), R.drawable.gears_file_unknown); + mImagesMap.put(path, image); + mImagesSelected.put(path, Boolean.FALSE); + } + + public int getCount() { + Vector elems = mCurrentElement.getChildren(); + setCurrentPath(mCurrentElement.getPath()); + return elems.size(); + } + + public Object getItem(int position) { + return position; + } + + public long getItemId(int position) { + return position; + } + + public Vector selectedElements() { + if (mCurrentElement == null) { + return null; + } + Vector children = mCurrentElement.getChildren(); + Vector ret = new Vector(); + for (int i = 0; i < children.size(); i++) { + FilePickerElement elem = (FilePickerElement) children.get(i); + if (elem.isSelected()) { + ret.add(elem); + } + } + return ret; + } + + public View getView(int position, View convertView, ViewGroup parent) { + View cell = convertView; + if (cell == null) { + LayoutInflater inflater = (LayoutInflater) getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + cell = inflater.inflate(R.layout.gears_dialog_filepicker_cell, null); + } + ImageView imageView = (ImageView) cell.findViewById(R.id.icon); + TextView textView = (TextView) cell.findViewById(R.id.name); + FilePickerElement elem = mCurrentElement.getChild(position); + if (elem == null) { + String message = "Could not get elem " + position; + message += " for " + mCurrentElement.getPath(); + Log.e(TAG, message); + return null; + } + String path = elem.getPath(); + textView.setText(elem.getName()); + + View.OnClickListener listener = new View.OnClickListener() { + public void onClick(View view) { + int pos = (Integer) view.getTag(); + FilePickerElement elem = mCurrentElement.getChild(pos); + if (elem.isDirectory()) { + mCurrentElement = elem; + mCurrentElement.refresh(); + } else { + if (mMultipleSelection) { + elem.toggleSelection(); + } else { + Vector elems = selectedElements(); + if (elems != null) { + if (elems.size() == 0) { + elem.toggleSelection(); + } else if ((elems.size() == 1) + && elem.isSelected()) { + elem.toggleSelection(); + } + } + } + } + setSelectionText(); + notifyDataSetChanged(); + } + }; + cell.setLayoutParams(new GridView.LayoutParams(96, 96)); + cell.setOnClickListener(listener); + cell.setOnTouchListener(new View.OnTouchListener() { + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + int color = getResources().getColor(R.color.icon_selection); + v.setBackgroundColor(color); + } else { + v.setBackgroundColor(android.R.color.background_dark); + } + return false; + } + }); + + cell.setTag(position); + + if (elem.isSelected()) { + int color = getResources().getColor(R.color.icon_selection); + cell.setBackgroundColor(color); + } else { + cell.setBackgroundColor(android.R.color.background_dark); + } + Bitmap bmp = elem.getIcon(position); + if (bmp != null) { + imageView.setImageBitmap(bmp); + } + + return cell; + } + } + + private String selectedFiles() { + Vector selection = mAdapter.selectedElements(); + JSONArray jsonSelection = new JSONArray(); + if (selection != null) { + for (int i = 0; i < selection.size(); i++) { + FilePickerElement elem = (FilePickerElement) selection.get(i); + jsonSelection.put(elem.getPath()); + } + } + return jsonSelection.toString(); + } + + public String closeDialog(int closingType) { + return selectedFiles(); + } +} diff --git a/src/com/android/browser/GearsNativeDialog.java b/src/com/android/browser/GearsNativeDialog.java index ecf166df..c72ad8ea 100644 --- a/src/com/android/browser/GearsNativeDialog.java +++ b/src/com/android/browser/GearsNativeDialog.java @@ -36,6 +36,8 @@ import android.webkit.gears.NativeDialog; import com.android.browser.GearsBaseDialog; import com.android.browser.GearsPermissionsDialog; import com.android.browser.GearsSettingsDialog; +import com.android.browser.GearsShortcutDialog; +import com.android.browser.GearsFilePickerDialog; /** * Native dialog Activity used by gears @@ -55,12 +57,16 @@ public class GearsNativeDialog extends Activity { private int mDialogType; private final int SETTINGS_DIALOG = 1; private final int PERMISSION_DIALOG = 2; - private final int LOCATION_DIALOG = 3; + private final int SHORTCUT_DIALOG = 3; + private final int LOCATION_DIALOG = 4; + private final int FILEPICKER_DIALOG = 5; private final String VERSION_STRING = "version"; private final String SETTINGS_DIALOG_STRING = "settings_dialog"; private final String PERMISSION_DIALOG_STRING = "permissions_dialog"; + private final String SHORTCUT_DIALOG_STRING = "shortcuts_dialog"; private final String LOCATION_DIALOG_STRING = "locations_dialog"; + private final String FILEPICKER_DIALOG_STRING = "filepicker_dialog"; private boolean mDialogDismissed = false; @@ -105,9 +111,15 @@ public class GearsNativeDialog extends Activity { case PERMISSION_DIALOG: dialog = new GearsPermissionsDialog(this, mHandler, mDialogArguments); break; + case SHORTCUT_DIALOG: + dialog = new GearsShortcutDialog(this, mHandler, mDialogArguments); + break; case LOCATION_DIALOG: dialog = new GearsPermissionsDialog(this, mHandler, mDialogArguments); break; + case FILEPICKER_DIALOG: + dialog = new GearsFilePickerDialog(this, mHandler, mDialogArguments); + break; default: dialog = new GearsBaseDialog(this, mHandler, mDialogArguments); } @@ -124,7 +136,7 @@ public class GearsNativeDialog extends Activity { */ private void getArguments() { if (mDebug) { - mDialogType = LOCATION_DIALOG +1; + mDialogType = FILEPICKER_DIALOG +1; mockArguments(); return; @@ -146,8 +158,12 @@ public class GearsNativeDialog extends Activity { mGearsVersion = intent.getStringExtra(VERSION_STRING); } else if (dialogTypeString.equalsIgnoreCase(PERMISSION_DIALOG_STRING)) { mDialogType = PERMISSION_DIALOG; + } else if (dialogTypeString.equalsIgnoreCase(SHORTCUT_DIALOG_STRING)) { + mDialogType = SHORTCUT_DIALOG; } else if (dialogTypeString.equalsIgnoreCase(LOCATION_DIALOG_STRING)) { mDialogType = LOCATION_DIALOG; + } else if (dialogTypeString.equalsIgnoreCase(FILEPICKER_DIALOG_STRING)) { + mDialogType = FILEPICKER_DIALOG; } } @@ -157,6 +173,17 @@ public class GearsNativeDialog extends Activity { * Set mock arguments. */ private void mockArguments() { + String argumentsShortcuts = "{ locale: \"en-US\"," + + "name: \"My Application\", link: \"http://www.google.com/\"," + + "description: \"This application does things does things!\"," + + "icon16x16: \"http://google-gears.googlecode.com/" + + "svn/trunk/gears/test/manual/shortcuts/16.png\"," + + "icon32x32: \"http://google-gears.googlecode.com/" + + "svn/trunk/gears/test/manual/shortcuts/32.png\"," + + "icon48x48: \"http://google-gears.googlecode.com/" + + "svn/trunk/gears/test/manual/shortcuts/48.png\"," + + "icon128x128: \"http://google-gears.googlecode.com/" + + "svn/trunk/gears/test/manual/shortcuts/128.png\"}"; String argumentsPermissions = "{ locale: \"en-US\", " + "origin: \"http://www.google.com\", dialogType: \"localData\"," @@ -188,7 +215,16 @@ public class GearsNativeDialog extends Activity { + "localStorage: { permissionState: 2 }, " + "locationData: { permissionState: 2 } } ] }"; + String argumentsFilePicker = "{ \"cameraMode\" : \"OFF\", \"filters\"" + + ": [ \"text/html\", \".txt\" ], \"mode\" : \"MULTIPLE_FILES\" }\""; + + String argumentsFilePicker2 = "{ \"cameraMode\" : \"OFF\", \"filters\"" + + ": [ \"text/html\", \".txt\" ], \"mode\" : \"SINGLE_FILE\" }\""; + switch (mDialogType) { + case SHORTCUT_DIALOG: + mDialogArguments = argumentsShortcuts; + break; case PERMISSION_DIALOG: mDialogArguments = argumentsPermissions; break; @@ -198,6 +234,8 @@ public class GearsNativeDialog extends Activity { case SETTINGS_DIALOG: mDialogArguments = argumentsSettings; break; + case FILEPICKER_DIALOG: + mDialogArguments = argumentsFilePicker2; } } diff --git a/src/com/android/browser/GearsShortcutDialog.java b/src/com/android/browser/GearsShortcutDialog.java new file mode 100644 index 00000000..11d936d7 --- /dev/null +++ b/src/com/android/browser/GearsShortcutDialog.java @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * 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 com.android.browser; + +import android.app.Activity; +import android.os.Handler; +import android.util.Log; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Gears Shortcut dialog + */ +class GearsShortcutDialog extends GearsBaseDialog { + + private static final String TAG = "GearsPermissionsDialog"; + + private final String ICON_16 = "icon16x16"; + private final String ICON_32 = "icon32x32"; + private final String ICON_48 = "icon48x48"; + private final String ICON_128 = "icon128x128"; + private int mNotification = 0; + + public GearsShortcutDialog(Activity activity, + Handler handler, + String arguments) { + super (activity, handler, arguments); + } + + public void setup() { + inflate(R.layout.gears_dialog_shortcut, R.id.panel_content); + setupButtons(R.string.shortcut_button_alwaysdeny, + R.string.shortcut_button_allow, + R.string.shortcut_button_deny); + + try { + JSONObject json = new JSONObject(mDialogArguments); + + String iconUrl = pickIconToRender(json); + if (iconUrl != null) { + downloadIcon(iconUrl); + } + + setupDialog(); + + setLabel(json, "name", R.id.shortcut_name); + setLabel(json, "link", R.id.origin_subtitle); + setLabel(json, "description", R.id.origin_message); + } catch (JSONException e) { + Log.e(TAG, "JSON exception", e); + } + + TextView msg = (TextView) findViewById(R.id.permission_dialog_message); + msg.setText(R.string.shortcut_message); + + View shortcutIcon = findViewById(R.id.shortcut_panel); + if (shortcutIcon != null) { + shortcutIcon.setVisibility(View.VISIBLE); + } + } + + public void setupDialog(TextView message, ImageView icon) { + message.setText(R.string.shortcut_prompt); + icon.setImageResource(R.drawable.ic_dialog_menu_generic); + } + + /** + * Utility method to validate an icon url. Used in the + * shortcut dialog. + */ + boolean validIcon(JSONObject json, String name) { + try { + if (json.has(name)) { + String str = json.getString(name); + if (str.length() > 0) { + return true; + } + } + } catch (JSONException e) { + Log.e(TAG, "JSON exception", e); + } + return false; + } + + + /** + * Utility method to pick the best indicated icon + * from the dialogs' arguments. Used in the + * shortcut dialog. + */ + String pickIconToRender(JSONObject json) { + try { + if (validIcon(json, ICON_48)) { // ideal size + mChoosenIconSize = 48; + return json.getString(ICON_48); + } else if (validIcon(json, ICON_32)) { + mChoosenIconSize = 32; + return json.getString(ICON_32); + } else if (validIcon(json, ICON_128)) { + mChoosenIconSize = 128; + return json.getString(ICON_128); + } else if (validIcon(json, ICON_16)) { + mChoosenIconSize = 16; + return json.getString(ICON_16); + } + } catch (JSONException e) { + Log.e(TAG, "JSON exception", e); + } + mChoosenIconSize = 0; + return null; + } + + public String closeDialog(int closingType) { + String ret = null; + switch (closingType) { + case ALWAYS_DENY: + ret = "{\"allow\": false, \"permanently\": true }"; + break; + case ALLOW: + ret = "{\"allow\": true, \"locations\": 0 }"; + mNotification = R.string.shortcut_notification; + break; + case DENY: + ret = null; + break; + } + return ret; + } + + public int notification() { + return mNotification; + } +} -- cgit v1.2.3