1package eu.siacs.conversations.ui;
2
3import android.app.Activity;
4import android.content.Context;
5import android.content.Intent;
6import android.os.Bundle;
7import android.support.annotation.StringRes;
8import android.support.v7.app.ActionBar;
9import android.view.ActionMode;
10import android.view.Menu;
11import android.view.MenuInflater;
12import android.view.MenuItem;
13import android.view.View;
14import android.view.inputmethod.InputMethodManager;
15import android.widget.AbsListView.MultiChoiceModeListener;
16import android.widget.AdapterView;
17import android.widget.ListView;
18
19import java.util.ArrayList;
20import java.util.Collections;
21import java.util.HashSet;
22import java.util.List;
23import java.util.Set;
24
25import eu.siacs.conversations.Config;
26import eu.siacs.conversations.R;
27import eu.siacs.conversations.entities.Account;
28import eu.siacs.conversations.entities.Contact;
29import eu.siacs.conversations.entities.Conversation;
30import eu.siacs.conversations.entities.ListItem;
31import eu.siacs.conversations.entities.MucOptions;
32import rocks.xmpp.addr.Jid;
33
34public class ChooseContactActivity extends AbstractSearchableListItemActivity {
35 private List<String> mActivatedAccounts = new ArrayList<>();
36 private List<String> mKnownHosts;
37
38 private Set<Contact> selected;
39 private Set<String> filterContacts;
40 public static final String EXTRA_TITLE_RES_ID = "extra_title_res_id";
41
42 @Override
43 public void onCreate(final Bundle savedInstanceState) {
44 super.onCreate(savedInstanceState);
45 filterContacts = new HashSet<>();
46 String[] contacts = getIntent().getStringArrayExtra("filter_contacts");
47 if (contacts != null) {
48 Collections.addAll(filterContacts, contacts);
49 }
50
51 if (getIntent().getBooleanExtra("multiple", false)) {
52 getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
53 getListView().setMultiChoiceModeListener(new MultiChoiceModeListener() {
54
55 @Override
56 public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
57 return false;
58 }
59
60 @Override
61 public boolean onCreateActionMode(ActionMode mode, Menu menu) {
62 final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
63 imm.hideSoftInputFromWindow(getSearchEditText().getWindowToken(),
64 InputMethodManager.HIDE_IMPLICIT_ONLY);
65 MenuInflater inflater = getMenuInflater();
66 inflater.inflate(R.menu.select_multiple, menu);
67 selected = new HashSet<>();
68 return true;
69 }
70
71 @Override
72 public void onDestroyActionMode(ActionMode mode) {
73 }
74
75 @Override
76 public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
77 switch(item.getItemId()) {
78 case R.id.selection_submit:
79 final Intent request = getIntent();
80 final Intent data = new Intent();
81 data.putExtra("conversation",
82 request.getStringExtra("conversation"));
83 String[] selection = getSelectedContactJids();
84 data.putExtra("contacts", selection);
85 data.putExtra("multiple", true);
86 data.putExtra(EXTRA_ACCOUNT,request.getStringExtra(EXTRA_ACCOUNT));
87 data.putExtra("subject", request.getStringExtra("subject"));
88 setResult(RESULT_OK, data);
89 finish();
90 return true;
91 }
92 return false;
93 }
94
95 @Override
96 public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
97 Contact item = (Contact) getListItems().get(position);
98 if (checked) {
99 selected.add(item);
100 } else {
101 selected.remove(item);
102 }
103 int numSelected = selected.size();
104 MenuItem selectButton = mode.getMenu().findItem(R.id.selection_submit);
105 String buttonText = getResources().getQuantityString(R.plurals.select_contact,
106 numSelected, numSelected);
107 selectButton.setTitle(buttonText);
108 }
109 });
110 }
111
112 getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
113
114 @Override
115 public void onItemClick(final AdapterView<?> parent, final View view,
116 final int position, final long id) {
117 final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
118 imm.hideSoftInputFromWindow(getSearchEditText().getWindowToken(),
119 InputMethodManager.HIDE_IMPLICIT_ONLY);
120 final Intent request = getIntent();
121 final Intent data = new Intent();
122 final ListItem mListItem = getListItems().get(position);
123 data.putExtra("contact", mListItem.getJid().toString());
124 String account = request.getStringExtra(EXTRA_ACCOUNT);
125 if (account == null && mListItem instanceof Contact) {
126 account = ((Contact) mListItem).getAccount().getJid().asBareJid().toString();
127 }
128 data.putExtra(EXTRA_ACCOUNT, account);
129 data.putExtra("conversation",
130 request.getStringExtra("conversation"));
131 data.putExtra("multiple", false);
132 data.putExtra("subject", request.getStringExtra("subject"));
133 setResult(RESULT_OK, data);
134 finish();
135 }
136 });
137
138 }
139
140 @Override
141 public void onStart() {
142 super.onStart();
143 Intent intent = getIntent();
144 @StringRes
145 int res = intent != null ? intent.getIntExtra(EXTRA_TITLE_RES_ID,R.string.title_activity_choose_contact) : R.string.title_activity_choose_contact;
146 ActionBar bar = getSupportActionBar();
147 if (bar != null) {
148 try {
149 bar.setTitle(res);
150 } catch (Exception e) {
151 bar.setTitle(R.string.title_activity_choose_contact);
152 }
153 }
154 }
155
156 @Override
157 public boolean onCreateOptionsMenu(final Menu menu) {
158 super.onCreateOptionsMenu(menu);
159 final Intent i = getIntent();
160 boolean showEnterJid = i != null && i.getBooleanExtra("show_enter_jid", false);
161 menu.findItem(R.id.action_create_contact).setVisible(showEnterJid);
162 return true;
163 }
164
165 protected void filterContacts(final String needle) {
166 getListItems().clear();
167 if (xmppConnectionService == null) {
168 getListItemAdapter().notifyDataSetChanged();
169 return;
170 }
171 for (final Account account : xmppConnectionService.getAccounts()) {
172 if (account.getStatus() != Account.State.DISABLED) {
173 for (final Contact contact : account.getRoster().getContacts()) {
174 if (contact.showInRoster() &&
175 !filterContacts.contains(contact.getJid().asBareJid().toString())
176 && contact.match(this, needle)) {
177 getListItems().add(contact);
178 }
179 }
180 }
181 }
182 Collections.sort(getListItems());
183 getListItemAdapter().notifyDataSetChanged();
184 }
185
186 private String[] getSelectedContactJids() {
187 List<String> result = new ArrayList<>();
188 for (Contact contact : selected) {
189 result.add(contact.getJid().toString());
190 }
191 return result.toArray(new String[result.size()]);
192 }
193
194
195 public void refreshUiReal() {
196 //nothing to do. This Activity doesn't implement any listeners
197 }
198
199 @Override
200 public boolean onOptionsItemSelected(MenuItem item) {
201 switch (item.getItemId()) {
202 case R.id.action_create_contact:
203 showEnterJidDialog();
204 return true;
205 }
206 return super.onOptionsItemSelected(item);
207 }
208
209 protected void showEnterJidDialog() {
210 EnterJidDialog dialog = new EnterJidDialog(
211 this, mKnownHosts, mActivatedAccounts,
212 getString(R.string.enter_contact), getString(R.string.select),
213 null, getIntent().getStringExtra(EXTRA_ACCOUNT), true
214 );
215
216 dialog.setOnEnterJidDialogPositiveListener(new EnterJidDialog.OnEnterJidDialogPositiveListener() {
217 @Override
218 public boolean onEnterJidDialogPositive(Jid accountJid, Jid contactJid) throws EnterJidDialog.JidError {
219 final Intent request = getIntent();
220 final Intent data = new Intent();
221 data.putExtra("contact", contactJid.toString());
222 data.putExtra(EXTRA_ACCOUNT, accountJid.toString());
223 data.putExtra("conversation",
224 request.getStringExtra("conversation"));
225 data.putExtra("multiple", false);
226 data.putExtra("subject", request.getStringExtra("subject"));
227 setResult(RESULT_OK, data);
228 finish();
229
230 return true;
231 }
232 });
233
234 dialog.show();
235 }
236
237 @Override
238 void onBackendConnected() {
239 filterContacts();
240 this.mActivatedAccounts.clear();
241 for (Account account : xmppConnectionService.getAccounts()) {
242 if (account.getStatus() != Account.State.DISABLED) {
243 if (Config.DOMAIN_LOCK != null) {
244 this.mActivatedAccounts.add(account.getJid().getLocal());
245 } else {
246 this.mActivatedAccounts.add(account.getJid().asBareJid().toString());
247 }
248 }
249 }
250 this.mKnownHosts = xmppConnectionService.getKnownHosts();
251 }
252
253 public static Intent create(Activity activity, Conversation conversation) {
254 final Intent intent = new Intent(activity, ChooseContactActivity.class);
255 List<String> contacts = new ArrayList<>();
256 if (conversation.getMode() == Conversation.MODE_MULTI) {
257 for (MucOptions.User user : conversation.getMucOptions().getUsers(false)) {
258 Jid jid = user.getRealJid();
259 if (jid != null) {
260 contacts.add(jid.asBareJid().toString());
261 }
262 }
263 } else {
264 contacts.add(conversation.getJid().asBareJid().toString());
265 }
266 intent.putExtra("filter_contacts", contacts.toArray(new String[contacts.size()]));
267 intent.putExtra("conversation", conversation.getUuid());
268 intent.putExtra("multiple", true);
269 intent.putExtra("show_enter_jid", true);
270 intent.putExtra(EXTRA_ACCOUNT, conversation.getAccount().getJid().asBareJid().toString());
271 return intent;
272 }
273}