From: Andy Scherzinger Date: Fri, 4 Sep 2015 11:43:36 +0000 (+0200) Subject: Merge branch 'material_buttons' of https://github.com/owncloud/android into material_fab X-Git-Tag: beta-20151202~3^2~65 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/4de7462140ced3df0926e40bf29960802482d111?hp=0d2aa0a97caa78428d8437b4959c0f9b50b793b7 Merge branch 'material_buttons' of https://github.com/owncloud/android into material_fab Conflicts: src/com/owncloud/android/ui/fragment/OCFileListFragment.java --- diff --git a/.gitmodules b/.gitmodules index 7ccbef03..882f3c27 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,3 @@ - [submodule "owncloud-android-library"] path = owncloud-android-library url = git://github.com/owncloud/android-library.git diff --git a/AndroidManifest.xml b/AndroidManifest.xml index fc701a94..a072d788 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,5 +1,4 @@ - - - + @@ -172,12 +160,12 @@ - + - + @@ -187,11 +175,11 @@ android:label="@string/copy_link" android:icon="@drawable/copy_link"/> - - diff --git a/build.gradle b/build.gradle index ad09b09b..56ba3462 100644 --- a/build.gradle +++ b/build.gradle @@ -59,12 +59,6 @@ android { abortOnError false } } - - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_7 - targetCompatibility JavaVersion.VERSION_1_7 - } productFlavors { } diff --git a/doc/oCC2015_Android_workshop.odp b/doc/oCC2015_Android_workshop.odp new file mode 100644 index 00000000..104d2233 Binary files /dev/null and b/doc/oCC2015_Android_workshop.odp differ diff --git a/res/drawable/backrepeat.xml b/res/drawable/backrepeat.xml new file mode 100644 index 00000000..37105c7b --- /dev/null +++ b/res/drawable/backrepeat.xml @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/res/drawable/checker_16_16.png b/res/drawable/checker_16_16.png new file mode 100644 index 00000000..3e9e3d09 Binary files /dev/null and b/res/drawable/checker_16_16.png differ diff --git a/res/layout/preview_image_fragment.xml b/res/layout/preview_image_fragment.xml index d584b445..11f88ba9 100644 --- a/res/layout/preview_image_fragment.xml +++ b/res/layout/preview_image_fragment.xml @@ -42,7 +42,7 @@ android:indeterminateOnly="true" android:layout_centerInParent="true" /> - + - + \ No newline at end of file diff --git a/res/layout/uploader_layout.xml b/res/layout/uploader_layout.xml index d0f9c6ef..9d95ee4f 100644 --- a/res/layout/uploader_layout.xml +++ b/res/layout/uploader_layout.xml @@ -53,13 +53,14 @@ android:orientation="horizontal" > + android:text="@string/common_cancel" /> - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 0a15186a..be9f464a 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -27,6 +27,7 @@ الإعدادات سجلّ إغلاق + افتح عام المزيد حسابات @@ -184,9 +185,7 @@ هل تريد حقاً حذف %1$s ؟ هل ترغب في حذف %1$s و جهات الإتصال التابعة له؟ محليا فقط - المحتويات المحلية فقط - الحذف من الخادم - محليا و عن بعد + محليا فقط تم الحذف بنجاح فشل الحذف أدخل اسما جديدا diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index 1e4b8f30..4201692c 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -23,6 +23,7 @@ + Aç Ümumi Daha da Hesablar @@ -186,9 +187,7 @@ Aşağıda göstərilən %5$s-də olan daxili və xarici fayl(lar) link edilmiş Siz həqiqətən %1$s silmək istəyirsiniz? Siz həqiqətəndə %1$s və onun kontentini silmək istəyirsiniz? Yalnız daxili - Yalnız daxili kontent - Serverdən sil - Uzaq və lokal + Yalnız daxili Silmə uğurlu oldu Silmək mümkün olmadı Yeni adı daxil edin diff --git a/res/values-bal/strings.xml b/res/values-bal/strings.xml new file mode 100644 index 00000000..37e61524 --- /dev/null +++ b/res/values-bal/strings.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/res/values-bg-rBG/strings.xml b/res/values-bg-rBG/strings.xml index 3edf84eb..03158dd9 100644 --- a/res/values-bg-rBG/strings.xml +++ b/res/values-bg-rBG/strings.xml @@ -27,6 +27,7 @@ Настройки Логове Затвори + Отвори Общи Още Профили @@ -199,9 +200,7 @@ Наистина ли искате да изтриете %1$s ? Наистина ли искате да премахнете %1$s и съдържанието му? Само локално - Само локалното съдържание - Премахване от сървъра - Отдалечено и локално + Само локално Премахването успешно. Неуспешно прехамхване. Въведете ново име diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml index 4907201b..13cdb22d 100644 --- a/res/values-bn-rBD/strings.xml +++ b/res/values-bn-rBD/strings.xml @@ -17,6 +17,7 @@ + খোল সাধারণ বেশী একাউন্ট @@ -171,9 +172,7 @@ আপনি কি সত্যিই %1$s অপসারণ করতে চান? আপনি কি সত্যিই %1$s এবং এর কনটেন্ট অপসারণ করতে চান? শুধুমাত্র লোকাল - শুধুমাত্র লোকাল কনটেন্ট - সার্ভসার থেকে অপসারণ কর - দুরবর্তী ও স্থানীয় + শুধুমাত্র লোকাল অপসারণ সফল অপসারণ ব্যার্থ একটি নতুন নাম লিখুন diff --git a/res/values-bn-rIN/strings.xml b/res/values-bn-rIN/strings.xml index d71af21a..d5295615 100644 --- a/res/values-bn-rIN/strings.xml +++ b/res/values-bn-rIN/strings.xml @@ -11,6 +11,7 @@ + খোলা অঙ্কিত করা ইউজারনেম ফাইলস diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index 70c12904..8c01ccc4 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -11,6 +11,7 @@ + Otvori ViÅ¡e Pomoć Korisničko ime diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 39877421..3c640d92 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -23,6 +23,9 @@ + configuració + tanca + Obre General Més Comptes @@ -177,9 +180,7 @@ Esteu segur que voleu eliminar %1$s? Estàs segur que vols esborrar %1$s i els seus continguts? Només local - Només contiguts locals - Elimina del servidor - Remot i local + Només local L\'eliminació ha tingut èxit No s\'ha pogut completar l\'eliminació Introdueix un nom nou diff --git a/res/values-cs-rCZ/strings.xml b/res/values-cs-rCZ/strings.xml index 0d5ed858..718aa1ea 100644 --- a/res/values-cs-rCZ/strings.xml +++ b/res/values-cs-rCZ/strings.xml @@ -27,6 +27,7 @@ Nastavení Logy Zavřít + Otevřít Obecné Více Účty @@ -199,9 +200,9 @@ Opravdu chcete odstranit %1$s ? Opravdu chcete odstranit %1$s a jeho obsah? Pouze místní - Pouze místní obsah - Odstranit ze serveru - Oboje, místní i vzdálené + Pouze místní + Ze serveru + Vzdálený & místní Úspěšně odstraněno Odstranění nelze dokončit Zadejte nový název @@ -256,8 +257,8 @@ Konflikt souboru Které soubory chcete ponechat? Pokud zvolíte obě verze, zkopírovaný soubor bude mít název doplněný o číslo. Ponechat oba - Použít lokální verzi - Použít serverovou verzi + místní verze + serverová verze Náhled obrázku Obrázek nelze zobrazit %1$s nelze zkopírovat do místního adresáře %2$s diff --git a/res/values-cy-rGB/strings.xml b/res/values-cy-rGB/strings.xml index d28261a9..e7e46fec 100644 --- a/res/values-cy-rGB/strings.xml +++ b/res/values-cy-rGB/strings.xml @@ -11,6 +11,7 @@ + Agor Cyffredinol Cyfrifon Rheoli Cyfrifon @@ -91,9 +92,7 @@ Ailenwi Gwaredu Lleol yn unig - Cynnwys lleol yn unig - Gwaredu o\'r gweinydd - Pell a lleol + Lleol yn unig Gwaredwyd yn llwyddiannus Methwyd gwaredu Rhowch enw newydd diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index 1c744d97..3e70097d 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -27,6 +27,7 @@ Indstillinger Logregistreringer Luk + Åbn Generel Mere Konti @@ -199,9 +200,9 @@ Er du sikker pÃ¥ at du vil fjerne %1$s ? Ønsker du virkelig at slette %1$s og dets indhold? Kun lokal - Lokalt indhold kun - Fjern fra server - BÃ¥de fjernt og lokalt + Kun lokal + Fra server + Fjernbeliggende og lokalt Vellykket fjernelse Fjernelse kunne ikke fuldføres Indtast et nyt navn @@ -256,8 +257,8 @@ Filkonflikt Hvilke filer ønsker du at beholde? Hvis du vælger begge versioner, sÃ¥ vil den lokale fil fÃ¥ et tal tilføjet til sit navn. Behold begge - Benyt lokal version - Benyt serverversionen + lokal version + serverversion ForhÃ¥ndsvisning af billede Dette billede kan ikke vises %1$s kunne ikke kopieres til %2$s lokale mappe diff --git a/res/values-de-rDE/strings.xml b/res/values-de-rDE/strings.xml index bcc60122..fa67888c 100644 --- a/res/values-de-rDE/strings.xml +++ b/res/values-de-rDE/strings.xml @@ -27,6 +27,7 @@ Einstellungen Protokolle Schließen + Öffnen Allgemein Mehr Konten @@ -201,8 +202,6 @@ Möchten Sie wirklich %1$s und dessen Inhalte entfernen? Nur lokal Nur lokal - Vom Server - Lokal & Server Erfolgreich gelöscht Der Löschvorgang konnte nicht beendet werden Geben Sie einen neuen Namen ein @@ -229,7 +228,7 @@ Möchten Sie diesem Zertifikat trotzdem vertrauen? Das Zertifikat konnte nicht gespeichert werden Details - Überblick + Ausblenden Ausgestellt für: Ausgestellt von: Üblicher Name: @@ -256,9 +255,7 @@ /SofortUpload Dateikonflikt Welche Datei möchtest du behalten? Wenn du beide Versionen auswählst, wird der lokalen Datei eine Zahl am Ende Ihres Dateiname angehangen. - Beide - lokale Version - Server Version + Beide behalten Bildvorschau Dieses Bild kann nicht angezeigt werden %1$s konnte nicht in den lokalen %2$s Ordner kopiert werden diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index d669ec38..0f7d6144 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -27,6 +27,7 @@ Einstellungen Protokolle Schließen + Öffnen Allgemein Mehr Konten @@ -201,8 +202,6 @@ Möchtest Du wirklich %1$s und dessen Inhalte entfernen? Nur lokal Nur lokal - Vom Server - Lokal & Server Erfolgreich gelöscht Der Löschvorgang konnte nicht beendet werden Gib einen neuen Namen ein @@ -257,8 +256,6 @@ Dateikonfilikt Welche Datei möchtest du behalten? Wenn du beide Versionen auswählst, wird der lokalen Datei eine Zahl am Ende Ihres Dateiname angehangen. Beide behalten - Benutze lokale Version - Benutze Version auf dem Server Bildvorschau Dieses Bild kann nicht angezeigt werden %1$s konnte nicht in den lokalen %2$s Ordner kopiert werden diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 0ccada8d..d7ffc33a 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -27,6 +27,7 @@ Ρυθμίσεις Αρχεία καταγραφών Κλείσιμο + Άνοιγμα Γενικά Περισσότερα Λογαριασμοί @@ -200,9 +201,9 @@ Θέλετε στ\' αλήθεια να αφαιρέσετε το %1$s; Θέλετε στ\' αλήθεια να διαγράψετε το %1$s και τα περιεχόμενά του; Μόνο τοπικά - Μόνο τοπικό περιεχόμενο - Αφαίρεση από το διακομιστή - Απομακρυσμένα και τοπικά + Μόνο τοπικά + Από το διακομιστή + Απομακρυσμένα & τοπικά Αφαίρεση επιτυχής Η αφαίρεση απέτυχε Εισάγετε νέο όνομα @@ -257,8 +258,8 @@ Διένεξη αρχείων Ποια αρχεία θέλετε να κρατήσετε; Αν επιλέξετε και τις δύο εκδοχές, στο τοπικό αρχείο θα προστεθεί ένας αριθμός στο όνομά του. Διατήρηση και των δύο - Χρήση τοπικής εκδοχής - Χρήση εκδοχής διακομιστή + τοπική έκδοση + έκδοση διακομιστή Προεπισκόπηση εικόνας Αυτή η εικόνα δεν μπορεί να προβληθεί Το %1$s δεν μπόρεσε να αντιγραφεί στον τοπικό φάκελο %2$s diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 2ee4e383..486eb581 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -23,6 +23,7 @@ + Open General More Accounts @@ -194,9 +195,7 @@ Do you really want to remove %1$s? Do you really want to remove %1$s and its contents? Local only - Local contents only - Remove from server - Remote and local + Local only Removal succeeded Removal failed Enter a new name diff --git a/res/values-eo/strings.xml b/res/values-eo/strings.xml index e4570adf..4a919210 100644 --- a/res/values-eo/strings.xml +++ b/res/values-eo/strings.xml @@ -16,6 +16,7 @@ + Malfermi Ĝeneralo Pli Kontoj @@ -124,9 +125,7 @@ Ĉu vi vere volas forigi %1$s? Ĉu vi vere volas forigi %1$s kaj ĝia enhavo? Nur loka - Nur lokaj enhavoj - Forigi el la servilo - Kaj malloka kaj loka + Nur loka Forigo sukcesis Forigo ne eblis plenumiĝi Enigu novan nomon diff --git a/res/values-es-rAR/strings.xml b/res/values-es-rAR/strings.xml index 9ca0336c..5d91a8fc 100644 --- a/res/values-es-rAR/strings.xml +++ b/res/values-es-rAR/strings.xml @@ -23,6 +23,7 @@ + Abrir General Más Cuentas @@ -179,9 +180,7 @@ ¿Realmente quieres eliminar %1$s? ¿Realmente deseas eliminar %1$s y todo su contenido? Sólo local - Solo archivos locales - Borrar del servidor - Ambos: remoto y local + Sólo local Borrado correctamente El borrado no pudo ser completado Ingrese un nombre diff --git a/res/values-es-rCL/strings.xml b/res/values-es-rCL/strings.xml index 9ea8786c..e4288f15 100644 --- a/res/values-es-rCL/strings.xml +++ b/res/values-es-rCL/strings.xml @@ -116,9 +116,7 @@ ¿Realmente desea eliminar %1$s? ¿Realmente desea eliminar el archivo %1$s y su contenido? Solo local - solo contenidos locales - Eliminar desde el servidor - Remoto y local + Solo local Removido correctamente Fallo al remover ingresar un nuevo nombre diff --git a/res/values-es-rMX/strings.xml b/res/values-es-rMX/strings.xml index d26f51c6..84733332 100644 --- a/res/values-es-rMX/strings.xml +++ b/res/values-es-rMX/strings.xml @@ -17,6 +17,7 @@ + Abrir General Más Cuentas @@ -153,9 +154,7 @@ Renombrar Borrar Sólo local - Sólo archivos locales - Eliminar del servidor - Tanto remoto como local + Sólo local Borrado correctamente El borrado no pudo ser completado Introduzca un nombre nuevo diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index a7c87e14..8b0d0ad1 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -27,6 +27,7 @@ Ajustes Registros Cerrar + Abrir General Más Cuentas @@ -200,9 +201,9 @@ ¿Realmente desea eliminar %1$s? ¿Realmente desea eliminar %1$s y todo su contenido? Sólo local - Sólo ficheros locales - Eliminar del servidor - Tanto remoto como local + Sólo local + Desde el servidor + Remoto & local Borrado correctamente El borrado no pudo ser completado Introduzca un nombre nuevo @@ -255,10 +256,10 @@ Subir vídeos sólo por WiFi /SubidasInstantáneas Conflicto con archivo - ¿Qué archivos desea mantener? Si selecciona ambas versiones, el archivo local tendrá un número añadido a su nombre. + ¿Cuáles archivos desea mantener? Si selecciona ambas versiones, el archivo local tendrá un número añadido a su nombre. Mantener ambos - Usar versión local - Usar versión del servidor + versión local + versión del servidor Previsualización de imagen No se puede mostrar la imagen %1$s se pudo copiar a la carpeta local %2$s diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml index 319cdffb..7c94bca4 100644 --- a/res/values-et-rEE/strings.xml +++ b/res/values-et-rEE/strings.xml @@ -27,6 +27,7 @@ Seaded Logid Sulge + Ava Üldine Rohkem Kontod @@ -204,9 +205,7 @@ Allpool on loend kohalikest failidest ning serveris asuvatest failidest %5$s, mi Oled sa kindel, et soovid %1$s eemaldada? Kas sa tõesti soovid eemaldada %1$s ja selle sisu? Ainult kohalik - Ainult kohalik sisu - Eemalda serverist - Eemalolev ja kohalik + Ainult kohalik Eemaldamine oli edukas Eemaldamine ebaõnnestus Sisesta uus nimi @@ -258,6 +257,8 @@ Allpool on loend kohalikest failidest ning serveris asuvatest failidest %5$s, mi Lae pilte üles ainult läbi WiFi Laadi videod üles ainult WiFi-t kasutades /InstantUpload + Failikonflikt + Millist faili sa soovid säilitada? Kui valid mõlemad versioonid, siis lisatakse kohaliku faili nimele number. Säilita mõlemad Pildi eelvaade Seda pilti ei saa näidata @@ -313,6 +314,7 @@ Allpool on loend kohalikest failidest ning serveris asuvatest failidest %5$s, mi jagatud sinuga %1$s jagas sinuga \"%2$s\" + \"%1$s\" on sinuga jagatud Värskenda ühendust Serveri aadress Mälu pole piisavalt diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 3ea68c19..8c14aefe 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -23,6 +23,7 @@ + Ireki Orokorra Gehiago Kontuak @@ -179,9 +180,7 @@ Mesedez, baimendu berriz Ziur zaude %1$s ezabatu nahi duzula? Ziru zaude %1$s eta bere edukiak ezabatu nahi dituzula? Bertakoa bakarrik - Eduki lokalak bakarrik - Zerbitzaritik ezabatu - Biak urrunekoa eta bertakoa + Bertakoa bakarrik Ongi ezabatu da Ezin izan da ezabaketa burutu Idatzi izen berri bat diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index 0efba32c..a84969fa 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -17,6 +17,7 @@ + باز کردن عمومی بیش‌تر حساب‌ها @@ -154,9 +155,7 @@ تغییرنام حذف فقط محلی - فقط محتوای محلی - پاک کردن از سرور - راه دور و محلی + فقط محلی حذف با موفقیت انجام شد حذف نا موفق بود نام جدید وارد کنید diff --git a/res/values-fi-rFI/strings.xml b/res/values-fi-rFI/strings.xml index 554b6c8e..f12292e6 100644 --- a/res/values-fi-rFI/strings.xml +++ b/res/values-fi-rFI/strings.xml @@ -27,6 +27,7 @@ Asetukset Lokit Sulje + Avaa Yleiset Enemmän Tilit @@ -191,9 +192,9 @@ Haluatko varmasti poistaa kohteen %1$s? Haluatko varmasti poistaa kohteen %1$s ja sen sisällön? Vain paikallinen - Vain paikallinen sisältö - Poista palvelimelta - Sekä etä- että paikallinen + Vain paikallinen + Palvelimelta + Etä ja paikallinen Poistettu onnistuneesti Poistamista ei voitu suorittaa loppuun asti Anna uusi nimi @@ -245,8 +246,8 @@ Tiedoston ristiriita Mitkä tiedostot haluat säilyttää? Jos valitset kummatkin versiot, paikallisen version tiedoston nimeen lisätään numero. Säilytä molemmat - Käytä paikallista versiota - Käytä palvelimen versiota + paikallinen versio + palvelimen versio Kuvan esikatselu Tätä kuvaa ei voi näyttää Lähetyspolku diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 6216eed6..a502db5f 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -27,6 +27,7 @@ Paramètres Logs Fermer + Ouvrir Général Plus Comptes @@ -205,9 +206,9 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq Voulez-vous vraiment supprimer %1$s ? Voulez-vous vraiment supprimer %1$s et son contenu ? Local seulement - Contenu local uniquement - Effacer du serveur - Distant et local + Local seulement + Depuis le serveur + Distant & local Suppression effectuée avec succès Suppression impossible Entrez un nouveau nom @@ -262,8 +263,8 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq Conflit de fichiers Quel(s) fichier(s) voulez-vous garder ? Si vous sélectionnez les deux, un chiffre sera ajouté au nom du fichier local. Garder les deux versions - Utiliser la version locale - Utiliser la version du serveur + version locale + version serveur Prévisualisation de l\'image Cette image ne peut pas être affichée %1$s n\'a pas pu être copié dans le dossier local %2$s diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index 84962f2a..18ae1a9e 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -27,6 +27,7 @@ Axustes Rexistros Pechar + Abrir Xeral Máis Contas @@ -201,8 +202,7 @@ Descárgueo de aquí: %2$s Confirma que quere retirar %1$s? Confirma que quere retirar %1$s e o seu contido? Só local - Só contidos locais - Retirar do servidor + Só local Remoto e local Retirado correctamente Non foi posíbel retiralo @@ -258,8 +258,8 @@ Descárgueo de aquí: %2$s Conflito de ficheiro Que ficheiros quere conservar? Se selecciona ambas versións, o ficheiro copiado terá un número engadido ao nome. Manter ambos - Usar a versión local - Usar a versión do servidor + versión local + versión no servidor Vista previa da imaxe Esta imaxe non pode ser amosada Non foi posíbel copiar %1$s no cartafol local %2$s diff --git a/res/values-he/strings.xml b/res/values-he/strings.xml index 669a55ba..f10f2d7d 100644 --- a/res/values-he/strings.xml +++ b/res/values-he/strings.xml @@ -17,6 +17,7 @@ + פתיחה כללי יותר חשבונות @@ -172,9 +173,7 @@ האם באמת להסיר %1$s? האם באמת להסיר %1$s ואת כל התכולה? מקומי בלבד - תכנים מקומיים בלבד - הסרה מהשרת - מרוחק ומקומי + מקומי בלבד ההסרה הצליחה ההסרה נכשלה נא להזין שם חדש diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index 9173a6d0..feb62ce7 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -17,6 +17,7 @@ + खोलें सामान्य और अधिक खाते diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index 1ada651c..12e7ef43 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -23,6 +23,7 @@ + Otvorite Općenito viÅ¡e Korisnićki računi diff --git a/res/values-hu-rHU/strings.xml b/res/values-hu-rHU/strings.xml index 6fc11933..b8bae64c 100644 --- a/res/values-hu-rHU/strings.xml +++ b/res/values-hu-rHU/strings.xml @@ -18,6 +18,7 @@ Beállítások + Megnyitás Általános Több Fiókok @@ -169,9 +170,7 @@ Tényleg el akarod távolítani %1$s? Tényleg el akarod távolítani a %1$s és tartalmát? Csak a helyi példány - Csak a helyi tartalmat - Törlés a szerverről - A szerveren levő és a helyi példány törlése + Csak a helyi példány Az eltávolítás sikerült Az eltávolítás nem sikerült Adj meg egy új nevet diff --git a/res/values-ia/strings.xml b/res/values-ia/strings.xml index d1cc465d..efb3d3d5 100644 --- a/res/values-ia/strings.xml +++ b/res/values-ia/strings.xml @@ -11,6 +11,7 @@ + Aperi General Plus Contos diff --git a/res/values-id/strings.xml b/res/values-id/strings.xml index 6ff09807..a23b66e1 100644 --- a/res/values-id/strings.xml +++ b/res/values-id/strings.xml @@ -27,6 +27,7 @@ Pengaturan Log Tutup + Buka Umum Lainnya Akun @@ -200,9 +201,9 @@ Apakah Anda yakin ingin menghapus %1$s? Apakah Anda yakin ingin menghapus %1$s dan isinya? Lokal saja - Konten lokal saja - Hapus dari server - Jarak jauh dan lokal + Lokal saja + Dari server + Remot & lokal Penghapusan berhasil Penghapusan gagal Masukkan nama baru @@ -257,8 +258,8 @@ Berkas konflik Berkas mana yang ingin Anda simpan? Jika Anda memilih kedua versi, berkas lokal akan memiliki angka yang ditambahkan pada namanya. Biarkan keduannya - Gunakan versi lokal - Gunakan versi server + versi lokal + versi server Pratilik gambar Gambar ini tidak dapat ditampilkan %1$s tidak dapat disalin ke folder lokal %2$s diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml index ac8f0eca..2d50d6fd 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -10,6 +10,7 @@ + Opna Meira Hjálp Notendanafn @@ -19,6 +20,7 @@ sek. Ekkert hér. Settu eitthvað inn! Niðurhal + Deila hlekk Já Nei Í lagi @@ -31,6 +33,7 @@ Fjarlægja Senda + Færa Veldu Host nafn netþjóns diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index c0e9d98e..09b89aaf 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -27,6 +27,7 @@ Impostazioni Registri Chiudi + Apri Generale Altro Account @@ -200,9 +201,9 @@ Vuoi davvero rimuovere %1$s? Vuoi davvero rimuovere %1$s e il suo contenuto? Solo localmente - Solo contenuti locali - Rimuovi dal server - Sia remoto che locale + Solo locale + Dal server + Remota e locale Rimozione effettuata con successo La rimozione non può essere completata Digita un nuovo nome @@ -257,8 +258,8 @@ File in conflitto Quali file vuoi tenere? Se selezioni entrambi le versioni, il file locale avrà un numero aggiunto al suo nome. Mantieni entrambi - Usa la versione locale - Usa la versione del server + Versione locale + versione del server Anteprima dell\'immagine Questa immagine non può essere mostrata %1$s non può essere copiato nella cartella locale %2$s diff --git a/res/values-ja-rJP/strings.xml b/res/values-ja-rJP/strings.xml index 528752ce..c6f90c20 100644 --- a/res/values-ja-rJP/strings.xml +++ b/res/values-ja-rJP/strings.xml @@ -27,6 +27,7 @@ 設定 ログ 閉じる + 開く 一般 もっと見る アカウント @@ -201,9 +202,7 @@ 本当に %1$s を削除しますか? 本当に %1$s およびそのコンテンツを削除してもよろしいですか? ローカルのみ - ローカルコンテンツのみ - サーバーから削除 - リモートとローカルの両方 + ローカルのみ 削除に成功しました 削除を完了できませんでした 新しい名前を入力 @@ -258,8 +257,6 @@ ファイルが競合 どちらのファイルを保存したいですか?両方のバージョンを選択した場合は、ファイル名の後ろに数字を追加したファイルのコピーを作成します。 両方を保持 - 手元のファイルで上書き - サーバーのファイルで上書き イメージプレビュー この画像は表示できません %1$s は、ローカルフォルダー %2$s にコピーできませんでした。 diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml index 241d5bab..0d7d8601 100644 --- a/res/values-ka-rGE/strings.xml +++ b/res/values-ka-rGE/strings.xml @@ -12,6 +12,7 @@ + გახსნა ზოგადი უფრო მეტი ანგარიში @@ -99,9 +100,7 @@ გადარქმევა წაშლა მხოლოდ ლოკალური - მხოლოდ ლოკალური კონტენტი - სერვერიდან წაშლა - დაშორებული და ლოკალური + მხოლოდ ლოკალური წაშლა შარმატებით დასრულდა წაშლა წარუმატებლად დამთავრდა შეიყვანეთ ახალი სახელი diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index 05de5dbc..68b39212 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -23,6 +23,7 @@ + បើក ទូទៅ ច្រើន​ទៀត គណនី @@ -84,8 +85,7 @@ ប្ដូរ​ឈ្មោះ ដកចេញ ទីកន្លែងតែមួយ - ដកចេញពី​សឺវឺ - បញ្ជារ និងទីតាំង + ទីកន្លែងតែមួយ ការដកយកចេញបានជោគជ័យ ការដកយកចេញបានបរាជ័យ បញ្ចូលឈ្មោះថ្មី diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index 056406d3..ef5e51c7 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -11,6 +11,7 @@ + ತೆರೆ ಇನ್ನಷ್ಟು ಸಹಾಯ ಮುದ್ರೆ diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index 1cd42cc1..efc3c1a2 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -27,6 +27,7 @@ 설정 로그 닫기 + 열기 일반 더 보기 계정 @@ -200,9 +201,7 @@ %1$s을(를) 삭제하시겠습니까? %1$s 및 포함된 내용을 삭제하시겠습니까? 로컬만 - 로컬 콘텐츠만 - 서버에서 삭제 - 서버와 로컬 모두 + 로컬만 성공적으로 삭제함 삭제할 수 없음 새 이름 입력 diff --git a/res/values-ku-rIQ/strings.xml b/res/values-ku-rIQ/strings.xml index 5bbaf796..af1edacf 100644 --- a/res/values-ku-rIQ/strings.xml +++ b/res/values-ku-rIQ/strings.xml @@ -9,6 +9,7 @@ + بیکەوە گشتی هەژمارەکان یارمەتی diff --git a/res/values-la/strings.xml b/res/values-la/strings.xml new file mode 100644 index 00000000..37e61524 --- /dev/null +++ b/res/values-la/strings.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/res/values-lb/strings.xml b/res/values-lb/strings.xml index eb2e5cfb..99468420 100644 --- a/res/values-lb/strings.xml +++ b/res/values-lb/strings.xml @@ -23,6 +23,7 @@ + Opmaachen Allgemeng Méi Konten @@ -145,9 +146,7 @@ Wëlls du %1$s wierklech läschen? Wëlls du %1$s an de ganzen Inhalt wierklech läschen? Nemme lokal - Nëmme lokal Inhalter - Vum Server läschen - Um Server a lokal + Nemme lokal Erfollegräich geläscht Läsche feelgeschloen Gëff en neien Numm an diff --git a/res/values-lt-rLT/strings.xml b/res/values-lt-rLT/strings.xml index 6e7855b5..9d3643f1 100644 --- a/res/values-lt-rLT/strings.xml +++ b/res/values-lt-rLT/strings.xml @@ -24,6 +24,7 @@ Parinktys + Atverti Bendras Daugiau Paskyros @@ -173,9 +174,7 @@ Ar tikrai norite paÅ¡alinti %1$s? Ar tikrai norite paÅ¡alinti %1$s ir ten esantį turinį? Tik vietiniai - Tik vietinis turinys - PaÅ¡alinti iÅ¡ serverio - Nutolę ir vietiniai + Tik vietiniai PaÅ¡alinta sėkmingai PaÅ¡alinti nepavyko Ä®veskite naują pavadinimą diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml index 32f38478..ea13b1b9 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -23,6 +23,7 @@ + Atvērt VispārÄ«gi Vairāk Konti @@ -117,9 +118,7 @@ Pārsaukt Izņemt Tikai lokālos - Tikai lokālo saturu - Izņemt no servera - Attālinātās un lokālās + Tikai lokālos VeiksmÄ«gi izņemts Neizdevās izņemt IevadÄ«t jaunu nosaukumu diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml index 28329fa7..8c842a2f 100644 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@ -23,6 +23,7 @@ + Отвори Општо Повеќе Сметки @@ -192,9 +193,7 @@ Дали навистина сакаш да ја отстраниш %1$s? Дали навистина сакаш да го отстранам %1$s и неговата содржина? Само локално - Само локална содржина - Отстрани од серверот - Далечинско и локално + Само локално Одстранувањето е успешно Одстранувањето е неуспешно Внеси ново име diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml index b2303ba9..4ac4d952 100644 --- a/res/values-ms-rMY/strings.xml +++ b/res/values-ms-rMY/strings.xml @@ -18,6 +18,7 @@ + Buka Umum Lanjutan Akaun @@ -55,6 +56,7 @@ Namakan Buang Lokal sahaja + Lokal sahaja Hantar Akaun diff --git a/res/values-nb-rNO/strings.xml b/res/values-nb-rNO/strings.xml index cd1b3b8f..cb99ece7 100644 --- a/res/values-nb-rNO/strings.xml +++ b/res/values-nb-rNO/strings.xml @@ -27,6 +27,7 @@ Innstillinger Logger Lukk + Åpne Generelt Mer Kontoer @@ -200,9 +201,7 @@ Vil du virkelig fjerne %1$s? Vil du virkelig fjerne %1$s inkludert innholdet? Kun lokalt - Kun lokalt innhold - Fjern fra server - Ekstern og lokal + Kun lokalt Fjerning var vellykket Fjerning mislyktes Skriv inn et nytt navn diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 1e05442d..8e1e5eb1 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -27,6 +27,7 @@ Instellingen Logs Sluiten + Open Algemeen Meer Accounts @@ -203,9 +204,9 @@ Hieronder staan de lokale bestanden en de externe bestanden in %5$s waar ze naar Wilt u %1$s werkelijk verwijderen? Wilt u %1$s en de inhoud ervan werkelijk verwijderen? Alleen lokaal - Alleen lokale inhoud - Verwijder van server - Lokaal en op de server + Alleen lokaal + Van server + Extern & lokaal Succesvol verwijderd Verwijdering kon niet voltooid worden Voer een nieuwe naam in @@ -260,8 +261,8 @@ Hieronder staan de lokale bestanden en de externe bestanden in %5$s waar ze naar Bestandsconflict Welke bestanden wilt u bewaren? Als u beide versies selecteert zal het lokale bestand een nummer aan de naam toegevoegd krijgen. Beide bewaren - Gebruik de lokale versie - Gebruik de server-versie + lokale versie + serverversie Afbeelding voorbeeld Deze afbeelding kan niet worden getoond %1$s kon niet worden gekopieerd naar de %2$s lokale map diff --git a/res/values-nn-rNO/strings.xml b/res/values-nn-rNO/strings.xml index b99a6204..2a12cc08 100644 --- a/res/values-nn-rNO/strings.xml +++ b/res/values-nn-rNO/strings.xml @@ -17,6 +17,7 @@ + Opna Generelt Meir Kontoar @@ -105,8 +106,7 @@ Endra namn Fjern Berre lokalt - Fjern frÃ¥ tenaren - Ekstern og lokal + Berre lokalt Fjerning vellukka Fjerning mislukka Klarte ikkje Ã¥ fullføra omdøyping diff --git a/res/values-oc/strings.xml b/res/values-oc/strings.xml index 69f2d181..3e175989 100644 --- a/res/values-oc/strings.xml +++ b/res/values-oc/strings.xml @@ -13,6 +13,7 @@ Paramètres + Dubrís General Mai d\'aquò Comptes diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml index a757dba0..f68a9c64 100644 --- a/res/values-pa/strings.xml +++ b/res/values-pa/strings.xml @@ -89,8 +89,7 @@ ਨਾਂ ਬਦਲੋ ਹਟਾਓ ਕੇਵਲ ਲੋਕਲ - ਸਰਵਰ ਤੋਂ ਹਟਾਓ - ਰਿਮੋਟ ਤੇ ਲੋਕਲ + ਕੇਵਲ ਲੋਕਲ ਪਲ਼ ਭਰ ਲਈ ਉਡੀਕੋ ਕੋਈ ਫਾਇਲ ਨਹੀਂ ਚੁਣੀ ਗਈ ਇਹ ਸਾਈਟ ਦੀ ਪਛਾਣ ਦੀ ਜਾਂਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ ਹੈ diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 0822459b..d9c5320e 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -21,8 +21,13 @@ Biggest - Smallest--> + Wszystkie pliki + Ustawienia + Logi + Zamknij + Otwórz Ogólne Więcej Konta @@ -65,6 +70,7 @@ Wysyłanie sekund temu Pusto. Wyślij coś! + Wczytywanie... Nie ma plików w tym folderze. Dotknij plik aby wyświetlić dodatkowe informacje Rozmiar: @@ -195,9 +201,8 @@ Czy naprawdę chcesz usunąć %1$s? Czy naprawdę chcesz usunąć %1$s i jego zawartość? Tylko lokalnie - Tylko zasoby lokalne - Usuń z serwera - Z serwera i telefonu + Tylko lokalnie + Z serwera Usunięto Nie można usunąć Wprowadź nową nazwę @@ -248,7 +253,10 @@ Wysyłaj zdjęcia tylko przez WiFi Aktualizuj filmy tylko przez WiFi /InstantUpload + Konflikt pliku Zatrzymaj oba + lokalna wersja + wersja zdalna Podgląd Ten obrazek nie może zostać wyświetlony %1$s nie może zostać skopiowany do lokalnego folderu %2$s @@ -300,7 +308,14 @@ Bezpieczeństwo Katalog wysyłania dla wideo Pobieranie %1$s katalogu nie może zostać ukończone + udostępniony + z tobą Odśwież połączenie Adres Serwera Brak wystarczającej pamięci + Użytkownik + 1 folder + %1$d folderów + 1 plik + 1 plik , 1 folder diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index 56f898d9..013757ca 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -27,6 +27,7 @@ Configurações Logs Fechar + Abrir Geral Mais Contas @@ -200,9 +201,9 @@ Você realmente deseja remover %1$s? Você realmente deseja remover %1$s e seus conteúdos? Somente local - Somente conteúdo local - Remover do servidor - Ambos remoto e local + Somente local + Do servidor + Remoto & local Removido com sucesso Erro ao remover Digite um novo nome @@ -257,8 +258,8 @@ Conflito de arquivo Quais arquivos você deseja manter? Se você selecionar ambas as versões, o arquivo local terá um número adicionado ao seu nome. Manter ambos - Usar a versão local - Usar a versão servidor + versão local + versão do servidor Pré-visualização da imagem Esta imagem não pode ser mostrada %1$s não pôde ser copiado para pasta local %2$s diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 3e399a43..83c1f5d4 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -27,6 +27,7 @@ Definições Registos de Alterações Fechar + Abrir Geral Mais Contas @@ -199,9 +200,7 @@ Tem a certeza que deseja remover %1$s ? Deseja realmente remover %1$s e o seu conteúdo? Apenas localmente - So conteúdos locais - Apagar do servidor - ambos os remoto e local + Apenas localmente Removido com sucesso Não foi possível remover Introduza um novo nome @@ -256,8 +255,6 @@ Conflito de ficheiro Quais os ficheiros que pretende manter? Se selecionar ambas as versões, o ficheiro local irá ter um número adicionado ao seu nome. Manter ambos - Usar versão local - Usar versão do servidor Pré-Visualizar imagem Esta imagem não pode ser mostrada Não foi possível copiar %1$s para a pasta local %2$s diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index cd989a49..d04e0b51 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -27,6 +27,7 @@ Setări Înregistrări Închide + Deschide General Mai mult Conturi @@ -194,14 +195,15 @@ Nu se poate autentifica cu acest server Contul nu există încă în dispozitiv Favorit + Defavoritați Redenumește Elimină Doriti sigur sa stergeti %1$s? Sigur vrei să elimini %1$s și conținutul său? Doar local - Doar continut local - Elimină de pe server - De la distanță și local + Doar local + De pe server + Ambele Eliminat cu succes Eliminarea nu a reușit IntroduceÅ£i un nou nume @@ -253,7 +255,11 @@ Încarcă poze doar prin WiFi Încarcă videoclipuri doar via WiFi /Încărcare instantă + Conflict de fișiere + Care fișiere doriți să păstrați? Dacă selectați „ambele”, fișierului local i se va adăuga un număr numelui său. Pastreaza amandoua + versiunea locală + versiunea de pe server Previzualizare imagine Aceasta imagine nu poate fi arătată %1$s nu a putut fi copiat in dosarul local %2$s @@ -307,6 +313,7 @@ partajat cu tine %1$s a partajat fișierul \"%2$s\" cu tine + „%1$s” a fost partajat cu dumneavoastră Reîmprospătează conexiunea Adresa server-ului Memorie insuficientă diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 3c5b4edd..fdad0bef 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -27,6 +27,7 @@ Настройки Журналы Закрыть + Открыть Основные Больше Учётные записи @@ -201,9 +202,7 @@ Вы действительно хотите удалить %1$s? Вы действительно хотите удалить %1$s и его содержимое? Только локально - Только локальные данные - Удалить с сервера - Удалённо и локально + Только локально Удаление завершено Ошибка удаления Введите новое имя @@ -258,8 +257,6 @@ Конфликт файлов Какие файлы Вы хотите сохранить? При выборе обеих версий, к названию локального файла будет добавлена цифра Сохранить оба - Использовать локальную версию - Использовать версию сервера Предпросмотр Это изображение не может быть отображено %1$s невозможно скопировать в локальный каталог %2$s diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml index dce26eeb..8116b724 100644 --- a/res/values-si-rLK/strings.xml +++ b/res/values-si-rLK/strings.xml @@ -9,6 +9,7 @@ + විවෘත කරන්න සාමාන්‍යයෙන් වැඩි ගිණුම් @@ -66,8 +67,7 @@ නැවත නම් කරන්න ඉවත් කරන්න පෙදෙසි පමණක් - සේවාදායකයාගෙන් ඉවත් කරන්න - දුරස්ථ හා පෙදෙසි + පෙදෙසි පමණක් සාර්ථක ඉවත්කිරීමක් ඉවත් කිරීම සම්පූර්ණ කළ නොහැක නැවත නම් කිරීම සම්පුර්ණ කළ නොහැකි විය diff --git a/res/values-sk-rSK/strings.xml b/res/values-sk-rSK/strings.xml index d3e366f9..7cc28c22 100644 --- a/res/values-sk-rSK/strings.xml +++ b/res/values-sk-rSK/strings.xml @@ -27,6 +27,7 @@ Nastavenia Logy ZavrieÅ¥ + OtvoriÅ¥ VÅ¡eobecné Viac Účty @@ -194,9 +195,7 @@ Naozaj chcete odstrániÅ¥ %1$s? Naozaj chcete odstrániÅ¥ %1$s a jeho obsah? Iba lokálne - Len lokálny obsah - ZmazaÅ¥ zo servera - Vzdialené a lokálne + Iba lokálne ÚspeÅ¡ne odstránené Odstránenie zlyhalo Zadajte nové meno diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index e13d17dd..2351338b 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -27,6 +27,7 @@ Nastavitve Dnevnik Zapri + Odpri SploÅ¡no Več Računi @@ -200,9 +201,9 @@ Ali res želite odstraniti %1$s? Ali res želite odstraniti %1$s skupaj s celotno vsebino? Le krajevno - Le krajevno vsebino - Odstrani s strežnika - Oddaljeno in krajevno + Le krajevno + S strežnika + Oddaljeno & krajevno Odstranitev je uspeÅ¡no končana Odstranjevanje je spodletelo Vnesite novo ime @@ -254,7 +255,11 @@ PoÅ¡iljaj slike le preko povezav Wi-Fi PoÅ¡lji posnetke le preko povezave Wi-Fi /Poslano + Neskladje datotek + Katere datoteke želite ohraniti? Če izberete obe različici, bo krajevni datoteki dodatna k imenu Å¡e Å¡tevilka. Ohrani obe + krajevna različica + različica strežnika Predogled slike Te slike ni mogoče prikazati Datoteke %1$s ni mogoče kopirati v krajevno mapo %2$s @@ -309,6 +314,7 @@ v souporabi z vami Uporabnik %1$s je omogočil souporabo \"%2$s\" z vami + \"%1$s\" je oddan v souporabo z vami Osveži povezavo Naslov strežnika Ni dovolj pomnilnika diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml index cf074a63..fc3b8a4d 100644 --- a/res/values-sq/strings.xml +++ b/res/values-sq/strings.xml @@ -11,6 +11,7 @@ + Hap Përgjithshme Më tepër Llogarit diff --git a/res/values-sr-rSP/strings.xml b/res/values-sr-rSP/strings.xml index 6380fe3f..a8200978 100644 --- a/res/values-sr-rSP/strings.xml +++ b/res/values-sr-rSP/strings.xml @@ -12,6 +12,7 @@ + Otvori OpÅ¡te Nalozi Upravljaj nalozima diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index 7ced0476..01dfce6c 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -27,6 +27,7 @@ Поставке Записници Затвори + Отвори Опште Остало Налози @@ -200,9 +201,7 @@ Желите да уклоните %1$s? Желите да уклоните %1$s и њен садржај? Само локално - Само локални садржај - Уклони са сервера - Удаљено и локално + Само локално Уклањање успешно Уклањање неуспешно Унесите нов назив diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 2efdb1af..98de6de6 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -23,6 +23,7 @@ + Öppna Allmänt Mer Konton @@ -182,9 +183,7 @@ Vill du verkligen ta bort %1$s? Vill du verkligen ta bort %1$s och dess innehÃ¥ll? Endast lokalt - Endast lokalt innehÃ¥ll - Radera frÃ¥n server - BÃ¥de server och lokalt + Endast lokalt Lyckad radering Radering kunde inte slutföras Ange ett nytt namn diff --git a/res/values-ta-rLK/strings.xml b/res/values-ta-rLK/strings.xml index 37b569a8..2f30505d 100644 --- a/res/values-ta-rLK/strings.xml +++ b/res/values-ta-rLK/strings.xml @@ -11,6 +11,7 @@ + திறக்க பொதுவான மேலதிக கணக்குகள் @@ -87,9 +88,7 @@ பெயர்மாற்றம் அகற்றுக உள்ளூர் மட்டும் - இடத்துரி உள்ளடக்கங்கள் மட்டும் - சேவையகத்திலிருந்து அகற்றுக - தொலைவு மற்றும் உள்ளூர் + உள்ளூர் மட்டும் வெற்றிகரமாக அகற்றப்பட்டது நீக்கலை நிறைவு செய்ய முடியவில்லை புதிய பெயரொன்றை நுழைக்க diff --git a/res/values-th-rTH/strings.xml b/res/values-th-rTH/strings.xml index 50d6fc25..c13c48ee 100644 --- a/res/values-th-rTH/strings.xml +++ b/res/values-th-rTH/strings.xml @@ -27,6 +27,7 @@ ตั้งค่า บันทึก ปิด + เปิด ทั่วไป เพิ่มเติม บัญชี @@ -199,9 +200,9 @@ คุณต้องการที่จะลบ %1$s? คุณต้องการที่จะลบ %1$s และเนื้อหาของมัน? เฉพาะต้นทางเท่านั้น - เนื้อหาต้นทางเท่านั้น - ลบออกจากเซิร์ฟเวอร์ - ต้นทางและปลายทาง + เฉพาะต้นทางเท่านั้น + จากเซิฟเวอร์ + รีโมท & ต้นทาง ลบเรียบร้อยแล้ว ไม่สามารถลบได้ กรอกชื่อใหม่ @@ -256,8 +257,8 @@ ไฟล์ที่ขัดแย้ง ไฟล์ใดที่คุณต้องการที่จะเก็บ? หากคุณเลือกทั้งสองรุ่น ไฟล์ต้นทางจะมีจำนวนชื่อเพิ่ม เก็บไว้ทั้งสองอย่าง - ใช้รุ่นทั่วไป - ใช้รุ่นของเซิร์ฟเวอร์ + เวอร์ชันต้นทาง + เวอร์ชันเซิฟเวอร์ แสดงรูปภาพตัวอย่าง ไม่สามารถแสดงรูปภาพนี้ได้ %1$s ไม่สามารถคัดลอกไปยังโฟลเดอร์ %2$s ในเครื่อง diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index 13e90b66..a4e4629b 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -27,6 +27,7 @@ Ayarlar Günlükler Kapat + Aç Genel Daha fazla Hesaplar @@ -200,8 +201,8 @@ Gerçekten %1$s dosyasını kaldırmak istiyor musunuz? Gerçekten %1$s ve içeriğini kaldırmak istediğinizden emin misiniz? Sadece yerel - Sadece yerel içerik - Sunucudan kaldır + Sadece yerel + Sunucudan Uzak ve yerel Kaldırma başarılı Kaldırma başarısız @@ -254,7 +255,11 @@ Fotoğrafları sadece kablosuzda (WiFi) yükle Videoları sadece kablosuzda (WiFi) yükle /AnındaYükle + Dosya çakışması + Hangi dosyaları saklamak istiyorsunuz? Her ikisini de saklamayı seçerseniz yerel dosyanın adına bir sayı eklenecek. İkisini de koru + yerel sürüm + sunucu sürümü Resim önizleme Bu resim gösterilemiyor %1$s, %2$s yerel klasörüne kopyalanamadı @@ -309,6 +314,7 @@ sizinle paylaştı %1$s, sizinle \"%2$s\" paylaşımını yaptı + \"%1$s\" sizinle paylaşıldı Bağlantıyı yenile Sunucu adresi Yeterli hafıza yok diff --git a/res/values-ug/strings.xml b/res/values-ug/strings.xml index 97255fef..4573d713 100644 --- a/res/values-ug/strings.xml +++ b/res/values-ug/strings.xml @@ -11,6 +11,7 @@ + ئاچ ئادەتتىكى تېخىمۇ كۆپ ھېساباتلار diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 485b6ab1..d036312f 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -27,6 +27,7 @@ Налаштування Журнали Закрити + Відкрити Основне Більше Облікові записи @@ -188,9 +189,7 @@ Ви дійсно бажаєте видалити %1$s? Ви дійсно бажаєте видалити %1$s та весь вміст? Лише локально - Лише локальний зміст - Видалити із серверу - Віддалено і локально + Лише локально Успішно видалено Видалення не вдалось Введіть нове ім\'я diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur-rPK/strings.xml index 0c1462d0..3e97d3fa 100644 --- a/res/values-ur-rPK/strings.xml +++ b/res/values-ur-rPK/strings.xml @@ -8,6 +8,7 @@ + کھولیں مزید مدد یوزر نیم diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index fdaec2a5..bdccc82a 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -17,6 +17,7 @@ + Mở Tổng hợp hÆ¡n Tài khoản @@ -154,9 +155,7 @@ Sá»­a tên Xóa Chỉ cục bộ - Chỉ nội dung trên máy - Xóa từ máy chá»§ - Remote và local + Chỉ cục bộ Xóa thành công Xóa không thành công Nhập tên mới diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 7d735ff8..f29976da 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -27,6 +27,7 @@ 设置 日志 关闭 + 打开 常规 更多 账号 @@ -200,9 +201,9 @@ 你确定要删除 %1$s 吗? 您确定要删除 %1$s 及其内容吗? 仅本地 - 仅本地内容 - 从服务器删除 - 远程和本地都 + 仅本地 + 来自服务器 + 远程 & 本地 成功删除 无法完成删除 请输出新的名字 @@ -257,8 +258,8 @@ 文件冲突 您想要保留哪个文件?如果您同时选中了两个版本,本地的文件的文件名将被加上一个数字 保留两者 - 使用本地版本 - 使用服务器版本 + 本地版本 + 服务器版本 图片预览 无法显示图片 无法复制 %1$s 到本地目录 %2$s diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index c283a8b9..21b43f13 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -13,6 +13,7 @@ + 開啟 一般 更多 帳號 diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 980ba44c..69701a58 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -27,10 +27,12 @@ 設定 紀錄 關閉 + 開啟 一般 更多 帳號 管理帳號 + 密碼鎖 即時圖片上傳 即時上傳相機照片 即時影像上傳 @@ -68,6 +70,7 @@ 上傳中 幾秒前 這裡還沒有東西,上傳一些吧! + 載入中… 這個目錄中沒有任何檔案. 在檔案上輕觸來顯示更多資訊。 容量: @@ -77,6 +80,7 @@ 下載 更新檔案列表 檔案名稱在上傳時已被更改為 %1$s + 列表版型 分享連結 取消共享連結 是 @@ -129,6 +133,15 @@ 本地: %1$s 遠端: %1$s 無足夠的空間可以複製檔案到 %1$s 目錄. 是否使用移動的方式來處理? + 請輸入您的密碼鎖密碼 + 輸入您的密碼鎖密碼 + 這個密碼在你每次啟動這程式時都會被要求輸入 + 請重新輸入您的密碼鎖密碼 + 移除您的密碼鎖密碼 + 密碼不相符 + 不正確的密碼 + 密碼鎖已被移除 + 密碼鎖已設定 %1$s 音樂播放器 %1$s (播放中) %1$s (載入中) @@ -182,14 +195,15 @@ 無法在這個伺服器上取得認證 帳號目前不存在於本裝置 我的最愛 + 不喜愛的 重新命名 移除 您真的要移除 %1$s ? 您真的要移除 %1$s 與裡頭的檔案? 只有本地 只有本地 - 從伺服器移除 - 遠端與本地 + 來自伺服器 + 遠端 & 本地 成功地移除 刪除失敗 輸入新名稱 @@ -199,11 +213,13 @@ 檔案與同步 資料夾無法建立 禁止使用字符: / \\ < > : \" | ? * + 檔案名稱含有不合法的字元 檔名不能為空的 請稍後 未知的問題; 請選擇其他程式開啟檔案 沒有挑選檔案 傳送連結至 ... + 由私有的儲存空間複製檔案中 以 oAuth2 方式登入 連線到 oAuth2 伺服器… 這個網站的憑證無法被驗證 @@ -239,7 +255,11 @@ 只使用 WiFi 來執行即時圖片上傳的功能 只使用 WiFi 來執行即時影像上傳的功能 /InstantUpload + 檔案衝突 + 您要保留那個檔案? 如果您同時選擇兩個版本, 本地的檔案將在檔案名稱後面會加上編號 都保留 + 本地版本 + 伺服器版本 圖片預覽 無法顯示圖片 %1$s 無法被複製到本地目錄 %2$s @@ -294,7 +314,17 @@ 以分享的 與你 %1$s 分享了 \"%2$s\" 給您 + \"%1$s\" 已經與您分享 重新連線 伺服器位址 + 記憶體不足 使用者名稱 + 1 個資料夾 + %1$d 個資料夾 + 1 個檔案 + 1 個檔案, 1 個資料夾 + 1 個檔案, %1$d 個資料夾 + %1$d 個檔案 + %1$d 個檔案, 1 個資料夾 + %1$d 個檔案, %2$d 個資料夾 diff --git a/res/values/strings.xml b/res/values/strings.xml index cc3587d1..00058946 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -122,14 +122,14 @@ Synchronization failed, you need to relogin Synchronization of %1$s could not be completed Invalid password for %1$s - Conflicts found - %1$d kept-in-sync files could not be sync\'ed + Conflicts found + %1$d kept-in-sync files could not be sync\'ed Kept-in-sync files failed Contents of %1$d files could not be sync\'ed (%2$d conflicts) Some local files were forgotten %1$d files out of the %2$s folder could not be copied into As of version 1.3.16, files uploaded from this device are copied into the local %1$s folder to prevent data loss when a single file is synced with multiple accounts.\n\nDue to this change, all files uploaded in previous versions of this app were copied into the %2$s folder. However, an error prevented the completion of this operation during account synchronization. You may either leave the file(s) as is and remove the link to %3$s, or move the file(s) into the %1$s folder and retain the link to %4$s.\n\nListed below are the local file(s), and the remote file(s) in %5$s they were linked to. - Folder %1$s does not exist anymore + Folder %1$s does not exist anymore "Move all" "All files were moved" "Some files could not be moved" @@ -152,20 +152,20 @@ "%1$s (loading)" "%1$s playback finished" No media file found - No account provided - File not in a valid account - Unsupported media codec - Media file could not be read - Media file not correctly encoded - Timed out while trying to play - Media file cannot be streamed - Media file cannot be played with the stock media player - Security error trying to play %1$s - Input error trying to play %1$s - Unexpected error trying to play %1$s - Rewind button - Play or pause button - Fast forward button + No account provided + File not in a valid account + Unsupported media codec + Media file could not be read + Media file not correctly encoded + Timed out while trying to play + Media file cannot be streamed + Media file cannot be played with the stock media player + Security error trying to play %1$s + Input error trying to play %1$s + Unexpected error trying to play %1$s + Rewind button + Play or pause button + Fast forward button Getting authorization… Trying to login… @@ -250,19 +250,19 @@ Location: Validity: From: - To: - Signature: - Algorithm: - The certificate could not be shown. - - No information about the error - + To: + Signature: + Algorithm: + The certificate could not be shown. + - No information about the error + This is a placeholder placeholder.txt PNG Image 389 KB 2012/05/18 12:23 PM 12:23:45 - + Upload pictures via WiFi only Upload videos via WiFi only /InstantUpload @@ -274,7 +274,7 @@ Image preview This image cannot be shown - + %1$s could not be copied to %2$s local folder Upload Path @@ -287,32 +287,24 @@ Enter a password You must enter a password - Send + An error occurred while connecting with the server. + An error occurred while waiting for the server, the operation couldn\'t have been done + An error occurred while waiting for the server, the operation couldn\'t have been done + The operation couldn\'t be completed, server is unavailable + - Copy link - Copied to clipboard + You do not have permission %s + to rename this file + to delete this file + to share this file + to unshare this file + to create the file + to upload in this folder + The file is no longer available on the server - Critical error: cannot perform operations - - An error occurred while connecting with the server. - An error occurred while waiting for the server, the operation couldn\'t have been done - An error occurred while waiting for the server, the operation couldn\'t have been done - The operation couldn\'t be completed, server is unavailable - - - - You do not have permission %s - to rename this file - to delete this file - to share this file - to unshare this file - to create the file - to upload in this folder - The file is no longer available on the server - - Accounts - Add account - Secure connection is redirected to an unsecured route. + Accounts + Add account + Secure connection is redirected through an unsecured route. Logs Send History @@ -326,13 +318,20 @@ Nothing in here. You can add a folder! Choose - Unable to move. Please check whether the file exists - It is not possible to move a folder into a descendant - The file exists already in the destination folder - An error occurred while trying to move this file or folder - to move this file + Unable to move. Please check whether the file exists + It is not possible to move a folder into a descendant + The file exists already in the destination folder + An error occurred while trying to move this file or folder + to move this file + + + Unable to copy. Please check whether the file exists + It is not possible to copy a folder into a descendant + The file exists already in the destination folder + An error occurred while trying to copy this file or folder + to copy this file - Instant Uploads + Instant Uploads Security Upload Video Path diff --git a/src/com/owncloud/android/datamodel/FileDataStorageManager.java b/src/com/owncloud/android/datamodel/FileDataStorageManager.java index c5fc94d1..29a11c42 100644 --- a/src/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/src/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -50,6 +50,12 @@ import com.owncloud.android.lib.resources.shares.OCShare; import com.owncloud.android.lib.resources.shares.ShareType; import com.owncloud.android.utils.FileStorageUtils; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + public class FileDataStorageManager { public static final int ROOT_PARENT_ID = 0; @@ -60,7 +66,7 @@ public class FileDataStorageManager { private static String TAG = FileDataStorageManager.class.getSimpleName(); - + public FileDataStorageManager(Account account, ContentResolver cr) { mContentProviderClient = null; mContentResolver = cr; @@ -73,7 +79,7 @@ public class FileDataStorageManager { mAccount = account; } - + public void setAccount(Account account) { mAccount = account; } @@ -97,7 +103,7 @@ public class FileDataStorageManager { public ContentProviderClient getContentProviderClient() { return mContentProviderClient; } - + public OCFile getFileByPath(String path) { Cursor c = getCursorForValue(ProviderTableMeta.FILE_PATH, path); @@ -141,7 +147,7 @@ public class FileDataStorageManager { return fileExists(ProviderTableMeta.FILE_PATH, path); } - + public Vector getFolderContent(OCFile f/*, boolean onlyOnDevice*/) { if (f != null && f.isFolder() && f.getFileId() != -1) { // TODO Enable when "On Device" is recovered ? @@ -151,8 +157,8 @@ public class FileDataStorageManager { return new Vector(); } } - - + + public Vector getFolderImages(OCFile folder/*, boolean onlyOnDevice*/) { Vector ret = new Vector(); if (folder != null) { @@ -183,7 +189,7 @@ public class FileDataStorageManager { cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype()); cv.put(ProviderTableMeta.FILE_NAME, file.getFileName()); //if (file.getParentId() != DataStorageManager.ROOT_PARENT_ID) - cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId()); + cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId()); cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath()); if (!file.isFolder()) cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath()); @@ -200,8 +206,7 @@ public class FileDataStorageManager { cv.put(ProviderTableMeta.FILE_IS_DOWNLOADING, file.isDownloading()); boolean sameRemotePath = fileExists(file.getRemotePath()); - if (sameRemotePath || - fileExists(file.getFileId()) ) { // for renamed files + if (sameRemotePath || fileExists(file.getFileId())) { // for renamed files; no more delete and create OCFile oldFile = null; if (sameRemotePath) { @@ -215,12 +220,12 @@ public class FileDataStorageManager { if (getContentResolver() != null) { getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv, ProviderTableMeta._ID + "=?", - new String[] { String.valueOf(file.getFileId()) }); + new String[]{String.valueOf(file.getFileId())}); } else { try { getContentProviderClient().update(ProviderTableMeta.CONTENT_URI, cv, ProviderTableMeta._ID + "=?", - new String[] { String.valueOf(file.getFileId()) }); + new String[]{String.valueOf(file.getFileId())}); } catch (RemoteException e) { Log_OC.e(TAG, "Fail to insert insert file to database " @@ -246,7 +251,7 @@ public class FileDataStorageManager { long new_id = Long.parseLong(result_uri.getPathSegments() .get(1)); file.setFileId(new_id); - } + } } // if (file.isFolder()) { @@ -254,17 +259,17 @@ public class FileDataStorageManager { // } else { // updateFolderSize(file.getParentId()); // } - + return overriden; } /** * Inserts or updates the list of files contained in a given folder. - * + *

