Browse Source

Merge branch 'master' into reliable_uploads_actions_uploads_view

David A. Velasco 9 years ago
parent
commit
15eb8b493b

+ 34 - 0
res/layout/share_file_layout.xml

@@ -228,6 +228,40 @@
 
         </RelativeLayout>
 
+        <RelativeLayout
+            android:id="@+id/shareViaLinkEditPermissionSection"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:visibility="invisible"
+            >
+
+            <Switch
+                android:id="@+id/shareViaLinkEditPermissionSwitch"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentRight="true"
+                android:layout_alignParentEnd="true"
+                android:layout_centerInParent="true"
+                android:padding="8dp"
+                />
+
+            <TextView
+                android:id="@+id/shareViaLinkEditPermissionLabel"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentStart="true"
+                android:layout_toLeftOf="@id/shareViaLinkEditPermissionSwitch"
+                android:layout_toStartOf="@id/shareViaLinkEditPermissionSwitch"
+                android:paddingTop="8dp"
+                android:paddingLeft="8dp"
+                android:paddingRight="8dp"
+                android:text="@string/share_via_link_edit_permission_label"
+                android:textSize="16sp"
+                />
+
+        </RelativeLayout>
+
         <android.support.v7.widget.AppCompatButton
             android:id="@+id/shareViaLinkGetLinkButton"
             style="@style/ownCloud.Button"

+ 2 - 0
res/values-de/strings.xml

@@ -352,6 +352,8 @@
   <string name="share_search">Suche</string>
   <string name="search_users_and_groups_hint">Nutzer und Gruppen suchen</string>
   <string name="share_group_clarification">%1$s (Gruppe)</string>
+  <string name="share_remote_clarification">%1$s (remote)</string>
+  <string name="share_known_remote_clarification">%1$s ( at %2$s )</string>
   <string name="share_sharee_unavailable">Entschuldigung, Deine Serverversion erlaubt das Teilen mit Nutzern innerhalb der Clients nicht.
 \nBitte kontaktiere Deinen Administrator</string>
   <string name="share_privilege_can_share">kann teilen</string>

+ 2 - 0
res/values-en-rGB/strings.xml

@@ -352,6 +352,8 @@
   <string name="share_search">Search</string>
   <string name="search_users_and_groups_hint">Search users and groups</string>
   <string name="share_group_clarification">%1$s (group)</string>
+  <string name="share_remote_clarification">%1$s (remote)</string>
+  <string name="share_known_remote_clarification">%1$s ( at %2$s )</string>
   <string name="share_sharee_unavailable">Sorry, your server version does not allow share with users within clients.
         \nPlease contact your administrator</string>
   <string name="share_privilege_can_share">can share</string>

+ 1 - 0
res/values-fi-rFI/strings.xml

@@ -329,6 +329,7 @@
   <string name="share_search">Etsi</string>
   <string name="search_users_and_groups_hint">Etsi käyttäjiä ja ryhmiä</string>
   <string name="share_group_clarification">%1$s (ryhmä)</string>
+  <string name="share_remote_clarification">%1$s (etä)</string>
   <string name="share_privilege_can_share">jaa</string>
   <string name="share_privilege_can_edit">voi muokata</string>
   <string name="share_privilege_can_edit_create">luo</string>

+ 2 - 0
res/values-fr/strings.xml

@@ -356,6 +356,8 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
   <string name="share_search">Rechercher</string>
   <string name="search_users_and_groups_hint">Chercher parmi les utilisateurs et groupes</string>
   <string name="share_group_clarification">%1$s (groupe)</string>
+  <string name="share_remote_clarification">%1$s (distant)</string>
+  <string name="share_known_remote_clarification">%1$s (sur %2$s)</string>
   <string name="share_sharee_unavailable">Désolé, la version du serveur ne permet pas aux applications d\'initier des partage avec d\'autres utilisateurs.
 \nVeuillez contacter votre administrateur</string>
   <string name="share_privilege_can_share">peut partager</string>

+ 2 - 0
res/values-he/strings.xml

@@ -352,6 +352,8 @@
   <string name="share_search">חיפוש</string>
   <string name="search_users_and_groups_hint">חיפוש משתמשים וקבוצות</string>
   <string name="share_group_clarification">%1$s (קבוצה)</string>
+  <string name="share_remote_clarification">%1$s (נשלט מרחוק)</string>
+  <string name="share_known_remote_clarification">%1$s ( ב- %2$s )</string>
   <string name="share_sharee_unavailable">מצטערים, גרסת השרת שלך לא מאפשרת שיתוף עם משתמשים בין לקוחות.
         \nיש ליצור קשר עם המנהל</string>
   <string name="share_privilege_can_share">ניתן לשתף</string>

+ 2 - 0
res/values-is/strings.xml

@@ -65,6 +65,7 @@
   <string name="change_password">Breyta lykilorði</string>
   <string name="create_account">Stofna aðgang</string>
   <string name="uploader_info_dirname">Nafn möppu</string>
+  <string name="downloader_download_failed_ticker">Niðurhal mistókst</string>
   <string name="foreign_files_move">Færa allt</string>
   <string name="favorite">Uppáhalds</string>
   <string name="common_rename">Endurnefna</string>
@@ -86,6 +87,7 @@
   <string name="conflict_use_local_version">útgáfu á tölvu</string>
   <string name="conflict_use_server_version">útgáfu á þjóni</string>
   <string name="activity_chooser_send_file_title">Senda</string>
+  <string name="clipboard_text_copied">Afritað á klippispjaldið</string>
   <string name="empty"></string>
   <string name="prefs_category_accounts">Notandaaðgangar</string>
   <string name="saml_authentication_required_text">Auðkenningar krafist</string>

+ 2 - 0
res/values-it/strings.xml

@@ -352,6 +352,8 @@
   <string name="share_search">Cerca</string>
   <string name="search_users_and_groups_hint">Cerca utenti e gruppi</string>
   <string name="share_group_clarification">%1$s (gruppo)</string>
+  <string name="share_remote_clarification">%1$s (remota)</string>
+  <string name="share_known_remote_clarification">%1$s ( su %2$s )</string>
   <string name="share_sharee_unavailable">Spiacenti, la versione del tuo server non consente la condivisione con utenti dai client.
 \nContatta il tuo amministratore.</string>
   <string name="share_privilege_can_share">può condividere</string>

+ 2 - 0
res/values-nl/strings.xml

@@ -355,6 +355,8 @@ Hieronder staan de lokale bestanden en de externe bestanden in %5$s waar ze naar
   <string name="share_search">Zoeken</string>
   <string name="search_users_and_groups_hint">Zoeken naar gebruikers en groepen</string>
   <string name="share_group_clarification">%1$s (groep)</string>
+  <string name="share_remote_clarification">%1$s (extern)</string>
+  <string name="share_known_remote_clarification">%1$s ( om %2$s )</string>
   <string name="share_sharee_unavailable">Sorry, uw serverversie staat niet toe om binnen de clients te delen met gebruikers.
 Neem contact op met uw beheerder</string>
   <string name="share_privilege_can_share">kan delen</string>

+ 2 - 0
res/values-pt-rBR/strings.xml

