Эх сурвалжийг харах

rewrite of sharing logic/persistence to store and use the fact if a share(mail) is password protected

AndyScherzinger 6 жил өмнө
parent
commit
62a53dc3e5

+ 7 - 0
src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java

@@ -997,6 +997,8 @@ public class FileDataStorageManager {
         cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getRemoteId());
         cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name);
 
+        cv.put(ProviderTableMeta.OCSHARES_IS_PASSWORD_PROTECTED, share.isPasswordProtected());
+
         if (shareExistsForRemoteId(share.getRemoteId())) {// for renamed files; no more delete and create
             overriden = true;
             if (getContentResolver() != null) {
@@ -1200,6 +1202,7 @@ public class FileDataStorageManager {
             share.setIsFolder(c.getInt(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.setIsPasswordProtected(c.getInt(c.getColumnIndex(ProviderTableMeta.OCSHARES_IS_PASSWORD_PROTECTED)) == 1);
         }
         return share;
     }
@@ -1307,6 +1310,8 @@ public class FileDataStorageManager {
                 cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getRemoteId());
                 cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name);
 
+                cv.put(ProviderTableMeta.OCSHARES_IS_PASSWORD_PROTECTED, share.isPasswordProtected() ? 1 : 0);
+
                 if (shareExistsForRemoteId(share.getRemoteId())) {
                     // updating an existing file
                     operations.add(
@@ -1588,6 +1593,8 @@ public class FileDataStorageManager {
                 cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getRemoteId());
                 cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name);
 
+                cv.put(ProviderTableMeta.OCSHARES_IS_PASSWORD_PROTECTED, share.isPasswordProtected() ? 1 : 0);
+
                 // adding a new share resource
                 operations.add(
                         ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI_SHARE).

+ 3 - 2
src/main/java/com/owncloud/android/db/ProviderMeta.java

@@ -1,4 +1,4 @@
-/**
+/*
  * ownCloud Android client application
  *
  * @author Bartek Przybylski
@@ -32,7 +32,7 @@ import com.owncloud.android.MainApp;
 public class ProviderMeta {
 
     public static final String DB_NAME = "filelist";
-    public static final int DB_VERSION = 31;
+    public static final int DB_VERSION = 32;
 
     private ProviderMeta() {
     }
@@ -128,6 +128,7 @@ public class ProviderMeta {
         public static final String OCSHARES_USER_ID = "user_id";
         public static final String OCSHARES_ID_REMOTE_SHARED = "id_remote_shared";
         public static final String OCSHARES_ACCOUNT_OWNER = "owner_share";
+        public static final String OCSHARES_IS_PASSWORD_PROTECTED = "is_password_protected";
 
         public static final String OCSHARES_DEFAULT_SORT_ORDER = OCSHARES_FILE_SOURCE
                 + " collate nocase asc";

+ 20 - 0
src/main/java/com/owncloud/android/operations/UpdateSharePermissionsOperation.java

@@ -39,6 +39,7 @@ public class UpdateSharePermissionsOperation extends SyncOperation {
     private long mShareId;
     private int mPermissions;
     private long mExpirationDateInMillis;
+    private String mPassword;
     private String mPath;
 
     /**
@@ -50,6 +51,18 @@ public class UpdateSharePermissionsOperation extends SyncOperation {
         mShareId = shareId;
         mPermissions = -1;
         mExpirationDateInMillis = 0L;
+        mPassword = null;
+    }
+
+    /**
+     * Set password to update in private share.
+     *
+     * @param password      Password to set to the private share.
+     *                      Empty string clears the current password.
+     *                      Null results in no update applied to the password.
+     */
+    public void setPassword(String password) {
+        mPassword = password;
     }
 
     /**
@@ -88,6 +101,7 @@ public class UpdateSharePermissionsOperation extends SyncOperation {
 
         // Update remote share with password
         UpdateRemoteShareOperation updateOp = new UpdateRemoteShareOperation(share.getRemoteId());
+        updateOp.setPassword(mPassword);
         updateOp.setPermissions(mPermissions);
         updateOp.setExpirationDate(mExpirationDateInMillis);
         RemoteOperationResult result = updateOp.execute(client);
@@ -109,6 +123,10 @@ public class UpdateSharePermissionsOperation extends SyncOperation {
         return mPath;
     }
 
+    public String getPassword() {
+        return mPassword;
+    }
+
     private void updateData(OCShare share) {
         // Update DB with the response
         share.setPath(mPath);   // TODO - check if may be moved to UpdateRemoteShareOperation
@@ -117,6 +135,8 @@ public class UpdateSharePermissionsOperation extends SyncOperation {
         } else {
             share.setIsFolder(false);
         }
+
+        share.setIsPasswordProtected((mPassword != null && mPassword.length() > 0));
         getStorageManager().saveShare(share);
     }
 

+ 0 - 1
src/main/java/com/owncloud/android/operations/UpdateShareViaLinkOperation.java

@@ -35,7 +35,6 @@ import com.owncloud.android.operations.common.SyncOperation;
 /**
  * Updates an existing public share for a given file
  */
-
 public class UpdateShareViaLinkOperation extends SyncOperation {
 
     private String mPath;

+ 17 - 0
src/main/java/com/owncloud/android/providers/FileContentProvider.java

@@ -1686,6 +1686,23 @@ public class FileContentProvider extends ContentProvider {
                 Log_OC.i(SQL, String.format(Locale.ENGLISH, UPGRADE_VERSION_MSG, oldVersion, newVersion));
             }
 
+            if (oldVersion < 32 && newVersion >= 32) {
+                Log_OC.i(SQL, "Entering in the #32 add ocshares.is_password_protected");
+                db.beginTransaction();
+                try {
+                    db.execSQL(ALTER_TABLE + ProviderTableMeta.OCSHARES_TABLE_NAME +
+                            ADD_COLUMN + ProviderTableMeta.OCSHARES_IS_PASSWORD_PROTECTED + " INTEGER "); // boolean
+
+                    upgraded = true;
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                }
+            }
+
+            if (!upgraded) {
+                Log_OC.i(SQL, String.format(Locale.ENGLISH, UPGRADE_VERSION_MSG, oldVersion, newVersion));
+            }
         }
 
         @Override

+ 2 - 0
src/main/java/com/owncloud/android/services/OperationsService.java

@@ -590,6 +590,8 @@ public class OperationsService extends Service {
                         ((UpdateSharePermissionsOperation)operation).setPermissions(permissions);
                         long expirationDateInMillis = operationIntent.getLongExtra(EXTRA_SHARE_EXPIRATION_DATE_IN_MILLIS, 0L);
                         ((UpdateSharePermissionsOperation)operation).setExpirationDate(expirationDateInMillis);
+                        String password = operationIntent.getStringExtra(EXTRA_SHARE_PASSWORD);
+                        ((UpdateSharePermissionsOperation)operation).setPassword(password);
                     }
 
                 } else if (action.equals(ACTION_CREATE_SHARE_WITH_SHAREE)) {

+ 72 - 11
src/main/java/com/owncloud/android/ui/adapter/UserListAdapter.java

@@ -44,9 +44,10 @@ 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.lib.resources.status.OCCapability;
+import com.owncloud.android.services.OperationsService;
 import com.owncloud.android.ui.TextDrawable;
 import com.owncloud.android.ui.dialog.ExpirationDatePickerDialogFragment;
-import com.owncloud.android.ui.fragment.util.FileDetailSharingFragmentHelper;
+import com.owncloud.android.ui.fragment.util.SharingMenuHelper;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.ThemeUtils;
 
@@ -185,27 +186,52 @@ public class UserListAdapter extends RecyclerView.Adapter<UserListAdapter.UserVi
      */
     private void prepareOptionsMenu(Menu menu, OCShare share) {
 
+        MenuItem editCreateItem = menu.findItem(R.id.action_can_edit_create);
+        MenuItem editChangeItem = menu.findItem(R.id.action_can_edit_change);
+        MenuItem editDeleteItem = menu.findItem(R.id.action_can_edit_delete);
+
+        MenuItem hideFileListingItem = menu.findItem(R.id.action_hide_file_listing);
+        MenuItem passwordItem = menu.findItem(R.id.action_password);
+        MenuItem expirationDateItem = menu.findItem(R.id.action_expiration_date);
+
         MenuItem reshareItem = menu.findItem(R.id.action_can_reshare);
+
         if (isReshareForbidden(share)) {
             reshareItem.setVisible(false);
         }
         reshareItem.setChecked(canReshare(share));
 
-        MenuItem editCreateItem = menu.findItem(R.id.action_can_edit_create);
-        MenuItem editChangeItem = menu.findItem(R.id.action_can_edit_change);
-        MenuItem editDeleteItem = menu.findItem(R.id.action_can_edit_delete);
-        if (file.isFolder() && isEditOptionsAvailable(share)) {
-            /// TODO change areEditOptionsAvailable in order to delete !isFederated
-            editCreateItem.setChecked(canCreate(share));
-            editChangeItem.setChecked(canUpdate(share));
-            editDeleteItem.setChecked(canDelete(share));
-        } else {
+        if (share.getShareType() == ShareType.EMAIL) {
+            SharingMenuHelper.setupHideFileListingMenuItem(
+                    hideFileListingItem,
+                    file.isFolder(),
+                    canEdit(share),
+                    share.getPermissions()
+            );
+            SharingMenuHelper.setupPasswordMenuItem(passwordItem, share.isPasswordProtected());
+
+            reshareItem.setVisible(false);
             editCreateItem.setVisible(false);
             editChangeItem.setVisible(false);
             editDeleteItem.setVisible(false);
+        } else {
+            if (file.isFolder() && isEditOptionsAvailable(share)) {
+                /// TODO change areEditOptionsAvailable in order to delete !isFederated
+                editCreateItem.setChecked(canCreate(share));
+                editChangeItem.setChecked(canUpdate(share));
+                editDeleteItem.setChecked(canDelete(share));
+            } else {
+                editCreateItem.setVisible(false);
+                editChangeItem.setVisible(false);
+                editDeleteItem.setVisible(false);
+            }
+
+            hideFileListingItem.setVisible(false);
+            passwordItem.setVisible(false);
+            expirationDateItem.setVisible(false);
         }
 
-        FileDetailSharingFragmentHelper.setupExpirationDateMenuItem(
+        SharingMenuHelper.setupExpirationDateMenuItem(
                 menu.findItem(R.id.action_expiration_date), share.getExpirationDate(), context.getResources());
     }
 
@@ -279,6 +305,20 @@ public class UserListAdapter extends RecyclerView.Adapter<UserListAdapter.UserVi
                 notifyDataSetChanged();
                 return true;
             }
+            case R.id.action_hide_file_listing: {
+                item.setChecked(!item.isChecked());
+                if (capabilities.getFilesFileDrop().isTrue()) {
+                    listener.setHideFileListingPermissionsToShare(share, item.isChecked());
+                } else {
+                    // not supported in ownCloud
+                    listener.showNotSupportedByOcMessage();
+                }
+                return true;
+            }
+            case R.id.action_password: {
+                listener.requestPasswordForShare(share);
+                return true;
+            }
             case R.id.action_expiration_date: {
                 ExpirationDatePickerDialogFragment dialog = ExpirationDatePickerDialogFragment.newInstance(share, -1);
                 dialog.show(
@@ -362,5 +402,26 @@ public class UserListAdapter extends RecyclerView.Adapter<UserListAdapter.UserVi
                                      boolean canEditCreate,
                                      boolean canEditChange,
                                      boolean canEditDelete);
+
+        /**
+         * show a snackbar that this feature is not supported by ownCloud.
+         */
+        void showNotSupportedByOcMessage();
+
+        /**
+         * Starts a dialog that requests a password to the user to protect a share.
+         *
+         * @param share the share for which a password shall be configured/removed
+         */
+        void requestPasswordForShare(OCShare share);
+
+        /**
+         * Updates a public share on a folder to set its hide file listing permission.
+         * Starts a request to do it in {@link OperationsService}
+         *
+         * @param share           {@link OCShare} instance which permissions will be updated.
+         * @param hideFileListing New state of the permission for editing the folder shared via link.
+         */
+        void setHideFileListingPermissionsToShare(OCShare share, boolean hideFileListing);
     }
 }

+ 32 - 2
src/main/java/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java

@@ -38,6 +38,7 @@ import android.widget.TextView;
 
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.lib.resources.shares.OCShare;
 import com.owncloud.android.ui.activity.FileActivity;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.ThemeUtils;
@@ -50,10 +51,12 @@ import com.owncloud.android.utils.ThemeUtils;
 public class SharePasswordDialogFragment extends DialogFragment implements DialogInterface.OnClickListener {
 
     private static final String ARG_FILE = "FILE";
+    private static final String ARG_SHARE = "SHARE";
     private static final String ARG_CREATE_SHARE = "CREATE_SHARE";
     public static final String PASSWORD_FRAGMENT = "PASSWORD_FRAGMENT";
 
     private OCFile file;
+    private OCShare share;
     private boolean createShare;
 
     @Override
@@ -85,6 +88,20 @@ public class SharePasswordDialogFragment extends DialogFragment implements Dialo
         return frag;
     }
 
+    /**
+     * Public factory method to create new SharePasswordDialogFragment instances.
+     *
+     * @param share        OCFile bound to the public share that which password will be set or updated
+     * @return Dialog ready to show.
+     */
+    public static SharePasswordDialogFragment newInstance(OCShare share) {
+        SharePasswordDialogFragment frag = new SharePasswordDialogFragment();
+        Bundle args = new Bundle();
+        args.putParcelable(ARG_SHARE, share);
+        frag.setArguments(args);
+        return frag;
+    }
+
     @Nullable
     @Override
     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
@@ -95,6 +112,7 @@ public class SharePasswordDialogFragment extends DialogFragment implements Dialo
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         file = getArguments().getParcelable(ARG_FILE);
+        share = getArguments().getParcelable(ARG_SHARE);
         createShare = getArguments().getBoolean(ARG_CREATE_SHARE, false);
 
         // Inflate the layout for the dialog
@@ -141,9 +159,17 @@ public class SharePasswordDialogFragment extends DialogFragment implements Dialo
                 return;
             }
 
-            setPassword(createShare, file, password);
+            if (share == null) {
+                setPassword(createShare, file, password);
+            } else {
+                setPassword(share, password);
+            }
         } else if (which == AlertDialog.BUTTON_NEUTRAL) {
-            setPassword(createShare, file, null);
+            if (share == null) {
+                setPassword(createShare, file, null);
+            } else {
+                setPassword(share, null);
+            }
         }
     }
 
