1package eu.siacs.conversations.ui;
2
3import android.annotation.SuppressLint;
4import android.annotation.TargetApi;
5import android.app.ActionBar;
6import android.app.ActionBar.Tab;
7import android.app.ActionBar.TabListener;
8import android.app.AlertDialog;
9import android.app.Fragment;
10import android.app.FragmentTransaction;
11import android.app.ListFragment;
12import android.content.Context;
13import android.content.DialogInterface;
14import android.content.DialogInterface.OnClickListener;
15import android.content.Intent;
16import android.net.Uri;
17import android.nfc.NdefMessage;
18import android.nfc.NdefRecord;
19import android.nfc.NfcAdapter;
20import android.os.Build;
21import android.os.Bundle;
22import android.os.Parcelable;
23import android.support.v13.app.FragmentPagerAdapter;
24import android.support.v4.view.ViewPager;
25import android.text.Editable;
26import android.text.TextWatcher;
27import android.util.Log;
28import android.view.ContextMenu;
29import android.view.ContextMenu.ContextMenuInfo;
30import android.view.KeyEvent;
31import android.view.Menu;
32import android.view.MenuItem;
33import android.view.View;
34import android.view.inputmethod.InputMethodManager;
35import android.widget.AdapterView;
36import android.widget.AdapterView.AdapterContextMenuInfo;
37import android.widget.AdapterView.OnItemClickListener;
38import android.widget.ArrayAdapter;
39import android.widget.AutoCompleteTextView;
40import android.widget.CheckBox;
41import android.widget.EditText;
42import android.widget.ListView;
43import android.widget.Spinner;
44
45import com.google.zxing.integration.android.IntentIntegrator;
46import com.google.zxing.integration.android.IntentResult;
47
48import java.util.ArrayList;
49import java.util.Arrays;
50import java.util.Collections;
51import java.util.List;
52
53import eu.siacs.conversations.Config;
54import eu.siacs.conversations.R;
55import eu.siacs.conversations.entities.Account;
56import eu.siacs.conversations.entities.Bookmark;
57import eu.siacs.conversations.entities.Contact;
58import eu.siacs.conversations.entities.Conversation;
59import eu.siacs.conversations.entities.ListItem;
60import eu.siacs.conversations.utils.XmppUri;
61import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
62import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
63import eu.siacs.conversations.ui.adapter.ListItemAdapter;
64import eu.siacs.conversations.utils.Validator;
65import eu.siacs.conversations.xmpp.jid.InvalidJidException;
66import eu.siacs.conversations.xmpp.jid.Jid;
67
68public class StartConversationActivity extends XmppActivity implements OnRosterUpdate {
69
70 public int conference_context_id;
71 public int contact_context_id;
72 private Tab mContactsTab;
73 private Tab mConferencesTab;
74 private ViewPager mViewPager;
75 private MyListFragment mContactsListFragment = new MyListFragment();
76 private List<ListItem> contacts = new ArrayList<>();
77 private ArrayAdapter<ListItem> mContactsAdapter;
78 private MyListFragment mConferenceListFragment = new MyListFragment();
79 private List<ListItem> conferences = new ArrayList<ListItem>();
80 private ArrayAdapter<ListItem> mConferenceAdapter;
81 private List<String> mActivatedAccounts = new ArrayList<String>();
82 private List<String> mKnownHosts;
83 private List<String> mKnownConferenceHosts;
84 private Invite mPendingInvite = null;
85 private Menu mOptionsMenu;
86 private EditText mSearchEditText;
87 private MenuItem.OnActionExpandListener mOnActionExpandListener = new MenuItem.OnActionExpandListener() {
88
89 @Override
90 public boolean onMenuItemActionExpand(MenuItem item) {
91 mSearchEditText.post(new Runnable() {
92
93 @Override
94 public void run() {
95 mSearchEditText.requestFocus();
96 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
97 imm.showSoftInput(mSearchEditText,
98 InputMethodManager.SHOW_IMPLICIT);
99 }
100 });
101
102 return true;
103 }
104
105 @Override
106 public boolean onMenuItemActionCollapse(MenuItem item) {
107 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
108 imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(),
109 InputMethodManager.HIDE_IMPLICIT_ONLY);
110 mSearchEditText.setText("");
111 filter(null);
112 return true;
113 }
114 };
115 private TabListener mTabListener = new TabListener() {
116
117 @Override
118 public void onTabUnselected(Tab tab, FragmentTransaction ft) {
119 return;
120 }
121
122 @Override
123 public void onTabSelected(Tab tab, FragmentTransaction ft) {
124 mViewPager.setCurrentItem(tab.getPosition());
125 onTabChanged();
126 }
127
128 @Override
129 public void onTabReselected(Tab tab, FragmentTransaction ft) {
130 return;
131 }
132 };
133 private ViewPager.SimpleOnPageChangeListener mOnPageChangeListener = new ViewPager.SimpleOnPageChangeListener() {
134 @Override
135 public void onPageSelected(int position) {
136 getActionBar().setSelectedNavigationItem(position);
137 onTabChanged();
138 }
139 };
140 private TextWatcher mSearchTextWatcher = new TextWatcher() {
141
142 @Override
143 public void afterTextChanged(Editable editable) {
144 filter(editable.toString());
145 }
146
147 @Override
148 public void beforeTextChanged(CharSequence s, int start, int count,
149 int after) {
150 }
151
152 @Override
153 public void onTextChanged(CharSequence s, int start, int before,
154 int count) {
155 }
156 };
157 private MenuItem mMenuSearchView;
158 private String mInitialJid;
159
160 @Override
161 public void onRosterUpdate() {
162 runOnUiThread(new Runnable() {
163
164 @Override
165 public void run() {
166 if (mSearchEditText != null) {
167 filter(mSearchEditText.getText().toString());
168 }
169 }
170 });
171 }
172
173 @Override
174 public void onCreate(Bundle savedInstanceState) {
175 super.onCreate(savedInstanceState);
176 setContentView(R.layout.activity_start_conversation);
177 mViewPager = (ViewPager) findViewById(R.id.start_conversation_view_pager);
178 ActionBar actionBar = getActionBar();
179 actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
180
181 mContactsTab = actionBar.newTab().setText(R.string.contacts)
182 .setTabListener(mTabListener);
183 mConferencesTab = actionBar.newTab().setText(R.string.conferences)
184 .setTabListener(mTabListener);
185 actionBar.addTab(mContactsTab);
186 actionBar.addTab(mConferencesTab);
187
188 mViewPager.setOnPageChangeListener(mOnPageChangeListener);
189 mViewPager.setAdapter(new FragmentPagerAdapter(getFragmentManager()) {
190
191 @Override
192 public int getCount() {
193 return 2;
194 }
195
196 @Override
197 public Fragment getItem(int position) {
198 if (position == 0) {
199 return mContactsListFragment;
200 } else {
201 return mConferenceListFragment;
202 }
203 }
204 });
205
206 mConferenceAdapter = new ListItemAdapter(this, conferences);
207 mConferenceListFragment.setListAdapter(mConferenceAdapter);
208 mConferenceListFragment.setContextMenu(R.menu.conference_context);
209 mConferenceListFragment
210 .setOnListItemClickListener(new OnItemClickListener() {
211
212 @Override
213 public void onItemClick(AdapterView<?> arg0, View arg1,
214 int position, long arg3) {
215 openConversationForBookmark(position);
216 }
217 });
218
219 mContactsAdapter = new ListItemAdapter(this, contacts);
220 mContactsListFragment.setListAdapter(mContactsAdapter);
221 mContactsListFragment.setContextMenu(R.menu.contact_context);
222 mContactsListFragment
223 .setOnListItemClickListener(new OnItemClickListener() {
224
225 @Override
226 public void onItemClick(AdapterView<?> arg0, View arg1,
227 int position, long arg3) {
228 openConversationForContact(position);
229 }
230 });
231
232 }
233
234 protected void openConversationForContact(int position) {
235 Contact contact = (Contact) contacts.get(position);
236 Conversation conversation = xmppConnectionService
237 .findOrCreateConversation(contact.getAccount(),
238 contact.getJid(), false);
239 switchToConversation(conversation);
240 }
241
242 protected void openConversationForContact() {
243 int position = contact_context_id;
244 openConversationForContact(position);
245 }
246
247 protected void openConversationForBookmark() {
248 openConversationForBookmark(conference_context_id);
249 }
250
251 protected void openConversationForBookmark(int position) {
252 Bookmark bookmark = (Bookmark) conferences.get(position);
253 Conversation conversation = xmppConnectionService
254 .findOrCreateConversation(bookmark.getAccount(),
255 bookmark.getJid(), true);
256 conversation.setBookmark(bookmark);
257 if (!conversation.getMucOptions().online()) {
258 xmppConnectionService.joinMuc(conversation);
259 }
260 if (!bookmark.autojoin()) {
261 bookmark.setAutojoin(true);
262 xmppConnectionService.pushBookmarks(bookmark.getAccount());
263 }
264 switchToConversation(conversation);
265 }
266
267 protected void openDetailsForContact() {
268 int position = contact_context_id;
269 Contact contact = (Contact) contacts.get(position);
270 switchToContactDetails(contact);
271 }
272
273 protected void deleteContact() {
274 int position = contact_context_id;
275 final Contact contact = (Contact) contacts.get(position);
276 AlertDialog.Builder builder = new AlertDialog.Builder(this);
277 builder.setNegativeButton(R.string.cancel, null);
278 builder.setTitle(R.string.action_delete_contact);
279 builder.setMessage(getString(R.string.remove_contact_text,
280 contact.getJid()));
281 builder.setPositiveButton(R.string.delete, new OnClickListener() {
282
283 @Override
284 public void onClick(DialogInterface dialog, int which) {
285 xmppConnectionService.deleteContactOnServer(contact);
286 filter(mSearchEditText.getText().toString());
287 }
288 });
289 builder.create().show();
290
291 }
292
293 protected void deleteConference() {
294 int position = conference_context_id;
295 final Bookmark bookmark = (Bookmark) conferences.get(position);
296
297 AlertDialog.Builder builder = new AlertDialog.Builder(this);
298 builder.setNegativeButton(R.string.cancel, null);
299 builder.setTitle(R.string.delete_bookmark);
300 builder.setMessage(getString(R.string.remove_bookmark_text,
301 bookmark.getJid()));
302 builder.setPositiveButton(R.string.delete, new OnClickListener() {
303
304 @Override
305 public void onClick(DialogInterface dialog, int which) {
306 bookmark.unregisterConversation();
307 Account account = bookmark.getAccount();
308 account.getBookmarks().remove(bookmark);
309 xmppConnectionService.pushBookmarks(account);
310 filter(mSearchEditText.getText().toString());
311 }
312 });
313 builder.create().show();
314
315 }
316
317 @SuppressLint("InflateParams")
318 protected void showCreateContactDialog(final String prefilledJid, final String fingerprint) {
319 AlertDialog.Builder builder = new AlertDialog.Builder(this);
320 builder.setTitle(R.string.create_contact);
321 View dialogView = getLayoutInflater().inflate(R.layout.create_contact_dialog, null);
322 final Spinner spinner = (Spinner) dialogView.findViewById(R.id.account);
323 final AutoCompleteTextView jid = (AutoCompleteTextView) dialogView.findViewById(R.id.jid);
324 jid.setAdapter(new KnownHostsAdapter(this,android.R.layout.simple_list_item_1, mKnownHosts));
325 if (prefilledJid != null) {
326 jid.append(prefilledJid);
327 if (fingerprint!=null) {
328 jid.setFocusable(false);
329 jid.setFocusableInTouchMode(false);
330 jid.setClickable(false);
331 jid.setCursorVisible(false);
332 }
333 }
334 populateAccountSpinner(spinner);
335 builder.setView(dialogView);
336 builder.setNegativeButton(R.string.cancel, null);
337 builder.setPositiveButton(R.string.create, null);
338 final AlertDialog dialog = builder.create();
339 dialog.show();
340 dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(
341 new View.OnClickListener() {
342
343 @Override
344 public void onClick(View v) {
345 if (!xmppConnectionServiceBound) {
346 return;
347 }
348 if (Validator.isValidJid(jid.getText().toString())) {
349 final Jid accountJid;
350 try {
351 accountJid = Jid.fromString((String) spinner.getSelectedItem());
352 } catch (final InvalidJidException e) {
353 return;
354 }
355 final Jid contactJid;
356 try {
357 contactJid = Jid.fromString(jid.getText().toString());
358 } catch (final InvalidJidException e) {
359 jid.setError(getString(R.string.invalid_jid));
360 return;
361 }
362 Account account = xmppConnectionService
363 .findAccountByJid(accountJid);
364 if (account == null) {
365 dialog.dismiss();
366 return;
367 }
368 Contact contact = account.getRoster().getContact(contactJid);
369 if (contact.showInRoster()) {
370 jid.setError(getString(R.string.contact_already_exists));
371 } else {
372 contact.addOtrFingerprint(fingerprint);
373 xmppConnectionService.createContact(contact);
374 dialog.dismiss();
375 switchToConversation(contact);
376 }
377 } else {
378 jid.setError(getString(R.string.invalid_jid));
379 }
380 }
381 });
382
383 }
384
385 @SuppressLint("InflateParams")
386 protected void showJoinConferenceDialog(String prefilledJid) {
387 AlertDialog.Builder builder = new AlertDialog.Builder(this);
388 builder.setTitle(R.string.join_conference);
389 View dialogView = getLayoutInflater().inflate(R.layout.join_conference_dialog, null);
390 final Spinner spinner = (Spinner) dialogView.findViewById(R.id.account);
391 final AutoCompleteTextView jid = (AutoCompleteTextView) dialogView.findViewById(R.id.jid);
392 jid.setAdapter(new KnownHostsAdapter(this,android.R.layout.simple_list_item_1, mKnownConferenceHosts));
393 if (prefilledJid != null) {
394 jid.append(prefilledJid);
395 }
396 populateAccountSpinner(spinner);
397 final CheckBox bookmarkCheckBox = (CheckBox) dialogView
398 .findViewById(R.id.bookmark);
399 builder.setView(dialogView);
400 builder.setNegativeButton(R.string.cancel, null);
401 builder.setPositiveButton(R.string.join, null);
402 final AlertDialog dialog = builder.create();
403 dialog.show();
404 dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(
405 new View.OnClickListener() {
406
407 @Override
408 public void onClick(View v) {
409 if (!xmppConnectionServiceBound) {
410 return;
411 }
412 if (Validator.isValidJid(jid.getText().toString())) {
413 final Jid accountJid;
414 try {
415 accountJid = Jid.fromString((String) spinner.getSelectedItem());
416 } catch (final InvalidJidException e) {
417 return;
418 }
419 final Jid conferenceJid;
420 try {
421 conferenceJid = Jid.fromString(jid.getText().toString());
422 } catch (final InvalidJidException e) {
423 jid.setError(getString(R.string.invalid_jid));
424 return;
425 }
426 Account account = xmppConnectionService
427 .findAccountByJid(accountJid);
428 if (account == null) {
429 dialog.dismiss();
430 return;
431 }
432 if (bookmarkCheckBox.isChecked()) {
433 if (account.hasBookmarkFor(conferenceJid)) {
434 jid.setError(getString(R.string.bookmark_already_exists));
435 } else {
436 Bookmark bookmark = new Bookmark(account,
437 conferenceJid);
438 bookmark.setAutojoin(true);
439 account.getBookmarks().add(bookmark);
440 xmppConnectionService
441 .pushBookmarks(account);
442 Conversation conversation = xmppConnectionService
443 .findOrCreateConversation(account,
444 conferenceJid, true);
445 conversation.setBookmark(bookmark);
446 if (!conversation.getMucOptions().online()) {
447 xmppConnectionService
448 .joinMuc(conversation);
449 }
450 dialog.dismiss();
451 switchToConversation(conversation);
452 }
453 } else {
454 Conversation conversation = xmppConnectionService
455 .findOrCreateConversation(account,
456 conferenceJid, true);
457 if (!conversation.getMucOptions().online()) {
458 xmppConnectionService.joinMuc(conversation);
459 }
460 dialog.dismiss();
461 switchToConversation(conversation);
462 }
463 } else {
464 jid.setError(getString(R.string.invalid_jid));
465 }
466 }
467 });
468 }
469
470 protected void switchToConversation(Contact contact) {
471 Conversation conversation = xmppConnectionService
472 .findOrCreateConversation(contact.getAccount(),
473 contact.getJid(), false);
474 switchToConversation(conversation);
475 }
476
477 private void populateAccountSpinner(Spinner spinner) {
478 ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
479 android.R.layout.simple_spinner_item, mActivatedAccounts);
480 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
481 spinner.setAdapter(adapter);
482 }
483
484 @Override
485 public boolean onCreateOptionsMenu(Menu menu) {
486 this.mOptionsMenu = menu;
487 getMenuInflater().inflate(R.menu.start_conversation, menu);
488 MenuItem menuCreateContact = menu
489 .findItem(R.id.action_create_contact);
490 MenuItem menuCreateConference = menu
491 .findItem(R.id.action_join_conference);
492 mMenuSearchView = menu.findItem(R.id.action_search);
493 mMenuSearchView.setOnActionExpandListener(mOnActionExpandListener);
494 View mSearchView = mMenuSearchView.getActionView();
495 mSearchEditText = (EditText) mSearchView
496 .findViewById(R.id.search_field);
497 mSearchEditText.addTextChangedListener(mSearchTextWatcher);
498 if (getActionBar().getSelectedNavigationIndex() == 0) {
499 menuCreateConference.setVisible(false);
500 } else {
501 menuCreateContact.setVisible(false);
502 }
503 if (mInitialJid != null) {
504 mMenuSearchView.expandActionView();
505 mSearchEditText.append(mInitialJid);
506 filter(mInitialJid);
507 }
508 return true;
509 }
510
511 @Override
512 public boolean onOptionsItemSelected(MenuItem item) {
513 switch (item.getItemId()) {
514 case R.id.action_create_contact:
515 showCreateContactDialog(null,null);
516 return true;
517 case R.id.action_join_conference:
518 showJoinConferenceDialog(null);
519 return true;
520 case R.id.action_scan_qr_code:
521 new IntentIntegrator(this).initiateScan();
522 return true;
523 }
524 return super.onOptionsItemSelected(item);
525 }
526
527 @Override
528 public boolean onKeyUp(int keyCode, KeyEvent event) {
529 if (keyCode == KeyEvent.KEYCODE_SEARCH && !event.isLongPress()) {
530 mOptionsMenu.findItem(R.id.action_search).expandActionView();
531 return true;
532 }
533 return super.onKeyUp(keyCode, event);
534 }
535
536 @Override
537 public void onActivityResult(int requestCode, int resultCode, Intent intent) {
538 if ((requestCode & 0xFFFF) == IntentIntegrator.REQUEST_CODE) {
539 IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
540 if (scanResult != null && scanResult.getFormatName() != null) {
541 String data = scanResult.getContents();
542 Invite invite = new Invite(data);
543 if (xmppConnectionServiceBound) {
544 invite.invite();
545 } else if (invite.getJid() != null) {
546 this.mPendingInvite = invite;
547 } else {
548 this.mPendingInvite = null;
549 }
550 }
551 }
552 super.onActivityResult(requestCode, requestCode, intent);
553 }
554
555 @Override
556 protected void onBackendConnected() {
557 this.mActivatedAccounts.clear();
558 for (Account account : xmppConnectionService.getAccounts()) {
559 if (account.getStatus() != Account.State.DISABLED) {
560 this.mActivatedAccounts.add(account.getJid().toBareJid().toString());
561 }
562 }
563 this.mKnownHosts = xmppConnectionService.getKnownHosts();
564 this.mKnownConferenceHosts = xmppConnectionService
565 .getKnownConferenceHosts();
566 if (this.mPendingInvite != null) {
567 mPendingInvite.invite();
568 this.mPendingInvite = null;
569 } else if (!handleIntent(getIntent())) {
570 if (mSearchEditText != null) {
571 filter(mSearchEditText.getText().toString());
572 } else {
573 filter(null);
574 }
575 }
576 setIntent(null);
577 }
578
579 @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
580 Invite getInviteJellyBean(NdefRecord record) {
581 return new Invite(record.toUri());
582 }
583
584 protected boolean handleIntent(Intent intent) {
585 if (intent == null || intent.getAction() == null) {
586 return false;
587 }
588 switch (intent.getAction()) {
589 case Intent.ACTION_SENDTO:
590 case Intent.ACTION_VIEW:
591 Log.d(Config.LOGTAG, "received uri=" + intent.getData());
592 return new Invite(intent.getData()).invite();
593 case NfcAdapter.ACTION_NDEF_DISCOVERED:
594 for (Parcelable message : getIntent().getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)) {
595 if (message instanceof NdefMessage) {
596 Log.d(Config.LOGTAG, "received message=" + message);
597 for (NdefRecord record : ((NdefMessage) message).getRecords()) {
598 switch (record.getTnf()) {
599 case NdefRecord.TNF_WELL_KNOWN:
600 if (Arrays.equals(record.getType(), NdefRecord.RTD_URI)) {
601 if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
602 return getInviteJellyBean(record).invite();
603 } else {
604 byte[] payload = record.getPayload();
605 if (payload[0] == 0) {
606 return new Invite(Uri.parse(new String(Arrays.copyOfRange(
607 payload, 1, payload.length)))).invite();
608 }
609 }
610 }
611 }
612 }
613 }
614 }
615 }
616 return false;
617 }
618
619 private boolean handleJid(Invite invite) {
620 List<Contact> contacts = xmppConnectionService.findContacts(invite.getJid());
621 if (contacts.size() == 0) {
622 showCreateContactDialog(invite.getJid().toString(),invite.getFingerprint());
623 return false;
624 } else if (contacts.size() == 1) {
625 Contact contact = contacts.get(0);
626 if (invite.getFingerprint() != null) {
627 if (contact.addOtrFingerprint(invite.getFingerprint())) {
628 Log.d(Config.LOGTAG,"added new fingerprint");
629 xmppConnectionService.syncRosterToDisk(contact.getAccount());
630 }
631 }
632 switchToConversation(contact);
633 return true;
634 } else {
635 if (mMenuSearchView != null) {
636 mMenuSearchView.expandActionView();
637 mSearchEditText.setText("");
638 mSearchEditText.append(invite.getJid().toString());
639 filter(invite.getJid().toString());
640 } else {
641 mInitialJid = invite.getJid().toString();
642 }
643 return true;
644 }
645 }
646
647 protected void filter(String needle) {
648 if (xmppConnectionServiceBound) {
649 this.filterContacts(needle);
650 this.filterConferences(needle);
651 }
652 }
653
654 protected void filterContacts(String needle) {
655 this.contacts.clear();
656 for (Account account : xmppConnectionService.getAccounts()) {
657 if (account.getStatus() != Account.State.DISABLED) {
658 for (Contact contact : account.getRoster().getContacts()) {
659 if (contact.showInRoster() && contact.match(needle)) {
660 this.contacts.add(contact);
661 }
662 }
663 }
664 }
665 Collections.sort(this.contacts);
666 mContactsAdapter.notifyDataSetChanged();
667 }
668
669 protected void filterConferences(String needle) {
670 this.conferences.clear();
671 for (Account account : xmppConnectionService.getAccounts()) {
672 if (account.getStatus() != Account.State.DISABLED) {
673 for (Bookmark bookmark : account.getBookmarks()) {
674 if (bookmark.match(needle)) {
675 this.conferences.add(bookmark);
676 }
677 }
678 }
679 }
680 Collections.sort(this.conferences);
681 mConferenceAdapter.notifyDataSetChanged();
682 }
683
684 private void onTabChanged() {
685 invalidateOptionsMenu();
686 }
687
688 public static class MyListFragment extends ListFragment {
689 private AdapterView.OnItemClickListener mOnItemClickListener;
690 private int mResContextMenu;
691
692 public void setContextMenu(int res) {
693 this.mResContextMenu = res;
694 }
695
696 @Override
697 public void onListItemClick(ListView l, View v, int position, long id) {
698 if (mOnItemClickListener != null) {
699 mOnItemClickListener.onItemClick(l, v, position, id);
700 }
701 }
702
703 public void setOnListItemClickListener(AdapterView.OnItemClickListener l) {
704 this.mOnItemClickListener = l;
705 }
706
707 @Override
708 public void onViewCreated(View view, Bundle savedInstanceState) {
709 super.onViewCreated(view, savedInstanceState);
710 registerForContextMenu(getListView());
711 getListView().setFastScrollEnabled(true);
712 }
713
714 @Override
715 public void onCreateContextMenu(ContextMenu menu, View v,
716 ContextMenuInfo menuInfo) {
717 super.onCreateContextMenu(menu, v, menuInfo);
718 StartConversationActivity activity = (StartConversationActivity) getActivity();
719 activity.getMenuInflater().inflate(mResContextMenu, menu);
720 AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
721 if (mResContextMenu == R.menu.conference_context) {
722 activity.conference_context_id = acmi.position;
723 } else {
724 activity.contact_context_id = acmi.position;
725 }
726 }
727
728 @Override
729 public boolean onContextItemSelected(MenuItem item) {
730 StartConversationActivity activity = (StartConversationActivity) getActivity();
731 switch (item.getItemId()) {
732 case R.id.context_start_conversation:
733 activity.openConversationForContact();
734 break;
735 case R.id.context_contact_details:
736 activity.openDetailsForContact();
737 break;
738 case R.id.context_delete_contact:
739 activity.deleteContact();
740 break;
741 case R.id.context_join_conference:
742 activity.openConversationForBookmark();
743 break;
744 case R.id.context_delete_conference:
745 activity.deleteConference();
746 }
747 return true;
748 }
749 }
750
751 private class Invite extends XmppUri {
752
753 public Invite(Uri uri) {
754 super(uri);
755 }
756
757 public Invite(String uri) {
758 super(uri);
759 }
760
761 boolean invite() {
762 if (jid != null) {
763 if (muc) {
764 showJoinConferenceDialog(jid);
765 } else {
766 return handleJid(this);
767 }
768 }
769 return false;
770 }
771 }
772}