@@ -352,6 +352,8 @@
   <string name="share_search">Perquisar</string>
   <string name="search_users_and_groups_hint">Pesquisar usuários e grupos</string>
   <string name="share_group_clarification">%1$s (grupo)</string>
+  <string name="share_remote_clarification">%1$s (remoto)</string>
+  <string name="share_known_remote_clarification">%1$s ( em %2$s )</string>
   <string name="share_sharee_unavailable">Desculpe, sua versão do servidor não permite compartilhamento com usuários que também são clientes.
         \nEntre em contato com o administrador</string>
   <string name="share_privilege_can_share">pode compartilhar</string>

+ 21 - 19
res/values-pt-rPT/strings.xml

@@ -2,7 +2,7 @@
 <resources>
   <string name="about_android">%1$s Aplicação Android</string>
   <string name="about_version">versão %1$s</string>
-  <string name="actionbar_sync">Atualizar conta</string>
+  <string name="actionbar_sync">Actualizar conta</string>
   <string name="actionbar_upload">Carregar</string>
   <string name="actionbar_upload_from_apps">Conteúdo de outras apps</string>
   <string name="actionbar_upload_files">Ficheiros</string>
@@ -32,22 +32,22 @@
   <string name="prefs_category_more">Mais</string>
   <string name="prefs_accounts">Contas</string>
   <string name="prefs_manage_accounts">Gerir contas</string>
-  <string name="prefs_passcode">Bloquear código</string>
-  <string name="prefs_instant_upload">Envios instantâneos de imagens</string>
-  <string name="prefs_instant_upload_summary">Envio instantâneo de imagens tiradas com a câmara</string>
-  <string name="prefs_instant_video_upload">Envios instantâneos dos vídeos</string>
-  <string name="prefs_instant_video_upload_summary">Envio instantâneo de vídeos gravados com a câmara  </string>
-  <string name="prefs_log_title">Ativar logging</string>
+  <string name="prefs_passcode">Protecção por senha</string>
+  <string name="prefs_instant_upload">Carregamentos instantâneos de imagens</string>
+  <string name="prefs_instant_upload_summary">Carregamento instantâneo de imagens tiradas com a câmara</string>
+  <string name="prefs_instant_video_upload">Carregamentos instantâneos de vídeos</string>
+  <string name="prefs_instant_video_upload_summary">Carregamento instantâneo de vídeos gravados com a câmara  </string>
+  <string name="prefs_log_title">Activar registo de alterações</string>
   <string name="prefs_log_summary">Isto é utilizado para registar problemas</string>
-  <string name="prefs_log_title_history">Histórico de logging</string>
-  <string name="prefs_log_summary_history">Isto mostra os registos guardados</string>
-  <string name="prefs_log_delete_history_button">Apagar histórico</string>
+  <string name="prefs_log_title_history">Histórico de registos de alterações</string>
+  <string name="prefs_log_summary_history">Isto mostra os registos de alterações guardados</string>
+  <string name="prefs_log_delete_history_button">Eliminar histórico</string>
   <string name="prefs_help">Ajuda</string>
   <string name="prefs_recommend">Recomendar a um amigo</string>
   <string name="prefs_feedback">Feedback</string>
   <string name="prefs_imprint">Imprint</string>
   <string name="prefs_remember_last_share_location">Lembrar localização de partilha</string>
-  <string name="prefs_remember_last_upload_location_summary">Lembrar da última localização de envio de partilha</string>
+  <string name="prefs_remember_last_upload_location_summary">Lembrar a última localização de partilha dos carregamentos</string>
   <string name="recommend_subject">Test %1$s no seu smartphone!</string>
   <string name="recommend_text">Eu quero convidar-te para usares %1$s no teu smartphone!\nTransfere  aqui: %2$s</string>
   <string name="auth_check_server">Verificar servidor</string>
@@ -57,19 +57,19 @@
   <string name="auth_register">Novo em %1$s?</string>
   <string name="sync_string_files">Ficheiros</string>
   <string name="setup_btn_connect">Ligar</string>
-  <string name="uploader_btn_upload_text">Enviar</string>
+  <string name="uploader_btn_upload_text">Carregar</string>
   <string name="uploader_btn_new_folder_text">Nova Pasta</string>
-  <string name="uploader_top_message">Escolha a pasta de envio:</string>
+  <string name="uploader_top_message">Escolha a pasta de carregamento:</string>
   <string name="uploader_wrn_no_account_title">A conta não foi encontrada</string>
-  <string name="uploader_wrn_no_account_text">Não existem contas %1$s no seu aparelho. Por favor, monte uma conta primeiro.</string>
+  <string name="uploader_wrn_no_account_text">Não existem as contas %1$s no seu equipamento. Por favor, configure uma conta primeiro.</string>
   <string name="uploader_wrn_no_account_setup_btn_text">Configurar</string>
   <string name="uploader_wrn_no_account_quit_btn_text">Sair</string>
-  <string name="uploader_wrn_no_content_title">Sem conteúdo para enviar</string>
-  <string name="uploader_wrn_no_content_text">Não foi recebido nenhum conteúdo. Nada para enviar.</string>
-  <string name="uploader_error_forbidden_content">O  %1$s não está autorizado a aceder aos ficheiro partilhados.</string>
-  <string name="uploader_info_uploading">A enviar</string>
+  <string name="uploader_wrn_no_content_title">Sem conteúdo para carregar</string>
+  <string name="uploader_wrn_no_content_text">Não foi recebido nenhum conteúdo. Nada para carregar.</string>
+  <string name="uploader_error_forbidden_content">%1$s não está autorizado a aceder ao conteúdo partilhado.</string>
+  <string name="uploader_info_uploading">A carregar</string>
   <string name="file_list_seconds_ago">segundos atrás</string>
-  <string name="file_list_empty">Aqui não existe nada. Envie alguma coisa!</string>
+  <string name="file_list_empty">Aqui não existe nada. Carregue alguma coisa!</string>
   <string name="file_list_loading">A carregar...</string>
   <string name="file_list_no_app_for_file_type">Nenhuma aplicação encontrada para o tipo de ficheiro!</string>
   <string name="local_file_list_empty">Não existem ficheiros nesta pasta.</string>
@@ -350,6 +350,8 @@
   <string name="share_search">Procurar</string>
   <string name="search_users_and_groups_hint">Pesquisar utilizadores e grupos</string>
   <string name="share_group_clarification">%1$s (grupo)</string>
+  <string name="share_remote_clarification">%1$s (remoto)</string>
+  <string name="share_known_remote_clarification">%1$s ( em %2$s )</string>
   <string name="share_sharee_unavailable">Desculpe, a versão do seu servidor não autoriza a partilha com utilizadores no mesmo cliente.
         \nPor favor contacte o seu administrador</string>
   <string name="share_privilege_can_share">pode partilhar</string>

+ 2 - 0
res/values-sl/strings.xml

@@ -352,6 +352,8 @@
   <string name="share_search">Poišči</string>
   <string name="search_users_and_groups_hint">Iskanje uporabnikov in skupin</string>
   <string name="share_group_clarification">%1$s (skupina)</string>
+  <string name="share_remote_clarification">%1$s (oddaljeno)</string>
+  <string name="share_known_remote_clarification">%1$s ( pri %2$s )</string>
   <string name="share_sharee_unavailable">Različica strežnika ne omogoča souporabe predmetov z uporabniki med strankami.
 \nStopite v stik s skrbnikom sistema.</string>
   <string name="share_privilege_can_share">lahko omogoči souporabo</string>

