Use a contextual action bar to edit and delete selected VPN profiles
[strongswan.git] / src / frontends / android / src / org / strongswan / android / ui / VpnProfileListFragment.java
1 /*
2 * Copyright (C) 2012 Tobias Brunner
3 * Copyright (C) 2012 Giuliano Grassi
4 * Copyright (C) 2012 Ralf Sager
5 * Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 package org.strongswan.android.ui;
19
20 import java.util.ArrayList;
21 import java.util.HashSet;
22 import java.util.List;
23
24 import org.strongswan.android.R;
25 import org.strongswan.android.data.VpnProfile;
26 import org.strongswan.android.data.VpnProfileDataSource;
27 import org.strongswan.android.ui.adapter.VpnProfileAdapter;
28
29 import android.app.Activity;
30 import android.app.Fragment;
31 import android.content.Context;
32 import android.content.Intent;
33 import android.os.Bundle;
34 import android.view.ActionMode;
35 import android.view.LayoutInflater;
36 import android.view.Menu;
37 import android.view.MenuInflater;
38 import android.view.MenuItem;
39 import android.view.View;
40 import android.view.ViewGroup;
41 import android.widget.AbsListView.MultiChoiceModeListener;
42 import android.widget.AdapterView;
43 import android.widget.AdapterView.OnItemClickListener;
44 import android.widget.ListView;
45 import android.widget.Toast;
46
47 public class VpnProfileListFragment extends Fragment
48 {
49 private static final int ADD_REQUEST = 1;
50 private static final int EDIT_REQUEST = 2;
51
52 private List<VpnProfile> mVpnProfiles;
53 private VpnProfileDataSource mDataSource;
54 private VpnProfileAdapter mListAdapter;
55 private ListView mListView;
56
57 @Override
58 public View onCreateView(LayoutInflater inflater, ViewGroup container,
59 Bundle savedInstanceState)
60 {
61 View view = inflater.inflate(R.layout.profile_list_fragment, null);
62
63 mListView = (ListView)view.findViewById(R.id.profile_list);
64 mListView.setEmptyView(view.findViewById(R.id.profile_list_empty));
65 mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
66 mListView.setMultiChoiceModeListener(mVpnProfileSelected);
67 mListView.setAdapter(mListAdapter);
68
69 return view;
70 }
71
72 @Override
73 public void onCreate(Bundle savedInstanceState)
74 {
75 super.onCreate(savedInstanceState);
76 setHasOptionsMenu(true);
77
78 Context context = getActivity().getApplicationContext();
79
80 mDataSource = new VpnProfileDataSource(this.getActivity());
81 mDataSource.open();
82
83 /* cached list of profiles used as backend for the ListView */
84 mVpnProfiles = mDataSource.getAllVpnProfiles();
85
86 mListAdapter = new VpnProfileAdapter(context, R.layout.profile_list_item, mVpnProfiles);
87 }
88
89 @Override
90 public void onDestroy()
91 {
92 super.onDestroy();
93 mDataSource.close();
94 }
95
96 @Override
97 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
98 {
99 inflater.inflate(R.menu.profile_list, menu);
100 }
101
102 @Override
103 public boolean onOptionsItemSelected(MenuItem item)
104 {
105 switch (item.getItemId())
106 {
107 case R.id.add_profile:
108 Intent connectionIntent = new Intent(getActivity(),
109 VpnProfileDetailActivity.class);
110 startActivityForResult(connectionIntent, ADD_REQUEST);
111 return true;
112 default:
113 return super.onOptionsItemSelected(item);
114 }
115 }
116
117 @Override
118 public void onActivityResult(int requestCode, int resultCode, Intent data)
119 {
120 switch (requestCode)
121 {
122 case ADD_REQUEST:
123 case EDIT_REQUEST:
124 if (resultCode != Activity.RESULT_OK)
125 {
126 return;
127 }
128 long id = data.getLongExtra(VpnProfileDataSource.KEY_ID, 0);
129 VpnProfile profile = mDataSource.getVpnProfile(id);
130 if (profile != null)
131 { /* in case this was an edit, we remove it first */
132 mVpnProfiles.remove(profile);
133 mVpnProfiles.add(profile);
134 mListAdapter.notifyDataSetChanged();
135 }
136 return;
137 }
138 super.onActivityResult(requestCode, resultCode, data);
139 }
140
141 private final MultiChoiceModeListener mVpnProfileSelected = new MultiChoiceModeListener() {
142 private HashSet<Integer> mSelected;
143 private MenuItem mEditProfile;
144
145 @Override
146 public boolean onPrepareActionMode(ActionMode mode, Menu menu)
147 {
148 return false;
149 }
150
151 @Override
152 public void onDestroyActionMode(ActionMode mode)
153 {
154 }
155
156 @Override
157 public boolean onCreateActionMode(ActionMode mode, Menu menu)
158 {
159 MenuInflater inflater = mode.getMenuInflater();
160 inflater.inflate(R.menu.profile_list_context, menu);
161 mEditProfile = menu.findItem(R.id.edit_profile);
162 mSelected = new HashSet<Integer>();
163 mode.setTitle("Select Profiles");
164 return true;
165 }
166
167 @Override
168 public boolean onActionItemClicked(ActionMode mode, MenuItem item)
169 {
170 switch (item.getItemId())
171 {
172 case R.id.edit_profile:
173 {
174 int position = mSelected.iterator().next();
175 VpnProfile profile = (VpnProfile)mListView.getItemAtPosition(position);
176 Intent connectionIntent = new Intent(getActivity(), VpnProfileDetailActivity.class);
177 connectionIntent.putExtra(VpnProfileDataSource.KEY_ID, profile.getId());
178 startActivityForResult(connectionIntent, EDIT_REQUEST);
179 break;
180 }
181 case R.id.delete_profile:
182 {
183 ArrayList<VpnProfile> profiles = new ArrayList<VpnProfile>();
184 for (int position : mSelected)
185 {
186 profiles.add((VpnProfile)mListView.getItemAtPosition(position));
187 }
188 for (VpnProfile profile : profiles)
189 {
190 mDataSource.deleteVpnProfile(profile);
191 mVpnProfiles.remove(profile);
192 }
193 mListAdapter.notifyDataSetChanged();
194 Toast.makeText(VpnProfileListFragment.this.getActivity(),
195 R.string.profiles_deleted, Toast.LENGTH_SHORT).show();
196 break;
197 }
198 default:
199 return false;
200 }
201 mode.finish();
202 return true;
203 }
204
205 @Override
206 public void onItemCheckedStateChanged(ActionMode mode, int position,
207 long id, boolean checked)
208 {
209 if (checked)
210 {
211 mSelected.add(position);
212 }
213 else
214 {
215 mSelected.remove(position);
216 }
217 final int checkedCount = mSelected.size();
218 mEditProfile.setEnabled(checkedCount == 1);
219 switch (checkedCount)
220 {
221 case 0:
222 mode.setSubtitle(R.string.no_profile_selected);
223 break;
224 case 1:
225 mode.setSubtitle(R.string.one_profile_selected);
226 break;
227 default:
228 mode.setSubtitle(String.format(getString(R.string.x_profiles_selected), checkedCount));
229 break;
230 }
231 }
232 };
233 }