From 9df07a2371bcbb8c2a47a8915c18a3e115769fdc Mon Sep 17 00:00:00 2001 From: emanuele-f Date: Sat, 9 Jul 2022 20:11:01 +0200 Subject: [PATCH] Refresh list editor when rules change --- .../adapters/ListEditAdapter.java | 16 ++++--- .../fragments/EditListFragment.java | 46 +++++++++++++++---- .../remote_capture/model/MatchList.java | 39 ++++++++++++++-- 3 files changed, 84 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/emanuelef/remote_capture/adapters/ListEditAdapter.java b/app/src/main/java/com/emanuelef/remote_capture/adapters/ListEditAdapter.java index 545d8775..6e2ec175 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/adapters/ListEditAdapter.java +++ b/app/src/main/java/com/emanuelef/remote_capture/adapters/ListEditAdapter.java @@ -47,7 +47,7 @@ public class ListEditAdapter extends ArrayAdapter implements Tex private final Drawable mDefaultIcon; private final Drawable mUnknownIcon; - public ListEditAdapter(Context context, Iterator items) { + public ListEditAdapter(Context context) { super(context, R.layout.rule_item); mLayoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mApps = new AppsResolver(context); @@ -55,11 +55,6 @@ public class ListEditAdapter extends ArrayAdapter implements Tex mDefaultIcon = ContextCompat.getDrawable(context, R.drawable.ic_short_text); assert mDefaultIcon != null; DrawableCompat.setTint(mDefaultIcon, ContextCompat.getColor(context, R.color.colorTabText)); - - while(items.hasNext()) { - MatchList.Rule item = items.next(); - add(item); - } } @NonNull @@ -87,4 +82,13 @@ public class ListEditAdapter extends ArrayAdapter implements Tex public String getItemText(int pos) { return getItem(pos).getLabel(); } + + public void reload(Iterator items) { + clear(); + + while(items.hasNext()) { + MatchList.Rule item = items.next(); + add(item); + } + } } diff --git a/app/src/main/java/com/emanuelef/remote_capture/fragments/EditListFragment.java b/app/src/main/java/com/emanuelef/remote_capture/fragments/EditListFragment.java index 46913d3a..ab76e910 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/fragments/EditListFragment.java +++ b/app/src/main/java/com/emanuelef/remote_capture/fragments/EditListFragment.java @@ -23,6 +23,7 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.util.Log; import android.view.ActionMode; import android.view.LayoutInflater; import android.view.Menu; @@ -58,13 +59,15 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.Scanner; -public class EditListFragment extends Fragment { +public class EditListFragment extends Fragment implements MatchList.ListChangeListener { private ListEditAdapter mAdapter; private TextView mEmptyText; private ArrayList mSelected = new ArrayList<>(); private MatchList mList; private ListInfo mListInfo; private ListView mListView; + private boolean mIsOwnUpdate; + private ActionMode mActionMode; private static final String TAG = "EditListFragment"; private static final String LIST_TYPE_ARG = "list_type"; @@ -97,8 +100,9 @@ public class EditListFragment extends Fragment { assert getArguments() != null; mListInfo = new ListInfo((ListInfo.Type)getArguments().getSerializable(LIST_TYPE_ARG)); mList = mListInfo.getList(); + mList.addListChangeListener(this); - mAdapter = new ListEditAdapter(requireContext(), mList.iterRules()); + mAdapter = new ListEditAdapter(requireContext()); mListView.setAdapter(mAdapter); mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); mListView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() { @@ -118,6 +122,7 @@ public class EditListFragment extends Fragment { public boolean onCreateActionMode(ActionMode mode, Menu menu) { MenuInflater inflater = requireActivity().getMenuInflater(); inflater.inflate(R.menu.list_edit_cab, menu); + mActionMode = mode; return true; } @@ -151,12 +156,20 @@ public class EditListFragment extends Fragment { @Override public void onDestroyActionMode(ActionMode mode) { mSelected = new ArrayList<>(); + mActionMode = null; } }); + mAdapter.reload(mList.iterRules()); recheckListSize(); } + @Override + public void onDestroyView() { + super.onDestroyView(); + mList.removeListChangeListener(this); + } + private void confirmDelete(ActionMode mode) { AlertDialog.Builder builder = new AlertDialog.Builder(requireContext()); builder.setMessage(R.string.rules_delete_confirm); @@ -259,6 +272,8 @@ public class EditListFragment extends Fragment { mList.removeRule(rule); mList.save(); } + + mIsOwnUpdate = true; } private String getExportName() { @@ -334,7 +349,7 @@ public class EditListFragment extends Fragment { builder.setCancelable(true); builder.setPositiveButton(R.string.keep_action, (dialog, which) -> importRules(rules)); builder.setNegativeButton(R.string.discard_action, (dialog, which) -> { - mList.clear(); + mList.clear(false); importRules(rules); }); @@ -350,12 +365,27 @@ public class EditListFragment extends Fragment { mList.save(); reloadListRules(); - // reload view - mAdapter = new ListEditAdapter(context, mList.iterRules()); - mListView.setAdapter(mAdapter); - recheckListSize(); - String msg = String.format(context.getResources().getString(R.string.rules_import_success), num_imported); Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); } + + @Override + public void onListChanged() { + if(mIsOwnUpdate) { + mIsOwnUpdate = false; + return; + } + + Log.d(TAG, "onListChanged"); + + if(mActionMode != null) { + mActionMode.finish(); + mActionMode = null; + } + + // reload view + mAdapter.reload(mList.iterRules()); + mListView.setAdapter(mAdapter); + recheckListSize(); + } } diff --git a/app/src/main/java/com/emanuelef/remote_capture/model/MatchList.java b/app/src/main/java/com/emanuelef/remote_capture/model/MatchList.java index 6c925f31..b8704cb9 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/model/MatchList.java +++ b/app/src/main/java/com/emanuelef/remote_capture/model/MatchList.java @@ -56,6 +56,7 @@ public class MatchList { private final Context mContext; private final SharedPreferences mPrefs; private final String mPrefName; + private final ArrayList mListeners = new ArrayList<>(); private final ArrayList mRules = new ArrayList<>(); private final ArrayMap mMatches = new ArrayMap<>(); private final ArraySet mUids = new ArraySet<>(); @@ -103,6 +104,10 @@ public class MatchList { } } + public interface ListChangeListener { + void onListChanged(); + } + public static class ListDescriptor { public final List apps = new ArrayList<>(); public final List hosts = new ArrayList<>(); @@ -191,7 +196,7 @@ public class MatchList { if(ruleArray == null) return false; - clear(); + clear(false); for(JsonElement el: ruleArray) { JsonObject ruleObj = el.getAsJsonObject(); @@ -295,6 +300,7 @@ public class MatchList { mRules.add(rule); mMatches.put(key, rule); + notifyListeners(); return true; } @@ -308,13 +314,16 @@ public class MatchList { num_added++; } + if(num_added > 0) + notifyListeners(); + return num_added; } public void removeRule(Rule rule) { String val = rule.getValue().toString(); String key = matchKey(rule.getType(), val); - mRules.remove(rule); + boolean removed = mRules.remove(rule); mMatches.remove(key); if(rule.getType() == RuleType.APP) { @@ -324,6 +333,9 @@ public class MatchList { else Log.w(TAG, "removeRule: no uid found for package " + val); } + + if(removed) + notifyListeners(); } public boolean matchesApp(int uid) { @@ -377,10 +389,18 @@ public class MatchList { return mRules.iterator(); } - public void clear() { + public void clear(boolean notify) { + boolean hasRules = mRules.size() > 0; mRules.clear(); mMatches.clear(); mUids.clear(); + + if(notify && hasRules) + notifyListeners(); + } + + public void clear() { + clear(true); } public boolean isEmpty() { @@ -441,4 +461,17 @@ public class MatchList { return rv; } + + public void addListChangeListener(ListChangeListener listener) { + mListeners.add(listener); + } + + public void removeListChangeListener(ListChangeListener listener) { + mListeners.remove(listener); + } + + private void notifyListeners() { + for(ListChangeListener listener: mListeners) + listener.onListChanged(); + } }