+ 2 - 0
res/values-sq/strings.xml

@@ -349,6 +349,8 @@
   <string name="share_search">Kërko</string>
   <string name="search_users_and_groups_hint">Kërkoni për grupe dhe përdorues</string>
   <string name="share_group_clarification">%1$s (grup)</string>
+  <string name="share_remote_clarification">%1$s (i largët)</string>
+  <string name="share_known_remote_clarification">%1$s ( te %2$s )</string>
   <string name="share_sharee_unavailable">Na ndjeni, versioni juaj i shërbyesit nuk lejon ndarje me përdorues brenda klientësh.
         \nJu lutemi, lidhuni me përgjegjësin tuaj</string>
   <string name="share_privilege_can_share">mund të ndajë</string>

+ 5 - 0
res/values-sv/strings.xml

@@ -338,6 +338,8 @@
   <string name="prefs_instant_behaviour_title">Originalfilen kommer att...</string>
   <string name="upload_copy_files">Kopiera fil</string>
   <string name="upload_move_files">Flytta fil</string>
+  <string name="pref_behaviour_entries_keep_file">behållen i orginalmapp</string>
+  <string name="pref_behaviour_entries_move">flyttad till app-mapp</string>
   <string name="share_dialog_title">Dela</string>
   <string name="share_with_user_section_title">Dela med användare och grupper</string>
   <string name="share_no_users">Ingen data delar med användare än</string>
@@ -350,6 +352,8 @@
   <string name="share_search">Sök</string>
   <string name="search_users_and_groups_hint">Sök användare och grupper</string>
   <string name="share_group_clarification">%1$s (grupp)</string>
+  <string name="share_remote_clarification">%1$s (fjärr)</string>
+  <string name="share_known_remote_clarification">%1$s ( på %2$s )</string>
   <string name="share_sharee_unavailable">Tyvärr tillåter inte din serverversion delning med användare inom klienter. \nVar god kontakta din administrator.</string>
   <string name="share_privilege_can_share">får dela</string>
   <string name="share_privilege_can_edit">kan redigera</string>
@@ -364,4 +368,5 @@
   <string name="manage_space_description">Inställningar, databas och servercertifikat från %1$s data kommer att raderas permanent. \n\nNedladdade förblir orörda.\n\nProcessen kommer ta tid.</string>
   <string name="manage_space_clear_data">Rensa data</string>
   <string name="manage_space_error">Vissa filer kunde inte raderas.</string>
+  <string name="permission_storage_access">Ytterligare rättigheter krävs för att ladda upp &amp; ner filer.</string>
 </resources>

+ 3 - 0
res/values/strings.xml

@@ -410,12 +410,15 @@
     <string name="share_via_link_expiration_date_label">Set expiration date</string>
     <string name="share_via_link_password_label">Password protect</string>
     <string name="share_via_link_password_title">Secured</string>
+    <string name="share_via_link_edit_permission_label">Allow editing</string>
     <string name="share_get_public_link_button">Get link</string>
 
     <string name="share_search">Search</string>
 
     <string name="search_users_and_groups_hint">Search users and groups</string>
     <string name="share_group_clarification">%1$s (group)</string>
+    <string name="share_remote_clarification">%1$s (remote)</string>
+    <string name="share_known_remote_clarification">%1$s ( at %2$s )</string>
 
     <string name="share_sharee_unavailable">Sorry, your server version does not allow share with users within clients.
         \nPlease contact your administrator</string>

+ 5 - 2
src/com/owncloud/android/datamodel/FileDataStorageManager.java

@@ -1539,6 +1539,7 @@ public class FileDataStorageManager {
                     getContentResolver().applyBatch(MainApp.getAuthority(), operations);
 
                 } else {
+
                     getContentProviderClient().applyBatch(operations);
                 }
 
