From: tobiasKaminsky Date: Fri, 27 Nov 2015 16:37:34 +0000 (+0100) Subject: Merge remote-tracking branch 'remotes/upstream/master' into beta X-Git-Tag: beta-20151128~10 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/a99a28cc61d48eca63803c3d661ea1be14f99aec?hp=-c Merge remote-tracking branch 'remotes/upstream/master' into beta --- a99a28cc61d48eca63803c3d661ea1be14f99aec diff --combined build.gradle index 15b8ff6d,d96997a6..23816a1a --- a/build.gradle +++ b/build.gradle @@@ -3,12 -3,13 +3,12 @@@ buildscript mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:1.2.3' + classpath 'com.android.tools.build:gradle:1.3.0' } } apply plugin: 'com.android.application' - repositories { mavenCentral() @@@ -23,19 -24,11 +23,19 @@@ dependencies compile 'com.android.support:support-v4:22.2.1' compile 'com.jakewharton:disklrucache:2.0.2' compile 'com.android.support:appcompat-v7:22.2.1' + compile 'com.getbase:floatingactionbutton:1.10.1' } android { compileSdkVersion 22 buildToolsVersion "22.0.1" + + defaultConfig { + applicationId "com.owncloud.android.beta" + versionCode 20151125 + versionName "ownCloud beta" + } + sourceSets { main { manifest.srcFile 'AndroidManifest.xml' @@@ -72,20 -65,10 +72,20 @@@ packagingOptions { exclude 'META-INF/LICENSE.txt' } -} - - - + signingConfigs { + release { - storeFile file("../beta.jks") - storePassword KSTOREPWD - keyAlias "beta" - keyPassword KSTOREPWD ++ storeFile file(RELEASE_STORE_FILE) ++ storePassword RELEASE_STORE_PASSWORD ++ keyAlias RELEASE_KEY_ALIAS ++ keyPassword RELEASE_KEY_PASSWORD + } + } + buildTypes { + release { + signingConfig signingConfigs.release + } + } +} diff --combined owncloud-android-library index 2d9ab655,9e5c44dd..8966dbce --- a/owncloud-android-library +++ b/owncloud-android-library @@@ -1,1 -1,1 +1,1 @@@ - Subproject commit 2d9ab65553e8f4b85aa10cb636921df9976e9878 -Subproject commit 9e5c44ddb58970f1bbdf6723145a47379bdbccba ++Subproject commit 8966dbcee044cec726633fdfd208ea106cf176c0 diff --combined res/menu/file_actions_menu.xml index 4d24759b,32134d34..894dc331 --- a/res/menu/file_actions_menu.xml +++ b/res/menu/file_actions_menu.xml @@@ -1,5 -1,4 +1,5 @@@ - + Todos los archivos Abrir @@@ -73,8 -74,6 +74,6 @@@ Modificado: Descargar El archivo fue renombrado como %1$s durante la subida - Compartir vínculo - Dejar de compartir vínculo Sí No Aceptar @@@ -174,7 -173,7 +173,7 @@@ Favorito Renombrar Borrar - ¿Realmente quieres eliminar %1$s? + ¿Realmente quieres eliminar %1$s? ¿Realmente deseas eliminar %1$s y todo su contenido? Sólo local Sólo local diff --combined res/values-es/strings.xml index 0f77b149,19a19b98..6a515b23 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@@ -82,9 -82,6 +82,6 @@@ Sincronizar El fichero fue renombrado como %1$s durante la subida Diseño de lista - Compartir con enlace - Dejar de compartir - Compartir con usuarios Sí No Aceptar @@@ -199,11 -196,11 +196,11 @@@ No-favorito Renombrar Borrar - ¿Realmente desea eliminar %1$s? + ¿Realmente desea eliminar %1$s? ¿Realmente desea eliminar %1$s y todo su contenido? Sólo local Sólo local - Desde el servidor + Desde el servidor Remoto & local Borrado correctamente El borrado no pudo ser completado @@@ -336,7 -333,6 +333,6 @@@ %1$d archivos, 1 carpeta %1$d archivos, %2$d carpetas Compartiendo - Compartir con Usuarios y Grupos Aún no se ha compartido con ningún usuario. Añadir usuario o grupo Buscar diff --combined res/values-et-rEE/strings.xml index 7167dc53,dcbc8ab6..79d41350 --- a/res/values-et-rEE/strings.xml +++ b/res/values-et-rEE/strings.xml @@@ -80,8 -80,6 +80,6 @@@ Lae alla Fail nimetati üleslaadimise käigus ümber %1$ Nimekirja paigutus - Jaga linki - Tühista lingi jagamine Jah Ei OK @@@ -199,11 -197,11 +197,11 @@@ Allpool on loend kohalikest failidest n Eemalda lemmik Nimeta ümber Eemalda - Oled sa kindel, et soovid %1$s eemaldada? + Oled sa kindel, et soovid %1$s eemaldada? Kas sa tõesti soovid eemaldada %1$s ja selle sisu? Ainult kohalik Ainult kohalik - Serverist + Serverist Kaugfail & kohalik Eemaldamine oli edukas Eemaldamine ebaõnnestus diff --combined res/values-eu/strings.xml index 7cb8302d,4ad73795..c65857d8 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@@ -71,8 -71,6 +71,6 @@@ Aldatuta: Deskargatu Fitxategiaren izena %1$sra aldatu da igotzean - Elkarbanatu lotura - Lotura partekatzeari utzi Bai Ez Ados @@@ -174,7 -172,7 +172,7 @@@ Mesedez, baimendu berrizGogokoa Berrizendatu Ezabatu - Ziur zaude %1$s ezabatu nahi duzula? + Ziur zaude %1$s ezabatu nahi duzula? Ziru zaude %1$s eta bere edukiak ezabatu nahi dituzula? Bertakoa bakarrik Bertakoa bakarrik diff --combined res/values-fi-rFI/strings.xml index 7db80666,0510e1cd..0be584db --- a/res/values-fi-rFI/strings.xml +++ b/res/values-fi-rFI/strings.xml @@@ -82,9 -82,6 +82,6 @@@ Synkronoi Tiedoston nimeksi muutettiin %1$s siirron yhteydessä Luettelon asettelu - Jaa linkki - Poista linkin jako - Jaa käyttäjien kanssa Kyllä Ei OK @@@ -190,11 -187,11 +187,11 @@@ Poista suosikeista Nimeä uudelleen Poista - Haluatko varmasti poistaa kohteen %1$s? + Haluatko varmasti poistaa kohteen %1$s? Haluatko varmasti poistaa kohteen %1$s ja sen sisällön? Vain paikallinen Vain paikallinen - Palvelimelta + Palvelimelta Etä ja paikallinen Poistettu onnistuneesti Poistamista ei voitu suorittaa loppuun asti @@@ -317,7 -314,6 +314,6 @@@ %1$d tiedostoa, 1 kansio %1$d tiedostoa, %2$d kansiota Jakaminen - Jaa käyttäjien tai ryhmien kanssa Lisää käyttäjä tai ryhmä Etsi Etsi käyttäjiä ja ryhmiä diff --combined res/values-fr/strings.xml index 260ffbdf,319f1f6b..a9e4c438 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@@ -83,9 -83,6 +83,6 @@@ Téléchargez-le ici : %2$sSynchroniser Le fichier a été renommé en %s pendant le téléversement Affichage en liste - Partager le lien - Ne plus partager ce lien - Partager avec des utilisateurs Oui Non OK @@@ -204,11 -201,11 +201,11 @@@ Ci-dessous la liste des fichiers locaux Retirer des favoris Renommer Supprimer - Voulez-vous vraiment supprimer %1$s ? + Voulez-vous vraiment supprimer %1$s ? Voulez-vous vraiment supprimer %1$s et son contenu ? Local seulement Local seulement - Depuis le serveur + Depuis le serveur Distant & local Suppression effectuée avec succès Suppression impossible @@@ -341,7 -338,6 +338,6 @@@ %1$d fichiers, 1 dossier %1$d fichiers, %2$d dossiers Partage - Partager avec des Utilisateurs et des Groupes Aucune donnée partagée avec des utilisateurs pour le moment Ajouter un Utilisateur ou un Groupe Rechercher diff --combined res/values-gl/strings.xml index 68ad0a43,b04617cb..f8061b81 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@@ -83,9 -83,6 +83,6 @@@ Descárgueo de aquí: %2$sSincronizar O ficheiro foi renomeado a %1$s durante o envío Deseño da lista - Ligazón para compartir - Deixar de compartir a ligazón - Compartir con usuarios Si Non Aceptar @@@ -200,7 -197,7 +197,7 @@@ Retirar de favoritos Renomear Retirar - Confirma que quere retirar %1$s? + Confirma que quere retirar %1$s? Confirma que quere retirar %1$s e o seu contido? Só local Só local @@@ -335,7 -332,6 +332,6 @@@ %1$d ficheiros, 1 cartafol %1$d ficheiros, %2$d cartafoles Compartindo - Compartir con Usuarios e Grupos Aínda non hai datos compartidos con usuarios Engadir Usuario ou Grupo Buscar diff --combined res/values-he/strings.xml index 14c8156d,6163043a..9361e434 --- a/res/values-he/strings.xml +++ b/res/values-he/strings.xml @@@ -64,8 -64,6 +64,6 @@@ מועד השינוי: הורדה שם הקובץ השתנה ל־ %1$s במהלך ההעלאה - קישור לשיתוף - ביטול קישור לשיתוף כן לא אישור @@@ -167,7 -165,7 +165,7 @@@ מועדף שינוי שם הסרה - האם באמת להסיר %1$s? + האם באמת להסיר %1$s? האם באמת להסיר %1$s ואת כל התכולה? מקומי בלבד מקומי בלבד diff --combined res/values-hu-rHU/strings.xml index 25967de6,1af77e9a..2add8a2c --- a/res/values-hu-rHU/strings.xml +++ b/res/values-hu-rHU/strings.xml @@@ -78,8 -78,6 +78,6 @@@ Szinkronizálás A feltöltés során az állmányt erre neveztük át: %1$s Lista Elrendezés - Megosztás hivatkozással - Megosztás visszavonása Igen Nem OK @@@ -179,7 -177,7 +177,7 @@@ Nem kedvenc Átnevezés Eltávolítás - Tényleg el akarod távolítani %1$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 példány diff --combined res/values-id/strings.xml index f1f7d9fe,dff7d3cb..09372150 --- a/res/values-id/strings.xml +++ b/res/values-id/strings.xml @@@ -81,8 -81,6 +81,6 @@@ Unduh Berkas diubah namanya menjadi %1$s saat pengunggahan Daftar Tata Letak - Bagikan tautan - Batal bagikan tautan Ya Tidak Oke @@@ -196,11 -194,11 +194,11 @@@ Hapus favorit Ubah nama Hapus - Apakah Anda yakin ingin menghapus %1$s? + Apakah Anda yakin ingin menghapus %1$s? Apakah Anda yakin ingin menghapus %1$s dan isinya? Lokal saja Lokal saja - Dari server + Dari server Remot & lokal Penghapusan berhasil Penghapusan gagal @@@ -330,7 -328,6 +328,6 @@@ %1$d berkas, 1 folder %1$d berkas, %2$d folder Berbagi - Bagikan dengan Pengguna dan Grup Tidak ada data yang dibagikan dengan pengguna Tambah Pengguna atau Grup Cari diff --combined res/values-it/strings.xml index 3a2e02cb,a4e2e8ce..94986c6b --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@@ -82,9 -82,6 +82,6 @@@ Sincronizza Il file è stato rinominato in %1$s durante il caricamento Struttura elenco - Condividi collegamento - Rimuovi condivisione collegamento - Condividi con utenti Sì No OK @@@ -199,11 -196,11 +196,11 @@@ Rimuovi dai preferiti Rinomina Rimuovi - Vuoi davvero rimuovere %1$s? + Vuoi davvero rimuovere %1$s? Vuoi davvero rimuovere %1$s e il suo contenuto? Solo localmente Solo locale - Dal server + Dal server Remota e locale Rimozione effettuata con successo La rimozione non può essere completata @@@ -337,7 -334,6 +334,6 @@@ %1$d file, 1 cartella %1$d file, %2$d cartelle Condivisione - Condividi con utenti e gruppi Ancora nessun dato condiviso con gli utenti Aggiungi utente o gruppo Cerca diff --combined res/values-ja-rJP/strings.xml index d17876a8,8806e3d3..cb7a2a92 --- a/res/values-ja-rJP/strings.xml +++ b/res/values-ja-rJP/strings.xml @@@ -83,9 -83,6 +83,6 @@@ ファイルを同期 アップロード中にファイル名を %1$s に変更しました リストレイアウト - URLで共有 - 未共有のリンク - ユーザーと共有 はい いいえ OK @@@ -200,7 -197,7 +197,7 @@@ お気に入りを解除 名前を変更 削除 - 本当に %1$s を削除しますか? + 本当に %1$s を削除しますか? 本当に %1$s およびそのコンテンツを削除してもよろしいですか? ローカルのみ ローカルのみ @@@ -338,7 -335,6 +335,6 @@@ %1$d ファイル、1 フォルダー %1$d ファイル、%2$d フォルダー 共有 - ユーザーまたはグループに共有 ユーザーと共有されているデータはありません ユーザーまたはグループを追加 検索 diff --combined res/values-ko/strings.xml index c856bf33,0e6a06bb..3947cc36 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@@ -81,8 -81,6 +81,6 @@@ 다운로드 업로드 중 파일 이름을 %1$s(으)로 변경하였습니다 목록 레이아웃 - 링크 공유 - 링크 공유 해제 예 아니요 확인 @@@ -196,7 -194,7 +194,7 @@@ 책갈피 해제 이름 바꾸기 삭제 - %1$s을(를) 삭제하시겠습니까? + %1$s을(를) 삭제하시겠습니까? %1$s 및 포함된 내용을 삭제하시겠습니까? 로컬만 로컬만 @@@ -329,7 -327,6 +327,6 @@@ 파일 %1$d개, 폴더 1개 파일 %1$d개, 폴더 %2$d개 공유 - Share with Users and Groups No data shared with users yet Add User or Group 검색 diff --combined res/values-lb/strings.xml index 1c958f38,ce639de3..0e29ce56 --- a/res/values-lb/strings.xml +++ b/res/values-lb/strings.xml @@@ -62,7 -62,6 +62,6 @@@ Erstallt: Geännert: Eroflueden - Link deelen Jo Nee OK @@@ -140,7 -139,7 +139,7 @@@ De Server ënnerstëtzt dës Authentifizéierungsmethod net Ëmbenennen Läschen - Wëlls du %1$s wierklech läschen? + Wëlls du %1$s wierklech läschen? Wëlls du %1$s an de ganzen Inhalt wierklech läschen? Nemme lokal Nemme lokal diff --combined res/values-lt-rLT/strings.xml index 1459761d,035cf765..c7361320 --- a/res/values-lt-rLT/strings.xml +++ b/res/values-lt-rLT/strings.xml @@@ -82,8 -82,6 +82,6 @@@ Sinchronizuojama Įkėlimo metu failas buvo pervadintas į %1$s Sąrašo išdėstymas - Dalintis nuoroda - Nebesidalinti nuoroda Taip Ne Gerai @@@ -101,7 -99,7 +99,7 @@@ Katalogo pavadinimas Įkeliama ... %1$d%% Siunčiama %2$s - Nusiuntimas pavyko + Įkėlimas pavyko %1$s buvo sėkmingai nusiųstas Nusiuntimas nepavyko Nepavyko baigti %1$s nusiuntimo @@@ -197,7 -195,7 +195,7 @@@ Nebemėgti Pervadinti Pašalinti - Ar tikrai norite pašalinti %1$s? + Ar tikrai norite pašalinti %1$s? Ar tikrai norite pašalinti %1$s ir ten esantį turinį? Tik vietiniai Tik vietiniai @@@ -243,6 -241,9 +241,9 @@@ Iki: Parašas: Algoritmas: + Tavo telefonas nepalaiko digest algoritmo. + Kontrolinis kodas: + Klaida įkeliant sertifikatą. Sertifikatas negali būti parodytas. - Nėra informacijos apie klaidą Rezervas @@@ -331,5 -332,11 +332,11 @@@ %1$d failai, 1 aplankas %1$d failai, %2$d aplankai Dalijimasis + Su vartotojais niekuo nesidalinama + Pridėti vartotoją ar grupę Ieškoti + Surasti vartotoją ar grupę + %1$s (grupė) + Serveris nepalaiko dalinimosi su vartotojais kliente. + \nSusisiekite su administratoriumi. diff --combined res/values-mk/strings.xml index a2708d3c,692328f1..f1bc0094 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@@ -74,8 -74,6 +74,6 @@@ Изменето: Преземање Датотеката беше преименувана во %1$s за време на префрлањето - Сподели ја врската - Тргнете го споделувањето на врската Да Не Во ред @@@ -187,7 -185,7 +185,7 @@@ Сметката сеуште не постои на овој уред Преименувај Отстрани - Дали навистина сакаш да ја отстраниш %1$s? + Дали навистина сакаш да ја отстраниш %1$s? Дали навистина сакаш да го отстранам %1$s и неговата содржина? Само локално Само локално diff --combined res/values-nb-rNO/strings.xml index 95ad2e54,27f90646..a18743a2 --- a/res/values-nb-rNO/strings.xml +++ b/res/values-nb-rNO/strings.xml @@@ -81,8 -81,6 +81,6 @@@ Last ned Filnavnet ble endret til %1$s under opplasting Listeoppsett - Del lenke - Avslutt deling av lenke Ja Nei OK @@@ -196,11 -194,11 +194,11 @@@ Fjern favoritt Endre navn Fjern - Vil du virkelig fjerne %1$s? + Vil du virkelig fjerne %1$s? Vil du virkelig fjerne %1$s inkludert innholdet? Kun lokalt Kun lokalt - Fra server + Fra server Ekstern & lokal Fjerning var vellykket Fjerning mislyktes @@@ -330,7 -328,6 +328,6 @@@ %1$d filer, 1 mappe %1$d filer, %2$d mapper Deling - Del med brukere og grupper Ingen data delt med brukere ennå Legg til bruker eller gruppe Søk diff --combined res/values-nl/strings.xml index 9a3fa847,6183647d..8161fbab --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@@ -83,9 -83,6 +83,6 @@@ Download hier: %2$sSynchroniseren Bestand is tijdens het uploaden hernoemd naar %1$s Lijst layout - Deel link - Link niet meer delen - Delen met gebruiker Ja Nee OK @@@ -202,11 -199,11 +199,11 @@@ Hieronder staan de lokale bestanden en Niet meer favoriet Hernoemen Verwijderen - Wilt u %1$s werkelijk verwijderen? + Wilt u %1$s werkelijk verwijderen? Wilt u %1$s en de inhoud ervan werkelijk verwijderen? Alleen lokaal Alleen lokaal - Van server + Van server Extern & lokaal Succesvol verwijderd Verwijdering kon niet voltooid worden @@@ -340,7 -337,6 +337,6 @@@ %1$d bestanden, 1 map %1$d bestanden, %2$d mappen Delen - Delen met gebruikers en groepen Nog geen gegevens met gebruikers gedeeld Toevoegen gebruiker of groep Zoeken diff --combined res/values-oc/strings.xml index 5ba832c1,e2974594..9ef27933 --- a/res/values-oc/strings.xml +++ b/res/values-oc/strings.xml @@@ -83,9 -83,6 +83,6 @@@ Telecargatz-lo aicí : %2$sSincronizar Lo fichièr es estat renomenat en %s pendent lo mandadís Afichatge en lista - Partejar lo ligam - Partejar pas mai aqueste ligam - Partejar amb d\'Utilizaires Òc Non D\'acòrdi @@@ -204,11 -201,11 +201,11 @@@ En rason d\'aquesta modificacion, tote Suprimir dels favorits Renomenar Suprimir - Sètz segur que volètz suprimir %1$s ? + Sètz segur que volètz suprimir %1$s ? Sètz segur que volètz suprimir %1$s e son contengut ? Local solament Local solament - Dempuèi lo servidor + Dempuèi lo servidor Distant & local Supression efectuada amb succès Supression impossibla @@@ -338,7 -335,6 +335,6 @@@ %1$d fichièrs, 1 dorsièr %1$d fichièrs, %2$d dorsièrs Partiment - Partejar amb d\'utilizaires e de gropes Cap de donada es pas partejada amb d\'utilizaires pel moment Apondre un utilizaire o un grop Recercar diff --combined res/values-pl/strings.xml index f6a6f454,bf2e673c..ed223e9f --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@@ -80,8 -80,6 +80,6 @@@ Pobierz Podczas wysyłania nazwa pliku została zmieniona na %1$s Lista szablonów wyglądu - Udostępnij link - Anuluj udostępnianie Tak Nie OK @@@ -195,11 -193,11 +193,11 @@@ Usuń z ulubionych Zmień nazwę Usuń - Czy naprawdę chcesz usunąć %1$s? + Czy naprawdę chcesz usunąć %1$s? Czy naprawdę chcesz usunąć %1$s i jego zawartość? Tylko lokalnie Tylko lokalnie - Z serwera + Z serwera Usunięto Nie można usunąć Wprowadź nową nazwę diff --combined res/values-pt-rBR/strings.xml index 7b494cdd,689bd8f8..a0333fe7 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@@ -82,9 -82,6 +82,6 @@@ Sincronizar Arquivo foi renomeado para %1$s durante o envio Lista de Layout - Compartilhar link - Descompartilhar o link - Compartilhado com usuários Sim Não OK @@@ -199,11 -196,11 +196,11 @@@ Nãofavorito Renomear Remover - Você realmente deseja remover %1$s? + Você realmente deseja remover %1$s? Você realmente deseja remover %1$s e seus conteúdos? Somente local Somente local - Do servidor + Do servidor Remoto & local Removido com sucesso Erro ao remover @@@ -337,7 -334,6 +334,6 @@@ %1$d arquivos, 1 pasta %1$d arquivos, %2$d pastas Compartilhamento - Compartilhar com Usuários e Grupos Ainda não existe nenhum dado compartilhado com usuários Adicionar Usuário ou Grupo Perquisar diff --combined res/values-pt-rPT/strings.xml index a1adba9e,057c6383..ae23c23c --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@@ -82,8 -82,6 +82,6 @@@ Sincronizar O ficheiro foi renomeado para %1$s durante o envio. Apresentação da Lista - Partilhar a hiperligação - Cancelar partilha da hiperligação Sim Não ACEITAR @@@ -197,11 -195,11 +195,11 @@@ Retirar Favorito Renomear Remover - Tem a certeza que deseja remover %1$s ? + Tem a certeza que deseja remover %1$s ? Deseja realmente remover %1$s e o seu conteúdo? Apenas localmente Apenas localmente - Do servidor + Do servidor Remoto & local Removido com sucesso Não foi possível remover @@@ -331,7 -329,6 +329,6 @@@ %1$d ficheiros, 1 pasta %1$d ficheiros, %2$d pastas Partilha - Partilhar com Utilizadores e Grupos Ainda não foram partilhados os dados com os utilizadores Adicionar Utilziador ou Grupo Procurar diff --combined res/values-ro/strings.xml index b997bc9b,8466624e..195a31fc --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@@ -80,8 -80,6 +80,6 @@@ Descarcă Fișierul a fost redenumit %1$s în timpul încărcării Aspect listă - Partajază legătură - Departajează legătura Da Nu OK @@@ -195,11 -193,11 +193,11 @@@ Defavoritați Redenumește Elimină - Doriti sigur sa stergeti %1$s? + Doriti sigur sa stergeti %1$s? Sigur vrei să elimini %1$s și conținutul său? Doar local Doar local - De pe server + De pe server Ambele Eliminat cu succes Eliminarea nu a reușit diff --combined res/values-ru/strings.xml index 5f124531,63439931..7d2886dd --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@@ -82,8 -82,6 +82,6 @@@ Скачать Файл был переименован в %1$s во время загрузки Макет списка - Поделиться ссылкой - Убрать ссылку Да Нет ОК @@@ -197,7 -195,7 +195,7 @@@ Убрать из избранного Переименовать Удалить - Вы действительно хотите удалить %1$s? + Вы действительно хотите удалить %1$s? Вы действительно хотите удалить %1$s и его содержимое? Только локально Только локально @@@ -331,7 -329,6 +329,6 @@@ %1$d файлов, 1 каталог %1$d файлов, %2$d каталогов Общий доступ - Поделиться с пользователями или группами Нет данных используемых совместно с другими пользователями Добавить пользователя или группу Найти diff --combined res/values-sk-rSK/strings.xml index b48dc6e0,662073a3..13acac24 --- a/res/values-sk-rSK/strings.xml +++ b/res/values-sk-rSK/strings.xml @@@ -82,9 -82,6 +82,6 @@@ Synchronizovať Súbor bol premenovaný na %1$s počas nahrávania Rozvrhnutie zoznamu - Zdieľať linku - Zrušiť zdieľanie odkazu - Zdieľať s používateľmi Áno Nie OK @@@ -199,11 -196,11 +196,11 @@@ Odobrať z obľúbených Premenuj Odober - Naozaj chcete odstrániť %1$s? + Naozaj chcete odstrániť %1$s? Naozaj chcete odstrániť %1$s a jeho obsah? Iba lokálne Iba lokálne - Zo servera + Zo servera Vzdialene aj lokálne Úspešne odstránené Odstránenie zlyhalo @@@ -337,7 -334,6 +334,6 @@@ %1$d súb., 1 priečinok %1$d súb., %2$d prieč. Zdieľanie - Zdieľať s používateľmi alebo skupinami Zatiaľ s používateľmi nezdieľate žiadne dáta. Pridať používateľa alebo skupinu Hľadať diff --combined res/values-sl/strings.xml index 0b5a4a6b,bf177a4b..1c4c26fc --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@@ -80,8 -80,6 +80,6 @@@ Prejmi Datoteka je bila med nalaganjem preimenovana v %1$s Postavitev seznama - Povezava za souporabo - Odstrani možnost souporabe Da Ne V redu @@@ -195,11 -193,11 +193,11 @@@ Odstrani priljubljeno Preimenuj Odstrani - Ali res želite odstraniti %1$s? + Ali res želite odstraniti %1$s? Ali res želite odstraniti %1$s skupaj s celotno vsebino? Le krajevno Le krajevno - S strežnika + S strežnika Oddaljeno & krajevno Odstranitev je uspešno končana Odstranjevanje je spodletelo diff --combined res/values-sr/strings.xml index f38facb6,bb8c8fc0..f30a6ad6 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@@ -80,8 -80,6 +80,6 @@@ Преузми Фајл је преименован у %1$s током отпремања Распоред листе - Веза дељења - Не дели везом Да Не У реду @@@ -195,7 -193,7 +193,7 @@@ Неомиљени Преименуј Уклони - Желите да уклоните %1$s? + Желите да уклоните %1$s? Желите да уклоните %1$s и њен садржај? Само локално Само локално diff --combined res/values-sv/strings.xml index 6766749f,f35adc2a..4c2c962a --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@@ -73,8 -73,6 +73,6 @@@ Ändrad: Ladda ner Filen bytte namn till %1$s under uppladdningen - Dela länk - Sluta dela länk Ja Nej OK @@@ -177,7 -175,7 +175,7 @@@ Avfavoritisera Byt namn Radera - Vill du verkligen ta bort %1$s? + Vill du verkligen ta bort %1$s? Vill du verkligen ta bort %1$s och dess innehåll? Endast lokalt Endast lokalt diff --combined res/values-th-rTH/strings.xml index 1dc33c1d,f349bce8..adb5208f --- a/res/values-th-rTH/strings.xml +++ b/res/values-th-rTH/strings.xml @@@ -82,9 -82,6 +82,6 @@@ ประสานข้อมูล ไฟล์ได้ถูกเปลี่ยนชื่อเป็น %1$s ในระหว่างการอัพโหลด เค้าโครงรายการ - แชร์ลิงค์ - ยกเลิกการแชร์ลิงค์ - แชร์กับผู้ใช้ ตกลง ไม่ตกลง ตกลง @@@ -198,7 -195,7 +195,7 @@@ ออกจากรายการโปรด เปลี่ยนชื่อ ลบออก - คุณต้องการที่จะลบ %1$s? + คุณต้องการที่จะลบ %1$s? คุณต้องการที่จะลบ %1$s และเนื้อหาของมัน? เฉพาะต้นทางเท่านั้น เฉพาะต้นทางเท่านั้น @@@ -335,7 -332,6 +332,6 @@@ %1$d ไฟล์, 1 โฟลเดอร์ %1$d ไฟล์, %2$d โฟลเดอร์ การแชร์ข้อมูล - แชร์ไปยังผู้ใช้หรือกลุ่ม ยังไม่มีข้อมูลที่แชร์กับผู้ใช้ในตอนนี้ เพิ่มผู้ใช่หรือกลุ่ม ค้นหา diff --combined res/values-tr/strings.xml index 918e5e38,63e038ef..1dea4b82 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@@ -71,6 -71,7 +71,7 @@@ saniyeler önce Burada hiçbir şey yok. Bir şeyler yükleyin! Yükleniyor... + Dosya tipi için uygulama bulunamadı! Bu klasörde dosya yok. Ek bilgileri görmek için dosyaya dokunun. Boyut: @@@ -78,13 -79,13 +79,13 @@@ Oluşturulma: Değiştirilme: İndir + Eşitleme Dosya adı, yükleme sırasında %1$s olarak değiştirildi Liste Yerleşimi - Paylaşma bağlantısı - Bağlantı paylaşımını kaldır Evet Hayır Tamam + Eşitlemeyi iptal et İptal Kaydet ve Çık Hata @@@ -195,11 -196,11 +196,11 @@@ Favoriden kaldır Yeniden adlandır Kaldır - Gerçekten %1$s dosyasını kaldırmak istiyor musunuz? + Gerçekten %1$s dosyasını kaldırmak istiyor musunuz? Gerçekten %1$s ve içeriğini kaldırmak istediğinizden emin misiniz? Sadece yerel Sadece yerel - Sunucudan + Sunucudan Uzak ve yerel Kaldırma başarılı Kaldırma başarısız @@@ -241,6 -242,9 +242,9 @@@ Bitiş: İmza: Algoritma: + Özümlenen algoritma telefonunuz için mevcut değil + Parmak izi: + Sertifika yüklemesinde problem var. Sertifika gösterilemedi. - Hata hakkında bilgi yok Bu bir yer tutucudur @@@ -312,6 -316,7 +316,7 @@@ Anında Yüklemeler Güvenlik Video Yükleme Yolu + %1$s klasörünün eşitlemesi tamamlanamadı sizinle paylaştı %1$s, sizinle \"%2$s\" paylaşımını yaptı @@@ -329,5 -334,11 +334,11 @@@ %1$d dosya, 1 klasör %1$d dosya, %2$d klasör Paylaşım + Henüz kullanıcılara paylaşılan veri yok + Kullanıcı veya Grup ekle Ara + Kullanıcı ve Grupları Ara + %1$s (grup) + Üzgünüz sunucu versiyonunuz istemcilerdeki kullanıcılara paylaşıma izin vermiyor. + \nLütfen yöneticinize başvurun diff --combined res/values-uk/strings.xml index fed88cec,4402645d..ebe436bf --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@@ -81,8 -81,6 +81,6 @@@ Завантажити Файл був переіменований в %1$s протягом вивантаження Вигляд списку - Опублікувати посилання - Видалити посилання Так Ні OK @@@ -196,7 -194,7 +194,7 @@@ Прибрати з вибраного Перейменувати Видалити - Ви дійсно бажаєте видалити %1$s? + Ви дійсно бажаєте видалити %1$s? Ви дійсно бажаєте видалити %1$s та весь вміст? Лише локально Лише локально diff --combined res/values-zh-rCN/strings.xml index 39d4ea90,39031449..322abdaa --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@@ -81,8 -81,6 +81,6 @@@ 下载 上传过程中文件被更名为了 %1$s 列表布局 - 分享链接 - 取消分享链接 是 否 确定 @@@ -196,11 -194,11 +194,11 @@@ 取消收藏 重命名 删除 - 你确定要删除 %1$s 吗? + 你确定要删除 %1$s 吗? 您确定要删除 %1$s 及其内容吗? 仅本地 仅本地 - 来自服务器 + 来自服务器 远程 & 本地 成功删除 无法完成删除 diff --combined res/values-zh-rTW/strings.xml index c783957b,16a9e4b1..58e64baf --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@@ -80,8 -80,6 +80,6 @@@ 下載 檔案名稱在上傳時已被更改為 %1$s 列表版型 - 分享連結 - 取消共享連結 是 否 好 @@@ -195,11 -193,11 +193,11 @@@ 不喜愛的 重新命名 移除 - 您真的要移除 %1$s ? + 您真的要移除 %1$s ? 您真的要移除 %1$s 與裡頭的檔案? 只有本地 只有本地 - 來自伺服器 + 來自伺服器 遠端 & 本地 成功地移除 刪除失敗 @@@ -324,7 -322,6 +322,6 @@@ %1$d 個檔案, 1 個資料夾 %1$d 個檔案, %2$d 個資料夾 分享 - 與用戶或群組分享 目前沒有任何您分享的內容 新增使用者或是群組 搜尋 diff --combined res/values/strings.xml index 7625c94f,d5e18cf2..68597bfb --- a/res/values/strings.xml +++ b/res/values/strings.xml @@@ -23,7 -23,8 +23,7 @@@ All files - + On device Settings Logs Close @@@ -61,7 -62,7 +61,7 @@@ Connect Upload New folder - Choose upload folder: + Choose upload folder No account found There are no %1$s accounts on your device. Please setup an account first. Setup @@@ -84,9 -85,7 +84,7 @@@ Synchronize File was renamed to %1$s during upload List Layout - Share link - Unshare link - Share with users + Share Yes No OK @@@ -205,11 -204,11 +203,11 @@@ Unfavorite Rename Remove - "Do you really want to remove %1$s?" + "Do you really want to remove %1$s?" "Do you really want to remove %1$s and its contents?" Local only Local only - From server + From server Remote & local "Removal succeeded" "Removal failed" @@@ -265,11 -264,9 +263,11 @@@ 389 KB 2012/05/18 12:23 PM 12:23:45 - - Upload pictures via WiFi only - Upload videos via WiFi only + + Upload pictures via wifi only + Upload when charging only + Upload videos via wifi only + Upload when charging only /InstantUpload File conflict Which files do you want to keep? If you select both versions, the local file will have a number added to its name. @@@ -281,7 -278,7 +279,7 @@@ This image cannot be shown %1$s could not be copied to %2$s local folder - Upload Path + Upload path Sorry, sharing is not enabled on your server. Please contact your administrator. @@@ -289,6 -286,8 +287,8 @@@ An error occurred while trying to share this file or folder Unable to unshare. Please check whether the file exists An error occurred while trying to unshare this file or folder + Unable to update. Please check whether the file exists + An error occurred while trying to update the shared link Enter a password You must enter a password @@@ -310,27 -309,11 +310,28 @@@ to delete this file to share this file to unshare this file + to update this shared link to create the file to upload in this folder The file is no longer available on the server + Finish + Preparing for migration... + Checking destination... + Saving accounts configuration... + Waiting for unfinished synchronizations... + Moving data... + Updating index... + Cleaning... + Restoring accounts configuration... + Finished + ERROR: Not enough space + ERROR: File is not writable + ERROR: File is not readable + ERROR: owncloud directory already exists + ERROR: While migrating + ERROR: While updating index + Accounts Add account Secure connection is redirected through an unsecured route. @@@ -363,8 -346,7 +364,8 @@@ Instant Uploads Security - Upload Video Path + Upload video path + Download of %1$s folder could not be completed Synchronization of %1$s folder could not be completed shared @@@ -387,36 -369,17 +388,42 @@@ %1$d files %1$d files, 1 folder %1$d files, %2$d folders + Switch to grid view + Switch to list view + Common + Cache size + Upload file to server and ... + Behaviour + Copy file + Move file + Storage path + Common + + do nothing + copy file to OC folder + move file to OC folder + delete origin file + Do you really want to remove selected items? + Do you really want to remove a folder and its content? + selected items + Exit + Send Log + Error Log + Stream file with external player + Do you want to stream this file with an external app?\n\nCAUTION: This may expose your password! + Set picture as + Set As Sharing - Share with Users and Groups + Share with users and groups No data shared with users yet Add User or Group + Share link + Set expiration date + Password protect + Secured + Get link + Search Search users and groups @@@ -424,6 -387,5 +431,6 @@@ Sorry, your server version does not allow share with users within clients. \nPlease contact your administrator + https://github.com/owncloud/android/raw/beta/CHANGELOG.md diff --combined src/com/owncloud/android/datamodel/FileDataStorageManager.java index 4ce3d42a,af912365..3e073759 --- a/src/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/src/com/owncloud/android/datamodel/FileDataStorageManager.java @@@ -20,16 -20,6 +20,6 @@@ package com.owncloud.android.datamodel; - import java.io.File; - import java.util.ArrayList; - import java.util.Collection; - import java.util.Collections; - import java.util.HashSet; - import java.util.Iterator; - import java.util.List; - import java.util.Set; - import java.util.Vector; - import android.accounts.Account; import android.content.ContentProviderClient; import android.content.ContentProviderOperation; @@@ -53,6 -43,21 +43,21 @@@ import com.owncloud.android.lib.resourc import com.owncloud.android.lib.resources.status.OCCapability; import com.owncloud.android.utils.FileStorageUtils; + import java.io.File; + import java.io.FileInputStream; + import java.io.FileOutputStream; + import java.io.IOException; + import java.io.InputStream; + import java.io.OutputStream; + import java.util.ArrayList; + import java.util.Collection; + import java.util.Collections; + import java.util.HashSet; + import java.util.Iterator; + import java.util.List; + import java.util.Set; + import java.util.Vector; + public class FileDataStorageManager { public static final int ROOT_PARENT_ID = 0; @@@ -137,9 -142,10 +142,9 @@@ } - public Vector getFolderContent(OCFile f/*, boolean onlyOnDevice*/) { + public Vector getFolderContent(OCFile f, boolean onlyOnDevice) { if (f != null && f.isFolder() && f.getFileId() != -1) { - // TODO Enable when "On Device" is recovered ? - return getFolderContent(f.getFileId()/*, onlyOnDevice*/); + return getFolderContent(f.getFileId(), onlyOnDevice); } else { return new Vector(); @@@ -147,12 -153,13 +152,12 @@@ } - public Vector getFolderImages(OCFile folder/*, boolean onlyOnDevice*/) { - Vector ret = new Vector(); + public Vector getFolderImages(OCFile folder, boolean onlyOnDevice) { + Vector ret = new Vector(); if (folder != null) { // TODO better implementation, filtering in the access to database instead of here - // TODO Enable when "On Device" is recovered ? - Vector tmp = getFolderContent(folder/*, onlyOnDevice*/); - OCFile current = null; + Vector tmp = getFolderContent(folder, onlyOnDevice); + OCFile current = null; for (int i=0; i files = getFolderContent(folder.getFileId()/*, false*/); + Vector files = getFolderContent(folder.getFileId(), false); if (files != null) { for (OCFile file : files) { if (file.isFolder()) { @@@ -704,78 -712,46 +709,78 @@@ if (!targetFolder.exists()) { targetFolder.mkdirs(); } - copied = copyFile(localFile, targetFile); + copied = FileStorageUtils.copyFile(localFile, targetFile); } Log_OC.d(TAG, "Local file COPIED : " + copied); } } - private boolean copyFile(File src, File target) { - boolean ret = true; + public void migrateStoredFiles(String srcPath, String dstPath) throws Exception { + Cursor c = null; + if (getContentResolver() != null) { + c = getContentResolver().query(ProviderTableMeta.CONTENT_URI_FILE, + null, + ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL", + null, + null); + + } else { + try { + c = getContentProviderClient().query(ProviderTableMeta.CONTENT_URI_FILE, + new String[]{ProviderTableMeta._ID, ProviderTableMeta.FILE_STORAGE_PATH}, + ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL", + null, + null); + } catch (RemoteException e) { + Log_OC.e(TAG, e.getMessage()); + throw e; + } + } + + ArrayList operations = + new ArrayList(c.getCount()); + if (c.moveToFirst()) { + do { + ContentValues cv = new ContentValues(); + long fileId = c.getLong(c.getColumnIndex(ProviderTableMeta._ID)); + String oldFileStoragePath = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH)); + + if (oldFileStoragePath.startsWith(srcPath)) { - InputStream in = null; - OutputStream out = null; + cv.put( + ProviderTableMeta.FILE_STORAGE_PATH, + oldFileStoragePath.replaceFirst(srcPath, dstPath)); + operations.add( + ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI). + withValues(cv). + withSelection( + ProviderTableMeta._ID + "=?", + new String[]{String.valueOf(fileId)} + ) + .build()); + } + + } while (c.moveToNext()); + } + c.close(); + + /// 3. apply updates in batch try { - in = new FileInputStream(src); - out = new FileOutputStream(target); - byte[] buf = new byte[1024]; - int len; - while ((len = in.read(buf)) > 0) { - out.write(buf, 0, len); - } - } catch (IOException ex) { - ret = false; - } finally { - if (in != null) try { - in.close(); - } catch (IOException e) { - e.printStackTrace(System.err); - } - if (out != null) try { - out.close(); - } catch (IOException e) { - e.printStackTrace(System.err); + if (getContentResolver() != null) { + getContentResolver().applyBatch(MainApp.getAuthority(), operations); + + } else { + getContentProviderClient().applyBatch(operations); } - } - return ret; + } catch (Exception e) { + throw e; + } } - - private Vector getFolderContent(long parentId/*, boolean onlyOnDevice*/) { + + private Vector getFolderContent(long parentId, boolean onlyOnDevice) { Vector ret = new Vector(); @@@ -802,9 -778,10 +807,9 @@@ if (c.moveToFirst()) { do { OCFile child = createFileInstance(c); - // TODO Enable when "On Device" is recovered ? - // if (child.isFolder() || !onlyOnDevice || onlyOnDevice && child.isDown()){ - ret.add(child); - // } + if (child.isFolder() || !onlyOnDevice || onlyOnDevice && child.isDown()){ + ret.add(child); + } } while (c.moveToNext()); } @@@ -956,20 -933,20 +961,20 @@@ ); cv.put(ProviderTableMeta.OCSHARES_IS_DIRECTORY, share.isFolder() ? 1 : 0); cv.put(ProviderTableMeta.OCSHARES_USER_ID, share.getUserId()); - cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getIdRemoteShared()); + cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getRemoteId()); cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name); - if (shareExists(share.getIdRemoteShared())) {// for renamed files; no more delete and create + if (shareExists(share.getRemoteId())) {// for renamed files; no more delete and create overriden = true; if (getContentResolver() != null) { getContentResolver().update(ProviderTableMeta.CONTENT_URI_SHARE, cv, ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?", - new String[]{String.valueOf(share.getIdRemoteShared())}); + new String[]{String.valueOf(share.getRemoteId())}); } else { try { getContentProviderClient().update(ProviderTableMeta.CONTENT_URI_SHARE, cv, ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?", - new String[]{String.valueOf(share.getIdRemoteShared())}); + new String[]{String.valueOf(share.getRemoteId())}); } catch (RemoteException e) { Log_OC.e(TAG, "Fail to insert insert file to database " @@@ -1002,16 -979,42 +1007,42 @@@ } + /** + * Get first share bound to a file with a known path and given {@link ShareType}. + * + * @param path Path of the file. + * @param type Type of the share to get + * @param shareWith Target of the share. Ignored in type is {@link ShareType#PUBLIC_LINK} + * @return First {@OCShare} instance found in DB bound to the file in 'path' + */ public OCShare getFirstShareByPathAndType(String path, ShareType type, String shareWith) { Cursor c = null; + if (shareWith == null) { + shareWith = ""; + } String selection = ProviderTableMeta.OCSHARES_PATH + "=? AND " + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? AND " - + ProviderTableMeta.OCSHARES_SHARE_WITH + "=? AND " + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?" ; + if (!ShareType.PUBLIC_LINK.equals(type)) { + selection += " AND " + ProviderTableMeta.OCSHARES_SHARE_WITH + "=?"; + } - String [] selectionArgs = new String[]{path, Integer.toString(type.getValue()), - shareWith, mAccount.name}; + String [] selectionArgs; + if (ShareType.PUBLIC_LINK.equals(type)) { + selectionArgs = new String[]{ + path, + Integer.toString(type.getValue()), + mAccount.name + }; + } else { + selectionArgs = new String[]{ + path, + Integer.toString(type.getValue()), + mAccount.name, + shareWith + }; + } if (getContentResolver() != null) { c = getContentResolver().query( @@@ -1211,16 -1214,16 +1242,16 @@@ ); cv.put(ProviderTableMeta.OCSHARES_IS_DIRECTORY, share.isFolder() ? 1 : 0); cv.put(ProviderTableMeta.OCSHARES_USER_ID, share.getUserId()); - cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getIdRemoteShared()); + cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getRemoteId()); cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name); - if (shareExists(share.getIdRemoteShared())) { + if (shareExists(share.getRemoteId())) { // updating an existing file operations.add( ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI_SHARE). withValues(cv). withSelection(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?", - new String[]{String.valueOf(share.getIdRemoteShared())}) + new String[]{String.valueOf(share.getRemoteId())}) .build()); } else { // adding a new file @@@ -1424,6 -1427,30 +1455,30 @@@ // updateSharedFiles(sharedFiles); } + public void removeSharesForFile(String remotePath) { + resetShareFlagInAFile(remotePath); + ArrayList operations = new ArrayList(); + operations = prepareRemoveSharesInFile(remotePath, operations); + // apply operations in batch + if (operations.size() > 0) { + Log_OC.d(TAG, "Sending " + operations.size() + " operations to FileContentProvider"); + try { + if (getContentResolver() != null) { + getContentResolver().applyBatch(MainApp.getAuthority(), operations); + + } else { + getContentProviderClient().applyBatch(operations); + } + + } catch (OperationApplicationException e) { + Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage()); + + } catch (RemoteException e) { + Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage()); + } + } + } + public void saveSharesInFolder(ArrayList shares, OCFile folder) { resetShareFlagsInFolder(folder); @@@ -1484,7 -1511,7 +1539,7 @@@ ); cv.put(ProviderTableMeta.OCSHARES_IS_DIRECTORY, share.isFolder() ? 1 : 0); cv.put(ProviderTableMeta.OCSHARES_USER_ID, share.getUserId()); - cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getIdRemoteShared()); + cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getRemoteId()); cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name); // adding a new share resource @@@ -1505,8 -1532,9 +1560,8 @@@ + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?"; String [] whereArgs = new String[]{ "", mAccount.name }; - // TODO Enable when "On Device" is recovered ? - Vector files = getFolderContent(folder /*, false*/); - + Vector files = getFolderContent(folder, false); + for (OCFile file : files) { whereArgs[0] = file.getRemotePath(); preparedOperations.add( @@@ -1577,12 -1605,10 +1632,12 @@@ return shares; } - public void triggerMediaScan(String path) { - Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); - intent.setData(Uri.fromFile(new File(path))); - MainApp.getAppContext().sendBroadcast(intent); + public static void triggerMediaScan(String path) { + if (path != null) { + Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + intent.setData(Uri.fromFile(new File(path))); + MainApp.getAppContext().sendBroadcast(intent); + } } public void deleteFileInMediaScan(String path) { @@@ -1882,6 -1908,8 +1937,8 @@@ if (c.moveToFirst()) { capability = createCapabilityInstance(c); + } else { + capability = new OCCapability(); // return default with all UNKNOWN } c.close(); return capability; diff --combined src/com/owncloud/android/files/FileMenuFilter.java index 0b7eb811,e562af0f..65253033 --- a/src/com/owncloud/android/files/FileMenuFilter.java +++ b/src/com/owncloud/android/files/FileMenuFilter.java @@@ -184,34 -184,19 +184,19 @@@ public class FileMenuFilter } // SHARE FILE - // TODO add check on SHARE available on server side? boolean shareAllowed = (mContext != null && mContext.getString(R.string.share_feature).equalsIgnoreCase("on")); - if (!shareAllowed || mFile == null) { - toHide.add(R.id.action_share_file); - } else { - toShow.add(R.id.action_share_file); - } - - // UNSHARE FILE - // TODO add check on SHARE available on server side? - if ( !shareAllowed || (mFile == null || !mFile.isSharedViaLink())) { - toHide.add(R.id.action_unshare_file); - } else { - toShow.add(R.id.action_unshare_file); - } - - // SHARE FILE, with Users OCCapability capability = mComponentsGetter.getStorageManager().getCapability(mAccount.name); boolean shareApiEnabled = capability != null && - (capability.getFilesSharingApiEnabled().isTrue() || capability.getFilesSharingApiEnabled().isUnknown()); - if (!shareAllowed || mFile == null || !shareApiEnabled ) { - toHide.add(R.id.action_share_with_users); + (capability.getFilesSharingApiEnabled().isTrue() || + capability.getFilesSharingApiEnabled().isUnknown() + ); + if (!shareAllowed || mFile == null || !shareApiEnabled) { + toHide.add(R.id.action_share_file); } else { - toShow.add(R.id.action_share_with_users); + toShow.add(R.id.action_share_file); } - // SEE DETAILS if (mFile == null || mFile.isFolder()) { toHide.add(R.id.action_see_details); @@@ -242,20 -227,6 +227,20 @@@ toShow.add(R.id.action_unfavorite_file); } + // STREAM + if (mFile != null && !mFile.isDown() && (mFile.isAudio() || mFile.isVideo())){ + toShow.add(R.id.action_stream_file); + } else { + toHide.add(R.id.action_stream_file); + } + + // SET PICTURE AS + if (mFile == null || !mFile.isImage()){ + toHide.add(R.id.action_set_as_wallpaper); + } else { + toShow.add(R.id.action_set_as_wallpaper); + } + } } diff --combined src/com/owncloud/android/files/FileOperationsHelper.java index f5050d4d,5ce6cc30..989b8487 --- a/src/com/owncloud/android/files/FileOperationsHelper.java +++ b/src/com/owncloud/android/files/FileOperationsHelper.java @@@ -25,20 -25,16 +25,20 @@@ import android.accounts.Account import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; +import android.graphics.Bitmap; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.graphics.Bitmap; import android.net.Uri; import android.support.v4.app.DialogFragment; import android.webkit.MimeTypeMap; import android.widget.Toast; +import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.authentication.AccountUtils; import com.owncloud.android.datamodel.OCFile; +import com.owncloud.android.datamodel.ThumbnailsCacheManager; import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder; import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; import com.owncloud.android.lib.common.network.WebdavUtils; @@@ -48,24 -44,11 +48,24 @@@ import com.owncloud.android.lib.resourc import com.owncloud.android.services.OperationsService; import com.owncloud.android.services.observer.FileObserverService; import com.owncloud.android.ui.activity.FileActivity; +import com.owncloud.android.ui.adapter.DiskLruImageCacheFileProvider; import com.owncloud.android.ui.activity.ShareActivity; import com.owncloud.android.ui.dialog.ShareLinkToDialog; + import com.owncloud.android.ui.dialog.SharePasswordDialogFragment; - import org.apache.http.protocol.HTTP; +import java.io.File; +import java.util.List; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +import org.apache.http.protocol.HTTP; + +import java.util.ArrayList; import java.util.List; /** @@@ -156,19 -139,32 +156,32 @@@ public class FileOperationsHelper .show(); } - public void shareFileWithLink(OCFile file) { + /** + * Helper method to share a file via a public link. Starts a request to do it in {@link OperationsService} + * + * @param file The file to share. + * @param password Optional password to protect the public share. + */ + public void shareFileViaLink(OCFile file, String password) { if (isSharedSupported()) { if (file != null) { - String link = "https://fake.url"; - Intent intent = createShareWithLinkIntent(link); - String[] packagesToExclude = new String[]{mFileActivity.getPackageName()}; - DialogFragment chooserDialog = ShareLinkToDialog.newInstance(intent, - packagesToExclude, file); - chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG); + mFileActivity.showLoadingDialog( + mFileActivity.getApplicationContext(). + getString(R.string.wait_a_moment) + ); + Intent service = new Intent(mFileActivity, OperationsService.class); + service.setAction(OperationsService.ACTION_CREATE_SHARE_VIA_LINK); + service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount()); + if (password != null && password.length() > 0) { + service.putExtra(OperationsService.EXTRA_SHARE_PASSWORD, password); + } + service.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath()); + mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service); } else { Log_OC.wtf(TAG, "Trying to share a NULL OCFile"); + // TODO user-level error? } } else { @@@ -181,6 -177,30 +194,30 @@@ } } + public void getFileWithLink(OCFile file){ + if (isSharedSupported()) { + if (file != null) { + mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext(). + getString(R.string.wait_a_moment)); + + Intent service = new Intent(mFileActivity, OperationsService.class); + service.setAction(OperationsService.ACTION_CREATE_SHARE_VIA_LINK); + service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount()); + service.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath()); + mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service); + + } else { + Log_OC.wtf(TAG, "Trying to share a NULL OCFile"); + } + } else { + // Show a Message + Toast t = Toast.makeText( + mFileActivity, mFileActivity.getString(R.string.share_link_no_support_share_api), + Toast.LENGTH_LONG + ); + t.show(); + } + } public void shareFileWithLinkToApp(OCFile file, String password, Intent sendIntent) { @@@ -192,7 -212,7 +229,7 @@@ service.setAction(OperationsService.ACTION_CREATE_SHARE_VIA_LINK); service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount()); service.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath()); - service.putExtra(OperationsService.EXTRA_PASSWORD_SHARE, password); + service.putExtra(OperationsService.EXTRA_SHARE_PASSWORD, password); service.putExtra(OperationsService.EXTRA_SEND_INTENT, sendIntent); mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service); @@@ -201,17 -221,8 +238,8 @@@ } } - - private Intent createShareWithLinkIntent(String link) { - Intent intentToShareLink = new Intent(Intent.ACTION_SEND); - intentToShareLink.putExtra(Intent.EXTRA_TEXT, link); - intentToShareLink.setType(HTTP.PLAIN_TEXT_TYPE); - return intentToShareLink; - } - - /** - * Helper method to share a file with a know sharee. Starts a request to do it in {@link OperationsService} + * Helper method to share a file with a known sharee. Starts a request to do it in {@link OperationsService} * * @param file The file to share. * @param shareeName Name (user name or group name) of the target sharee. @@@ -249,7 -260,13 +277,13 @@@ } - public void unshareFileWithLink(OCFile file) { + /** + * Helper method to unshare a file publicly shared via link. + * Starts a request to do it in {@link OperationsService} + * + * @param file The file to unshare. + */ + public void unshareFileViaLink(OCFile file) { // Unshare the file: Create the intent Intent unshareService = new Intent(mFileActivity, OperationsService.class); @@@ -259,7 -276,7 +293,7 @@@ unshareService.putExtra(OperationsService.EXTRA_SHARE_TYPE, ShareType.PUBLIC_LINK); unshareService.putExtra(OperationsService.EXTRA_SHARE_WITH, ""); - unshareFile(unshareService); + queueShareIntent(unshareService); } public void unshareFileWithUserOrGroup(OCFile file, ShareType shareType, String userOrGroup){ @@@ -272,15 -289,15 +306,15 @@@ unshareService.putExtra(OperationsService.EXTRA_SHARE_TYPE, shareType); unshareService.putExtra(OperationsService.EXTRA_SHARE_WITH, userOrGroup); - unshareFile(unshareService); + queueShareIntent(unshareService); } - private void unshareFile(Intent unshareService){ + private void queueShareIntent(Intent shareIntent){ if (isSharedSupported()) { // Unshare the file mWaitingForOpId = mFileActivity.getOperationsServiceBinder(). - queueNewOperation(unshareService); + queueNewOperation(shareIntent); mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext(). getString(R.string.wait_a_moment)); @@@ -310,6 -327,67 +344,67 @@@ /** + * Starts a dialog that requests a password to the user to protect a share link. + * + * @param file File which public share will be protected by the requested password + * @param createShare When 'true', the request for password will be followed by the creation of a new + * public link; when 'false', a public share is assumed to exist, and the password + * is bound to it. + */ + public void requestPasswordForShareViaLink(OCFile file, boolean createShare) { + SharePasswordDialogFragment dialog = + SharePasswordDialogFragment.newInstance(file, createShare); + dialog.show( + mFileActivity.getSupportFragmentManager(), + SharePasswordDialogFragment.PASSWORD_FRAGMENT + ); + } + + /** + * Updates a public share on a file to set its password. + * Starts a request to do it in {@link OperationsService} + * + * @param file File which public share will be protected with a password. + * @param password Password to set for the public link; null or empty string to clear + * the current password + */ + public void setPasswordToShareViaLink(OCFile file, String password) { + // Set password updating share + Intent updateShareIntent = new Intent(mFileActivity, OperationsService.class); + updateShareIntent.setAction(OperationsService.ACTION_UPDATE_SHARE); + updateShareIntent.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount()); + updateShareIntent.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath()); + updateShareIntent.putExtra( + OperationsService.EXTRA_SHARE_PASSWORD, + (password == null) ? "" : password + ); + + queueShareIntent(updateShareIntent); + } + + + /** + * Updates a public share on a file to set its expiration date. + * Starts a request to do it in {@link OperationsService} + * + * @param file File which public share will be constrained with an expiration date. + * @param expirationTimeInMillis Expiration date to set. A negative value clears the current expiration + * date, leaving the link unrestricted. Zero makes no change. + */ + public void setExpirationDateToShareViaLink(OCFile file, long expirationTimeInMillis) { + Intent updateShareIntent = new Intent(mFileActivity, OperationsService.class); + updateShareIntent.setAction(OperationsService.ACTION_UPDATE_SHARE); + updateShareIntent.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount()); + updateShareIntent.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath()); + updateShareIntent.putExtra( + OperationsService.EXTRA_SHARE_EXPIRATION_DATE_IN_MILLIS, + expirationTimeInMillis + ); + queueShareIntent(updateShareIntent); + } + + + /** * @return 'True' if the server supports the Search Users API */ public boolean isSearchUsersSupportedSupported() { @@@ -332,8 -410,7 +427,7 @@@ // Show dialog, without the own app String[] packagesToExclude = new String[]{mFileActivity.getPackageName()}; - DialogFragment chooserDialog = ShareLinkToDialog.newInstance(sendIntent, - packagesToExclude, file); + DialogFragment chooserDialog = ShareLinkToDialog.newInstance(sendIntent, packagesToExclude); chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG); } else { @@@ -341,65 -418,6 +435,65 @@@ } } + public void setPictureAs(OCFile file) { + if (file != null){ + if (file.isDown()) { + File externalFile = new File(file.getStoragePath()); + Uri sendUri = Uri.fromFile(externalFile); + Intent intent = new Intent(Intent.ACTION_ATTACH_DATA); + intent.setDataAndType(sendUri, file.getMimetype()); + intent.putExtra("mimeType", file.getMimetype()); + mFileActivity.startActivityForResult(Intent.createChooser(intent, + mFileActivity.getString(R.string.set_as)), 200); + } else { + // TODO re-enable after resized images is available + Uri sendUri = Uri.parse("content://" + DiskLruImageCacheFileProvider.AUTHORITY + file.getRemotePath()); + Intent intent = new Intent(Intent.ACTION_ATTACH_DATA); + intent.setDataAndType(sendUri, file.getMimetype()); + intent.putExtra("mimeType", file.getMimetype()); + mFileActivity.startActivityForResult(Intent.createChooser(intent, "Set As"), 200); + +// Intent sendIntent = new Intent(android.content.Intent.ACTION_SEND); +// // set MimeType +// sendIntent.setType(file.getMimetype()); +//// sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" + DiskLruImageCacheFileProvider.AUTHORITY + "/#" + file.getRemoteId() + "#" + file.getFileName())); +// sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" + DiskLruImageCacheFileProvider.AUTHORITY + file.getRemotePath())); +// sendIntent.putExtra(Intent.ACTION_SEND, true); // Send Action +// +// // Show dialog, without the own app +// String[] packagesToExclude = new String[] { mFileActivity.getPackageName() }; +// DialogFragment chooserDialog = ShareLinkToDialog.newInstance(sendIntent, packagesToExclude, file); +// chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG); + } + } else { + Log_OC.wtf(TAG, "Trying to send a NULL OCFile"); + } + } + + public void sendCachedImage(OCFile file) { + if (file != null) { + Intent sendIntent = new Intent(android.content.Intent.ACTION_SEND); + // set MimeType + sendIntent.setType(file.getMimetype()); +// sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" + DiskLruImageCacheFileProvider.AUTHORITY + "/#" + file.getRemoteId() + "#" + file.getFileName())); + sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" + DiskLruImageCacheFileProvider.AUTHORITY + file.getRemotePath())); + sendIntent.putExtra(Intent.ACTION_SEND, true); // Send Action + + // Show dialog, without the own app + String[] packagesToExclude = new String[] { mFileActivity.getPackageName() }; + DialogFragment chooserDialog = ShareLinkToDialog.newInstance(sendIntent, packagesToExclude, file); + chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG); + } else { + Log_OC.wtf(TAG, "Trying to send a NULL OCFile"); + } + } + + public void syncFiles(ArrayList files) { + for (OCFile file: files) { + syncFile(file); + } + } + /** * Request the synchronization of a file or folder with the OC server, including its contents. * @@@ -426,12 -444,6 +520,12 @@@ } } + public void toggleFavorites(ArrayList files, boolean isFavorite){ + for (OCFile file: files) { + toggleFavorite(file, isFavorite); + } + } + public void toggleFavorite(OCFile file, boolean isFavorite) { file.setFavorite(isFavorite); mFileActivity.getStorageManager().saveFile(file); @@@ -531,9 -543,8 +625,9 @@@ service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount()); mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service); - mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext(). - getString(R.string.wait_a_moment)); + // TODO Tobi loading dialog? +// mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext(). +// getString(R.string.wait_a_moment)); } /** @@@ -575,4 -586,5 +669,5 @@@ } return false; } + } diff --combined src/com/owncloud/android/operations/RefreshFolderOperation.java index 87dde21d,368833e5..f9f9e8c9 --- a/src/com/owncloud/android/operations/RefreshFolderOperation.java +++ b/src/com/owncloud/android/operations/RefreshFolderOperation.java @@@ -197,7 -197,7 +197,7 @@@ public class RefreshFolderOperation ext result = fetchAndSyncRemoteFolder(client); } else { fetchFavoritesToSyncFromLocalData(); - mChildren = mStorageManager.getFolderContent(mLocalFolder/*, false*/); + mChildren = mStorageManager.getFolderContent(mLocalFolder, false); } if (result.isSuccess()) { @@@ -246,7 -246,7 +246,7 @@@ GetCapabilitiesOperarion getCapabilities = new GetCapabilitiesOperarion(); RemoteOperationResult result = getCapabilities.execute(mStorageManager,mContext); if (!result.isSuccess()){ - Log_OC.d(TAG, "Update Capabilities unsuccessfully"); + Log_OC.w(TAG, "Update Capabilities unsuccessfully"); } } @@@ -361,7 -361,8 +361,7 @@@ mFilesToSyncContents.clear(); // get current data about local contents of the folder to synchronize - // TODO Enable when "On Device" is recovered ? - List localFiles = mStorageManager.getFolderContent(mLocalFolder/*, false*/); + List localFiles = mStorageManager.getFolderContent(mLocalFolder, false); Map localFilesMap = new HashMap(localFiles.size()); for (OCFile file : localFiles) { localFilesMap.put(file.getRemotePath(), file); @@@ -524,7 -525,7 +524,7 @@@ private void fetchFavoritesToSyncFromLocalData() { - List children = mStorageManager.getFolderContent(mLocalFolder); + List children = mStorageManager.getFolderContent(mLocalFolder, false); for (OCFile child : children) { if (!child.isFolder() && child.isFavorite()) { SynchronizeFileOperation operation = new SynchronizeFileOperation( diff --combined src/com/owncloud/android/ui/activity/FileActivity.java index 275f5d63,99e4c91f..8a794436 --- a/src/com/owncloud/android/ui/activity/FileActivity.java +++ b/src/com/owncloud/android/ui/activity/FileActivity.java @@@ -67,12 -67,14 +67,14 @@@ import com.owncloud.android.lib.common. import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.utils.Log_OC; + import com.owncloud.android.lib.resources.status.OCCapability; import com.owncloud.android.operations.CreateShareViaLinkOperation; import com.owncloud.android.operations.CreateShareWithShareeOperation; import com.owncloud.android.operations.GetSharesForFileOperation; import com.owncloud.android.operations.SynchronizeFileOperation; import com.owncloud.android.operations.SynchronizeFolderOperation; import com.owncloud.android.operations.UnshareOperation; + import com.owncloud.android.operations.UpdateShareViaLinkOperation; import com.owncloud.android.services.OperationsService; import com.owncloud.android.services.OperationsService.OperationsServiceBinder; import com.owncloud.android.ui.NavigationDrawerItem; @@@ -93,8 -95,6 +95,6 @@@ public class FileActivity extends AppCo public static final String EXTRA_FILE = "com.owncloud.android.ui.activity.FILE"; public static final String EXTRA_ACCOUNT = "com.owncloud.android.ui.activity.ACCOUNT"; - public static final String EXTRA_WAITING_TO_PREVIEW = - "com.owncloud.android.ui.activity.WAITING_TO_PREVIEW"; public static final String EXTRA_FROM_NOTIFICATION = "com.owncloud.android.ui.activity.FROM_NOTIFICATION"; @@@ -113,9 -113,13 +113,13 @@@ /** OwnCloud {@link Account} where the main {@link OCFile} handled by the activity is located.*/ private Account mAccount; - /** Main {@link OCFile} handled by the activity.*/ + /** Capabilites of the server where {@link #mAccount} lives */ + private OCCapability mCapabilities; + + /** Main {@link OCFile} handled by the activity.*/ private OCFile mFile; + /** Flag to signal that the activity will is finishing to enforce the creation of an ownCloud * {@link Account} */ private boolean mRedirectingToSetupAccount = false; @@@ -141,12 -145,12 +145,12 @@@ private OperationsServiceBinder mOperationsServiceBinder = null; + private boolean mResumed = false; + protected FileDownloaderBinder mDownloaderBinder = null; protected FileUploaderBinder mUploaderBinder = null; private ServiceConnection mDownloadServiceConnection, mUploadServiceConnection = null; - private boolean mTryShareAgain = false; - // Navigation Drawer protected DrawerLayout mDrawerLayout; protected ActionBarDrawerToggle mDrawerToggle; @@@ -161,6 -165,7 +165,7 @@@ protected NavigationDrawerListAdapter mNavigationDrawerAdapter = null; + // TODO re-enable when "Accounts" is available in Navigation Drawer // protected boolean mShowAccounts = false; @@@ -183,7 -188,6 +188,6 @@@ mFileOperationsHelper.setOpIdWaitingFor( savedInstanceState.getLong(KEY_WAITING_FOR_OP_ID, Long.MAX_VALUE) ); - mTryShareAgain = savedInstanceState.getBoolean(KEY_TRY_SHARE_AGAIN); if (getSupportActionBar() != null) { getSupportActionBar().setTitle(savedInstanceState.getString(KEY_ACTION_BAR_TITLE)); } @@@ -255,7 -259,7 +259,7 @@@ @Override protected void onResume() { super.onResume(); - + mResumed = true; if (mOperationsServiceBinder != null) { doOnResumeAndBound(); } @@@ -266,7 -270,7 +270,7 @@@ if (mOperationsServiceBinder != null) { mOperationsServiceBinder.removeOperationListener(this); } - + mResumed = false; super.onPause(); } @@@ -367,7 -371,12 +371,7 @@@ // } // Display username in drawer - Account account = AccountUtils.getCurrentOwnCloudAccount(getApplicationContext()); - if (account != null) { - TextView username = (TextView) navigationDrawerLayout.findViewById(R.id.drawer_username); - int lastAtPos = account.name.lastIndexOf("@"); - username.setText(account.name.substring(0, lastAtPos)); - } + setUsernameInDrawer(navigationDrawerLayout, AccountUtils.getCurrentOwnCloudAccount(getApplicationContext())); // load slide menu items mDrawerTitles = getResources().getStringArray(R.array.drawer_items); @@@ -387,17 -396,18 +391,17 @@@ mDrawerItems.add(new NavigationDrawerItem(mDrawerTitles[0], mDrawerContentDescriptions[0], R.drawable.ic_folder_open)); - // TODO Enable when "On Device" is recovered // On Device - //mDrawerItems.add(new NavigationDrawerItem(mDrawerTitles[2], - // mDrawerContentDescriptions[2])); + mDrawerItems.add(new NavigationDrawerItem(mDrawerTitles[1], mDrawerContentDescriptions[1], + R.drawable.ic_action_download_grey)); // Settings - mDrawerItems.add(new NavigationDrawerItem(mDrawerTitles[1], mDrawerContentDescriptions[1], - R.drawable.ic_settings)); + mDrawerItems.add(new NavigationDrawerItem(mDrawerTitles[2], mDrawerContentDescriptions[2], + R.drawable.ic_action_settings)); // Logs if (BuildConfig.DEBUG) { - mDrawerItems.add(new NavigationDrawerItem(mDrawerTitles[2], - mDrawerContentDescriptions[2],R.drawable.ic_log)); + mDrawerItems.add(new NavigationDrawerItem(mDrawerTitles[3], + mDrawerContentDescriptions[3],R.drawable.ic_log)); } // setting the nav drawer list adapter @@@ -433,21 -443,6 +437,21 @@@ } /** + * sets the given account name in the drawer in case the drawer is available. The account name + * is shortened beginning from the @-sign in the username. + * + * @param navigationDrawerLayout the drawer layout to be used + * @param account the account to be set in the drawer + */ + protected void setUsernameInDrawer(RelativeLayout navigationDrawerLayout, Account account) { + if (navigationDrawerLayout != null && getAccount() != null) { + TextView username = (TextView) navigationDrawerLayout.findViewById(R.id.drawer_username); + int lastAtPos = account.name.lastIndexOf("@"); + username.setText(account.name.substring(0, lastAtPos)); + } + } + + /** * Updates title bar and home buttons (state and icon). * * Assumes that navigation drawer is NOT visible. @@@ -563,7 -558,6 +567,6 @@@ outState.putParcelable(FileActivity.EXTRA_FILE, mFile); outState.putBoolean(FileActivity.EXTRA_FROM_NOTIFICATION, mFromNotification); outState.putLong(KEY_WAITING_FOR_OP_ID, mFileOperationsHelper.getOpIdWaitingFor()); - outState.putBoolean(KEY_TRY_SHARE_AGAIN, mTryShareAgain); if(getSupportActionBar() != null && getSupportActionBar().getTitle() != null) { // Null check in case the actionbar is used in ActionBar.NAVIGATION_MODE_LIST // since it doesn't have a title then @@@ -607,6 -601,18 +610,18 @@@ mAccount = account; } + + /** + * Getter for the capabilities of the server where the current OC account lives. + * + * @return Capabilities of the server where the current OC account lives. Null if the account is not + * set yet. + */ + public OCCapability getCapabilities() { + return mCapabilities; + } + + /** * @return Value of mFromNotification: True if the Activity is launched by a notification */ @@@ -621,14 -627,6 +636,6 @@@ return mRedirectingToSetupAccount; } - public boolean isTryShareAgain(){ - return mTryShareAgain; - } - - public void setTryShareAgain(boolean tryShareAgain) { - mTryShareAgain = tryShareAgain; - } - public OperationsServiceBinder getOperationsServiceBinder() { return mOperationsServiceBinder; } @@@ -685,6 -683,7 +692,7 @@@ protected void onAccountSet(boolean stateWasRecovered) { if (getAccount() != null) { mStorageManager = new FileDataStorageManager(getAccount(), getContentResolver()); + mCapabilities = mStorageManager.getCapability(mAccount.name); } else { Log_OC.wtf(TAG, "onAccountChanged was called with NULL account associated!"); @@@ -739,12 -738,12 +747,12 @@@ Toast.LENGTH_LONG); t.show(); } - mTryShareAgain = false; } else if (operation == null || operation instanceof CreateShareWithShareeOperation || operation instanceof UnshareOperation || - operation instanceof SynchronizeFolderOperation + operation instanceof SynchronizeFolderOperation || + operation instanceof UpdateShareViaLinkOperation ) { if (result.isSuccess()) { updateFileFromDB(); @@@ -763,10 -762,10 +771,10 @@@ onSynchronizeFileOperationFinish((SynchronizeFileOperation) operation, result); } else if (operation instanceof GetSharesForFileOperation) { - if (result.isSuccess()) { + if (result.isSuccess() || result.getCode() == ResultCode.SHARE_NOT_FOUND) { updateFileFromDB(); - } else if (result.getCode() != ResultCode.SHARE_NOT_FOUND) { + } else { Toast t = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), Toast.LENGTH_LONG); @@@ -790,25 -789,31 +798,31 @@@ private void onCreateShareViaLinkOperationFinish(CreateShareViaLinkOperation operation, RemoteOperationResult result) { if (result.isSuccess()) { - mTryShareAgain = false; updateFileFromDB(); Intent sendIntent = operation.getSendIntentWithSubject(this); - startActivity(sendIntent); + if (sendIntent != null) { + startActivity(sendIntent); + } + } else { // Detect Failure (403) --> needs Password if (result.getCode() == ResultCode.SHARE_FORBIDDEN) { - if (!isTryShareAgain()) { + String password = operation.getPassword(); + if ((password == null || password.length() == 0) && + getCapabilities().getFilesSharingPublicEnabled().isUnknown()) + { + // Was tried without password, but not sure that it's optional. Try with password. + // Try with password before giving up. + // See also ShareFileFragment#OnShareViaLinkListener SharePasswordDialogFragment dialog = - SharePasswordDialogFragment.newInstance(new OCFile(operation.getPath()), - operation.getSendIntent()); + SharePasswordDialogFragment.newInstance(new OCFile(operation.getPath()), true); dialog.show(getSupportFragmentManager(), DIALOG_SHARE_PASSWORD); } else { Toast t = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), Toast.LENGTH_LONG); t.show(); - mTryShareAgain = false; } } else { Toast t = Toast.makeText(this, @@@ -868,7 -873,6 +882,7 @@@ public void dismissLoadingDialog() { Fragment frag = getSupportFragmentManager().findFragmentByTag(DIALOG_WAIT_TAG); if (frag != null) { + Log_OC.d(TAG, "dismiss loading dialog"); LoadingDialog loading = (LoadingDialog) frag; loading.dismiss(); } @@@ -901,7 -905,9 +915,9 @@@ /*if (!mOperationsServiceBinder.isPerformingBlockingOperation()) { dismissLoadingDialog(); }*/ - doOnResumeAndBound(); + if (mResumed) { + doOnResumeAndBound(); + } } else { return; @@@ -938,12 -944,6 +954,12 @@@ startActivity(i); } + public void refresh(){ + Intent i = new Intent(this, FileDisplayActivity.class); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(i); + } + // TODO re-enable when "Accounts" is available in Navigation Drawer // public void closeDrawer() { // mDrawerLayout.closeDrawers(); @@@ -953,10 -953,6 +969,10 @@@ restart(); } + public void refreshDirectory(){ + // overridden by FileDisplayActivity + } + private class DrawerItemClickListener implements ListView.OnItemClickListener { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { @@@ -973,25 -969,24 +989,25 @@@ // break; case 0: // All Files - allFilesOption(); + MainApp.showOnlyFilesOnDevice(false); + refreshDirectory(); mDrawerLayout.closeDrawers(); break; - // TODO Enable when "On Device" is recovered ? -// case 2: -// MainApp.showOnlyFilesOnDevice(true); -// mDrawerLayout.closeDrawers(); -// break; + case 1: // On Device + MainApp.showOnlyFilesOnDevice(true); + refreshDirectory(); + mDrawerLayout.closeDrawers(); + break; - case 1: // Settings + case 2: // Settings Intent settingsIntent = new Intent(getApplicationContext(), Preferences.class); startActivity(settingsIntent); mDrawerLayout.closeDrawers(); break; - case 2: // Logs + case 3: // Logs Intent loggerIntent = new Intent(getApplicationContext(), LogHistoryActivity.class); startActivity(loggerIntent); diff --combined src/com/owncloud/android/ui/activity/FileDisplayActivity.java index 39649ef4,f09ed6c7..e69eb047 --- a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java +++ b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java @@@ -26,8 -26,6 +26,8 @@@ import android.accounts.Account import android.accounts.AccountManager; import android.accounts.AuthenticatorException; import android.annotation.TargetApi; +import android.os.Parcelable; +import android.support.v7.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; @@@ -51,6 -49,7 +51,7 @@@ import android.support.v4.app.FragmentM import android.support.v4.app.FragmentTransaction; import android.support.v4.content.ContextCompat; import android.support.v4.view.GravityCompat; + import android.support.v7.app.AlertDialog; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@@ -80,14 -79,11 +81,11 @@@ import com.owncloud.android.lib.common. import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.operations.CopyFileOperation; import com.owncloud.android.operations.CreateFolderOperation; - import com.owncloud.android.operations.CreateShareViaLinkOperation; - import com.owncloud.android.operations.CreateShareWithShareeOperation; import com.owncloud.android.operations.MoveFileOperation; import com.owncloud.android.operations.RefreshFolderOperation; import com.owncloud.android.operations.RemoveFileOperation; import com.owncloud.android.operations.RenameFileOperation; import com.owncloud.android.operations.SynchronizeFileOperation; - import com.owncloud.android.operations.UnshareOperation; import com.owncloud.android.services.observer.FileObserverService; import com.owncloud.android.syncadapter.FileSyncAdapter; import com.owncloud.android.ui.dialog.ConfirmationDialogFragment; @@@ -109,8 -105,6 +107,8 @@@ import com.owncloud.android.utils.FileS import com.owncloud.android.utils.UriUtils; import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; /** * Displays, what files the user has available in his ownCloud. @@@ -151,14 -145,13 +149,14 @@@ public class FileDisplayActivity extend private boolean mSyncInProgress = false; private static String DIALOG_UNTRUSTED_CERT = "DIALOG_UNTRUSTED_CERT"; - private static String DIALOG_CREATE_FOLDER = "DIALOG_CREATE_FOLDER"; + public static String DIALOG_CREATE_FOLDER = "DIALOG_CREATE_FOLDER"; private static String DIALOG_UPLOAD_SOURCE = "DIALOG_UPLOAD_SOURCE"; private static String DIALOG_CERT_NOT_SAVED = "DIALOG_CERT_NOT_SAVED"; private OCFile mWaitingToSend; + private Menu mOptionsMenu; + - @Override protected void onCreate(Bundle savedInstanceState) { Log_OC.v(TAG, "onCreate() start"); @@@ -275,7 -268,12 +273,7 @@@ setFile(file); if (mAccountWasSet) { - RelativeLayout navigationDrawerLayout = (RelativeLayout) findViewById(R.id.left_drawer); - if (navigationDrawerLayout != null && getAccount() != null) { - TextView username = (TextView) navigationDrawerLayout.findViewById(R.id.drawer_username); - int lastAtPos = getAccount().name.lastIndexOf("@"); - username.setText(getAccount().name.substring(0, lastAtPos)); - } + setUsernameInDrawer((RelativeLayout) findViewById(R.id.left_drawer), getAccount()); } if (!stateWasRecovered) { @@@ -304,7 -302,10 +302,7 @@@ /// First fragment OCFileListFragment listOfFiles = getListOfFilesFragment(); if (listOfFiles != null) { - listOfFiles.listDirectory(getCurrentDir()); - // TODO Enable when "On Device" is recovered - // listOfFiles.listDirectory(getCurrentDir(), MainApp.getOnlyOnDevice()); - + listOfFiles.listDirectory(getCurrentDir(), MainApp.getOnlyOnDevice()); } else { Log_OC.e(TAG, "Still have a chance to lose the initializacion of list fragment >("); } @@@ -323,8 -324,6 +321,8 @@@ startTextPreview(file); } + switchLayout(getFile()); + } else { Log_OC.wtf(TAG, "initFragments() called with invalid NULLs!"); if (getAccount() == null) { @@@ -336,14 -335,6 +334,14 @@@ } } + private void switchLayout(OCFile file){ + if (DisplayUtils.isGridView(file, getStorageManager())){ + switchToGridView(); + } else { + switchToListView(); + } + } + private Fragment chooseInitialSecondFragment(OCFile file) { Fragment secondFragment = null; if (file != null && !file.isFolder()) { @@@ -443,7 -434,9 +441,7 @@@ protected void refreshListOfFilesFragment() { OCFileListFragment fileListFragment = getListOfFilesFragment(); if (fileListFragment != null) { - fileListFragment.listDirectory(); - // TODO Enable when "On Device" is recovered ? - // fileListFragment.listDirectory(MainApp.getOnlyOnDevice()); + fileListFragment.listDirectory(MainApp.getOnlyOnDevice()); } } @@@ -495,9 -488,10 +493,9 @@@ @Override public boolean onPrepareOptionsMenu(Menu menu) { boolean drawerOpen = mDrawerLayout.isDrawerOpen(GravityCompat.START); - menu.findItem(R.id.action_upload).setVisible(!drawerOpen); - menu.findItem(R.id.action_create_dir).setVisible(!drawerOpen); menu.findItem(R.id.action_sort).setVisible(!drawerOpen); menu.findItem(R.id.action_sync_account).setVisible(!drawerOpen); + menu.findItem(R.id.action_switch_view).setVisible(!drawerOpen); return super.onPrepareOptionsMenu(menu); } @@@ -506,13 -500,6 +504,13 @@@ public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main_menu, menu); + menu.findItem(R.id.action_create_dir).setVisible(false); + mOptionsMenu = menu; + + MenuItem menuItem = mOptionsMenu.findItem(R.id.action_switch_view); + + changeGridIcon(); + return true; } @@@ -521,10 -508,23 +519,10 @@@ public boolean onOptionsItemSelected(MenuItem item) { boolean retval = true; switch (item.getItemId()) { - case R.id.action_create_dir: { - CreateFolderDialogFragment dialog = - CreateFolderDialogFragment.newInstance(getCurrentDir()); - dialog.show(getSupportFragmentManager(), DIALOG_CREATE_FOLDER); - break; - } - case R.id.action_sync_account: { startSynchronization(); break; } - case R.id.action_upload: { - UploadSourceDialogFragment dialog = - UploadSourceDialogFragment.newInstance(getAccount()); - dialog.show(getSupportFragmentManager(), DIALOG_UPLOAD_SOURCE); - break; - } case android.R.id.home: { FileFragment second = getSecondFragment(); OCFile currentDir = getCurrentDir(); @@@ -567,57 -567,12 +565,57 @@@ builder.create().show(); break; } + case R.id.action_switch_view:{ + if (isGridView()){ + item.setTitle(getApplicationContext().getString(R.string.action_switch_grid_view)); + item.setIcon(ContextCompat.getDrawable(getApplicationContext(), + R.drawable.ic_view_module)); + DisplayUtils.setViewMode(getFile(), false); + switchToListView(); + } else { + item.setTitle(getApplicationContext().getString(R.string.action_switch_list_view)); + item.setIcon(ContextCompat.getDrawable(getApplicationContext(), + R.drawable.ic_view_list)); + DisplayUtils.setViewMode(getFile(), true); + switchToGridView(); + } + + return true; + } default: retval = super.onOptionsItemSelected(item); } return retval; } + public void createFolder() { + CreateFolderDialogFragment dialog = + CreateFolderDialogFragment.newInstance(getCurrentDir()); + dialog.show(getSupportFragmentManager(), DIALOG_CREATE_FOLDER); + } + + public void uploadLocalFilesSelected() { + Intent action = new Intent(this, UploadFilesActivity.class); + action.putExtra( + UploadFilesActivity.EXTRA_ACCOUNT, + getAccount() + ); + startActivityForResult(action, ACTION_SELECT_MULTIPLE_FILES); + } + + public void uploadFromOtherAppsSelected() { + Intent action = new Intent(Intent.ACTION_GET_CONTENT); + action = action.setType("*/*").addCategory(Intent.CATEGORY_OPENABLE); + //Intent.EXTRA_ALLOW_MULTIPLE is only supported on api level 18+, Jelly Bean + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + action.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); + } + startActivityForResult( + Intent.createChooser(action, getString(R.string.upload_chooser_title)), + ACTION_SELECT_CONTENT_FROM_APPS + ); + } + private void startSynchronization() { Log_OC.d(TAG, "Got to start sync"); if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT) { @@@ -812,12 -767,8 +810,12 @@@ */ private void requestMoveOperation(Intent data, int resultCode) { OCFile folderToMoveAt = (OCFile) data.getParcelableExtra(FolderPickerActivity.EXTRA_FOLDER); - OCFile targetFile = (OCFile) data.getParcelableExtra(FolderPickerActivity.EXTRA_FILE); - getFileOperationsHelper().moveFile(folderToMoveAt, targetFile); + + ArrayList files = data.getParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES); + + for (Parcelable file : files) { + getFileOperationsHelper().moveFile(folderToMoveAt, (OCFile) file); + } } /** @@@ -828,36 -779,13 +826,36 @@@ */ private void requestCopyOperation(Intent data, int resultCode) { OCFile folderToMoveAt = data.getParcelableExtra(FolderPickerActivity.EXTRA_FOLDER); - OCFile targetFile = data.getParcelableExtra(FolderPickerActivity.EXTRA_FILE); - getFileOperationsHelper().copyFile(folderToMoveAt, targetFile); + + ArrayList files = data.getParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES); + + for (Parcelable file : files) { + getFileOperationsHelper().copyFile(folderToMoveAt, (OCFile) file); + } } @Override public void onBackPressed() { - if (!isDrawerOpen()){ + boolean isFabOpen = isFabOpen(); + boolean isDrawerOpen = isDrawerOpen(); + + /* + * BackPressed priority/hierarchy: + * 1. close drawer if opened + * 2. close FAB if open (only if drawer isn't open) + * 3. navigate up (only if drawer and FAB aren't open) + */ + if(isDrawerOpen && isFabOpen) { + // close drawer first + super.onBackPressed(); + } else if(isDrawerOpen && !isFabOpen) { + // close drawer + super.onBackPressed(); + } else if (!isDrawerOpen && isFabOpen) { + // close fab + getListOfFilesFragment().getFabMain().collapse(); + } else { + // all closed OCFileListFragment listOfFiles = getListOfFilesFragment(); if (mDualPane || getSecondFragment() == null) { OCFile currentDir = getCurrentDir(); @@@ -873,20 -801,8 +871,20 @@@ setFile(listOfFiles.getCurrentFile()); } cleanSecondFragment(); + changeGridIcon(); + } + } + + private void changeGridIcon(){ + MenuItem menuItem = mOptionsMenu.findItem(R.id.action_switch_view); + if (DisplayUtils.isGridView(getFile(), getStorageManager())){ + menuItem.setTitle(getApplicationContext().getString(R.string.action_switch_list_view)); + menuItem.setIcon(ContextCompat.getDrawable(getApplicationContext(), + R.drawable.ic_view_list)); } else { - super.onBackPressed(); + menuItem.setTitle(getApplicationContext().getString(R.string.action_switch_grid_view)); + menuItem.setIcon(ContextCompat.getDrawable(getApplicationContext(), + R.drawable.ic_view_module)); } } @@@ -965,14 -881,6 +963,14 @@@ Log_OC.v(TAG, "onPause() end"); } + public boolean isFabOpen() { + if(getListOfFilesFragment() != null && getListOfFilesFragment().getFabMain() != null && getListOfFilesFragment().getFabMain().isExpanded()) { + return true; + } else { + return false; + } + } + private class SyncBroadcastReceiver extends BroadcastReceiver { @@@ -1028,8 -936,10 +1026,8 @@@ currentDir.getRemotePath().equals(synchFolderRemotePath)) { OCFileListFragment fileListFragment = getListOfFilesFragment(); if (fileListFragment != null) { - fileListFragment.listDirectory(); - // TODO Enable when "On Device" is recovered ? - // fileListFragment.listDirectory(currentDir, - // MainApp.getOnlyOnDevice()); + fileListFragment.listDirectory(currentDir, + MainApp.getOnlyOnDevice()); } } setFile(currentFile); @@@ -1285,7 -1195,9 +1283,7 @@@ OCFileListFragment listOfFiles = getListOfFilesFragment(); if (listOfFiles != null) { // should never be null, indeed OCFile root = getStorageManager().getFileByPath(OCFile.ROOT_PATH); - listOfFiles.listDirectory(root); - // TODO Enable when "On Device" is recovered ? - // listOfFiles.listDirectory(root, MainApp.getOnlyOnDevice()); + listOfFiles.listDirectory(root, MainApp.getOnlyOnDevice()); setFile(listOfFiles.getCurrentFile()); startSyncFolderOperation(root, false); } @@@ -1304,11 -1216,6 +1302,11 @@@ cleanSecondFragment(); // Sync Folder startSyncFolderOperation(directory, false); + + MenuItem menuItem = mOptionsMenu.findItem(R.id.action_switch_view); + + changeGridIcon(); + switchLayout(directory); } /** @@@ -1375,7 -1282,9 +1373,7 @@@ // getFileDownloadBinder() - THIS IS A MESS OCFileListFragment listOfFiles = getListOfFilesFragment(); if (listOfFiles != null) { - listOfFiles.listDirectory(); - // TODO Enable when "On Device" is recovered ? - // listOfFiles.listDirectory(MainApp.getOnlyOnDevice()); + listOfFiles.listDirectory(MainApp.getOnlyOnDevice()); } FileFragment secondFragment = getSecondFragment(); if (secondFragment != null && secondFragment instanceof FileDetailFragment) { @@@ -1441,15 -1350,6 +1439,6 @@@ } else if (operation instanceof CreateFolderOperation) { onCreateFolderOperationFinish((CreateFolderOperation) operation, result); - } else if (operation instanceof CreateShareViaLinkOperation || - operation instanceof CreateShareWithShareeOperation ) { - - refreshShowDetails(); - refreshListOfFilesFragment(); - - } else if (operation instanceof UnshareOperation) { - onUnshareLinkOperationFinish((UnshareOperation) operation, result); - } else if (operation instanceof MoveFileOperation) { onMoveFileOperationFinish((MoveFileOperation) operation, result); @@@ -1459,18 -1359,6 +1448,6 @@@ } - private void onUnshareLinkOperationFinish(UnshareOperation operation, - RemoteOperationResult result) { - if (result.isSuccess()) { - refreshShowDetails(); - refreshListOfFilesFragment(); - - } else if (result.getCode() == ResultCode.SHARE_NOT_FOUND) { - cleanSecondFragment(); - refreshListOfFilesFragment(); - } - } - private void refreshShowDetails() { FileFragment details = getSecondFragment(); if (details != null) { @@@ -1925,19 -1813,8 +1902,19 @@@ private void sortByName(boolean ascending) { getListOfFilesFragment().sortByName(ascending); } + private boolean isGridView(){ return getListOfFilesFragment().isGridView(); } + private void switchToGridView() { + getListOfFilesFragment().switchToGridView(); + } + private void switchToListView() { + getListOfFilesFragment().switchToListView(); + } public void allFilesOption() { browseToRoot(); } + + public void refreshDirectory(){ + getListOfFilesFragment().refreshDirectory(); + } } diff --combined src/com/owncloud/android/ui/fragment/FileDetailFragment.java index 1362a125,5264af11..e9cd9162 --- a/src/com/owncloud/android/ui/fragment/FileDetailFragment.java +++ b/src/com/owncloud/android/ui/fragment/FileDetailFragment.java @@@ -217,24 -217,6 +217,24 @@@ public class FileDetailFragment extend item.setVisible(false); item.setEnabled(false); } + + item = menu.findItem(R.id.action_switch_view); + if (item != null){ + item.setVisible(false); + item.setEnabled(false); + } + + item = menu.findItem(R.id.action_sync_account); + if (item != null) { + item.setVisible(false); + item.setEnabled(false); + } + + item = menu.findItem(R.id.action_sort); + if (item != null) { + item.setVisible(false); + item.setEnabled(false); + } } @@@ -245,18 -227,9 +245,9 @@@ public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_share_file: { - mContainerActivity.getFileOperationsHelper().shareFileWithLink(getFile()); - return true; - } - case R.id.action_share_with_users: { mContainerActivity.getFileOperationsHelper().showShareFile(getFile()); return true; } - case R.id.action_unshare_file: { - mContainerActivity.getFileOperationsHelper().unshareFileWithLink(getFile()); - return true; - } - case R.id.action_open_file_with: { mContainerActivity.getFileOperationsHelper().openFile(getFile()); return true; diff --combined src/com/owncloud/android/ui/fragment/OCFileListFragment.java index 9a1f9eef,b47f648a..c606e676 --- a/src/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/src/com/owncloud/android/ui/fragment/OCFileListFragment.java @@@ -22,32 -22,19 +22,32 @@@ */ package com.owncloud.android.ui.fragment; +import android.accounts.Account; import android.app.Activity; +import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.net.Uri; import android.os.Bundle; +import android.preference.PreferenceManager; import android.support.v4.widget.SwipeRefreshLayout; +import android.view.ActionMode; +import android.support.v7.app.AlertDialog; import android.view.ContextMenu; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; +import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.PopupMenu; +import android.widget.TextView; +import android.widget.Toast; +import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.authentication.AccountUtils; import com.owncloud.android.datamodel.FileDataStorageManager; @@@ -55,37 -42,29 +55,37 @@@ import com.owncloud.android.datamodel.O import com.owncloud.android.files.FileMenuFilter; import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.lib.resources.status.OwnCloudVersion; +import com.owncloud.android.media.MediaService; import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.ui.activity.FileDisplayActivity; import com.owncloud.android.ui.activity.FolderPickerActivity; import com.owncloud.android.ui.activity.OnEnforceableRefreshListener; +import com.owncloud.android.ui.activity.UploadFilesActivity; import com.owncloud.android.ui.adapter.FileListListAdapter; import com.owncloud.android.ui.dialog.ConfirmationDialogFragment; +import com.owncloud.android.ui.dialog.CreateFolderDialogFragment; import com.owncloud.android.ui.dialog.FileActionsDialogFragment; import com.owncloud.android.ui.dialog.RemoveFileDialogFragment; +import com.owncloud.android.ui.dialog.RemoveFilesDialogFragment; import com.owncloud.android.ui.dialog.RenameFileDialogFragment; +import com.owncloud.android.ui.dialog.UploadSourceDialogFragment; import com.owncloud.android.ui.preview.PreviewImageFragment; import com.owncloud.android.ui.preview.PreviewMediaFragment; +import com.owncloud.android.utils.DisplayUtils; +import com.owncloud.android.utils.ExceptionHandler; +import com.owncloud.android.utils.FileStorageUtils; import com.owncloud.android.ui.preview.PreviewTextFragment; import com.owncloud.android.utils.FileStorageUtils; import java.io.File; +import java.util.ArrayList; /** * A Fragment that lists all files and folders in a given path. * * TODO refactor to get rid of direct dependency on FileDisplayActivity */ -public class OCFileListFragment extends ExtendedListFragment - implements FileActionsDialogFragment.FileActionsDialogFragmentListener { +public class OCFileListFragment extends ExtendedListFragment { private static final String TAG = OCFileListFragment.class.getSimpleName(); @@@ -94,12 -73,8 +94,12 @@@ public final static String ARG_JUST_FOLDERS = MY_PACKAGE + ".JUST_FOLDERS"; public final static String ARG_ALLOW_CONTEXTUAL_ACTIONS = MY_PACKAGE + ".ALLOW_CONTEXTUAL"; + public final static String ARG_HIDE_FAB = MY_PACKAGE + ".HIDE_FAB"; private static final String KEY_FILE = MY_PACKAGE + ".extra.FILE"; + private static final String KEY_FAB_EVER_CLICKED = "FAB_EVER_CLICKED"; + + private static String DIALOG_CREATE_FOLDER = "DIALOG_CREATE_FOLDER"; private FileFragment.ContainerActivity mContainerActivity; @@@ -108,8 -83,8 +108,8 @@@ private boolean mJustFolders; private OCFile mTargetFile; - - + + private boolean miniFabClicked = false; /** * {@inheritDoc} @@@ -170,211 -145,15 +170,211 @@@ setListAdapter(mAdapter); registerLongClickListener(); + + boolean hideFab = (args != null) && args.getBoolean(ARG_HIDE_FAB, false); + if (hideFab) { + setFabEnabled(false); + } else { + setFabEnabled(true); + registerFabListeners(); + + // detect if a mini FAB has ever been clicked + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); + if(prefs.getLong(KEY_FAB_EVER_CLICKED, 0) > 0) { + miniFabClicked = true; + } + + // add labels to the min FABs when none of them has ever been clicked on + if(!miniFabClicked) { + setFabLabels(); + } else { + removeFabLabels(); + } + } } + /** + * adds labels to all mini FABs. + */ + private void setFabLabels() { + getFabUpload().setTitle(getResources().getString(R.string.actionbar_upload)); + getFabMkdir().setTitle(getResources().getString(R.string.actionbar_mkdir)); + getFabUploadFromApp().setTitle(getResources().getString(R.string.actionbar_upload_from_apps)); + } + + /** + * registers all listeners on all mini FABs. + */ + private void registerFabListeners() { + registerFabUploadListeners(); + registerFabMkDirListeners(); + registerFabUploadFromAppListeners(); + } + + /** + * registers {@link android.view.View.OnClickListener} and {@link android.view.View.OnLongClickListener} + * on the Upload mini FAB for the linked action and {@link Toast} showing the underlying action. + */ + private void registerFabUploadListeners() { + getFabUpload().setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent action = new Intent(getActivity(), UploadFilesActivity.class); + action.putExtra( + UploadFilesActivity.EXTRA_ACCOUNT, + ((FileActivity) getActivity()).getAccount() + ); + getActivity().startActivityForResult(action, UploadSourceDialogFragment.ACTION_SELECT_MULTIPLE_FILES); + getFabMain().collapse(); + recordMiniFabClick(); + } + }); + + getFabUpload().setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + Toast.makeText(getActivity(), R.string.actionbar_upload, Toast.LENGTH_SHORT).show(); + return true; + } + }); + } + + /** + * registers {@link android.view.View.OnClickListener} and {@link android.view.View.OnLongClickListener} + * on the 'Create Dir' mini FAB for the linked action and {@link Toast} showing the underlying action. + */ + private void registerFabMkDirListeners() { + getFabMkdir().setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + CreateFolderDialogFragment dialog = + CreateFolderDialogFragment.newInstance(mFile); + dialog.show(getActivity().getSupportFragmentManager(), FileDisplayActivity.DIALOG_CREATE_FOLDER); + getFabMain().collapse(); + recordMiniFabClick(); + } + }); + + getFabMkdir().setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + Toast.makeText(getActivity(), R.string.actionbar_mkdir, Toast.LENGTH_SHORT).show(); + return true; + } + }); + } + + /** + * registers {@link android.view.View.OnClickListener} and {@link android.view.View.OnLongClickListener} + * on the Upload from App mini FAB for the linked action and {@link Toast} showing the underlying action. + */ + private void registerFabUploadFromAppListeners() { + getFabUploadFromApp().setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent action = new Intent(Intent.ACTION_GET_CONTENT); + action = action.setType("*/*").addCategory(Intent.CATEGORY_OPENABLE); + + //Intent.EXTRA_ALLOW_MULTIPLE is only supported on api level 18+, Jelly Bean + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + action.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); + } + + getActivity().startActivityForResult( + Intent.createChooser(action, getString(R.string.upload_chooser_title)), + UploadSourceDialogFragment.ACTION_SELECT_CONTENT_FROM_APPS + ); + getFabMain().collapse(); + recordMiniFabClick(); + } + }); + + getFabUploadFromApp().setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + Toast.makeText(getActivity(), + R.string.actionbar_upload_from_apps, + Toast.LENGTH_SHORT).show(); + return true; + } + }); + } + + /** + * records a click on a mini FAB and thus: + *
    + *
  1. persists the click fact
  2. + *
  3. removes the mini FAB labels
  4. + *
+ */ + private void recordMiniFabClick() { + // only record if it hasn't been done already at some other time + if(!miniFabClicked) { + final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity()); + sp.edit().putLong(KEY_FAB_EVER_CLICKED, 1).commit(); + miniFabClicked = true; + } + } + + /** + * removes the labels on all known min FABs. + */ + private void removeFabLabels() { + getFabUpload().setTitle(null); + getFabMkdir().setTitle(null); + getFabUploadFromApp().setTitle(null); + ((TextView) getFabUpload().getTag(com.getbase.floatingactionbutton.R.id.fab_label)).setVisibility(View.GONE); + ((TextView) getFabMkdir().getTag(com.getbase.floatingactionbutton.R.id.fab_label)).setVisibility(View.GONE); + ((TextView) getFabUploadFromApp().getTag(com.getbase.floatingactionbutton.R.id.fab_label)).setVisibility(View.GONE); + } + private void registerLongClickListener() { - getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { - public boolean onItemLongClick(AdapterView arg0, View v, - int index, long arg3) { - showFileAction(index); + getListView().setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() { + private Menu menu; + + @Override + public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { + final int checkedCount = getListView().getCheckedItemCount(); + // TODO Tobi extract to values + mode.setTitle(checkedCount + " selected"); + + if (checked) { + mAdapter.setNewSelection(position, checked); + } else { + mAdapter.removeSelection(position); + } + + // TODO maybe change: only recreate menu if count changes + menu.clear(); + if (checkedCount == 1) { + createContextMenu(menu); + } else { + // download, move, copy, delete + getActivity().getMenuInflater().inflate(R.menu.multiple_file_actions_menu, menu); + } + + } + + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + this.menu = menu; return true; } + + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + return false; + } + + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + return onFileActionChosen(item.getItemId()); + } + + @Override + public void onDestroyActionMode(ActionMode mode) { + mAdapter.removeSelection(); + } }); } @@@ -433,11 -212,11 +433,11 @@@ /** * Call this, when the user presses the up button. - * - * Tries to move up the current folder one level. If the parent folder was removed from the - * database, it continues browsing up until finding an existing folders. - *

- * return Count of folder levels browsed up. + *

+ * Tries to move up the current folder one level. If the parent folder was removed from the + * database, it continues browsing up until finding an existing folders. + *

+ * @return Count of folder levels browsed up. */ public int onBrowseUp() { OCFile parentDir = null; @@@ -465,7 -244,8 +465,7 @@@ } // exit is granted because storageManager.getFileByPath("/") never returns null mFile = parentDir; - // TODO Enable when "On Device" is recovered ? - listDirectory(mFile /*, MainApp.getOnlyOnDevice()*/); + listDirectory(mFile, MainApp.getOnlyOnDevice()); onRefresh(false); @@@ -483,7 -263,8 +483,7 @@@ if (file != null) { if (file.isFolder()) { // update state and view of this fragment - // TODO Enable when "On Device" is recovered ? - listDirectory(file/*, MainApp.getOnlyOnDevice()*/); + listDirectory(file, MainApp.getOnlyOnDevice()); // then, notify parent activity to let it update its state and view mContainerActivity.onBrowsedDownTo(file); // save index and top position @@@ -495,36 -276,41 +495,36 @@@ ((FileDisplayActivity)mContainerActivity).startImagePreview(file); } else if (PreviewTextFragment.canBePreviewed(file)){ ((FileDisplayActivity)mContainerActivity).startTextPreview(file); - } else if (file.isDown()) { - if (PreviewMediaFragment.canBePreviewed(file)) { + } else if (PreviewMediaFragment.canBePreviewed(file)) { // media preview ((FileDisplayActivity) mContainerActivity).startMediaPreview(file, 0, true); - } else { + } else if (file.isDown()) { mContainerActivity.getFileOperationsHelper().openFile(file); - } - } else { // automatic download, preview on finish ((FileDisplayActivity) mContainerActivity).startDownloadForPreview(file); } - } - } else { Log_OC.d(TAG, "Null object in ListAdapter!!"); } - } /** * {@inheritDoc} */ - @Override - public void onCreateContextMenu( - ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + // TODO Tobi needed? + public void createContextMenu(Menu menu) { Bundle args = getArguments(); boolean allowContextualActions = (args == null) ? true : args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, true); if (allowContextualActions) { MenuInflater inflater = getActivity().getMenuInflater(); inflater.inflate(R.menu.file_actions_menu, menu); - AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; - OCFile targetFile = (OCFile) mAdapter.getItem(info.position); + OCFile targetFile = null; + if (mAdapter.getCheckedItems().size() == 1){ + targetFile = mAdapter.getCheckedItems().get(0); + } if (mContainerActivity.getStorageManager() != null) { FileMenuFilter mf = new FileMenuFilter( @@@ -547,135 -333,83 +547,127 @@@ item.setEnabled(false); } } + +// String.format(mContext.getString(R.string.subject_token), +// getClient().getCredentials().getUsername(), file.getFileName())); } } - /** - * {@inheritDoc} - */ - @Override - public boolean onFileActionChosen(int menuId, int filePosition) { - mTargetFile = (OCFile) mAdapter.getItem(filePosition); - switch (menuId) { - case R.id.action_share_file: { - mContainerActivity.getFileOperationsHelper().showShareFile(mTargetFile); - return true; - } - case R.id.action_open_file_with: { - mContainerActivity.getFileOperationsHelper().openFile(mTargetFile); - return true; - } - case R.id.action_rename_file: { - RenameFileDialogFragment dialog = RenameFileDialogFragment.newInstance(mTargetFile); - dialog.show(getFragmentManager(), FileDetailFragment.FTAG_RENAME_FILE); - return true; - } - case R.id.action_remove_file: { - RemoveFileDialogFragment dialog = RemoveFileDialogFragment.newInstance(mTargetFile); - dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION); - return true; - } - case R.id.action_download_file: - case R.id.action_sync_file: { - mContainerActivity.getFileOperationsHelper().syncFile(mTargetFile); - return true; - } - case R.id.action_cancel_sync: { - ((FileDisplayActivity)mContainerActivity).cancelTransference(mTargetFile); - return true; - } - case R.id.action_see_details: { - mContainerActivity.showDetails(mTargetFile); - return true; - } - case R.id.action_send_file: { - // Obtain the file - if (!mTargetFile.isDown()) { // Download the file - Log_OC.d(TAG, mTargetFile.getRemotePath() + " : File must be downloaded"); - ((FileDisplayActivity) mContainerActivity).startDownloadForSending(mTargetFile); + public boolean onFileActionChosen(int menuId) { + if (mAdapter.getCheckedItems().size() == 1){ + OCFile mTargetFile = mAdapter.getCheckedItems().get(0); - } else { - mContainerActivity.getFileOperationsHelper().sendDownloadedFile(mTargetFile); + switch (menuId) { + case R.id.action_share_file: { - mContainerActivity.getFileOperationsHelper().shareFileWithLink(mTargetFile); - return true; - } - case R.id.action_share_with_users: { + mContainerActivity.getFileOperationsHelper().showShareFile(mTargetFile); + return true; } - return true; + case R.id.action_open_file_with: { + mContainerActivity.getFileOperationsHelper().openFile(mTargetFile); + return true; + } - case R.id.action_unshare_file: { - mContainerActivity.getFileOperationsHelper().unshareFileWithLink(mTargetFile); - return true; - } + case R.id.action_rename_file: { + RenameFileDialogFragment dialog = RenameFileDialogFragment.newInstance(mTargetFile); + dialog.show(getFragmentManager(), FileDetailFragment.FTAG_RENAME_FILE); + return true; + } + case R.id.action_remove_file: { + RemoveFileDialogFragment dialog = RemoveFileDialogFragment.newInstance(mTargetFile); + dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION); + return true; + } + case R.id.action_download_file: + case R.id.action_sync_file: { + mContainerActivity.getFileOperationsHelper().syncFile(mTargetFile); + return true; + } + case R.id.action_cancel_sync: { + ((FileDisplayActivity) mContainerActivity).cancelTransference(mTargetFile); + return true; + } + case R.id.action_see_details: { + mContainerActivity.showDetails(mTargetFile); + return true; + } + case R.id.action_send_file: { + // Obtain the file + if (!mTargetFile.isDown()) { // Download the file + Log_OC.d(TAG, mTargetFile.getRemotePath() + " : File must be downloaded"); + ((FileDisplayActivity) mContainerActivity).startDownloadForSending(mTargetFile); + return true; + } else { + mContainerActivity.getFileOperationsHelper().sendDownloadedFile(mTargetFile); + } + } + case R.id.action_stream_file: { + Account account = ((FileActivity)mContainerActivity).getAccount(); + Context context = MainApp.getAppContext(); + String uri = PreviewMediaFragment.generateUrlWithCredentials(account, context, mTargetFile); + MediaService.streamWithExternalApp(uri, getActivity()).show(); + return true; + } + case R.id.action_move: { + Intent action = new Intent(getActivity(), FolderPickerActivity.class); + ArrayList files = new ArrayList(); + files.add(mTargetFile); + action.putParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES, files); + getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_MOVE_FILES); + return true; + } + case R.id.action_favorite_file: { + mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, true); + return true; + } + case R.id.action_unfavorite_file: { + mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, false); + return true; + } + case R.id.action_copy: + Intent action = new Intent(getActivity(), FolderPickerActivity.class); + ArrayList files = new ArrayList(); + files.add(mTargetFile); + action.putExtra(FolderPickerActivity.EXTRA_FILES, files); + getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_COPY_FILES); + return true; + default: + return false; } - case R.id.action_move: { - Intent action = new Intent(getActivity(), FolderPickerActivity.class); + } else { + ArrayList mTargetFiles = mAdapter.getCheckedItems(); - // Pass mTargetFile that contains info of selected file/folder - action.putExtra(FolderPickerActivity.EXTRA_FILE, mTargetFile); - getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_MOVE_FILES); - return true; - } - case R.id.action_favorite_file: { - mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, true); - return true; - } - case R.id.action_unfavorite_file: { - mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, false); - return true; + switch (menuId) { + case R.id.action_remove_file: { + RemoveFilesDialogFragment dialog = RemoveFilesDialogFragment.newInstance(mTargetFiles); + dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION); + return true; + } + case R.id.action_download_file: + case R.id.action_sync_file: { + mContainerActivity.getFileOperationsHelper().syncFiles(mTargetFiles); + return true; + } + case R.id.action_move: { + Intent action = new Intent(getActivity(), FolderPickerActivity.class); + action.putParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES, mTargetFiles); + getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_MOVE_FILES); + return true; + } + case R.id.action_favorite_file: { + mContainerActivity.getFileOperationsHelper().toggleFavorites(mTargetFiles, true); + return true; + } + case R.id.action_unfavorite_file: { + mContainerActivity.getFileOperationsHelper().toggleFavorites(mTargetFiles, false); + return true; + } + case R.id.action_copy: + Intent action = new Intent(getActivity(), FolderPickerActivity.class); + action.putParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES, mTargetFiles); + getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_COPY_FILES); + return true; + default: + return false; } - case R.id.action_copy: - Intent action = new Intent(getActivity(), FolderPickerActivity.class); - - // Pass mTargetFile that contains info of selected file/folder - action.putExtra(FolderPickerActivity.EXTRA_FILE, mTargetFile); - getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_COPY_FILES); - return true; - default: - return false; } } @@@ -685,7 -419,8 +677,7 @@@ @Override public boolean onContextItemSelected (MenuItem item) { AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); - boolean matched = onFileActionChosen(item.getItemId(), - ((AdapterContextMenuInfo) item.getMenuInfo()).position); + boolean matched = onFileActionChosen(item.getItemId()) ; if(!matched) { return super.onContextItemSelected(item); } else { @@@ -705,14 -440,17 +697,14 @@@ } /** - * Calls {@link OCFileListFragment#listDirectory(OCFile)} with a null parameter + * Calls {@link OCFileListFragment#listDirectory(OCFile, boolean)} with a null parameter */ - public void listDirectory(/*boolean onlyOnDevice*/){ - listDirectory(null); - // TODO Enable when "On Device" is recovered ? - // listDirectory(null, onlyOnDevice); + public void listDirectory(boolean onlyOnDevice){ + listDirectory(null, onlyOnDevice); } public void refreshDirectory(){ - // TODO Enable when "On Device" is recovered ? - listDirectory(getCurrentFile()/*, MainApp.getOnlyOnDevice()*/); + listDirectory(getCurrentFile(), MainApp.getOnlyOnDevice()); } /** @@@ -722,7 -460,7 +714,7 @@@ * * @param directory File to be listed */ - public void listDirectory(OCFile directory/*, boolean onlyOnDevice*/) { + public void listDirectory(OCFile directory, boolean onlyOnDevice) { FileDataStorageManager storageManager = mContainerActivity.getStorageManager(); if (storageManager != null) { @@@ -743,7 -481,8 +735,7 @@@ directory = storageManager.getFileById(directory.getParentId()); } - // TODO Enable when "On Device" is recovered ? - mAdapter.swapDirectory(directory, storageManager/*, onlyOnDevice*/); + mAdapter.swapDirectory(directory, storageManager, onlyOnDevice); if (mFile == null || !mFile.equals(directory)) { mCurrentListView.setSelection(0); } @@@ -767,7 -506,7 +759,7 @@@ if (!file.isHidden()) { filesCount++; - if (file.isImage()) { + if (file.isImage() || file.isVideo()) { imagesCount++; } } @@@ -780,12 -519,11 +772,12 @@@ OwnCloudVersion version = AccountUtils.getServerVersion( ((FileActivity)mContainerActivity).getAccount()); if (version != null && version.supportsRemoteThumbnails() && - imagesCount > 0 && imagesCount == filesCount) { + DisplayUtils.isGridView(mFile, mContainerActivity.getStorageManager())) { switchToGridView(); registerLongClickListener(); } else { switchToListView(); +// switchToGridView(); } } } diff --combined src/com/owncloud/android/ui/preview/PreviewImageActivity.java index f797fe2f,25acb8cb..6a260dd5 --- a/src/com/owncloud/android/ui/preview/PreviewImageActivity.java +++ b/src/com/owncloud/android/ui/preview/PreviewImageActivity.java @@@ -40,7 -40,6 +40,7 @@@ import android.view.View import android.view.Window; import com.ortiz.touch.ExtendedViewPager; +import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.authentication.AccountUtils; import com.owncloud.android.datamodel.FileDataStorageManager; @@@ -52,16 -51,11 +52,11 @@@ import com.owncloud.android.files.servi import com.owncloud.android.lib.common.operations.OnRemoteOperationListener; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; - import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.utils.Log_OC; - import com.owncloud.android.operations.CreateShareViaLinkOperation; - import com.owncloud.android.operations.CreateShareWithShareeOperation; import com.owncloud.android.operations.RemoveFileOperation; import com.owncloud.android.operations.SynchronizeFileOperation; - import com.owncloud.android.operations.UnshareOperation; import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.ui.activity.FileDisplayActivity; - import com.owncloud.android.ui.activity.ShareActivity; import com.owncloud.android.ui.fragment.FileFragment; @@@ -157,8 -151,9 +152,8 @@@ public class PreviewImageActivity exten parentFolder = getStorageManager().getFileByPath(OCFile.ROOT_PATH); } - // TODO Enable when "On Device" is recovered ? mPreviewImagePagerAdapter = new PreviewImagePagerAdapter(getSupportFragmentManager(), - parentFolder, getAccount(), getStorageManager()/*, MainApp.getOnlyOnDevice()*/); + parentFolder, getAccount(), getStorageManager(), MainApp.getOnlyOnDevice()); mViewPager = (ExtendedViewPager) findViewById(R.id.fragmentPager); int position = mHasSavedPosition ? mSavedPosition : @@@ -230,14 -225,7 +225,7 @@@ public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) { super.onRemoteOperationFinish(operation, result); - if (operation instanceof CreateShareViaLinkOperation || - operation instanceof CreateShareWithShareeOperation) { - onCreateShareOperationFinish(result); - - } else if (operation instanceof UnshareOperation) { - onUnshareLinkOperationFinish((UnshareOperation) operation, result); - - } else if (operation instanceof RemoveFileOperation) { + if (operation instanceof RemoveFileOperation) { finish(); } else if (operation instanceof SynchronizeFileOperation) { onSynchronizeFileOperationFinish((SynchronizeFileOperation) operation, result); @@@ -245,31 -233,6 +233,6 @@@ } } - - private void onUnshareLinkOperationFinish(UnshareOperation operation, - RemoteOperationResult result) { - if (result.isSuccess()) { - OCFile file = getStorageManager().getFileByPath(getFile().getRemotePath()); - if (file != null) { - setFile(file); - } - invalidateOptionsMenu(); - } else if (result.getCode() == ResultCode.SHARE_NOT_FOUND) { - backToDisplayActivity(); - } - - } - - private void onCreateShareOperationFinish(RemoteOperationResult result) { - if (result.isSuccess()) { - OCFile file = getStorageManager().getFileByPath(getFile().getRemotePath()); - if (file != null) { - setFile(file); - } - invalidateOptionsMenu(); - } - } - private void onSynchronizeFileOperationFinish(SynchronizeFileOperation operation, RemoteOperationResult result) { if (result.isSuccess()) { @@@ -429,7 -392,12 +392,7 @@@ OCFile currentFile = mPreviewImagePagerAdapter.getFileAt(position); getSupportActionBar().setTitle(currentFile.getFileName()); mDrawerToggle.setDrawerIndicatorEnabled(false); - if (!currentFile.isDown()) { - if (!mPreviewImagePagerAdapter.pendingErrorAt(position)) { - requestForDownload(currentFile); - } - } - + // Call to reset image zoom to initial state ((PreviewImagePagerAdapter) mViewPager.getAdapter()).resetZoom(); } diff --combined src/com/owncloud/android/ui/preview/PreviewImageFragment.java index bdbfa1fc,df0fb7aa..1ef0377e --- a/src/com/owncloud/android/ui/preview/PreviewImageFragment.java +++ b/src/com/owncloud/android/ui/preview/PreviewImageFragment.java @@@ -41,10 -41,8 +41,10 @@@ import android.widget.ImageView import android.widget.ProgressBar; import android.widget.TextView; +import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.datamodel.OCFile; +import com.owncloud.android.datamodel.ThumbnailsCacheManager; import com.owncloud.android.files.FileMenuFilter; import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.ui.dialog.ConfirmationDialogFragment; @@@ -71,14 -69,11 +71,14 @@@ public class PreviewImageFragment exten private static final String ARG_FILE = "FILE"; private static final String ARG_IGNORE_FIRST = "IGNORE_FIRST"; + private static final String ARG_SHOW_RESIZED_IMAGE = "SHOW_RESIZED_IMAGE"; private TouchImageViewCustom mImageView; private TextView mMessageView; private ProgressBar mProgressWheel; + private Boolean mShowResizedImage = false; + public Bitmap mBitmap = null; private static final String TAG = PreviewImageFragment.class.getSimpleName(); @@@ -102,14 -97,11 +102,14 @@@ * {@link FragmentStatePagerAdapter} * ; TODO better solution */ - public static PreviewImageFragment newInstance(OCFile imageFile, boolean ignoreFirstSavedState){ + public static PreviewImageFragment newInstance(OCFile imageFile, boolean ignoreFirstSavedState, + boolean showResizedImage){ PreviewImageFragment frag = new PreviewImageFragment(); + frag.mShowResizedImage = showResizedImage; Bundle args = new Bundle(); args.putParcelable(ARG_FILE, imageFile); args.putBoolean(ARG_IGNORE_FIRST, ignoreFirstSavedState); + args.putBoolean(ARG_SHOW_RESIZED_IMAGE, showResizedImage); frag.setArguments(args); return frag; } @@@ -142,7 -134,6 +142,7 @@@ // not right now mIgnoreFirstSavedState = args.getBoolean(ARG_IGNORE_FIRST); + mShowResizedImage = args.getBoolean(ARG_SHOW_RESIZED_IMAGE); setHasOptionsMenu(true); } @@@ -188,6 -179,9 +188,6 @@@ if (getFile() == null) { throw new IllegalStateException("Instanced with a NULL OCFile"); } - if (!getFile().isDown()) { - throw new IllegalStateException("There is no local file to preview"); - } } @@@ -205,56 -199,10 +205,56 @@@ public void onStart() { super.onStart(); if (getFile() != null) { - mLoadBitmapTask = new LoadBitmapTask(mImageView, mMessageView, mProgressWheel); - //mLoadBitmapTask.execute(new String[]{getFile().getStoragePath()}); -// mLoadBitmapTask.execute(getFile().getStoragePath()); - mLoadBitmapTask.execute(getFile()); + mImageView.setTag(getFile().getFileId()); + + if (mShowResizedImage){ + Bitmap resizedImage = ThumbnailsCacheManager.getBitmapFromDiskCache( + String.valueOf("r" + getFile().getRemoteId())); + + if (resizedImage != null && !getFile().needsUpdateThumbnail()){ + mProgressWheel.setVisibility(View.GONE); + mImageView.setImageBitmap(resizedImage); + mImageView.setVisibility(View.VISIBLE); + mBitmap = resizedImage; + } else { + // show thumbnail while loading resized image + Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache( + String.valueOf("t" + getFile().getRemoteId())); + + if (thumbnail != null){ + mImageView.setImageBitmap(thumbnail); + mProgressWheel.setVisibility(View.VISIBLE); + mImageView.setVisibility(View.VISIBLE); + mBitmap = thumbnail; + } else { + thumbnail = ThumbnailsCacheManager.mDefaultImg; + } + + // generate new resized image + if (ThumbnailsCacheManager.cancelPotentialWork(getFile(), mImageView) && + mContainerActivity.getStorageManager() != null) { + final ThumbnailsCacheManager.ThumbnailGenerationTask task = + new ThumbnailsCacheManager.ThumbnailGenerationTask( + mImageView, mContainerActivity.getStorageManager(), + mContainerActivity.getStorageManager().getAccount(), + mProgressWheel); + if (resizedImage == null) { + resizedImage = thumbnail; + } + final ThumbnailsCacheManager.AsyncDrawable asyncDrawable = + new ThumbnailsCacheManager.AsyncDrawable( + MainApp.getAppContext().getResources(), + resizedImage, + task + ); + mImageView.setImageDrawable(asyncDrawable); + task.execute(getFile(), false); + } + } + } else { + mLoadBitmapTask = new LoadBitmapTask(mImageView, mMessageView, mProgressWheel); + mLoadBitmapTask.execute(getFile()); + } } } @@@ -276,9 -224,6 +276,9 @@@ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.file_actions_menu, menu); + +// MenuItem item = menu.findItem(R.id.action_set_as_wallpaper); +// item.setVisible(getFile().isDown()); } /** @@@ -341,17 -286,9 +341,9 @@@ public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_share_file: { - mContainerActivity.getFileOperationsHelper().shareFileWithLink(getFile()); - return true; - } - case R.id.action_share_with_users: { mContainerActivity.getFileOperationsHelper().showShareFile(getFile()); return true; } - case R.id.action_unshare_file: { - mContainerActivity.getFileOperationsHelper().unshareFileWithLink(getFile()); - return true; - } case R.id.action_open_file_with: { openFile(); return true; @@@ -366,15 -303,9 +358,15 @@@ return true; } case R.id.action_send_file: { - mContainerActivity.getFileOperationsHelper().sendDownloadedFile(getFile()); - return true; + if (getFile().isImage() && !getFile().isDown()){ + mContainerActivity.getFileOperationsHelper().sendCachedImage(getFile()); + return true; + } else { + mContainerActivity.getFileOperationsHelper().sendDownloadedFile(getFile()); + return true; + } } + case R.id.action_download_file: case R.id.action_sync_file: { mContainerActivity.getFileOperationsHelper().syncFile(getFile()); return true; @@@ -387,10 -318,6 +379,10 @@@ mContainerActivity.getFileOperationsHelper().toggleFavorite(getFile(), false); return true; } + case R.id.action_set_as_wallpaper:{ + mContainerActivity.getFileOperationsHelper().setPictureAs(getFile()); + return true; + } default: return false; } @@@ -577,12 -504,7 +569,12 @@@ imageView.setBackground(backrepeat); } - imageView.setImageBitmap(bitmap); + if (result.ocFile.getMimetype().equalsIgnoreCase("image/gif")){ + imageView.setGifImage(result.ocFile); + } else { + imageView.setImageBitmap(bitmap); + } + imageView.setVisibility(View.VISIBLE); mBitmap = bitmap; // needs to be kept for recycling when not useful } diff --combined src/com/owncloud/android/ui/preview/PreviewMediaFragment.java index ba80ace6,ee9180d0..b6ee12b9 --- a/src/com/owncloud/android/ui/preview/PreviewMediaFragment.java +++ b/src/com/owncloud/android/ui/preview/PreviewMediaFragment.java @@@ -20,15 -20,10 +20,15 @@@ package com.owncloud.android.ui.preview; import android.accounts.Account; +import android.accounts.AuthenticatorException; +import android.accounts.OperationCanceledException; import android.app.Activity; +import android.content.ActivityNotFoundException; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.media.MediaMetadataRetriever; +import android.net.Uri; +import android.os.AsyncTask; import android.support.v7.app.AlertDialog; import android.content.ComponentName; import android.content.Context; @@@ -55,16 -50,9 +55,16 @@@ import android.widget.ImageView import android.widget.Toast; import android.widget.VideoView; +import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.datamodel.OCFile; +import com.owncloud.android.datamodel.ThumbnailsCacheManager; import com.owncloud.android.files.FileMenuFilter; +import com.owncloud.android.lib.common.OwnCloudAccount; +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; +import com.owncloud.android.lib.common.OwnCloudCredentials; +import com.owncloud.android.lib.common.accounts.AccountUtils; import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.media.MediaControlView; import com.owncloud.android.media.MediaService; @@@ -74,9 -62,6 +74,9 @@@ import com.owncloud.android.ui.dialog.C import com.owncloud.android.ui.dialog.RemoveFileDialogFragment; import com.owncloud.android.ui.fragment.FileFragment; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + /** * This fragment shows a preview of a downloaded media file (audio or video). @@@ -100,7 -85,6 +100,7 @@@ public class PreviewMediaFragment exten private ImageView mImagePreview; private VideoView mVideoPreview; private int mSavedPlaybackPosition; + private String mUri; private MediaServiceBinder mMediaServiceBinder = null; private MediaControlView mMediaController = null; @@@ -198,6 -182,10 +198,6 @@@ if (mAccount == null) { throw new IllegalStateException("Instanced with a NULL ownCloud Account"); } - if (!file.isDown()) { - throw new IllegalStateException("There is no local file to preview"); - } - } else { file = (OCFile) savedInstanceState.getParcelable(PreviewMediaFragment.EXTRA_FILE); @@@ -208,7 -196,7 +208,7 @@@ mAutoplay = savedInstanceState.getBoolean(PreviewMediaFragment.EXTRA_PLAYING); } - if (file != null && file.isDown()) { + if (file != null) { if (file.isVideo()) { mVideoPreview.setVisibility(View.VISIBLE); mImagePreview.setVisibility(View.GONE); @@@ -281,7 -269,7 +281,7 @@@ Log_OC.v(TAG, "onStart"); OCFile file = getFile(); - if (file != null && file.isDown()) { + if (file != null) { if (file.isAudio()) { bindMediaService(); @@@ -361,19 -349,9 +361,9 @@@ public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_share_file: { - stopPreview(false); - mContainerActivity.getFileOperationsHelper().shareFileWithLink(getFile()); - return true; - } - case R.id.action_share_with_users: { seeShareFile(); return true; } - case R.id.action_unshare_file: { - stopPreview(false); - mContainerActivity.getFileOperationsHelper().unshareFileWithLink(getFile()); - return true; - } case R.id.action_open_file_with: { openFile(); return true; @@@ -449,67 -427,9 +439,67 @@@ // load the video file in the video player ; // when done, VideoHelper#onPrepared() will be called + if (getFile().isDown()) { + mUri = getFile().getStoragePath(); + } else { + Context context = MainApp.getAppContext(); + Account account = mContainerActivity.getStorageManager().getAccount(); + + mUri = generateUrlWithCredentials(account, context, getFile()); + } + mVideoPreview.setVideoURI(getFile().getStorageUri()); } + public static String generateUrlWithCredentials(Account account, Context context, OCFile file){ + OwnCloudAccount ocAccount = null; + try { + ocAccount = new OwnCloudAccount(account, context); + + final ClientGenerationTask task = new ClientGenerationTask(); + task.execute(ocAccount); + + OwnCloudClient mClient = task.get(); + String url = AccountUtils.constructFullURLForAccount(context, account) + Uri.encode(file.getRemotePath(), "/"); + OwnCloudCredentials credentials = mClient.getCredentials(); + + return url.replace("//", "//" + credentials.getUsername() + ":" + credentials.getAuthToken() + "@"); + + } catch (AccountUtils.AccountNotFoundException e) { + e.printStackTrace(); + + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + return ""; + } + + public static class ClientGenerationTask extends AsyncTask { + @Override + protected OwnCloudClient doInBackground(Object... params) { + Object account = params[0]; + if (account instanceof OwnCloudAccount){ + try { + OwnCloudAccount ocAccount = (OwnCloudAccount) account; + return OwnCloudClientManagerFactory.getDefaultSingleton(). + getClientFor(ocAccount, MainApp.getAppContext()); + } catch (AccountUtils.AccountNotFoundException e) { + e.printStackTrace(); + } catch (OperationCanceledException e) { + e.printStackTrace(); + } catch (AuthenticatorException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + return null; + } + } + private class VideoHelper implements OnCompletionListener, OnPreparedListener, OnErrorListener { @@@ -559,11 -479,28 +549,11 @@@ */ @Override public boolean onError(MediaPlayer mp, int what, int extra) { - Log_OC.e(TAG, "Error in video playback, what = " + what + ", extra = " + extra); - if (mVideoPreview.getWindowToken() != null) { - String message = MediaService.getMessageForMediaError( - getActivity(), what, extra); - new AlertDialog.Builder(getActivity()) - .setMessage(message) - .setPositiveButton(android.R.string.VideoView_error_button, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - dialog.dismiss(); - VideoHelper.this.onCompletion(null); - } - }) - .setCancelable(false) - .show(); - } + MediaService.streamWithExternalApp(mUri, getActivity()).show(); return true; } - } - @Override public void onPause() { Log_OC.v(TAG, "onPause"); diff --combined src/com/owncloud/android/ui/preview/PreviewTextFragment.java index a37a1bb3,41fd6db2..f0714695 --- a/src/com/owncloud/android/ui/preview/PreviewTextFragment.java +++ b/src/com/owncloud/android/ui/preview/PreviewTextFragment.java @@@ -290,18 -290,6 +290,18 @@@ public class PreviewTextFragment extend item.setVisible(false); item.setEnabled(false); } + + item = menu.findItem(R.id.action_switch_view); + if (item != null){ + item.setVisible(false); + item.setEnabled(false); + } + + item = menu.findItem(R.id.action_sort); + if (item != null) { + item.setVisible(false); + item.setEnabled(false); + } } /** @@@ -311,17 -299,9 +311,9 @@@ public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_share_file: { - mContainerActivity.getFileOperationsHelper().shareFileWithLink(getFile()); - return true; - } - case R.id.action_share_with_users: { mContainerActivity.getFileOperationsHelper().showShareFile(getFile()); return true; } - case R.id.action_unshare_file: { - mContainerActivity.getFileOperationsHelper().unshareFileWithLink(getFile()); - return true; - } case R.id.action_open_file_with: { openFile(); return true;