@@ -154,4 +180,8 @@ public class SharePasswordDialogFragment extends DialogFragment implements Dialo
             ((FileActivity) getActivity()).getFileOperationsHelper().setPasswordToShareViaLink(file, password);
         }
     }
+
+    private void setPassword(OCShare share, String password) {
+        ((FileActivity) getActivity()).getFileOperationsHelper().setPasswordToShare(share, password);
+    }
 }

+ 37 - 18
src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java

@@ -58,6 +58,7 @@ import com.owncloud.android.ui.decoration.SimpleListItemDividerDecoration;
 import com.owncloud.android.ui.dialog.ExpirationDatePickerDialogFragment;
 import com.owncloud.android.ui.dialog.SharePasswordDialogFragment;
 import com.owncloud.android.ui.fragment.util.FileDetailSharingFragmentHelper;
+import com.owncloud.android.ui.fragment.util.SharingMenuHelper;
 import com.owncloud.android.utils.ThemeUtils;
 
 import java.util.ArrayList;
@@ -273,18 +274,18 @@ public class FileDetailSharingFragment extends Fragment implements UserListAdapt
 
     private void prepareOptionsMenu(Menu menu) {
         Resources res = getResources();
-        FileDetailSharingFragmentHelper.setupHideFileListingMenuItem(
-                menu.findItem(R.id.action_share_link_hide_file_listing),
+        SharingMenuHelper.setupHideFileListingMenuItem(
+                menu.findItem(R.id.action_hide_file_listing),
                 file.isFolder(),
                 shareByLinkAllowEditing.isChecked(),
                 publicShare.getPermissions()
         );
-        FileDetailSharingFragmentHelper.setupPasswordMenuItem(
-                menu.findItem(R.id.action_share_link_password),
+        SharingMenuHelper.setupPasswordMenuItem(
+                menu.findItem(R.id.action_password),
                 publicShare.isPasswordProtected()
         );
-        FileDetailSharingFragmentHelper.setupExpirationDateMenuItem(
-                menu.findItem(R.id.action_share_link_expiration_date),
+        SharingMenuHelper.setupExpirationDateMenuItem(
+                menu.findItem(R.id.action_share_expiration_date),
                 publicShare.getExpirationDate(),
                 res
         );
@@ -292,28 +293,21 @@ public class FileDetailSharingFragment extends Fragment implements UserListAdapt
 
     private boolean optionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
-            case R.id.action_share_link_hide_file_listing: {
+            case R.id.action_hide_file_listing: {
                 item.setChecked(!item.isChecked());
                 if (capabilities.getFilesFileDrop().isTrue()) {
-                    ((FileActivity) getActivity()).getFileOperationsHelper().
-                            setHideFileListingPermissionsToShare(publicShare, item.isChecked());
+                    setHideFileListingPermissionsToShare(publicShare, item.isChecked());
                 } else {
                     // not supported in ownCloud
-                    Snackbar.make(getView(), R.string.files_drop_not_supported, Snackbar.LENGTH_LONG)
-                            .setAction(R.string.learn_more, v -> {
-                                Intent i = new Intent(Intent.ACTION_VIEW);
-                                i.setData(Uri.parse(getString(R.string.url_server_install)));
-                                startActivity(i);
-                            })
-                            .show();
+                    showNotSupportedByOcMessage();
                 }
                 return true;
             }
-            case R.id.action_share_link_password: {
+            case R.id.action_password: {
                 requestPasswordForShareViaLink(false);
                 return true;
             }
-            case R.id.action_share_link_expiration_date: {
+            case R.id.action_expiration_date: {
                 ExpirationDatePickerDialogFragment dialog = ExpirationDatePickerDialogFragment.newInstance(file, -1);
                 dialog.show(
                         getActivity().getSupportFragmentManager(),
@@ -326,6 +320,25 @@ public class FileDetailSharingFragment extends Fragment implements UserListAdapt
         }
     }
 
+    @Override
+    public void setHideFileListingPermissionsToShare(OCShare share, boolean hideFileListing) {
+        ((FileActivity) getActivity()).getFileOperationsHelper().
+                setHideFileListingPermissionsToShare(share, hideFileListing);
+    }
+
+    @Override
+    public void showNotSupportedByOcMessage() {
+        if (getView() != null) {
+            Snackbar.make(getView(), R.string.files_drop_not_supported, Snackbar.LENGTH_LONG)
+                    .setAction(R.string.learn_more, v -> {
+                        Intent i = new Intent(Intent.ACTION_VIEW);
+                        i.setData(Uri.parse(getString(R.string.url_server_install)));
+                        startActivity(i);
+                    })
+                    .show();
+        }
+    }
+
     /**
      * Updates the UI after the result of an update operation on the edited {@link OCFile}.
      *
@@ -404,6 +417,12 @@ public class FileDetailSharingFragment extends Fragment implements UserListAdapt
         dialog.show(getChildFragmentManager(), SharePasswordDialogFragment.PASSWORD_FRAGMENT);
     }
 
+    @Override
+    public void requestPasswordForShare(OCShare share) {
+        SharePasswordDialogFragment dialog = SharePasswordDialogFragment.newInstance(share);
+        dialog.show(getChildFragmentManager(), SharePasswordDialogFragment.PASSWORD_FRAGMENT);
+    }
+
     /**
      * Get known server capabilities from DB
      * 

+ 0 - 57
src/main/java/com/owncloud/android/ui/fragment/util/FileDetailSharingFragmentHelper.java

@@ -38,67 +38,10 @@ import java.util.Date;
  * Helper calls for visibility logic of the sharing fragment.
  */
 public class FileDetailSharingFragmentHelper {
-
     private FileDetailSharingFragmentHelper() {
         // Private empty constructor
     }
 
-    /**
-     * Sets checked/visiblity state on the given {@link MenuItem} based on the given criteria.
-     *
-     * @param fileListing            the {@link MenuItem} to be setup
-     * @param isFolder               flag if it is a folder
-     * @param isEditingAllowed       flag if editing is allowed
-     * @param publicSharePermissions share permissions of the link
-     */
-    public static void setupHideFileListingMenuItem(MenuItem fileListing,
-                                                    boolean isFolder,
-                                                    boolean isEditingAllowed,
-                                                    int publicSharePermissions) {
-        if (!isFolder) {
-            fileListing.setVisible(false);
-        } else {
-            if (isEditingAllowed) {
-                boolean readOnly = (publicSharePermissions & OCShare.READ_PERMISSION_FLAG) != 0;
-                fileListing.setChecked(!readOnly);
-            } else {
-                fileListing.setVisible(false);
-            }
-        }
-    }
-
-    /**
-     * sets up the password {@link MenuItem}'s title based on the fact if a password is present.
-     *
-     * @param password            the password {@link MenuItem}
-     * @param isPasswordProtected flag is a password is present
-     */
-    public static void setupPasswordMenuItem(MenuItem password, boolean isPasswordProtected) {
-        if (isPasswordProtected) {
-            password.setTitle(R.string.share_password_title);
-        } else {
-            password.setTitle(R.string.share_no_password_title);
-        }
-    }
-
-    /**
-     * sets up the expiration date {@link MenuItem}'s title based on the fact if an expiration date is present.
-     *
-     * @param expirationDate      the expiration date {@link MenuItem}
-     * @param expirationDateValue the expiration date
-     * @param res                 Resources to load the corresponding strings.
-     */
-    public static void setupExpirationDateMenuItem(MenuItem expirationDate, long expirationDateValue, Resources res) {
-        if (expirationDateValue > 0) {
-            expirationDate.setTitle(res.getString(
-                    R.string.share_expiration_date_label,
-                    SimpleDateFormat.getDateInstance().format(new Date(expirationDateValue))
-            ));
-        } else {
-            expirationDate.setTitle(R.string.share_no_expiration_date_label);
-        }
-    }
-
     /**
      * sets up the {@link SearchView}.
      *

+ 97 - 0
src/main/java/com/owncloud/android/ui/fragment/util/SharingMenuHelper.java

@@ -0,0 +1,97 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Andy Scherzinger
+ * Copyright (C) 2018 Andy Scherzinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.owncloud.android.ui.fragment.util;
+
+import android.app.SearchManager;
+import android.content.ComponentName;
+import android.content.res.Resources;
+import android.support.v7.widget.SearchView;
+import android.view.MenuItem;
+import android.view.inputmethod.EditorInfo;
+
+import com.owncloud.android.R;
+import com.owncloud.android.lib.resources.shares.OCShare;
+import com.owncloud.android.lib.resources.status.OCCapability;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Helper calls for visibility logic of the sharing menu.
+ */
+public class SharingMenuHelper {
+
+    /**
+     * Sets checked/visiblity state on the given {@link MenuItem} based on the given criteria.
+     *
+     * @param fileListing            the {@link MenuItem} to be setup
+     * @param isFolder               flag if it is a folder
+     * @param isEditingAllowed       flag if editing is allowed
+     * @param publicSharePermissions share permissions of the link
+     */
+    public static void setupHideFileListingMenuItem(MenuItem fileListing,
+                                                    boolean isFolder,
+                                                    boolean isEditingAllowed,
+                                                    int publicSharePermissions) {
+        if (!isFolder) {
+            fileListing.setVisible(false);
+        } else {
+            if (isEditingAllowed) {
+                boolean readOnly = (publicSharePermissions & OCShare.READ_PERMISSION_FLAG) != 0;
+                fileListing.setChecked(!readOnly);
+            } else {
+                fileListing.setVisible(false);
+            }
+        }
+    }
+
+    /**
+     * sets up the password {@link MenuItem}'s title based on the fact if a password is present.
+     *
+     * @param password            the password {@link MenuItem}
+     * @param isPasswordProtected flag is a password is present
+     */
+    public static void setupPasswordMenuItem(MenuItem password, boolean isPasswordProtected) {
+        if (isPasswordProtected) {
+            password.setTitle(R.string.share_password_title);
+        } else {
+            password.setTitle(R.string.share_no_password_title);
+        }
+    }
+
+    /**
+     * sets up the expiration date {@link MenuItem}'s title based on the fact if an expiration date is present.
+     *
+     * @param expirationDate      the expiration date {@link MenuItem}
+     * @param expirationDateValue the expiration date
+     * @param res                 Resources to load the corresponding strings.
+     */
+    public static void setupExpirationDateMenuItem(MenuItem expirationDate, long expirationDateValue, Resources res) {
+        if (expirationDateValue > 0) {
+            expirationDate.setTitle(res.getString(
+                    R.string.share_expiration_date_label,
+                    SimpleDateFormat.getDateInstance().format(new Date(expirationDateValue))
+            ));
+        } else {
+            expirationDate.setTitle(R.string.share_no_expiration_date_label);
+        }
+    }
+}

+ 20 - 0
src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java

@@ -522,6 +522,26 @@ public class FileOperationsHelper {
         queueShareIntent(updateShareIntent);
     }
 
+    /**
+     * Updates a share on a file to set its password.
+     * Starts a request to do it in {@link OperationsService}
+     *
+     * @param share    File which share will be protected with a password.
+     * @param password Password to set for the public link; null or empty string to clear
+     *                 the current password
+     */
+    public void setPasswordToShare(OCShare share, String password) {
+        Intent updateShareIntent = new Intent(mFileActivity, OperationsService.class);
+        updateShareIntent.setAction(OperationsService.ACTION_UPDATE_SHARE);
+        updateShareIntent.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
+        updateShareIntent.putExtra(OperationsService.EXTRA_SHARE_ID, share.getId());
+        updateShareIntent.putExtra(
+                OperationsService.EXTRA_SHARE_PASSWORD,
+                (password == null) ? "" : password
+        );
+        queueShareIntent(updateShareIntent);
+    }
+
 
     /**
      * Updates a public share on a file to set its expiration date.

+ 3 - 3
src/main/res/menu/file_detail_sharing_link_menu.xml

@@ -23,18 +23,18 @@
     tools:ignore="AppCompatResource">
 
     <item
-        android:id="@+id/action_share_link_hide_file_listing"
+        android:id="@+id/action_hide_file_listing"
         android:showAsAction="never"
         android:title="@string/share_via_link_hide_file_listing_permission_label"
         android:checkable="true"
         app:showAsAction="never" />
     <item
-        android:id="@+id/action_share_link_password"
+        android:id="@+id/action_password"
         android:showAsAction="never"
         android:title="@string/share_via_link_menu_password_label"
         app:showAsAction="never" />
     <item
-        android:id="@+id/action_share_link_expiration_date"
+        android:id="@+id/action_share_expiration_date"
         android:showAsAction="never"
         android:title="@string/share_expiration_date_label"
         app:showAsAction="never" />

+ 11 - 0
src/main/res/menu/file_detail_sharing_menu.xml

@@ -46,6 +46,17 @@
         android:showAsAction="never"
         android:title="@string/share_privilege_can_share"
         app:showAsAction="never" />
+    <item
+        android:id="@+id/action_hide_file_listing"
+        android:showAsAction="never"
+        android:title="@string/share_via_link_hide_file_listing_permission_label"
+        android:checkable="true"
+        app:showAsAction="never" />
+    <item
+        android:id="@+id/action_password"
+        android:showAsAction="never"
+        android:title="@string/share_via_link_menu_password_label"
+        app:showAsAction="never" />
     <item
         android:id="@+id/action_expiration_date"
         android:showAsAction="never"