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=05aece0ec829c82673aac5df271afe7fd29a14e7 Merge remote-tracking branch 'remotes/upstream/master' into beta --- diff --git a/build.gradle b/build.gradle index 15b8ff6d..23816a1a 100644 --- a/build.gradle +++ b/build.gradle @@ -75,10 +75,10 @@ android { 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 } } diff --git a/owncloud-android-library b/owncloud-android-library index 2d9ab655..8966dbce 160000 --- a/owncloud-android-library +++ b/owncloud-android-library @@ -1 +1 @@ -Subproject commit 2d9ab65553e8f4b85aa10cb636921df9976e9878 +Subproject commit 8966dbcee044cec726633fdfd208ea106cf176c0 diff --git a/res/layout/share_file_layout.xml b/res/layout/share_file_layout.xml index feaddb3b..27a6133d 100644 --- a/res/layout/share_file_layout.xml +++ b/res/layout/share_file_layout.xml @@ -15,17 +15,19 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . --> - + + android:orientation="vertical" + > @@ -80,10 +85,10 @@ @@ -101,7 +106,7 @@ android:layout_height="wrap_content" android:id="@+id/shareNoUsers" android:text="@string/share_no_users" - android:textSize="12dip" + android:textSize="12sp" android:padding="12dp" /> + + + + + + + + + + + + + + + + + + + + + + + + - + + \ No newline at end of file diff --git a/res/menu/file_actions_menu.xml b/res/menu/file_actions_menu.xml index 4d24759b..894dc331 100644 --- a/res/menu/file_actions_menu.xml +++ b/res/menu/file_actions_menu.xml @@ -21,7 +21,7 @@ - - - عُدل في : تحميل تم تغيير اسم الملف إلى %1$s أثناء الرفع - شارك الرابط - الغاء مشاركة الرابط نعم لا تم diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index d3cd832e..9fc528b9 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -73,8 +73,6 @@ Dəyişdirildi: Yüklə Yüklənmə müddətində fayl buna %1$s yeniləndi - Linki yayımla - Link yayımlanmasını dayandır Bəli Xeyir Oldu diff --git a/res/values-bg-rBG/strings.xml b/res/values-bg-rBG/strings.xml index eea53c9c..555aee80 100644 --- a/res/values-bg-rBG/strings.xml +++ b/res/values-bg-rBG/strings.xml @@ -80,8 +80,6 @@ Изтегляне Файлът беше преименуван на %1$s по време на качването. Списък с изгледи - Връзка за споделяне - Премахване връзка за споделяне Да Не ОК diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml index 49df5a65..643a77a7 100644 --- a/res/values-bn-rBD/strings.xml +++ b/res/values-bn-rBD/strings.xml @@ -64,8 +64,6 @@ পরিবর্তিতঃ ডাউনলোড আপলোডের সময় ফাইলের পূণঃনামকরণ করা হয়েছে %1$s - লিংক ভাগাভাগি করেন - লিংক ছিনন করেন হ্যাঁ না তথাস্তু diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index 4ce4a45e..0047e351 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -20,7 +20,6 @@ Učitaj Novi direktorij Preuzmite - Podijelite vezu Da Ne Ok diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index b860271b..f4259ee5 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -73,8 +73,6 @@ Modificat: Baixa L\'arxiu s\'ha canviat de nom a %1$s durant la càrrega - Enllaç de compartició - Deixa de compartir l\'enllaç Sí No D\'acord diff --git a/res/values-cs-rCZ/strings.xml b/res/values-cs-rCZ/strings.xml index 5941be1b..17b824bc 100644 --- a/res/values-cs-rCZ/strings.xml +++ b/res/values-cs-rCZ/strings.xml @@ -82,9 +82,6 @@ Synchronizovat Soubor byl v průběhu odesílání přejmenován na %1$s Náhled seznamu - Sdílet odkaz - Zrušit sdílení odkazu - Sdílet s uživateli Ano Ne OK @@ -336,7 +333,6 @@ správce systému. %1$d soubory(ů), 1 adresář %1$d soubory(ů), %2$d adresáře(ů) Sdílení - Sdílet s uživateli a skupinami Zatím nebyla s uživateli sdílena žádná data Přidat uživatele nebo skupinu Hledat diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index be4c942e..ba66f244 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -80,8 +80,6 @@ Hent Filen blev omdøbt til %1$s under upload Listevisning - Del link - Ophæv deling Ja Nej OK diff --git a/res/values-de-rAT/strings.xml b/res/values-de-rAT/strings.xml index 43963466..5a161798 100644 --- a/res/values-de-rAT/strings.xml +++ b/res/values-de-rAT/strings.xml @@ -59,8 +59,6 @@ Erstellt am: Verändert am: Herunterladen - Link teilen - Link nicht mehr teilen Ja Nein OK diff --git a/res/values-de-rDE/strings.xml b/res/values-de-rDE/strings.xml index 45e371e2..26614c16 100644 --- a/res/values-de-rDE/strings.xml +++ b/res/values-de-rDE/strings.xml @@ -80,8 +80,6 @@ Herunterladen Datei wurde wärend des Uploads zu %1$s umbenannt Listen-Layout - Link teilen - Link nicht mehr teilen Ja Nein OK diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index c84258dd..e402cd31 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -81,8 +81,6 @@ Herunterladen Datei wurde wärend des Uploads zu %1$s umbenannt Listen-Layout - Link teilen - Link nicht mehr freigeben Ja Nein OK @@ -330,5 +328,7 @@ %1$d Dateien, 1 Ordner %1$d Dateien, %2$d Ordner Teilen + Es wurden noch keine Dateien mit Benutzern geteilt + Benutzer oder Gruppe hinzufügen Suche diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 66df5fdc..e18a37b3 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -82,9 +82,6 @@ Συγχρονισμός Το αρχείο μετονομάστηκε σε %1$s κατά τη μεταφόρτωση Διάταξη Λίστας - Διαμοιρασμός συνδέσμου - Ακύρωση διαμοιρασμού συνδέσμου - Διαμοιρασμός με χρήστες Ναι Όχι ΟΚ @@ -337,7 +334,6 @@ %1$d αρχεία, 1 φάκελος %1$d αρχεία, %2$d φάκελοι Διαμοιρασμός - Διαμοιρασμός με χρήστες και ομάδες Δεν έχουν διαμοιραστεί ακόμα δεδομένα με τους χρήστες Προσθήκη χρήστη ή ομάδας Αναζήτηση diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 5fc8dfd5..d6db6ccb 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -74,8 +74,6 @@ Modified: Download File was renamed to %1$s during upload - Share link - Unshare link Yes No OK diff --git a/res/values-eo/strings.xml b/res/values-eo/strings.xml index 4d98b491..a5d948af 100644 --- a/res/values-eo/strings.xml +++ b/res/values-eo/strings.xml @@ -48,8 +48,6 @@ Modifita je: Elŝuti La dosiero alinomiĝis al %1$s dum alŝuto - Konhavigi ligilon - Malkunhavigi ligilon Jes Ne Akcepti diff --git a/res/values-es-rAR/strings.xml b/res/values-es-rAR/strings.xml index 61655826..734f875a 100644 --- a/res/values-es-rAR/strings.xml +++ b/res/values-es-rAR/strings.xml @@ -21,6 +21,7 @@ Biggest - Smallest--> + Todos los archivos Abrir @@ -73,8 +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 diff --git a/res/values-es-rMX/strings.xml b/res/values-es-rMX/strings.xml index dc31f88b..e6945816 100644 --- a/res/values-es-rMX/strings.xml +++ b/res/values-es-rMX/strings.xml @@ -59,7 +59,6 @@ Modificado: Descargar El archivo fue renombrado como %1$s durante la subida - Enlace compartido Sí No Aceptar diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 0f77b149..6a515b23 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -82,9 +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 @@ -336,7 +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 --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml index 7167dc53..79d41350 100644 --- a/res/values-et-rEE/strings.xml +++ b/res/values-et-rEE/strings.xml @@ -80,8 +80,6 @@ Lae alla Fail nimetati üleslaadimise käigus ümber %1$ Nimekirja paigutus - Jaga linki - Tühista lingi jagamine Jah Ei OK diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 7cb8302d..c65857d8 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -71,8 +71,6 @@ Aldatuta: Deskargatu Fitxategiaren izena %1$sra aldatu da igotzean - Elkarbanatu lotura - Lotura partekatzeari utzi Bai Ez Ados diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index 35696da1..c8d95de4 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -71,8 +71,6 @@ تغییر یافته توسط: بارگیری فایل در هنگام بارگزاری به %1$s تغییر نام یافت - اشتراک گذاشتن لینک - لغو اشتراک گذاشتن لینک بله نه باشه diff --git a/res/values-fi-rFI/strings.xml b/res/values-fi-rFI/strings.xml index 7db80666..0be584db 100644 --- a/res/values-fi-rFI/strings.xml +++ b/res/values-fi-rFI/strings.xml @@ -82,9 +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 @@ -317,7 +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 --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 260ffbdf..a9e4c438 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -83,9 +83,6 @@ Téléchargez-le ici : %2$s Synchroniser 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 @@ -341,7 +338,6 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq %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 --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index 68ad0a43..f8061b81 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -83,9 +83,6 @@ Descárgueo de aquí: %2$s Sincronizar 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 @@ -335,7 +332,6 @@ Descárgueo de aquí: %2$s %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 --git a/res/values-he/strings.xml b/res/values-he/strings.xml index 14c8156d..9361e434 100644 --- a/res/values-he/strings.xml +++ b/res/values-he/strings.xml @@ -64,8 +64,6 @@ מועד השינוי: הורדה שם הקובץ השתנה ל־ %1$s במהלך ההעלאה - קישור לשיתוף - ביטול קישור לשיתוף כן לא אישור diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index 6fba8ee6..444158a2 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -43,7 +43,6 @@ prije par sekundi Nema ničega u ovoj mapi. Pošalji nešto! Preuzimanje - Podijelite vezu Da Ne U redu diff --git a/res/values-hu-rHU/strings.xml b/res/values-hu-rHU/strings.xml index 25967de6..2add8a2c 100644 --- a/res/values-hu-rHU/strings.xml +++ b/res/values-hu-rHU/strings.xml @@ -78,8 +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 diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml index ef78c1f3..aae25ab5 100644 --- a/res/values-hy/strings.xml +++ b/res/values-hy/strings.xml @@ -20,7 +20,6 @@ վրկ. առաջ Չափս. Բեռնել - Կիսվել հղմամբ Այո Ոչ Չեղարկել diff --git a/res/values-ia/strings.xml b/res/values-ia/strings.xml index 666c923b..48378a77 100644 --- a/res/values-ia/strings.xml +++ b/res/values-ia/strings.xml @@ -29,7 +29,6 @@ Dimension: Typo: Discargar - Compartir ligamine Si No Ok diff --git a/res/values-id/strings.xml b/res/values-id/strings.xml index f1f7d9fe..09372150 100644 --- a/res/values-id/strings.xml +++ b/res/values-id/strings.xml @@ -81,8 +81,6 @@ Unduh Berkas diubah namanya menjadi %1$s saat pengunggahan Daftar Tata Letak - Bagikan tautan - Batal bagikan tautan Ya Tidak Oke @@ -330,7 +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 --git a/res/values-is/strings.xml b/res/values-is/strings.xml index 046a7969..18b0ce4d 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -20,7 +20,6 @@ sek. Ekkert hér. Settu eitthvað inn! Niðurhal - Deila hlekk Já Nei Í lagi diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 3a2e02cb..94986c6b 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -82,9 +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 @@ -337,7 +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 --git a/res/values-ja-rJP/strings.xml b/res/values-ja-rJP/strings.xml index d17876a8..cb7a2a92 100644 --- a/res/values-ja-rJP/strings.xml +++ b/res/values-ja-rJP/strings.xml @@ -83,9 +83,6 @@ ファイルを同期 アップロード中にファイル名を %1$s に変更しました リストレイアウト - URLで共有 - 未共有のリンク - ユーザーと共有 はい いいえ OK @@ -338,7 +335,6 @@ %1$d ファイル、1 フォルダー %1$d ファイル、%2$d フォルダー 共有 - ユーザーまたはグループに共有 ユーザーと共有されているデータはありません ユーザーまたはグループを追加 検索 diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index 4ca45b17..0b621009 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -21,7 +21,6 @@ ಪೇರಿಸು ಹೊಸ ಕಡತಕೋಶ ಪ್ರತಿಯನ್ನು ಸ್ಥಳೀಯವಾಗಿ ಉಳಿಸಿಕೊಳ್ಳಿ - ಸಂಪರ್ಕ ಕೊಂಡಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು ಹೌದು ಇಲ್ಲ ಸರಿ diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index c856bf33..3947cc36 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -81,8 +81,6 @@ 다운로드 업로드 중 파일 이름을 %1$s(으)로 변경하였습니다 목록 레이아웃 - 링크 공유 - 링크 공유 해제 예 아니요 확인 @@ -329,7 +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 --git a/res/values-lb/strings.xml b/res/values-lb/strings.xml index 1c958f38..0e29ce56 100644 --- a/res/values-lb/strings.xml +++ b/res/values-lb/strings.xml @@ -62,7 +62,6 @@ Erstallt: Geännert: Eroflueden - Link deelen Jo Nee OK diff --git a/res/values-lt-rLT/strings.xml b/res/values-lt-rLT/strings.xml index 1459761d..c7361320 100644 --- a/res/values-lt-rLT/strings.xml +++ b/res/values-lt-rLT/strings.xml @@ -82,8 +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 @@ 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 @@ -243,6 +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 @@ %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 --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml index 42cb5bbf..47f28451 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -70,8 +70,6 @@ Modificēta: Lejupielādēt Datne tika pārsaukta uz %1$s augšupielādes laikā - Dalīt saiti - Pārtraukt dalīt saiti Jā Nē Labi diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml index a2708d3c..f1bc0094 100644 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@ -74,8 +74,6 @@ Изменето: Преземање Датотеката беше преименувана во %1$s за време на префрлањето - Сподели ја врската - Тргнете го споделувањето на врската Да Не Во ред diff --git a/res/values-nb-rNO/strings.xml b/res/values-nb-rNO/strings.xml index 95ad2e54..a18743a2 100644 --- a/res/values-nb-rNO/strings.xml +++ b/res/values-nb-rNO/strings.xml @@ -81,8 +81,6 @@ Last ned Filnavnet ble endret til %1$s under opplasting Listeoppsett - Del lenke - Avslutt deling av lenke Ja Nei OK @@ -330,7 +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 --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 9a3fa847..8161fbab 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -83,9 +83,6 @@ Download hier: %2$s Synchroniseren Bestand is tijdens het uploaden hernoemd naar %1$s Lijst layout - Deel link - Link niet meer delen - Delen met gebruiker Ja Nee OK @@ -340,7 +337,6 @@ Hieronder staan de lokale bestanden en de externe bestanden in %5$s waar ze naar %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 --git a/res/values-nn-rNO/strings.xml b/res/values-nn-rNO/strings.xml index aa846e38..ad53fb8d 100644 --- a/res/values-nn-rNO/strings.xml +++ b/res/values-nn-rNO/strings.xml @@ -58,7 +58,6 @@ Oppretta: Endra: Last ned - Del lenkje Ja Nei Greitt diff --git a/res/values-oc/strings.xml b/res/values-oc/strings.xml index 5ba832c1..9ef27933 100644 --- a/res/values-oc/strings.xml +++ b/res/values-oc/strings.xml @@ -83,9 +83,6 @@ Telecargatz-lo aicí : %2$s Sincronizar 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 @@ -338,7 +335,6 @@ En rason d\'aquesta modificacion, totes los fichièrs mandats amb de versions an %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 --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index f6a6f454..ed223e9f 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -80,8 +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 diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index 7b494cdd..a0333fe7 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -82,9 +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 @@ -337,7 +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 --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index a1adba9e..ae23c23c 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -82,8 +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 @@ -331,7 +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 --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index b997bc9b..195a31fc 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -80,8 +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 diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 5f124531..7d2886dd 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -82,8 +82,6 @@ Скачать Файл был переименован в %1$s во время загрузки Макет списка - Поделиться ссылкой - Убрать ссылку Да Нет ОК @@ -331,7 +329,6 @@ %1$d файлов, 1 каталог %1$d файлов, %2$d каталогов Общий доступ - Поделиться с пользователями или группами Нет данных используемых совместно с другими пользователями Добавить пользователя или группу Найти diff --git a/res/values-sk-rSK/strings.xml b/res/values-sk-rSK/strings.xml index b48dc6e0..13acac24 100644 --- a/res/values-sk-rSK/strings.xml +++ b/res/values-sk-rSK/strings.xml @@ -82,9 +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 @@ -337,7 +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 --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index 0b5a4a6b..1c4c26fc 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -80,8 +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 diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml index c4a9dec8..b6ccd8e6 100644 --- a/res/values-sq/strings.xml +++ b/res/values-sq/strings.xml @@ -82,9 +82,6 @@ Njëkohëso Kartela u riemërtua si %1$s gjatë ngarkimit Skemë Liste - Ndajeni lidhjen me të tjerët - Zhbëjeni ndarjen e lidhjes me të tjerët - Ndajeni me përdoruesit Po Jo OK @@ -333,7 +330,6 @@ %1$d kartela, 1 dosje %1$d kartela, %2$d dosje Ndarje me të tjerët - Ndani me Përdorues dhe Grupe Ende pa të dhëna të ndara me përdorues Shtoni Përdorues ose Grup Kërko diff --git a/res/values-sr-rSP/strings.xml b/res/values-sr-rSP/strings.xml index cde6c3d9..24bc8eb1 100644 --- a/res/values-sr-rSP/strings.xml +++ b/res/values-sr-rSP/strings.xml @@ -30,7 +30,6 @@ Veličina: Tip: Preuzmi - Podeli prečicu Da Ne Ok diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index f38facb6..f30a6ad6 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -80,8 +80,6 @@ Преузми Фајл је преименован у %1$s током отпремања Распоред листе - Веза дељења - Не дели везом Да Не У реду diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 6766749f..4c2c962a 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -73,8 +73,6 @@ Ändrad: Ladda ner Filen bytte namn till %1$s under uppladdningen - Dela länk - Sluta dela länk Ja Nej OK diff --git a/res/values-th-rTH/strings.xml b/res/values-th-rTH/strings.xml index 1dc33c1d..adb5208f 100644 --- a/res/values-th-rTH/strings.xml +++ b/res/values-th-rTH/strings.xml @@ -82,9 +82,6 @@ ประสานข้อมูล ไฟล์ได้ถูกเปลี่ยนชื่อเป็น %1$s ในระหว่างการอัพโหลด เค้าโครงรายการ - แชร์ลิงค์ - ยกเลิกการแชร์ลิงค์ - แชร์กับผู้ใช้ ตกลง ไม่ตกลง ตกลง @@ -335,7 +332,6 @@ %1$d ไฟล์, 1 โฟลเดอร์ %1$d ไฟล์, %2$d โฟลเดอร์ การแชร์ข้อมูล - แชร์ไปยังผู้ใช้หรือกลุ่ม ยังไม่มีข้อมูลที่แชร์กับผู้ใช้ในตอนนี้ เพิ่มผู้ใช่หรือกลุ่ม ค้นหา diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index 918e5e38..1dea4b82 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -71,6 +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 @@ 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 @@ -241,6 +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 @@ 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 @@ %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 --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index fed88cec..ebe436bf 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -81,8 +81,6 @@ Завантажити Файл був переіменований в %1$s протягом вивантаження Вигляд списку - Опублікувати посилання - Видалити посилання Так Ні OK diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur-rPK/strings.xml index 111a8662..e1ffd9fd 100644 --- a/res/values-ur-rPK/strings.xml +++ b/res/values-ur-rPK/strings.xml @@ -16,7 +16,6 @@ منسلک سیکنڈز پہلے ڈاؤن لوڈ، - اشتراک لنک ہاں نہیں اوکے diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 6ec75156..419d2123 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -58,8 +58,6 @@ Đã chỉnh sửa: Tải về Tập tin đã bị đổi tên thành %1$s trong quá trình tải lên - Chia sẻ liên kết - Liên kết không chia sẻ Yes Không Chấp nhận diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 39d4ea90..322abdaa 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -81,8 +81,6 @@ 下载 上传过程中文件被更名为了 %1$s 列表布局 - 分享链接 - 取消分享链接 是 否 确定 diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index 50f708ac..176f2834 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -38,8 +38,6 @@ 建立時間: 修改時間: 下載 - 分享連結 - 取消分享連結 是 否 確定 diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index c783957b..58e64baf 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -80,8 +80,6 @@ 下載 檔案名稱在上傳時已被更改為 %1$s 列表版型 - 分享連結 - 取消共享連結 是 否 好 @@ -324,7 +322,6 @@ %1$d 個檔案, 1 個資料夾 %1$d 個檔案, %2$d 個資料夾 分享 - 與用戶或群組分享 目前沒有任何您分享的內容 新增使用者或是群組 搜尋 diff --git a/res/values/strings.xml b/res/values/strings.xml index 7625c94f..68597bfb 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -84,9 +84,7 @@ Synchronize File was renamed to %1$s during upload List Layout - Share link - Unshare link - Share with users + Share Yes No OK @@ -289,6 +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,6 +310,7 @@ 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 @@ -414,9 +415,15 @@ 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 diff --git a/src/com/owncloud/android/datamodel/FileDataStorageManager.java b/src/com/owncloud/android/datamodel/FileDataStorageManager.java index 4ce3d42a..3e073759 100644 --- a/src/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/src/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -20,16 +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 @@ import com.owncloud.android.lib.resources.status.CapabilityBooleanType; 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; @@ -956,20 +961,20 @@ public class FileDataStorageManager { ); 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 +1007,42 @@ public class FileDataStorageManager { } + /** + * 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 +1242,16 @@ public class FileDataStorageManager { ); 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 +1455,30 @@ public class FileDataStorageManager { // 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 +1539,7 @@ public class FileDataStorageManager { ); 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 @@ -1882,6 +1937,8 @@ public class FileDataStorageManager { if (c.moveToFirst()) { capability = createCapabilityInstance(c); + } else { + capability = new OCCapability(); // return default with all UNKNOWN } c.close(); return capability; diff --git a/src/com/owncloud/android/files/FileMenuFilter.java b/src/com/owncloud/android/files/FileMenuFilter.java index 0b7eb811..65253033 100644 --- a/src/com/owncloud/android/files/FileMenuFilter.java +++ b/src/com/owncloud/android/files/FileMenuFilter.java @@ -184,34 +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); diff --git a/src/com/owncloud/android/files/FileOperationsHelper.java b/src/com/owncloud/android/files/FileOperationsHelper.java index f5050d4d..989b8487 100644 --- a/src/com/owncloud/android/files/FileOperationsHelper.java +++ b/src/com/owncloud/android/files/FileOperationsHelper.java @@ -51,8 +51,8 @@ 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; @@ -156,19 +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 +194,30 @@ public class FileOperationsHelper { } } + 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 +229,7 @@ public class FileOperationsHelper { 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 +238,8 @@ public class FileOperationsHelper { } } - - 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 +277,13 @@ public class FileOperationsHelper { } - 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 +293,7 @@ public class FileOperationsHelper { 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 +306,15 @@ public class FileOperationsHelper { 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 +344,67 @@ public class FileOperationsHelper { /** + * 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 +427,7 @@ public class FileOperationsHelper { // 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 { @@ -575,4 +669,5 @@ public class FileOperationsHelper { } return false; } + } diff --git a/src/com/owncloud/android/operations/CreateShareViaLinkOperation.java b/src/com/owncloud/android/operations/CreateShareViaLinkOperation.java index 373c57d1..e9cb7d2d 100644 --- a/src/com/owncloud/android/operations/CreateShareViaLinkOperation.java +++ b/src/com/owncloud/android/operations/CreateShareViaLinkOperation.java @@ -30,7 +30,6 @@ import android.content.Context; import android.content.Intent; import com.owncloud.android.R; -import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.operations.RemoteOperation; @@ -42,9 +41,9 @@ import com.owncloud.android.lib.resources.shares.OCShare; import com.owncloud.android.lib.resources.shares.ShareType; import com.owncloud.android.operations.common.SyncOperation; -public class CreateShareViaLinkOperation extends SyncOperation { +import java.util.ArrayList; - protected FileDataStorageManager mStorageManager; +public class CreateShareViaLinkOperation extends SyncOperation { private String mPath; private String mPassword; @@ -76,10 +75,21 @@ public class CreateShareViaLinkOperation extends SyncOperation { // Check if the share link already exists RemoteOperation operation = new GetRemoteSharesForFileOperation(mPath, false, false); RemoteOperationResult result = operation.execute(client); - // TODO - fix this check; if the user already shared the file with users or group, a share via link will not be created - if (!result.isSuccess() || result.getData().size() <= 0) { - operation = new CreateRemoteShareOperation( + boolean shareByLink = false; + // Check if the file is shared by link + if (result.isSuccess() && result.getData().size() > 0){ + ArrayList shares = result.getData(); + for(Object object: shares){ + if (((OCShare) object).getShareType() == ShareType.PUBLIC_LINK){ + shareByLink = true; + break; + } + } + } + + if (!result.isSuccess() || !shareByLink) { + CreateRemoteShareOperation createOp = new CreateRemoteShareOperation( mPath, ShareType.PUBLIC_LINK, "", @@ -87,7 +97,8 @@ public class CreateShareViaLinkOperation extends SyncOperation { mPassword, OCShare.DEFAULT_PERMISSION ); - result = operation.execute(client); + createOp.setGetShareDetails(true); + result = createOp.execute(client); } if (result.isSuccess()) { @@ -148,10 +159,12 @@ public class CreateShareViaLinkOperation extends SyncOperation { // Update OCFile with data from share: ShareByLink and publicLink OCFile file = getStorageManager().getFileByPath(mPath); if (file!=null) { - mSendIntent.putExtra(Intent.EXTRA_TEXT, share.getShareLink()); file.setPublicLink(share.getShareLink()); file.setShareViaLink(true); getStorageManager().saveFile(file); + if (mSendIntent != null) { + mSendIntent.putExtra(Intent.EXTRA_TEXT, share.getShareLink()); + } } } diff --git a/src/com/owncloud/android/operations/GetSharesForFileOperation.java b/src/com/owncloud/android/operations/GetSharesForFileOperation.java index 62c3be18..a04d4159 100644 --- a/src/com/owncloud/android/operations/GetSharesForFileOperation.java +++ b/src/com/owncloud/android/operations/GetSharesForFileOperation.java @@ -72,6 +72,11 @@ public class GetSharesForFileOperation extends SyncOperation { } getStorageManager().saveSharesDB(shares); + + } else if (result.getCode() == RemoteOperationResult.ResultCode.SHARE_NOT_FOUND) { + // no share on the file - remove local shares + getStorageManager().removeSharesForFile(mPath); + } return result; diff --git a/src/com/owncloud/android/operations/RefreshFolderOperation.java b/src/com/owncloud/android/operations/RefreshFolderOperation.java index 87dde21d..f9f9e8c9 100644 --- a/src/com/owncloud/android/operations/RefreshFolderOperation.java +++ b/src/com/owncloud/android/operations/RefreshFolderOperation.java @@ -246,7 +246,7 @@ public class RefreshFolderOperation extends RemoteOperation { 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"); } } diff --git a/src/com/owncloud/android/operations/UnshareOperation.java b/src/com/owncloud/android/operations/UnshareOperation.java index 41678314..d819abf5 100644 --- a/src/com/owncloud/android/operations/UnshareOperation.java +++ b/src/com/owncloud/android/operations/UnshareOperation.java @@ -69,11 +69,11 @@ public class UnshareOperation extends SyncOperation { if (share != null) { OCFile file = getStorageManager().getFileByPath(mRemotePath); RemoveRemoteShareOperation operation = - new RemoveRemoteShareOperation((int) share.getIdRemoteShared()); + new RemoveRemoteShareOperation((int) share.getRemoteId()); result = operation.execute(client); if (result.isSuccess()) { - Log_OC.d(TAG, "Share id = " + share.getIdRemoteShared() + " deleted"); + Log_OC.d(TAG, "Share id = " + share.getRemoteId() + " deleted"); if (mShareType == ShareType.PUBLIC_LINK) { file.setShareViaLink(false); diff --git a/src/com/owncloud/android/operations/UpdateShareViaLinkOperation.java b/src/com/owncloud/android/operations/UpdateShareViaLinkOperation.java new file mode 100644 index 00000000..14b60e8f --- /dev/null +++ b/src/com/owncloud/android/operations/UpdateShareViaLinkOperation.java @@ -0,0 +1,152 @@ +/** + * ownCloud Android client application + * + * @author David A. Velasco + * Copyright (C) 2015 ownCloud Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.owncloud.android.operations; + +import com.owncloud.android.datamodel.OCFile; +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.operations.RemoteOperation; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.resources.files.FileUtils; +import com.owncloud.android.lib.resources.shares.GetRemoteShareOperation; +import com.owncloud.android.lib.resources.shares.OCShare; +import com.owncloud.android.lib.resources.shares.ShareType; +import com.owncloud.android.lib.resources.shares.UpdateRemoteShareOperation; +import com.owncloud.android.operations.common.SyncOperation; + +import java.util.Calendar; + + +/** + * Updates an existing public share for a given file + */ + +public class UpdateShareViaLinkOperation extends SyncOperation { + + private String mPath; + private String mPassword; + private long mExpirationDateInMillis; + + /** + * Constructor + * + * @param path Full path of the file/folder being shared. Mandatory argument + */ + public UpdateShareViaLinkOperation(String path) { + + mPath = path; + mPassword = null; + mExpirationDateInMillis = 0; + } + + + /** + * Set password to update in public link. + * + * @param password Password to set to the public link. + * Empty string clears the current password. + * Null results in no update applied to the password. + */ + public void setPassword(String password) { + mPassword = password; + } + + + /** + * Set expiration date to update in Share resource. + * + * @param expirationDateInMillis Expiration date to set to the public link. + * A negative value clears the current expiration date. + * Zero value (start-of-epoch) results in no update done on + * the expiration date. + */ + public void setExpirationDate(long expirationDateInMillis) { + mExpirationDateInMillis = expirationDateInMillis; + } + + + @Override + protected RemoteOperationResult run(OwnCloudClient client) { + + OCShare publicShare = getStorageManager().getFirstShareByPathAndType( + mPath, + ShareType.PUBLIC_LINK, + "" + ); + + if (publicShare == null) { + // TODO try to get remote share before failing? + return new RemoteOperationResult( + RemoteOperationResult.ResultCode.SHARE_NOT_FOUND + ); + } + + // Update remote share with password + UpdateRemoteShareOperation udpateOp = new UpdateRemoteShareOperation( + publicShare.getRemoteId() + ); + udpateOp.setPassword(mPassword); + udpateOp.setExpirationDate(mExpirationDateInMillis); + RemoteOperationResult result = udpateOp.execute(client); + + if (result.isSuccess()) { + // Retrieve updated share / save directly with password? -> no; the password is not be saved + RemoteOperation getShareOp = new GetRemoteShareOperation(publicShare.getRemoteId()); + result = getShareOp.execute(client); + if (result.isSuccess()) { + OCShare share = (OCShare) result.getData().get(0); + updateData(share); + } + } + + return result; + } + + public String getPath() { + return mPath; + } + + public String getPassword() { + return mPassword; + } + + private void updateData(OCShare share) { + // Update DB with the response + share.setPath(mPath); + if (mPath.endsWith(FileUtils.PATH_SEPARATOR)) { + share.setIsFolder(true); + } else { + share.setIsFolder(false); + } + + getStorageManager().saveShare(share); // TODO info about having a password? ask to Gonzalo + + // Update OCFile with data from share: ShareByLink and publicLink + // TODO check & remove if not needed + OCFile file = getStorageManager().getFileByPath(mPath); + if (file != null) { + file.setPublicLink(share.getShareLink()); + file.setShareViaLink(true); + getStorageManager().saveFile(file); + } + } + +} + diff --git a/src/com/owncloud/android/services/OperationsService.java b/src/com/owncloud/android/services/OperationsService.java index eff8e032..b8658c95 100644 --- a/src/com/owncloud/android/services/OperationsService.java +++ b/src/com/owncloud/android/services/OperationsService.java @@ -64,9 +64,11 @@ import com.owncloud.android.operations.RenameFileOperation; 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.operations.common.SyncOperation; import java.io.IOException; +import java.util.Calendar; import java.util.Iterator; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; @@ -88,15 +90,19 @@ public class OperationsService extends Service { public static final String EXTRA_RESULT = "RESULT"; public static final String EXTRA_NEW_PARENT_PATH = "NEW_PARENT_PATH"; public static final String EXTRA_FILE = "FILE"; - public static final String EXTRA_PASSWORD_SHARE = "PASSWORD_SHARE"; + public static final String EXTRA_SHARE_PASSWORD = "SHARE_PASSWORD"; public static final String EXTRA_SHARE_TYPE = "SHARE_TYPE"; public static final String EXTRA_SHARE_WITH = "SHARE_WITH"; + public static final String EXTRA_SHARE_EXPIRATION_DATE_IN_MILLIS = "SHARE_EXPIRATION_YEAR"; + public static final String EXTRA_SHARE_EXPIRATION_MONTH_OF_YEAR = "SHARE_EXPIRATION_MONTH_OF_YEAR"; + public static final String EXTRA_SHARE_EXPIRATION_DAY_OF_MONTH = "SHARE_EXPIRATION_DAY_OF_MONTH"; public static final String EXTRA_COOKIE = "COOKIE"; public static final String ACTION_CREATE_SHARE_VIA_LINK = "CREATE_SHARE_VIA_LINK"; public static final String ACTION_CREATE_SHARE_WITH_SHAREE = "CREATE_SHARE_WITH_SHAREE"; public static final String ACTION_UNSHARE = "UNSHARE"; + public static final String ACTION_UPDATE_SHARE = "UPDATE_SHARE"; public static final String ACTION_GET_SERVER_INFO = "GET_SERVER_INFO"; public static final String ACTION_OAUTH2_GET_ACCESS_TOKEN = "OAUTH2_GET_ACCESS_TOKEN"; public static final String ACTION_GET_USER_NAME = "GET_USER_NAME"; @@ -553,7 +559,7 @@ public class OperationsService extends Service { String action = operationIntent.getAction(); if (action.equals(ACTION_CREATE_SHARE_VIA_LINK)) { // Create public share via link String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH); - String password = operationIntent.getStringExtra(EXTRA_PASSWORD_SHARE); + String password = operationIntent.getStringExtra(EXTRA_SHARE_PASSWORD); Intent sendIntent = operationIntent.getParcelableExtra(EXTRA_SEND_INTENT); if (remotePath.length() > 0) { operation = new CreateShareViaLinkOperation( @@ -563,17 +569,35 @@ public class OperationsService extends Service { ); } - } else if (action.equals(ACTION_CREATE_SHARE_WITH_SHAREE)) { // Create private share with user or group - String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH); - String shareeName = operationIntent.getStringExtra(EXTRA_SHARE_WITH); - ShareType shareType = (ShareType) operationIntent.getSerializableExtra(EXTRA_SHARE_TYPE); - if (remotePath.length() > 0) { - operation = new CreateShareWithShareeOperation( - remotePath, - shareeName, - shareType - ); - } + } else if (ACTION_UPDATE_SHARE.equals(action)) { + String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH); + if (remotePath.length() > 0) { + operation = new UpdateShareViaLinkOperation(remotePath); + + String password = operationIntent.getStringExtra(EXTRA_SHARE_PASSWORD); + ((UpdateShareViaLinkOperation)operation).setPassword(password); + + long expirationDate = operationIntent.getLongExtra( + EXTRA_SHARE_EXPIRATION_DATE_IN_MILLIS, + 0 + ); + ((UpdateShareViaLinkOperation)operation).setExpirationDate( + expirationDate + ); + } + + } else if (action.equals(ACTION_CREATE_SHARE_WITH_SHAREE)) { + // Create private share with user or group + String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH); + String shareeName = operationIntent.getStringExtra(EXTRA_SHARE_WITH); + ShareType shareType = (ShareType) operationIntent.getSerializableExtra(EXTRA_SHARE_TYPE); + if (remotePath.length() > 0) { + operation = new CreateShareWithShareeOperation( + remotePath, + shareeName, + shareType + ); + } } else if (action.equals(ACTION_UNSHARE)) { // Unshare file String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH); diff --git a/src/com/owncloud/android/ui/activity/FileActivity.java b/src/com/owncloud/android/ui/activity/FileActivity.java index 275f5d63..8a794436 100644 --- a/src/com/owncloud/android/ui/activity/FileActivity.java +++ b/src/com/owncloud/android/ui/activity/FileActivity.java @@ -67,12 +67,14 @@ 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.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 @@ public class FileActivity extends AppCompatActivity 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 @@ public class FileActivity extends AppCompatActivity /** 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 @@ public class FileActivity extends AppCompatActivity 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 @@ public class FileActivity extends AppCompatActivity protected NavigationDrawerListAdapter mNavigationDrawerAdapter = null; + // TODO re-enable when "Accounts" is available in Navigation Drawer // protected boolean mShowAccounts = false; @@ -183,7 +188,6 @@ public class FileActivity extends AppCompatActivity 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 @@ public class FileActivity extends AppCompatActivity @Override protected void onResume() { super.onResume(); - + mResumed = true; if (mOperationsServiceBinder != null) { doOnResumeAndBound(); } @@ -266,7 +270,7 @@ public class FileActivity extends AppCompatActivity if (mOperationsServiceBinder != null) { mOperationsServiceBinder.removeOperationListener(this); } - + mResumed = false; super.onPause(); } @@ -563,7 +567,6 @@ public class FileActivity extends AppCompatActivity 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 +610,18 @@ public class FileActivity extends AppCompatActivity 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 +636,6 @@ public class FileActivity extends AppCompatActivity return mRedirectingToSetupAccount; } - public boolean isTryShareAgain(){ - return mTryShareAgain; - } - - public void setTryShareAgain(boolean tryShareAgain) { - mTryShareAgain = tryShareAgain; - } - public OperationsServiceBinder getOperationsServiceBinder() { return mOperationsServiceBinder; } @@ -685,6 +692,7 @@ public class FileActivity extends AppCompatActivity 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 +747,12 @@ public class FileActivity extends AppCompatActivity 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 +771,10 @@ public class FileActivity extends AppCompatActivity 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 +798,31 @@ public class FileActivity extends AppCompatActivity 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, @@ -901,7 +915,9 @@ public class FileActivity extends AppCompatActivity /*if (!mOperationsServiceBinder.isPerformingBlockingOperation()) { dismissLoadingDialog(); }*/ - doOnResumeAndBound(); + if (mResumed) { + doOnResumeAndBound(); + } } else { return; diff --git a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java index 39649ef4..e69eb047 100644 --- a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java +++ b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java @@ -51,6 +51,7 @@ import android.support.v4.app.FragmentManager; 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 +81,11 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCo 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; @@ -1441,15 +1439,6 @@ public class FileDisplayActivity extends HookActivity } 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 +1448,6 @@ public class FileDisplayActivity extends HookActivity } - 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) { diff --git a/src/com/owncloud/android/ui/activity/ShareActivity.java b/src/com/owncloud/android/ui/activity/ShareActivity.java index 180b2a06..bf6e37a6 100644 --- a/src/com/owncloud/android/ui/activity/ShareActivity.java +++ b/src/com/owncloud/android/ui/activity/ShareActivity.java @@ -25,11 +25,14 @@ import android.app.SearchManager; import android.content.Intent; import android.net.Uri; import android.os.Bundle; +import android.support.v4.app.DialogFragment; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import com.owncloud.android.R; import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.operations.CreateShareViaLinkOperation; +import com.owncloud.android.operations.GetSharesForFileOperation; import com.owncloud.android.providers.UsersAndGroupsSearchProvider; import com.owncloud.android.lib.common.operations.RemoteOperation; @@ -37,10 +40,13 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.lib.resources.shares.OCShare; import com.owncloud.android.lib.resources.shares.ShareType; +import com.owncloud.android.ui.dialog.ShareLinkToDialog; import com.owncloud.android.ui.fragment.SearchShareesFragment; import com.owncloud.android.ui.fragment.ShareFileFragment; import com.owncloud.android.utils.GetShareWithUsersAsyncTask; +import org.apache.http.protocol.HTTP; + /** * Activity for sharing files @@ -55,6 +61,8 @@ public class ShareActivity extends FileActivity private static final String TAG_SHARE_FRAGMENT = "SHARE_FRAGMENT"; private static final String TAG_SEARCH_FRAGMENT = "SEARCH_USER_AND_GROUPS_FRAGMENT"; + /** Tag for dialog */ + private static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG"; @Override protected void onCreate(Bundle savedInstanceState) { @@ -78,7 +86,7 @@ public class ShareActivity extends FileActivity // Load data into the list Log_OC.d(TAG, "Refreshing lists on account set"); - refreshUsersInLists(); + refreshSharesFromStorageManager(); // Request for a refresh of the data through the server (starts an Async Task) refreshUsersOrGroupsListFromServer(); @@ -153,26 +161,48 @@ public class ShareActivity extends FileActivity public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) { super.onRemoteOperationFinish(operation, result); - if (result.isSuccess()) { - Log_OC.d(TAG, "Refreshing lists on successful sync"); - refreshUsersInLists(); + if (result.isSuccess() || + (operation instanceof GetSharesForFileOperation && + result.getCode() == RemoteOperationResult.ResultCode.SHARE_NOT_FOUND + ) + ) { + Log_OC.d(TAG, "Refreshing view on successful operation or finished refresh"); + refreshSharesFromStorageManager(); + } + + if (operation instanceof CreateShareViaLinkOperation) { + // Send link to the app + String link = ((OCShare) (result.getData().get(0))).getShareLink(); + Log_OC.d(TAG, "Share link = " + link); + + Intent intentToShareLink = new Intent(Intent.ACTION_SEND); + intentToShareLink.putExtra(Intent.EXTRA_TEXT, link); + intentToShareLink.setType(HTTP.PLAIN_TEXT_TYPE); + String[] packagesToExclude = new String[]{getPackageName()}; + DialogFragment chooserDialog = ShareLinkToDialog.newInstance(intentToShareLink, packagesToExclude); + chooserDialog.show(getSupportFragmentManager(), FTAG_CHOOSER_DIALOG); } } - private void refreshUsersInLists() { + + /** + * Updates the view, reading data from {@link com.owncloud.android.datamodel.FileDataStorageManager} + */ + private void refreshSharesFromStorageManager() { + ShareFileFragment shareFileFragment = getShareFileFragment(); - if (shareFileFragment != null) { // only if added to the view hierarchy!! - if (shareFileFragment.isAdded()) { - shareFileFragment.refreshUsersOrGroupsListFromDB(); - } + if (shareFileFragment != null + && shareFileFragment.isAdded()) { // only if added to the view hierarchy!! + shareFileFragment.refreshCapabilitiesFromDB(); + shareFileFragment.refreshUsersOrGroupsListFromDB(); + shareFileFragment.refreshPublicShareFromDB(); } SearchShareesFragment searchShareesFragment = getSearchFragment(); - if (searchShareesFragment != null) { - if (searchShareesFragment.isAdded()) { // only if added to the view hierarchy!! - searchShareesFragment.refreshUsersOrGroupsListFromDB(); - } + if (searchShareesFragment != null && + searchShareesFragment.isAdded()) { // only if added to the view hierarchy!! + searchShareesFragment.refreshUsersOrGroupsListFromDB(); } } diff --git a/src/com/owncloud/android/ui/dialog/ExpirationDatePickerDialogFragment.java b/src/com/owncloud/android/ui/dialog/ExpirationDatePickerDialogFragment.java new file mode 100644 index 00000000..502e18a9 --- /dev/null +++ b/src/com/owncloud/android/ui/dialog/ExpirationDatePickerDialogFragment.java @@ -0,0 +1,138 @@ +/** + * ownCloud Android client application + * + * @author David A. Velasco + * Copyright (C) 2015 ownCloud Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.owncloud.android.ui.dialog; + + +import android.app.DatePickerDialog; +import android.app.Dialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.text.format.DateUtils; +import android.widget.DatePicker; +import android.widget.Toast; + +import com.owncloud.android.datamodel.OCFile; +import com.owncloud.android.ui.activity.FileActivity; + +import java.util.Calendar; +import java.util.Date; + +/** + * Dialog requesting a date after today. + */ +public class ExpirationDatePickerDialogFragment + extends DialogFragment + implements DatePickerDialog.OnDateSetListener { + + /** Tag for FragmentsManager */ + public static final String DATE_PICKER_DIALOG = "DATE_PICKER_DIALOG"; + + /** Parameter constant for {@link OCFile} instance to set the expiration date */ + private static final String ARG_FILE = "FILE"; + + /** Parameter constant for date chosen initially */ + private static final String ARG_CHOSEN_DATE_IN_MILLIS = "CHOSEN_DATE_IN_MILLIS"; + + /** File to bind an expiration date */ + private OCFile mFile; + + /** + * Factory method to create new instances + * + * @param file File to bind an expiration date + * @param chosenDateInMillis Date chosen when the dialog appears + * @return New dialog instance + */ + public static ExpirationDatePickerDialogFragment newInstance(OCFile file, long chosenDateInMillis) { + Bundle arguments = new Bundle(); + arguments.putParcelable(ARG_FILE, file); + arguments.putLong(ARG_CHOSEN_DATE_IN_MILLIS, chosenDateInMillis); + + ExpirationDatePickerDialogFragment dialog = new ExpirationDatePickerDialogFragment(); + dialog.setArguments(arguments); + return dialog; + } + + /** + * {@inheritDoc} + * + * @return A new dialog to let the user choose an expiration date that will be bound to a share link. + */ + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + // Load arguments + mFile = getArguments().getParcelable(ARG_FILE); + + // Chosen date received as an argument must be later than tomorrow ; default to tomorrow in other case + final Calendar chosenDate = Calendar.getInstance(); + long tomorrowInMillis = chosenDate.getTimeInMillis() + DateUtils.DAY_IN_MILLIS; + long chosenDateInMillis = getArguments().getLong(ARG_CHOSEN_DATE_IN_MILLIS); + if (chosenDateInMillis > tomorrowInMillis) { + chosenDate.setTimeInMillis(chosenDateInMillis); + } else { + chosenDate.setTimeInMillis(tomorrowInMillis); + } + + // Create a new instance of DatePickerDialog + DatePickerDialog dialog = new DatePickerDialog( + getActivity(), + this, + chosenDate.get(Calendar.YEAR), + chosenDate.get(Calendar.MONTH), + chosenDate.get(Calendar.DAY_OF_MONTH) + ); + + // Prevent days in the past may be chosen + DatePicker picker = dialog.getDatePicker(); + picker.setMinDate(tomorrowInMillis - 1000); + + // Enforce spinners view; ignored by MD-based theme in Android >=5, but calendar is REALLY buggy + // in Android < 5, so let's be sure it never appears (in tablets both spinners and calendar are + // shown by default) + picker.setCalendarViewShown(false); + + return dialog; + } + + /** + * Called when the user choses an expiration date. + * + * @param view View instance where the date was chosen + * @param year Year of the date chosen. + * @param monthOfYear Month of the date chosen [0, 11] + * @param dayOfMonth Day of the date chosen + */ + @Override + public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { + + Calendar chosenDate = Calendar.getInstance(); + chosenDate.set(Calendar.YEAR, year); + chosenDate.set(Calendar.MONTH, monthOfYear); + chosenDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); + long chosenDateInMillis = chosenDate.getTimeInMillis(); + + ((FileActivity)getActivity()).getFileOperationsHelper().setExpirationDateToShareViaLink( + mFile, + chosenDateInMillis + ); + } +} diff --git a/src/com/owncloud/android/ui/dialog/ShareLinkToDialog.java b/src/com/owncloud/android/ui/dialog/ShareLinkToDialog.java index a315a1d5..29eaac2b 100644 --- a/src/com/owncloud/android/ui/dialog/ShareLinkToDialog.java +++ b/src/com/owncloud/android/ui/dialog/ShareLinkToDialog.java @@ -44,11 +44,8 @@ import android.widget.ImageView; import android.widget.TextView; import com.owncloud.android.R; -import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.lib.common.utils.Log_OC; -import com.owncloud.android.ui.activity.ComponentsGetter; import com.owncloud.android.ui.activity.CopyToClipboardActivity; -import com.owncloud.android.ui.activity.FileActivity; /** * Dialog showing a list activities able to resolve a given Intent, @@ -61,20 +58,15 @@ public class ShareLinkToDialog extends DialogFragment { ".ARG_INTENT"; private final static String ARG_PACKAGES_TO_EXCLUDE = ShareLinkToDialog.class.getSimpleName() + ".ARG_PACKAGES_TO_EXCLUDE"; - private final static String ARG_FILE_TO_SHARE = ShareLinkToDialog.class.getSimpleName() + - ".FILE_TO_SHARE"; - + private ActivityAdapter mAdapter; - private OCFile mFile; private Intent mIntent; - public static ShareLinkToDialog newInstance(Intent intent, String[] packagesToExclude, - OCFile fileToShare) { + public static ShareLinkToDialog newInstance(Intent intent, String[] packagesToExclude) { ShareLinkToDialog f = new ShareLinkToDialog(); Bundle args = new Bundle(); args.putParcelable(ARG_INTENT, intent); args.putStringArray(ARG_PACKAGES_TO_EXCLUDE, packagesToExclude); - args.putParcelable(ARG_FILE_TO_SHARE, fileToShare); f.setArguments(args); return f; } @@ -90,8 +82,7 @@ public class ShareLinkToDialog extends DialogFragment { String[] packagesToExclude = getArguments().getStringArray(ARG_PACKAGES_TO_EXCLUDE); List packagesToExcludeList = Arrays.asList(packagesToExclude != null ? packagesToExclude : new String[0]); - mFile = getArguments().getParcelable(ARG_FILE_TO_SHARE); - + PackageManager pm= getActivity().getPackageManager(); List activities = pm.queryIntentActivities(mIntent, PackageManager.MATCH_DEFAULT_ONLY); @@ -142,19 +133,10 @@ public class ShareLinkToDialog extends DialogFragment { ComponentName name=new ComponentName( actInfo.applicationInfo.packageName, actInfo.name); - mIntent.setComponent(name); - - if (sendAction) { - dialog.dismiss(); // explicitly added for Android 2.x devices - - // Send the file - ((FileActivity)getActivity()).startActivity(mIntent); + mIntent.setComponent(name); - } else { - // Create a new share resource - ((ComponentsGetter)getActivity()).getFileOperationsHelper() - .shareFileWithLinkToApp(mFile, "", mIntent); - } + // Send the file + getActivity().startActivity(mIntent); } }) .create(); diff --git a/src/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java b/src/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java index d069b5a0..1b7def27 100644 --- a/src/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java +++ b/src/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java @@ -21,7 +21,6 @@ package com.owncloud.android.ui.dialog; import android.support.v7.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; -import android.content.Intent; import android.os.Bundle; import android.support.v4.app.DialogFragment; import android.view.LayoutInflater; @@ -45,25 +44,26 @@ public class SharePasswordDialogFragment extends DialogFragment implements DialogInterface.OnClickListener { private static final String ARG_FILE = "FILE"; - private static final String ARG_SEND_INTENT = "SEND_INTENT"; + private static final String ARG_CREATE_SHARE = "CREATE_SHARE"; public static final String PASSWORD_FRAGMENT = "PASSWORD_FRAGMENT"; private OCFile mFile; - private Intent mSendIntent; + private boolean mCreateShare; /** * Public factory method to create new SharePasswordDialogFragment instances. * - * @param file - * @param sendIntent - * @return Dialog ready to show. + * @param file OCFile bound to the public share that which password will be set or updated + * @param createShare When 'true', the public share will be created; when 'false', will be assumed + * that the public share already exists, and its state will be directly updated. + * @return Dialog ready to show. */ - public static SharePasswordDialogFragment newInstance(OCFile file, Intent sendIntent) { + public static SharePasswordDialogFragment newInstance(OCFile file, boolean createShare) { SharePasswordDialogFragment frag = new SharePasswordDialogFragment(); Bundle args = new Bundle(); args.putParcelable(ARG_FILE, file); - args.putParcelable(ARG_SEND_INTENT, sendIntent); + args.putBoolean(ARG_CREATE_SHARE, createShare); frag.setArguments(args); return frag; } @@ -71,7 +71,7 @@ public class SharePasswordDialogFragment extends DialogFragment @Override public Dialog onCreateDialog(Bundle savedInstanceState) { mFile = getArguments().getParcelable(ARG_FILE); - mSendIntent = getArguments().getParcelable(ARG_SEND_INTENT); + mCreateShare = getArguments().getBoolean(ARG_CREATE_SHARE, false); // Inflate the layout for the dialog LayoutInflater inflater = getActivity().getLayoutInflater(); @@ -97,9 +97,6 @@ public class SharePasswordDialogFragment extends DialogFragment @Override public void onClick(DialogInterface dialog, int which) { if (which == AlertDialog.BUTTON_POSITIVE) { - // Enable the flag "Share again" - ((FileActivity) getActivity()).setTryShareAgain(true); - String password = ((TextView)(getDialog().findViewById(R.id.share_password))) .getText().toString(); @@ -112,13 +109,16 @@ public class SharePasswordDialogFragment extends DialogFragment return; } - // Share the file - ((FileActivity)getActivity()).getFileOperationsHelper() - .shareFileWithLinkToApp(mFile, password, mSendIntent); + if (mCreateShare) { + // Share the file + ((FileActivity) getActivity()).getFileOperationsHelper(). + shareFileViaLink(mFile, password); - } else { - // Disable the flag "Share again" - ((FileActivity) getActivity()).setTryShareAgain(false); + } else { + // updat existing link + ((FileActivity) getActivity()).getFileOperationsHelper(). + setPasswordToShareViaLink(mFile, password); + } } } } diff --git a/src/com/owncloud/android/ui/fragment/FileDetailFragment.java b/src/com/owncloud/android/ui/fragment/FileDetailFragment.java index 1362a125..e9cd9162 100644 --- a/src/com/owncloud/android/ui/fragment/FileDetailFragment.java +++ b/src/com/owncloud/android/ui/fragment/FileDetailFragment.java @@ -245,18 +245,9 @@ public class FileDetailFragment extends FileFragment implements OnClickListener 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 --git a/src/com/owncloud/android/ui/fragment/OCFileListFragment.java b/src/com/owncloud/android/ui/fragment/OCFileListFragment.java index 9a1f9eef..c606e676 100644 --- a/src/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/src/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -559,10 +559,6 @@ public class OCFileListFragment extends ExtendedListFragment { 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; } @@ -570,10 +566,6 @@ public class OCFileListFragment extends ExtendedListFragment { 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); diff --git a/src/com/owncloud/android/ui/fragment/ShareFileFragment.java b/src/com/owncloud/android/ui/fragment/ShareFileFragment.java index a0296533..46382a65 100644 --- a/src/com/owncloud/android/ui/fragment/ShareFileFragment.java +++ b/src/com/owncloud/android/ui/fragment/ShareFileFragment.java @@ -26,12 +26,17 @@ import android.app.Activity; import android.graphics.Bitmap; import android.os.Bundle; import android.support.v4.app.Fragment; +import android.support.v7.widget.AppCompatButton; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; +import android.widget.CompoundButton; import android.widget.ImageView; +import android.widget.ListAdapter; import android.widget.ListView; +import android.widget.ScrollView; +import android.widget.Switch; import android.widget.TextView; import android.widget.Toast; @@ -41,16 +46,22 @@ import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.datamodel.ThumbnailsCacheManager; import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.lib.resources.shares.OCShare; +import com.owncloud.android.lib.resources.shares.ShareType; +import com.owncloud.android.lib.resources.status.OCCapability; import com.owncloud.android.ui.activity.FileActivity; -import com.owncloud.android.ui.activity.ShareActivity; import com.owncloud.android.ui.adapter.ShareUserListAdapter; +import com.owncloud.android.ui.dialog.ExpirationDatePickerDialogFragment; import com.owncloud.android.utils.DisplayUtils; import com.owncloud.android.utils.MimetypeIconUtil; +import java.text.SimpleDateFormat; + import java.util.ArrayList; +import java.util.Date; /** - * Fragment for Sharing a file with sharees (users or groups) + * Fragment for Sharing a file with sharees (users or groups) or creating + * a public link. * * A simple {@link Fragment} subclass. * @@ -66,19 +77,48 @@ public class ShareFileFragment extends Fragment private static final String TAG = ShareFileFragment.class.getSimpleName(); - // the fragment initialization parameters + /** The fragment initialization parameters */ private static final String ARG_FILE = "FILE"; private static final String ARG_ACCOUNT = "ACCOUNT"; - // Parameters +// /** Tag for dialog */ +// private static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG"; + + /** File to share, received as a parameter in construction time */ private OCFile mFile; + + /** OC account holding the file to share, received as a parameter in construction time */ private Account mAccount; - // other members - private ArrayList mShares; - private ShareUserListAdapter mUserGroupsAdapter = null; + /** Reference to parent listener */ private OnShareFragmentInteractionListener mListener; + /** List of private shares bound to the file */ + private ArrayList mPrivateShares; + + /** Capabilities of the server */ + private OCCapability mCapabilities; + + /** Adapter to show private shares */ + private ShareUserListAdapter mUserGroupsAdapter = null; + + /** Public share bound to the file */ + private OCShare mPublicShare; + + /** Listener for changes on switch to share / unshare publicly */ + private CompoundButton.OnCheckedChangeListener mOnShareViaLinkSwitchCheckedChangeListener; + + /** + * Listener for user actions to set, update or clear password on public link + */ + private OnPasswordInteractionListener mOnPasswordInteractionListener = null; + + /** + * Listener for user actions to set, update or clear expiration date on public link + */ + private OnExpirationDateInteractionListener mOnExpirationDateInteractionListener = null; + + /** * Public factory method to create new ShareFileFragment instances. * @@ -105,18 +145,22 @@ public class ShareFileFragment extends Fragment @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + Log_OC.d(TAG, "onCreate"); if (getArguments() != null) { mFile = getArguments().getParcelable(ARG_FILE); mAccount = getArguments().getParcelable(ARG_ACCOUNT); } } + /** * {@inheritDoc} */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + Log_OC.d(TAG, "onCreateView"); + // Inflate the layout for this fragment View view = inflater.inflate(R.layout.share_file_layout, container, false); @@ -149,7 +193,7 @@ public class ShareFileFragment extends Fragment addUserGroupButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - boolean shareWithUsersEnable = AccountUtils.hasSearchUsersSupport(mAccount); + boolean shareWithUsersEnable = AccountUtils.hasSearchUsersSupport(mAccount); if (shareWithUsersEnable) { // Show Search Fragment mListener.showSearchUsersAndGroups(); @@ -160,15 +204,253 @@ public class ShareFileFragment extends Fragment } }); + // Switch to create public share + mOnShareViaLinkSwitchCheckedChangeListener = new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton switchView, boolean isChecked) { + } + }; + + // Set listener for user actions on switch for sharing/unsharing via link + initShareViaLinkListener(view); + + // Set listener for user actions on expiration date + initExpirationListener(view); + + // Set listener for user actions on password + initPasswordListener(view); + return view; } + + /** + * Binds listener for user actions to create or delete a public share + * to the views receiving the user events. + * + * @param shareView Root view in the fragment. + */ + private void initShareViaLinkListener(View shareView) { + mOnShareViaLinkSwitchCheckedChangeListener = new OnShareViaLinkListener(); + Switch shareViaLinkSwitch = (Switch) shareView.findViewById(R.id.shareViaLinkSectionSwitch); + shareViaLinkSwitch.setOnCheckedChangeListener(mOnShareViaLinkSwitchCheckedChangeListener); + } + + /** + * Listener for user actions that create or delete a public share. + */ + private class OnShareViaLinkListener + implements CompoundButton.OnCheckedChangeListener { + + /** + * Called by R.id.shareViaLinkSectionSwitch to create or delete a public link. + * + * @param switchView {@link Switch} toggled by the user, R.id.shareViaLinkSectionSwitch + * @param isChecked New switch state. + */ + @Override + public void onCheckedChanged(CompoundButton switchView, boolean isChecked) { + if (!isResumed()) { + // very important, setCheched(...) is called automatically during + // Fragment recreation on device rotations + return; + } + if (isChecked) { + if (mCapabilities != null && + mCapabilities.getFilesSharingPublicPasswordEnforced().isTrue()) { + // password enforced by server, request to the user before trying to create + ((FileActivity) getActivity()).getFileOperationsHelper(). + requestPasswordForShareViaLink(mFile, true); + + } else { + // create without password if not enforced by server or we don't know if enforced; + ((FileActivity) getActivity()).getFileOperationsHelper(). + shareFileViaLink(mFile, null); + + // FileActivtiy#onCreateShareViaLinkOperationFinish still handles the guess of enforcement + // for server in versions previous to OwnCloudVersion#MINIMUM_VERSION_CAPABILITIES_API + } + + } else { + ((FileActivity) getActivity()).getFileOperationsHelper(). + unshareFileViaLink(mFile); + } + + // undo the toggle to grant the view will be correct if any intermediate dialog is cancelled or + // the create/delete operation fails + switchView.setOnCheckedChangeListener(null); + switchView.toggle(); + switchView.setOnCheckedChangeListener(mOnShareViaLinkSwitchCheckedChangeListener); + } + } + + + /** + * Binds listener for user actions that start any update on a expiration date + * for the public link to the views receiving the user events. + * + * @param shareView Root view in the fragment. + */ + private void initExpirationListener(View shareView) { + mOnExpirationDateInteractionListener = new OnExpirationDateInteractionListener(); + + ((Switch) shareView.findViewById(R.id.shareViaLinkExpirationSwitch)). + setOnCheckedChangeListener(mOnExpirationDateInteractionListener); + + shareView.findViewById(R.id.shareViaLinkExpirationLabel). + setOnClickListener(mOnExpirationDateInteractionListener); + + shareView.findViewById(R.id.shareViaLinkExpirationValue). + setOnClickListener(mOnExpirationDateInteractionListener); + } + + /** + * Listener for user actions that start any update on the expiration date for the public link. + */ + private class OnExpirationDateInteractionListener + implements CompoundButton.OnCheckedChangeListener, View.OnClickListener { + + /** + * Called by R.id.shareViaLinkExpirationSwitch to set or clear the expiration date. + * + * @param switchView {@link Switch} toggled by the user, R.id.shareViaLinkExpirationSwitch + * @param isChecked New switch state. + */ + @Override + public void onCheckedChanged(CompoundButton switchView, boolean isChecked) { + if (!isResumed()) { + // very important, setCheched(...) is called automatically during + // Fragment recreation on device rotations + return; + } + if (isChecked) { + ExpirationDatePickerDialogFragment dialog = + ExpirationDatePickerDialogFragment.newInstance(mFile, -1); + dialog.show( + getActivity().getSupportFragmentManager(), + ExpirationDatePickerDialogFragment.DATE_PICKER_DIALOG + ); + + } else { + ((FileActivity) getActivity()).getFileOperationsHelper(). + setExpirationDateToShareViaLink(mFile, -1); + } + + // undo the toggle to grant the view will be correct if the dialog is cancelled + switchView.setOnCheckedChangeListener(null); + switchView.toggle(); + switchView.setOnCheckedChangeListener(mOnExpirationDateInteractionListener); + } + + /** + * Called by R.id.shareViaLinkExpirationLabel or R.id.shareViaLinkExpirationValue + * to change the current expiration date. + * + * @param expirationView Label or value view touched by the user. + */ + @Override + public void onClick(View expirationView) { + if (mPublicShare != null && mPublicShare.getExpirationDate() > 0) { + long chosenDateInMillis = -1; + if (mPublicShare != null) { + chosenDateInMillis = mPublicShare.getExpirationDate(); + } + ExpirationDatePickerDialogFragment dialog = + ExpirationDatePickerDialogFragment.newInstance( + mFile, + chosenDateInMillis + ); + dialog.show( + getActivity().getSupportFragmentManager(), + ExpirationDatePickerDialogFragment.DATE_PICKER_DIALOG + ); + } + } + } + + + /** + * Binds listener for user actions that start any update on a password for the public link + * to the views receiving the user events. + * + * @param shareView Root view in the fragment. + */ + private void initPasswordListener(View shareView) { + mOnPasswordInteractionListener = new OnPasswordInteractionListener(); + + ((Switch) shareView.findViewById(R.id.shareViaLinkPasswordSwitch)). + setOnCheckedChangeListener(mOnPasswordInteractionListener); + + shareView.findViewById(R.id.shareViaLinkPasswordLabel). + setOnClickListener(mOnPasswordInteractionListener); + + shareView.findViewById(R.id.shareViaLinkPasswordValue). + setOnClickListener(mOnPasswordInteractionListener); + } + + + /** + * Listener for user actions that start any update on a password for the public link. + */ + private class OnPasswordInteractionListener + implements CompoundButton.OnCheckedChangeListener, View.OnClickListener { + + /** + * Called by R.id.shareViaLinkPasswordSwitch to set or clear the password. + * + * @param switchView {@link Switch} toggled by the user, R.id.shareViaLinkPasswordSwitch + * @param isChecked New switch state. + */ + @Override + public void onCheckedChanged(CompoundButton switchView, boolean isChecked) { + if (!isResumed()) { + // very important, setCheched(...) is called automatically during + // Fragment recreation on device rotations + return; + } + if (isChecked) { + ((FileActivity) getActivity()).getFileOperationsHelper(). + requestPasswordForShareViaLink(mFile, false); + } else { + ((FileActivity) getActivity()).getFileOperationsHelper(). + setPasswordToShareViaLink(mFile, ""); // "" clears + } + + // undo the toggle to grant the view will be correct if the dialog is cancelled + switchView.setOnCheckedChangeListener(null); + switchView.toggle(); + switchView.setOnCheckedChangeListener(mOnPasswordInteractionListener); + } + + /** + * Called by R.id.shareViaLinkPasswordLabel or R.id.shareViaLinkPasswordValue + * to change the current password. + * + * @param passwordView Label or value view touched by the user. + */ + @Override + public void onClick(View passwordView) { + if (mPublicShare != null && mPublicShare.isPasswordProtected()) { + ((FileActivity) getActivity()).getFileOperationsHelper(). + requestPasswordForShareViaLink(mFile, false); + } + } + } + + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); + Log_OC.d(TAG, "onActivityCreated"); + + // Load known capabilities of the server from DB + refreshCapabilitiesFromDB(); - // Load data into the list + // Load data into the list of private shares refreshUsersOrGroupsListFromDB(); + + // Load data of public share, if exists + refreshPublicShareFromDB(); } @Override @@ -188,8 +470,23 @@ public class ShareFileFragment extends Fragment mListener = null; } + + /** + * Get known server capabilities from DB + * + * Depends on the parent Activity provides a {@link com.owncloud.android.datamodel.FileDataStorageManager} + * instance ready to use. If not ready, does nothing. + */ + public void refreshCapabilitiesFromDB() { + if (((FileActivity)mListener).getStorageManager() != null) { + mCapabilities = ((FileActivity)mListener).getStorageManager(). + getCapability(mAccount.name); + } + } + + /** - * Get users and groups from the DB to fill in the "share with" list + * Get users and groups from the DB to fill in the "share with" list. * * Depends on the parent Activity provides a {@link com.owncloud.android.datamodel.FileDataStorageManager} * instance ready to use. If not ready, does nothing. @@ -197,7 +494,7 @@ public class ShareFileFragment extends Fragment public void refreshUsersOrGroupsListFromDB (){ if (((FileActivity) mListener).getStorageManager() != null) { // Get Users and Groups - mShares = ((FileActivity) mListener).getStorageManager().getSharesWithForAFile( + mPrivateShares = ((FileActivity) mListener).getStorageManager().getSharesWithForAFile( mFile.getRemotePath(), mAccount.name ); @@ -213,7 +510,7 @@ public class ShareFileFragment extends Fragment mUserGroupsAdapter = new ShareUserListAdapter( getActivity(), R.layout.share_user_item, - mShares, + mPrivateShares, this ); @@ -221,15 +518,19 @@ public class ShareFileFragment extends Fragment TextView noShares = (TextView) getView().findViewById(R.id.shareNoUsers); ListView usersList = (ListView) getView().findViewById(R.id.shareUsersList); - if (mShares.size() > 0) { + if (mPrivateShares.size() > 0) { noShares.setVisibility(View.GONE); usersList.setVisibility(View.VISIBLE); usersList.setAdapter(mUserGroupsAdapter); - + setListViewHeightBasedOnChildren(usersList); } else { noShares.setVisibility(View.VISIBLE); usersList.setVisibility(View.GONE); } + + // Set Scroll to initial position + ScrollView scrollView = (ScrollView) getView().findViewById(R.id.shareScroll); + scrollView.scrollTo(0, 0); } @Override @@ -240,6 +541,201 @@ public class ShareFileFragment extends Fragment } + + /** + * Get public link from the DB to fill in the "Share link" section in the UI. + * + * Takes into account server capabilities before reading database. + * + * Depends on the parent Activity provides a {@link com.owncloud.android.datamodel.FileDataStorageManager} + * instance ready to use. If not ready, does nothing. + */ + public void refreshPublicShareFromDB() { + if (isPublicShareDisabled()) { + hidePublicShare(); + + } else if (((FileActivity) mListener).getStorageManager() != null) { + // Get public share + mPublicShare = ((FileActivity) mListener).getStorageManager().getFirstShareByPathAndType( + mFile.getRemotePath(), + ShareType.PUBLIC_LINK, + "" + ); + + // Update public share section + updatePublicShareSection(); + } + } + + /** + * @return 'True' when public share is disabled in the server + */ + private boolean isPublicShareDisabled() { + return (mCapabilities != null && + mCapabilities.getFilesSharingPublicEnabled().isFalse() + ); + } + + /** + * Updates in the UI the section about public share with the information in the current + * public share bound to mFile, if any + */ + private void updatePublicShareSection() { + if (mPublicShare != null && ShareType.PUBLIC_LINK.equals(mPublicShare.getShareType())) { + /// public share bound -> expand section + Switch shareViaLinkSwitch = getShareViaLinkSwitch(); + if (!shareViaLinkSwitch.isChecked()) { + // set null listener before setChecked() to prevent infinite loop of calls + shareViaLinkSwitch.setOnCheckedChangeListener(null); + shareViaLinkSwitch.setChecked(true); + shareViaLinkSwitch.setOnCheckedChangeListener( + mOnShareViaLinkSwitchCheckedChangeListener + ); + } + getExpirationDateSection().setVisibility(View.VISIBLE); + getPasswordSection().setVisibility(View.VISIBLE); + // GetLink button + AppCompatButton getLinkButton = getGetLinkButton(); + getLinkButton.setVisibility(View.VISIBLE); + getLinkButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + //GetLink from the server and show ShareLinkToDialog + ((FileActivity) getActivity()).getFileOperationsHelper(). + getFileWithLink(mFile); + + } + }); + + /// update state of expiration date switch and message depending on expiration date + Switch expirationDateSwitch = getExpirationDateSwitch(); + // set null listener before setChecked() to prevent infinite loop of calls + expirationDateSwitch.setOnCheckedChangeListener(null); + long expirationDate = mPublicShare.getExpirationDate(); + if (expirationDate > 0) { + if (!expirationDateSwitch.isChecked()) { + expirationDateSwitch.toggle(); + } + String formattedDate = + SimpleDateFormat.getDateInstance().format( + new Date(expirationDate) + ); + getExpirationDateValue().setText(formattedDate); + } else { + if (expirationDateSwitch.isChecked()) { + expirationDateSwitch.toggle(); + } + getExpirationDateValue().setText(R.string.empty); + } + // recover listener + expirationDateSwitch.setOnCheckedChangeListener( + mOnExpirationDateInteractionListener + ); + + /// update state of password switch and message depending on password protection + Switch passwordSwitch = getPasswordSwitch(); + // set null listener before setChecked() to prevent infinite loop of calls + passwordSwitch.setOnCheckedChangeListener(null); + if (mPublicShare.isPasswordProtected()) { + if (!passwordSwitch.isChecked()) { + passwordSwitch.toggle(); + } + getPasswordValue().setVisibility(View.VISIBLE); + } else { + if (passwordSwitch.isChecked()) { + passwordSwitch.toggle(); + } + getPasswordValue().setVisibility(View.INVISIBLE); + } + // recover listener + passwordSwitch.setOnCheckedChangeListener( + mOnPasswordInteractionListener + ); + + + } else { + /// no public share -> collapse section + Switch shareViaLinkSwitch = getShareViaLinkSwitch(); + if (shareViaLinkSwitch.isChecked()) { + shareViaLinkSwitch.setOnCheckedChangeListener(null); + getShareViaLinkSwitch().setChecked(false); + shareViaLinkSwitch.setOnCheckedChangeListener( + mOnShareViaLinkSwitchCheckedChangeListener + ); + } + getExpirationDateSection().setVisibility(View.GONE); + getPasswordSection().setVisibility(View.GONE); + getGetLinkButton().setVisibility(View.GONE); + } + } + + + /// BEWARE: next methods will failed with NullPointerException if called before onCreateView() finishes + + private Switch getShareViaLinkSwitch() { + return (Switch) getView().findViewById(R.id.shareViaLinkSectionSwitch); + } + + private View getExpirationDateSection() { + return getView().findViewById(R.id.shareViaLinkExpirationSection); + } + + private Switch getExpirationDateSwitch() { + return (Switch) getView().findViewById(R.id.shareViaLinkExpirationSwitch); + } + + private TextView getExpirationDateValue() { + return (TextView) getView().findViewById(R.id.shareViaLinkExpirationValue); + } + + private View getPasswordSection() { + return getView().findViewById(R.id.shareViaLinkPasswordSection); + } + + private Switch getPasswordSwitch() { + return (Switch) getView().findViewById(R.id.shareViaLinkPasswordSwitch); + } + + private TextView getPasswordValue() { + return (TextView) getView().findViewById(R.id.shareViaLinkPasswordValue); + } + + private AppCompatButton getGetLinkButton() { + return (AppCompatButton) getView().findViewById(R.id.shareViaLinkGetLinkButton); + } + + /** + * Hides all the UI elements related to public share + */ + private void hidePublicShare() { + getShareViaLinkSwitch().setVisibility(View.GONE); + getExpirationDateSection().setVisibility(View.GONE); + getPasswordSection().setVisibility(View.GONE); + getGetLinkButton().setVisibility(View.GONE); + } + + public static void setListViewHeightBasedOnChildren(ListView listView) { + ListAdapter listAdapter = listView.getAdapter(); + if (listAdapter == null) { + return; + } + int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(), View.MeasureSpec.AT_MOST); + int totalHeight = 0; + View view = null; + for (int i = 0; i < listAdapter.getCount(); i++) { + view = listAdapter.getView(i, view, listView); + if (i == 0) { + view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, ViewGroup.LayoutParams.WRAP_CONTENT)); + } + view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED); + totalHeight += view.getMeasuredHeight(); + } + ViewGroup.LayoutParams params = listView.getLayoutParams(); + params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); + listView.setLayoutParams(params); + listView.requestLayout(); + } + /** * This interface must be implemented by activities that contain this * fragment to allow an interaction in this fragment to be communicated diff --git a/src/com/owncloud/android/ui/preview/PreviewImageActivity.java b/src/com/owncloud/android/ui/preview/PreviewImageActivity.java index f797fe2f..6a260dd5 100644 --- a/src/com/owncloud/android/ui/preview/PreviewImageActivity.java +++ b/src/com/owncloud/android/ui/preview/PreviewImageActivity.java @@ -52,16 +52,11 @@ import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; 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; @@ -230,14 +225,7 @@ public class PreviewImageActivity extends FileActivity implements 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 @@ public class PreviewImageActivity extends FileActivity implements } } - - 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()) { diff --git a/src/com/owncloud/android/ui/preview/PreviewImageFragment.java b/src/com/owncloud/android/ui/preview/PreviewImageFragment.java index bdbfa1fc..1ef0377e 100644 --- a/src/com/owncloud/android/ui/preview/PreviewImageFragment.java +++ b/src/com/owncloud/android/ui/preview/PreviewImageFragment.java @@ -341,17 +341,9 @@ public class PreviewImageFragment extends FileFragment { 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; diff --git a/src/com/owncloud/android/ui/preview/PreviewMediaFragment.java b/src/com/owncloud/android/ui/preview/PreviewMediaFragment.java index ba80ace6..b6ee12b9 100644 --- a/src/com/owncloud/android/ui/preview/PreviewMediaFragment.java +++ b/src/com/owncloud/android/ui/preview/PreviewMediaFragment.java @@ -361,19 +361,9 @@ public class PreviewMediaFragment extends FileFragment implements 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; diff --git a/src/com/owncloud/android/ui/preview/PreviewTextFragment.java b/src/com/owncloud/android/ui/preview/PreviewTextFragment.java index a37a1bb3..f0714695 100644 --- a/src/com/owncloud/android/ui/preview/PreviewTextFragment.java +++ b/src/com/owncloud/android/ui/preview/PreviewTextFragment.java @@ -311,17 +311,9 @@ public class PreviewTextFragment extends FileFragment { 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; diff --git a/src/com/owncloud/android/utils/ErrorMessageAdapter.java b/src/com/owncloud/android/utils/ErrorMessageAdapter.java index 37b2fbac..be743866 100644 --- a/src/com/owncloud/android/utils/ErrorMessageAdapter.java +++ b/src/com/owncloud/android/utils/ErrorMessageAdapter.java @@ -27,6 +27,7 @@ import com.owncloud.android.R; 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.resources.shares.UpdateRemoteShareOperation; import com.owncloud.android.operations.CopyFileOperation; import com.owncloud.android.operations.CreateFolderOperation; import com.owncloud.android.operations.CreateShareViaLinkOperation; @@ -38,6 +39,7 @@ import com.owncloud.android.operations.RenameFileOperation; 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.operations.UploadFileOperation; import org.apache.commons.httpclient.ConnectTimeoutException; @@ -189,7 +191,7 @@ public class ErrorMessageAdapter { if (result.getData() != null && result.getData().size() > 0) { message = (String) result.getData().get(0); // share API sends its own error messages - } else if (result.getCode() == ResultCode.SHARE_NOT_FOUND) { + } else if (result.getCode() == ResultCode.SHARE_NOT_FOUND) { message = res.getString(R.string.unshare_link_file_no_exist); } else if (result.getCode() == ResultCode.SHARE_FORBIDDEN) { @@ -201,6 +203,25 @@ public class ErrorMessageAdapter { // Show a Message, operation finished without success message = res.getString(R.string.unshare_link_file_error); } + + } else if (operation instanceof UpdateShareViaLinkOperation) { + + if (result.getData() != null && result.getData().size() > 0) { + message = (String) result.getData().get(0); // share API sends its own error messages + + } else if (result.getCode() == ResultCode.SHARE_NOT_FOUND) { + message = res.getString(R.string.update_link_file_no_exist); + + } else if (result.getCode() == ResultCode.SHARE_FORBIDDEN) { + // Error --> No permissions + message = String.format(res.getString(R.string.forbidden_permissions), + res.getString(R.string.update_link_forbidden_permissions)); + + } else { // Generic error + // Show a Message, operation finished without success + message = res.getString(R.string.update_link_file_error); + } + } else if (operation instanceof MoveFileOperation) { if (result.getCode() == ResultCode.FILE_NOT_FOUND) {