@@ -1639,10 +1640,12 @@ public class FileDataStorageManager {
         String where = ProviderTableMeta.OCSHARES_PATH + "=?" + " AND "
                 + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?"+ "AND"
                 + " (" + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? OR "
-                + ProviderTableMeta.OCSHARES_SHARE_TYPE +  "=? ) ";
+                + ProviderTableMeta.OCSHARES_SHARE_TYPE +  "=? OR "
+                + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? ) ";
         String [] whereArgs = new String[]{ filePath, accountName ,
                 Integer.toString(ShareType.USER.getValue()),
-                Integer.toString(ShareType.GROUP.getValue()) };
+                Integer.toString(ShareType.GROUP.getValue()),
+                Integer.toString(ShareType.FEDERATED.getValue())};
 
         Cursor c = null;
         if (getContentResolver() != null) {

+ 20 - 0
src/com/owncloud/android/files/FileOperationsHelper.java

@@ -3,6 +3,7 @@
  *
  *   @author masensio
  *   @author David A. Velasco
+ *   @author Juan Carlos González Cabrero
  *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
@@ -410,6 +411,25 @@ public class FileOperationsHelper {
         queueShareIntent(updateShareIntent);
     }
 
+    /**
+     * Updates a public share on a folder to set its editing permission.
+     * Starts a request to do it in {@link OperationsService}
+     *
+     * @param folder                     Folder which editing permission of his public share will be modified.
+     * @param uploadPermission          New state of the permission for editing the folder shared via link.
+     */
+    public void setUploadPermissionsToShare(OCFile folder, boolean uploadPermission) {
+        Intent updateShareIntent = new Intent(mFileActivity, OperationsService.class);
+        updateShareIntent.setAction(OperationsService.ACTION_UPDATE_SHARE);
+        updateShareIntent.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
+        updateShareIntent.putExtra(OperationsService.EXTRA_REMOTE_PATH, folder.getRemotePath());
+        updateShareIntent.putExtra(
+                OperationsService.EXTRA_SHARE_PUBLIC_UPLOAD,
+                uploadPermission
+        );
+        queueShareIntent(updateShareIntent);
+    }
+
 
     /**
      * @return 'True' if the server supports the Search Users API

+ 2 - 1
src/com/owncloud/android/operations/CreateShareWithShareeOperation.java

@@ -60,7 +60,8 @@ public class CreateShareWithShareeOperation extends SyncOperation {
      *                      https://doc.owncloud.org/server/8.2/developer_manual/core/ocs-share-api.html .
      */
     public CreateShareWithShareeOperation(String path, String shareeName, ShareType shareType, int permissions) {
-        if (!ShareType.USER.equals(shareType) && !ShareType.GROUP.equals(shareType)) {
+        if (!ShareType.USER.equals(shareType) && !ShareType.GROUP.equals(shareType)
+            && !ShareType.FEDERATED.equals(shareType)) {
             throw new IllegalArgumentException("Illegal share type " + shareType);
         }
         mPath = path;

+ 3 - 2
src/com/owncloud/android/operations/UnshareOperation.java

@@ -75,10 +75,11 @@ public class UnshareOperation extends SyncOperation {
             if (result.isSuccess()) {
                 Log_OC.d(TAG, "Share id = " + share.getRemoteId() + " deleted");
 
-                if (mShareType == ShareType.PUBLIC_LINK) {
+                if (ShareType.PUBLIC_LINK.equals(mShareType)) {
                     file.setShareViaLink(false);
                     file.setPublicLink("");
-                } else if (mShareType == ShareType.USER || mShareType == ShareType.GROUP){
+                } else if (ShareType.USER.equals(mShareType) || ShareType.GROUP.equals(mShareType)
+                    || ShareType.FEDERATED.equals(mShareType)){
                     // Check if it is the last share
                     ArrayList <OCShare> sharesWith = getStorageManager().
                             getSharesWithForAFile(mRemotePath,

+ 12 - 2
src/com/owncloud/android/operations/UpdateShareViaLinkOperation.java

@@ -31,8 +31,6 @@ import com.owncloud.android.lib.resources.shares.ShareType;
 import com.owncloud.android.lib.resources.shares.UpdateRemoteShareOperation;
 import com.owncloud.android.operations.common.SyncOperation;
 
-import java.util.Calendar;
-
 
 /**
  * Updates an existing public share for a given file
@@ -42,6 +40,7 @@ public class UpdateShareViaLinkOperation extends SyncOperation {
 
     private String mPath;
     private String mPassword;
+    private boolean mPublicUpload;
     private long mExpirationDateInMillis;
 
     /**
@@ -54,6 +53,7 @@ public class UpdateShareViaLinkOperation extends SyncOperation {
         mPath = path;
         mPassword = null;
         mExpirationDateInMillis = 0;
+        mPublicUpload = false;
     }
 
 
@@ -81,6 +81,15 @@ public class UpdateShareViaLinkOperation extends SyncOperation {
         mExpirationDateInMillis = expirationDateInMillis;
     }
 
+    /**
+     * Enable upload permissions to update in Share resource.
+     *
+     * @param publicUpload    Upload Permission to set to the public link.
+     */
+    public void setPublicUpload(boolean publicUpload) {
+        mPublicUpload = publicUpload;
+    }
+
 
     @Override
     protected RemoteOperationResult run(OwnCloudClient client) {
@@ -104,6 +113,7 @@ public class UpdateShareViaLinkOperation extends SyncOperation {
         );
         updateOp.setPassword(mPassword);
         updateOp.setExpirationDate(mExpirationDateInMillis);
+        updateOp.setPublicUpload(mPublicUpload);
         RemoteOperationResult result = updateOp.execute(client);
 
         if (result.isSuccess()) {

+ 73 - 31
src/com/owncloud/android/providers/UsersAndGroupsSearchProvider.java

@@ -1,21 +1,21 @@
 /**
- *   ownCloud Android client application
- *
- *   @author David A. Velasco
- *   Copyright (C) 2015 ownCloud Inc.
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License version 2,
- *   as published by the Free Software Foundation.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * ownCloud Android client application
  *
+ * @author David A. Velasco
+ * @author Juan Carlos González Cabrero
+ * Copyright (C) 2015 ownCloud Inc.
+ * <p/>
+ * 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.
+ * <p/>
+ * 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.
+ * <p/>
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 
@@ -37,15 +37,18 @@ import android.widget.Toast;
 
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
+import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.resources.shares.GetRemoteShareesOperation;
+import com.owncloud.android.lib.resources.shares.ShareType;
 import com.owncloud.android.utils.ErrorMessageAdapter;
 
 import org.json.JSONException;
 import org.json.JSONObject;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 
@@ -58,9 +61,9 @@ public class UsersAndGroupsSearchProvider extends ContentProvider {
     private static final String TAG = UsersAndGroupsSearchProvider.class.getSimpleName();
 
     private static final String[] COLUMNS = {
-        BaseColumns._ID,
-        SearchManager.SUGGEST_COLUMN_TEXT_1,
-        SearchManager.SUGGEST_COLUMN_INTENT_DATA
+            BaseColumns._ID,
+            SearchManager.SUGGEST_COLUMN_TEXT_1,
+            SearchManager.SUGGEST_COLUMN_INTENT_DATA
     };
 
     private static final int SEARCH = 1;
@@ -70,11 +73,29 @@ public class UsersAndGroupsSearchProvider extends ContentProvider {
 
     public static final String AUTHORITY = UsersAndGroupsSearchProvider.class.getCanonicalName();
     public static final String ACTION_SHARE_WITH = AUTHORITY + ".action.SHARE_WITH";
+
+    public static final String CONTENT = "content";
+
     public static final String DATA_USER = AUTHORITY + ".data.user";
     public static final String DATA_GROUP = AUTHORITY + ".data.group";
+    public static final String DATA_REMOTE = AUTHORITY + ".data.remote";
 
     private UriMatcher mUriMatcher;
 
+    private static HashMap<String, ShareType> sShareTypes;
+
+    static {
+        sShareTypes = new HashMap<>();
+        sShareTypes.put(DATA_USER, ShareType.USER);
+        sShareTypes.put(DATA_GROUP, ShareType.GROUP);
+        sShareTypes.put(DATA_REMOTE, ShareType.FEDERATED);
+    }
+
+    public static ShareType getShareType(String authority) {
+
+        return sShareTypes.get(authority);
+    }
+
     @Nullable
     @Override
     public String getType(Uri uri) {
@@ -91,7 +112,7 @@ public class UsersAndGroupsSearchProvider extends ContentProvider {
 
     /**
      * TODO description
-     *
+     * <p/>
      * Reference: http://developer.android.com/guide/topics/search/adding-custom-suggestions.html#CustomContentProvider
      *
      * @param uri           Content {@link Uri}, formattted as
@@ -101,7 +122,7 @@ public class UsersAndGroupsSearchProvider extends ContentProvider {
      * @param selection     Expected to be NULL.
      * @param selectionArgs Expected to be NULL.
      * @param sortOrder     Expected to be NULL.
-     * @return              Cursor with users and groups in the ownCloud server that match 'userQuery'.
+     * @return Cursor with users and groups in the ownCloud server that match 'userQuery'.
      */
     @Nullable
     @Override
@@ -148,31 +169,52 @@ public class UsersAndGroupsSearchProvider extends ContentProvider {
         if (names.size() > 0) {
             response = new MatrixCursor(COLUMNS);
             Iterator<JSONObject> namesIt = names.iterator();
-            int count = 0;
             JSONObject item;
-            String displayName;
-            Uri dataUri;
-            Uri userBaseUri = new Uri.Builder().scheme("content").authority(DATA_USER).build();
-            Uri groupBaseUri = new Uri.Builder().scheme("content").authority(DATA_GROUP).build();
+            String displayName = null;
+            Uri dataUri = null;
+            int count = 0;
+
+            Uri userBaseUri = new Uri.Builder().scheme(CONTENT).authority(DATA_USER).build();
+            Uri groupBaseUri = new Uri.Builder().scheme(CONTENT).authority(DATA_GROUP).build();
+            Uri remoteBaseUri = new Uri.Builder().scheme(CONTENT).authority(DATA_REMOTE).build();
+
+            FileDataStorageManager manager = new FileDataStorageManager(account, getContext().getContentResolver());
+            boolean federatedShareAllowed = manager.getCapability(account.name).getFilesSharingFederationOutgoing()
+                    .isTrue();
+
             try {
                 while (namesIt.hasNext()) {
                     item = namesIt.next();
                     String userName = item.getString(GetRemoteShareesOperation.PROPERTY_LABEL);
                     JSONObject value = item.getJSONObject(GetRemoteShareesOperation.NODE_VALUE);
-                    byte type = (byte) value.getInt(GetRemoteShareesOperation.PROPERTY_SHARE_TYPE);
+                    int type = value.getInt(GetRemoteShareesOperation.PROPERTY_SHARE_TYPE);
                     String shareWith = value.getString(GetRemoteShareesOperation.PROPERTY_SHARE_WITH);
-                    if (GetRemoteShareesOperation.GROUP_TYPE.equals(type)) {
+
+                    if (ShareType.GROUP.getValue() == type) {
                         displayName = getContext().getString(R.string.share_group_clarification, userName);
                         dataUri = Uri.withAppendedPath(groupBaseUri, shareWith);
-                    } else {
+                    } else if (ShareType.FEDERATED.getValue() == type && federatedShareAllowed) {
+                        if (userName.equals(shareWith)) {
+                            displayName = getContext().getString(R.string.share_remote_clarification, userName);
+                        } else {
+                            String[] uriSplitted = shareWith.split("@");
+                            displayName = getContext().getString(R.string.share_known_remote_clarification, userName,
+                                uriSplitted[uriSplitted.length - 1]);
+                        }
+                        dataUri = Uri.withAppendedPath(remoteBaseUri, shareWith);
+                    } else if (ShareType.USER.getValue() == type) {
                         displayName = userName;
                         dataUri = Uri.withAppendedPath(userBaseUri, shareWith);
                     }
-                    response.newRow()
+
+                    if (displayName != null && dataUri != null) {
+                        response.newRow()
                             .add(count++)             // BaseColumns._ID
                             .add(displayName)         // SearchManager.SUGGEST_COLUMN_TEXT_1
                             .add(dataUri);
+                    }
                 }
+
             } catch (JSONException e) {
                 Log_OC.e(TAG, "Exception while parsing data of users/groups", e);
             }
@@ -203,7 +245,7 @@ public class UsersAndGroupsSearchProvider extends ContentProvider {
     /**
      * Show error message
      *
-     * @param result    Result with the failure information.
+     * @param result Result with the failure information.
      */
     public void showErrorMessage(final RemoteOperationResult result) {
         Handler handler = new Handler(Looper.getMainLooper());

+ 5 - 1
src/com/owncloud/android/services/OperationsService.java

@@ -96,6 +96,7 @@ public class OperationsService extends Service {
     public static final String EXTRA_SHARE_WITH = "SHARE_WITH";
     public static final String EXTRA_SHARE_EXPIRATION_DATE_IN_MILLIS = "SHARE_EXPIRATION_YEAR";
     public static final String EXTRA_SHARE_PERMISSIONS = "SHARE_PERMISSIONS";
+    public static final String EXTRA_SHARE_PUBLIC_UPLOAD = "SHARE_PUBLIC_UPLOAD";
     public static final String EXTRA_SHARE_ID = "SHARE_ID";
 
     public static final String EXTRA_COOKIE = "COOKIE";
@@ -578,7 +579,7 @@ public class OperationsService extends Service {
                         operation = new UpdateShareViaLinkOperation(remotePath);
 
                         String password = operationIntent.getStringExtra(EXTRA_SHARE_PASSWORD);
-                        ((UpdateShareViaLinkOperation)operation).setPassword(password);
+                        ((UpdateShareViaLinkOperation) operation).setPassword(password);
 
                         long expirationDate = operationIntent.getLongExtra(
                                 EXTRA_SHARE_EXPIRATION_DATE_IN_MILLIS,
@@ -588,6 +589,9 @@ public class OperationsService extends Service {
                                 expirationDate
                         );
 
+                        boolean publicUpload = operationIntent.getBooleanExtra(EXTRA_SHARE_PUBLIC_UPLOAD, false);
+                        ((UpdateShareViaLinkOperation) operation).setPublicUpload(publicUpload);
+
                     } else if (shareId > 0) {
                         operation = new UpdateSharePermissionsOperation(shareId);
                         int permissions = operationIntent.getIntExtra(EXTRA_SHARE_PERMISSIONS, 1);

+ 47 - 39
src/com/owncloud/android/ui/activity/ShareActivity.java

@@ -1,22 +1,22 @@
 /**
- *   ownCloud Android client application
- *
- *   @author masensio
- *   @author David A. Velasco
- *   Copyright (C) 2015 ownCloud Inc.
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License version 2,
- *   as published by the Free Software Foundation.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * ownCloud Android client application
  *
+ * @author masensio
+ * @author David A. Velasco
+ * @author Juan Carlos González Cabrero
+ * Copyright (C) 2015 ownCloud Inc.
+ * <p/>
+ * 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.
+ * <p/>
+ * 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.
+ * <p/>
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 package com.owncloud.android.ui.activity;
@@ -30,18 +30,17 @@ import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentTransaction;
 
 import com.owncloud.android.R;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.lib.common.operations.RemoteOperation;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.lib.resources.shares.OCShare;
+import com.owncloud.android.lib.resources.shares.ShareType;
 import com.owncloud.android.operations.CreateShareViaLinkOperation;
 import com.owncloud.android.operations.GetSharesForFileOperation;
 import com.owncloud.android.operations.UnshareOperation;
 import com.owncloud.android.operations.UpdateSharePermissionsOperation;
 import com.owncloud.android.providers.UsersAndGroupsSearchProvider;
-
-import com.owncloud.android.lib.common.operations.RemoteOperation;
-import com.owncloud.android.lib.common.operations.RemoteOperationResult;
-import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.lib.resources.shares.OCShare;
-import com.owncloud.android.lib.resources.shares.ShareType;
 import com.owncloud.android.ui.dialog.ShareLinkToDialog;
 import com.owncloud.android.ui.fragment.EditShareFragment;
 import com.owncloud.android.ui.fragment.SearchShareesFragment;
@@ -63,7 +62,9 @@ public class ShareActivity extends FileActivity
     private static final String TAG_SEARCH_FRAGMENT = "SEARCH_USER_AND_GROUPS_FRAGMENT";
     private static final String TAG_EDIT_SHARE_FRAGMENT = "EDIT_SHARE_FRAGMENT";
 
-    /** Tag for dialog */
+    /**
+     * Tag for dialog
+     */
     private static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG";
 
     @Override
@@ -108,7 +109,7 @@ public class ShareActivity extends FileActivity
             String shareWith = dataString.substring(dataString.lastIndexOf('/') + 1);
             doShareWith(
                     shareWith,
-                    UsersAndGroupsSearchProvider.DATA_GROUP.equals(data.getAuthority())
+                    data.getAuthority()
             );
 
         } else {
@@ -116,25 +117,32 @@ public class ShareActivity extends FileActivity
         }
     }
 
-    private void doShareWith(String shareeName, boolean isGroup) {
+    private void doShareWith(String shareeName, String dataAuthority) {
+
+        ShareType shareType = UsersAndGroupsSearchProvider.getShareType(dataAuthority);
+
         getFileOperationsHelper().shareFileWithSharee(
                 getFile(),
                 shareeName,
-                (isGroup ? ShareType.GROUP : ShareType.USER),
-                getAppropiatePermissions()
+                shareType,
+                getAppropiatePermissions(shareType)
         );
     }
 
 
-    private int getAppropiatePermissions() {
+    private int getAppropiatePermissions(ShareType shareType) {
+
+        // check if the Share is FERERATED
+        boolean isFederated = ShareType.FEDERATED.equals(shareType);
+
         if (getFile().isSharedWithMe()) {
             return OCShare.READ_PERMISSION_FLAG;    // minimum permissions
 
         } else if (getFile().isFolder()) {
-            return OCShare.MAXIMUM_PERMISSIONS_FOR_FOLDER;
+            return (isFederated) ? OCShare.FEDERATED_PERMISSIONS_FOR_FOLDER : OCShare.MAXIMUM_PERMISSIONS_FOR_FOLDER;
 
         } else {    // isFile
-            return OCShare.MAXIMUM_PERMISSIONS_FOR_FILE;
+            return (isFederated) ? OCShare.FEDERATED_PERMISSIONS_FOR_FILE : OCShare.MAXIMUM_PERMISSIONS_FOR_FILE;
         }
     }
 
@@ -191,10 +199,10 @@ public class ShareActivity extends FileActivity
         super.onRemoteOperationFinish(operation, result);
 
         if (result.isSuccess() ||
-            (operation instanceof GetSharesForFileOperation &&
-                result.getCode() == RemoteOperationResult.ResultCode.SHARE_NOT_FOUND
-            )
-        ) {
+                (operation instanceof GetSharesForFileOperation &&
+                        result.getCode() == RemoteOperationResult.ResultCode.SHARE_NOT_FOUND
+                )
+                ) {
             Log_OC.d(TAG, "Refreshing view on successful operation or finished refresh");
             refreshSharesFromStorageManager();
         }
@@ -245,7 +253,7 @@ public class ShareActivity extends FileActivity
 
         EditShareFragment editShareFragment = getEditShareFragment();
         if (editShareFragment != null &&
-                editShareFragment.isAdded())    {
+                editShareFragment.isAdded()) {
             editShareFragment.refreshUiFromDB();
         }
 
@@ -254,7 +262,7 @@ public class ShareActivity extends FileActivity
     /**
      * Shortcut to get access to the {@link ShareFileFragment} instance, if any
      *
-     * @return  A {@link ShareFileFragment} instance, or null
+     * @return A {@link ShareFileFragment} instance, or null
      */
     private ShareFileFragment getShareFileFragment() {
         return (ShareFileFragment) getSupportFragmentManager().findFragmentByTag(TAG_SHARE_FRAGMENT);
@@ -263,7 +271,7 @@ public class ShareActivity extends FileActivity
     /**
      * Shortcut to get access to the {@link SearchShareesFragment} instance, if any
      *
-     * @return  A {@link SearchShareesFragment} instance, or null
+     * @return A {@link SearchShareesFragment} instance, or null
      */
     private SearchShareesFragment getSearchFragment() {
         return (SearchShareesFragment) getSupportFragmentManager().findFragmentByTag(TAG_SEARCH_FRAGMENT);
@@ -272,7 +280,7 @@ public class ShareActivity extends FileActivity
     /**
      * Shortcut to get access to the {@link EditShareFragment} instance, if any
      *
-     * @return  A {@link EditShareFragment} instance, or null
+     * @return A {@link EditShareFragment} instance, or null
      */
     private EditShareFragment getEditShareFragment() {
         return (EditShareFragment) getSupportFragmentManager().findFragmentByTag(TAG_EDIT_SHARE_FRAGMENT);

+ 14 - 9
src/com/owncloud/android/ui/fragment/EditShareFragment.java

@@ -38,6 +38,7 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.resources.shares.OCShare;
 import com.owncloud.android.lib.resources.shares.SharePermissionsBuilder;
+import com.owncloud.android.lib.resources.shares.ShareType;
 import com.owncloud.android.ui.activity.FileActivity;
 
 public class EditShareFragment extends Fragment {
@@ -131,7 +132,6 @@ public class EditShareFragment extends Fragment {
 
         // Setup layout
         refreshUiFromState(view);
-        setPermissionsListening(view, true);
 
         return view;
     }
@@ -147,9 +147,13 @@ public class EditShareFragment extends Fragment {
             setPermissionsListening(editShareView, false);
 
             int sharePermissions = mShare.getPermissions();
+            boolean isFederated = ShareType.FEDERATED.equals(mShare.getShareType());
             CompoundButton compound;
 
             compound = (CompoundButton) editShareView.findViewById(R.id.canShareSwitch);
+            if(isFederated) {
+                compound.setVisibility(View.INVISIBLE);
+            }
             compound.setChecked((sharePermissions & OCShare.SHARE_PERMISSION_FLAG) > 0);
 
             compound = (CompoundButton) editShareView.findViewById(R.id.canEditSwitch);
@@ -160,7 +164,7 @@ public class EditShareFragment extends Fragment {
             boolean canEdit = (sharePermissions & anyUpdatePermission) > 0;
             compound.setChecked(canEdit);
 
-            if (mFile.isFolder()) {
+            if (mFile.isFolder() && !isFederated) {
                 compound = (CompoundButton) editShareView.findViewById(R.id.canEditCreateCheckBox);
                 compound.setChecked((sharePermissions & OCShare.CREATE_PERMISSION_FLAG) > 0);
                 compound.setVisibility(canEdit ? View.VISIBLE : View.GONE);
@@ -245,21 +249,20 @@ public class EditShareFragment extends Fragment {
                 case R.id.canEditSwitch:
                     Log_OC.v(TAG, "canEditCheckBox toggled to " + isChecked);
                     /// sync subordinate CheckBoxes
+                    boolean isFederated = ShareType.FEDERATED.equals(mShare.getShareType());
                     if (mFile.isFolder()) {
                         if (isChecked) {
                             for (int i = 0; i < sSubordinateCheckBoxIds.length; i++) {
                                 //noinspection ConstantConditions, prevented in the method beginning
                                 subordinate = (CompoundButton) getView().findViewById(sSubordinateCheckBoxIds[i]);
-                                subordinate.setVisibility(View.VISIBLE);
+                                if (!isFederated) {
+                                    subordinate.setVisibility(View.VISIBLE);
+                                }
                                 if (!subordinate.isChecked() &&
                                         !mFile.isSharedWithMe()) {          // see (1)
                                     toggleDisablingListener(subordinate);
                                 }
                             }
-                            if (!mFile.isSharedWithMe()) {
-                                updatePermissionsToShare(); // see (1)
-                            }
-
                         } else {
                             for (int i = 0; i < sSubordinateCheckBoxIds.length; i++) {
                                 //noinspection ConstantConditions, prevented in the method beginning
@@ -269,11 +272,13 @@ public class EditShareFragment extends Fragment {
                                     toggleDisablingListener(subordinate);
                                 }
                             }
-                            updatePermissionsToShare(); // see (1)
                         }
-                    } else {
+                    }
+
+                    if(!(mFile.isFolder() && isChecked && mFile.isSharedWithMe())) {    // see (1)
                         updatePermissionsToShare();
                     }
+
                     // updatePermissionsToShare()   // see (1)
                     // (1) These modifications result in an exceptional UI behaviour for the case
                     // where the switch 'can edit' is enabled for a *reshared folder*; if the same

+ 157 - 50
src/com/owncloud/android/ui/fragment/ShareFileFragment.java

@@ -1,22 +1,22 @@
 /**
- *   ownCloud Android client application
- *
- *   @author masensio
- *   @author David A. Velasco
- *   Copyright (C) 2015 ownCloud Inc.
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License version 2,
- *   as published by the Free Software Foundation.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * ownCloud Android client application
  *
+ * @author masensio
+ * @author David A. Velasco
+ * @author Juan Carlos González Cabrero
+ * Copyright (C) 2015 ownCloud Inc.
+ * <p/>
+ * 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.
+ * <p/>
+ * 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.
+ * <p/>
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 package com.owncloud.android.ui.fragment;
@@ -55,57 +55,74 @@ import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.MimetypeIconUtil;
 
 import java.text.SimpleDateFormat;
-
 import java.util.ArrayList;
 import java.util.Date;
 
 /**
  * Fragment for Sharing a file with sharees (users or groups) or creating
  * a public link.
- *
+ * <p/>
  * A simple {@link Fragment} subclass.
- *
+ * <p/>
  * Activities that contain this fragment must implement the
  * {@link ShareFragmentListener} interface
  * to handle interaction events.
- *
+ * <p/>
  * Use the {@link ShareFileFragment#newInstance} factory method to
  * create an instance of this fragment.
  */
 public class ShareFileFragment extends Fragment
-        implements ShareUserListAdapter.ShareUserAdapterListener{
+        implements ShareUserListAdapter.ShareUserAdapterListener {
 
     private static final String TAG = ShareFileFragment.class.getSimpleName();
 
-    /** The fragment initialization parameters */
+    /**
+     * The fragment initialization parameters
+     */
     private static final String ARG_FILE = "FILE";
     private static final String ARG_ACCOUNT = "ACCOUNT";
 
 //    /** Tag for dialog */
 //    private static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG";
 
-    /** File to share, received as a parameter in construction time */
+    /**
+     * File to share, received as a parameter in construction time
+     */
     private OCFile mFile;
 
-    /** OC account holding the file to share, received as a parameter in construction time */
+    /**
+     * OC account holding the file to share, received as a parameter in construction time
+     */
     private Account mAccount;
 
-    /** Reference to parent listener */
+    /**
+     * Reference to parent listener
+     */
     private ShareFragmentListener mListener;
 
-    /** List of private shares bound to the file */
+    /**
+     * List of private shares bound to the file
+     */
     private ArrayList<OCShare> mPrivateShares;
 
-    /** Capabilities of the server */
+    /**
+     * Capabilities of the server
+     */
     private OCCapability mCapabilities;
 
-    /** Adapter to show private shares */
+    /**
+     * Adapter to show private shares
+     */
     private ShareUserListAdapter mUserGroupsAdapter = null;
 
-    /** Public share bound to the file */
+    /**
+     * Public share bound to the file
+     */
     private OCShare mPublicShare;
 
-    /** Listener for changes on switch to share / unshare publicly */
+    /**
+     * Listener for changes on switch to share / unshare publicly
+     */
     private CompoundButton.OnCheckedChangeListener mOnShareViaLinkSwitchCheckedChangeListener;
 
     /**
@@ -118,6 +135,11 @@ public class ShareFileFragment extends Fragment
      */
     private OnExpirationDateInteractionListener mOnExpirationDateInteractionListener = null;
 
+    /**
+     * Listener for user actions to set or unset edit permission on public link
+     */
+    private OnEditPermissionInteractionListener mOnEditPermissionInteractionListener = null;
+
 
     /**
      * Public factory method to create new ShareFileFragment instances.
@@ -215,6 +237,9 @@ public class ShareFileFragment extends Fragment
         // Set listener for user actions on password
         initPasswordListener(view);
 
+        // Set listener for user actions on edit permission
+        initEditPermissionListener(view);
+
         return view;
     }
 
@@ -223,7 +248,7 @@ public class ShareFileFragment extends Fragment
      * Binds listener for user actions to create or delete a public share
      * to the views receiving the user events.
      *
-     * @param shareView     Root view in the fragment.
+     * @param shareView Root view in the fragment.
      */
     private void initShareViaLinkListener(View shareView) {
         mOnShareViaLinkSwitchCheckedChangeListener = new OnShareViaLinkListener();
@@ -240,8 +265,8 @@ public class ShareFileFragment extends Fragment
         /**
          * Called by R.id.shareViaLinkSectionSwitch to create or delete a public link.
          *
-         * @param switchView    {@link Switch} toggled by the user, R.id.shareViaLinkSectionSwitch
-         * @param isChecked     New switch state.
+         * @param switchView {@link Switch} toggled by the user, R.id.shareViaLinkSectionSwitch
+         * @param isChecked  New switch state.
          */
         @Override
         public void onCheckedChanged(CompoundButton switchView, boolean isChecked) {
@@ -284,7 +309,7 @@ public class ShareFileFragment extends Fragment
      * Binds listener for user actions that start any update on a expiration date
      * for the public link to the views receiving the user events.
      *
-     * @param shareView     Root view in the fragment.
+     * @param shareView Root view in the fragment.
      */
     private void initExpirationListener(View shareView) {
         mOnExpirationDateInteractionListener = new OnExpirationDateInteractionListener();
@@ -308,8 +333,8 @@ public class ShareFileFragment extends Fragment
         /**
          * Called by R.id.shareViaLinkExpirationSwitch to set or clear the expiration date.
          *
-         * @param switchView    {@link Switch} toggled by the user, R.id.shareViaLinkExpirationSwitch
-         * @param isChecked     New switch state.
+         * @param switchView {@link Switch} toggled by the user, R.id.shareViaLinkExpirationSwitch
+         * @param isChecked  New switch state.
          */
         @Override
         public void onCheckedChanged(CompoundButton switchView, boolean isChecked) {
@@ -341,7 +366,7 @@ public class ShareFileFragment extends Fragment
          * Called by R.id.shareViaLinkExpirationLabel or R.id.shareViaLinkExpirationValue
          * to change the current expiration date.
          *
-         * @param expirationView      Label or value view touched by the user.
+         * @param expirationView Label or value view touched by the user.
          */
         @Override
         public void onClick(View expirationView) {
@@ -368,7 +393,7 @@ public class ShareFileFragment extends Fragment
      * Binds listener for user actions that start any update on a password for the public link
      * to the views receiving the user events.
      *
-     * @param shareView     Root view in the fragment.
+     * @param shareView Root view in the fragment.
      */
     private void initPasswordListener(View shareView) {
         mOnPasswordInteractionListener = new OnPasswordInteractionListener();
@@ -393,8 +418,8 @@ public class ShareFileFragment extends Fragment
         /**
          * Called by R.id.shareViaLinkPasswordSwitch to set or clear the password.
          *
-         * @param switchView    {@link Switch} toggled by the user, R.id.shareViaLinkPasswordSwitch
-         * @param isChecked     New switch state.
+         * @param switchView {@link Switch} toggled by the user, R.id.shareViaLinkPasswordSwitch
+         * @param isChecked  New switch state.
          */
         @Override
         public void onCheckedChanged(CompoundButton switchView, boolean isChecked) {
@@ -421,7 +446,7 @@ public class ShareFileFragment extends Fragment
          * Called by R.id.shareViaLinkPasswordLabel or R.id.shareViaLinkPasswordValue
          * to change the current password.
          *
-         * @param passwordView      Label or value view touched by the user.
+         * @param passwordView Label or value view touched by the user.
          */
         @Override
         public void onClick(View passwordView) {
@@ -432,6 +457,55 @@ public class ShareFileFragment extends Fragment
         }
     }
 
+    /**
+     * Binds listener for user actions that start any update the edit permissions
+     * for the public link to the views receiving the user events.
+     *
+     * @param shareView Root view in the fragment.
+     */
+    private void initEditPermissionListener(View shareView) {
+        mOnEditPermissionInteractionListener = new OnEditPermissionInteractionListener();
+
+        ((Switch) shareView.findViewById(R.id.shareViaLinkEditPermissionSwitch)).
+                setOnCheckedChangeListener(mOnEditPermissionInteractionListener);
+
+    }
+
+    /**
+     * Listener for user actions that start any update on the edit permissions for the public link.
+     */
+    private class OnEditPermissionInteractionListener
+            implements CompoundButton.OnCheckedChangeListener {
+
+        /**
+         * Called by R.id.shareViaLinkEditPermissionSwitch to set or clear the edit permission.
+         *
+         * @param switchView {@link Switch} toggled by the user, R.id.shareViaLinkEditPermissionSwitch
+         * @param isChecked  New switch state.
+         */
+        @Override
+        public void onCheckedChanged(CompoundButton switchView, boolean isChecked) {
+            if (!isResumed()) {
+                // very important, setCheched(...) is called automatically during
+                // Fragment recreation on device rotations
+                return;
+            }
+
+            ((FileActivity) getActivity()).getFileOperationsHelper().
+                    setUploadPermissionsToShare(
+                            mFile,
+                            isChecked
+                    );
+            ;
+
+            // undo the toggle to grant the view will be correct if the dialog is cancelled
+            switchView.setOnCheckedChangeListener(null);
+            switchView.toggle();
+            switchView.setOnCheckedChangeListener(mOnEditPermissionInteractionListener);
+        }
+
+    }
+
 
     @Override
     public void onActivityCreated(Bundle savedInstanceState) {
@@ -470,13 +544,13 @@ public class ShareFileFragment extends Fragment
 
     /**
      * Get known server capabilities from DB
-     *
+     * <p/>
      * Depends on the parent Activity provides a {@link com.owncloud.android.datamodel.FileDataStorageManager}
      * instance ready to use. If not ready, does nothing.
      */
     public void refreshCapabilitiesFromDB() {
-        if (((FileActivity)mListener).getStorageManager() != null) {
-            mCapabilities = ((FileActivity)mListener).getStorageManager().
+        if (((FileActivity) mListener).getStorageManager() != null) {
+            mCapabilities = ((FileActivity) mListener).getStorageManager().
                     getCapability(mAccount.name);
         }
     }
@@ -484,11 +558,11 @@ public class ShareFileFragment extends Fragment
 
     /**
      * Get users and groups from the DB to fill in the "share with" list.
-     *
+     * <p/>
      * Depends on the parent Activity provides a {@link com.owncloud.android.datamodel.FileDataStorageManager}
      * instance ready to use. If not ready, does nothing.
      */
-    public void refreshUsersOrGroupsListFromDB (){
+    public void refreshUsersOrGroupsListFromDB() {
         if (((FileActivity) mListener).getStorageManager() != null) {
             // Get Users and Groups
             mPrivateShares = ((FileActivity) mListener).getStorageManager().getSharesWithForAFile(
@@ -547,9 +621,9 @@ public class ShareFileFragment extends Fragment
 
     /**
      * Get public link from the DB to fill in the "Share link" section in the UI.
-     *
+     * <p/>
      * Takes into account server capabilities before reading database.
-     *
+     * <p/>
      * Depends on the parent Activity provides a {@link com.owncloud.android.datamodel.FileDataStorageManager}
      * instance ready to use. If not ready, does nothing.
      */
@@ -571,7 +645,7 @@ public class ShareFileFragment extends Fragment
     }
 
     /**
-     * @return  'True' when public share is disabled in the server
+     * @return 'True' when public share is disabled in the server
      */
     private boolean isPublicShareDisabled() {
         return (mCapabilities != null &&
@@ -597,6 +671,11 @@ public class ShareFileFragment extends Fragment
             }
             getExpirationDateSection().setVisibility(View.VISIBLE);
             getPasswordSection().setVisibility(View.VISIBLE);
+            if (mFile.isFolder() && !mCapabilities.getFilesSharingPublicUpload().isFalse()) {
+                getEditPermissionSection().setVisibility(View.VISIBLE);
+            } else {
+                getEditPermissionSection().setVisibility(View.GONE);
+            }
             // GetLink button
             AppCompatButton getLinkButton = getGetLinkButton();
             getLinkButton.setVisibility(View.VISIBLE);
@@ -655,6 +734,24 @@ public class ShareFileFragment extends Fragment
                     mOnPasswordInteractionListener
             );
 
+            /// update state of the edit permission switch
+            Switch editPermissionSwitch = getEditPermissionSwitch();
+
+            // set null listener before setChecked() to prevent infinite loop of calls
+            editPermissionSwitch.setOnCheckedChangeListener(null);
+            if (mPublicShare.getPermissions() > OCShare.READ_PERMISSION_FLAG) {
+                if (!editPermissionSwitch.isChecked()) {
+                    editPermissionSwitch.toggle();
+                }
+            } else {
+                if (editPermissionSwitch.isChecked()) {
+                    editPermissionSwitch.toggle();
+                }
+            }
+            // recover listener
+            editPermissionSwitch.setOnCheckedChangeListener(
+                    mOnEditPermissionInteractionListener
+            );
 
         } else {
             /// no public share -> collapse section
@@ -668,6 +765,7 @@ public class ShareFileFragment extends Fragment
             }
             getExpirationDateSection().setVisibility(View.GONE);
             getPasswordSection().setVisibility(View.GONE);
+            getEditPermissionSection().setVisibility(View.GONE);
             getGetLinkButton().setVisibility(View.GONE);
         }
     }
@@ -703,6 +801,14 @@ public class ShareFileFragment extends Fragment
         return (TextView) getView().findViewById(R.id.shareViaLinkPasswordValue);
     }
 
+    private View getEditPermissionSection() {
+        return getView().findViewById(R.id.shareViaLinkEditPermissionSection);
+    }
+
+    private Switch getEditPermissionSwitch() {
+        return (Switch) getView().findViewById(R.id.shareViaLinkEditPermissionSwitch);
+    }
+
     private AppCompatButton getGetLinkButton() {
         return (AppCompatButton) getView().findViewById(R.id.shareViaLinkGetLinkButton);
     }
@@ -714,6 +820,7 @@ public class ShareFileFragment extends Fragment
         getShareViaLinkSwitch().setVisibility(View.GONE);
         getExpirationDateSection().setVisibility(View.GONE);
         getPasswordSection().setVisibility(View.GONE);
+        getEditPermissionSection().setVisibility(View.GONE);
         getGetLinkButton().setVisibility(View.GONE);
     }