diff options
Diffstat (limited to 'src')
4 files changed, 146 insertions, 1 deletions
diff --git a/src/frontends/android/res/menu/profile_list_context.xml b/src/frontends/android/res/menu/profile_list_context.xml new file mode 100644 index 000000000..e674ae856 --- /dev/null +++ b/src/frontends/android/res/menu/profile_list_context.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2012 Tobias Brunner + Hochschule fuer Technik Rapperswil + + 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. See <http://www.fsf.org/copyleft/gpl.txt>. + + 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. +--> +<menu xmlns:android="http://schemas.android.com/apk/res/android" > + + <item android:id="@+id/edit_profile" + android:title="@string/edit_profile" ></item> + + <item android:id="@+id/delete_profile" + android:title="@string/delete_profile" ></item> + +</menu>
\ No newline at end of file diff --git a/src/frontends/android/res/values/strings.xml b/src/frontends/android/res/values/strings.xml index 9d52c1e3e..53a94bb30 100644 --- a/src/frontends/android/res/values/strings.xml +++ b/src/frontends/android/res/values/strings.xml @@ -23,6 +23,12 @@ <!-- VPN profile list --> <string name="no_profiles">No VPN profiles.</string> <string name="add_profile">Add VPN profile</string> + <string name="edit_profile">Edit</string> + <string name="delete_profile">Delete</string> + <string name="profiles_deleted">Selected profiles deleted</string> + <string name="no_profile_selected">No profile selected</string> + <string name="one_profile_selected">One profile selected</string> + <string name="x_profiles_selected">%1$d profiles selected"</string> <!-- VPN profile details --> <string name="profile_edit_save">Save</string> diff --git a/src/frontends/android/src/org/strongswan/android/data/VpnProfile.java b/src/frontends/android/src/org/strongswan/android/data/VpnProfile.java index 8dc5f2499..3e248d2eb 100644 --- a/src/frontends/android/src/org/strongswan/android/data/VpnProfile.java +++ b/src/frontends/android/src/org/strongswan/android/data/VpnProfile.java @@ -87,4 +87,14 @@ public class VpnProfile { return mName; } + + @Override + public boolean equals(Object o) + { + if (o != null && o instanceof VpnProfile) + { + return this.mId == ((VpnProfile)o).getId(); + } + return false; + } } diff --git a/src/frontends/android/src/org/strongswan/android/ui/VpnProfileListFragment.java b/src/frontends/android/src/org/strongswan/android/ui/VpnProfileListFragment.java index a7211c5de..252330b28 100644 --- a/src/frontends/android/src/org/strongswan/android/ui/VpnProfileListFragment.java +++ b/src/frontends/android/src/org/strongswan/android/ui/VpnProfileListFragment.java @@ -17,6 +17,8 @@ package org.strongswan.android.ui; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import org.strongswan.android.R; @@ -29,17 +31,23 @@ import android.app.Fragment; import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.view.ActionMode; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.AbsListView.MultiChoiceModeListener; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; +import android.widget.Toast; public class VpnProfileListFragment extends Fragment { private static final int ADD_REQUEST = 1; + private static final int EDIT_REQUEST = 2; private List<VpnProfile> mVpnProfiles; private VpnProfileDataSource mDataSource; @@ -54,6 +62,8 @@ public class VpnProfileListFragment extends Fragment mListView = (ListView)view.findViewById(R.id.profile_list); mListView.setEmptyView(view.findViewById(R.id.profile_list_empty)); + mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); + mListView.setMultiChoiceModeListener(mVpnProfileSelected); mListView.setAdapter(mListAdapter); return view; @@ -110,6 +120,7 @@ public class VpnProfileListFragment extends Fragment switch (requestCode) { case ADD_REQUEST: + case EDIT_REQUEST: if (resultCode != Activity.RESULT_OK) { return; @@ -117,7 +128,8 @@ public class VpnProfileListFragment extends Fragment long id = data.getLongExtra(VpnProfileDataSource.KEY_ID, 0); VpnProfile profile = mDataSource.getVpnProfile(id); if (profile != null) - { + { /* in case this was an edit, we remove it first */ + mVpnProfiles.remove(profile); mVpnProfiles.add(profile); mListAdapter.notifyDataSetChanged(); } @@ -125,4 +137,97 @@ public class VpnProfileListFragment extends Fragment } super.onActivityResult(requestCode, resultCode, data); } + + private final MultiChoiceModeListener mVpnProfileSelected = new MultiChoiceModeListener() { + private HashSet<Integer> mSelected; + private MenuItem mEditProfile; + + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) + { + return false; + } + + @Override + public void onDestroyActionMode(ActionMode mode) + { + } + + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) + { + MenuInflater inflater = mode.getMenuInflater(); + inflater.inflate(R.menu.profile_list_context, menu); + mEditProfile = menu.findItem(R.id.edit_profile); + mSelected = new HashSet<Integer>(); + mode.setTitle("Select Profiles"); + return true; + } + + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) + { + switch (item.getItemId()) + { + case R.id.edit_profile: + { + int position = mSelected.iterator().next(); + VpnProfile profile = (VpnProfile)mListView.getItemAtPosition(position); + Intent connectionIntent = new Intent(getActivity(), VpnProfileDetailActivity.class); + connectionIntent.putExtra(VpnProfileDataSource.KEY_ID, profile.getId()); + startActivityForResult(connectionIntent, EDIT_REQUEST); + break; + } + case R.id.delete_profile: + { + ArrayList<VpnProfile> profiles = new ArrayList<VpnProfile>(); + for (int position : mSelected) + { + profiles.add((VpnProfile)mListView.getItemAtPosition(position)); + } + for (VpnProfile profile : profiles) + { + mDataSource.deleteVpnProfile(profile); + mVpnProfiles.remove(profile); + } + mListAdapter.notifyDataSetChanged(); + Toast.makeText(VpnProfileListFragment.this.getActivity(), + R.string.profiles_deleted, Toast.LENGTH_SHORT).show(); + break; + } + default: + return false; + } + mode.finish(); + return true; + } + + @Override + public void onItemCheckedStateChanged(ActionMode mode, int position, + long id, boolean checked) + { + if (checked) + { + mSelected.add(position); + } + else + { + mSelected.remove(position); + } + final int checkedCount = mSelected.size(); + mEditProfile.setEnabled(checkedCount == 1); + switch (checkedCount) + { + case 0: + mode.setSubtitle(R.string.no_profile_selected); + break; + case 1: + mode.setSubtitle(R.string.one_profile_selected); + break; + default: + mode.setSubtitle(String.format(getString(R.string.x_profiles_selected), checkedCount)); + break; + } + } + }; } |