From: jabarros Date: Thu, 2 Oct 2014 07:04:11 +0000 (+0200) Subject: Merge branch 'develop' into release-1.6.0 X-Git-Tag: oc-android-1.7.0_signed~15^2~28 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/2e472998c16e504c0c2ceddf7de52a000d7bd7f8?hp=ba798ccda231d4b9354dd7ffc72c01025cc664da Merge branch 'develop' into release-1.6.0 --- diff --git a/.classpath b/.classpath index 7bc01d9a..51769745 100644 --- a/.classpath +++ b/.classpath @@ -1,9 +1,9 @@ - - + + diff --git a/libs/disklrucache-2.0.2.jar b/libs/disklrucache-2.0.2.jar new file mode 100644 index 00000000..ca7907d0 Binary files /dev/null and b/libs/disklrucache-2.0.2.jar differ diff --git a/lint.xml b/lint.xml deleted file mode 100644 index ee0eead5..00000000 --- a/lint.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index c02736ab..9ab44ea9 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -31,6 +31,7 @@ Geriyə cavab İşarələmək %1$s-i ağıllı telefonunuzda yoxlayın! + Mən sizi öz smartfonunuzda %1$s istifadə etmək üçün dəvət etmək istəyirəm! Burdan endirin: %2$s Serveri yoxla Server ünvanı https://… İstifadəçi adı @@ -128,6 +129,7 @@ Aşağıda göstərilən %5$s-də olan daxili və xarici fayl(lar) link edilmiş %1$s (oxuyur) %1$s (yüklənir) %1$s geriyə oxunuş bitib + Media faylı tapılmadı Sil Detallar Bu fayl və ya qovluğun yayımlanmasının dayandırılmasında səhv baş verdi diff --git a/res/values-bg-rBG/strings.xml b/res/values-bg-rBG/strings.xml index e11d5483..8eebb6a8 100644 --- a/res/values-bg-rBG/strings.xml +++ b/res/values-bg-rBG/strings.xml @@ -264,6 +264,9 @@ Профили Добавяне на профил Сигурна връзка е пренасочена по несигурен път. + Доклади + Изпрати История + Зареждане на информация... Нужна е идентификация Грешна парола Премести diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml index a6acaade..74739f5d 100644 --- a/res/values-bn-rBD/strings.xml +++ b/res/values-bn-rBD/strings.xml @@ -49,7 +49,7 @@ এই যৌথ কনটেন্ট এ %1$s এর প্রবেশ অনুমোদিত নয় আপলোড করা হচ্ছে এখানে কিছুই নেই। কিছু আপলোড করুন ! - লোড হচছে.... + লোড হচ্ছে.... এই ফোলডারে কোন ফাইল নেই অতিরিক্ত তথ্য প্রদর্শন করতে চাইলে ফাইলে ট্যাপ দিন আয়তনঃ @@ -140,7 +140,7 @@ আগান অনুমোদন নেয়া হচ্ছে.... লগইনের চেষটা চলছে.. - নেটওয়ারক কানেকশন নেই + নেটওয়ার্ক সংযোগ নেই নিরাপদ যোগাযোগ পাওয়া গেলনা যোগাযোগ স্থাপিত হয়েছে যোগাযোগ পরীক্ষা করা হচ্ছে... @@ -232,7 +232,7 @@ স্থানীয় ফাইল আর দুরবর্তী ফাইল %s এক নয়। এগোতে চাইলে সার্ভারের ফাইলের কনটেন্ট প্রদিস্থাপিত হবে। উভয়কে রাখ উপরে লেখ - আপলোড করোনা + আপলোড কোরোনা ছবি প্রাকদর্শন ছবিটি প্রদর্শন করা যাবেনা %1$s কে %2$s স্থানীয় ফোল্ডারে কপি করা গেলনা @@ -260,5 +260,9 @@ একাউন্ট একাউন্ট যোগ কর নিরাপদ সংযোগকে একটি অনিরাপদ পথে দিকবদল করা হয়েছে + ভুল কুটশব্দ + সরাও + এখানে কিছু নেই। একটি ফোল্ডার যোগ করতে পারেন! বেছে নিন + সরাতে ব্যার্থ হলো। ফাইলটি রয়েছে কিনা দেখুন। diff --git a/res/values-cs-rCZ/strings.xml b/res/values-cs-rCZ/strings.xml index 75a8d618..71b84c9e 100644 --- a/res/values-cs-rCZ/strings.xml +++ b/res/values-cs-rCZ/strings.xml @@ -263,6 +263,10 @@ administrátora. Účty Přidat účet Zabezpečené spojení je přesměrováváno nezabezpečenou trasou. + Logy + Odeslat historii + Logy aplikace ownCloud pro Android + Načítám data... Vyžadováno přihlášení Nesprávné heslo Přesunout diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index d0189503..cbb2d75f 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -262,6 +262,9 @@ Konti Tilføj konto Sikker forbindelse videredirigeres gennem en usikker rute. + Logge + Send historik + Indlæser data... Godkendelse påkrævet Forkert kodeord Flyt diff --git a/res/values-de-rDE/strings.xml b/res/values-de-rDE/strings.xml index 09abb6a5..b1132871 100644 --- a/res/values-de-rDE/strings.xml +++ b/res/values-de-rDE/strings.xml @@ -264,14 +264,18 @@ Konten Konto hinzufügen Die gesicherte Verbindung wird auf eine unsichere Route weitergeleitet. - Authentifizierung benötigt + Protokolle + Verlauf senden + Protokolle der ownCloud-Android-App + Daten werden geladen … + Legitimierung benötigt Falsches Passwort Verschieben Nichts vorhanden. Sie können einen Ordner hinzufügen! Auswählen - Verschieben nicht möglich. Prüfen Sie, ob die Datei existiert + Verschieben nicht möglich. Bitte überprüfen Sie, ob die Datei existiert Es ist nicht möglich einen Ordner eine Ebene tiefer zu verschieben - Die Datei existiert bereits im Zielordner - Es ist ein Fehler beim Verschieben dieser Datei oder Ordners aufgetreten. + Die Datei ist bereits im Zielordner vorhanden + Es ist ein Fehler beim Verschieben dieser Datei oder dieses Ordners aufgetreten. um diese Datei zu verschieben diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index c20c88f2..0b536c10 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -264,14 +264,18 @@ Konten Konto hinzufügen Die gesicherte Verbindung wird auf eine unsichere Route weitergeleitet. - Authentifizierung benötigt + Protokolle + Verlauf senden + Protokolle der ownCloud-Android-App + Daten werden geladen … + Legitimierung benötigt Falsches Passwort Verschieben Nichts vorhanden. Du kannst einen Ordner hinzufügen! Auswählen Verschieben nicht möglich. Prüfe, dass die Datei existiert Es ist nicht möglich einen Ordner eine Ebene tiefer zu verschieben - Die Datei existiert bereits im Zielordner + Die Datei ist bereits im Zielordner vorhanden Es ist ein Fehler beim Verschieben dieser Datei oder Ordners aufgetreten. zum Datei verschieben diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 39f099e2..179cdc56 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -264,4 +264,5 @@ Απαιτείται πιστοποίηση Εσφαλμένο συνθηματικό Επιλέξτε + για μετακίνηση αυτού του αρχείου diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index d7559e23..fd812c64 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -264,6 +264,10 @@ Accounts Add account Secure connection is redirected through an unsecured route. + Logs + Send History + ownCloud Android app logs + Loading data... Authentication required Incorrect password Move diff --git a/res/values-es-rPY/strings.xml b/res/values-es-rPY/strings.xml index 56e55a1d..56fe6665 100644 --- a/res/values-es-rPY/strings.xml +++ b/res/values-es-rPY/strings.xml @@ -1,4 +1,6 @@ + Archivos + Archivos diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index a5c8dc6d..9fa84e2f 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -104,6 +104,7 @@ Los contenidos de %1$d ficheros no se han sincronizado (%2$d conflictos) Algunos archivos locales se han perdido %1$d archivos en la carpeta %2$s no pudieron ser copiados a + A partir de la versión 1.3.16, los ficheros subidos desde este dispositivo se copian en la carpeta local %1$s para evitar la pérdida de datos cuando se sincroniza un único archivo con varias cuentas.\n\nDebido a este cambio, todos los ficheros subidos con versiones anteriores de esta aplicación fueron copiados a la carpeta %2$s. Sin embargo, un error impidió que se completara esta operación durante la sincronización de la cuenta. Puede dejar los archivos tal y como están y eliminar el enlace a %3$s o mover los archivos a la carpeta %1$s y mantener el enlace a %4$s.\n\nDebajo se muestran los archivos locales y los archivos remotos en %5$s a los que fueron enlazados. La carpeta local %1$s no existe. Mover todo Todos los archivos fueron movidos @@ -263,12 +264,16 @@ Cuentas Agregar cuenta La conexión segura está siendo redirigida por una ruta insegura. + Trazas + Enviar historial + Cargando datos... Se necesita autenticación Contraseña incorrecta Mover Aquí no hay nada. ¡Puede agregar una carpeta! Seleccionar No se puede mover. Revise si el archivo existe + No se puede mover una carpeta dentro de una de sus descendientes. El archivo ya existe en la carpeta de destino Hubo un error al tratar de mover este archivo o carpeta para mover este archivo diff --git a/res/values-fi-rFI/strings.xml b/res/values-fi-rFI/strings.xml index f480fc6b..9419f95f 100644 --- a/res/values-fi-rFI/strings.xml +++ b/res/values-fi-rFI/strings.xml @@ -30,6 +30,7 @@ Suosittele kaverille Palaute Kokeile %1$sia älypuhelimellasi! + Kutsun sinut käyttämään %1$sia älypuhelimellasi!\nLataa se tästä: %2$s Tarkista palvelin Palvelinosoite https://… Käyttäjätunnus @@ -240,6 +241,10 @@ Tilit Lisää tili Salattu yhteys on ohjattu uudelleen salaamatonta reittiä pitkin. + Lokit + Lähetä historia + ownCloudin Android-sovelluksen lokit + Ladataan tietoja... Tunnistautuminen vaaditaan Väärä salasana Siirrä diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index e67237c1..5cbcd334 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -16,7 +16,7 @@ Comptes Gestion des comptes utilisateur Utilisation d\'un code de sécurité - Protéger l\'accès aux données maniplulées par le client + Protéger l\'accès aux données manipulées par le client Téléchargements instantanés d\'images Téléversement instantané des photos prises par la caméra Téléchargements instantanés de vidéos @@ -31,6 +31,8 @@ Commentaires Empreinte Essayez %1$s sur votre smartphone ! + J\'aimerais vous inviter à utiliser %1$s sur votre smartphone ! +Téléchargez-le ici : %2$s Vérifier le serveur Adresse du serveur https://... Nom d\'utilisateur @@ -103,6 +105,11 @@ Le contenu de %1$d fichiers n\'a put être synchronisé (%2$d conflits) Certains fichiers locaux ont été oubliés %1$d fichiers du dossier %2$s n\'ont pas pu être copiés dans + Depuis la version 1.3.16, les fichiers envoyé depuis ce périphérique sont copiés dans le dossier local %1$s pour éviter une perte de données lorsqu\'un même fichier est synchronisé avec plusieurs comptes. + +En raison de cette modification, tous les fichiers envoyés avec des versions antérieures de cette application ont été copiés dans le dossier %2$s. Cependant une erreur a empêché l\'achèvement de cette opération pendant la synchronisation du compte. Vous pouvez soit laisser les fichiers tels quels et supprimer le lien vers %3$s, soit déplacer les fichiers dans le dossier %1$s et garder le lien vers %4$s. + +Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxquels ils étaient liés. Le dossier %1$s n\'existe plus Tout déplacer Tous les fichiers ont été déplacés @@ -237,7 +244,9 @@ Cette image ne peut pas être affichée %1$s n\'a pas pu être copié dans le dossier local %2$s Désolé, le partage n\'est pas disponible sur votre serveur. Contactez votre administrateur, s\'il vous plait. + Impossible de partager. Vérifiez que le fichier est bien présent Une erreur est survenue lors de la tentative de partage de ce fichier ou répertoire + Impossible de supprimer le partage. Vérifiez que le fichier est bien présent Une erreur est survenue lors de la tentative d’annulation du partage de ce fichier ou répertoire Envoyer Copier le lien @@ -258,8 +267,18 @@ Ce fichier n’est plus disponible sur le serveur Comptes Ajouter un compte + Le connexion sécurisée est redirigée vers une route non-sécurisée. + Journaux + Historique des envois + Chargement des données... Authentification requise Mot de passe incorrect Déplacer + Il n\'y rien ici. Vous pouvez ajouter un dossier ! Choisir + Impossible de supprimer. Vérifiez que le fichier est bien présent + Il n\'est pas possible de déplacer un dossier vers un de ses descendants + Le fichier existe déjà dans le dossier destinataire + Une erreur est survenue lors de la tentative de déplacement de ce fichier ou dossier + de déplacer ce fichier diff --git a/res/values-hu-rHU/strings.xml b/res/values-hu-rHU/strings.xml index fea47b42..a0b16a04 100644 --- a/res/values-hu-rHU/strings.xml +++ b/res/values-hu-rHU/strings.xml @@ -83,6 +83,7 @@ %1$s sikeresen fel lett töltve A feltöltés nem sikerült %1$s fájl feltöltése sikertelen + Feltöltés sikertelen, jelentkezz be újra Letöltés ... %1$d%% Letöltés %2$s A letöltés sikeres @@ -90,8 +91,10 @@ A letöltés sikertelen A letöltésből %1$s nem lett befejezve Még nem töltötte le + Letöltés sikertelen, jelentkezz be újra. Válasszon azonosítót A szinkronizálás sikertelen + Szinkronizálás sikertelen, jelentkezz be újra. %1$s szinkronizációját nem sikerült befejezni Érvénytelen jelszó a következőhöz %1$s Ütközések vannak @@ -105,6 +108,7 @@ Egyes fájlokat nem sikerült áthelyezni Helyi: %1$s Távoli: %1$s + Nincs elég hely a kiválasztott fájlok másolására a %1$s könyvtárban. Szeretnéd áthelyezni inkább? Kérem adja meg az alkalmazás PIN-kódját Az alkalmazás PIN-kódja A PIN-t kötelező lesz megadni az alkalmazás minden indításakor @@ -161,9 +165,12 @@ Kapcsolódás a felhasználóazonosítást végző kiszolgálóhoz... A kiszolgáló nem támogatja ezt a felhasználóazonosítási módszert %1$s nem támogat több bejelenkezési jogosultságot + Nem tudod hitelesíteni magadat ezen a szerveren Automatikusan frissítse a fájlokat Átnevezés Eltávolítás + Tényleg el akarod távolítani %1$s? + Tényleg el akarod távolítani a %1$s és tartalmát? Csak a helyi példány Csak a helyi tartalmat Törlés a szerverről @@ -175,7 +182,9 @@ Az átnevezés nem sikerült A távoli fájl nem volt ellenőrizhető Az állományok már szinkonizálva vannak + A könyvtárt nem lehet létrehozni Nem megendedett karakterek: / \\ < > : \" | ? * + A fájl név nem lehet üres Egy pillanat... Váratlan hiba; válassza ki a fájlt más programból Egy fájl sincs kiválasztva @@ -213,6 +222,7 @@ 2012/05/18 12:23 12:23:45 Képeket csak WiFi kapcsolaton keresztül töltsünk föl + Videó feltöltés csak WIFI-vel /InstantUpload Frissítési ütközés %s távoli állományt nem szinkronizáltuk a helyi példánnyal. Ha folytatja, akkor a távoli állományt felülírjuk. @@ -220,6 +230,8 @@ Felülírás Ne töltsük föl Előnézeti kép + Ez a kép nem jeleníthető meg + %1$s nem lehet másolni a %2$s helyi könyvtárba Hiba lépett fel a mappa megosztásakor Hiba lépett fel a mappa megosztásának visszavonásakor Küldjük el diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index ac37b198..d4507602 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -264,6 +264,10 @@ Account Aggiungi account La connessione sicura è rediretta attraverso un percorso non sicuro. + Registri + Invia cronologia + Registri applicazione ownCloud Android + Caricamento dati... Autenticazione richiesta Password errata Sposta diff --git a/res/values-ja-rJP/strings.xml b/res/values-ja-rJP/strings.xml index 958f41f0..d4e64f0f 100644 --- a/res/values-ja-rJP/strings.xml +++ b/res/values-ja-rJP/strings.xml @@ -265,6 +265,9 @@ アカウント アカウントを追加 暗号化されていない接続を経て、暗号化接続へリダイレクトされました。 + ログ + ログを送信 + 読込中 ... 認証を必要とする 無効なパスワード 移動 diff --git a/res/values-lt-rLT/strings.xml b/res/values-lt-rLT/strings.xml index c88b5cdf..5dfaffa4 100644 --- a/res/values-lt-rLT/strings.xml +++ b/res/values-lt-rLT/strings.xml @@ -35,6 +35,7 @@ Serverio adresas Prisijungimo vardas Slaptažodis + Naujas į %1$s? Failai Prisijungti Įkelti @@ -48,6 +49,8 @@ %1$s neleidžiama prieiti prie turinio, kuriuo dalijamasi Išsiunčiama Čia tuščia. Įkelkite ką nors! + Įkeliama ... + Šiame aplanke nėra failų. Palieskite failą, kad parodyti papildomą informaciją. Dydis: Tipas: @@ -91,6 +94,7 @@ Atsisiuntimas nepavyko, Jums reikia prisijungti pakartotinai Pasirinkite paskyrą Sinchronizacija nepavyko + Sinchronizacija nepavyko. Jums reikia prisijungti iš naujo %1$s sinchronizacija nepavyko Netinkamas slaptažodis %1$s Rastas konfliktas @@ -158,10 +162,12 @@ Jungiamasi prie autentikacijos serverio... Serveris nepalaiko šio autentikacijos metodo %1$s nepalaiko kelių paskyrų iš karto + Jungiamasi prie autentikacijos serverio... Laikyti failą naujinamą Pervadinti Pašalinti Ar tikrai norite pašalinti %1$s? + Ar tikrai norite pašalinti %1$s ir ten esantį turinį? Tik vietiniai Tik vietinis turinys Pašalinti iš serverio @@ -174,6 +180,7 @@ Nutolę failai negalėjo būti patikrinti Failo turinys jau sunchronizuotas Aplanko sukurti nepavyko + Neleistini simboliai: / \\ < > : \" | ? * Failo pavadinimas negali būti tuščias Truputį palaukite Netikėta problema ; prašome pasirinkti failą iš kitos programėlės diff --git a/res/values-mt-rMT/strings.xml b/res/values-mt-rMT/strings.xml new file mode 100644 index 00000000..56e55a1d --- /dev/null +++ b/res/values-mt-rMT/strings.xml @@ -0,0 +1,4 @@ + + + + diff --git a/res/values-nb-rNO/strings.xml b/res/values-nb-rNO/strings.xml index 8832e0f7..78ded4f9 100644 --- a/res/values-nb-rNO/strings.xml +++ b/res/values-nb-rNO/strings.xml @@ -31,6 +31,7 @@ Tilbakemelding Avtrykk Prøv %1$s på smarttelefonen din! + Jeg ønsker å invitere deg til å bruke %1$s på smarttelefonen din!\nLast ned her: %2$s Sjekk server Serveradresse https://... Brukernavn @@ -103,6 +104,7 @@ Innholdet av %1$d filer kunne ikke synkroniseres (%2$d konflikter) Noen lokale filer ble glemt %1$d filer fra %2$s mappen kunne ikke kopieres til + Fra versjon 1.3.16 blir filer som lastes opp fra denne enheten kopiert inn i den lokale mappen %1$s for å forhindre tap av data når samme fil synkroniseres med flere kontoer.\n\nPga. denne endringen ble alle filer som er blitt lastet opp med tidligere versjoner av denne appen, kopiert til mappe %2$s. Imidlertid kunne ikke denne kopieringen fullføres under konto-synkroniseringen pga. en feil. Du kan enten la filen(e) ligge der de ligger og fjerne lenken til %3$s, eller flytte filene til mappe %1$s og beholde lenken til %4$s.\n\nNedenfor finner du en liste over de lokale filene og de eksterne filene i %5$s som de var lenket til. Mappen %1$s finnes ikke lengere Flytt alle Alle filer ble flyttet @@ -238,7 +240,9 @@ %1$s kunne ikke kopieres til lokal mappe %2$s Beklager, deling er ikke skrudd på for din tjener. Ta kontakt med administratoren. + Kan ikke dele. Sjekk om filen eksisterer. Det skjedde en feil under deling av denne filen eller mappen + Kan ikke fjerne deling. Sjekk om filen eksisterer. En feil oppstod ved avslutting av delingen av denne filen eller mappen Send Kopier lenke @@ -260,7 +264,17 @@ Kontoer Legg til en konto Sikker tilkobling videresendes gjennom en usikker rute. + Logger + Send historikk + Laster data... Autentisering kreves Feil passord + Flytt + Ingenting her. Du kan legge til en mappe! Velg + Kan ikke flytte. Sjekk om filen eksisterer. + Det er ikke mulig å flytte en mappe inn i sin egen undermappe + Filen finnes allerede i målmappen + En feil oppstod ved flytting av denne filen eller mappen + å flytte denne filen diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index d625794a..2f12347a 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -267,6 +267,10 @@ Hieronder staan de lokale bestanden en de externe bestanden in %5$s waar ze naar Accounts Toevoegen account De beveiligde verbinding is omgeleid via een onveilige route. + Logs + Verstuur geschiedenis + ownCloud Android app logs + Laden data... Authenticatie vereist Onjuist wachtwoord verplaatsen diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index dd84ee10..9fd718a0 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -264,6 +264,9 @@ Konta Dodaj konto Bezpieczne połączenie jest przekierowywane przez niezabezpieczone trasy. + Logi + Wyślij historię + Ładuję dane... Wymagana autoryzacja Złe hasło Przenieś diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index a58a0b47..71df1607 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -264,6 +264,10 @@ Contas Adicionar uma conta A conexão segura está redirecionada através de uma rota insegura. + Logs + Enviar Histórico + Logs do aplicativo ownCloud Android + Carregamento de dados... Autenticação é requerida Senha incorreta Mover diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 7ae54297..413b35e8 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -260,6 +260,8 @@ Contas Adicionar conta Uma ligação segura foi redireccionada por uma rota insegura. + Enviar Histórico + A carregar os dados... Autenticação necessária Password errada Mover diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index a5aab206..49c3e3cc 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -31,6 +31,8 @@ Обратная связь Штамп Попробуйте %1$s на вашем смартфоне! + Хочу предложить вам использовать %1$s на смартфоне!\nЗагрузить можно здесь: %2$s + Проверить сервер Адрес сервера https://... Имя пользователя @@ -238,7 +240,9 @@ Это изображение не может быть отображено %1$s не возможно скопировать в локальною папку %2$s К сожалению, на вашем сервере отключен совместный доступ. Пожалуйста, свяжитесь с вашим администратором. + Невозможно добавить в общий доступ. Пожалуйста, проверьте, существует ли файл Ошибка предоставления общего доступа к этому файлу или каталогу + Невозможно убрать из общего доступа. Пожалуйста, проверьте, существует ли файл Ошибка удаления общего доступа к этому файлу или каталогу Отправить Копировать ссылку @@ -260,8 +264,18 @@ Учётные записи Добавить учетную запись Безопасное соединение перенаправлено через небезопасный маршрут. + Журналы + История Отправлений + Журналы Андроид-приложения ownCloud + Загружаются данные... Требуется аутентификация Неправильный пароль Переместить + Здесь ничего нет. Вы можете добавить папку! Выбрать + Невозможно переместить. Пожалуйста, проверьте, существует ли файл + Невозможно переместить папку в папку-потомок + Файл уже существует в папке назначения + Произошла ошибка при попытке перемещения этого файла или папки + переместить этот файл diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index b1bf1bcb..5dc4e63b 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -104,6 +104,7 @@ Vsebine %1$d datotek ni bilo mogoče uskladiti (zaznanih je %2$d sporov) Nekatere krajevne datoteke so spregledane Skupno %1$d datotek iz mape %2$s ni mogoče kopirati v + Od različice 1.3.16 so datoteke, poslane iz te naprave, varnostno kopirane v krajevno mapo %1$s. S tem je preprečena možnost izgube podatkov, ko se ena datoteka usklajuje z več računi.\n\nZaradi te spremembe so vse datoteke, ki so bile kopirane v prejšnjih različicah, kopirane v mapo %2$s. Zaradi napake ni mogoče končati usklajevanja. Datoteke lahko ali pustite kjer so, in odstranite povezavo na %3$s, ali pa premaknete datoteke v mapo %1$s in ohranite povezavo do %4$s.\n\nSpodaj so izpisane krajevne datoteke in oddaljene povezane datoteke v mapi %5$s. Mapa %1$s ne obstaja več Premakni vse Vse datoteke so uspešno premaknjene na novo mesto @@ -263,6 +264,9 @@ Računi Dodaj račun Varna povezava je preusmerjena preko ne-varne poti. + Dnevnik + Pošlji zgodovino + Poteka nalaganje podatkov ... Zahtevana je overitev Napačno geslo Premakni @@ -272,4 +276,5 @@ Ni mogoče premakniti mape v podrejeno mapo. Datoteka v ciljni mapi že obstaja. Prišlo je do napake med premikanjem datoteke v mapo + med premikanjem datoteke diff --git a/res/values-tg-rTJ/strings.xml b/res/values-tg-rTJ/strings.xml new file mode 100644 index 00000000..56e55a1d --- /dev/null +++ b/res/values-tg-rTJ/strings.xml @@ -0,0 +1,4 @@ + + + + diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index ccd09301..72a15891 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -264,6 +264,10 @@ Hesaplar Hesap ekle Güvenli bağlantı, güvenli olmayan bir rotaya yönlendiriliyor. + Günlükler + Geçmişi Gönder + ownCloud Android uygulama kayıtları + Veri yükleniyor... Kimlik doğrulama gerekli Hatalı parola Taşı diff --git a/res/values/strings.xml b/res/values/strings.xml index d80a79b3..03b53623 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -287,7 +287,7 @@ Logs Send History - Owncloud Android app logs + ownCloud Android app logs Loading data... Authentication required diff --git a/src/com/owncloud/android/datamodel/FileDataStorageManager.java b/src/com/owncloud/android/datamodel/FileDataStorageManager.java index 4848246f..795004a1 100644 --- a/src/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/src/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -188,6 +188,7 @@ public class FileDataStorageManager { cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink()); cv.put(ProviderTableMeta.FILE_PERMISSIONS, file.getPermissions()); cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId()); + cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.needsUpdateThumbnail()); boolean sameRemotePath = fileExists(file.getRemotePath()); if (sameRemotePath || @@ -878,6 +879,8 @@ public class FileDataStorageManager { file.setPublicLink(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_PUBLIC_LINK))); file.setPermissions(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_PERMISSIONS))); file.setRemoteId(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_REMOTE_ID))); + file.setNeedsUpdateThumbnail(c.getInt( + c.getColumnIndex(ProviderTableMeta.FILE_UPDATE_THUMBNAIL)) == 1 ? true : false); } return file; @@ -1222,6 +1225,7 @@ public class FileDataStorageManager { cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink()); cv.put(ProviderTableMeta.FILE_PERMISSIONS, file.getPermissions()); cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId()); + cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.needsUpdateThumbnail() ? 1 : 0); boolean existsByPath = fileExists(file.getRemotePath()); if (existsByPath || fileExists(file.getFileId())) { diff --git a/src/com/owncloud/android/datamodel/OCFile.java b/src/com/owncloud/android/datamodel/OCFile.java index 58851063..c3284fc0 100644 --- a/src/com/owncloud/android/datamodel/OCFile.java +++ b/src/com/owncloud/android/datamodel/OCFile.java @@ -68,6 +68,8 @@ public class OCFile implements Parcelable, Comparable { private String mPermissions; private String mRemoteId; + private boolean mNeedsUpdateThumbnail; + /** * Create new {@link OCFile} with given path. @@ -109,6 +111,8 @@ public class OCFile implements Parcelable, Comparable { mPublicLink = source.readString(); mPermissions = source.readString(); mRemoteId = source.readString(); + mNeedsUpdateThumbnail = source.readInt() == 0; + } @Override @@ -131,6 +135,7 @@ public class OCFile implements Parcelable, Comparable { dest.writeString(mPublicLink); dest.writeString(mPermissions); dest.writeString(mRemoteId); + dest.writeInt(mNeedsUpdateThumbnail ? 1 : 0); } /** @@ -343,6 +348,7 @@ public class OCFile implements Parcelable, Comparable { mPublicLink = null; mPermissions = null; mRemoteId = null; + mNeedsUpdateThumbnail = false; } /** @@ -408,6 +414,14 @@ public class OCFile implements Parcelable, Comparable { return mNeedsUpdating; } + public boolean needsUpdateThumbnail() { + return mNeedsUpdateThumbnail; + } + + public void setNeedsUpdateThumbnail(boolean needsUpdateThumbnail) { + this.mNeedsUpdateThumbnail = needsUpdateThumbnail; + } + public long getLastSyncDateForProperties() { return mLastSyncDateForProperties; } diff --git a/src/com/owncloud/android/db/ProviderMeta.java b/src/com/owncloud/android/db/ProviderMeta.java index 1adf6971..bc59869a 100644 --- a/src/com/owncloud/android/db/ProviderMeta.java +++ b/src/com/owncloud/android/db/ProviderMeta.java @@ -31,7 +31,7 @@ import com.owncloud.android.MainApp; public class ProviderMeta { public static final String DB_NAME = "filelist"; - public static final int DB_VERSION = 7; + public static final int DB_VERSION = 8; private ProviderMeta() { } @@ -70,6 +70,7 @@ public class ProviderMeta { public static final String FILE_PUBLIC_LINK = "public_link"; public static final String FILE_PERMISSIONS = "permissions"; public static final String FILE_REMOTE_ID = "remote_id"; + public static final String FILE_UPDATE_THUMBNAIL = "update_thumbnail"; public static final String FILE_DEFAULT_SORT_ORDER = FILE_NAME + " collate nocase asc"; diff --git a/src/com/owncloud/android/files/services/FileDownloader.java b/src/com/owncloud/android/files/services/FileDownloader.java index 2e423beb..cb0f12ce 100644 --- a/src/com/owncloud/android/files/services/FileDownloader.java +++ b/src/com/owncloud/android/files/services/FileDownloader.java @@ -391,6 +391,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis long syncDate = System.currentTimeMillis(); file.setLastSyncDateForProperties(syncDate); file.setLastSyncDateForData(syncDate); + file.setNeedsUpdateThumbnail(true); file.setModificationTimestamp(mCurrentDownload.getModificationTimestamp()); file.setModificationTimestampAtLastSyncForData(mCurrentDownload.getModificationTimestamp()); // file.setEtag(mCurrentDownload.getEtag()); // TODO Etag, where available diff --git a/src/com/owncloud/android/providers/FileContentProvider.java b/src/com/owncloud/android/providers/FileContentProvider.java index 8113e046..9792f3e9 100644 --- a/src/com/owncloud/android/providers/FileContentProvider.java +++ b/src/com/owncloud/android/providers/FileContentProvider.java @@ -97,6 +97,8 @@ public class FileContentProvider extends ContentProvider { ProviderTableMeta.FILE_PERMISSIONS); mFileProjectionMap.put(ProviderTableMeta.FILE_REMOTE_ID, ProviderTableMeta.FILE_REMOTE_ID); + mFileProjectionMap.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, + ProviderTableMeta.FILE_UPDATE_THUMBNAIL); } private static final int SINGLE_FILE = 1; @@ -559,7 +561,8 @@ public class FileContentProvider extends ContentProvider { + ProviderTableMeta.FILE_SHARE_BY_LINK + " INTEGER, " + ProviderTableMeta.FILE_PUBLIC_LINK + " TEXT, " + ProviderTableMeta.FILE_PERMISSIONS + " TEXT null," - + ProviderTableMeta.FILE_REMOTE_ID + " TEXT null);" + + ProviderTableMeta.FILE_REMOTE_ID + " TEXT null," + + ProviderTableMeta.FILE_UPDATE_THUMBNAIL + " INTEGER);" //boolean ); // Create table ocshares @@ -708,6 +711,23 @@ public class FileContentProvider extends ContentProvider { } if (!upgraded) Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion + ", newVersion == " + newVersion); + + if (oldVersion < 8 && newVersion >= 8) { + Log_OC.i("SQL", "Entering in the #8 ADD in onUpgrade"); + db.beginTransaction(); + try { + db .execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME + + " ADD COLUMN " + ProviderTableMeta.FILE_UPDATE_THUMBNAIL + " INTEGER " + + " DEFAULT 0"); + + upgraded = true; + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + } + if (!upgraded) + Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion + ", newVersion == " + newVersion); } } diff --git a/src/com/owncloud/android/ui/adapter/DiskLruImageCache.java b/src/com/owncloud/android/ui/adapter/DiskLruImageCache.java new file mode 100644 index 00000000..d22dc971 --- /dev/null +++ b/src/com/owncloud/android/ui/adapter/DiskLruImageCache.java @@ -0,0 +1,189 @@ +package com.owncloud.android.ui.adapter; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Bitmap.CompressFormat; +import android.graphics.BitmapFactory; +import android.util.Log; + +import com.jakewharton.disklrucache.DiskLruCache; +import com.owncloud.android.BuildConfig; +import com.owncloud.android.lib.common.utils.Log_OC; + +public class DiskLruImageCache { + + private DiskLruCache mDiskCache; + private CompressFormat mCompressFormat; + private int mCompressQuality; + private static final int CACHE_VERSION = 1; + private static final int VALUE_COUNT = 1; + private static final int IO_BUFFER_SIZE = 8 * 1024; + private static final Pattern CAPITAL_LETTERS = Pattern.compile("[A-Z]"); + + private StringBuffer mValidKeyBuffer = new StringBuffer(64); + private StringBuffer mConversionBuffer = new StringBuffer(2).append('_'); + + private static final String TAG = "DiskLruImageCache"; + + public DiskLruImageCache( Context context,String uniqueName, int diskCacheSize, + CompressFormat compressFormat, int quality ) throws IOException { + final File diskCacheDir = getDiskCacheDir(context, uniqueName ); + mDiskCache = DiskLruCache.open( + diskCacheDir, CACHE_VERSION, VALUE_COUNT, diskCacheSize + ); + mCompressFormat = compressFormat; + mCompressQuality = quality; + } + + private boolean writeBitmapToFile( Bitmap bitmap, DiskLruCache.Editor editor ) + throws IOException, FileNotFoundException { + OutputStream out = null; + try { + out = new BufferedOutputStream( editor.newOutputStream( 0 ), IO_BUFFER_SIZE ); + return bitmap.compress( mCompressFormat, mCompressQuality, out ); + } finally { + if ( out != null ) { + out.close(); + } + } + } + + private File getDiskCacheDir(Context context, String uniqueName) { + + // Check if media is mounted or storage is built-in, if so, try and use external cache dir + // otherwise use internal cache dir + final String cachePath = context.getExternalCacheDir().getPath(); + + Log_OC.d(TAG, "create dir: " + cachePath + File.separator + uniqueName); + + return new File(cachePath + File.separator + uniqueName); + } + + public void put( String key, Bitmap data ) { + + DiskLruCache.Editor editor = null; + String validKey = convertToValidKey(key); + try { + editor = mDiskCache.edit( validKey ); + if ( editor == null ) { + return; + } + + if( writeBitmapToFile( data, editor ) ) { + mDiskCache.flush(); + editor.commit(); + if ( BuildConfig.DEBUG ) { + Log.d( "cache_test_DISK_", "image put on disk cache " + validKey ); + } + } else { + editor.abort(); + if ( BuildConfig.DEBUG ) { + Log.d( "cache_test_DISK_", "ERROR on: image put on disk cache " + validKey ); + } + } + } catch (IOException e) { + if ( BuildConfig.DEBUG ) { + Log.d( "cache_test_DISK_", "ERROR on: image put on disk cache " + validKey ); + } + try { + if ( editor != null ) { + editor.abort(); + } + } catch (IOException ignored) { + } + } + + } + + public Bitmap getBitmap( String key ) { + + Bitmap bitmap = null; + DiskLruCache.Snapshot snapshot = null; + String validKey = convertToValidKey(key); + try { + + snapshot = mDiskCache.get( validKey ); + if ( snapshot == null ) { + return null; + } + final InputStream in = snapshot.getInputStream( 0 ); + if ( in != null ) { + final BufferedInputStream buffIn = + new BufferedInputStream( in, IO_BUFFER_SIZE ); + bitmap = BitmapFactory.decodeStream( buffIn ); + } + } catch ( IOException e ) { + e.printStackTrace(); + } finally { + if ( snapshot != null ) { + snapshot.close(); + } + } + + if ( BuildConfig.DEBUG ) { + Log.d("cache_test_DISK_", bitmap == null ? "not found" : "image read from disk " + validKey); + } + + return bitmap; + + } + + public boolean containsKey( String key ) { + + boolean contained = false; + DiskLruCache.Snapshot snapshot = null; + String validKey = convertToValidKey(key); + try { + snapshot = mDiskCache.get( validKey ); + contained = snapshot != null; + } catch (IOException e) { + e.printStackTrace(); + } finally { + if ( snapshot != null ) { + snapshot.close(); + } + } + + return contained; + + } + + public void clearCache() { + if ( BuildConfig.DEBUG ) { + Log.d( "cache_test_DISK_", "disk cache CLEARED"); + } + try { + mDiskCache.delete(); + } catch ( IOException e ) { + e.printStackTrace(); + } + } + + public File getCacheFolder() { + return mDiskCache.getDirectory(); + } + + private String convertToValidKey(String key) { + Matcher capitalLettersMatcher = CAPITAL_LETTERS.matcher(key); + mValidKeyBuffer.delete(0, mValidKeyBuffer.length()); + mConversionBuffer.delete(1, mConversionBuffer.length()); + + while (capitalLettersMatcher.find()) { + mConversionBuffer.replace(1, 2, capitalLettersMatcher.group(0).toLowerCase()); + capitalLettersMatcher.appendReplacement(mValidKeyBuffer, mConversionBuffer.toString()); + } + capitalLettersMatcher.appendTail(mValidKeyBuffer); + return mValidKeyBuffer.toString(); + } + +} \ No newline at end of file diff --git a/src/com/owncloud/android/ui/adapter/FileListListAdapter.java b/src/com/owncloud/android/ui/adapter/FileListListAdapter.java index 65a9c83c..ffdad175 100644 --- a/src/com/owncloud/android/ui/adapter/FileListListAdapter.java +++ b/src/com/owncloud/android/ui/adapter/FileListListAdapter.java @@ -17,10 +17,21 @@ */ package com.owncloud.android.ui.adapter; +import java.io.File; +import java.lang.ref.WeakReference; import java.util.Vector; import android.accounts.Account; import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.Bitmap.CompressFormat; +import android.graphics.BitmapFactory; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.media.ThumbnailUtils; +import android.os.AsyncTask; +import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -36,7 +47,9 @@ import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder; import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; +import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.ui.activity.ComponentsGetter; +import com.owncloud.android.utils.BitmapUtils; import com.owncloud.android.utils.DisplayUtils; @@ -45,10 +58,13 @@ import com.owncloud.android.utils.DisplayUtils; * instance. * * @author Bartek Przybylski - * + * @author Tobias Kaminsky + * @author David A. Velasco */ public class FileListListAdapter extends BaseAdapter implements ListAdapter { private final static String PERMISSION_SHARED_WITH_ME = "S"; + + private static final String TAG = FileListListAdapter.class.getSimpleName(); private Context mContext; private OCFile mFile = null; @@ -59,15 +75,159 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter { private Account mAccount; private ComponentsGetter mTransferServiceGetter; + private final Object thumbnailDiskCacheLock = new Object(); + private DiskLruImageCache mThumbnailCache; + private boolean mThumbnailCacheStarting = true; + private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB + private static final CompressFormat mCompressFormat = CompressFormat.JPEG; + private static final int mCompressQuality = 70; + private Bitmap defaultImg; + public FileListListAdapter( boolean justFolders, Context context, ComponentsGetter transferServiceGetter ) { + mJustFolders = justFolders; mContext = context; mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext); mTransferServiceGetter = transferServiceGetter; + defaultImg = BitmapFactory.decodeResource(mContext.getResources(), + DisplayUtils.getResourceId("image/png", "default.png")); + + // Initialise disk cache on background thread + new InitDiskCacheTask().execute(); + } + + class InitDiskCacheTask extends AsyncTask { + @Override + protected Void doInBackground(File... params) { + synchronized (thumbnailDiskCacheLock) { + try { + mThumbnailCache = new DiskLruImageCache(mContext, "thumbnailCache", + DISK_CACHE_SIZE, mCompressFormat, mCompressQuality); + } catch (Exception e) { + Log_OC.d(TAG, "Thumbnail cache could not be opened ", e); + mThumbnailCache = null; + } + mThumbnailCacheStarting = false; // Finished initialization + thumbnailDiskCacheLock.notifyAll(); // Wake any waiting threads + } + return null; + } + } + + static class AsyncDrawable extends BitmapDrawable { + private final WeakReference bitmapWorkerTaskReference; + + public AsyncDrawable(Resources res, Bitmap bitmap, + ThumbnailGenerationTask bitmapWorkerTask) { + super(res, bitmap); + bitmapWorkerTaskReference = + new WeakReference(bitmapWorkerTask); + } + + public ThumbnailGenerationTask getBitmapWorkerTask() { + return bitmapWorkerTaskReference.get(); + } + } + + class ThumbnailGenerationTask extends AsyncTask { + private final WeakReference imageViewReference; + private OCFile file; + + + public ThumbnailGenerationTask(ImageView imageView) { + // Use a WeakReference to ensure the ImageView can be garbage collected + imageViewReference = new WeakReference(imageView); + } + + // Decode image in background. + @Override + protected Bitmap doInBackground(OCFile... params) { + Bitmap thumbnail = null; + + try { + file = params[0]; + final String imageKey = String.valueOf(file.getRemoteId()); + + // Check disk cache in background thread + thumbnail = getBitmapFromDiskCache(imageKey); + + // Not found in disk cache + if (thumbnail == null || file.needsUpdateThumbnail()) { + // Converts dp to pixel + Resources r = mContext.getResources(); + int px = (int) Math.round(TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, 150, r.getDisplayMetrics() + )); + + if (file.isDown()){ + Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile( + file.getStoragePath(), px, px); + + if (bitmap != null) { + thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px); + + // Add thumbnail to cache + addBitmapToCache(imageKey, thumbnail); + + file.setNeedsUpdateThumbnail(false); + mStorageManager.saveFile(file); + } + + } + } + + } catch (Throwable t) { + // the app should never break due to a problem with thumbnails + Log_OC.e(TAG, "Generation of thumbnail for " + file + " failed", t); + if (t instanceof OutOfMemoryError) { + System.gc(); + } + } + + return thumbnail; + } + + protected void onPostExecute(Bitmap bitmap){ + if (isCancelled()) { + bitmap = null; + } + + if (imageViewReference != null && bitmap != null) { + final ImageView imageView = imageViewReference.get(); + final ThumbnailGenerationTask bitmapWorkerTask = + getBitmapWorkerTask(imageView); + if (this == bitmapWorkerTask && imageView != null) { + imageView.setImageBitmap(bitmap); + } + } + } + } + + public void addBitmapToCache(String key, Bitmap bitmap) { + synchronized (thumbnailDiskCacheLock) { + if (mThumbnailCache != null) { + mThumbnailCache.put(key, bitmap); + } + } + } + + public Bitmap getBitmapFromDiskCache(String key) { + synchronized (thumbnailDiskCacheLock) { + // Wait while disk cache is started from background thread + while (mThumbnailCacheStarting) { + try { + thumbnailDiskCacheLock.wait(); + } catch (InterruptedException e) {} + } + if (mThumbnailCache != null) { + return (Bitmap) mThumbnailCache.getBitmap(key); + } + } + return null; } @Override @@ -112,10 +272,10 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter { .getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflator.inflate(R.layout.list_item, null); } - + if (mFiles != null && mFiles.size() > position) { OCFile file = mFiles.get(position); - TextView fileName = (TextView) view.findViewById(R.id.Filename); + TextView fileName = (TextView) view.findViewById(R.id.Filename); String name = file.getFileName(); fileName.setText(name); @@ -126,7 +286,8 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter { ImageView localStateView = (ImageView) view.findViewById(R.id.imageView2); localStateView.bringToFront(); - FileDownloaderBinder downloaderBinder = mTransferServiceGetter.getFileDownloaderBinder(); + FileDownloaderBinder downloaderBinder = + mTransferServiceGetter.getFileDownloaderBinder(); FileUploaderBinder uploaderBinder = mTransferServiceGetter.getFileUploaderBinder(); if (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, file)) { localStateView.setImageResource(R.drawable.downloading_file_indicator); @@ -149,7 +310,9 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter { fileSizeV.setVisibility(View.VISIBLE); fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength())); lastModV.setVisibility(View.VISIBLE); - lastModV.setText(DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp())); + lastModV.setText( + DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp()) + ); // this if-else is needed even thoe fav icon is visible by default // because android reuses views in listview if (!file.keepInSync()) { @@ -168,20 +331,42 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter { checkBoxV.setImageResource(android.R.drawable.checkbox_off_background); } checkBoxV.setVisibility(View.VISIBLE); + } + + // get Thumbnail if file is image + if (file.isImage()){ + // Thumbnail in Cache? + Bitmap thumbnail = getBitmapFromDiskCache(String.valueOf(file.getRemoteId())); + if (thumbnail != null && !file.needsUpdateThumbnail()){ + fileIcon.setImageBitmap(thumbnail); + } else { + // generate new Thumbnail + if (cancelPotentialWork(file, fileIcon)) { + final ThumbnailGenerationTask task = + new ThumbnailGenerationTask(fileIcon); + final AsyncDrawable asyncDrawable = + new AsyncDrawable(mContext.getResources(), defaultImg, task); + fileIcon.setImageDrawable(asyncDrawable); + task.execute(file); + } + } + } else { + fileIcon.setImageResource( + DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()) + ); } - - fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName())); - + if (checkIfFileIsSharedWithMe(file)) { sharedWithMeIconV.setVisibility(View.VISIBLE); } } else { - fileSizeV.setVisibility(View.INVISIBLE); //fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength())); lastModV.setVisibility(View.VISIBLE); - lastModV.setText(DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp())); + lastModV.setText( + DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp()) + ); checkBoxV.setVisibility(View.GONE); view.findViewById(R.id.imageView3).setVisibility(View.GONE); @@ -189,7 +374,9 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter { fileIcon.setImageResource(R.drawable.shared_with_me_folder); sharedWithMeIconV.setVisibility(View.VISIBLE); } else { - fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName())); + fileIcon.setImageResource( + DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()) + ); } // If folder is sharedByLink, icon folder must be changed to @@ -208,6 +395,35 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter { return view; } + + public static boolean cancelPotentialWork(OCFile file, ImageView imageView) { + final ThumbnailGenerationTask bitmapWorkerTask = getBitmapWorkerTask(imageView); + + if (bitmapWorkerTask != null) { + final OCFile bitmapData = bitmapWorkerTask.file; + // If bitmapData is not yet set or it differs from the new data + if (bitmapData == null || bitmapData != file) { + // Cancel previous task + bitmapWorkerTask.cancel(true); + } else { + // The same work is already in progress + return false; + } + } + // No task associated with the ImageView, or an existing task was cancelled + return true; + } + + private static ThumbnailGenerationTask getBitmapWorkerTask(ImageView imageView) { + if (imageView != null) { + final Drawable drawable = imageView.getDrawable(); + if (drawable instanceof AsyncDrawable) { + final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; + return asyncDrawable.getBitmapWorkerTask(); + } + } + return null; + } @Override public int getViewTypeCount() { @@ -226,8 +442,10 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter { /** * Change the adapted directory for a new one - * @param directory New file to adapt. Can be NULL, meaning "no content to adapt". - * @param updatedStorageManager Optional updated storage manager; used to replace mStorageManager if is different (and not NULL) + * @param directory New file to adapt. Can be NULL, meaning + * "no content to adapt". + * @param updatedStorageManager Optional updated storage manager; used to replace + * mStorageManager if is different (and not NULL) */ public void swapDirectory(OCFile directory, FileDataStorageManager updatedStorageManager) { mFile = directory; @@ -273,7 +491,9 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter { * @return boolean: True if it is shared with me and false if it is not */ private boolean checkIfFileIsSharedWithMe(OCFile file) { - return (mFile.getPermissions() != null && !mFile.getPermissions().contains(PERMISSION_SHARED_WITH_ME) - && file.getPermissions() != null && file.getPermissions().contains(PERMISSION_SHARED_WITH_ME)); + return (mFile.getPermissions() != null + && !mFile.getPermissions().contains(PERMISSION_SHARED_WITH_ME) + && file.getPermissions() != null + && file.getPermissions().contains(PERMISSION_SHARED_WITH_ME)); } } diff --git a/src/com/owncloud/android/utils/BitmapUtils.java b/src/com/owncloud/android/utils/BitmapUtils.java new file mode 100644 index 00000000..687b5a4f --- /dev/null +++ b/src/com/owncloud/android/utils/BitmapUtils.java @@ -0,0 +1,99 @@ +/* ownCloud Android client application + * Copyright (C) 2012-2014 ownCloud Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.owncloud.android.utils; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.BitmapFactory.Options; + +/** + * Utility class with methods for decoding Bitmaps. + * + * @author David A. Velasco + */ +public class BitmapUtils { + + + /** + * Decodes a bitmap from a file containing it minimizing the memory use, known that the bitmap + * will be drawn in a surface of reqWidth x reqHeight + * + * @param srcPath Absolute path to the file containing the image. + * @param reqWidth Width of the surface where the Bitmap will be drawn on, in pixels. + * @param reqHeight Height of the surface where the Bitmap will be drawn on, in pixels. + * @return + */ + public static Bitmap decodeSampledBitmapFromFile(String srcPath, int reqWidth, int reqHeight) { + + // set desired options that will affect the size of the bitmap + final Options options = new Options(); + options.inScaled = true; + options.inPurgeable = true; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD_MR1) { + options.inPreferQualityOverSpeed = false; + } + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { + options.inMutable = false; + } + + // make a false load of the bitmap to get its dimensions + options.inJustDecodeBounds = true; + + BitmapFactory.decodeFile(srcPath, options); + + // calculate factor to subsample the bitmap + options.inSampleSize = calculateSampleFactor(options, reqWidth, reqHeight); + + // decode bitmap with inSampleSize set + options.inJustDecodeBounds = false; + return BitmapFactory.decodeFile(srcPath, options); + + } + + + /** + * Calculates a proper value for options.inSampleSize in order to decode a Bitmap minimizing + * the memory overload and covering a target surface of reqWidth x reqHeight if the original + * image is big enough. + * + * @param options Bitmap decoding options; options.outHeight and options.inHeight should + * be set. + * @param reqWidth Width of the surface where the Bitmap will be drawn on, in pixels. + * @param reqHeight Height of the surface where the Bitmap will be drawn on, in pixels. + * @return The largest inSampleSize value that is a power of 2 and keeps both + * height and width larger than reqWidth and reqHeight. + */ + private static int calculateSampleFactor(Options options, int reqWidth, int reqHeight) { + + final int height = options.outHeight; + final int width = options.outWidth; + int inSampleSize = 1; + + if (height > reqHeight || width > reqWidth) { + final int halfHeight = height / 2; + final int halfWidth = width / 2; + + while ((halfHeight / inSampleSize) > reqHeight + && (halfWidth / inSampleSize) > reqWidth) { + inSampleSize *= 2; + } + } + + return inSampleSize; + } + +}