From: tobiasKaminsky Date: Fri, 27 Nov 2015 16:49:53 +0000 (+0100) Subject: Merge remote-tracking branch 'remotes/upstream/removeRadiosInMigration' into beta X-Git-Tag: beta-20151128~4 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/16f21025318f8dc55945638893020977d443218b?hp=ee7ed7d322fdfa26e23ec3d4440b8139bc9f1ca0 Merge remote-tracking branch 'remotes/upstream/removeRadiosInMigration' into beta --- diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 12bd3f18..761afad6 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -18,7 +18,7 @@ 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 @@ - - - Gebruikersnaam Wagwoord sekondes gelede + Deel Ja Nee OK @@ -19,4 +20,6 @@ Stuur Kies + Stel verval datum + Beskerm met Wagwoord diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 81613eac..c55da81f 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -78,8 +78,7 @@ عُدل في : تحميل تم تغيير اسم الملف إلى %1$s أثناء الرفع - شارك الرابط - الغاء مشاركة الرابط + شارك نعم لا تم @@ -256,5 +255,8 @@ الأمان عنوان الخادم مشاركة + شارك الرابط + تعيين تاريخ إنتهاء الصلاحية + حماية كلمة السر البحث diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index d3cd832e..207fa46f 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -73,8 +73,7 @@ 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 + Paylaş Bəli Xeyir Oldu @@ -289,5 +288,6 @@ inzibatçınızla əlaqə saxlayasınız. Qoşulmanı yenilə Server ünvanı Paylaşılır + Linki yayımla Axtarış diff --git a/res/values-bg-rBG/strings.xml b/res/values-bg-rBG/strings.xml index eea53c9c..30e03e4c 100644 --- a/res/values-bg-rBG/strings.xml +++ b/res/values-bg-rBG/strings.xml @@ -80,8 +80,7 @@ Изтегляне Файлът беше преименуван на %1$s по време на качването. Списък с изгледи - Връзка за споделяне - Премахване връзка за споделяне + Споделяне Да Не ОК @@ -317,5 +316,8 @@ %1$d файла, 1 папка %1$d файла, %2$d папки Споделяне + Връзка за споделяне + Задаване на дата на изтичане + Защитено с парола Търсене diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml index 49df5a65..a4b0aad2 100644 --- a/res/values-bn-rBD/strings.xml +++ b/res/values-bn-rBD/strings.xml @@ -64,8 +64,7 @@ পরিবর্তিতঃ ডাউনলোড আপলোডের সময় ফাইলের পূণঃনামকরণ করা হয়েছে %1$s - লিংক ভাগাভাগি করেন - লিংক ছিনন করেন + ভাগাভাগি কর হ্যাঁ না তথাস্তু @@ -255,5 +254,8 @@ নিরাপত্তা সার্ভার ঠিকানা ভাগাভাগিরত + লিংক ভাগাভাগি করেন + মেয়াদোত্তীর্ণ হওয়ার তারিখ নির্ধারণ করুন + কূটশব্দ সুরক্ষিত অনুসন্ধান diff --git a/res/values-bn-rIN/strings.xml b/res/values-bn-rIN/strings.xml index 87b4b203..d8eddb68 100644 --- a/res/values-bn-rIN/strings.xml +++ b/res/values-bn-rIN/strings.xml @@ -17,6 +17,7 @@ ফাইলস নতুন ফোল্ডার ডাউনলোড করুন + শেয়ার বাতিল করা ভুল ফোল্ডারের নাম diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index 4ce4a45e..569bff0e 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -20,7 +20,7 @@ Učitaj Novi direktorij Preuzmite - Podijelite vezu + Dijeli Da Ne Ok @@ -39,5 +39,8 @@ Sigurnost Adresa servera Dijeljenje + Podijelite vezu + Postavite datum isteka + Zaštitita lozinkom Potraži diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index b860271b..e54eda68 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -73,8 +73,7 @@ Modificat: Baixa L\'arxiu s\'ha canviat de nom a %1$s durant la càrrega - Enllaç de compartició - Deixa de compartir l\'enllaç + Comparteix Sí No D\'acord @@ -262,5 +261,8 @@ Seguretat Adreça del servidor Compartir + Comparteix l\'enllaç + Estableix la data de venciment + Protegir amb contrasenya Cerca diff --git a/res/values-cs-rCZ/strings.xml b/res/values-cs-rCZ/strings.xml index 5941be1b..77aba362 100644 --- a/res/values-cs-rCZ/strings.xml +++ b/res/values-cs-rCZ/strings.xml @@ -82,9 +82,7 @@ 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 + Sdílet Ano Ne OK @@ -273,6 +271,8 @@ správce systému. Při pokusu o sdílení tohoto souboru či složky nastala chyba Nelze ukončit sdílení. Zkontrolujte prosím že soubor existuje Při pokusu o zrušení sdílení tohoto souboru či složky nastala chyba + Nelze aktulizovat. Ověřte že soubor existuje + Došlo k chybě při pokusu aktualizovat sdílený odkaz Zadejte heslo Musíte zadat heslo Odeslat @@ -289,6 +289,7 @@ správce systému. smazat tento soubor sdílet tento soubor zrušit sdílení tohoto souboru + aktualizovat tento sdílený odkaz vytvořit tento soubor nahrávat do tohoto adresáře Tento soubor již není dostupný na serveru @@ -339,6 +340,11 @@ správce systému. Sdílet s uživateli a skupinami Zatím nebyla s uživateli sdílena žádná data Přidat uživatele nebo skupinu + Sdílet odkaz + Nastavit datum vypršení platnosti + Chránit heslem + Zabezpečeno + Vytvořit odkaz Hledat Prohledat uživatele a skupiny %1$s (skupina) diff --git a/res/values-cy-rGB/strings.xml b/res/values-cy-rGB/strings.xml index d3b885d2..5a47c641 100644 --- a/res/values-cy-rGB/strings.xml +++ b/res/values-cy-rGB/strings.xml @@ -39,6 +39,7 @@ Addaswyd: Llwytho i lawr Ailenwyd y ffeil i %1$s wrth lwytho i fyny + Rhannu Ie Na Iawn @@ -130,5 +131,7 @@ Cyfrifon Dewisiwch + Gosod dyddiad dod i ben + Diogelu cyfrinair Chwilio diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index be4c942e..26979262 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -80,8 +80,7 @@ Hent Filen blev omdøbt til %1$s under upload Listevisning - Del link - Ophæv deling + Del Ja Nej OK @@ -328,5 +327,8 @@ %1$d filer, 1 mape %1$d filer, %2$d mapper Deling + Del link + Vælg udløbsdato + Beskyt med adgangskode Søg diff --git a/res/values-de-rAT/strings.xml b/res/values-de-rAT/strings.xml index 43963466..98dcaff2 100644 --- a/res/values-de-rAT/strings.xml +++ b/res/values-de-rAT/strings.xml @@ -59,8 +59,7 @@ Erstellt am: Verändert am: Herunterladen - Link teilen - Link nicht mehr teilen + Freigeben Ja Nein OK @@ -107,4 +106,5 @@ Konten Adresse des Servers + Link teilen diff --git a/res/values-de-rDE/strings.xml b/res/values-de-rDE/strings.xml index 45e371e2..fac8a64a 100644 --- a/res/values-de-rDE/strings.xml +++ b/res/values-de-rDE/strings.xml @@ -80,8 +80,7 @@ Herunterladen Datei wurde wärend des Uploads zu %1$s umbenannt Listen-Layout - Link teilen - Link nicht mehr teilen + Share Ja Nein OK @@ -321,5 +320,8 @@ %1$d Dateien, 1 Ordner %1$d Dateien, %2$d Ordner Teilen + Link teilen + Ein Ablaufdatum setzen + Passwortschutz Suche diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index c84258dd..0618cc42 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -81,8 +81,7 @@ Herunterladen Datei wurde wärend des Uploads zu %1$s umbenannt Listen-Layout - Link teilen - Link nicht mehr freigeben + Teilen Ja Nein OK @@ -330,5 +329,10 @@ %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 + Link teilen + Setze ein Ablaufdatum + Passwortschutz Suche diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 66df5fdc..19cdf9d1 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -82,9 +82,7 @@ Συγχρονισμός Το αρχείο μετονομάστηκε σε %1$s κατά τη μεταφόρτωση Διάταξη Λίστας - Διαμοιρασμός συνδέσμου - Ακύρωση διαμοιρασμού συνδέσμου - Διαμοιρασμός με χρήστες + Διαμοιράστε Ναι Όχι ΟΚ @@ -337,9 +335,11 @@ %1$d αρχεία, 1 φάκελος %1$d αρχεία, %2$d φάκελοι Διαμοιρασμός - Διαμοιρασμός με χρήστες και ομάδες Δεν έχουν διαμοιραστεί ακόμα δεδομένα με τους χρήστες Προσθήκη χρήστη ή ομάδας + Διαμοιρασμός συνδέσμου + Ορισμός ημ. λήξης + Προστασία συνθηματικού Αναζήτηση Αναζήτηση χρηστών και ομάδων %1$s (ομάδα) diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 5fc8dfd5..c87a88a8 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -74,8 +74,7 @@ Modified: Download File was renamed to %1$s during upload - Share link - Unshare link + Share Yes No OK @@ -300,5 +299,8 @@ Server address Not enough memory Sharing + Share link + Set expiration date + Password protect Search diff --git a/res/values-eo/strings.xml b/res/values-eo/strings.xml index 4d98b491..f9cabdfd 100644 --- a/res/values-eo/strings.xml +++ b/res/values-eo/strings.xml @@ -48,8 +48,7 @@ Modifita je: Elŝuti La dosiero alinomiĝis al %1$s dum alŝuto - Konhavigi ligilon - Malkunhavigi ligilon + Kunhavigi Jes Ne Akcepti @@ -187,5 +186,8 @@ 1 dosiero %1$d dosieroj Kunhavigo + Kunhavigi ligilon + Agordi limdaton + Protekti per pasvorto Serĉi diff --git a/res/values-es-rAR/strings.xml b/res/values-es-rAR/strings.xml index 61655826..5686138b 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,7 @@ Modificado: Descargar El archivo fue renombrado como %1$s durante la subida - Compartir vínculo - Dejar de compartir vínculo + Compartir Sí No Aceptar @@ -277,5 +277,8 @@ Dirección de subida del video Dirección del servidor Compartiendo + Compartir vínculo + Asignar fecha de vencimiento + Proteger con contraseña Buscar diff --git a/res/values-es-rCL/strings.xml b/res/values-es-rCL/strings.xml index 441831cf..2ba28fd5 100644 --- a/res/values-es-rCL/strings.xml +++ b/res/values-es-rCL/strings.xml @@ -44,6 +44,7 @@ Modificado: Descargar El archivo fue renombrado a %1$s durante la subida + Compartir Si No OK diff --git a/res/values-es-rMX/strings.xml b/res/values-es-rMX/strings.xml index dc31f88b..2a287bc4 100644 --- a/res/values-es-rMX/strings.xml +++ b/res/values-es-rMX/strings.xml @@ -59,7 +59,7 @@ Modificado: Descargar El archivo fue renombrado como %1$s durante la subida - Enlace compartido + Compartir Sí No Aceptar @@ -207,5 +207,8 @@ Seguridad Dirección del servidor Compartiendo + Enlace compartido + Establecer fecha de caducidad + Protección con contraseña Buscar diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 0f77b149..ae326b42 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -82,9 +82,7 @@ Sincronizar El fichero fue renombrado como %1$s durante la subida Diseño de lista - Compartir con enlace - Dejar de compartir - Compartir con usuarios + Compartir Sí No Aceptar @@ -336,9 +334,11 @@ %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 + Compartir enlace + Establecer fecha de caducidad + Protección con contraseña Buscar Buscar usuarios y grupos %1$s (grupo) diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml index 7167dc53..1cf4e6c4 100644 --- a/res/values-et-rEE/strings.xml +++ b/res/values-et-rEE/strings.xml @@ -80,8 +80,7 @@ Lae alla Fail nimetati üleslaadimise käigus ümber %1$ Nimekirja paigutus - Jaga linki - Tühista lingi jagamine + Jaga Jah Ei OK @@ -333,5 +332,8 @@ Allpool on loend kohalikest failidest ning serveris asuvatest failidest %5$s, mi %1$d faili, 1 kaust %1$d faili, %2$d kausta Jagamine + Jaga linki + Määra aegumise kuupäev + Parooliga kaitstud Otsi diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 7cb8302d..c9879c69 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -71,8 +71,7 @@ Aldatuta: Deskargatu Fitxategiaren izena %1$sra aldatu da igotzean - Elkarbanatu lotura - Lotura partekatzeari utzi + Partekatu Bai Ez Ados @@ -277,5 +276,8 @@ Mesedez, baimendu berriz Bideo Igoera Bidea Zerbitzariaren helbidea Partekatzea + Elkarbanatu lotura + Ezarri muga data + Babestu pasahitzarekin Bilatu diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index 35696da1..8dab96bf 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -71,8 +71,7 @@ تغییر یافته توسط: بارگیری فایل در هنگام بارگزاری به %1$s تغییر نام یافت - اشتراک گذاشتن لینک - لغو اشتراک گذاشتن لینک + اشتراک‌گذاری بله نه باشه @@ -296,5 +295,8 @@ %1$d فایل، 1 پوشه %1$d فایل, %2$d پوشه اشتراک گذاری + اشتراک گذاشتن لینک + تنظیم تاریخ انقضا + نگهداری کردن رمز عبور جست‌و‌جو diff --git a/res/values-fi-rFI/strings.xml b/res/values-fi-rFI/strings.xml index 7db80666..b0852a23 100644 --- a/res/values-fi-rFI/strings.xml +++ b/res/values-fi-rFI/strings.xml @@ -82,9 +82,7 @@ Synkronoi Tiedoston nimeksi muutettiin %1$s siirron yhteydessä Luettelon asettelu - Jaa linkki - Poista linkin jako - Jaa käyttäjien kanssa + Jaa Kyllä Ei OK @@ -317,8 +315,11 @@ %1$d tiedostoa, 1 kansio %1$d tiedostoa, %2$d kansiota Jakaminen - Jaa käyttäjien tai ryhmien kanssa + Jaa käyttäjien ja ryhmien kanssa Lisää käyttäjä tai ryhmä + Jaa linkki + Aseta päättymispäivä + Suojaa salasanalla Etsi Etsi käyttäjiä ja ryhmiä %1$s (ryhmä) diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 260ffbdf..1a5bc5ca 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -83,9 +83,7 @@ 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 + Partage Oui Non OK @@ -278,6 +276,8 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq Une erreur est survenue lors de la tentative de partage de ce fichier ou répertoire Impossible de supprimer le partage. Vérifiez que le fichier est bien présent Une erreur est survenue lors de la tentative d’annulation du partage de ce fichier ou répertoire + Actualisation impossible. Veuillez vérifier si ce fichier existe + Une erreur est survenue lors de la tentative de rafraîchissement du lien partagé Saisissez un mot de passe Vous devez saisir un mot de passe Envoyer @@ -294,6 +294,7 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq d’effacer ce fichier afin de partager ce fichier afin de ne plus partager ce fichier + pour mettre à jour ce lien partagé de créer ce fichier afin d’importer dans ce répertoire Ce fichier n’est plus disponible sur le serveur @@ -341,9 +342,14 @@ 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 + Partager avec des utilisateurs et des groupes Aucune donnée partagée avec des utilisateurs pour le moment Ajouter un Utilisateur ou un Groupe + Partager par lien public + Spécifier une date d\'expiration + Protéger par un mot de passe + Sécurisé + Obtenir le lien Rechercher Chercher parmi les utilisateurs et groupes %1$s (groupe) diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index 68ad0a43..b649f946 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -83,9 +83,7 @@ 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 + Compartir Si Non Aceptar @@ -335,9 +333,11 @@ 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 + Ligazón para compartir + Definir a data de caducidade + Protexido con contrasinal Buscar Buscar usuarios e grupos %1$s (grupo) diff --git a/res/values-he/strings.xml b/res/values-he/strings.xml index 14c8156d..693c69ee 100644 --- a/res/values-he/strings.xml +++ b/res/values-he/strings.xml @@ -64,8 +64,7 @@ מועד השינוי: הורדה שם הקובץ השתנה ל־ %1$s במהלך ההעלאה - קישור לשיתוף - ביטול קישור לשיתוף + שיתוף כן לא אישור @@ -252,5 +251,8 @@ אבטחה כתובת שרת שיתוף + קישור לשיתוף + הגדרת תאריך תפוגה + הגנה בססמה חיפוש diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index feb62ce7..ae1a5d70 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -28,6 +28,7 @@ जुड़ें अपलोड नया फ़ोल्डर + साझा करें रद्द करें त्रुटि विवरण diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index 6fba8ee6..7e422695 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -43,7 +43,7 @@ prije par sekundi Nema ničega u ovoj mapi. Pošalji nešto! Preuzimanje - Podijelite vezu + Dijeljenje Da Ne U redu @@ -66,5 +66,8 @@ Sigurnost Adresa poslužitelja Dijeljenje zajedničkih resursa + Podijelite vezu + Odredite datum isteka + Zaštititi lozinkom pretraži diff --git a/res/values-hu-rHU/strings.xml b/res/values-hu-rHU/strings.xml index 25967de6..3fb3b79f 100644 --- a/res/values-hu-rHU/strings.xml +++ b/res/values-hu-rHU/strings.xml @@ -78,8 +78,7 @@ 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 + Megosztás Igen Nem OK @@ -269,5 +268,8 @@ %1$d fájl, 1 könyvtár %1$d fájl, %2$d könyvtár Megosztás + Megosztás hivatkozással + Legyen lejárati idő + Jelszóval is védem Keresés diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml index ef78c1f3..1debd950 100644 --- a/res/values-hy/strings.xml +++ b/res/values-hy/strings.xml @@ -20,7 +20,7 @@ վրկ. առաջ Չափս. Բեռնել - Կիսվել հղմամբ + Կիսվել Այո Ոչ Չեղարկել @@ -42,4 +42,5 @@ %1$d ֆայլ %1$d ֆայլ, 1 պանակ %1$d ֆայլ, %2$d պանակ + Կիսվել հղմամբ diff --git a/res/values-ia/strings.xml b/res/values-ia/strings.xml index 666c923b..402b64ab 100644 --- a/res/values-ia/strings.xml +++ b/res/values-ia/strings.xml @@ -29,7 +29,7 @@ Dimension: Typo: Discargar - Compartir ligamine + Compartir Si No Ok @@ -45,5 +45,8 @@ Contos Contrasigno errate Seliger + Compartir ligamine + Fixa data de expiration + Protegite per contrasigno Cercar diff --git a/res/values-id/strings.xml b/res/values-id/strings.xml index f1f7d9fe..295a8edf 100644 --- a/res/values-id/strings.xml +++ b/res/values-id/strings.xml @@ -81,8 +81,7 @@ Unduh Berkas diubah namanya menjadi %1$s saat pengunggahan Daftar Tata Letak - Bagikan tautan - Batal bagikan tautan + Bagikan Ya Tidak Oke @@ -330,8 +329,10 @@ %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 + Bagikan tautan + Atur tanggal kedaluwarsa + Lindungi dengan sandi Cari diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml index 046a7969..3e89b526 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -20,7 +20,7 @@ sek. Ekkert hér. Settu eitthvað inn! Niðurhal - Deila hlekk + Deila Já Nei Í lagi @@ -35,5 +35,8 @@ Færa Veldu Host nafn netþjóns + Deila hlekk + Setja gildistíma + Verja með lykilorði Leita diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 3a2e02cb..49b5ce22 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -82,9 +82,7 @@ Sincronizza Il file è stato rinominato in %1$s durante il caricamento Struttura elenco - Condividi collegamento - Rimuovi condivisione collegamento - Condividi con utenti + Condividi Sì No OK @@ -274,6 +272,8 @@ Si è verificato un errore durante il tentativo di condivisione del file o della cartella Impossibile rimuovere dalla condivisione. Assicurati che il file esista Si è verificato un errore durante il tentativo di rimuovere la condivisione del file o della cartella + Impossibile aggiornare. Assicurati che il file esista + Si è verificato un errore durante il tentativo di aggiornare il collegamento condiviso Digita una password Devi digitare una password Invia @@ -290,6 +290,7 @@ per eliminare questo file per condividere questo file per rimuovere la condivisione di questo file + per aggiornare questo collegamento condiviso per creare il file per caricare in questa cartella Il file non è più disponibile sul server @@ -340,6 +341,11 @@ Condividi con utenti e gruppi Ancora nessun dato condiviso con gli utenti Aggiungi utente o gruppo + Condividi collegamento + Imposta data di scadenza + Proteggi con password + Protetto + Ottieni collegamento Cerca Cerca utenti e gruppi %1$s (gruppo) diff --git a/res/values-ja-rJP/strings.xml b/res/values-ja-rJP/strings.xml index d17876a8..eb66912f 100644 --- a/res/values-ja-rJP/strings.xml +++ b/res/values-ja-rJP/strings.xml @@ -83,9 +83,7 @@ ファイルを同期 アップロード中にファイル名を %1$s に変更しました リストレイアウト - URLで共有 - 未共有のリンク - ユーザーと共有 + 共有 はい いいえ OK @@ -275,6 +273,8 @@ このファイルまたはフォルダーを共有する際にエラーが発生しました 共有を解除できません。ファイルがあるか確認してください。 このファイルまたはフォルダーの共有を解除する際にエラーが発生しました + 更新できません。ファイルがあるか確認してください。 + 共有リンクを更新する際にエラーが発生しました パスワードを入力 パスワードを入力しなければなりません 送信 @@ -338,9 +338,14 @@ %1$d ファイル、1 フォルダー %1$d ファイル、%2$d フォルダー 共有 - ユーザーまたはグループに共有 + ユーザーとグループで共有 ユーザーと共有されているデータはありません ユーザーまたはグループを追加 + URLで共有 + 有効期限を設定 + パスワード保護を有効化 + セキュア + リンクを取得 検索 ユーザーとグループを検索 %1$s (グループ) diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml index 06bf89b1..acdeb627 100644 --- a/res/values-ka-rGE/strings.xml +++ b/res/values-ka-rGE/strings.xml @@ -43,6 +43,7 @@ მოდიფიცირებულია: ჩამოტვირთვა ფაილ %1$s–ზე გადარქმეულ იქნა სახელი ატვირთვის დროს + გაზიარება კი არა დიახ @@ -142,5 +143,7 @@ უსაფრთხოება სერვერის მისამართი გაზიარება + მიუთითე ვადის გასვლის დრო + პაროლით დაცვა ძებნა diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index 1c9ef992..ece7d32a 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -55,6 +55,7 @@ បាន​បង្កើត៖ បាន​កែ​សម្រួល៖ ទាញយក + ចែក​រំលែក ព្រម ទេ OK @@ -104,5 +105,7 @@ សុវត្ថិភាព អាសយដ្ឋាន​ម៉ាស៊ីន​បម្រើ ការ​ចែក​រំលែក + កំណត់​ពេល​ផុត​កំណត់ + ការ​ពារ​ដោយ​ពាក្យ​សម្ងាត់ ស្វែង​រក diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index 4ca45b17..52476d52 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -21,7 +21,7 @@ ಪೇರಿಸು ಹೊಸ ಕಡತಕೋಶ ಪ್ರತಿಯನ್ನು ಸ್ಥಳೀಯವಾಗಿ ಉಳಿಸಿಕೊಳ್ಳಿ - ಸಂಪರ್ಕ ಕೊಂಡಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು + ಹಂಚಿಕೊಳ್ಳಿ ಹೌದು ಇಲ್ಲ ಸರಿ @@ -40,5 +40,8 @@ ಭದ್ರತೆ ಪರಿಚಾರಕ ಗಣಕಯಂತ್ರದ ವಿಳಾಸ ಹಂಚಿಕೆ + ಸಂಪರ್ಕ ಕೊಂಡಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು + ಮುಕ್ತಾಯ ದಿನಾಂಕವನ್ನು ನಿರ್ದರಿಸಿ + ಗುಪ್ತಪದ ರಕ್ಷಿಸಿಕೂಳ್ಲಿ ಹುಡುಕು diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index c856bf33..2d1574cc 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -81,8 +81,7 @@ 다운로드 업로드 중 파일 이름을 %1$s(으)로 변경하였습니다 목록 레이아웃 - 링크 공유 - 링크 공유 해제 + 공유 예 아니요 확인 @@ -329,8 +328,10 @@ 파일 %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-ku-rIQ/strings.xml b/res/values-ku-rIQ/strings.xml index e03d0801..c40728bd 100644 --- a/res/values-ku-rIQ/strings.xml +++ b/res/values-ku-rIQ/strings.xml @@ -27,6 +27,7 @@ درووستبووە: گۆردراو: داگرتن + هاوبەشی کردن بەڵێ نەخێر باشە diff --git a/res/values-lb/strings.xml b/res/values-lb/strings.xml index 1c958f38..55bae322 100644 --- a/res/values-lb/strings.xml +++ b/res/values-lb/strings.xml @@ -62,7 +62,7 @@ Erstallt: Geännert: Eroflueden - Link deelen + Deelen Jo Nee OK @@ -230,5 +230,8 @@ %1$s huet \"%2$s\" mat dir gedeelt Connectioun opfrëschen Server-Adress + Link deelen + Verfallsdatum setzen + Passwuertgeschützt Sichen diff --git a/res/values-lt-rLT/strings.xml b/res/values-lt-rLT/strings.xml index 1459761d..201a001e 100644 --- a/res/values-lt-rLT/strings.xml +++ b/res/values-lt-rLT/strings.xml @@ -82,8 +82,7 @@ Sinchronizuojama Įkėlimo metu failas buvo pervadintas į %1$s Sąrašo išdėstymas - Dalintis nuoroda - Nebesidalinti nuoroda + Dalintis Taip Ne Gerai @@ -101,7 +100,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 +242,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 +333,14 @@ %1$d failai, 1 aplankas %1$d failai, %2$d aplankai Dalijimasis + Su vartotojais niekuo nesidalinama + Pridėti vartotoją ar grupę + Dalintis nuoroda + Nustatykite galiojimo laiką + Apsaugotas slaptažodžiu 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..0b2930d7 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -70,8 +70,7 @@ Modificēta: Lejupielādēt Datne tika pārsaukta uz %1$s augšupielādes laikā - Dalīt saiti - Pārtraukt dalīt saiti + Dalīties Jā Nē Labi @@ -190,5 +189,8 @@ 1 mape 1 datne Dalīšanās + Dalīt saiti + Iestaties termiņa datumu + Aizsargāt ar paroli Meklēt diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml index a2708d3c..0773d698 100644 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@ -74,8 +74,7 @@ Изменето: Преземање Датотеката беше преименувана во %1$s за време на префрлањето - Сподели ја врската - Тргнете го споделувањето на врската + Сподели Да Не Во ред @@ -296,5 +295,8 @@ Освежи ја конекцијата Адреса на сервер Споделување + Сподели ја врската + Постави рок на траење + Заштити со лозинка Барај diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml index 50f7a44c..9d180450 100644 --- a/res/values-mn/strings.xml +++ b/res/values-mn/strings.xml @@ -14,6 +14,7 @@ Нууц үг Файлууд Байршуулах + Түгээх Аккаунт үүсгэх Устгах diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml index 910ed909..66752dbd 100644 --- a/res/values-ms-rMY/strings.xml +++ b/res/values-ms-rMY/strings.xml @@ -38,6 +38,7 @@ Telah dibina: Telah diubah: Muatturun + Kongsi Ya Tidak OK diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml index 48cf4e1f..943676df 100644 --- a/res/values-my/strings.xml +++ b/res/values-my/strings.xml @@ -19,4 +19,5 @@ ပယ်ဖျက်မည် ရွေးချယ် + သက်တမ်းကုန်ဆုံးမည့်ရက်သတ်မှတ်မည် diff --git a/res/values-nb-rNO/strings.xml b/res/values-nb-rNO/strings.xml index 95ad2e54..8cc58e72 100644 --- a/res/values-nb-rNO/strings.xml +++ b/res/values-nb-rNO/strings.xml @@ -81,8 +81,7 @@ Last ned Filnavnet ble endret til %1$s under opplasting Listeoppsett - Del lenke - Avslutt deling av lenke + Delt ressurs Ja Nei OK @@ -330,8 +329,10 @@ %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 + Del lenke + Sett utløpsdato + Passordbeskyttet Søk diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 9a3fa847..50ab4156 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -83,9 +83,7 @@ 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 + Deel Ja Nee OK @@ -340,9 +338,11 @@ 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 + Deel link + Stel vervaldatum in + Wachtwoord beveiligd Zoeken Zoeken naar gebruikers en groepen %1$s (groep) diff --git a/res/values-nn-rNO/strings.xml b/res/values-nn-rNO/strings.xml index aa846e38..6392a965 100644 --- a/res/values-nn-rNO/strings.xml +++ b/res/values-nn-rNO/strings.xml @@ -58,7 +58,7 @@ Oppretta: Endra: Last ned - Del lenkje + Del Ja Nei Greitt @@ -127,5 +127,8 @@ Tryggleik Tenaradresse Deling + Del lenkje + Set utløpsdato + Passordvern Søk diff --git a/res/values-oc/strings.xml b/res/values-oc/strings.xml index 5ba832c1..b06c6fe0 100644 --- a/res/values-oc/strings.xml +++ b/res/values-oc/strings.xml @@ -83,9 +83,7 @@ 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 + Partejar Òc Non D\'acòrdi @@ -338,9 +336,11 @@ 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 + Partejar lo ligam + Especificar una data d\'expiracion + Protegir per un senhal Recercar Recercar d\'utilizaires e de gropes diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml index 35a3769a..bee80589 100644 --- a/res/values-pa/strings.xml +++ b/res/values-pa/strings.xml @@ -40,6 +40,7 @@ ਬਣਾਈ: ਸੋਧ ਕੀਤੀ: ਡਾਊਨਲੋਡ + ਸਾਂਝਾ ਕਰੋ ਹਾਂ ਨਹੀਂ ਠੀਕ ਹੈ diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index f6a6f454..9d77e88f 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -80,8 +80,7 @@ Pobierz Podczas wysyłania nazwa pliku została zmieniona na %1$s Lista szablonów wyglądu - Udostępnij link - Anuluj udostępnianie + Udostępnij Tak Nie OK @@ -317,5 +316,8 @@ 1 plik 1 plik , 1 folder Udostępnianie + Udostępnij link + Ustaw datę wygaśnięcia + Zabezpiecz hasłem Wyszukaj diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index 7b494cdd..075acaf8 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -82,9 +82,7 @@ Sincronizar Arquivo foi renomeado para %1$s durante o envio Lista de Layout - Compartilhar link - Descompartilhar o link - Compartilhado com usuários + Compartilhar Sim Não OK @@ -337,9 +335,11 @@ %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 + Compartilhar link + Definir data de expiração + Proteger com senha Perquisar Pesquisar usuários e grupos %1$s (grupo) diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index a1adba9e..70367249 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -82,8 +82,7 @@ Sincronizar O ficheiro foi renomeado para %1$s durante o envio. Apresentação da Lista - Partilhar a hiperligação - Cancelar partilha da hiperligação + Compartilhar Sim Não ACEITAR @@ -331,8 +330,10 @@ %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 + Compartilhar hiperligação + Definir a data de expiração + Proteger com Palavra-passe Procurar diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index b997bc9b..040e1148 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -80,8 +80,7 @@ Descarcă Fișierul a fost redenumit %1$s în timpul încărcării Aspect listă - Partajază legătură - Departajează legătura + Partajează Da Nu OK @@ -323,5 +322,8 @@ %1$d fișiere, 1 folder %1$d fișiere, %2$d foldere Partajare + Partajază legătură + Specifică data expirării + Protejare cu parolă Căutare diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 5f124531..0b416836 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -82,8 +82,7 @@ Скачать Файл был переименован в %1$s во время загрузки Макет списка - Поделиться ссылкой - Убрать ссылку + Общий доступ Да Нет ОК @@ -331,8 +330,10 @@ %1$d файлов, 1 каталог %1$d файлов, %2$d каталогов Общий доступ - Поделиться с пользователями или группами Нет данных используемых совместно с другими пользователями Добавить пользователя или группу + Поделиться ссылкой + Установить срок действия + Защитить паролем Найти diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml index 7ecb8cce..2531d9b2 100644 --- a/res/values-si-rLK/strings.xml +++ b/res/values-si-rLK/strings.xml @@ -33,6 +33,7 @@ සෑදු දිනය: වෙනස් කළ දිනය: භාගත කරන්න + බෙදා හදා ගන්න ඔව් එපා හරි @@ -79,5 +80,7 @@ තෝරන්න සේවාදායකයේ ලිපිනය හුවමාරු කිරීම + කල් ඉකුත් විමේ දිනය දමන්න + මුර පදයකින් ආරක්ශාකරන්න සොයන්න diff --git a/res/values-sk-rSK/strings.xml b/res/values-sk-rSK/strings.xml index b48dc6e0..5d9f412f 100644 --- a/res/values-sk-rSK/strings.xml +++ b/res/values-sk-rSK/strings.xml @@ -82,9 +82,7 @@ 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 + Zdieľať Áno Nie OK @@ -337,9 +335,11 @@ %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 + Zdieľať linku + Nastaviť dátum expirácie + Chrániť heslom Hľadať Vyhľadať používateľov alebo skupiny %1$s (skupina) diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index 0b5a4a6b..ca340d27 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -80,8 +80,7 @@ Prejmi Datoteka je bila med nalaganjem preimenovana v %1$s Postavitev seznama - Povezava za souporabo - Odstrani možnost souporabe + Souporaba Da Ne V redu @@ -325,5 +324,8 @@ %1$d datotek, 1 mapa %1$d datotek, %2$d map Souporaba + Povezava za souporabo + Nastavi datum preteka + Zaščiti z geslom Poišči diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml index c4a9dec8..3bb00882 100644 --- a/res/values-sq/strings.xml +++ b/res/values-sq/strings.xml @@ -82,9 +82,7 @@ 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 + Ndaje Po Jo OK @@ -270,6 +268,8 @@ Ndodhi një gabim teksa përpiqej të ndahej me të tjerët kjo kartelë apo dosje S\’arrin të zhbëjë ndarjen me të tjerët. Ju lutemi, kontrolloni nëse kartela ekziston Ndodhi një gabim teksa përpiqej të zhbëhej ndarja me të tjerët e kësaj kartele apo dosjeje + S’u arrit të përditësohej gjë. Ju lutemi, kontrolloni nëse ekziston apo jo kartela. + Ndodhi një gabim teksa provohej të përditësohej lidhja e ndarë me të tjerët Jepni një fjalëkalim Duhet të jepni një fjalëkalim Dërgoje @@ -286,6 +286,7 @@ për fshirje të kësaj kartele për ndarje me të tjerët të kësaj kartele për zhbërje të ndarjes me të tjerët të kësaj kartele + që të përditësohet kjo lidhje e ndarë me të tjerët për krijim kartele për ngarkim në këtë dosje Kartela s\’gjendet më te shërbyesi @@ -333,9 +334,14 @@ %1$d kartela, 1 dosje %1$d kartela, %2$d dosje Ndarje me të tjerët - Ndani me Përdorues dhe Grupe + Ndajeni me përdorues dhe grupe Ende pa të dhëna të ndara me përdorues Shtoni Përdorues ose Grup + Lidhje ndarjeje + Caktoni datë skadimi + Mbroje me fjalëkalim + E siguruar + Merreni lidhjen Kërko Kërkoni për grupe dhe përdorues %1$s (grup) diff --git a/res/values-sr-rSP/strings.xml b/res/values-sr-rSP/strings.xml index cde6c3d9..9b967f90 100644 --- a/res/values-sr-rSP/strings.xml +++ b/res/values-sr-rSP/strings.xml @@ -30,7 +30,7 @@ Veličina: Tip: Preuzmi - Podeli prečicu + Deljenje Da Ne Ok @@ -72,5 +72,8 @@ Nalozi Izaberi + Veza deljenja + Datum isteka + Zaštita lozinkom Traži diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index f38facb6..c20addc9 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -80,8 +80,7 @@ Преузми Фајл је преименован у %1$s током отпремања Распоред листе - Веза дељења - Не дели везом + Дељење Да Не У реду @@ -318,5 +317,8 @@ %1$d фајлова, 1 фасцикла %1$d фајлова, %2$d фасцикли Дељење + Веза дељења + Постави датум истека + Заштићено лозинком Тражи diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 6766749f..29bf4a2c 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -73,8 +73,7 @@ Ändrad: Ladda ner Filen bytte namn till %1$s under uppladdningen - Dela länk - Sluta dela länk + Dela Ja Nej OK @@ -284,5 +283,8 @@ %1$s delade \"%2$s\" med dig Serveradress Dela + Dela länk + Sätt utgångsdatum + Lösenordsskydda Sök diff --git a/res/values-ta-rLK/strings.xml b/res/values-ta-rLK/strings.xml index 19374391..43b6e82c 100644 --- a/res/values-ta-rLK/strings.xml +++ b/res/values-ta-rLK/strings.xml @@ -39,6 +39,7 @@ மாற்றப்பட்டது: பதிவிறக்குக பதிவேற்றும்போது கோப்பின் பெயரானது %1$s ஆக பெயர்மாற்றப்பட்டது + பகிர்வு ஆம் இல்லை சரி @@ -126,5 +127,7 @@ கணக்குகள் தெரிவுசெய்க சேவையக முகவரி + காலாவதி தேதியை குறிப்பிடுக + கடவுச்சொல்லை பாதுகாத்தல் தேடுதல் diff --git a/res/values-th-rTH/strings.xml b/res/values-th-rTH/strings.xml index 1dc33c1d..c54b0834 100644 --- a/res/values-th-rTH/strings.xml +++ b/res/values-th-rTH/strings.xml @@ -82,9 +82,7 @@ ประสานข้อมูล ไฟล์ได้ถูกเปลี่ยนชื่อเป็น %1$s ในระหว่างการอัพโหลด เค้าโครงรายการ - แชร์ลิงค์ - ยกเลิกการแชร์ลิงค์ - แชร์กับผู้ใช้ + แชร์ ตกลง ไม่ตกลง ตกลง @@ -288,6 +286,7 @@ เพื่อลบไฟล์นี้ เพื่อแชร์ไฟล์นี้ เพื่อเลิกแชร์ไฟล์นี้ + เพื่ออัพเดทลิงค์นี้ที่ถูกแชร์ เพื่อสร้างไฟล์ เพื่ออัพโหลดในโฟลเดอร์นี้ ไฟล์ไม่พร้อมใช้งานบนเซิร์ฟเวอร์ @@ -335,9 +334,14 @@ %1$d ไฟล์, 1 โฟลเดอร์ %1$d ไฟล์, %2$d โฟลเดอร์ การแชร์ข้อมูล - แชร์ไปยังผู้ใช้หรือกลุ่ม + แชร์กับผู้ใช้และกลุ่ม ยังไม่มีข้อมูลที่แชร์กับผู้ใช้ในตอนนี้ เพิ่มผู้ใช่หรือกลุ่ม + แชร์ลิงค์ + กำหนดวันที่หมดอายุ + รหัสผ่านป้องกัน + ความปลอดภัย + รับลิงค์ ค้นหา ค้นหาผู้ใช้และกลุ่ม %1$s (กลุ่ม) diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index 918e5e38..bad3ccc9 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,14 @@ 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 + Paylaş Evet Hayır Tamam + Eşitlemeyi iptal et İptal Kaydet ve Çık Hata @@ -241,6 +243,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 +317,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 +335,14 @@ %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 + Paylaşma bağlantısı + Son kullanma tarihini ayarla + Parola koruması 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-ug/strings.xml b/res/values-ug/strings.xml index 7d64b162..bd4ba67f 100644 --- a/res/values-ug/strings.xml +++ b/res/values-ug/strings.xml @@ -33,6 +33,7 @@ قۇرۇلغان ۋاقتى: ئۆزگەرتكەن ۋاقىت: چۈشۈر + ھەمبەھىر ھەئە ياق جەزملە diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index fed88cec..37b26e04 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -81,8 +81,7 @@ Завантажити Файл був переіменований в %1$s протягом вивантаження Вигляд списку - Опублікувати посилання - Видалити посилання + Поділитися Так Ні OK @@ -329,5 +328,8 @@ %1$d файлів, 1 тека %1$d файлів, %2$d тек Спільний доступ + Поділитись посиланням + Встановити термін дії + Захистити паролем Пошук diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur-rPK/strings.xml index 111a8662..2e391418 100644 --- a/res/values-ur-rPK/strings.xml +++ b/res/values-ur-rPK/strings.xml @@ -16,7 +16,7 @@ منسلک سیکنڈز پہلے ڈاؤن لوڈ، - اشتراک لنک + اشتراک ہاں نہیں اوکے @@ -26,5 +26,8 @@ بھجیں منتخب کریں + اشتراک لنک + تاریخ معیاد سیٹ کریں + محفوظ پاسورڈ تلاش diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 6ec75156..e6482b4f 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -58,8 +58,7 @@ Đã 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ẻ + Chia sẻ Yes Không Chấp nhận @@ -207,5 +206,8 @@ Chọn Địa chỉ máy chủ Chia sẻ + Chia sẻ liên kết + Đặt ngày kết thúc + Mật khẩu bảo vệ Tìm kiếm diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 39d4ea90..25ca1f95 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -81,8 +81,7 @@ 下载 上传过程中文件被更名为了 %1$s 列表布局 - 分享链接 - 取消分享链接 + 共享 是 否 确定 @@ -329,5 +328,8 @@ %1$d 个文件,1 个文件夹 %1$d 个文件,%2$d 个文件夹 共享 + 分享链接 + 设置过期日期 + 密码保护 搜索 diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index 50f708ac..aba6546a 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -38,8 +38,7 @@ 建立時間: 修改時間: 下載 - 分享連結 - 取消分享連結 + 分享 是 否 確定 @@ -78,5 +77,8 @@ 安全 伺服器地址 分享 + 分享連結 + 設定分享期限 + 密碼保護 尋找 diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index c783957b..7b0ec252 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -80,8 +80,7 @@ 下載 檔案名稱在上傳時已被更改為 %1$s 列表版型 - 分享連結 - 取消共享連結 + 分享 是 否 好 @@ -324,8 +323,10 @@ %1$d 個檔案, 1 個資料夾 %1$d 個檔案, %2$d 個資料夾 分享 - 與用戶或群組分享 目前沒有任何您分享的內容 新增使用者或是群組 + 分享連結 + 指定到期日 + 密碼保護 搜尋 diff --git a/res/values/strings.xml b/res/values/strings.xml index 3750f610..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 @@ -411,11 +412,18 @@ Stream file with external player Do you want to stream this file with an external app?\n\nCAUTION: This may expose your password! Set picture as + Set As Sharing - Share with Users and Groups + Share with users and groups No data shared with users yet Add User or Group + Share link + Set expiration date + Password protect + Secured + Get link + Search Search users and groups diff --git a/src/com/owncloud/android/datamodel/FileDataStorageManager.java b/src/com/owncloud/android/datamodel/FileDataStorageManager.java index cef10bc7..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 @@ -1578,9 +1633,11 @@ public class FileDataStorageManager { } public static void triggerMediaScan(String path) { - Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); - intent.setData(Uri.fromFile(new File(path))); - MainApp.getAppContext().sendBroadcast(intent); + if (path != null) { + Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + intent.setData(Uri.fromFile(new File(path))); + MainApp.getAppContext().sendBroadcast(intent); + } } public void deleteFileInMediaScan(String path) { @@ -1880,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 362cada4..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 { @@ -349,7 +443,8 @@ public class FileOperationsHelper { Intent intent = new Intent(Intent.ACTION_ATTACH_DATA); intent.setDataAndType(sendUri, file.getMimetype()); intent.putExtra("mimeType", file.getMimetype()); - mFileActivity.startActivityForResult(Intent.createChooser(intent, "Set As"), 200); + mFileActivity.startActivityForResult(Intent.createChooser(intent, + mFileActivity.getString(R.string.set_as)), 200); } else { // TODO re-enable after resized images is available Uri sendUri = Uri.parse("content://" + DiskLruImageCacheFileProvider.AUTHORITY + file.getRemotePath()); @@ -574,4 +669,5 @@ public class FileOperationsHelper { } return false; } + } diff --git a/src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java b/src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java index e152dafe..dc32ecc0 100644 --- a/src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java +++ b/src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java @@ -128,6 +128,12 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver { i.putExtra(FileUploader.KEY_INSTANT_UPLOAD, true); // instant upload behaviour + i = addInstantUploadBehaviour(i, context); + + context.startService(i); + } + + private Intent addInstantUploadBehaviour(Intent i, Context context){ SharedPreferences appPreferences = PreferenceManager.getDefaultSharedPreferences(context); String behaviour = appPreferences.getString("prefs_instant_behaviour", "NOTHING"); @@ -145,7 +151,7 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver { Log_OC.d(TAG, "upload file and delete file in original place"); } - context.startService(i); + return i; } private void handleNewVideoAction(Context context, Intent intent) { @@ -200,22 +206,7 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver { i.putExtra(FileUploader.KEY_INSTANT_UPLOAD, true); // instant upload behaviour - SharedPreferences appPreferences = PreferenceManager.getDefaultSharedPreferences(context); - String behaviour = appPreferences.getString("prefs_instant_behaviour", "NOTHING"); - - if (behaviour.equalsIgnoreCase("NOTHING")) { - Log_OC.d(TAG, "upload file and do nothing"); - i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_FORGET); - } else if (behaviour.equalsIgnoreCase("COPY")) { - i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_COPY); - Log_OC.d(TAG, "upload file and copy file to oc folder"); - } else if (behaviour.equalsIgnoreCase("MOVE")) { - i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_MOVE); - Log_OC.d(TAG, "upload file and move file to oc folder"); - } else if (behaviour.equalsIgnoreCase("DELETE")){ - i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_REMOVE); - Log_OC.d(TAG, "upload file and delete file in original place"); - } + i = addInstantUploadBehaviour(i, context); context.startService(i); @@ -281,22 +272,7 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver { i.putExtra(FileUploader.KEY_INSTANT_UPLOAD, true); // instant upload behaviour - SharedPreferences appPreferences = PreferenceManager.getDefaultSharedPreferences(context); - String behaviour = appPreferences.getString("prefs_instant_behaviour", "NOTHING"); - - if (behaviour.equalsIgnoreCase("NOTHING")) { - Log_OC.d(TAG, "upload file and do nothing"); - i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_FORGET); - } else if (behaviour.equalsIgnoreCase("COPY")) { - i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_COPY); - Log_OC.d(TAG, "upload file and copy file to oc folder"); - } else if (behaviour.equalsIgnoreCase("MOVE")) { - i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_MOVE); - Log_OC.d(TAG, "upload file and move file to oc folder"); - } else if (behaviour.equalsIgnoreCase("DELETE")){ - i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_REMOVE); - Log_OC.d(TAG, "upload file and delete file in original place"); - } + i = addInstantUploadBehaviour(i, context); context.startService(i); 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/operations/UploadFileOperation.java b/src/com/owncloud/android/operations/UploadFileOperation.java index d6466c54..512056ba 100644 --- a/src/com/owncloud/android/operations/UploadFileOperation.java +++ b/src/com/owncloud/android/operations/UploadFileOperation.java @@ -26,6 +26,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.channels.FileChannel; import java.util.HashSet; import java.util.Iterator; import java.util.Set; @@ -325,6 +326,8 @@ public class UploadFileOperation extends RemoteOperation { throw new OperationCancelledException(); } + result = mUploadOperation.execute(client); + /// move local temporal file or original file to its corresponding // location in the ownCloud local folder if (result.isSuccess()) { @@ -346,17 +349,37 @@ public class UploadFileOperation extends RemoteOperation { if (!expectedFile.equals(fileToMove)) { File expectedFolder = expectedFile.getParentFile(); expectedFolder.mkdirs(); - if (!expectedFolder.isDirectory() || !fileToMove.renameTo(expectedFile)) { - mFile.setStoragePath(null); // forget the local file - // by now, treat this as a success; the file was - // uploaded; the user won't like that the local file - // is not linked, but this should be a very rare - // fail; - // the best option could be show a warning message - // (but not a fail) - // result = new - // RemoteOperationResult(ResultCode.LOCAL_STORAGE_NOT_MOVED); - // return result; + + if (expectedFolder.isDirectory()){ + if (!fileToMove.renameTo(expectedFile)){ + // try to copy and then delete + expectedFile.createNewFile(); + FileChannel inChannel = new FileInputStream(fileToMove).getChannel(); + FileChannel outChannel = new FileOutputStream(expectedFile).getChannel(); + + try { + inChannel.transferTo(0, inChannel.size(), outChannel); + fileToMove.delete(); + } catch (Exception e){ + mFile.setStoragePath(null); // forget the local file + // by now, treat this as a success; the file was + // uploaded; the user won't like that the local file + // is not linked, but this should be a very rare + // fail; + // the best option could be show a warning message + // (but not a fail) + // result = new + // RemoteOperationResult(ResultCode.LOCAL_STORAGE_NOT_MOVED); + // return result; + } + finally { + if (inChannel != null) inChannel.close(); + if (outChannel != null) outChannel.close(); + } + } + + } else { + mFile.setStoragePath(null); } } } 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/activity/StorageMigrationActivity.java b/src/com/owncloud/android/ui/activity/StorageMigrationActivity.java index c0b45228..ee4f08e1 100644 --- a/src/com/owncloud/android/ui/activity/StorageMigrationActivity.java +++ b/src/com/owncloud/android/ui/activity/StorageMigrationActivity.java @@ -240,10 +240,19 @@ public class StorageMigrationActivity extends AppCompatActivity { void cleanup() { File srcFile = new File(mStorageSource + File.separator + MainApp.getDataFolder()); - if (!srcFile.delete()) + if (!deleteRecursive(srcFile)) Log_OC.w(TAG, "Migration cleanup step failed"); } + boolean deleteRecursive(File f) { + boolean res = true; + if (f.isDirectory()) + for (File c : f.listFiles()) + res = deleteRecursive(c) && res; + return f.delete() && res; + } + + void rollback() { File dstFile = new File(mStorageTarget + File.separator + MainApp.getDataFolder()); if (dstFile.exists()) diff --git a/src/com/owncloud/android/ui/adapter/LocalFileListAdapter.java b/src/com/owncloud/android/ui/adapter/LocalFileListAdapter.java index 79bad6ad..ec489368 100644 --- a/src/com/owncloud/android/ui/adapter/LocalFileListAdapter.java +++ b/src/com/owncloud/android/ui/adapter/LocalFileListAdapter.java @@ -227,7 +227,7 @@ public class LocalFileListAdapter extends BaseAdapter implements ListAdapter { public void swapDirectory(File directory) { mDirectory = directory; mFiles = (mDirectory != null ? mDirectory.listFiles() : null); - if (mFiles != null) { + if (mFiles != null && mFiles.length > 0) { Arrays.sort(mFiles, new Comparator() { @Override public int compare(File lhs, File rhs) { 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) {