* CALLER IS THE RESPONSIBLE FOR GRANTING RIGHT UPDATE OF INFORMATION, NOT THIS METHOD. * HERE ONLY DATA CONSISTENCY SHOULD BE GRANTED - * + * * @param folder * @param updatedFiles * @param filesToRemove @@ -314,9 +319,9 @@ public class FileDataStorageManager { // updating an existing file operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI). withValues(cv). - withSelection( ProviderTableMeta._ID + "=?", - new String[] { String.valueOf(file.getFileId()) }) - .build()); + withSelection(ProviderTableMeta._ID + "=?", + new String[]{String.valueOf(file.getFileId())}) + .build()); } else { // adding a new file @@ -324,9 +329,9 @@ public class FileDataStorageManager { withValues(cv).build()); } } - + // prepare operations to remove files in the given folder - String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " + + String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " + ProviderTableMeta.FILE_PATH + "=?"; String [] whereArgs = null; for (OCFile file : filesToRemove) { @@ -351,7 +356,7 @@ public class FileDataStorageManager { ProviderTableMeta.CONTENT_URI_FILE, file.getFileId() ) ).withSelection(where, whereArgs).build()); - + if (file.isDown()) { String path = file.getStoragePath(); new File(path).delete(); @@ -360,7 +365,7 @@ public class FileDataStorageManager { } } } - + // update metadata of folder ContentValues cv = new ContentValues(); cv.put(ProviderTableMeta.FILE_MODIFIED, folder.getModificationTimestamp()); @@ -383,12 +388,12 @@ public class FileDataStorageManager { cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, folder.getPublicLink()); cv.put(ProviderTableMeta.FILE_PERMISSIONS, folder.getPermissions()); cv.put(ProviderTableMeta.FILE_REMOTE_ID, folder.getRemoteId()); - + operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI). withValues(cv). - withSelection( ProviderTableMeta._ID + "=?", - new String[] { String.valueOf(folder.getFileId()) }) - .build()); + withSelection(ProviderTableMeta._ID + "=?", + new String[]{String.valueOf(folder.getFileId())}) + .build()); // apply operations in batch ContentProviderResult[] results = null; @@ -413,7 +418,7 @@ public class FileDataStorageManager { long newId; Iterator filesIt = updatedFiles.iterator(); OCFile file = null; - for (int i=0; i 0); + success &= (deleted > 0); } String localPath = file.getStoragePath(); if (removeLocalCopy && file.isDown() && localPath != null && success) { @@ -509,12 +511,12 @@ public class FileDataStorageManager { } return success; } - + public boolean removeFolder(OCFile folder, boolean removeDBData, boolean removeLocalContent) { boolean success = true; if (folder != null && folder.isFolder()) { - if (removeDBData && folder.getFileId() != -1) { + if (removeDBData && folder.getFileId() != -1) { success = removeFolderInDb(folder); } if (removeLocalContent && success) { @@ -525,7 +527,7 @@ public class FileDataStorageManager { } private boolean removeFolderInDb(OCFile folder) { - Uri folder_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, "" + + Uri folder_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, "" + folder.getFileId()); // URI for recursive deletion String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " + ProviderTableMeta.FILE_PATH + "=?"; @@ -538,7 +540,7 @@ public class FileDataStorageManager { e.printStackTrace(); } } else { - deleted = getContentResolver().delete(folder_uri, where, whereArgs); + deleted = getContentResolver().delete(folder_uri, where, whereArgs); } return deleted > 0; } @@ -597,54 +599,54 @@ public class FileDataStorageManager { /** * Updates database and file system for a file or folder that was moved to a different location. - * + * * TODO explore better (faster) implementations * TODO throw exceptions up ! */ public void moveLocalFile(OCFile file, String targetPath, String targetParentPath) { if (file != null && file.fileExists() && !OCFile.ROOT_PATH.equals(file.getFileName())) { - + OCFile targetParent = getFileByPath(targetParentPath); if (targetParent == null) { throw new IllegalStateException("Parent folder of the target path does not exist!!"); } - + /// 1. get all the descendants of the moved element in a single QUERY Cursor c = null; if (getContentProviderClient() != null) { try { c = getContentProviderClient().query( - ProviderTableMeta.CONTENT_URI, - null, - ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + - ProviderTableMeta.FILE_PATH + " LIKE ? ", - new String[] { - mAccount.name, - file.getRemotePath() + "%" - }, - ProviderTableMeta.FILE_PATH + " ASC " + ProviderTableMeta.CONTENT_URI, + null, + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + + ProviderTableMeta.FILE_PATH + " LIKE ? ", + new String[]{ + mAccount.name, + file.getRemotePath() + "%" + }, + ProviderTableMeta.FILE_PATH + " ASC " ); } catch (RemoteException e) { Log_OC.e(TAG, e.getMessage()); } - + } else { c = getContentResolver().query( - ProviderTableMeta.CONTENT_URI, - null, - ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + - ProviderTableMeta.FILE_PATH + " LIKE ? ", - new String[] { - mAccount.name, - file.getRemotePath() + "%" - }, - ProviderTableMeta.FILE_PATH + " ASC " + ProviderTableMeta.CONTENT_URI, + null, + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + + ProviderTableMeta.FILE_PATH + " LIKE ? ", + new String[]{ + mAccount.name, + file.getRemotePath() + "%" + }, + ProviderTableMeta.FILE_PATH + " ASC " ); } /// 2. prepare a batch of update operations to change all the descendants - ArrayList operations = + ArrayList operations = new ArrayList(c.getCount()); String defaultSavePath = FileStorageUtils.getSavePath(mAccount.name); List originalPathsToTriggerMediaScan = new ArrayList(); @@ -656,13 +658,13 @@ public class FileDataStorageManager { ContentValues cv = new ContentValues(); // keep construction in the loop OCFile child = createFileInstance(c); cv.put( - ProviderTableMeta.FILE_PATH, - targetPath + child.getRemotePath().substring(lengthOfOldPath) + ProviderTableMeta.FILE_PATH, + targetPath + child.getRemotePath().substring(lengthOfOldPath) ); - if (child.getStoragePath() != null && + if (child.getStoragePath() != null && child.getStoragePath().startsWith(defaultSavePath)) { // update link to downloaded content - but local move is not done here! - String targetLocalPath = defaultSavePath + targetPath + + String targetLocalPath = defaultSavePath + targetPath + child.getStoragePath().substring(lengthOfOldStoragePath); cv.put(ProviderTableMeta.FILE_STORAGE_PATH, targetLocalPath); @@ -675,17 +677,17 @@ public class FileDataStorageManager { cv.put( ProviderTableMeta.FILE_PARENT, targetParent.getFileId() - ); + ); } operations.add( - ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI). - withValues(cv). - withSelection( - ProviderTableMeta._ID + "=?", - new String[] { String.valueOf(child.getFileId()) } + ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI). + withValues(cv). + withSelection( + ProviderTableMeta._ID + "=?", + new String[]{String.valueOf(child.getFileId())} ) - .build()); - + .build()); + } while (c.moveToNext()); } c.close(); @@ -730,9 +732,60 @@ public class FileDataStorageManager { } } } - + } - + + public void copyLocalFile(OCFile file, String targetPath) { + + if (file != null && file.fileExists() && !OCFile.ROOT_PATH.equals(file.getFileName())) { + String localPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, file); + File localFile = new File(localPath); + boolean copied = false; + String defaultSavePath = FileStorageUtils.getSavePath(mAccount.name); + if (localFile.exists()) { + File targetFile = new File(defaultSavePath + targetPath); + File targetFolder = targetFile.getParentFile(); + if (!targetFolder.exists()) { + targetFolder.mkdirs(); + } + copied = copyFile(localFile, targetFile); + } + Log_OC.d(TAG, "Local file COPIED : " + copied); + } + } + + private boolean copyFile(File src, File target) { + boolean ret = true; + + InputStream in = null; + OutputStream out = null; + + try { + in = new FileInputStream(src); + out = new FileOutputStream(target); + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + } catch (IOException ex) { + ret = false; + } finally { + if (in != null) try { + in.close(); + } catch (IOException e) { + e.printStackTrace(System.err); + } + if (out != null) try { + out.close(); + } catch (IOException e) { + e.printStackTrace(System.err); + } + } + + return ret; + } + private Vector getFolderContent(long parentId/*, boolean onlyOnDevice*/) { @@ -745,17 +798,17 @@ public class FileDataStorageManager { if (getContentProviderClient() != null) { try { - c = getContentProviderClient().query(req_uri, null, - ProviderTableMeta.FILE_PARENT + "=?" , - new String[] { String.valueOf(parentId)}, null); + c = getContentProviderClient().query(req_uri, null, + ProviderTableMeta.FILE_PARENT + "=?", + new String[]{String.valueOf(parentId)}, null); } catch (RemoteException e) { Log_OC.e(TAG, e.getMessage()); return ret; } } else { - c = getContentResolver().query(req_uri, null, - ProviderTableMeta.FILE_PARENT + "=?" , - new String[] { String.valueOf(parentId)}, null); + c = getContentResolver().query(req_uri, null, + ProviderTableMeta.FILE_PARENT + "=?", + new String[]{String.valueOf(parentId)}, null); } if (c.moveToFirst()) { @@ -774,8 +827,8 @@ public class FileDataStorageManager { return ret; } - - + + private OCFile createRootDir() { OCFile file = new OCFile(OCFile.ROOT_PATH); file.setMimetype("DIR"); @@ -793,7 +846,7 @@ public class FileDataStorageManager { cmp_key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?", - new String[] { value, mAccount.name }, null); + new String[]{value, mAccount.name}, null); } else { try { c = getContentProviderClient().query( @@ -801,7 +854,7 @@ public class FileDataStorageManager { null, cmp_key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?", - new String[] { value, mAccount.name }, null); + new String[]{value, mAccount.name}, null); } catch (RemoteException e) { Log_OC.e(TAG, "Couldn't determine file existance, assuming non existance: " @@ -823,14 +876,14 @@ public class FileDataStorageManager { key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?", - new String[] { value, mAccount.name }, null); + new String[]{value, mAccount.name}, null); } else { try { c = getContentProviderClient().query( ProviderTableMeta.CONTENT_URI, null, key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER - + "=?", new String[] { value, mAccount.name }, + + "=?", new String[]{value, mAccount.name}, null); } catch (RemoteException e) { Log_OC.e(TAG, "Could not get file details: " + e.getMessage()); @@ -839,7 +892,7 @@ public class FileDataStorageManager { } return c; } - + private OCFile createFileInstance(Cursor c) { OCFile file = null; @@ -893,10 +946,11 @@ public class FileDataStorageManager { } return file; } - + /** * Returns if the file/folder is shared by link or not - * @param path Path of the file/folder + * + * @param path Path of the file/folder * @return */ public boolean isShareByLink(String path) { @@ -908,10 +962,11 @@ public class FileDataStorageManager { c.close(); return file.isShareByLink(); } - + /** * Returns the public link of the file/folder - * @param path Path of the file/folder + * + * @param path Path of the file/folder * @return */ public String getPublicLink(String path) { @@ -923,8 +978,8 @@ public class FileDataStorageManager { c.close(); return file.getPublicLink(); } - - + + // Methods for Shares public boolean saveShare(OCShare share) { boolean overriden = false; @@ -946,19 +1001,18 @@ public class FileDataStorageManager { cv.put(ProviderTableMeta.OCSHARES_USER_ID, share.getUserId()); cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getIdRemoteShared()); cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name); - - if (shareExists(share.getIdRemoteShared())) { // for renamed files + if (shareExists(share.getIdRemoteShared())) { // 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.getIdRemoteShared())}); } 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.getIdRemoteShared())}); } catch (RemoteException e) { Log_OC.e(TAG, "Fail to insert insert file to database " @@ -984,7 +1038,7 @@ public class FileDataStorageManager { long new_id = Long.parseLong(result_uri.getPathSegments() .get(1)); share.setId(new_id); - } + } } return overriden; @@ -1000,7 +1054,7 @@ public class FileDataStorageManager { ProviderTableMeta.OCSHARES_PATH + "=? AND " + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? AND " + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?", - new String[] { path, Integer.toString(type.getValue()), mAccount.name }, + new String[]{path, Integer.toString(type.getValue()), mAccount.name}, null); } else { try { @@ -1010,7 +1064,7 @@ public class FileDataStorageManager { ProviderTableMeta.OCSHARES_PATH + "=? AND " + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? AND " + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?", - new String[] { path, Integer.toString(type.getValue()), mAccount.name }, + new String[]{path, Integer.toString(type.getValue()), mAccount.name}, null); } catch (RemoteException e) { @@ -1025,7 +1079,7 @@ public class FileDataStorageManager { c.close(); return share; } - + private OCShare createShareInstance(Cursor c) { OCShare share = null; if (c != null) { @@ -1047,12 +1101,9 @@ public class FileDataStorageManager { share.setSharedWithDisplayName(c.getString(c .getColumnIndex(ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME))); share.setIsFolder(c.getInt( - c.getColumnIndex(ProviderTableMeta.OCSHARES_IS_DIRECTORY)) == 1 ? true : false); + c.getColumnIndex(ProviderTableMeta.OCSHARES_IS_DIRECTORY)) == 1); share.setUserId(c.getLong(c.getColumnIndex(ProviderTableMeta.OCSHARES_USER_ID))); - share.setIdRemoteShared( - c.getLong(c.getColumnIndex(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED)) - ); - + share.setIdRemoteShared(c.getLong(c.getColumnIndex(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED))); } return share; } @@ -1066,7 +1117,7 @@ public class FileDataStorageManager { cmp_key + "=? AND " + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?", - new String[] { value, mAccount.name }, null); + new String[]{value, mAccount.name}, null); } else { try { c = getContentProviderClient().query( @@ -1074,7 +1125,7 @@ public class FileDataStorageManager { null, cmp_key + "=? AND " + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?", - new String[] { value, mAccount.name }, null); + new String[]{value, mAccount.name}, null); } catch (RemoteException e) { Log_OC.e(TAG, "Couldn't determine file existance, assuming non existance: " @@ -1086,7 +1137,7 @@ public class FileDataStorageManager { c.close(); return retval; } - + private boolean shareExists(long remoteId) { return shareExists(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, String.valueOf(remoteId)); } @@ -1096,17 +1147,14 @@ public class FileDataStorageManager { cv.put(ProviderTableMeta.FILE_SHARE_BY_LINK, false); cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, ""); String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?"; - String [] whereArgs = new String[]{mAccount.name}; - + String[] whereArgs = new String[]{mAccount.name}; + if (getContentResolver() != null) { getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv, where, whereArgs); } else { try { - getContentProviderClient().update( - ProviderTableMeta.CONTENT_URI, cv, where, whereArgs - ); - + getContentProviderClient().update(ProviderTableMeta.CONTENT_URI, cv, where, whereArgs); } catch (RemoteException e) { Log_OC.e(TAG, "Exception in cleanSharedFiles" + e.getMessage()); } @@ -1117,7 +1165,7 @@ public class FileDataStorageManager { ContentValues cv = new ContentValues(); cv.put(ProviderTableMeta.FILE_SHARE_BY_LINK, false); cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, ""); - String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + + String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + ProviderTableMeta.FILE_PARENT + "=?"; String [] whereArgs = new String[] { mAccount.name , String.valueOf(folder.getFileId()) }; @@ -1126,10 +1174,7 @@ public class FileDataStorageManager { } else { try { - getContentProviderClient().update( - ProviderTableMeta.CONTENT_URI, cv, where, whereArgs - ); - + getContentProviderClient().update(ProviderTableMeta.CONTENT_URI, cv, where, whereArgs); } catch (RemoteException e) { Log_OC.e(TAG, "Exception in cleanSharedFilesInFolder " + e.getMessage()); } @@ -1138,23 +1183,20 @@ public class FileDataStorageManager { private void cleanShares() { String where = ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?"; - String [] whereArgs = new String[]{mAccount.name}; - + String[] whereArgs = new String[]{mAccount.name}; + if (getContentResolver() != null) { getContentResolver().delete(ProviderTableMeta.CONTENT_URI_SHARE, where, whereArgs); } else { try { - getContentProviderClient().delete( - ProviderTableMeta.CONTENT_URI_SHARE, where, whereArgs - ); - + getContentProviderClient().delete(ProviderTableMeta.CONTENT_URI_SHARE, where, whereArgs); } catch (RemoteException e) { Log_OC.e(TAG, "Exception in cleanShares" + e.getMessage()); } } } - + public void saveShares(Collection shares) { cleanShares(); if (shares != null) { @@ -1187,13 +1229,9 @@ public class FileDataStorageManager { operations.add( ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI_SHARE). withValues(cv). - withSelection( - ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?", - new String[] { String.valueOf(share.getIdRemoteShared()) } - ). - build() - ); - + withSelection(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?", + new String[]{String.valueOf(share.getIdRemoteShared())}) + .build()); } else { // adding a new file operations.add( @@ -1203,7 +1241,7 @@ public class FileDataStorageManager { ); } } - + // apply operations in batch if (operations.size() > 0) { @SuppressWarnings("unused") @@ -1212,28 +1250,25 @@ public class FileDataStorageManager { " operations to FileContentProvider"); try { if (getContentResolver() != null) { - results = getContentResolver().applyBatch( - MainApp.getAuthority(), operations - ); - + results = getContentResolver().applyBatch(MainApp.getAuthority(), operations); } else { results = 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 updateSharedFiles(Collection sharedFiles) { cleanSharedFiles(); - + if (sharedFiles != null) { ArrayList operations = new ArrayList(sharedFiles.size()); @@ -1282,11 +1317,9 @@ public class FileDataStorageManager { operations.add( ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI). withValues(cv). - withSelection( - ProviderTableMeta._ID + "=?", - new String[] { String.valueOf(file.getFileId()) } - ).build() - ); + withSelection(ProviderTableMeta._ID + "=?", + new String[]{String.valueOf(file.getFileId())}) + .build()); } else { // adding a new file @@ -1297,7 +1330,7 @@ public class FileDataStorageManager { ); } } - + // apply operations in batch if (operations.size() > 0) { @SuppressWarnings("unused") @@ -1306,28 +1339,25 @@ public class FileDataStorageManager { " operations to FileContentProvider"); try { if (getContentResolver() != null) { - results = getContentResolver().applyBatch( - MainApp.getAuthority(), operations - ); - + results = getContentResolver().applyBatch(MainApp.getAuthority(), operations); } else { results = 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 removeShare(OCShare share){ + + } + + public void removeShare(OCShare share) { Uri share_uri = ProviderTableMeta.CONTENT_URI_SHARE; - String where = ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?" + " AND " + + String where = ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?" + " AND " + ProviderTableMeta.FILE_PATH + "=?"; String [] whereArgs = new String[]{mAccount.name, share.getPath()}; if (getContentProviderClient() != null) { @@ -1337,10 +1367,10 @@ public class FileDataStorageManager { e.printStackTrace(); } } else { - getContentResolver().delete(share_uri, where, whereArgs); + getContentResolver().delete(share_uri, where, whereArgs); } } - + public void saveSharesDB(ArrayList shares) { saveShares(shares); @@ -1351,7 +1381,7 @@ public class FileDataStorageManager { String path = share.getPath(); if (share.isFolder()) { path = path + FileUtils.PATH_SEPARATOR; - } + } // Update OCFile with data from share: ShareByLink and publicLink OCFile file = getFileByPath(path); @@ -1360,18 +1390,18 @@ public class FileDataStorageManager { file.setShareByLink(true); sharedFiles.add(file); } - } + } } - + updateSharedFiles(sharedFiles); } - + public void saveSharesInFolder(ArrayList shares, OCFile folder) { cleanSharedFilesInFolder(folder); ArrayList operations = new ArrayList(); operations = prepareRemoveSharesInFolder(folder, operations); - + if (shares != null) { // prepare operations to insert or update files to save in the given folder for (OCShare share : shares) { @@ -1415,7 +1445,7 @@ public class FileDataStorageManager { //} } } - + // apply operations in batch if (operations.size() > 0) { @SuppressWarnings("unused") @@ -1437,13 +1467,13 @@ public class FileDataStorageManager { } } //} - + } private ArrayList prepareRemoveSharesInFolder( OCFile folder, ArrayList preparedOperations) { if (folder != null) { - String where = ProviderTableMeta.OCSHARES_PATH + "=?" + " AND " + String where = ProviderTableMeta.OCSHARES_PATH + "=?" + " AND " + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?"; String [] whereArgs = new String[]{ "", mAccount.name }; diff --git a/src/com/owncloud/android/datamodel/OCFile.java b/src/com/owncloud/android/datamodel/OCFile.java index d1821b44..2aa5dbc0 100644 --- a/src/com/owncloud/android/datamodel/OCFile.java +++ b/src/com/owncloud/android/datamodel/OCFile.java @@ -543,6 +543,13 @@ public class OCFile implements Parcelable, Comparable { FileStorageUtils.getMimeTypeFromName(mRemotePath).startsWith("image/")); } + /** + * @return 'True' if the file is hidden + */ + public boolean isHidden() { + return getFileName().startsWith("."); + } + public String getPermissions() { return mPermissions; } diff --git a/src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java b/src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java index 0e59a834..ce8bfd4a 100644 --- a/src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java +++ b/src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java @@ -33,7 +33,9 @@ import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; +import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.media.ThumbnailUtils; import android.net.Uri; @@ -259,10 +261,16 @@ public class ThumbnailsCacheManager { int px = getThumbnailDimension(); if (file.isDown()) { - Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile( + Bitmap temp = BitmapUtils.decodeSampledBitmapFromFile( file.getStoragePath(), px, px); + Bitmap bitmap = ThumbnailUtils.extractThumbnail(temp, px, px); if (bitmap != null) { + // Handle PNG + if (file.getMimetype().equalsIgnoreCase("image/png")) { + bitmap = handlePNG(bitmap, px); + } + thumbnail = addThumbnailToCache(imageKey, bitmap, file.getStoragePath(), px); file.setNeedsUpdateThumbnail(false); @@ -282,13 +290,15 @@ public class ThumbnailsCacheManager { GetMethod get = new GetMethod(uri); int status = mClient.executeMethod(get); if (status == HttpStatus.SC_OK) { -// byte[] bytes = get.getResponseBody(); -// Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, -// bytes.length); InputStream inputStream = get.getResponseBodyAsStream(); Bitmap bitmap = BitmapFactory.decodeStream(inputStream); thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px); + // Handle PNG + if (file.getMimetype().equalsIgnoreCase("image/png")) { + thumbnail = handlePNG(thumbnail, px); + } + // Add thumbnail to cache if (thumbnail != null) { addBitmapToCache(imageKey, thumbnail); @@ -308,6 +318,19 @@ public class ThumbnailsCacheManager { } + private Bitmap handlePNG(Bitmap bitmap, int px){ + Bitmap resultBitmap = Bitmap.createBitmap(px, + px, + Bitmap.Config.ARGB_8888); + Canvas c = new Canvas(resultBitmap); + + c.drawColor(MainApp.getAppContext().getResources(). + getColor(R.color.background_color)); + c.drawBitmap(bitmap, 0, 0, null); + + return resultBitmap; + } + private Bitmap doFileInBackground() { File file = (File)mFile; diff --git a/src/com/owncloud/android/files/FileMenuFilter.java b/src/com/owncloud/android/files/FileMenuFilter.java index 2c2754cc..f7fee626 100644 --- a/src/com/owncloud/android/files/FileMenuFilter.java +++ b/src/com/owncloud/android/files/FileMenuFilter.java @@ -39,7 +39,7 @@ import com.owncloud.android.services.OperationsService.OperationsServiceBinder; import com.owncloud.android.ui.activity.ComponentsGetter; /** - * Filters out the file actions available in a given {@link Menu} for a given {@link OCFile} + * Filters out the file actions available in a given {@link Menu} for a given {@link OCFile} * according to the current state of the latest. */ public class FileMenuFilter { @@ -48,10 +48,10 @@ public class FileMenuFilter { private ComponentsGetter mComponentsGetter; private Account mAccount; private Context mContext; - + /** * Constructor - * + * * @param targetFile {@link OCFile} target of the action to filter in the {@link Menu}. * @param account ownCloud {@link Account} holding targetFile. * @param cg Accessor to app components, needed to access the @@ -64,20 +64,20 @@ public class FileMenuFilter { mComponentsGetter = cg; mContext = context; } - - + + /** * Filters out the file actions available in the passed {@link Menu} taken into account * the state of the {@link OCFile} held by the filter. - * + * * @param menu Options or context menu to filter. */ public void filter(Menu menu) { - List toShow = new ArrayList(); - List toHide = new ArrayList(); - + List toShow = new ArrayList(); + List toHide = new ArrayList(); + filter(toShow, toHide); - + MenuItem item = null; for (int i : toShow) { item = menu.findItem(i); @@ -86,7 +86,7 @@ public class FileMenuFilter { item.setEnabled(true); } } - + for (int i : toHide) { item = menu.findItem(i); if (item != null) { @@ -99,10 +99,10 @@ public class FileMenuFilter { /** * Performs the real filtering, to be applied in the {@link Menu} by the caller methods. - * + * * Decides what actions must be shown and hidden. - * - * @param toShow List to save the options that must be shown in the menu. + * + * @param toShow List to save the options that must be shown in the menu. * @param toHide List to save the options that must be shown in the menu. */ private void filter(List toShow, List toHide) { @@ -116,71 +116,72 @@ public class FileMenuFilter { FileUploaderBinder uploaderBinder = mComponentsGetter.getFileUploaderBinder(); uploading = (uploaderBinder != null && uploaderBinder.isUploading(mAccount, mFile)); } - + /// decision is taken for each possible action on a file in the menu - + // DOWNLOAD if (mFile == null || mFile.isDown() || downloading || uploading) { toHide.add(R.id.action_download_file); - + } else { toShow.add(R.id.action_download_file); } - + // RENAME if (mFile == null || downloading || uploading) { toHide.add(R.id.action_rename_file); - + } else { toShow.add(R.id.action_rename_file); } - // MOVE + // MOVE & COPY if (mFile == null || downloading || uploading) { toHide.add(R.id.action_move); - + toHide.add(R.id.action_copy); } else { toShow.add(R.id.action_move); + toShow.add(R.id.action_copy); } - + // REMOVE if (mFile == null || downloading || uploading) { toHide.add(R.id.action_remove_file); - + } else { toShow.add(R.id.action_remove_file); } - + // OPEN WITH (different to preview!) if (mFile == null || mFile.isFolder() || !mFile.isDown() || downloading || uploading) { toHide.add(R.id.action_open_file_with); - + } else { toShow.add(R.id.action_open_file_with); } - - + + // CANCEL DOWNLOAD if (mFile == null || !downloading) { toHide.add(R.id.action_cancel_download); } else { toShow.add(R.id.action_cancel_download); } - + // CANCEL UPLOAD if (mFile == null || !uploading || mFile.isFolder()) { toHide.add(R.id.action_cancel_upload); } else { toShow.add(R.id.action_cancel_upload); } - + // SYNC FILE CONTENTS if (mFile == null || mFile.isFolder() || !mFile.isDown() || downloading || uploading) { toHide.add(R.id.action_sync_file); } else { toShow.add(R.id.action_sync_file); } - + // SHARE FILE // TODO add check on SHARE available on server side? boolean shareAllowed = (mContext != null && @@ -190,7 +191,7 @@ public class FileMenuFilter { } else { toShow.add(R.id.action_share_file); } - + // UNSHARE FILE // TODO add check on SHARE available on server side? if ( !shareAllowed || (mFile == null || !mFile.isShareByLink())) { @@ -205,7 +206,7 @@ public class FileMenuFilter { } else { toShow.add(R.id.action_see_details); } - + // SEND boolean sendAllowed = (mContext != null && mContext.getString(R.string.send_files_to_other_apps).equalsIgnoreCase("on")); diff --git a/src/com/owncloud/android/files/FileOperationsHelper.java b/src/com/owncloud/android/files/FileOperationsHelper.java index ddee2050..22370289 100644 --- a/src/com/owncloud/android/files/FileOperationsHelper.java +++ b/src/com/owncloud/android/files/FileOperationsHelper.java @@ -21,8 +21,6 @@ package com.owncloud.android.files; -import org.apache.http.protocol.HTTP; - import android.accounts.Account; import android.content.Intent; import android.net.Uri; @@ -35,7 +33,6 @@ import com.owncloud.android.authentication.AccountUtils; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder; import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; - import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.lib.resources.status.OwnCloudVersion; @@ -44,20 +41,22 @@ import com.owncloud.android.services.observer.FileObserverService; import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.ui.dialog.ShareLinkToDialog; +import org.apache.http.protocol.HTTP; + /** * */ public class FileOperationsHelper { private static final String TAG = FileOperationsHelper.class.getName(); - - private static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG"; + + private static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG"; protected FileActivity mFileActivity = null; /// Identifier of operation in progress which result shouldn't be lost private long mWaitingForOpId = Long.MAX_VALUE; - + public FileOperationsHelper(FileActivity fileActivity) { mFileActivity = fileActivity; } @@ -67,7 +66,7 @@ public class FileOperationsHelper { if (file != null) { String storagePath = file.getStoragePath(); String encodedStoragePath = WebdavUtils.encodePath(storagePath); - + Intent intentForSavedMimeType = new Intent(Intent.ACTION_VIEW); intentForSavedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), file.getMimetype()); intentForSavedMimeType.setFlags( @@ -94,29 +93,29 @@ public class FileOperationsHelper { } else { chooserIntent = Intent.createChooser(intentForSavedMimeType, mFileActivity.getString(R.string.actionbar_open_with)); } - + mFileActivity.startActivity(chooserIntent); - + } else { Log_OC.wtf(TAG, "Trying to open a NULL OCFile"); } } - - + + public void shareFileWithLink(OCFile file) { - + if (isSharedSupported()) { if (file != null) { String link = "https://fake.url"; Intent intent = createShareWithLinkIntent(link); - String[] packagesToExclude = new String[] { mFileActivity.getPackageName() }; + String[] packagesToExclude = new String[]{mFileActivity.getPackageName()}; DialogFragment chooserDialog = ShareLinkToDialog.newInstance(intent, packagesToExclude, file); chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG); - + } else { Log_OC.wtf(TAG, "Trying to share a NULL OCFile"); } - + } else { // Show a Message Toast t = Toast.makeText( @@ -125,13 +124,13 @@ public class FileOperationsHelper { t.show(); } } - - + + public void shareFileWithLinkToApp(OCFile file, String password, Intent sendIntent) { if (file != null) { mFileActivity.showLoadingDialog(); - + Intent service = new Intent(mFileActivity, OperationsService.class); service.setAction(OperationsService.ACTION_CREATE_SHARE); service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount()); @@ -144,18 +143,18 @@ public class FileOperationsHelper { Log_OC.wtf(TAG, "Trying to open a NULL OCFile"); } } - - + + 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; + return intentToShareLink; } - - + + /** - * @return 'True' if the server supports the Share API + * @return 'True' if the server supports the Share API */ public boolean isSharedSupported() { if (mFileActivity.getAccount() != null) { @@ -164,10 +163,10 @@ public class FileOperationsHelper { } return false; } - - + + public void unshareFileWithLink(OCFile file) { - + if (isSharedSupported()) { // Unshare the file Intent service = new Intent(mFileActivity, OperationsService.class); @@ -177,15 +176,15 @@ public class FileOperationsHelper { mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service); mFileActivity.showLoadingDialog(); - + } 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 sendDownloadedFile(OCFile file) { if (file != null) { String storagePath = file.getStoragePath(); @@ -197,7 +196,7 @@ public class FileOperationsHelper { sendIntent.putExtra(Intent.ACTION_SEND, true); // Send Action // Show dialog, without the own app - String[] packagesToExclude = new String[] { mFileActivity.getPackageName() }; + String[] packagesToExclude = new String[]{mFileActivity.getPackageName()}; DialogFragment chooserDialog = ShareLinkToDialog.newInstance(sendIntent, packagesToExclude, file); chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG); @@ -205,10 +204,10 @@ public class FileOperationsHelper { Log_OC.wtf(TAG, "Trying to send a NULL OCFile"); } } - - + + public void syncFile(OCFile file) { - + if (!file.isFolder()){ Intent intent = new Intent(mFileActivity, OperationsService.class); intent.setAction(OperationsService.ACTION_SYNC_FILE); @@ -269,8 +268,8 @@ public class FileOperationsHelper { mFileActivity.showLoadingDialog(); } - - + + public void createFolder(String remotePath, boolean createFullPath) { // Create Folder Intent service = new Intent(mFileActivity, OperationsService.class); @@ -317,8 +316,9 @@ public class FileOperationsHelper { /** * Start move file operation - * @param newfile File where it is going to be moved - * @param currentFile File with the previous info + * + * @param newfile File where it is going to be moved + * @param currentFile File with the previous info */ public void moveFile(OCFile newfile, OCFile currentFile) { // Move files @@ -332,6 +332,23 @@ public class FileOperationsHelper { mFileActivity.showLoadingDialog(); } + /** + * Start copy file operation + * + * @param newfile File where it is going to be moved + * @param currentFile File with the previous info + */ + public void copyFile(OCFile newfile, OCFile currentFile) { + // Copy files + Intent service = new Intent(mFileActivity, OperationsService.class); + service.setAction(OperationsService.ACTION_COPY_FILE); + service.putExtra(OperationsService.EXTRA_NEW_PARENT_PATH, newfile.getRemotePath()); + service.putExtra(OperationsService.EXTRA_REMOTE_PATH, currentFile.getRemotePath()); + service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount()); + mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service); + + mFileActivity.showLoadingDialog(); + } public long getOpIdWaitingFor() { return mWaitingForOpId; @@ -341,7 +358,7 @@ public class FileOperationsHelper { public void setOpIdWaitingFor(long waitingForOpId) { mWaitingForOpId = waitingForOpId; } - + /** * @return 'True' if the server doesn't need to check forbidden characters */ diff --git a/src/com/owncloud/android/operations/CopyFileOperation.java b/src/com/owncloud/android/operations/CopyFileOperation.java new file mode 100644 index 00000000..77a9a071 --- /dev/null +++ b/src/com/owncloud/android/operations/CopyFileOperation.java @@ -0,0 +1,103 @@ +/* ownCloud Android client application + * Copyright (C) 2012-2014 ownCloud Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.owncloud.android.operations; + +import android.accounts.Account; +import android.content.Context; + +import com.owncloud.android.datamodel.OCFile; +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; +import com.owncloud.android.lib.resources.files.CopyRemoteFileOperation; +import com.owncloud.android.operations.common.SyncOperation; + + +/** + * Operation copying an {@link OCFile} to a different folder. + * + * @author David A. Velasco + */ +public class CopyFileOperation extends SyncOperation { + + //private static final String TAG = MoveFileOperation.class.getSimpleName(); + + private String mSrcPath; + private String mTargetParentPath; + + private OCFile mFile; + + + /** + * Constructor + * + * @param srcPath Remote path of the {@link OCFile} to move. + * @param targetParentPath Path to the folder where the file will be copied into. + * @param account OwnCloud account containing both the file and the target folder + */ + public CopyFileOperation(String srcPath, String targetParentPath, Account account) { + mSrcPath = srcPath; + mTargetParentPath = targetParentPath; + if (!mTargetParentPath.endsWith(OCFile.PATH_SEPARATOR)) { + mTargetParentPath += OCFile.PATH_SEPARATOR; + } + + mFile = null; + } + + /** + * Performs the operation. + * + * @param client Client object to communicate with the remote ownCloud server. + */ + @Override + protected RemoteOperationResult run(OwnCloudClient client) { + RemoteOperationResult result; + + /// 1. check copy validity + if (mTargetParentPath.startsWith(mSrcPath)) { + return new RemoteOperationResult(ResultCode.INVALID_COPY_INTO_DESCENDANT); + } + mFile = getStorageManager().getFileByPath(mSrcPath); + if (mFile == null) { + return new RemoteOperationResult(ResultCode.FILE_NOT_FOUND); + } + + /// 2. remote copy + String targetPath = mTargetParentPath + mFile.getFileName(); + if (mFile.isFolder()) { + targetPath += OCFile.PATH_SEPARATOR; + } + CopyRemoteFileOperation operation = new CopyRemoteFileOperation( + mSrcPath, + targetPath, + false + ); + result = operation.execute(client); + + /// 3. local copy + if (result.isSuccess()) { + getStorageManager().copyLocalFile(mFile, targetPath); + } + // TODO handle ResultCode.PARTIAL_COPY_DONE in client Activity, for the moment + + return result; + } + + +} diff --git a/src/com/owncloud/android/operations/RefreshFolderOperation.java b/src/com/owncloud/android/operations/RefreshFolderOperation.java index ddbffb8c..977f72a8 100644 --- a/src/com/owncloud/android/operations/RefreshFolderOperation.java +++ b/src/com/owncloud/android/operations/RefreshFolderOperation.java @@ -252,8 +252,14 @@ public class RefreshFolderOperation extends RemoteOperation { if (!mIgnoreETag) { // check if remote and local folder are different - mRemoteFolderChanged = - !(remoteFolder.getEtag().equalsIgnoreCase(mLocalFolder.getEtag())); + String remoteFolderETag = remoteFolder.getEtag(); + if (remoteFolderETag != null) { + mRemoteFolderChanged = + !(remoteFolderETag.equalsIgnoreCase(mLocalFolder.getEtag())); + } else { + Log_OC.e(TAG, "Checked " + mAccount.name + remotePath + " : " + + "No ETag received from server"); + } } result = new RemoteOperationResult(ResultCode.OK); diff --git a/src/com/owncloud/android/services/OperationsService.java b/src/com/owncloud/android/services/OperationsService.java index 2514c4de..099bd087 100644 --- a/src/com/owncloud/android/services/OperationsService.java +++ b/src/com/owncloud/android/services/OperationsService.java @@ -19,11 +19,21 @@ package com.owncloud.android.services; -import java.io.IOException; -import java.util.Iterator; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ConcurrentMap; +import android.accounts.Account; +import android.accounts.AccountsException; +import android.accounts.AuthenticatorException; +import android.accounts.OperationCanceledException; +import android.app.Service; +import android.content.Intent; +import android.net.Uri; +import android.os.Binder; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.IBinder; +import android.os.Looper; +import android.os.Message; +import android.os.Process; +import android.util.Pair; import com.owncloud.android.MainApp; import com.owncloud.android.R; @@ -42,7 +52,7 @@ import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.lib.resources.shares.ShareType; import com.owncloud.android.lib.resources.status.OwnCloudVersion; import com.owncloud.android.lib.resources.users.GetRemoteUserNameOperation; -import com.owncloud.android.operations.common.SyncOperation; +import com.owncloud.android.operations.CopyFileOperation; import com.owncloud.android.operations.CreateFolderOperation; import com.owncloud.android.operations.CreateShareOperation; import com.owncloud.android.operations.GetServerInfoOperation; @@ -53,28 +63,18 @@ import com.owncloud.android.operations.RenameFileOperation; import com.owncloud.android.operations.SynchronizeFileOperation; import com.owncloud.android.operations.SynchronizeFolderOperation; import com.owncloud.android.operations.UnshareLinkOperation; +import com.owncloud.android.operations.common.SyncOperation; -import android.accounts.Account; -import android.accounts.AccountManager; -import android.accounts.AccountsException; -import android.accounts.AuthenticatorException; -import android.accounts.OperationCanceledException; -import android.app.Service; -import android.content.Intent; -import android.net.Uri; -import android.os.Binder; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.IBinder; -import android.os.Looper; -import android.os.Message; -import android.os.Process; -import android.util.Pair; +import java.io.IOException; +import java.util.Iterator; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ConcurrentMap; public class OperationsService extends Service { - + private static final String TAG = OperationsService.class.getSimpleName(); - + public static final String EXTRA_ACCOUNT = "ACCOUNT"; public static final String EXTRA_SERVER_URL = "SERVER_URL"; public static final String EXTRA_OAUTH2_QUERY_PARAMETERS = "OAUTH2_QUERY_PARAMETERS"; @@ -90,7 +90,7 @@ public class OperationsService extends Service { public static final String EXTRA_PASSWORD_SHARE = "PASSWORD_SHARE"; public static final String EXTRA_COOKIE = "COOKIE"; - + public static final String ACTION_CREATE_SHARE = "CREATE_SHARE"; public static final String ACTION_UNSHARE = "UNSHARE"; public static final String ACTION_GET_SERVER_INFO = "GET_SERVER_INFO"; @@ -102,22 +102,24 @@ public class OperationsService extends Service { public static final String ACTION_SYNC_FILE = "SYNC_FILE"; public static final String ACTION_SYNC_FOLDER = "SYNC_FOLDER";//for the moment, just to download public static final String ACTION_MOVE_FILE = "MOVE_FILE"; - + public static final String ACTION_COPY_FILE = "COPY_FILE"; + public static final String ACTION_OPERATION_ADDED = OperationsService.class.getName() + ".OPERATION_ADDED"; public static final String ACTION_OPERATION_FINISHED = OperationsService.class.getName() + ".OPERATION_FINISHED"; - private ConcurrentMap> - mUndispatchedFinishedOperations = + + private ConcurrentMap> + mUndispatchedFinishedOperations = new ConcurrentHashMap>(); - + private static class Target { public Uri mServerUrl = null; public Account mAccount = null; public String mCookie = null; - + public Target(Account account, Uri serverUrl, String cookie) { mAccount = account; mServerUrl = serverUrl; @@ -151,11 +153,11 @@ public class OperationsService extends Service { mSyncFolderHandler = new SyncFolderHandler(thread.getLooper(), this); } - + /** * Entry point to add a new operation to the queue of operations. - * - * New operations are added calling to startService(), resulting in a call to this method. + *

+ * New operations are added calling to startService(), resulting in a call to this method. * This ensures the service will keep on working although the caller activity goes away. */ @Override @@ -200,8 +202,8 @@ public class OperationsService extends Service { // Saving cookies try { OwnCloudClientManagerFactory.getDefaultSingleton(). - saveAllClients(this, MainApp.getAccountType()); - + saveAllClients(this, MainApp.getAccountType()); + // TODO - get rid of these exceptions } catch (AccountNotFoundException e) { e.printStackTrace(); @@ -212,7 +214,7 @@ public class OperationsService extends Service { } catch (IOException e) { e.printStackTrace(); } - + mUndispatchedFinishedOperations.clear(); mOperationsBinder = null; @@ -227,8 +229,8 @@ public class OperationsService extends Service { } /** - * Provides a binder object that clients can use to perform actions on the queue of operations, - * except the addition of new operations. + * Provides a binder object that clients can use to perform actions on the queue of operations, + * except the addition of new operations. */ @Override public IBinder onBind(Intent intent) { @@ -236,7 +238,7 @@ public class OperationsService extends Service { return mOperationsBinder; } - + /** * Called when ALL the bound clients were unbound. */ @@ -248,20 +250,20 @@ public class OperationsService extends Service { /** - * Binder to let client components to perform actions on the queue of operations. - * - * It provides by itself the available operations. + * Binder to let client components to perform actions on the queue of operations. + *

+ * It provides by itself the available operations. */ public class OperationsServiceBinder extends Binder /* implements OnRemoteOperationListener */ { - - /** + + /** * Map of listeners that will be reported about the end of operations from a * {@link OperationsServiceBinder} instance */ - private ConcurrentMap mBoundListeners = + private final ConcurrentMap mBoundListeners = new ConcurrentHashMap(); - - private ServiceHandler mServiceHandler = null; + + private ServiceHandler mServiceHandler = null; public OperationsServiceBinder(ServiceHandler serviceHandler) { mServiceHandler = serviceHandler; @@ -280,15 +282,15 @@ public class OperationsService extends Service { public void clearListeners() { - + mBoundListeners.clear(); } - + /** * Adds a listener interested in being reported about the end of operations. - * - * @param listener Object to notify about the end of operations. + * + * @param listener Object to notify about the end of operations. * @param callbackHandler {@link Handler} to access the listener without * breaking Android threading protection. */ @@ -298,15 +300,15 @@ public class OperationsService extends Service { mBoundListeners.put(listener, callbackHandler); } } - - + + /** * Removes a listener from the list of objects interested in the being reported about * the end of operations. * * @param listener Object to notify about progress of transfer. */ - public void removeOperationListener (OnRemoteOperationListener listener) { + public void removeOperationListener(OnRemoteOperationListener listener) { synchronized (mBoundListeners) { mBoundListeners.remove(listener); } @@ -314,8 +316,8 @@ public class OperationsService extends Service { /** - * TODO - IMPORTANT: update implementation when more operations are moved into the service - * + * TODO - IMPORTANT: update implementation when more operations are moved into the service + * * @return 'True' when an operation that enforces the user to wait for completion is * in process. */ @@ -343,8 +345,8 @@ public class OperationsService extends Service { return Long.MAX_VALUE; } } - - + + public boolean dispatchResultIfFinished(int operationId, OnRemoteOperationListener listener) { Pair undispatched = @@ -378,8 +380,8 @@ public class OperationsService extends Service { /** - * Operations worker. Performs the pending operations in the order they were requested. - * + * Operations worker. Performs the pending operations in the order they were requested. + * * Created with the Looper of a new thread, started in {@link OperationsService#onCreate()}. */ private static class ServiceHandler extends Handler { @@ -388,8 +390,8 @@ public class OperationsService extends Service { OperationsService mService; - - + + private ConcurrentLinkedQueue> mPendingOperations = new ConcurrentLinkedQueue>(); private RemoteOperation mCurrentOperation = null; @@ -412,7 +414,7 @@ public class OperationsService extends Service { Log_OC.d(TAG, "Stopping after command with id " + msg.arg1); mService.stopSelf(msg.arg1); } - + /** * Performs the next operation in the queue @@ -475,7 +477,7 @@ public class OperationsService extends Service { } else { result = mCurrentOperation.execute(mOwnCloudClient); } - + } catch (AccountsException e) { if (mLastTarget.mAccount == null) { Log_OC.e(TAG, "Error while trying to get authorization for a NULL account", @@ -515,9 +517,9 @@ public class OperationsService extends Service { } - + } - + /** * Creates a new operation, as described by operationIntent. @@ -535,7 +537,7 @@ public class OperationsService extends Service { if (!operationIntent.hasExtra(EXTRA_ACCOUNT) && !operationIntent.hasExtra(EXTRA_SERVER_URL)) { Log_OC.e(TAG, "Not enough information provided in intent"); - + } else { Account account = operationIntent.getParcelableExtra(EXTRA_ACCOUNT); String serverUrl = operationIntent.getStringExtra(EXTRA_SERVER_URL); @@ -556,7 +558,7 @@ public class OperationsService extends Service { ShareType.PUBLIC_LINK, "", false, password, 1, sendIntent); } - + } else if (action.equals(ACTION_UNSHARE)) { // Unshare file String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH); if (remotePath.length() > 0) { @@ -568,7 +570,7 @@ public class OperationsService extends Service { } else if (action.equals(ACTION_GET_SERVER_INFO)) { // check OC server and get basic information from it operation = new GetServerInfoOperation(serverUrl, OperationsService.this); - + } else if (action.equals(ACTION_OAUTH2_GET_ACCESS_TOKEN)) { /// GET ACCESS TOKEN to the OAuth server String oauth2QueryParameters = @@ -578,7 +580,7 @@ public class OperationsService extends Service { getString(R.string.oauth2_redirect_uri), getString(R.string.oauth2_grant_type), oauth2QueryParameters); - + } else if (action.equals(ACTION_GET_USER_NAME)) { // Get User Name operation = new GetRemoteUserNameOperation(); @@ -602,7 +604,7 @@ public class OperationsService extends Service { boolean createFullPath = operationIntent.getBooleanExtra(EXTRA_CREATE_FULL_PATH, true); operation = new CreateFolderOperation(remotePath, createFullPath); - + } else if (action.equals(ACTION_SYNC_FILE)) { // Sync file String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH); @@ -626,9 +628,14 @@ public class OperationsService extends Service { // Move file/folder String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH); String newParentPath = operationIntent.getStringExtra(EXTRA_NEW_PARENT_PATH); - operation = new MoveFileOperation(remotePath,newParentPath,account); + operation = new MoveFileOperation(remotePath, newParentPath, account); + + } else if (action.equals(ACTION_COPY_FILE)) { + // Copy file/folder + String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH); + String newParentPath = operationIntent.getStringExtra(EXTRA_NEW_PARENT_PATH); + operation = new CopyFileOperation(remotePath, newParentPath, account); } - } } catch (IllegalArgumentException e) { @@ -642,11 +649,11 @@ public class OperationsService extends Service { return null; } } - + /** * Sends a broadcast when a new operation is added to the queue. - * + * * Local broadcasts are only delivered to activities in the same process, but can't be * done sticky :\ * @@ -656,43 +663,43 @@ public class OperationsService extends Service { private void sendBroadcastNewOperation(Target target, RemoteOperation operation) { Intent intent = new Intent(ACTION_OPERATION_ADDED); if (target.mAccount != null) { - intent.putExtra(EXTRA_ACCOUNT, target.mAccount); + intent.putExtra(EXTRA_ACCOUNT, target.mAccount); } else { - intent.putExtra(EXTRA_SERVER_URL, target.mServerUrl); + intent.putExtra(EXTRA_SERVER_URL, target.mServerUrl); } //LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this); //lbm.sendBroadcast(intent); sendStickyBroadcast(intent); } - + // TODO - maybe add a notification for real start of operations - + /** * Sends a LOCAL broadcast when an operations finishes in order to the interested activities c * an update their view * * Local broadcasts are only delivered to activities in the same process. - * - * @param target Account or URL pointing to an OC server. - * @param operation Finished operation. - * @param result Result of the operation. + * + * @param target Account or URL pointing to an OC server. + * @param operation Finished operation. + * @param result Result of the operation. */ private void sendBroadcastOperationFinished(Target target, RemoteOperation operation, RemoteOperationResult result) { Intent intent = new Intent(ACTION_OPERATION_FINISHED); intent.putExtra(EXTRA_RESULT, result); if (target.mAccount != null) { - intent.putExtra(EXTRA_ACCOUNT, target.mAccount); + intent.putExtra(EXTRA_ACCOUNT, target.mAccount); } else { - intent.putExtra(EXTRA_SERVER_URL, target.mServerUrl); + intent.putExtra(EXTRA_SERVER_URL, target.mServerUrl); } //LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this); //lbm.sendBroadcast(intent); sendStickyBroadcast(intent); } - + /** * Notifies the currently subscribed listeners about the end of an operation. * @@ -720,9 +727,9 @@ public class OperationsService extends Service { } if (count == 0) { //mOperationResults.put(operation.hashCode(), result); - Pair undispatched = + Pair undispatched = new Pair(operation, result); - mUndispatchedFinishedOperations.put(operation.hashCode(), undispatched); + mUndispatchedFinishedOperations.put(((Runnable) operation).hashCode(), undispatched); } Log_OC.d(TAG, "Called " + count + " listeners"); } diff --git a/src/com/owncloud/android/ui/activity/FileActivity.java b/src/com/owncloud/android/ui/activity/FileActivity.java index 80e9129f..3edd40c9 100644 --- a/src/com/owncloud/android/ui/activity/FileActivity.java +++ b/src/com/owncloud/android/ui/activity/FileActivity.java @@ -520,7 +520,7 @@ public class FileActivity extends AppCompatActivity */ private void swapToDefaultAccount() { // default to the most recently used account - Account newAccount = AccountUtils.getCurrentOwnCloudAccount(getApplicationContext()); + Account newAccount = AccountUtils.getCurrentOwnCloudAccount(getApplicationContext()); if (newAccount == null) { /// no account available: force account creation createFirstAccount(); @@ -612,7 +612,7 @@ public class FileActivity extends AppCompatActivity } /** - * @return 'True' when the Activity is finishing to enforce the setup of a new account. + * @return 'True' when the Activity is finishing to enforce the setup of a new account. */ protected boolean isRedirectingToSetupAccount() { return mRedirectingToSetupAccount; @@ -762,6 +762,7 @@ public class FileActivity extends AppCompatActivity } + private void onCreateShareOperationFinish(CreateShareOperation operation, RemoteOperationResult result) { dismissLoadingDialog(); @@ -867,7 +868,7 @@ public class FileActivity extends AppCompatActivity /** * Dismiss loading dialog */ - public void dismissLoadingDialog(){ + public void dismissLoadingDialog() { Fragment frag = getSupportFragmentManager().findFragmentByTag(DIALOG_WAIT_TAG); if (frag != null) { LoadingDialog loading = (LoadingDialog) frag; diff --git a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java index fdc78d75..1576a605 100644 --- a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java +++ b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java @@ -77,6 +77,7 @@ 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.CopyFileOperation; import com.owncloud.android.operations.CreateFolderOperation; import com.owncloud.android.operations.CreateShareOperation; import com.owncloud.android.operations.MoveFileOperation; @@ -134,6 +135,7 @@ public class FileDisplayActivity extends HookActivity public static final int ACTION_SELECT_CONTENT_FROM_APPS = 1; public static final int ACTION_SELECT_MULTIPLE_FILES = 2; public static final int ACTION_MOVE_FILES = 3; + public static final int ACTION_COPY_FILES = 4; private static final String TAG = FileDisplayActivity.class.getSimpleName(); @@ -141,7 +143,7 @@ public class FileDisplayActivity extends HookActivity private static final String TAG_SECOND_FRAGMENT = "SECOND_FRAGMENT"; private OCFile mWaitingToPreview; - + private boolean mSyncInProgress = false; private static String DIALOG_UNTRUSTED_CERT = "DIALOG_UNTRUSTED_CERT"; @@ -164,7 +166,7 @@ public class FileDisplayActivity extends HookActivity Intent initObserversIntent = FileObserverService.makeInitIntent(this); startService(initObserversIntent); } - + /// Load of saved instance state if(savedInstanceState != null) { mWaitingToPreview = (OCFile) savedInstanceState.getParcelable( @@ -177,13 +179,13 @@ public class FileDisplayActivity extends HookActivity mWaitingToPreview = null; mSyncInProgress = false; mWaitingToSend = null; - } + } /// USER INTERFACE // Inflate and set the layout view setContentView(R.layout.files); - + // Navigation Drawer initDrawer(); @@ -231,8 +233,8 @@ public class FileDisplayActivity extends HookActivity } /** - * Called when the ownCloud {@link Account} associated to the Activity was just updated. - */ + * Called when the ownCloud {@link Account} associated to the Activity was just updated. + */ @Override protected void onAccountSet(boolean stateWasRecovered) { super.onAccountSet(stateWasRecovered); @@ -271,7 +273,7 @@ public class FileDisplayActivity extends HookActivity if (file.isFolder()) { startSyncFolderOperation(file, false); } - + } else { updateFragmentsVisibility(!file.isFolder()); updateActionBarTitleAndHomeButton(file.isFolder() ? null : file); @@ -285,11 +287,11 @@ public class FileDisplayActivity extends HookActivity transaction.add(R.id.left_fragment_container, listOfFiles, TAG_LIST_OF_FILES); transaction.commit(); } - + private void initFragmentsWithFile() { if (getAccount() != null && getFile() != null) { /// First fragment - OCFileListFragment listOfFiles = getListOfFilesFragment(); + OCFileListFragment listOfFiles = getListOfFilesFragment(); if (listOfFiles != null) { listOfFiles.listDirectory(getCurrentDir()); // TODO Enable when "On Device" is recovered @@ -297,9 +299,9 @@ public class FileDisplayActivity extends HookActivity } else { Log_OC.e(TAG, "Still have a chance to lose the initializacion of list fragment >("); } - + /// Second fragment - OCFile file = getFile(); + OCFile file = getFile(); Fragment secondFragment = chooseInitialSecondFragment(file); if (secondFragment != null) { setSecondFragment(secondFragment); @@ -324,7 +326,7 @@ public class FileDisplayActivity extends HookActivity private Fragment chooseInitialSecondFragment(OCFile file) { Fragment secondFragment = null; if (file != null && !file.isFolder()) { - if (file.isDown() && PreviewMediaFragment.canBePreviewed(file) + if (file.isDown() && PreviewMediaFragment.canBePreviewed(file) && file.getLastSyncDateForProperties() > 0 // temporal fix ) { int startPlaybackPosition = @@ -345,10 +347,10 @@ public class FileDisplayActivity extends HookActivity /** * Replaces the second fragment managed by the activity with the received as * a parameter. - * - * Assumes never will be more than two fragments managed at the same time. - * - * @param fragment New second Fragment to set. + *

+ * Assumes never will be more than two fragments managed at the same time. + * + * @param fragment New second Fragment to set. */ private void setSecondFragment(Fragment fragment) { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); @@ -389,7 +391,7 @@ public class FileDisplayActivity extends HookActivity Fragment listOfFiles = getSupportFragmentManager().findFragmentByTag( FileDisplayActivity.TAG_LIST_OF_FILES); if (listOfFiles != null) { - return (OCFileListFragment)listOfFiles; + return (OCFileListFragment) listOfFiles; } Log_OC.wtf(TAG, "Access to unexisting list of files fragment!!"); return null; @@ -399,7 +401,7 @@ public class FileDisplayActivity extends HookActivity Fragment second = getSupportFragmentManager().findFragmentByTag( FileDisplayActivity.TAG_SECOND_FRAGMENT); if (second != null) { - return (FileFragment)second; + return (FileFragment) second; } return null; } @@ -637,17 +639,30 @@ public class FileDisplayActivity extends HookActivity requestMultipleUpload(data, resultCode); } else if (requestCode == ACTION_MOVE_FILES && resultCode == RESULT_OK){ + final Intent fData = data; + final int fResultCode = resultCode; + getHandler().postDelayed( + new Runnable() { + @Override + public void run() { + requestMoveOperation(fData, fResultCode); + } + }, + DELAY_TO_REQUEST_OPERATION_ON_ACTIVITY_RESULTS + ); + + } else if (requestCode == ACTION_COPY_FILES && resultCode == RESULT_OK) { final Intent fData = data; - final int fResultCode = resultCode; + final int fResultCode = resultCode; getHandler().postDelayed( - new Runnable() { - @Override - public void run() { - requestMoveOperation(fData, fResultCode); - } - }, - DELAY_TO_REQUEST_OPERATION_ON_ACTIVITY_RESULTS + new Runnable() { + @Override + public void run() { + requestCopyOperation(fData, fResultCode); + } + }, + DELAY_TO_REQUEST_OPERATION_ON_ACTIVITY_RESULTS ); } else { @@ -755,9 +770,9 @@ public class FileDisplayActivity extends HookActivity /** * Request the operation for moving the file/folder from one path to another - * - * @param data Intent received - * @param resultCode Result code received + * + * @param data Intent received + * @param resultCode Result code received */ private void requestMoveOperation(Intent data, int resultCode) { OCFile folderToMoveAt = (OCFile) data.getParcelableExtra(FolderPickerActivity.EXTRA_FOLDER); @@ -765,6 +780,18 @@ public class FileDisplayActivity extends HookActivity getFileOperationsHelper().moveFile(folderToMoveAt, targetFile); } + /** + * Request the operation for copying the file/folder from one path to another + * + * @param data Intent received + * @param resultCode Result code received + */ + private void requestCopyOperation(Intent data, int resultCode) { + OCFile folderToMoveAt = data.getParcelableExtra(FolderPickerActivity.EXTRA_FOLDER); + OCFile targetFile = data.getParcelableExtra(FolderPickerActivity.EXTRA_FILE); + getFileOperationsHelper().copyFile(folderToMoveAt, targetFile); + } + @Override public void onBackPressed() { if (!isDrawerOpen()){ @@ -802,7 +829,6 @@ public class FileDisplayActivity extends HookActivity Log_OC.v(TAG, "onSaveInstanceState() end"); } - @Override @@ -839,7 +865,7 @@ public class FileDisplayActivity extends HookActivity downloadIntentFilter.addAction(FileDownloader.getDownloadFinishMessage()); mDownloadFinishReceiver = new DownloadFinishReceiver(); registerReceiver(mDownloadFinishReceiver, downloadIntentFilter); - + Log_OC.v(TAG, "onResume() end"); } @@ -860,7 +886,7 @@ public class FileDisplayActivity extends HookActivity unregisterReceiver(mDownloadFinishReceiver); mDownloadFinishReceiver = null; } - + super.onPause(); Log_OC.v(TAG, "onPause() end"); } @@ -886,10 +912,10 @@ public class FileDisplayActivity extends HookActivity accountName.equals(getAccount().name) && getStorageManager() != null); if (sameAccount) { - + if (FileSyncAdapter.EVENT_FULL_SYNC_START.equals(event)) { mSyncInProgress = true; - + } else { OCFile currentFile = (getFile() == null) ? null : getStorageManager().getFileByPath(getFile().getRemotePath()); @@ -906,7 +932,7 @@ public class FileDisplayActivity extends HookActivity Toast.LENGTH_LONG) .show(); browseToRoot(); - + } else { if (currentFile == null && !getFile().isFolder()) { // currently selected file was removed in the server, and now we @@ -927,7 +953,7 @@ public class FileDisplayActivity extends HookActivity } setFile(currentFile); } - + mSyncInProgress = (!FileSyncAdapter.EVENT_FULL_SYNC_END.equals(event) && !RefreshFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED .equals(event)); @@ -935,11 +961,11 @@ public class FileDisplayActivity extends HookActivity if (RefreshFolderOperation.EVENT_SINGLE_FOLDER_CONTENTS_SYNCED. equals(event) && /// TODO refactor and make common - synchResult != null && !synchResult.isSuccess() && - (synchResult.getCode() == ResultCode.UNAUTHORIZED || - synchResult.isIdPRedirection() || - (synchResult.isException() && synchResult.getException() - instanceof AuthenticatorException))) { + synchResult != null && !synchResult.isSuccess() && + (synchResult.getCode() == ResultCode.UNAUTHORIZED || + synchResult.isIdPRedirection() || + (synchResult.isException() && synchResult.getException() + instanceof AuthenticatorException))) { try { @@ -979,9 +1005,9 @@ public class FileDisplayActivity extends HookActivity /*|| mRefreshSharesInProgress*/ //); setBackgroundText(); - + } - + if (synchResult != null) { if (synchResult.getCode().equals( RemoteOperationResult.ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED)) { @@ -995,7 +1021,7 @@ public class FileDisplayActivity extends HookActivity } } } - + /** * Show a text message on screen view for notifying user if content is * loading or folder is empty @@ -1020,7 +1046,8 @@ public class FileDisplayActivity extends HookActivity private class UploadFinishReceiver extends BroadcastReceiver { /** * Once the file upload has finished -> update view - * @author David A. Velasco + * + * @author David A. Velasco * {@link BroadcastReceiver} to enable upload feedback in UI */ @Override @@ -1030,23 +1057,23 @@ public class FileDisplayActivity extends HookActivity String accountName = intent.getStringExtra(FileUploader.ACCOUNT_NAME); boolean sameAccount = getAccount() != null && accountName.equals(getAccount().name); OCFile currentDir = getCurrentDir(); - boolean isDescendant = (currentDir != null) && (uploadedRemotePath != null) && + boolean isDescendant = (currentDir != null) && (uploadedRemotePath != null) && (uploadedRemotePath.startsWith(currentDir.getRemotePath())); - + if (sameAccount && isDescendant) { refreshListOfFilesFragment(); } - + boolean uploadWasFine = intent.getBooleanExtra(FileUploader.EXTRA_UPLOAD_RESULT, false); boolean renamedInUpload = getFile().getRemotePath(). equals(intent.getStringExtra(FileUploader.EXTRA_OLD_REMOTE_PATH)); - boolean sameFile = getFile().getRemotePath().equals(uploadedRemotePath) || + boolean sameFile = getFile().getRemotePath().equals(uploadedRemotePath) || renamedInUpload; FileFragment details = getSecondFragment(); - boolean detailFragmentIsShown = (details != null && + boolean detailFragmentIsShown = (details != null && details instanceof FileDetailFragment); - + if (sameAccount && sameFile && detailFragmentIsShown) { if (uploadWasFine) { setFile(getStorageManager().getFileByPath(uploadedRemotePath)); @@ -1054,19 +1081,19 @@ public class FileDisplayActivity extends HookActivity if (renamedInUpload) { String newName = (new File(uploadedRemotePath)).getName(); Toast msg = Toast.makeText( - context, + context, String.format( - getString(R.string.filedetails_renamed_in_upload_msg), - newName), + getString(R.string.filedetails_renamed_in_upload_msg), + newName), Toast.LENGTH_LONG); msg.show(); } if (uploadWasFine || getFile().fileExists()) { - ((FileDetailFragment)details).updateFileDetails(false, true); + ((FileDetailFragment) details).updateFileDetails(false, true); } else { cleanSecondFragment(); } - + // Force the preview if the file is an image if (uploadWasFine && PreviewImageFragment.canBePreviewed(getFile())) { startImagePreview(getFile()); @@ -1079,15 +1106,15 @@ public class FileDisplayActivity extends HookActivity removeStickyBroadcast(intent); } } - + } - + } /** * Class waiting for broadcast events from the {@link FileDownloader} service. - * + * * Updates the UI when a download is started or finished, provided that it is relevant for the * current folder. */ @@ -1115,7 +1142,7 @@ public class FileDisplayActivity extends HookActivity intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false) ); } - + if (mWaitingToSend != null) { mWaitingToSend = getStorageManager().getFileByPath(mWaitingToSend.getRemotePath()); @@ -1123,7 +1150,7 @@ public class FileDisplayActivity extends HookActivity sendDownloadedFile(); } } - + } finally { if (intent != null) { removeStickyBroadcast(intent); @@ -1154,10 +1181,10 @@ public class FileDisplayActivity extends HookActivity accountName.equals(getAccount().name)); } } - - + + public void browseToRoot() { - OCFileListFragment listOfFiles = getListOfFilesFragment(); + OCFileListFragment listOfFiles = getListOfFilesFragment(); if (listOfFiles != null) { // should never be null, indeed OCFile root = getStorageManager().getFileByPath(OCFile.ROOT_PATH); listOfFiles.listDirectory(root); @@ -1173,7 +1200,7 @@ public class FileDisplayActivity extends HookActivity /** * {@inheritDoc} - * + *

* Updates action bar and second fragment, if in dual pane mode. */ @Override @@ -1185,10 +1212,10 @@ public class FileDisplayActivity extends HookActivity } /** - * Shows the information of the {@link OCFile} received as a + * Shows the information of the {@link OCFile} received as a * parameter in the second fragment. - * - * @param file {@link OCFile} whose details will be shown + * + * @param file {@link OCFile} whose details will be shown */ @Override public void showDetails(OCFile file) { @@ -1216,7 +1243,9 @@ public class FileDisplayActivity extends HookActivity return new ListServiceConnection(); } - /** Defines callbacks for service binding, passed to bindService() */ + /** + * Defines callbacks for service binding, passed to bindService() + */ private class ListServiceConnection implements ServiceConnection { @Override @@ -1233,7 +1262,7 @@ public class FileDisplayActivity extends HookActivity if (!mWaitingToPreview.isDown()) { requestForDownload(); } - } + } } else if (component.equals(new ComponentName(FileDisplayActivity.this, FileUploader.class))) { @@ -1252,7 +1281,7 @@ public class FileDisplayActivity extends HookActivity } FileFragment secondFragment = getSecondFragment(); if (secondFragment != null && secondFragment instanceof FileDetailFragment) { - FileDetailFragment detailFragment = (FileDetailFragment)secondFragment; + FileDetailFragment detailFragment = (FileDetailFragment) secondFragment; detailFragment.listenForTransferProgress(); detailFragment.updateFileDetails(false, false); } @@ -1270,7 +1299,7 @@ public class FileDisplayActivity extends HookActivity mUploaderBinder = null; } } - }; + } @Override public void onSavedCertificate() { @@ -1294,39 +1323,42 @@ public class FileDisplayActivity extends HookActivity /** * Updates the view associated to the activity after the finish of some operation over files * in the current account. - * - * @param operation Removal operation performed. - * @param result Result of the removal. + * + * @param operation Removal operation performed. + * @param result Result of the removal. */ @Override public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) { super.onRemoteOperationFinish(operation, result); - + if (operation instanceof RemoveFileOperation) { onRemoveFileOperationFinish((RemoveFileOperation) operation, result); } else if (operation instanceof RenameFileOperation) { - onRenameFileOperationFinish((RenameFileOperation)operation, result); + onRenameFileOperationFinish((RenameFileOperation) operation, result); } else if (operation instanceof SynchronizeFileOperation) { - onSynchronizeFileOperationFinish((SynchronizeFileOperation)operation, result); + onSynchronizeFileOperationFinish((SynchronizeFileOperation) operation, result); } else if (operation instanceof CreateFolderOperation) { - onCreateFolderOperationFinish((CreateFolderOperation)operation, result); - + onCreateFolderOperationFinish((CreateFolderOperation) operation, result); + } else if (operation instanceof CreateShareOperation) { onCreateShareOperationFinish((CreateShareOperation) operation, result); - + } else if (operation instanceof UnshareLinkOperation) { - onUnshareLinkOperationFinish((UnshareLinkOperation)operation, result); - + onUnshareLinkOperationFinish((UnshareLinkOperation) operation, result); + } else if (operation instanceof MoveFileOperation) { - onMoveFileOperationFinish((MoveFileOperation)operation, result); + onMoveFileOperationFinish((MoveFileOperation) operation, result); + + } else if (operation instanceof CopyFileOperation) { + onCopyFileOperationFinish((CopyFileOperation) operation, result); } - + } - + private void onCreateShareOperationFinish(CreateShareOperation operation, RemoteOperationResult result) { if (result.isSuccess()) { @@ -1335,36 +1367,36 @@ public class FileDisplayActivity extends HookActivity } } - + private void onUnshareLinkOperationFinish(UnshareLinkOperation 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) { OCFile file = details.getFile(); if (file != null) { - file = getStorageManager().getFileByPath(file.getRemotePath()); + file = getStorageManager().getFileByPath(file.getRemotePath()); if (details instanceof PreviewMediaFragment) { // Refresh OCFile of the fragment ((PreviewMediaFragment) details).updateFile(file); } else { showDetails(file); - } + } } invalidateOptionsMenu(); - } + } } - + /** * Updates the view associated to the activity after the finish of an operation trying to * remove a file. @@ -1375,18 +1407,18 @@ public class FileDisplayActivity extends HookActivity private void onRemoveFileOperationFinish(RemoveFileOperation operation, RemoteOperationResult result) { dismissLoadingDialog(); - + Toast msg = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), Toast.LENGTH_LONG); msg.show(); - + if (result.isSuccess()) { OCFile removedFile = operation.getFile(); FileFragment second = getSecondFragment(); if (second != null && removedFile.equals(second.getFile())) { if (second instanceof PreviewMediaFragment) { - ((PreviewMediaFragment)second).stopPreview(true); + ((PreviewMediaFragment) second).stopPreview(true); } setFile(getStorageManager().getFileById(removedFile.getParentId())); cleanSecondFragment(); @@ -1402,14 +1434,14 @@ public class FileDisplayActivity extends HookActivity } } } - - + + /** - * Updates the view associated to the activity after the finish of an operation trying to move a + * Updates the view associated to the activity after the finish of an operation trying to move a * file. - * - * @param operation Move operation performed. - * @param result Result of the move operation. + * + * @param operation Move operation performed. + * @param result Result of the move operation. */ private void onMoveFileOperationFinish(MoveFileOperation operation, RemoteOperationResult result) { @@ -1419,17 +1451,41 @@ public class FileDisplayActivity extends HookActivity } else { dismissLoadingDialog(); try { - Toast msg = Toast.makeText(FileDisplayActivity.this, - ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), - Toast.LENGTH_LONG); + Toast msg = Toast.makeText(FileDisplayActivity.this, + ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), + Toast.LENGTH_LONG); msg.show(); } catch (NotFoundException e) { - Log_OC.e(TAG, "Error while trying to show fail message " , e); + Log_OC.e(TAG, "Error while trying to show fail message ", e); } } } + /** + * Updates the view associated to the activity after the finish of an operation trying to copy a + * file. + * + * @param operation Copy operation performed. + * @param result Result of the copy operation. + */ + private void onCopyFileOperationFinish(CopyFileOperation operation, RemoteOperationResult result) { + if (result.isSuccess()) { + dismissLoadingDialog(); + refreshListOfFilesFragment(); + } else { + dismissLoadingDialog(); + try { + Toast msg = Toast.makeText(FileDisplayActivity.this, + ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), + Toast.LENGTH_LONG); + msg.show(); + + } catch (NotFoundException e) { + Log_OC.e(TAG, "Error while trying to show fail message ", e); + } + } + } /** * Updates the view associated to the activity after the finish of an operation trying to rename @@ -1454,14 +1510,14 @@ public class FileDisplayActivity extends HookActivity renamedFile.equals(details.getFile())) { ((PreviewMediaFragment) details).updateFile(renamedFile); if (PreviewMediaFragment.canBePreviewed(renamedFile)) { - int position = ((PreviewMediaFragment)details).getPosition(); + int position = ((PreviewMediaFragment) details).getPosition(); startMediaPreview(renamedFile, position, true); } else { getFileOperationsHelper().openFile(renamedFile); } } } - + if (getStorageManager().getFileById(renamedFile.getParentId()).equals(getCurrentDir())){ refreshListOfFilesFragment(); } @@ -1471,7 +1527,7 @@ public class FileDisplayActivity extends HookActivity ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), Toast.LENGTH_LONG); msg.show(); - + if (result.isSslRecoverableException()) { mLastSslUntrustedServerResult = result; showUntrustedCertDialog(mLastSslUntrustedServerResult); @@ -1505,18 +1561,18 @@ public class FileDisplayActivity extends HookActivity } else { dismissLoadingDialog(); try { - Toast msg = Toast.makeText(FileDisplayActivity.this, - ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), - Toast.LENGTH_LONG); + Toast msg = Toast.makeText(FileDisplayActivity.this, + ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), + Toast.LENGTH_LONG); msg.show(); } catch (NotFoundException e) { - Log_OC.e(TAG, "Error while trying to show fail message " , e); + Log_OC.e(TAG, "Error while trying to show fail message ", e); } } } - + /** * {@inheritDoc} */ @@ -1527,16 +1583,16 @@ public class FileDisplayActivity extends HookActivity if (details != null && details instanceof FileDetailFragment && file.equals(details.getFile()) ) { if (downloading || uploading) { - ((FileDetailFragment)details).updateFileDetails(file, getAccount()); + ((FileDetailFragment) details).updateFileDetails(file, getAccount()); } else { if (!file.fileExists()) { cleanSecondFragment(); } else { - ((FileDetailFragment)details).updateFileDetails(false, true); + ((FileDetailFragment) details).updateFileDetails(false, true); } } } - + } @@ -1565,12 +1621,12 @@ public class FileDisplayActivity extends HookActivity } return null; } - + public void startSyncFolderOperation(OCFile folder, boolean ignoreETag) { - long currentSyncTime = System.currentTimeMillis(); - + long currentSyncTime = System.currentTimeMillis(); + mSyncInProgress = true; - + // perform folder synchronization RemoteOperation synchFolderOp = new RefreshFolderOperation( folder, currentSyncTime, @@ -1588,7 +1644,7 @@ public class FileDisplayActivity extends HookActivity } /** - * Show untrusted cert dialog + * Show untrusted cert dialog */ public void showUntrustedCertDialog(RemoteOperationResult result) { // Show a dialog with the certificate info @@ -1598,7 +1654,7 @@ public class FileDisplayActivity extends HookActivity FragmentTransaction ft = fm.beginTransaction(); dialog.show(ft, DIALOG_UNTRUSTED_CERT); } - + private void requestForDownload(OCFile file) { Account account = getAccount(); if (!mDownloaderBinder.isDownloading(account, mWaitingToPreview)) { @@ -1608,43 +1664,43 @@ public class FileDisplayActivity extends HookActivity startService(i); } } - - private void sendDownloadedFile(){ + + private void sendDownloadedFile() { getFileOperationsHelper().sendDownloadedFile(mWaitingToSend); mWaitingToSend = null; } - + /** * Requests the download of the received {@link OCFile} , updates the UI * to monitor the download progress and prepares the activity to send the file * when the download finishes. - * - * @param file {@link OCFile} to download and preview. + * + * @param file {@link OCFile} to download and preview. */ public void startDownloadForSending(OCFile file) { mWaitingToSend = file; requestForDownload(mWaitingToSend); - boolean hasSecondFragment = (getSecondFragment()!= null); + boolean hasSecondFragment = (getSecondFragment() != null); updateFragmentsVisibility(hasSecondFragment); } - + /** * Opens the image gallery showing the image {@link OCFile} received as parameter. - * - * @param file Image {@link OCFile} to show. + * + * @param file Image {@link OCFile} to show. */ public void startImagePreview(OCFile file) { Intent showDetailsIntent = new Intent(this, PreviewImageActivity.class); showDetailsIntent.putExtra(EXTRA_FILE, file); showDetailsIntent.putExtra(EXTRA_ACCOUNT, getAccount()); startActivity(showDetailsIntent); - + } /** * Stars the preview of an already down media {@link OCFile}. - * + * * @param file Media {@link OCFile} to preview. * @param startPlaybackPosition Media position where the playback will be started, * in milliseconds. @@ -1664,8 +1720,8 @@ public class FileDisplayActivity extends HookActivity * Requests the download of the received {@link OCFile} , updates the UI * to monitor the download progress and prepares the activity to preview * or open the file when the download finishes. - * - * @param file {@link OCFile} to download and preview. + * + * @param file {@link OCFile} to download and preview. */ public void startDownloadForPreview(OCFile file) { Fragment detailFragment = FileDetailFragment.newInstance(file, getAccount()); @@ -1680,7 +1736,7 @@ public class FileDisplayActivity extends HookActivity public void cancelTransference(OCFile file) { getFileOperationsHelper().cancelTransference(file); - if (mWaitingToPreview != null && + if (mWaitingToPreview != null && mWaitingToPreview.getRemotePath().equals(file.getRemotePath())) { mWaitingToPreview = null; } @@ -1713,15 +1769,15 @@ public class FileDisplayActivity extends HookActivity } } - private void sortByDate(boolean ascending){ + private void sortByDate(boolean ascending) { getListOfFilesFragment().sortByDate(ascending); } - private void sortBySize(boolean ascending){ + private void sortBySize(boolean ascending) { getListOfFilesFragment().sortBySize(ascending); } - private void sortByName(boolean ascending){ + private void sortByName(boolean ascending) { getListOfFilesFragment().sortByName(ascending); } diff --git a/src/com/owncloud/android/ui/activity/Uploader.java b/src/com/owncloud/android/ui/activity/Uploader.java index 7bea4bb3..d221bc92 100644 --- a/src/com/owncloud/android/ui/activity/Uploader.java +++ b/src/com/owncloud/android/ui/activity/Uploader.java @@ -57,6 +57,8 @@ import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v7.app.ActionBar; +import android.view.Menu; +import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; @@ -361,9 +363,8 @@ public class Uploader extends FileActivity break; - case R.id.uploader_new_folder: - CreateFolderDialogFragment dialog = CreateFolderDialogFragment.newInstance(mFile); - dialog.show(getSupportFragmentManager(), "createdirdialog"); + case R.id.uploader_cancel: + finish(); break; @@ -437,7 +438,7 @@ public class Uploader extends FileActivity Button btnChooseFolder = (Button) findViewById(R.id.uploader_choose_folder); btnChooseFolder.setOnClickListener(this); - Button btnNewFolder = (Button) findViewById(R.id.uploader_new_folder); + Button btnNewFolder = (Button) findViewById(R.id.uploader_cancel); btnNewFolder.setOnClickListener(this); mListView.setOnItemClickListener(this); @@ -653,11 +654,26 @@ public class Uploader extends FileActivity } } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.main_menu, menu); + menu.findItem(R.id.action_upload).setVisible(false); + menu.findItem(R.id.action_sort).setVisible(false); + menu.findItem(R.id.action_sync_account).setVisible(false); + return true; + } @Override public boolean onOptionsItemSelected(MenuItem item) { boolean retval = true; switch (item.getItemId()) { + case R.id.action_create_dir: + CreateFolderDialogFragment dialog = CreateFolderDialogFragment.newInstance(mFile); + dialog.show( + getSupportFragmentManager(), + CreateFolderDialogFragment.CREATE_FOLDER_FRAGMENT); + break; case android.R.id.home: if((mParents.size() > 1)) { onBackPressed(); diff --git a/src/com/owncloud/android/ui/adapter/FileListListAdapter.java b/src/com/owncloud/android/ui/adapter/FileListListAdapter.java index f839c23b..c2639a8c 100644 --- a/src/com/owncloud/android/ui/adapter/FileListListAdapter.java +++ b/src/com/owncloud/android/ui/adapter/FileListListAdapter.java @@ -4,6 +4,7 @@ * @author Bartek Przybylski * @author Tobias Kaminsky * @author David A. Velasco + * @author masensio * Copyright (C) 2011 Bartek Przybylski * Copyright (C) 2015 ownCloud Inc. * @@ -323,6 +324,13 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter { task.execute(file); } } + + if (file.getMimetype().equalsIgnoreCase("image/png")) { + fileIcon.setBackgroundColor(mContext.getResources() + .getColor(R.color.background_color)); + } + + } else { fileIcon.setImageResource(DisplayUtils.getFileTypeIconId(file.getMimetype(), file.getFileName())); @@ -330,6 +338,7 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter { } else { // Folder + if (checkIfFileIsSharedWithMe(file)) { fileIcon.setImageResource(R.drawable.shared_with_me_folder); } else if (file.isShareByLink()) { diff --git a/src/com/owncloud/android/ui/fragment/ExtendedListFragment.java b/src/com/owncloud/android/ui/fragment/ExtendedListFragment.java index 5f9e7e4b..2ca2cc3b 100644 --- a/src/com/owncloud/android/ui/fragment/ExtendedListFragment.java +++ b/src/com/owncloud/android/ui/fragment/ExtendedListFragment.java @@ -79,8 +79,8 @@ public class ExtendedListFragment extends Fragment private ArrayList mTops; private int mHeightCell = 0; - private OnEnforceableRefreshListener mOnRefreshListener = null; - + private SwipeRefreshLayout.OnRefreshListener mOnRefreshListener = null; + protected AbsListView mCurrentListView; private ExtendedListView mListView; private View mListFooterView; @@ -397,7 +397,7 @@ public class ExtendedListFragment extends Fragment mRefreshEmptyLayout.setRefreshing(false); if (mOnRefreshListener != null) { - mOnRefreshListener.onRefresh(ignoreETag); + mOnRefreshListener.onRefresh(); } } diff --git a/src/com/owncloud/android/ui/fragment/FileDetailFragment.java b/src/com/owncloud/android/ui/fragment/FileDetailFragment.java index 68ee6771..24f7248f 100644 --- a/src/com/owncloud/android/ui/fragment/FileDetailFragment.java +++ b/src/com/owncloud/android/ui/fragment/FileDetailFragment.java @@ -21,10 +21,7 @@ */ package com.owncloud.android.ui.fragment; -import java.lang.ref.WeakReference; - import android.accounts.Account; -import android.content.Intent; import android.os.Bundle; import android.view.LayoutInflater; import android.view.Menu; @@ -46,13 +43,14 @@ import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder; import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; import com.owncloud.android.lib.common.network.OnDatatransferProgressListener; import com.owncloud.android.lib.common.utils.Log_OC; -import com.owncloud.android.services.observer.FileObserverService; import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.ui.activity.FileDisplayActivity; import com.owncloud.android.ui.dialog.RemoveFileDialogFragment; import com.owncloud.android.ui.dialog.RenameFileDialogFragment; import com.owncloud.android.utils.DisplayUtils; +import java.lang.ref.WeakReference; + /** * This Fragment is used to display the details about a file. @@ -62,9 +60,9 @@ public class FileDetailFragment extends FileFragment implements OnClickListener private int mLayout; private View mView; private Account mAccount; - + public ProgressListener mProgressListener; - + private static final String TAG = FileDetailFragment.class.getSimpleName(); public static final String FTAG_CONFIRMATION = "REMOVE_CONFIRMATION_FRAGMENT"; public static final String FTAG_RENAME_FILE = "RENAME_FILE_FRAGMENT"; @@ -103,14 +101,14 @@ public class FileDetailFragment extends FileFragment implements OnClickListener mLayout = R.layout.file_details_empty; mProgressListener = null; } - + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); } - + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -120,14 +118,14 @@ public class FileDetailFragment extends FileFragment implements OnClickListener mAccount = getArguments().getParcelable(ARG_ACCOUNT); if (savedInstanceState != null) { - setFile((OCFile)savedInstanceState.getParcelable(FileActivity.EXTRA_FILE)); + setFile((OCFile) savedInstanceState.getParcelable(FileActivity.EXTRA_FILE)); mAccount = savedInstanceState.getParcelable(FileActivity.EXTRA_ACCOUNT); } - - if(getFile() != null && mAccount != null) { + + if (getFile() != null && mAccount != null) { mLayout = R.layout.file_details_fragment; } - + mView = inflater.inflate(mLayout, null); if (mLayout == R.layout.file_details_fragment) { @@ -154,20 +152,20 @@ public class FileDetailFragment extends FileFragment implements OnClickListener super.onStart(); listenForTransferProgress(); } - + @Override public void onStop() { leaveTransferProgress(); super.onStop(); } - + @Override public View getView() { return super.getView() == null ? mView : super.getView(); } - + /** * {@inheritDoc} */ @@ -175,16 +173,16 @@ public class FileDetailFragment extends FileFragment implements OnClickListener public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.file_actions_menu, menu); - } + } + - /** * {@inheritDoc} */ @Override - public void onPrepareOptionsMenu (Menu menu) { + public void onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); - + if (mContainerActivity.getStorageManager() != null) { FileMenuFilter mf = new FileMenuFilter( getFile(), @@ -194,7 +192,7 @@ public class FileDetailFragment extends FileFragment implements OnClickListener ); mf.filter(menu); } - + // additional restriction for this fragment MenuItem item = menu.findItem(R.id.action_see_details); if (item != null) { @@ -208,9 +206,16 @@ public class FileDetailFragment extends FileFragment implements OnClickListener item.setVisible(false); item.setEnabled(false); } + + // additional restriction for this fragment + item = menu.findItem(R.id.action_copy); + if (item != null) { + item.setVisible(false); + item.setEnabled(false); + } } - + /** * {@inheritDoc} */ @@ -241,10 +246,10 @@ public class FileDetailFragment extends FileFragment implements OnClickListener } case R.id.action_cancel_download: case R.id.action_cancel_upload: { - ((FileDisplayActivity)mContainerActivity).cancelTransference(getFile()); + ((FileDisplayActivity) mContainerActivity).cancelTransference(getFile()); return true; } - case R.id.action_download_file: + case R.id.action_download_file: case R.id.action_sync_file: { mContainerActivity.getFileOperationsHelper().syncFile(getFile()); return true; @@ -253,9 +258,10 @@ public class FileDetailFragment extends FileFragment implements OnClickListener // Obtain the file if (!getFile().isDown()) { // Download the file Log_OC.d(TAG, getFile().getRemotePath() + " : File must be downloaded"); - ((FileDisplayActivity)mContainerActivity).startDownloadForSending(getFile()); - - } else { + ((FileDisplayActivity) mContainerActivity).startDownloadForSending(getFile()); + + } + else { mContainerActivity.getFileOperationsHelper().sendDownloadedFile(getFile()); } return true; @@ -282,7 +288,7 @@ public class FileDetailFragment extends FileFragment implements OnClickListener break; } case R.id.fdCancelBtn: { - ((FileDisplayActivity)mContainerActivity).cancelTransference(getFile()); + ((FileDisplayActivity) mContainerActivity).cancelTransference(getFile()); break; } default: @@ -293,17 +299,17 @@ public class FileDetailFragment extends FileFragment implements OnClickListener /** * Check if the fragment was created with an empty layout. An empty fragment can't show file details, must be replaced. - * - * @return True when the fragment was created with the empty layout. + * + * @return True when the fragment was created with the empty layout. */ public boolean isEmpty() { return (mLayout == R.layout.file_details_empty || getFile() == null || mAccount == null); } - + /** * Use this method to signal this Activity that it shall update its view. - * + * * @param file : An {@link OCFile} */ public void updateFileDetails(OCFile file, Account ocAccount) { @@ -314,14 +320,13 @@ public class FileDetailFragment extends FileFragment implements OnClickListener /** * Updates the view with all relevant details about that file. + *

+ * TODO Remove parameter when the transferring state of files is kept in database. * - * TODO Remove parameter when the transferring state of files is kept in database. - * - * @param transferring Flag signaling if the file should be considered as downloading or uploading, - * although {@link FileDownloaderBinder#isDownloading(Account, OCFile)} and - * {@link FileUploaderBinder#isUploading(Account, OCFile)} return false. - * - * @param refresh If 'true', try to refresh the whole file from the database + * @param transferring Flag signaling if the file should be considered as downloading or uploading, + * although {@link FileDownloaderBinder#isDownloading(Account, OCFile)} and + * {@link FileUploaderBinder#isUploading(Account, OCFile)} return false. + * @param refresh If 'true', try to refresh the whole file from the database */ public void updateFileDetails(boolean transferring, boolean refresh) { if (readyToShow()) { @@ -330,7 +335,7 @@ public class FileDetailFragment extends FileFragment implements OnClickListener setFile(storageManager.getFileByPath(getFile().getRemotePath())); } OCFile file = getFile(); - + // set file details setFilename(file.getFileName()); setFiletype(file.getMimetype(), file.getFileName()); @@ -349,7 +354,7 @@ public class FileDetailFragment extends FileFragment implements OnClickListener (uploaderBinder != null && uploaderBinder.isUploading(mAccount, file)) ) { setButtonsForTransferring(); - + } else if (file.isDown()) { setButtonsForDown(); @@ -362,25 +367,27 @@ public class FileDetailFragment extends FileFragment implements OnClickListener } getView().invalidate(); } - + /** * Checks if the fragment is ready to show details of a OCFile - * - * @return 'True' when the fragment is ready to show details of a file + * + * @return 'True' when the fragment is ready to show details of a file */ private boolean readyToShow() { - return (getFile() != null && mAccount != null && mLayout == R.layout.file_details_fragment); + return (getFile() != null && mAccount != null && mLayout == R.layout.file_details_fragment); } /** * Updates the filename in view + * * @param filename to set */ private void setFilename(String filename) { TextView tv = (TextView) getView().findViewById(R.id.fdFilename); - if (tv != null) + if (tv != null) { tv.setText(filename); + } } /** @@ -402,25 +409,28 @@ public class FileDetailFragment extends FileFragment implements OnClickListener /** * Updates the file size in view + * * @param filesize in bytes to set */ private void setFilesize(long filesize) { TextView tv = (TextView) getView().findViewById(R.id.fdSize); - if (tv != null) + if (tv != null) { tv.setText(DisplayUtils.bytesToHumanReadable(filesize)); + } } - + /** * Updates the time that the file was last modified + * * @param milliseconds Unix time to set */ - private void setTimeModified(long milliseconds){ + private void setTimeModified(long milliseconds) { TextView tv = (TextView) getView().findViewById(R.id.fdModified); - if(tv != null){ + if (tv != null) { tv.setText(DisplayUtils.unixTimeToHumanReadable(milliseconds)); } } - + /** * Enables or disables buttons for a file being downloaded */ @@ -431,21 +441,24 @@ public class FileDetailFragment extends FileFragment implements OnClickListener // show the progress bar for the transfer getView().findViewById(R.id.fdProgressBlock).setVisibility(View.VISIBLE); - TextView progressText = (TextView)getView().findViewById(R.id.fdProgressText); + TextView progressText = (TextView) getView().findViewById(R.id.fdProgressText); progressText.setVisibility(View.VISIBLE); FileDownloaderBinder downloaderBinder = mContainerActivity.getFileDownloaderBinder(); FileUploaderBinder uploaderBinder = mContainerActivity.getFileUploaderBinder(); //if (getFile().isDownloading()) { if (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, getFile())) { progressText.setText(R.string.downloader_download_in_progress_ticker); - } else if (uploaderBinder != null && uploaderBinder.isUploading(mAccount, getFile())) { - progressText.setText(R.string.uploader_upload_in_progress_ticker); + } + else { + if (uploaderBinder != null && uploaderBinder.isUploading(mAccount, getFile())) { + progressText.setText(R.string.uploader_upload_in_progress_ticker); + } } } } /** - * Enables or disables buttons for a file locally available + * Enables or disables buttons for a file locally available */ private void setButtonsForDown() { if (!isEmpty()) { @@ -453,13 +466,13 @@ public class FileDetailFragment extends FileFragment implements OnClickListener // hides the progress bar getView().findViewById(R.id.fdProgressBlock).setVisibility(View.GONE); - TextView progressText = (TextView)getView().findViewById(R.id.fdProgressText); + TextView progressText = (TextView) getView().findViewById(R.id.fdProgressText); progressText.setVisibility(View.GONE); } } /** - * Enables or disables buttons for a file not locally available + * Enables or disables buttons for a file not locally available */ private void setButtonsForRemote() { if (!isEmpty()) { @@ -467,11 +480,11 @@ public class FileDetailFragment extends FileFragment implements OnClickListener // hides the progress bar getView().findViewById(R.id.fdProgressBlock).setVisibility(View.GONE); - TextView progressText = (TextView)getView().findViewById(R.id.fdProgressText); + TextView progressText = (TextView) getView().findViewById(R.id.fdProgressText); progressText.setVisibility(View.GONE); } } - + public void listenForTransferProgress() { if (mProgressListener != null) { @@ -485,8 +498,8 @@ public class FileDetailFragment extends FileFragment implements OnClickListener } } } - - + + public void leaveTransferProgress() { if (mProgressListener != null) { if (mContainerActivity.getFileDownloaderBinder() != null) { @@ -501,7 +514,6 @@ public class FileDetailFragment extends FileFragment implements OnClickListener } - /** * Helper class responsible for updating the progress bar shown for file uploading or * downloading @@ -509,11 +521,11 @@ public class FileDetailFragment extends FileFragment implements OnClickListener private class ProgressListener implements OnDatatransferProgressListener { int mLastPercent = 0; WeakReference mProgressBar = null; - + ProgressListener(ProgressBar progressBar) { mProgressBar = new WeakReference(progressBar); } - + @Override public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String filename) { diff --git a/src/com/owncloud/android/ui/fragment/OCFileListFragment.java b/src/com/owncloud/android/ui/fragment/OCFileListFragment.java index 146d0ba2..8d76e3aa 100644 --- a/src/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/src/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -22,26 +22,19 @@ */ package com.owncloud.android.ui.fragment; -import java.io.File; - import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.support.v4.widget.SwipeRefreshLayout; import android.view.ContextMenu; -import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; -import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.AdapterContextMenuInfo; -import android.widget.ListView; import android.widget.PopupMenu; -import android.widget.Toast; -import com.getbase.floatingactionbutton.FloatingActionsMenu; import com.owncloud.android.R; import com.owncloud.android.authentication.AccountUtils; import com.owncloud.android.datamodel.FileDataStorageManager; @@ -60,12 +53,14 @@ import com.owncloud.android.ui.dialog.RemoveFileDialogFragment; import com.owncloud.android.ui.dialog.RenameFileDialogFragment; import com.owncloud.android.ui.preview.PreviewImageFragment; import com.owncloud.android.ui.preview.PreviewMediaFragment; -import com.owncloud.android.utils.DialogMenuItem; import com.owncloud.android.utils.FileStorageUtils; +import java.io.File; +import java.util.Vector; + /** * A Fragment that lists all files and folders in a given path. - * + * * TODO refactor to get rid of direct dependency on FileDisplayActivity */ public class OCFileListFragment extends ExtendedListFragment implements FileActionsDialogFragment.FileActionsDialogFragmentListener { @@ -74,14 +69,14 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi private static final String MY_PACKAGE = OCFileListFragment.class.getPackage() != null ? OCFileListFragment.class.getPackage().getName() : "com.owncloud.android.ui.fragment"; - + public final static String ARG_JUST_FOLDERS = MY_PACKAGE + ".JUST_FOLDERS"; public final static String ARG_ALLOW_CONTEXTUAL_ACTIONS = MY_PACKAGE + ".ALLOW_CONTEXTUAL"; - + private static final String KEY_FILE = MY_PACKAGE + ".extra.FILE"; private FileFragment.ContainerActivity mContainerActivity; - + private OCFile mFile = null; private FileListListAdapter mAdapter; private boolean mJustFolders; @@ -99,58 +94,21 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi Log_OC.e(TAG, "onAttach"); try { mContainerActivity = (FileFragment.ContainerActivity) activity; - + } catch (ClassCastException e) { - throw new ClassCastException(activity.toString() + " must implement " + + throw new ClassCastException(activity.toString() + " must implement " + FileFragment.ContainerActivity.class.getSimpleName()); } try { setOnRefreshListener((OnEnforceableRefreshListener) activity); } catch (ClassCastException e) { - throw new ClassCastException(activity.toString() + " must implement " + + throw new ClassCastException(activity.toString() + " must implement " + SwipeRefreshLayout.OnRefreshListener.class.getSimpleName()); } } - /** - * {@inheritDoc} - */ - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - Log_OC.i(TAG, "onCreateView() start"); - View v = super.onCreateView(inflater, container, savedInstanceState); - - // Setup FAB listeners - getFabUpload().setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - ((FileDisplayActivity)getActivity()).uploadLocalFilesSelected(); - getFabMain().collapse(); - } - }); - - getFabMkdir().setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - ((FileDisplayActivity) getActivity()).createFolder(); - getFabMain().collapse(); - } - }); - getFabUploadFromApp().setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - ((FileDisplayActivity) getActivity()).uploadFromOtherAppsSelected(); - getFabMain().collapse(); - } - }); - - Log_OC.i(TAG, "onCreateView() end"); - return v; - } - - @Override public void onDetach() { setOnRefreshListener(null); @@ -182,7 +140,7 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi mJustFolders, getActivity(), mContainerActivity - ); + ); setListAdapter(mAdapter); registerLongClickListener(); @@ -245,31 +203,31 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi * Saves the current listed folder. */ @Override - public void onSaveInstanceState (Bundle outState) { + public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putParcelable(KEY_FILE, mFile); } - + /** * Call this, when the user presses the up button. - * + * * Tries to move up the current folder one level. If the parent folder was removed from the * database, it continues browsing up until finding an existing folders. - * + *

* return Count of folder levels browsed up. */ public int onBrowseUp() { OCFile parentDir = null; int moveCount = 0; - - if(mFile != null){ + + if (mFile != null) { FileDataStorageManager storageManager = mContainerActivity.getStorageManager(); - + String parentPath = null; if (mFile.getParentId() != FileDataStorageManager.ROOT_PARENT_ID) { parentPath = new File(mFile.getRemotePath()).getParent(); - parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : - parentPath + OCFile.PATH_SEPARATOR; + parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : + parentPath + OCFile.PATH_SEPARATOR; parentDir = storageManager.getFileByPath(parentPath); moveCount++; } else { @@ -277,8 +235,8 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi } while (parentDir == null) { parentPath = new File(parentPath).getParent(); - parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : - parentPath + OCFile.PATH_SEPARATOR; + parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : + parentPath + OCFile.PATH_SEPARATOR; parentDir = storageManager.getFileByPath(parentPath); moveCount++; } // exit is granted because storageManager.getFileByPath("/") never returns null @@ -288,20 +246,20 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi listDirectory(mFile /*, MainApp.getOnlyOnDevice()*/); onRefresh(false); - + // restore index and top position restoreIndexAndTopPosition(); - + } // else - should never happen now - + return moveCount; } - + @Override public void onItemClick(AdapterView l, View v, int position, long id) { OCFile file = (OCFile) mAdapter.getItem(position); if (file != null) { - if (file.isFolder()) { + if (file.isFolder()) { // update state and view of this fragment // TODO Enable when "On Device" is recovered ? listDirectory(file/*, MainApp.getOnlyOnDevice()*/); @@ -309,48 +267,48 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi mContainerActivity.onBrowsedDownTo(file); // save index and top position saveIndexAndTopPosition(position); - + } else { /// Click on a file if (PreviewImageFragment.canBePreviewed(file)) { // preview image - it handles the download, if needed - ((FileDisplayActivity)mContainerActivity).startImagePreview(file); - + ((FileDisplayActivity) mContainerActivity).startImagePreview(file); + } else if (file.isDown()) { if (PreviewMediaFragment.canBePreviewed(file)) { // media preview - ((FileDisplayActivity)mContainerActivity).startMediaPreview(file, 0, true); + ((FileDisplayActivity) mContainerActivity).startMediaPreview(file, 0, true); } else { mContainerActivity.getFileOperationsHelper().openFile(file); } - + } else { // automatic download, preview on finish - ((FileDisplayActivity)mContainerActivity).startDownloadForPreview(file); + ((FileDisplayActivity) mContainerActivity).startDownloadForPreview(file); } - + } - + } else { Log_OC.d(TAG, "Null object in ListAdapter!!"); } - + } - + /** * {@inheritDoc} */ @Override - public void onCreateContextMenu ( + public void onCreateContextMenu( ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { Bundle args = getArguments(); - boolean allowContextualActions = - (args == null) ? true : args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, true); + boolean allowContextualActions = + (args == null) ? true : args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, true); if (allowContextualActions) { MenuInflater inflater = getActivity().getMenuInflater(); inflater.inflate(R.menu.file_actions_menu, menu); AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; OCFile targetFile = (OCFile) mAdapter.getItem(info.position); - + if (mContainerActivity.getStorageManager() != null) { FileMenuFilter mf = new FileMenuFilter( targetFile, @@ -445,6 +403,13 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, false); return true; } + case R.id.action_copy: + Intent action = new Intent(getActivity(), FolderPickerActivity.class); + + // Pass mTargetFile that contains info of selected file/folder + action.putExtra(FolderPickerActivity.EXTRA_FILE, mTargetFile); + getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_COPY_FILES); + return true; default: return false; } @@ -468,12 +433,13 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi /** * Use this to query the {@link OCFile} that is currently * being displayed by this fragment + * * @return The currently viewed OCFile */ - public OCFile getCurrentFile(){ + public OCFile getCurrentFile() { return mFile; } - + /** * Calls {@link OCFileListFragment#listDirectory(OCFile)} with a null parameter */ @@ -487,12 +453,12 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi // TODO Enable when "On Device" is recovered ? listDirectory(getCurrentFile()/*, MainApp.getOnlyOnDevice()*/); } - + /** * Lists the given directory on the view. When the input parameter is null, * it will either refresh the last known directory. list the root * if there never was a directory. - * + * * @param directory File to be listed */ public void listDirectory(OCFile directory/*, boolean onlyOnDevice*/) { @@ -500,18 +466,18 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi if (storageManager != null) { // Check input parameters for null - if(directory == null){ - if(mFile != null){ + if (directory == null) { + if (mFile != null) { directory = mFile; } else { directory = storageManager.getFileByPath("/"); if (directory == null) return; // no files, wait for sync } } - - + + // If that's not a directory -> List its parent - if(!directory.isFolder()){ + if (!directory.isFolder()) { Log_OC.w(TAG, "You see, that is not a directory -> " + directory.toString()); directory = storageManager.getFileById(directory.getParentId()); } @@ -538,9 +504,12 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi if (file.isFolder()) { foldersCount++; } else { - filesCount++; - if (file.isImage()){ - imagesCount++; + if (!file.isHidden()) { + filesCount++; + + if (file.isImage()) { + imagesCount++; + } } } } diff --git a/src/com/owncloud/android/ui/preview/FileDownloadFragment.java b/src/com/owncloud/android/ui/preview/FileDownloadFragment.java index dd78a039..e63b3245 100644 --- a/src/com/owncloud/android/ui/preview/FileDownloadFragment.java +++ b/src/com/owncloud/android/ui/preview/FileDownloadFragment.java @@ -59,9 +59,9 @@ public class FileDownloadFragment extends FileFragment implements OnClickListene public ProgressListener mProgressListener; private boolean mListening; - + private static final String TAG = FileDownloadFragment.class.getSimpleName(); - + private boolean mIgnoreFirstSavedState; private boolean mError; @@ -118,19 +118,20 @@ public class FileDownloadFragment extends FileFragment implements OnClickListene mIgnoreFirstSavedState = args.getBoolean(ARG_IGNORE_FIRST); mAccount = args.getParcelable(ARG_ACCOUNT); } - + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { + Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); - + if (savedInstanceState != null) { if (!mIgnoreFirstSavedState) { - setFile((OCFile)savedInstanceState.getParcelable(FileDownloadFragment.EXTRA_FILE)); + setFile((OCFile) savedInstanceState.getParcelable(FileDownloadFragment.EXTRA_FILE)); mAccount = savedInstanceState.getParcelable(FileDownloadFragment.EXTRA_ACCOUNT); mError = savedInstanceState.getBoolean(FileDownloadFragment.EXTRA_ERROR); - } else { + } + else { mIgnoreFirstSavedState = false; } } @@ -140,7 +141,7 @@ public class FileDownloadFragment extends FileFragment implements OnClickListene ProgressBar progressBar = (ProgressBar)mView.findViewById(R.id.progressBar); DisplayUtils.colorPreLollipopHorizontalProgressBar(progressBar); mProgressListener = new ProgressListener(progressBar); - + (mView.findViewById(R.id.cancelBtn)).setOnClickListener(this); (mView.findViewById(R.id.fileDownloadLL)).setOnClickListener(new OnClickListener() { @@ -152,13 +153,14 @@ public class FileDownloadFragment extends FileFragment implements OnClickListene if (mError) { setButtonsForRemote(); - } else { + } + else { setButtonsForTransferring(); } - + return mView; } - + @Override public void onSaveInstanceState(Bundle outState) { @@ -173,7 +175,7 @@ public class FileDownloadFragment extends FileFragment implements OnClickListene super.onStart(); listenForTransferProgress(); } - + @Override public void onResume() { super.onResume(); @@ -185,19 +187,19 @@ public class FileDownloadFragment extends FileFragment implements OnClickListene super.onPause(); } - + @Override public void onStop() { leaveTransferProgress(); super.onStop(); } - + @Override public void onDestroy() { super.onDestroy(); } - - + + @Override public View getView() { if (!mListening) { @@ -206,7 +208,7 @@ public class FileDownloadFragment extends FileFragment implements OnClickListene return super.getView() == null ? mView : super.getView(); } - + @Override public void onClick(View v) { switch (v.getId()) { @@ -220,53 +222,52 @@ public class FileDownloadFragment extends FileFragment implements OnClickListene } } - + /** * Enables or disables buttons for a file being downloaded */ private void setButtonsForTransferring() { getView().findViewById(R.id.cancelBtn).setVisibility(View.VISIBLE); - + // show the progress bar for the transfer getView().findViewById(R.id.progressBar).setVisibility(View.VISIBLE); - TextView progressText = (TextView)getView().findViewById(R.id.progressText); + TextView progressText = (TextView) getView().findViewById(R.id.progressText); progressText.setText(R.string.downloader_download_in_progress_ticker); progressText.setVisibility(View.VISIBLE); - + // hides the error icon getView().findViewById(R.id.errorText).setVisibility(View.GONE); getView().findViewById(R.id.error_image).setVisibility(View.GONE); } - /** - * Enables or disables buttons for a file locally available + * Enables or disables buttons for a file locally available */ private void setButtonsForDown() { getView().findViewById(R.id.cancelBtn).setVisibility(View.GONE); - + // hides the progress bar getView().findViewById(R.id.progressBar).setVisibility(View.GONE); - + // updates the text message - TextView progressText = (TextView)getView().findViewById(R.id.progressText); + TextView progressText = (TextView) getView().findViewById(R.id.progressText); progressText.setText(R.string.common_loading); progressText.setVisibility(View.VISIBLE); - + // hides the error icon getView().findViewById(R.id.errorText).setVisibility(View.GONE); getView().findViewById(R.id.error_image).setVisibility(View.GONE); } - + /** - * Enables or disables buttons for a file not locally available - * + * Enables or disables buttons for a file not locally available + *

* Currently, this is only used when a download was failed */ private void setButtonsForRemote() { getView().findViewById(R.id.cancelBtn).setVisibility(View.GONE); - + // hides the progress bar and message getView().findViewById(R.id.progressBar).setVisibility(View.GONE); getView().findViewById(R.id.progressText).setVisibility(View.GONE); @@ -275,7 +276,7 @@ public class FileDownloadFragment extends FileFragment implements OnClickListene getView().findViewById(R.id.errorText).setVisibility(View.VISIBLE); getView().findViewById(R.id.error_image).setVisibility(View.VISIBLE); } - + public void listenForTransferProgress() { if (mProgressListener != null && !mListening) { @@ -288,8 +289,8 @@ public class FileDownloadFragment extends FileFragment implements OnClickListene } } } - - + + public void leaveTransferProgress() { if (mProgressListener != null) { if (mContainerActivity.getFileDownloaderBinder() != null) { @@ -308,11 +309,11 @@ public class FileDownloadFragment extends FileFragment implements OnClickListene private class ProgressListener implements OnDatatransferProgressListener { int mLastPercent = 0; WeakReference mProgressBar = null; - + ProgressListener(ProgressBar progressBar) { mProgressBar = new WeakReference(progressBar); } - + @Override public void onTransferProgress( long progressRate, long totalTransferredSoFar, long totalToTransfer, String filename @@ -333,8 +334,9 @@ public class FileDownloadFragment extends FileFragment implements OnClickListene public void setError(boolean error) { mError = error; - }; - + } + + ; } diff --git a/src/com/owncloud/android/ui/preview/PreviewImageFragment.java b/src/com/owncloud/android/ui/preview/PreviewImageFragment.java index 7ca1cfbb..b6f36823 100644 --- a/src/com/owncloud/android/ui/preview/PreviewImageFragment.java +++ b/src/com/owncloud/android/ui/preview/PreviewImageFragment.java @@ -26,6 +26,7 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Point; +import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.FragmentStatePagerAdapter; @@ -74,11 +75,11 @@ public class PreviewImageFragment extends FileFragment { private ProgressBar mProgressWheel; public Bitmap mBitmap = null; - + private static final String TAG = PreviewImageFragment.class.getSimpleName(); private boolean mIgnoreFirstSavedState; - + private LoadBitmapTask mLoadBitmapTask = null; @@ -105,7 +106,7 @@ public class PreviewImageFragment extends FileFragment { return frag; } - + /** * Creates an empty fragment for image previews. @@ -119,8 +120,8 @@ public class PreviewImageFragment extends FileFragment { public PreviewImageFragment() { mIgnoreFirstSavedState = false; } - - + + /** * {@inheritDoc} */ @@ -135,14 +136,14 @@ public class PreviewImageFragment extends FileFragment { mIgnoreFirstSavedState = args.getBoolean(ARG_IGNORE_FIRST); setHasOptionsMenu(true); } - + /** * {@inheritDoc} */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { + Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); View view = inflater.inflate(R.layout.preview_image_fragment, container, false); mImageView = (TouchImageViewCustom) view.findViewById(R.id.image); @@ -182,7 +183,7 @@ public class PreviewImageFragment extends FileFragment { throw new IllegalStateException("There is no local file to preview"); } } - + /** * {@inheritDoc} @@ -192,7 +193,7 @@ public class PreviewImageFragment extends FileFragment { super.onSaveInstanceState(outState); outState.putParcelable(PreviewImageFragment.EXTRA_FILE, getFile()); } - + @Override public void onStart() { @@ -200,11 +201,12 @@ public class PreviewImageFragment extends FileFragment { if (getFile() != null) { mLoadBitmapTask = new LoadBitmapTask(mImageView, mMessageView, mProgressWheel); //mLoadBitmapTask.execute(new String[]{getFile().getStoragePath()}); - mLoadBitmapTask.execute(getFile().getStoragePath()); +// mLoadBitmapTask.execute(getFile().getStoragePath()); + mLoadBitmapTask.execute(getFile()); } } - - + + @Override public void onStop() { Log_OC.d(TAG, "onStop starts"); @@ -214,7 +216,7 @@ public class PreviewImageFragment extends FileFragment { } super.onStop(); } - + /** * {@inheritDoc} */ @@ -230,11 +232,11 @@ public class PreviewImageFragment extends FileFragment { @Override public void onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); - + if (mContainerActivity.getStorageManager() != null) { // Update the file setFile(mContainerActivity.getStorageManager().getFileById(getFile().getFileId())); - + FileMenuFilter mf = new FileMenuFilter( getFile(), mContainerActivity.getStorageManager().getAccount(), @@ -243,7 +245,7 @@ public class PreviewImageFragment extends FileFragment { ); mf.filter(menu); } - + // additional restriction for this fragment // TODO allow renaming in PreviewImageFragment MenuItem item = menu.findItem(R.id.action_rename_file); @@ -251,7 +253,7 @@ public class PreviewImageFragment extends FileFragment { item.setVisible(false); item.setEnabled(false); } - + // additional restriction for this fragment // TODO allow refresh file in PreviewImageFragment item = menu.findItem(R.id.action_sync_file); @@ -266,11 +268,17 @@ public class PreviewImageFragment extends FileFragment { item.setVisible(false); item.setEnabled(false); } - + + // additional restriction for this fragment + item = menu.findItem(R.id.action_copy); + if (item != null) { + item.setVisible(false); + item.setEnabled(false); + } + } - - + /** * {@inheritDoc} */ @@ -318,10 +326,10 @@ public class PreviewImageFragment extends FileFragment { return false; } } - + private void seeDetails() { - mContainerActivity.showDetails(getFile()); + mContainerActivity.showDetails(getFile()); } @@ -348,7 +356,7 @@ public class PreviewImageFragment extends FileFragment { super.onDestroy(); } - + /** * Opens the previewed image with an external application. */ @@ -356,9 +364,9 @@ public class PreviewImageFragment extends FileFragment { mContainerActivity.getFileOperationsHelper().openFile(getFile()); finish(); } + - - private class LoadBitmapTask extends AsyncTask { + private class LoadBitmapTask extends AsyncTask { /** * Weak reference to the target {@link ImageView} where the bitmap will be loaded into. @@ -376,7 +384,7 @@ public class PreviewImageFragment extends FileFragment { */ private final WeakReference mMessageViewRef; - + /** * Weak reference to the target {@link ProgressBar} shown while the load is in progress. * @@ -385,17 +393,17 @@ public class PreviewImageFragment extends FileFragment { */ private final WeakReference mProgressWheelRef; - + /** - * Error message to show when a load fails + * Error message to show when a load fails */ private int mErrorMessageId; - - + + /** * Constructor. - * - * @param imageView Target {@link ImageView} where the bitmap will be loaded into. + * + * @param imageView Target {@link ImageView} where the bitmap will be loaded into. */ public LoadBitmapTask(ImageViewCustom imageView, TextView messageView, ProgressBar progressWheel) { @@ -403,13 +411,13 @@ public class PreviewImageFragment extends FileFragment { mMessageViewRef = new WeakReference(messageView); mProgressWheelRef = new WeakReference(progressWheel); } - - + @Override - protected Bitmap doInBackground(String... params) { + protected LoadImage doInBackground(OCFile... params) { Bitmap result = null; if (params.length != 1) return null; - String storagePath = params[0]; + OCFile ocFile = params[0]; + String storagePath = ocFile.getStoragePath(); try { int maxDownScale = 3; // could be a parameter passed to doInBackground(...) @@ -422,7 +430,7 @@ public class PreviewImageFragment extends FileFragment { result = BitmapUtils.decodeSampledBitmapFromFile(storagePath, minWidth, minHeight); - if (isCancelled()) return result; + if (isCancelled()) return new LoadImage(result, ocFile); if (result == null) { mErrorMessageId = R.string.preview_image_error_unknown_format; @@ -454,48 +462,56 @@ public class PreviewImageFragment extends FileFragment { } catch (NoSuchFieldError e) { mErrorMessageId = R.string.common_error_unknown; - Log_OC.e(TAG, "Error from access to unexisting field despite protection; file " - + storagePath, e); - + Log_OC.e(TAG, "Error from access to unexisting field despite protection; file " + + storagePath, e); + } catch (Throwable t) { mErrorMessageId = R.string.common_error_unknown; Log_OC.e(TAG, "Unexpected error loading " + getFile().getStoragePath(), t); - + } - - return result; + + return new LoadImage(result, ocFile); } - + @Override - protected void onCancelled(Bitmap result) { - if (result != null) { - result.recycle(); + protected void onCancelled(LoadImage result) { + if (result.bitmap != null) { + result.bitmap.recycle(); } } @Override - protected void onPostExecute(Bitmap result) { + protected void onPostExecute(LoadImage result) { hideProgressWheel(); - if (result != null) { + if (result.bitmap != null) { showLoadedImage(result); - } else { + } + else { showErrorMessage(); } - if (result != null && mBitmap != result) { + if (result.bitmap != null && mBitmap != result.bitmap) { // unused bitmap, release it! (just in case) - result.recycle(); + result.bitmap.recycle(); } } - + @SuppressLint("InlinedApi") - private void showLoadedImage(Bitmap result) { + private void showLoadedImage(LoadImage result) { final ImageViewCustom imageView = mImageViewRef.get(); + Bitmap bitmap = result.bitmap; if (imageView != null) { - Log_OC.d(TAG, "Showing image with resolution " + result.getWidth() + "x" + - result.getHeight()); - imageView.setImageBitmap(result); + Log_OC.d(TAG, "Showing image with resolution " + bitmap.getWidth() + "x" + + bitmap.getHeight()); + + if (result.ocFile.getMimetype().equalsIgnoreCase("image/png")){ + Drawable backrepeat = getResources().getDrawable(R.drawable.backrepeat); + imageView.setBackground(backrepeat); + } + + imageView.setImageBitmap(bitmap); imageView.setVisibility(View.VISIBLE); - mBitmap = result; // needs to be kept for recycling when not useful + mBitmap = bitmap; // needs to be kept for recycling when not useful } final TextView messageView = mMessageViewRef.get(); @@ -503,7 +519,7 @@ public class PreviewImageFragment extends FileFragment { messageView.setVisibility(View.GONE); } // else , silently finish, the fragment was destroyed } - + private void showErrorMessage() { final ImageView imageView = mImageViewRef.get(); if (imageView != null) { @@ -517,14 +533,14 @@ public class PreviewImageFragment extends FileFragment { messageView.setVisibility(View.VISIBLE); } // else , silently finish, the fragment was destroyed } - + private void hideProgressWheel() { final ProgressBar progressWheel = mProgressWheelRef.get(); if (progressWheel != null) { progressWheel.setVisibility(View.GONE); } } - + } /** @@ -538,7 +554,7 @@ public class PreviewImageFragment extends FileFragment { return (file != null && file.isImage()); } - + /** * Finishes the preview */ @@ -546,9 +562,20 @@ public class PreviewImageFragment extends FileFragment { Activity container = getActivity(); container.finish(); } - + public TouchImageViewCustom getImageView() { return mImageView; } + private class LoadImage { + private Bitmap bitmap; + private OCFile ocFile; + + public LoadImage(Bitmap bitmap, OCFile ocFile){ + this.bitmap = bitmap; + this.ocFile = ocFile; + } + + } + } diff --git a/src/com/owncloud/android/ui/preview/PreviewMediaFragment.java b/src/com/owncloud/android/ui/preview/PreviewMediaFragment.java index b197a855..0dbb1a32 100644 --- a/src/com/owncloud/android/ui/preview/PreviewMediaFragment.java +++ b/src/com/owncloud/android/ui/preview/PreviewMediaFragment.java @@ -49,7 +49,6 @@ import android.view.View; import android.view.View.OnTouchListener; import android.view.ViewGroup; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.Toast; import android.widget.VideoView; @@ -68,7 +67,7 @@ import com.owncloud.android.ui.fragment.FileFragment; /** * This fragment shows a preview of a downloaded media file (audio or video). - * + * * Trying to get an instance with NULL {@link OCFile} or ownCloud {@link Account} values will * produce an {@link IllegalStateException}. * @@ -88,46 +87,46 @@ public class PreviewMediaFragment extends FileFragment implements private ImageView mImagePreview; private VideoView mVideoPreview; private int mSavedPlaybackPosition; - + private MediaServiceBinder mMediaServiceBinder = null; private MediaControlView mMediaController = null; private MediaServiceConnection mMediaServiceConnection = null; private VideoHelper mVideoHelper; private boolean mAutoplay; public boolean mPrepared; - + private static final String TAG = PreviewMediaFragment.class.getSimpleName(); - + /** * Creates a fragment to preview a file. - * + *

* When 'fileToDetail' or 'ocAccount' are null - * - * @param fileToDetail An {@link OCFile} to preview in the fragment - * @param ocAccount An ownCloud account; needed to start downloads + * + * @param fileToDetail An {@link OCFile} to preview in the fragment + * @param ocAccount An ownCloud account; needed to start downloads */ public PreviewMediaFragment( - OCFile fileToDetail, - Account ocAccount, - int startPlaybackPosition, + OCFile fileToDetail, + Account ocAccount, + int startPlaybackPosition, boolean autoplay) { - + super(fileToDetail); mAccount = ocAccount; mSavedPlaybackPosition = startPlaybackPosition; mAutoplay = autoplay; } - - + + /** - * Creates an empty fragment for previews. - * - * MUST BE KEPT: the system uses it when tries to reinstantiate a fragment automatically - * (for instance, when the device is turned a aside). - * - * DO NOT CALL IT: an {@link OCFile} and {@link Account} must be provided for a successful - * construction + * Creates an empty fragment for previews. + *

+ * MUST BE KEPT: the system uses it when tries to reinstantiate a fragment automatically + * (for instance, when the device is turned a aside). + *

+ * DO NOT CALL IT: an {@link OCFile} and {@link Account} must be provided for a successful + * construction */ public PreviewMediaFragment() { super(); @@ -135,8 +134,8 @@ public class PreviewMediaFragment extends FileFragment implements mSavedPlaybackPosition = 0; mAutoplay = true; } - - + + /** * {@inheritDoc} */ @@ -145,29 +144,29 @@ public class PreviewMediaFragment extends FileFragment implements super.onCreate(savedInstanceState); setHasOptionsMenu(true); } - + /** * {@inheritDoc} */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { + Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); Log_OC.e(TAG, "onCreateView"); - + mView = inflater.inflate(R.layout.file_preview, container, false); - - mImagePreview = (ImageView)mView.findViewById(R.id.image_preview); - mVideoPreview = (VideoView)mView.findViewById(R.id.video_preview); + + mImagePreview = (ImageView) mView.findViewById(R.id.image_preview); + mVideoPreview = (VideoView) mView.findViewById(R.id.video_preview); mVideoPreview.setOnTouchListener(this); - - mMediaController = (MediaControlView)mView.findViewById(R.id.media_controller); - + + mMediaController = (MediaControlView) mView.findViewById(R.id.media_controller); + return mView; } - + /** * {@inheritDoc} @@ -188,29 +187,31 @@ public class PreviewMediaFragment extends FileFragment implements if (!file.isDown()) { throw new IllegalStateException("There is no local file to preview"); } - - } else { - file = (OCFile)savedInstanceState.getParcelable(PreviewMediaFragment.EXTRA_FILE); + + } + else { + file = (OCFile) savedInstanceState.getParcelable(PreviewMediaFragment.EXTRA_FILE); setFile(file); mAccount = savedInstanceState.getParcelable(PreviewMediaFragment.EXTRA_ACCOUNT); - mSavedPlaybackPosition = + mSavedPlaybackPosition = savedInstanceState.getInt(PreviewMediaFragment.EXTRA_PLAY_POSITION); mAutoplay = savedInstanceState.getBoolean(PreviewMediaFragment.EXTRA_PLAYING); - + } if (file != null && file.isDown()) { if (file.isVideo()) { mVideoPreview.setVisibility(View.VISIBLE); mImagePreview.setVisibility(View.GONE); prepareVideo(); - - } else { + + } + else { mVideoPreview.setVisibility(View.GONE); mImagePreview.setVisibility(View.VISIBLE); extractAndSetCoverArt(file); } } - + } /** @@ -244,24 +245,25 @@ public class PreviewMediaFragment extends FileFragment implements public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); Log_OC.e(TAG, "onSaveInstanceState"); - + outState.putParcelable(PreviewMediaFragment.EXTRA_FILE, getFile()); outState.putParcelable(PreviewMediaFragment.EXTRA_ACCOUNT, mAccount); - + if (getFile().isVideo()) { mSavedPlaybackPosition = mVideoPreview.getCurrentPosition(); mAutoplay = mVideoPreview.isPlaying(); - outState.putInt(PreviewMediaFragment.EXTRA_PLAY_POSITION , mSavedPlaybackPosition); - outState.putBoolean(PreviewMediaFragment.EXTRA_PLAYING , mAutoplay); - } else { + outState.putInt(PreviewMediaFragment.EXTRA_PLAY_POSITION, mSavedPlaybackPosition); + outState.putBoolean(PreviewMediaFragment.EXTRA_PLAYING, mAutoplay); + } + else { outState.putInt( - PreviewMediaFragment.EXTRA_PLAY_POSITION , + PreviewMediaFragment.EXTRA_PLAY_POSITION, mMediaServiceBinder.getCurrentPosition()); outState.putBoolean( - PreviewMediaFragment.EXTRA_PLAYING , mMediaServiceBinder.isPlaying()); + PreviewMediaFragment.EXTRA_PLAYING, mMediaServiceBinder.isPlaying()); } } - + @Override public void onStart() { @@ -270,17 +272,20 @@ public class PreviewMediaFragment extends FileFragment implements OCFile file = getFile(); if (file != null && file.isDown()) { - if (file.isAudio()) { - bindMediaService(); - - } else if (file.isVideo()) { - stopAudio(); - playVideo(); - } + if (file.isAudio()) { + bindMediaService(); + + } + else { + if (file.isVideo()) { + stopAudio(); + playVideo(); + } + } } } - - + + private void stopAudio() { Intent i = new Intent(getActivity(), MediaService.class); i.setAction(MediaService.ACTION_STOP_ALL); @@ -304,7 +309,7 @@ public class PreviewMediaFragment extends FileFragment implements @Override public void onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); - + if (mContainerActivity.getStorageManager() != null) { FileMenuFilter mf = new FileMenuFilter( getFile(), @@ -329,9 +334,16 @@ public class PreviewMediaFragment extends FileFragment implements item.setVisible(false); item.setEnabled(false); } + + // additional restriction for this fragment + item = menu.findItem(R.id.action_copy); + if (item != null) { + item.setVisible(false); + item.setEnabled(false); + } } - - + + /** * {@inheritDoc} */ @@ -381,26 +393,26 @@ public class PreviewMediaFragment extends FileFragment implements return false; } } - /** * Update the file of the fragment with file value + * * @param file */ - public void updateFile(OCFile file){ + public void updateFile(OCFile file) { setFile(file); } - + private void sendFile() { stopPreview(false); mContainerActivity.getFileOperationsHelper().sendDownloadedFile(getFile()); - + } private void seeDetails() { stopPreview(false); - mContainerActivity.showDetails(getFile()); + mContainerActivity.showDetails(getFile()); } @@ -411,77 +423,80 @@ public class PreviewMediaFragment extends FileFragment implements mVideoPreview.setOnCompletionListener(mVideoHelper); mVideoPreview.setOnErrorListener(mVideoHelper); } - + @SuppressWarnings("static-access") private void playVideo() { // create and prepare control panel for the user mMediaController.setMediaPlayer(mVideoPreview); - + // load the video file in the video player ; // when done, VideoHelper#onPrepared() will be called Uri uri = Uri.parse(getFile().getStoragePath()); mVideoPreview.setVideoPath(uri.encode(getFile().getStoragePath())); } - + private class VideoHelper implements OnCompletionListener, OnPreparedListener, OnErrorListener { - - /** + + /** * Called when the file is ready to be played. - * + *

* Just starts the playback. - * + * * @param vp {@link MediaPlayer} instance performing the playback. */ @Override public void onPrepared(MediaPlayer vp) { Log_OC.e(TAG, "onPrepared"); mVideoPreview.seekTo(mSavedPlaybackPosition); - if (mAutoplay) { + if (mAutoplay) { mVideoPreview.start(); } mMediaController.setEnabled(true); mMediaController.updatePausePlay(); mPrepared = true; } - - + + /** * Called when the file is finished playing. - * + *

* Finishes the activity. - * - * @param mp {@link MediaPlayer} instance performing the playback. + * + * @param mp {@link MediaPlayer} instance performing the playback. */ @Override - public void onCompletion(MediaPlayer mp) { + public void onCompletion(MediaPlayer mp) { Log_OC.e(TAG, "completed"); if (mp != null) { mVideoPreview.seekTo(0); // next lines are necessary to work around undesired video loops if (Build.VERSION.SDK_INT == Build.VERSION_CODES.GINGERBREAD) { - mVideoPreview.pause(); - - } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.GINGERBREAD_MR1) { - // mVideePreview.pause() is not enough - - mMediaController.setEnabled(false); - mVideoPreview.stopPlayback(); - mAutoplay = false; - mSavedPlaybackPosition = 0; - mVideoPreview.setVideoPath(getFile().getStoragePath()); + mVideoPreview.pause(); + + } + else { + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.GINGERBREAD_MR1) { + // mVideePreview.pause() is not enough + + mMediaController.setEnabled(false); + mVideoPreview.stopPlayback(); + mAutoplay = false; + mSavedPlaybackPosition = 0; + mVideoPreview.setVideoPath(getFile().getStoragePath()); + } } } // else : called from onError() mMediaController.updatePausePlay(); } - - + + /** * Called when an error in playback occurs. - * - * @param mp {@link MediaPlayer} instance performing the playback. - * @param what Type of error - * @param extra Extra code specific to the error + * + * @param mp {@link MediaPlayer} instance performing the playback. + * @param what Type of error + * @param extra Extra code specific to the error */ @Override public boolean onError(MediaPlayer mp, int what, int extra) { @@ -502,28 +517,28 @@ public class PreviewMediaFragment extends FileFragment implements } return true; } - + } - + @Override public void onPause() { Log_OC.e(TAG, "onPause"); super.onPause(); } - + @Override public void onResume() { super.onResume(); Log_OC.e(TAG, "onResume"); } - + @Override public void onDestroy() { Log_OC.e(TAG, "onDestroy"); super.onDestroy(); } - + @Override public void onStop() { Log_OC.e(TAG, "onStop"); @@ -538,10 +553,10 @@ public class PreviewMediaFragment extends FileFragment implements mMediaServiceConnection = null; mMediaServiceBinder = null; } - + super.onStop(); } - + @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN && v == mVideoPreview) { @@ -554,7 +569,7 @@ public class PreviewMediaFragment extends FileFragment implements return false; } - + private void startFullScreenVideo() { Intent i = new Intent(getActivity(), PreviewVideoActivity.class); i.putExtra(FileActivity.EXTRA_ACCOUNT, mAccount); @@ -566,29 +581,30 @@ public class PreviewMediaFragment extends FileFragment implements } @Override - public void onConfigurationChanged (Configuration newConfig) { + public void onConfigurationChanged(Configuration newConfig) { Log_OC.e(TAG, "onConfigurationChanged " + this); } - + @Override - public void onActivityResult (int requestCode, int resultCode, Intent data) { + public void onActivityResult(int requestCode, int resultCode, Intent data) { Log_OC.e(TAG, "onActivityResult " + this); super.onActivityResult(requestCode, resultCode, data); if (resultCode == Activity.RESULT_OK) { mSavedPlaybackPosition = data.getExtras().getInt( PreviewVideoActivity.EXTRA_START_POSITION); - mAutoplay = data.getExtras().getBoolean(PreviewVideoActivity.EXTRA_AUTOPLAY); + mAutoplay = data.getExtras().getBoolean(PreviewVideoActivity.EXTRA_AUTOPLAY); } } - + private void playAudio() { OCFile file = getFile(); if (!mMediaServiceBinder.isPlaying(file)) { Log_OC.d(TAG, "starting playback of " + file.getStoragePath()); mMediaServiceBinder.start(mAccount, file, mAutoplay, mSavedPlaybackPosition); - - } else { + + } + else { if (!mMediaServiceBinder.isPlaying() && mAutoplay) { mMediaServiceBinder.start(); mMediaController.updatePausePlay(); @@ -625,7 +641,8 @@ public class PreviewMediaFragment extends FileFragment implements Log_OC.d(TAG, "Successfully bound to MediaService, MediaController ready"); - } else { + } + else { Log_OC.e(TAG, "Unexpected response from MediaService while binding"); } } @@ -647,7 +664,8 @@ public class PreviewMediaFragment extends FileFragment implements Log_OC.e(TAG, "Media service suddenly disconnected"); if (mMediaController != null) { mMediaController.setMediaPlayer(null); - } else { + } + else { Toast.makeText( getActivity(), "No media controller to release when disconnected from media service", @@ -657,9 +675,8 @@ public class PreviewMediaFragment extends FileFragment implements mMediaServiceConnection = null; } } - } + } - /** * Opens the previewed file with an external application. @@ -669,31 +686,33 @@ public class PreviewMediaFragment extends FileFragment implements mContainerActivity.getFileOperationsHelper().openFile(getFile()); finish(); } - + /** * Helper method to test if an {@link OCFile} can be passed to a {@link PreviewMediaFragment} - * to be previewed. - * - * @param file File to test if can be previewed. - * @return 'True' if the file can be handled by the fragment. + * to be previewed. + * + * @param file File to test if can be previewed. + * @return 'True' if the file can be handled by the fragment. */ public static boolean canBePreviewed(OCFile file) { return (file != null && (file.isAudio() || file.isVideo())); } - + public void stopPreview(boolean stopAudio) { OCFile file = getFile(); if (file.isAudio() && stopAudio) { mMediaServiceBinder.pause(); - - } else if (file.isVideo()) { - mVideoPreview.stopPlayback(); + + } + else { + if (file.isVideo()) { + mVideoPreview.stopPlayback(); + } } } - /** * Finishes the preview */ @@ -709,12 +728,12 @@ public class PreviewMediaFragment extends FileFragment implements Log_OC.e(TAG, "getting position: " + mSavedPlaybackPosition); return mSavedPlaybackPosition; } - + public boolean isPlaying() { if (mPrepared) { mAutoplay = mVideoPreview.isPlaying(); } return mAutoplay; } - + } diff --git a/src/com/owncloud/android/utils/ErrorMessageAdapter.java b/src/com/owncloud/android/utils/ErrorMessageAdapter.java index 75736e53..b80cc573 100644 --- a/src/com/owncloud/android/utils/ErrorMessageAdapter.java +++ b/src/com/owncloud/android/utils/ErrorMessageAdapter.java @@ -21,17 +21,13 @@ package com.owncloud.android.utils; -import java.io.File; -import java.net.SocketTimeoutException; - -import org.apache.commons.httpclient.ConnectTimeoutException; - import android.content.res.Resources; 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.operations.CopyFileOperation; import com.owncloud.android.operations.CreateFolderOperation; import com.owncloud.android.operations.CreateShareOperation; import com.owncloud.android.operations.DownloadFileOperation; @@ -43,6 +39,11 @@ import com.owncloud.android.operations.SynchronizeFolderOperation; import com.owncloud.android.operations.UnshareLinkOperation; import com.owncloud.android.operations.UploadFileOperation; +import org.apache.commons.httpclient.ConnectTimeoutException; + +import java.io.File; +import java.net.SocketTimeoutException; + /** * Class to choose proper error messages to show to the user depending on the results of operations, * always following the same policy @@ -51,16 +52,16 @@ import com.owncloud.android.operations.UploadFileOperation; public class ErrorMessageAdapter { public ErrorMessageAdapter() { - + } public static String getErrorCauseMessage(RemoteOperationResult result, RemoteOperation operation, Resources res) { String message = null; - + if (operation instanceof UploadFileOperation) { - + if (result.isSuccess()) { message = String.format( res.getString(R.string.uploader_upload_succeeded_content_single), @@ -76,7 +77,7 @@ public class ErrorMessageAdapter { } else if (result.getCode() == ResultCode.QUOTA_EXCEEDED) { message = res.getString(R.string.failed_upload_quota_exceeded_text); */ - + } else if (result.getCode() == ResultCode.FORBIDDEN) { message = String.format(res.getString(R.string.forbidden_permissions), res.getString(R.string.uploader_upload_forbidden_permissions)); @@ -90,14 +91,14 @@ public class ErrorMessageAdapter { ((UploadFileOperation) operation).getFileName()); } } - + } else if (operation instanceof DownloadFileOperation) { - + if (result.isSuccess()) { message = String.format( res.getString(R.string.downloader_download_succeeded_content), new File(((DownloadFileOperation) operation).getSavePath()).getName()); - + } else { if (result.getCode() == ResultCode.FILE_NOT_FOUND) { message = res.getString(R.string.downloader_download_file_not_found); @@ -108,11 +109,11 @@ public class ErrorMessageAdapter { ((DownloadFileOperation) operation).getSavePath()).getName()); } } - + } else if (operation instanceof RemoveFileOperation) { if (result.isSuccess()) { message = res.getString(R.string.remove_success_msg); - + } else { if (result.getCode().equals(ResultCode.FORBIDDEN)) { // Error --> No permissions @@ -120,7 +121,7 @@ public class ErrorMessageAdapter { res.getString(R.string.forbidden_permissions_delete)); } else if (isNetworkError(result.getCode())) { message = getErrorMessage(result, res); - + } else { message = res.getString(R.string.remove_fail_msg); } @@ -140,19 +141,19 @@ public class ErrorMessageAdapter { } else if (isNetworkError(result.getCode())) { message = getErrorMessage(result, res); - + } else if (result.getCode() == ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER) { message = res.getString(R.string.filename_forbidden_charaters_from_server); } else { - message = res.getString(R.string.rename_server_fail_msg); + message = res.getString(R.string.rename_server_fail_msg); } - + } else if (operation instanceof SynchronizeFileOperation) { if (!((SynchronizeFileOperation) operation).transferWasRequested()) { message = res.getString(R.string.sync_file_nothing_to_do_msg); } - + } else if (operation instanceof CreateFolderOperation) { if (result.getCode() == ResultCode.INVALID_CHARACTER_IN_NAME) { message = res.getString(R.string.filename_forbidden_characters); @@ -163,7 +164,7 @@ public class ErrorMessageAdapter { } else if (isNetworkError(result.getCode())) { message = getErrorMessage(result, res); - + } else if (result.getCode() == ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER) { message = res.getString(R.string.filename_forbidden_charaters_from_server); } else { @@ -172,7 +173,7 @@ public class ErrorMessageAdapter { } else if (operation instanceof CreateShareOperation) { if (result.getCode() == ResultCode.SHARE_NOT_FOUND) { // Error --> SHARE_NOT_FOUND message = res.getString(R.string.share_link_file_no_exist); - + } else if (result.getCode() == ResultCode.SHARE_FORBIDDEN) { // Error --> No permissions message = String.format(res.getString(R.string.forbidden_permissions), @@ -180,17 +181,17 @@ public class ErrorMessageAdapter { } else if (isNetworkError(result.getCode())) { message = getErrorMessage(result, res); - + } else { // Generic error // Show a Message, operation finished without success message = res.getString(R.string.share_link_file_error); } - + } else if (operation instanceof UnshareLinkOperation) { - + if (result.getCode() == ResultCode.SHARE_NOT_FOUND) { // Error --> SHARE_NOT_FOUND message = res.getString(R.string.unshare_link_file_no_exist); - + } else if (result.getCode() == ResultCode.SHARE_FORBIDDEN) { // Error --> No permissions message = String.format(res.getString(R.string.forbidden_permissions), @@ -198,17 +199,18 @@ public class ErrorMessageAdapter { } else if (isNetworkError(result.getCode())) { message = getErrorMessage(result, res); - + } else { // Generic error // Show a Message, operation finished without success message = res.getString(R.string.unshare_link_file_error); } } else if (operation instanceof MoveFileOperation) { - if (result.getCode() == ResultCode.FILE_NOT_FOUND) { + if(isNetworkError(result.getCode())){ + message = getErrorMessage(result, res); + } else if (result.getCode() == ResultCode.FILE_NOT_FOUND) { message = res.getString(R.string.move_file_not_found); - - } else if (result.getCode() == ResultCode.INVALID_MOVE_INTO_DESCENDANT) { + } else if (result.getCode() == ResultCode.INVALID_MOVE_INTO_DESCENDANT) { message = res.getString(R.string.move_file_invalid_into_descendent); } else if (result.getCode() == ResultCode.INVALID_OVERWRITE) { @@ -240,44 +242,62 @@ public class ErrorMessageAdapter { folderPathName); } } + } else if (operation instanceof CopyFileOperation) { + if(isNetworkError(result.getCode())){ + message = getErrorMessage(result, res); + } else if (result.getCode() == ResultCode.FILE_NOT_FOUND) { + message = res.getString(R.string.copy_file_not_found); + } else if (result.getCode() == ResultCode.INVALID_COPY_INTO_DESCENDANT) { + message = res.getString(R.string.copy_file_invalid_into_descendent); + + } else if (result.getCode() == ResultCode.INVALID_OVERWRITE) { + message = res.getString(R.string.copy_file_invalid_overwrite); + + } else if (result.getCode() == ResultCode.FORBIDDEN) { + message = String.format(res.getString(R.string.forbidden_permissions), + res.getString(R.string.forbidden_permissions_copy)); + + } else { // Generic error + // Show a Message, operation finished without success + message = res.getString(R.string.copy_file_error); + } } - + return message; } - - private static String getErrorMessage(RemoteOperationResult result , Resources res) { - + + private static String getErrorMessage(RemoteOperationResult result, Resources res) { + String message = null; - + if (!result.isSuccess()) { - + if (result.getCode() == ResultCode.WRONG_CONNECTION) { message = res.getString(R.string.network_error_socket_exception); - + } else if (result.getCode() == ResultCode.TIMEOUT) { message = res.getString(R.string.network_error_socket_exception); - + if (result.getException() instanceof SocketTimeoutException) { message = res.getString(R.string.network_error_socket_timeout_exception); - } else if(result.getException() instanceof ConnectTimeoutException) { + } else if (result.getException() instanceof ConnectTimeoutException) { message = res.getString(R.string.network_error_connect_timeout_exception); - } - + } + } else if (result.getCode() == ResultCode.HOST_NOT_AVAILABLE) { message = res.getString(R.string.network_host_not_available); } } - + return message; } - + private static boolean isNetworkError(RemoteOperationResult.ResultCode code) { - if (code == ResultCode.WRONG_CONNECTION || - code == ResultCode.TIMEOUT || + if (code == ResultCode.WRONG_CONNECTION || + code == ResultCode.TIMEOUT || code == ResultCode.HOST_NOT_AVAILABLE) { return true; - } - else + } else return false; } }