From 3316d76c485845ef3b793de5a45bced494f5faa2 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 17 Nov 2017 15:00:21 +0100 Subject: [PATCH] Created helper classes ListSelectionHelper and ListSelectionAdapter to prevent developper to duplicate code to handle lists' items' selection for removal --- .../org/linphone/chat/ChatEventsAdapter.java | 78 ++------- .../org/linphone/chat/ChatListFragment.java | 119 ++------------ .../org/linphone/chat/ChatRoomsAdapter.java | 67 ++------ .../org/linphone/chat/GroupChatFragment.java | 111 ++----------- .../org/linphone/ui/ListSelectionAdapter.java | 82 ++++++++++ .../org/linphone/ui/ListSelectionHelper.java | 152 ++++++++++++++++++ 6 files changed, 279 insertions(+), 330 deletions(-) create mode 100644 src/android/org/linphone/ui/ListSelectionAdapter.java create mode 100644 src/android/org/linphone/ui/ListSelectionHelper.java diff --git a/src/android/org/linphone/chat/ChatEventsAdapter.java b/src/android/org/linphone/chat/ChatEventsAdapter.java index 97401d860..1cc4496c3 100644 --- a/src/android/org/linphone/chat/ChatEventsAdapter.java +++ b/src/android/org/linphone/chat/ChatEventsAdapter.java @@ -62,6 +62,8 @@ import org.linphone.core.Content; import org.linphone.core.Core; import org.linphone.core.EventLog; import org.linphone.mediastream.Log; +import org.linphone.ui.ListSelectionAdapter; +import org.linphone.ui.ListSelectionHelper; import java.io.File; import java.io.FileNotFoundException; @@ -73,37 +75,21 @@ import java.util.List; import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION; -public class ChatEventsAdapter extends BaseAdapter implements ChatMessageListener { +public class ChatEventsAdapter extends ListSelectionAdapter implements ChatMessageListener { private Context mContext; - GroupChatFragment mFragment; private List mHistory; private List mParticipants; private LayoutInflater mLayoutInflater; private Bitmap mDefaultBitmap; + private GroupChatFragment mFragment; - private boolean mIsEditionEnabled; - private List mSelectedItems; - private CompoundButton.OnCheckedChangeListener mDeleteCheckboxListener = new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - Integer position = (Integer)compoundButton.getTag(); - if (checked) { - mSelectedItems.add(position); - } else { - mSelectedItems.remove(position); - } - mFragment.updateSelectionButtons(mSelectedItems.size() == 0, mSelectedItems.size() == mHistory.size()); - } - }; - - public ChatEventsAdapter(Context context, GroupChatFragment fragment, LayoutInflater inflater, EventLog[] history, ArrayList participants) { - mContext = context; + public ChatEventsAdapter(GroupChatFragment fragment, ListSelectionHelper helper, LayoutInflater inflater, EventLog[] history, ArrayList participants) { + super(helper); mFragment = fragment; + mContext = mFragment.getActivity(); mLayoutInflater = inflater; mHistory = new ArrayList<>(Arrays.asList(history)); mParticipants = participants; - mIsEditionEnabled = false; - mSelectedItems = new ArrayList<>(); } public void addToHistory(EventLog log) { @@ -115,44 +101,6 @@ public class ChatEventsAdapter extends BaseAdapter implements ChatMessageListene mParticipants = participants; } - /** - * List edition - */ - - public void enableEdition(boolean enable) { - mIsEditionEnabled = enable; - notifyDataSetInvalidated(); - mSelectedItems.clear(); - } - - public EventLog[] getSelectedItems() { - EventLog logs[] = new EventLog[mSelectedItems.size()]; - int index = 0; - for (Integer i : mSelectedItems) { - logs[index] = (EventLog)getItem(i); - index++; - } - return logs; - } - - public void selectAll() { - for (Integer i = 0; i < mHistory.size(); i++) { - mSelectedItems.add(i); - } - mFragment.updateSelectionButtons(false, true); - notifyDataSetInvalidated(); - } - - public void deselectAll() { - mSelectedItems.clear(); - mFragment.updateSelectionButtons(true, false); - notifyDataSetInvalidated(); - } - - /** - * Adapter's methods - */ - @Override public int getCount() { return mHistory.size(); @@ -181,7 +129,7 @@ public class ChatEventsAdapter extends BaseAdapter implements ChatMessageListene holder.eventLayout.setVisibility(View.GONE); holder.bubbleLayout.setVisibility(View.GONE); - holder.delete.setVisibility(mIsEditionEnabled ? View.VISIBLE : View.GONE); + holder.delete.setVisibility(isEditionEnabled() ? View.VISIBLE : View.GONE); holder.messageText.setVisibility(View.GONE); holder.messageImage.setVisibility(View.GONE); holder.fileTransferLayout.setVisibility(View.GONE); @@ -193,11 +141,11 @@ public class ChatEventsAdapter extends BaseAdapter implements ChatMessageListene holder.messageSendingInProgress.setVisibility(View.GONE); holder.imdmLayout.setVisibility(View.INVISIBLE); - if (mIsEditionEnabled) { + if (isEditionEnabled()) { holder.delete.setOnCheckedChangeListener(null); - holder.delete.setChecked(mSelectedItems.contains(i)); + holder.delete.setChecked(getSelectedItemsPosition().contains(i)); holder.delete.setTag(i); - holder.delete.setOnCheckedChangeListener(mDeleteCheckboxListener); + holder.delete.setOnCheckedChangeListener(getDeleteListener()); } EventLog event = (EventLog)getItem(i); @@ -243,7 +191,7 @@ public class ChatEventsAdapter extends BaseAdapter implements ChatMessageListene holder.imdmLabel.setTextColor(mContext.getResources().getColor(R.color.colorI)); } - if (mIsEditionEnabled) { + if (isEditionEnabled()) { layoutParams.addRule(RelativeLayout.LEFT_OF, holder.delete.getId()); layoutParams.setMargins(100, 10, 10, 10); } else { @@ -280,7 +228,7 @@ public class ChatEventsAdapter extends BaseAdapter implements ChatMessageListene holder.contactPicture.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap()); } - if (mIsEditionEnabled) { + if (isEditionEnabled()) { layoutParams.addRule(RelativeLayout.LEFT_OF, holder.delete.getId()); layoutParams.setMargins(100, 10, 10, 10); } else { diff --git a/src/android/org/linphone/chat/ChatListFragment.java b/src/android/org/linphone/chat/ChatListFragment.java index 93c25b707..a31047381 100644 --- a/src/android/org/linphone/chat/ChatListFragment.java +++ b/src/android/org/linphone/chat/ChatListFragment.java @@ -19,7 +19,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. package org.linphone.chat; -import android.app.Dialog; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; @@ -27,13 +26,12 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; -import android.widget.Button; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import org.linphone.contacts.ContactsManager; +import org.linphone.ui.ListSelectionHelper; import org.linphone.receivers.ContactsUpdatedListener; import org.linphone.fragments.FragmentsAvailable; import org.linphone.activities.LinphoneActivity; @@ -46,48 +44,31 @@ import org.linphone.core.CoreListenerStub; import static org.linphone.fragments.FragmentsAvailable.CHAT_LIST; -public class ChatListFragment extends Fragment implements OnItemClickListener, ContactsUpdatedListener { +public class ChatListFragment extends Fragment implements OnItemClickListener, ContactsUpdatedListener, ListSelectionHelper.DeleteListener { private LayoutInflater mInflater; private ListView mChatRoomsList; private TextView mNoChatHistory; - private ImageView mEditButton, mSelectAllButton, mDeselectAllButton, mDeleteSelectionButton, mNewDiscussionButton, mCancelButton, mBackToCallButton; - private LinearLayout mEditTopBar, mTopBar; + private ImageView mNewDiscussionButton, mBackToCallButton; private boolean isEditMode = false; private ChatRoomsAdapter mChatRoomsAdapter; private CoreListenerStub mListener; + private ListSelectionHelper mSelectionHelper; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mInflater = inflater; View view = inflater.inflate(R.layout.chatlist, container, false); + mSelectionHelper = new ListSelectionHelper(view, this); + mChatRoomsAdapter = new ChatRoomsAdapter(getActivity(), mSelectionHelper, mInflater); + mSelectionHelper.setAdapter(mChatRoomsAdapter); + mChatRoomsList = view.findViewById(R.id.chatList); - mChatRoomsList.setAdapter(new ChatRoomsAdapter(getActivity(), this, mInflater)); + mChatRoomsList.setAdapter(mChatRoomsAdapter); mChatRoomsList.setOnItemClickListener(this); mNoChatHistory = view.findViewById(R.id.noChatHistory); - mEditTopBar = view.findViewById(R.id.edit_list); - mTopBar = view.findViewById(R.id.top_bar); - - mCancelButton = view.findViewById(R.id.cancel); - mCancelButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - quitEditionMode(); - } - }); - - mEditButton = view.findViewById(R.id.edit); - mEditButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - mChatRoomsAdapter.enableEdition(true); - mTopBar.setVisibility(View.GONE); - mEditTopBar.setVisibility(View.VISIBLE); - } - }); - mNewDiscussionButton = view.findViewById(R.id.new_discussion); mNewDiscussionButton.setOnClickListener(new View.OnClickListener() { @Override @@ -96,22 +77,6 @@ public class ChatListFragment extends Fragment implements OnItemClickListener, C } }); - mSelectAllButton = view.findViewById(R.id.select_all); - mSelectAllButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - mChatRoomsAdapter.selectAll(); - } - }); - - mDeselectAllButton = view.findViewById(R.id.deselect_all); - mDeselectAllButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - mChatRoomsAdapter.deselectAll(); - } - }); - mBackToCallButton = view.findViewById(R.id.back_in_call); mBackToCallButton.setOnClickListener(new View.OnClickListener() { @Override @@ -120,35 +85,6 @@ public class ChatListFragment extends Fragment implements OnItemClickListener, C } }); - mDeleteSelectionButton = view.findViewById(R.id.delete); - mDeleteSelectionButton.setEnabled(false); - mDeleteSelectionButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - final Dialog dialog = LinphoneActivity.instance().displayDialog(getString(R.string.delete_text)); - Button delete = dialog.findViewById(R.id.delete_button); - Button cancel = dialog.findViewById(R.id.cancel); - - delete.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - deleteSelectedRooms(); - dialog.dismiss(); - quitEditionMode(); - } - }); - - cancel.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - dialog.dismiss(); - quitEditionMode(); - } - }); - dialog.show(); - } - }); - mListener = new CoreListenerStub() { @Override public void onMessageReceived(Core lc, ChatRoom cr, ChatMessage message) { @@ -161,8 +97,6 @@ public class ChatListFragment extends Fragment implements OnItemClickListener, C } }; - mChatRoomsAdapter = new ChatRoomsAdapter(getActivity(), this, mInflater); - mChatRoomsList.setAdapter(mChatRoomsAdapter); return view; } @@ -171,36 +105,6 @@ public class ChatListFragment extends Fragment implements OnItemClickListener, C mChatRoomsAdapter.refresh(); } - private void deleteSelectedRooms() { - ChatRoom rooms[] = mChatRoomsAdapter.getSelectedItems(); - //TODO - } - - public void updateSelectionButtons(boolean isSelectionEmpty, boolean isSelectionFull) { - if (isSelectionEmpty) { - mDeleteSelectionButton.setEnabled(false); - } else { - mDeleteSelectionButton.setEnabled(true); - } - - if (isSelectionFull) { - mSelectAllButton.setVisibility(View.GONE); - mDeselectAllButton.setVisibility(View.VISIBLE); - } else { - mSelectAllButton.setVisibility(View.VISIBLE); - mDeselectAllButton.setVisibility(View.GONE); - } - } - - private void quitEditionMode() { - mChatRoomsAdapter.enableEdition(false); - mTopBar.setVisibility(View.VISIBLE); - mEditTopBar.setVisibility(View.GONE); - mDeleteSelectionButton.setEnabled(false); - mSelectAllButton.setVisibility(View.VISIBLE); - mDeselectAllButton.setVisibility(View.GONE); - } - @Override public void onResume() { super.onResume(); @@ -235,6 +139,11 @@ public class ChatListFragment extends Fragment implements OnItemClickListener, C super.onPause(); } + @Override + public void onDeleteSelection(Object[] objectsToDelete) { + //TODO + } + @Override public void onContactsUpdated() { if (!LinphoneActivity.isInstanciated() || LinphoneActivity.instance().getCurrentFragment() != CHAT_LIST) diff --git a/src/android/org/linphone/chat/ChatRoomsAdapter.java b/src/android/org/linphone/chat/ChatRoomsAdapter.java index 7c7a70fd7..a63bf7d9a 100644 --- a/src/android/org/linphone/chat/ChatRoomsAdapter.java +++ b/src/android/org/linphone/chat/ChatRoomsAdapter.java @@ -41,12 +41,14 @@ import org.linphone.contacts.LinphoneContact; import org.linphone.core.Address; import org.linphone.core.ChatMessage; import org.linphone.core.ChatRoom; +import org.linphone.ui.ListSelectionAdapter; +import org.linphone.ui.ListSelectionHelper; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -public class ChatRoomsAdapter extends BaseAdapter { +public class ChatRoomsAdapter extends ListSelectionAdapter { private class ChatRoomViewHolder { public TextView lastMessageView; @@ -67,34 +69,17 @@ public class ChatRoomsAdapter extends BaseAdapter { } private Context mContext; - ChatListFragment mFragment; private List mRooms; private LayoutInflater mLayoutInflater; private Bitmap mDefaultBitmap, mDefaultGroupBitmap; - private boolean mIsEditionEnabled; - private List mSelectedItems; - private CompoundButton.OnCheckedChangeListener mDeleteCheckboxListener = new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - Integer position = (Integer)compoundButton.getTag(); - if (checked) { - mSelectedItems.add(position); - } else { - mSelectedItems.remove(position); - } - mFragment.updateSelectionButtons(mSelectedItems.size() == 0, mSelectedItems.size() == mRooms.size()); - } - }; - public ChatRoomsAdapter(Context context, ChatListFragment fragment, LayoutInflater inflater) { + public ChatRoomsAdapter(Context context, ListSelectionHelper helper, LayoutInflater inflater) { + super(helper); mContext = context; - mFragment = fragment; mLayoutInflater = inflater; mRooms = new ArrayList<>(); mDefaultBitmap = ContactsManager.getInstance().getDefaultAvatarBitmap(); mDefaultGroupBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.chat_group_avatar); - mIsEditionEnabled = false; - mSelectedItems = new ArrayList<>(); } public void refresh() { @@ -102,40 +87,6 @@ public class ChatRoomsAdapter extends BaseAdapter { notifyDataSetChanged(); } - /** - * List edition - */ - - public void enableEdition(boolean enable) { - mIsEditionEnabled = enable; - notifyDataSetInvalidated(); - mSelectedItems.clear(); - } - - public ChatRoom[] getSelectedItems() { - ChatRoom rooms[] = new ChatRoom[mSelectedItems.size()]; - int index = 0; - for (Integer i : mSelectedItems) { - rooms[index] = (ChatRoom)getItem(i); - index++; - } - return rooms; - } - - public void selectAll() { - for (Integer i = 0; i < mRooms.size(); i++) { - mSelectedItems.add(i); - } - mFragment.updateSelectionButtons(false, true); - notifyDataSetInvalidated(); - } - - public void deselectAll() { - mSelectedItems.clear(); - mFragment.updateSelectionButtons(true, false); - notifyDataSetInvalidated(); - } - /** * Adapter's methods */ @@ -238,15 +189,15 @@ public class ChatRoomsAdapter extends BaseAdapter { holder.displayName.setTypeface(null, Typeface.NORMAL); } - if (mIsEditionEnabled) { + if (isEditionEnabled()) { holder.unreadMessages.setVisibility(View.GONE); holder.delete.setOnCheckedChangeListener(null); holder.delete.setVisibility(View.VISIBLE); - holder.delete.setChecked(mSelectedItems.contains(position)); + holder.delete.setChecked(getSelectedItemsPosition().contains(position)); holder.delete.setTag(position); - holder.delete.setOnCheckedChangeListener(mDeleteCheckboxListener); + holder.delete.setOnCheckedChangeListener(getDeleteListener()); } else { - holder.delete.setVisibility(mIsEditionEnabled ? View.VISIBLE : View.GONE); + holder.delete.setVisibility(isEditionEnabled() ? View.VISIBLE : View.GONE); } return view; } diff --git a/src/android/org/linphone/chat/GroupChatFragment.java b/src/android/org/linphone/chat/GroupChatFragment.java index afaca2b10..2045b0162 100644 --- a/src/android/org/linphone/chat/GroupChatFragment.java +++ b/src/android/org/linphone/chat/GroupChatFragment.java @@ -56,7 +56,6 @@ import org.linphone.contacts.ContactsManager; import org.linphone.contacts.LinphoneContact; import org.linphone.core.Address; import org.linphone.core.ChatMessage; -import org.linphone.core.ChatMessageListenerStub; import org.linphone.core.ChatRoom; import org.linphone.core.ChatRoomListener; import org.linphone.core.Content; @@ -65,6 +64,7 @@ import org.linphone.core.EventLog; import org.linphone.core.Factory; import org.linphone.core.Participant; import org.linphone.receivers.ContactsUpdatedListener; +import org.linphone.ui.ListSelectionHelper; import java.io.File; import java.util.ArrayList; @@ -72,19 +72,18 @@ import java.util.List; import static org.linphone.fragments.FragmentsAvailable.CHAT; -public class GroupChatFragment extends Fragment implements ChatRoomListener, ContactsUpdatedListener { +public class GroupChatFragment extends Fragment implements ChatRoomListener, ContactsUpdatedListener, ListSelectionHelper.DeleteListener { private static final int ADD_PHOTO = 1337; - private ImageView mBackButton, mCallButton, mBackToCallButton, mGroupInfosButton, mEditButton; - private ImageView mCancelEditButton, mSelectAllButton, mDeselectAllButton, mDeleteSelectionButton; + private ImageView mBackButton, mCallButton, mBackToCallButton, mGroupInfosButton; private ImageView mAttachImageButton, mSendMessageButton; private TextView mRoomLabel, mParticipantsLabel, mRemoteComposing; private EditText mMessageTextToSend; private LayoutInflater mInflater; private ListView mChatEventsList; private LinearLayout mFilesUploadLayout; - private LinearLayout mTopBar, mEditTopBar; private boolean mIsReadOnly; + private ListSelectionHelper mSelectionHelper; private ViewTreeObserver.OnGlobalLayoutListener mKeyboardListener; private Uri mImageToUploadUri; @@ -108,8 +107,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con mInflater = inflater; View view = inflater.inflate(R.layout.chat, container, false); - mTopBar = view.findViewById(R.id.top_bar); - mEditTopBar = view.findViewById(R.id.edit_list); + mSelectionHelper = new ListSelectionHelper(view, this); mBackButton = view.findViewById(R.id.back); mBackButton.setOnClickListener(new View.OnClickListener() { @@ -156,69 +154,6 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con } }); - mEditButton = view.findViewById(R.id.edit); - mEditButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - mEventsAdapter.enableEdition(true); - mTopBar.setVisibility(View.GONE); - mEditTopBar.setVisibility(View.VISIBLE); - } - }); - - mCancelEditButton = view.findViewById(R.id.cancel); - mCancelEditButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - quitEditionMode(); - } - }); - - mSelectAllButton = view.findViewById(R.id.select_all); - mSelectAllButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - mEventsAdapter.selectAll(); - } - }); - - mDeselectAllButton = view.findViewById(R.id.deselect_all); - mDeselectAllButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - mEventsAdapter.deselectAll(); - } - }); - - mDeleteSelectionButton = view.findViewById(R.id.delete); - mDeleteSelectionButton.setEnabled(false); - mDeleteSelectionButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - final Dialog dialog = LinphoneActivity.instance().displayDialog(getString(R.string.delete_text)); - Button delete = dialog.findViewById(R.id.delete_button); - Button cancel = dialog.findViewById(R.id.cancel); - - delete.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - deleteSelectedEvents(); - dialog.dismiss(); - quitEditionMode(); - } - }); - - cancel.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - dialog.dismiss(); - quitEditionMode(); - } - }); - dialog.show(); - } - }); - mRoomLabel = view.findViewById(R.id.subject); mParticipantsLabel = view.findViewById(R.id.participants); @@ -338,40 +273,11 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con } } - /** - * Edition related methods - */ - - private void deleteSelectedEvents() { - EventLog logs[] = mEventsAdapter.getSelectedItems(); + @Override + public void onDeleteSelection(Object[] objectsToDelete) { //TODO } - public void updateSelectionButtons(boolean isSelectionEmpty, boolean isSelectionFull) { - if (isSelectionEmpty) { - mDeleteSelectionButton.setEnabled(false); - } else { - mDeleteSelectionButton.setEnabled(true); - } - - if (isSelectionFull) { - mSelectAllButton.setVisibility(View.GONE); - mDeselectAllButton.setVisibility(View.VISIBLE); - } else { - mSelectAllButton.setVisibility(View.VISIBLE); - mDeselectAllButton.setVisibility(View.GONE); - } - } - - private void quitEditionMode() { - mEventsAdapter.enableEdition(false); - mTopBar.setVisibility(View.VISIBLE); - mEditTopBar.setVisibility(View.GONE); - mDeleteSelectionButton.setEnabled(false); - mSelectAllButton.setVisibility(View.VISIBLE); - mDeselectAllButton.setVisibility(View.GONE); - } - /** * Keyboard management */ @@ -504,7 +410,8 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con private void displayChatRoomHistory() { if (mChatRoom == null) return; - mEventsAdapter = new ChatEventsAdapter(getActivity(), this, mInflater, mChatRoom.getHistoryEvents(0), mParticipants); + mEventsAdapter = new ChatEventsAdapter(this, mSelectionHelper, mInflater, mChatRoom.getHistoryEvents(0), mParticipants); + mSelectionHelper.setAdapter(mEventsAdapter); mChatEventsList.setAdapter(mEventsAdapter); } diff --git a/src/android/org/linphone/ui/ListSelectionAdapter.java b/src/android/org/linphone/ui/ListSelectionAdapter.java new file mode 100644 index 000000000..2dac2357c --- /dev/null +++ b/src/android/org/linphone/ui/ListSelectionAdapter.java @@ -0,0 +1,82 @@ +/* +ListSelectionAdapter.java +Copyright (C) 2017 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +package org.linphone.ui; + +import android.widget.BaseAdapter; +import android.widget.CompoundButton; + +import java.util.ArrayList; +import java.util.List; + +public abstract class ListSelectionAdapter extends BaseAdapter { + private ListSelectionHelper mListHelper; + private List mSelectedItems; + private boolean mIsEditionEnabled; + + private CompoundButton.OnCheckedChangeListener mDeleteCheckboxListener = new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + Integer position = (Integer)compoundButton.getTag(); + if (checked) { + mSelectedItems.add(position); + } else { + mSelectedItems.remove(position); + } + mListHelper.updateSelectionButtons(mSelectedItems.size() == 0, mSelectedItems.size() == getCount()); + } + }; + + public ListSelectionAdapter(ListSelectionHelper helper) { + mListHelper = helper; + mSelectedItems = new ArrayList<>(); + } + + public boolean isEditionEnabled() { + return mIsEditionEnabled; + } + + public CompoundButton.OnCheckedChangeListener getDeleteListener() { + return mDeleteCheckboxListener; + } + + public void selectAll() { + for (Integer i = 0; i < getCount(); i++) { + mSelectedItems.add(i); + } + mListHelper.updateSelectionButtons(false, true); + notifyDataSetInvalidated(); + } + + public void deselectAll() { + mSelectedItems.clear(); + mListHelper.updateSelectionButtons(true, false); + notifyDataSetInvalidated(); + } + + public void enableEdition(boolean enable) { + mIsEditionEnabled = enable; + notifyDataSetInvalidated(); + mSelectedItems.clear(); + } + + public List getSelectedItemsPosition() { + return mSelectedItems; + } +} diff --git a/src/android/org/linphone/ui/ListSelectionHelper.java b/src/android/org/linphone/ui/ListSelectionHelper.java new file mode 100644 index 000000000..5f337f40e --- /dev/null +++ b/src/android/org/linphone/ui/ListSelectionHelper.java @@ -0,0 +1,152 @@ +/* +ListSelectionHelper.java +Copyright (C) 2017 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +package org.linphone.ui; + +import android.app.Dialog; +import android.content.Context; +import android.view.View; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.LinearLayout; + +import org.linphone.R; +import org.linphone.activities.LinphoneActivity; + +public class ListSelectionHelper { + private ImageView mEditButton, mSelectAllButton, mDeselectAllButton, mDeleteSelectionButton, mCancelButton; + private LinearLayout mEditTopBar, mTopBar; + private ListSelectionAdapter mAdapter; + private DeleteListener mDeleteListener; + private Context mContext; + + public interface DeleteListener { + void onDeleteSelection(Object[] objectsToDelete); + } + + public ListSelectionHelper(View view, DeleteListener listener) { + mContext = view.getContext(); + mDeleteListener = listener; + + mEditTopBar = view.findViewById(R.id.edit_list); + mTopBar = view.findViewById(R.id.top_bar); + + mCancelButton = view.findViewById(R.id.cancel); + mCancelButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + quitEditionMode(); + } + }); + + mEditButton = view.findViewById(R.id.edit); + mEditButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mAdapter.enableEdition(true); + mTopBar.setVisibility(View.GONE); + mEditTopBar.setVisibility(View.VISIBLE); + } + }); + + mSelectAllButton = view.findViewById(R.id.select_all); + mSelectAllButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mAdapter.selectAll(); + } + }); + + mDeselectAllButton = view.findViewById(R.id.deselect_all); + mDeselectAllButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mAdapter.deselectAll(); + } + }); + + mDeleteSelectionButton = view.findViewById(R.id.delete); + mDeleteSelectionButton.setEnabled(false); + mDeleteSelectionButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final Dialog dialog = LinphoneActivity.instance().displayDialog(mContext.getString(R.string.delete_text)); + Button delete = dialog.findViewById(R.id.delete_button); + Button cancel = dialog.findViewById(R.id.cancel); + + delete.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + mDeleteListener.onDeleteSelection(getSelectedObjects()); + dialog.dismiss(); + quitEditionMode(); + } + }); + + cancel.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + dialog.dismiss(); + quitEditionMode(); + } + }); + dialog.show(); + } + }); + } + + public void setAdapter(ListSelectionAdapter adapter) { + mAdapter = adapter; + } + + public void updateSelectionButtons(boolean isSelectionEmpty, boolean isSelectionFull) { + if (isSelectionEmpty) { + mDeleteSelectionButton.setEnabled(false); + } else { + mDeleteSelectionButton.setEnabled(true); + } + + if (isSelectionFull) { + mSelectAllButton.setVisibility(View.GONE); + mDeselectAllButton.setVisibility(View.VISIBLE); + } else { + mSelectAllButton.setVisibility(View.VISIBLE); + mDeselectAllButton.setVisibility(View.GONE); + } + } + + private void quitEditionMode() { + mAdapter.enableEdition(false); + mTopBar.setVisibility(View.VISIBLE); + mEditTopBar.setVisibility(View.GONE); + mDeleteSelectionButton.setEnabled(false); + mSelectAllButton.setVisibility(View.VISIBLE); + mDeselectAllButton.setVisibility(View.GONE); + } + + private Object[] getSelectedObjects() { + Object objects[] = new Object[mAdapter.getSelectedItemsPosition().size()]; + int index = 0; + for (Integer i : mAdapter.getSelectedItemsPosition()) { + objects[index] = mAdapter.getItem(i); + index++; + } + return objects; + } +}