1package eu.siacs.conversations.ui;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import eu.siacs.conversations.R;
7import eu.siacs.conversations.crypto.PgpEngine;
8import eu.siacs.conversations.crypto.PgpEngine.UserInputRequiredException;
9import eu.siacs.conversations.entities.Account;
10import eu.siacs.conversations.ui.EditAccount.EditAccountListener;
11import android.app.Activity;
12import android.app.AlertDialog;
13import android.content.Context;
14import android.content.DialogInterface;
15import android.content.DialogInterface.OnClickListener;
16import android.content.Intent;
17import android.content.IntentSender.SendIntentException;
18import android.os.Bundle;
19import android.util.Log;
20import android.view.ActionMode;
21import android.view.ActionMode.Callback;
22import android.view.LayoutInflater;
23import android.view.Menu;
24import android.view.MenuInflater;
25import android.view.MenuItem;
26import android.view.View;
27import android.view.ViewGroup;
28import android.widget.AdapterView;
29import android.widget.AdapterView.OnItemClickListener;
30import android.widget.AdapterView.OnItemLongClickListener;
31import android.widget.ArrayAdapter;
32import android.widget.ListView;
33import android.widget.TextView;
34
35public class ManageAccountActivity extends XmppActivity {
36
37 public static final int REQUEST_ANNOUNCE_PGP = 0x73731;
38
39 protected boolean isActionMode = false;
40 protected ActionMode actionMode;
41 protected Account selectedAccountForActionMode = null;
42
43 protected List<Account> accountList = new ArrayList<Account>();
44 protected ListView accountListView;
45 protected ArrayAdapter<Account> accountListViewAdapter;
46 protected OnAccountListChangedListener accountChanged = new OnAccountListChangedListener() {
47
48 @Override
49 public void onAccountListChangedListener() {
50 Log.d("xmppService", "ui on account list changed listener");
51 accountList.clear();
52 accountList.addAll(xmppConnectionService.getAccounts());
53 runOnUiThread(new Runnable() {
54
55 @Override
56 public void run() {
57 accountListViewAdapter.notifyDataSetChanged();
58 }
59 });
60 }
61 };
62
63 @Override
64 protected void onCreate(Bundle savedInstanceState) {
65
66 super.onCreate(savedInstanceState);
67
68 setContentView(R.layout.manage_accounts);
69
70 accountListView = (ListView) findViewById(R.id.account_list);
71 accountListViewAdapter = new ArrayAdapter<Account>(
72 getApplicationContext(), R.layout.account_row, this.accountList) {
73 @Override
74 public View getView(int position, View view, ViewGroup parent) {
75 Account account = getItem(position);
76 if (view == null) {
77 LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
78 view = (View) inflater.inflate(R.layout.account_row, null);
79 }
80 ((TextView) view.findViewById(R.id.account_jid))
81 .setText(account.getJid());
82 TextView statusView = (TextView) view
83 .findViewById(R.id.account_status);
84 switch (account.getStatus()) {
85 case Account.STATUS_DISABLED:
86 statusView.setText("temporarily disabled");
87 statusView.setTextColor(0xFF1da9da);
88 break;
89 case Account.STATUS_ONLINE:
90 statusView.setText("online");
91 statusView.setTextColor(0xFF83b600);
92 break;
93 case Account.STATUS_OFFLINE:
94 statusView.setText("offline");
95 statusView.setTextColor(0xFFe92727);
96 break;
97 case Account.STATUS_UNAUTHORIZED:
98 statusView.setText("unauthorized");
99 statusView.setTextColor(0xFFe92727);
100 break;
101 case Account.STATUS_SERVER_NOT_FOUND:
102 statusView.setText("server not found");
103 statusView.setTextColor(0xFFe92727);
104 break;
105 default:
106 break;
107 }
108
109 return view;
110 }
111 };
112 final XmppActivity activity = this;
113 accountListView.setAdapter(this.accountListViewAdapter);
114 accountListView.setOnItemClickListener(new OnItemClickListener() {
115
116 @Override
117 public void onItemClick(AdapterView<?> arg0, View view,
118 int position, long arg3) {
119 if (!isActionMode) {
120 EditAccount dialog = new EditAccount();
121 dialog.setAccount(accountList.get(position));
122 dialog.setEditAccountListener(new EditAccountListener() {
123
124 @Override
125 public void onAccountEdited(Account account) {
126 xmppConnectionService.updateAccount(account);
127 }
128 });
129 dialog.show(getFragmentManager(), "edit_account");
130 } else {
131 selectedAccountForActionMode = accountList.get(position);
132 actionMode.invalidate();
133 }
134 }
135 });
136 accountListView.setOnItemLongClickListener(new OnItemLongClickListener() {
137
138 @Override
139 public boolean onItemLongClick(AdapterView<?> arg0, View view,
140 int position, long arg3) {
141 if (!isActionMode) {
142 accountListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
143 accountListView.setItemChecked(position,true);
144 selectedAccountForActionMode = accountList.get(position);
145 actionMode = activity.startActionMode((new ActionMode.Callback() {
146
147 @Override
148 public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
149 if (selectedAccountForActionMode.isOptionSet(Account.OPTION_DISABLED)) {
150 menu.findItem(R.id.account_enable).setVisible(true);
151 menu.findItem(R.id.account_disable).setVisible(false);
152 } else {
153 menu.findItem(R.id.account_disable).setVisible(true);
154 menu.findItem(R.id.account_enable).setVisible(false);
155 }
156 return true;
157 }
158
159 @Override
160 public void onDestroyActionMode(ActionMode mode) {
161 // TODO Auto-generated method stub
162
163 }
164
165 @Override
166 public boolean onCreateActionMode(ActionMode mode, Menu menu) {
167 MenuInflater inflater = mode.getMenuInflater();
168 inflater.inflate(R.menu.manageaccounts_context, menu);
169 return true;
170 }
171
172 @Override
173 public boolean onActionItemClicked(final ActionMode mode, MenuItem item) {
174 if (item.getItemId()==R.id.account_disable) {
175 selectedAccountForActionMode.setOption(Account.OPTION_DISABLED, true);
176 xmppConnectionService.updateAccount(selectedAccountForActionMode);
177 mode.finish();
178 } else if (item.getItemId()==R.id.account_enable) {
179 selectedAccountForActionMode.setOption(Account.OPTION_DISABLED, false);
180 xmppConnectionService.updateAccount(selectedAccountForActionMode);
181 mode.finish();
182 } else if (item.getItemId()==R.id.account_delete) {
183 AlertDialog.Builder builder = new AlertDialog.Builder(activity);
184 builder.setTitle("Are you sure?");
185 builder.setIconAttribute(android.R.attr.alertDialogIcon);
186 builder.setMessage("If you delete your account your entire conversation history will be lost");
187 builder.setPositiveButton("Delete", new OnClickListener() {
188
189 @Override
190 public void onClick(DialogInterface dialog, int which) {
191 xmppConnectionService.deleteAccount(selectedAccountForActionMode);
192 selectedAccountForActionMode = null;
193 mode.finish();
194 }
195 });
196 builder.setNegativeButton("Cancel",null);
197 builder.create().show();
198 } else if (item.getItemId()==R.id.announce_pgp) {
199 if (activity.hasPgp()) {
200 mode.finish();
201 try {
202 xmppConnectionService.generatePgpAnnouncement(selectedAccountForActionMode);
203 } catch (PgpEngine.UserInputRequiredException e) {
204 try {
205 startIntentSenderForResult(e.getPendingIntent().getIntentSender(), REQUEST_ANNOUNCE_PGP, null, 0, 0, 0);
206 } catch (SendIntentException e1) {
207 Log.d("gultsch","sending intent failed");
208 }
209 }
210 }
211 }
212 return true;
213 }
214 }));
215 return true;
216 } else {
217 return false;
218 }
219 }
220 });
221 }
222
223 @Override
224 protected void onStop() {
225 if (xmppConnectionServiceBound) {
226 xmppConnectionService.removeOnAccountListChangedListener();
227 }
228 super.onStop();
229 }
230
231 @Override
232 void onBackendConnected() {
233 xmppConnectionService.setOnAccountListChangedListener(accountChanged);
234 this.accountList.clear();
235 this.accountList.addAll(xmppConnectionService.getAccounts());
236 accountListViewAdapter.notifyDataSetChanged();
237 if (this.accountList.size() == 0) {
238 getActionBar().setDisplayHomeAsUpEnabled(false);
239 addAccount();
240 }
241 }
242
243 @Override
244 public boolean onCreateOptionsMenu(Menu menu) {
245 getMenuInflater().inflate(R.menu.manageaccounts, menu);
246 return true;
247 }
248
249 @Override
250 public boolean onOptionsItemSelected(MenuItem item) {
251 switch (item.getItemId()) {
252 case R.id.action_settings:
253 startActivity(new Intent(this, SettingsActivity.class));
254 break;
255 case R.id.action_add_account:
256 addAccount();
257 break;
258 default:
259 break;
260 }
261 return super.onOptionsItemSelected(item);
262 }
263
264 protected void addAccount() {
265 final Activity activity = this;
266 EditAccount dialog = new EditAccount();
267 dialog.setEditAccountListener(new EditAccountListener() {
268
269 @Override
270 public void onAccountEdited(Account account) {
271 xmppConnectionService.createAccount(account);
272 activity.getActionBar().setDisplayHomeAsUpEnabled(true);
273 }
274 });
275 dialog.show(getFragmentManager(), "add_account");
276 }
277
278
279 @Override
280 public void onActionModeStarted(ActionMode mode) {
281 super.onActionModeStarted(mode);
282 this.isActionMode = true;
283 }
284
285 @Override
286 public void onActionModeFinished(ActionMode mode) {
287 super.onActionModeFinished(mode);
288 this.isActionMode = false;
289 accountListView.clearChoices();
290 accountListView.requestLayout();
291 accountListView.post(new Runnable() {
292 @Override
293 public void run() {
294 accountListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
295 }
296 });
297 }
298
299 @Override
300 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
301 super.onActivityResult(requestCode, resultCode, data);
302 if (resultCode == RESULT_OK) {
303 if (requestCode == REQUEST_ANNOUNCE_PGP) {
304 try {
305 xmppConnectionService.generatePgpAnnouncement(selectedAccountForActionMode);
306 } catch (UserInputRequiredException e) {
307 Log.d("gultsch","already came back. ignoring");
308 }
309 }
310 }
311 }
312}