diff --git a/src/main/java/com/owncloud/android/files/FileMenuFilter.java b/src/main/java/com/owncloud/android/files/FileMenuFilter.java index db820ec99f5f..1c0fa469da5d 100644 --- a/src/main/java/com/owncloud/android/files/FileMenuFilter.java +++ b/src/main/java/com/owncloud/android/files/FileMenuFilter.java @@ -52,6 +52,7 @@ public class FileMenuFilter { private ComponentsGetter mComponentsGetter; private Account mAccount; private Context mContext; + private boolean mOverflowMenu; /** * Constructor @@ -61,14 +62,16 @@ public class FileMenuFilter { * @param account ownCloud {@link Account} holding targetFile. * @param cg Accessor to app components, needed to access synchronization services * @param context Android {@link Context}, needed to access build setup resources. + * @param overflowMenu true if the overflow menu items are being filtered */ public FileMenuFilter(int numberOfAllFiles, Collection targetFiles, Account account, - ComponentsGetter cg, Context context) { + ComponentsGetter cg, Context context, boolean overflowMenu) { mNumberOfAllFiles = numberOfAllFiles; mFiles = targetFiles; mAccount = account; mComponentsGetter = cg; mContext = context; + mOverflowMenu = overflowMenu; } /** @@ -78,9 +81,11 @@ public FileMenuFilter(int numberOfAllFiles, Collection targetFiles, Acco * @param account ownCloud {@link Account} holding targetFile. * @param cg Accessor to app components, needed to access synchronization services * @param context Android {@link Context}, needed to access build setup resources. + * @param overflowMenu true if the overflow menu items are being filtered */ - public FileMenuFilter(OCFile targetFile, Account account, ComponentsGetter cg, Context context) { - this(1, Collections.singletonList(targetFile), account, cg, context); + public FileMenuFilter(OCFile targetFile, Account account, ComponentsGetter cg, Context context, + boolean overflowMenu) { + this(1, Collections.singletonList(targetFile), account, cg, context, overflowMenu); } /** @@ -178,7 +183,7 @@ private void filter(List toShow, List toHide, boolean inSingle // SELECT ALL if (!inSingleFileFragment) { // Show only if at least one item isn't selected. - if (mFiles.size() >= mNumberOfAllFiles) { + if (mFiles.size() >= mNumberOfAllFiles || mOverflowMenu) { toHide.add(R.id.action_select_all_action_menu); } else { toShow.add(R.id.action_select_all_action_menu); @@ -191,7 +196,7 @@ private void filter(List toShow, List toHide, boolean inSingle // DESELECT ALL if (!inSingleFileFragment) { // Show only if at least one item is selected. - if (mFiles.isEmpty()) { + if (mFiles.isEmpty() || mOverflowMenu) { toHide.add(R.id.action_deselect_all_action_menu); } else { toShow.add(R.id.action_deselect_all_action_menu); @@ -235,7 +240,8 @@ private void filter(List toShow, List toHide, boolean inSingle (capability.getFilesSharingApiEnabled().isTrue() || capability.getFilesSharingApiEnabled().isUnknown() ); - if ((!shareViaLinkAllowed && !shareWithUsersAllowed) || !isSingleSelection() || !shareApiEnabled) { + if ((!shareViaLinkAllowed && !shareWithUsersAllowed) || + !isSingleSelection() || !shareApiEnabled || mOverflowMenu) { toHide.add(R.id.action_share_file); } else { toShow.add(R.id.action_share_file); diff --git a/src/main/java/com/owncloud/android/ui/adapter/FileListListAdapter.java b/src/main/java/com/owncloud/android/ui/adapter/FileListListAdapter.java index 2d87d2daddb3..ccb0f089e487 100644 --- a/src/main/java/com/owncloud/android/ui/adapter/FileListListAdapter.java +++ b/src/main/java/com/owncloud/android/ui/adapter/FileListListAdapter.java @@ -26,7 +26,6 @@ import android.accounts.Account; import android.content.ContentValues; import android.content.Context; -import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Color; import android.os.Handler; @@ -62,8 +61,6 @@ import com.owncloud.android.operations.RemoteOperationFailedException; import com.owncloud.android.services.OperationsService.OperationsServiceBinder; import com.owncloud.android.ui.activity.ComponentsGetter; -import com.owncloud.android.ui.activity.FileActivity; -import com.owncloud.android.ui.activity.ShareActivity; import com.owncloud.android.ui.fragment.ExtendedListFragment; import com.owncloud.android.ui.interfaces.OCFileListFragmentInterface; import com.owncloud.android.utils.DisplayUtils; @@ -234,10 +231,6 @@ public View getView(int position, View convertView, ViewGroup parent) { if (file != null) { ImageView fileIcon = (ImageView) view.findViewById(R.id.thumbnail); - ImageView sharedIconV = (ImageView) view.findViewById(R.id.sharedIcon); - if (file.isSharedWithSharee() || file.isSharedWithMe()) { - sharedIconV.setImageResource(R.drawable.shared_via_users); - } fileIcon.setTag(file.getFileId()); TextView fileName; @@ -258,21 +251,6 @@ public View getView(int position, View convertView, ViewGroup parent) { fileSizeV.setVisibility(View.VISIBLE); fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength())); - // Shared icon clickable - if (file.isSharedViaLink() || file.isSharedWithSharee()) { - final OCFile temp = file; - sharedIconV.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - Intent intent = new Intent(mContext, ShareActivity.class); - intent.putExtra(FileActivity.EXTRA_FILE, temp); - intent.putExtra(FileActivity.EXTRA_ACCOUNT, mAccount); - mContext.startActivity(intent); - } - }); - } - - case GRID_ITEM: // filename fileName = (TextView) view.findViewById(R.id.Filename); @@ -284,16 +262,6 @@ public void onClick(View view) { } case GRID_IMAGE: - // sharedIcon - if (file.isSharedViaLink()) { - sharedIconV.setVisibility(View.VISIBLE); - sharedIconV.bringToFront(); - } else if (file.isSharedWithSharee() || file.isSharedWithMe()) { - sharedIconV.setVisibility(View.VISIBLE); - sharedIconV.bringToFront(); - } else { - sharedIconV.setVisibility(View.GONE); - } // local state ImageView localStateView = (ImageView) view.findViewById(R.id.localFileIndicator); @@ -340,7 +308,6 @@ public void onClick(View view) { } ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox); - checkBoxV.setVisibility(View.GONE); view.setBackgroundColor(Color.WHITE); AbsListView parentList = (AbsListView) parent; @@ -355,6 +322,12 @@ public void onClick(View view) { checkBoxV.setImageResource(R.drawable.ic_checkbox_blank_outline); } checkBoxV.setVisibility(View.VISIBLE); + hideShareIcon(view); + hideOverflowMenuIcon(view, viewType); + } else { + checkBoxV.setVisibility(View.GONE); + showShareIcon(view, file); + showOverflowMenuIcon(view, file, viewType); } // this if-else is needed even though kept-in-sync icon is visible by default @@ -430,6 +403,48 @@ public void onClick(View view) { return view; } + private void showShareIcon(View view, OCFile file) { + ImageView sharedIconV = (ImageView) view.findViewById(R.id.sharedIcon); + sharedIconV.setVisibility(View.VISIBLE); + if (file.isSharedWithSharee() || file.isSharedWithMe()) { + sharedIconV.setImageResource(R.drawable.shared_via_users); + } else if (file.isSharedViaLink()) { + sharedIconV.setImageResource(R.drawable.shared_via_link); + } else { + sharedIconV.setImageResource(R.drawable.ic_unshared); + } + sharedIconV.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + OCFileListFragmentInterface.onShareIconClick(file); + } + }); + } + + private void hideShareIcon(View view) { + view.findViewById(R.id.sharedIcon).setVisibility(View.GONE); + } + + private void showOverflowMenuIcon(View view, OCFile file, ViewType viewType) { + if (ViewType.LIST_ITEM.equals(viewType)) { + ImageView overflowIndicatorV = (ImageView) view.findViewById(R.id.overflow_menu); + overflowIndicatorV.setVisibility(View.VISIBLE); + overflowIndicatorV.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + OCFileListFragmentInterface.onOverflowIconClick(v, file); + } + }); + } + } + + private void hideOverflowMenuIcon(View view, ViewType viewType) { + if (ViewType.LIST_ITEM.equals(viewType)) { + ImageView overflowIndicatorV = (ImageView) view.findViewById(R.id.overflow_menu); + overflowIndicatorV.setVisibility(View.GONE); + } + } + @Override public int getViewTypeCount() { return 1; diff --git a/src/main/java/com/owncloud/android/ui/adapter/LocalFileListAdapter.java b/src/main/java/com/owncloud/android/ui/adapter/LocalFileListAdapter.java index 01a683642318..beaa9f2b7771 100644 --- a/src/main/java/com/owncloud/android/ui/adapter/LocalFileListAdapter.java +++ b/src/main/java/com/owncloud/android/ui/adapter/LocalFileListAdapter.java @@ -178,6 +178,7 @@ public View getView(int position, View convertView, ViewGroup parent) { TextView lastModV = (TextView) view.findViewById(R.id.last_mod); lastModV.setVisibility(View.VISIBLE); lastModV.setText(DisplayUtils.getRelativeTimestamp(mContext, file.lastModified())); + view.findViewById(R.id.overflow_menu).setVisibility(View.GONE); } if (!file.isDirectory()) { diff --git a/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java b/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java index 4a94ba6abe5f..59883b4c955e 100644 --- a/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java +++ b/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java @@ -216,7 +216,8 @@ public void onPrepareOptionsMenu(Menu menu) { getFile(), mContainerActivity.getStorageManager().getAccount(), mContainerActivity, - getActivity() + getActivity(), + false ); mf.filter(menu, true); } diff --git a/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index bfc5c185dbd3..c6c85e006482 100644 --- a/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -53,6 +53,7 @@ import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.ListView; +import android.widget.PopupMenu; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; @@ -107,6 +108,7 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -513,6 +515,34 @@ public void finishedFiltering() { updateFooter(); } + @Override + public void onShareIconClick(OCFile file) { + shareFile(file); + } + + @Override + public void onOverflowIconClick(View view, OCFile file) { + PopupMenu popup = new PopupMenu(getActivity(), view); + popup.inflate(R.menu.file_actions_menu); + FileMenuFilter mf = new FileMenuFilter( + mAdapter.getFiles().size(), + Collections.singleton(file), + ((FileActivity) getActivity()).getAccount(), + mContainerActivity, + getActivity(), + true + ); + mf.filter(popup.getMenu(), true); + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + ArrayList checkedFiles = new ArrayList<>(Collections.singletonList(file)); + return onFileActionChosen(item.getItemId(), checkedFiles); + } + }); + popup.show(); + } + /** * Handler for multiple selection mode. * @@ -632,7 +662,8 @@ public boolean onPrepareActionMode(ActionMode mode, Menu menu) { checkedFiles, ((FileActivity) getActivity()).getAccount(), mContainerActivity, - getActivity() + getActivity(), + false ); mf.filter(menu, false); return true; @@ -643,7 +674,8 @@ public boolean onPrepareActionMode(ActionMode mode, Menu menu) { */ @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - return onFileActionChosen(item.getItemId()); + ArrayList checkedFiles = mAdapter.getCheckedItems(getListView()); + return onFileActionChosen(item.getItemId(), checkedFiles); } /** @@ -902,10 +934,10 @@ public void onItemClick(AdapterView l, View v, int position, long id) { * Start the appropriate action(s) on the currently selected files given menu selected by the user. * * @param menuId Identifier of the action menu selected by the user + * @param checkedFiles List of files selected by the user on which the action should be performed * @return 'true' if the menu selection started any action, 'false' otherwise. */ - public boolean onFileActionChosen(int menuId) { - final ArrayList checkedFiles = mAdapter.getCheckedItems(getListView()); + public boolean onFileActionChosen(int menuId, ArrayList checkedFiles) { if (checkedFiles.size() <= 0) { return false; } @@ -915,11 +947,7 @@ public boolean onFileActionChosen(int menuId) { OCFile singleFile = checkedFiles.get(0); switch (menuId) { case R.id.action_share_file: { - if(singleFile.isSharedWithMe() && !singleFile.canReshare()){ - Snackbar.make(getView(), R.string.resharing_is_not_allowed, Snackbar.LENGTH_LONG).show(); - } else { - mContainerActivity.getFileOperationsHelper().showShareFile(singleFile); - } + shareFile(singleFile); return true; } case R.id.action_open_file_with: { @@ -1019,6 +1047,14 @@ public boolean onFileActionChosen(int menuId) { } } + private void shareFile(OCFile file) { + if(file.isSharedWithMe() && !file.canReshare()){ + Snackbar.make(getView(), R.string.resharing_is_not_allowed, Snackbar.LENGTH_LONG).show(); + } else { + mContainerActivity.getFileOperationsHelper().showShareFile(file); + } + } + /** * Use this to query the {@link OCFile} that is currently * being displayed by this fragment diff --git a/src/main/java/com/owncloud/android/ui/interfaces/OCFileListFragmentInterface.java b/src/main/java/com/owncloud/android/ui/interfaces/OCFileListFragmentInterface.java index 195c499cc64b..9fe06ac331d4 100644 --- a/src/main/java/com/owncloud/android/ui/interfaces/OCFileListFragmentInterface.java +++ b/src/main/java/com/owncloud/android/ui/interfaces/OCFileListFragmentInterface.java @@ -20,12 +20,21 @@ */ package com.owncloud.android.ui.interfaces; +import android.view.View; + +import com.owncloud.android.datamodel.OCFile; + /** - * Interface for signaling filter finish + * Interface for communication between {@link com.owncloud.android.ui.fragment.OCFileListFragment} + * and {@link com.owncloud.android.ui.adapter.FileListListAdapter} */ public interface OCFileListFragmentInterface { void finishedFiltering(); int getColumnSize(); + + void onShareIconClick(OCFile file); + + void onOverflowIconClick(View view, OCFile file); } diff --git a/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.java b/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.java index d92fe401ee6f..169f65a29923 100644 --- a/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.java +++ b/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.java @@ -275,7 +275,8 @@ public void onPrepareOptionsMenu(Menu menu) { getFile(), mContainerActivity.getStorageManager().getAccount(), mContainerActivity, - getActivity() + getActivity(), + false ); mf.filter(menu, true); } diff --git a/src/main/java/com/owncloud/android/ui/preview/PreviewMediaFragment.java b/src/main/java/com/owncloud/android/ui/preview/PreviewMediaFragment.java index 3188de0a6ed5..09de311abed5 100644 --- a/src/main/java/com/owncloud/android/ui/preview/PreviewMediaFragment.java +++ b/src/main/java/com/owncloud/android/ui/preview/PreviewMediaFragment.java @@ -375,7 +375,8 @@ public void onPrepareOptionsMenu(Menu menu) { getFile(), mContainerActivity.getStorageManager().getAccount(), mContainerActivity, - getActivity() + getActivity(), + false ); mf.filter(menu, true); } diff --git a/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.java b/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.java index c048c5e2e498..26d670dbefd8 100644 --- a/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.java +++ b/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.java @@ -285,7 +285,8 @@ public void onPrepareOptionsMenu(Menu menu) { getFile(), mContainerActivity.getStorageManager().getAccount(), mContainerActivity, - getActivity() + getActivity(), + false ); mf.filter(menu, true); } diff --git a/src/main/res/drawable-hdpi/shared_via_users.png b/src/main/res/drawable-hdpi/ic_unshared.png similarity index 100% rename from src/main/res/drawable-hdpi/shared_via_users.png rename to src/main/res/drawable-hdpi/ic_unshared.png diff --git a/src/main/res/drawable-hdpi/shared_via_link.png b/src/main/res/drawable-hdpi/shared_via_link.png deleted file mode 100644 index a7c3fd6ba373..000000000000 Binary files a/src/main/res/drawable-hdpi/shared_via_link.png and /dev/null differ diff --git a/src/main/res/drawable-mdpi/shared_via_users.png b/src/main/res/drawable-mdpi/ic_unshared.png similarity index 100% rename from src/main/res/drawable-mdpi/shared_via_users.png rename to src/main/res/drawable-mdpi/ic_unshared.png diff --git a/src/main/res/drawable-mdpi/shared_via_link.png b/src/main/res/drawable-mdpi/shared_via_link.png deleted file mode 100644 index 7426f07582ef..000000000000 Binary files a/src/main/res/drawable-mdpi/shared_via_link.png and /dev/null differ diff --git a/src/main/res/drawable-xhdpi/shared_via_users.png b/src/main/res/drawable-xhdpi/ic_unshared.png similarity index 100% rename from src/main/res/drawable-xhdpi/shared_via_users.png rename to src/main/res/drawable-xhdpi/ic_unshared.png diff --git a/src/main/res/drawable-xhdpi/shared_via_link.png b/src/main/res/drawable-xhdpi/shared_via_link.png deleted file mode 100644 index 9ebd6230432d..000000000000 Binary files a/src/main/res/drawable-xhdpi/shared_via_link.png and /dev/null differ diff --git a/src/main/res/drawable-xxhdpi/shared_via_users.png b/src/main/res/drawable-xxhdpi/ic_unshared.png similarity index 100% rename from src/main/res/drawable-xxhdpi/shared_via_users.png rename to src/main/res/drawable-xxhdpi/ic_unshared.png diff --git a/src/main/res/drawable-xxhdpi/shared_via_link.png b/src/main/res/drawable-xxhdpi/shared_via_link.png deleted file mode 100644 index 0c7d2f3b37f0..000000000000 Binary files a/src/main/res/drawable-xxhdpi/shared_via_link.png and /dev/null differ diff --git a/src/main/res/drawable-xxxhdpi/shared_via_users.png b/src/main/res/drawable-xxxhdpi/ic_unshared.png similarity index 100% rename from src/main/res/drawable-xxxhdpi/shared_via_users.png rename to src/main/res/drawable-xxxhdpi/ic_unshared.png diff --git a/src/main/res/drawable-xxxhdpi/shared_via_link.png b/src/main/res/drawable-xxxhdpi/shared_via_link.png deleted file mode 100644 index 194edfa6b815..000000000000 Binary files a/src/main/res/drawable-xxxhdpi/shared_via_link.png and /dev/null differ diff --git a/src/main/res/drawable/shared_via_link.xml b/src/main/res/drawable/shared_via_link.xml new file mode 100644 index 000000000000..b57c8f4432af --- /dev/null +++ b/src/main/res/drawable/shared_via_link.xml @@ -0,0 +1,18 @@ + + + + diff --git a/src/main/res/drawable/shared_via_users.xml b/src/main/res/drawable/shared_via_users.xml new file mode 100644 index 000000000000..a33c1d61ec55 --- /dev/null +++ b/src/main/res/drawable/shared_via_users.xml @@ -0,0 +1,12 @@ + + + diff --git a/src/main/res/layout/list_item.xml b/src/main/res/layout/list_item.xml index 8ae40df923a7..2bfa727de7bc 100644 --- a/src/main/res/layout/list_item.xml +++ b/src/main/res/layout/list_item.xml @@ -30,7 +30,6 @@ android:layout_height="match_parent" android:orientation="horizontal"> - - + android:contentDescription="@string/favorite_switch" + android:src="@drawable/ic_favorite" /> @@ -141,36 +140,50 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" - android:paddingRight="@dimen/standard_padding"> + android:paddingLeft="@dimen/alternate_padding" + android:paddingRight="@dimen/alternate_padding"> + android:layout_centerVertical="true" + android:layout_marginRight="@dimen/list_item_share_right_margin" + android:padding="@dimen/standard_quarter_padding" + android:clickable="true" + android:focusable="true" + android:src="@drawable/ic_unshared" /> - android:src="@drawable/ic_checkbox_blank_outline" - android:layout_toRightOf="@id/sharedIcon"/> - + + + android:background="@color/list_divider_background" /> diff --git a/src/main/res/values/dims.xml b/src/main/res/values/dims.xml index 9df5c75c478e..b3aa0df7480b 100644 --- a/src/main/res/values/dims.xml +++ b/src/main/res/values/dims.xml @@ -47,6 +47,7 @@ 14sp 20dp 20dp + 10dp 72dp 0dp 72dp