diff options
author | Samuel Holland <samuel@sholland.org> | 2017-08-16 00:55:44 -0500 |
---|---|---|
committer | Samuel Holland <samuel@sholland.org> | 2017-08-16 00:55:44 -0500 |
commit | 73217a098a264e3da8497b2c3696c8816004ca64 (patch) | |
tree | ea654a9ae85806eec9005f9882b4f6b2b0cf6173 /app/src/main/java/com/wireguard/android | |
parent | f1d97a585a66613a1080cde7bb9b6d633ecc4582 (diff) |
ConfigListFragment: Implement config selection and removal
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'app/src/main/java/com/wireguard/android')
-rw-r--r-- | app/src/main/java/com/wireguard/android/ConfigListFragment.java | 107 |
1 files changed, 97 insertions, 10 deletions
diff --git a/app/src/main/java/com/wireguard/android/ConfigListFragment.java b/app/src/main/java/com/wireguard/android/ConfigListFragment.java index 9dbf77d9..c5c9dbf7 100644 --- a/app/src/main/java/com/wireguard/android/ConfigListFragment.java +++ b/app/src/main/java/com/wireguard/android/ConfigListFragment.java @@ -1,21 +1,31 @@ package com.wireguard.android; +import android.content.res.Resources; +import android.databinding.ObservableArrayMap; import android.os.Bundle; import android.util.Log; +import android.view.ActionMode; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.ListView; import com.wireguard.android.databinding.ConfigListFragmentBinding; import com.wireguard.config.Config; +import java.util.LinkedList; +import java.util.List; + /** * Fragment containing the list of known WireGuard configurations. */ public class ConfigListFragment extends BaseConfigFragment { + private ListView listView; @Override public View onCreateView(final LayoutInflater inflater, final ViewGroup parent, @@ -23,7 +33,9 @@ public class ConfigListFragment extends BaseConfigFragment { final ConfigListFragmentBinding binding = ConfigListFragmentBinding.inflate(inflater, parent, false); binding.setConfigs(VpnService.getInstance().getConfigs()); - final ListView listView = binding.getRoot().findViewById(R.id.config_list); + final View root = binding.getRoot(); + listView = root.findViewById(R.id.config_list); + listView.setMultiChoiceModeListener(new ConfigListModeListener()); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(final AdapterView<?> parent, final View view, @@ -36,18 +48,15 @@ public class ConfigListFragment extends BaseConfigFragment { @Override public boolean onItemLongClick(final AdapterView<?> parent, final View view, final int position, final long id) { - final Config config = (Config) parent.getItemAtPosition(position); - final VpnService service = VpnService.getInstance(); - if (config == null || service == null) - return false; - if (config.isEnabled()) - service.disable(config.getName()); - else - service.enable(config.getName()); + setConfigChecked(null); + listView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE_MODAL); + listView.setItemChecked(position, true); return true; } }); - return binding.getRoot(); + binding.executePendingBindings(); + setConfigChecked(getCurrentConfig()); + return root; } @Override @@ -57,5 +66,83 @@ public class ConfigListFragment extends BaseConfigFragment { final BaseConfigActivity activity = ((BaseConfigActivity) getActivity()); if (activity != null && activity.getCurrentConfig() != config) activity.setCurrentConfig(config); + if (listView != null) + setConfigChecked(config); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + listView = null; + } + + private void setConfigChecked(final Config config) { + if (config != null) { + final int position = VpnService.getInstance().getConfigs().indexOfKey(config.getName()); + if (position >= 0) + listView.setItemChecked(position, true); + } else { + final int position = listView.getCheckedItemPosition(); + if (position >= 0) + listView.setItemChecked(position, false); + } + } + + private class ConfigListModeListener implements AbsListView.MultiChoiceModeListener { + private final List<Config> configsToRemove = new LinkedList<>(); + + @Override + public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_action_delete: + // Ensure an unmanaged config is never the current config. + if (configsToRemove.contains(getCurrentConfig())) + setCurrentConfig(null); + for (final Config config : configsToRemove) + VpnService.getInstance().remove(config.getName()); + configsToRemove.clear(); + mode.finish(); + return true; + default: + return false; + } + } + + @Override + public void onItemCheckedStateChanged(final ActionMode mode, final int position, + final long id, final boolean checked) { + if (checked) + configsToRemove.add((Config) listView.getItemAtPosition(position)); + else + configsToRemove.remove(listView.getItemAtPosition(position)); + final int count = configsToRemove.size(); + final Resources resources = listView.getContext().getResources(); + mode.setTitle(resources.getQuantityString(R.plurals.list_delete_title, count, count)); + } + + @Override + public boolean onCreateActionMode(final ActionMode mode, final Menu menu) { + mode.getMenuInflater().inflate(R.menu.config_list_delete, menu); + return true; + } + + @Override + public void onDestroyActionMode(final ActionMode mode) { + configsToRemove.clear(); + listView.post(new Runnable() { + @Override + public void run() { + listView.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE); + // Restore the previous selection (before entering the action mode). + setConfigChecked(getCurrentConfig()); + } + }); + } + + @Override + public boolean onPrepareActionMode(final ActionMode mode, final Menu menu) { + configsToRemove.clear(); + return false; + } } } |