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(
322 R.layout.create_contact_dialog, null);
323 final Spinner spinner = (Spinner) dialogView.findViewById(R.id.account);
324 final AutoCompleteTextView jid = (AutoCompleteTextView) dialogView
325 .findViewById(R.id.jid);
326 jid.setAdapter(new KnownHostsAdapter(this,
327 android.R.layout.simple_list_item_1, mKnownHosts));
328 if (prefilledJid != null) {
329 jid.append(prefilledJid);
330 if (fingerprint!=null) {
331 jid.setFocusable(false);
332 jid.setFocusableInTouchMode(false);
333 jid.setClickable(false);
334 jid.setCursorVisible(false);
335 }
336 }
337 populateAccountSpinner(spinner);
338 builder.setView(dialogView);
339 builder.setNegativeButton(R.string.cancel, null);
340 builder.setPositiveButton(R.string.create, null);
341 final AlertDialog dialog = builder.create();
342 dialog.show();
343 dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(
344 new View.OnClickListener() {
345
346 @Override
347 public void onClick(View v) {
348 if (!xmppConnectionServiceBound) {
349 return;
350 }
351 if (Validator.isValidJid(jid.getText().toString())) {
352 final Jid accountJid;
353 try {
354 accountJid = Jid.fromString((String) spinner
355 .getSelectedItem());
356 } catch (final InvalidJidException e) {
357 return;
358 }
359 final Jid contactJid;
360 try {
361 contactJid = Jid.fromString(jid.getText().toString());
362 } catch (final InvalidJidException e) {
363 return;
364 }
365 Account account = xmppConnectionService
366 .findAccountByJid(accountJid);
367 if (account == null) {
368 dialog.dismiss();
369 return;
370 }
371 Contact contact = account.getRoster().getContact(contactJid);
372 if (contact.showInRoster()) {
373 jid.setError(getString(R.string.contact_already_exists));
374 } else {
375 contact.addOtrFingerprint(fingerprint);
376 xmppConnectionService.createContact(contact);
377 dialog.dismiss();
378 switchToConversation(contact);
379 }
380 } else {
381 jid.setError(getString(R.string.invalid_jid));
382 }
383 }
384 });
385
386 }
387
388 @SuppressLint("InflateParams")
389 protected void showJoinConferenceDialog(String prefilledJid) {
390 AlertDialog.Builder builder = new AlertDialog.Builder(this);
391 builder.setTitle(R.string.join_conference);
392 View dialogView = getLayoutInflater().inflate(
393 R.layout.join_conference_dialog, null);
394 final Spinner spinner = (Spinner) dialogView.findViewById(R.id.account);
395 final AutoCompleteTextView jid = (AutoCompleteTextView) dialogView
396 .findViewById(R.id.jid);
397 jid.setAdapter(new KnownHostsAdapter(this,
398 android.R.layout.simple_list_item_1, mKnownConferenceHosts));
399 if (prefilledJid != null) {
400 jid.append(prefilledJid);
401 }
402 populateAccountSpinner(spinner);
403 final CheckBox bookmarkCheckBox = (CheckBox) dialogView
404 .findViewById(R.id.bookmark);
405 builder.setView(dialogView);
406 builder.setNegativeButton(R.string.cancel, null);
407 builder.setPositiveButton(R.string.join, null);
408 final AlertDialog dialog = builder.create();
409 dialog.show();
410 dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(
411 new View.OnClickListener() {
412
413 @Override
414 public void onClick(View v) {
415 if (!xmppConnectionServiceBound) {
416 return;
417 }
418 if (Validator.isValidJid(jid.getText().toString())) {
419 final Jid accountJid;
420 try {
421 accountJid = Jid.fromString((String) spinner.getSelectedItem());
422 } catch (final InvalidJidException e) {
423 return;
424 }
425 final Jid conferenceJid;
426 try {
427 conferenceJid = Jid.fromString(jid.getText().toString());
428 } catch (final InvalidJidException e) {
429 return; // TODO: Do some error handling...
430 }
431 Account account = xmppConnectionService
432 .findAccountByJid(accountJid);
433 if (account == null) {
434 dialog.dismiss();
435 return;
436 }
437 if (bookmarkCheckBox.isChecked()) {
438 if (account.hasBookmarkFor(conferenceJid)) {
439 jid.setError(getString(R.string.bookmark_already_exists));
440 } else {
441 Bookmark bookmark = new Bookmark(account,
442 conferenceJid);
443 bookmark.setAutojoin(true);
444 account.getBookmarks().add(bookmark);
445 xmppConnectionService
446 .pushBookmarks(account);
447 Conversation conversation = xmppConnectionService
448 .findOrCreateConversation(account,
449 conferenceJid, true);
450 conversation.setBookmark(bookmark);
451 if (!conversation.getMucOptions().online()) {
452 xmppConnectionService
453 .joinMuc(conversation);
454 }
455 dialog.dismiss();
456 switchToConversation(conversation);
457 }
458 } else {
459 Conversation conversation = xmppConnectionService
460 .findOrCreateConversation(account,
461 conferenceJid, true);
462 if (!conversation.getMucOptions().online()) {
463 xmppConnectionService.joinMuc(conversation);
464 }
465 dialog.dismiss();
466 switchToConversation(conversation);
467 }
468 } else {
469 jid.setError(getString(R.string.invalid_jid));
470 }
471 }
472 });
473 }
474
475 protected void switchToConversation(Contact contact) {
476 Conversation conversation = xmppConnectionService
477 .findOrCreateConversation(contact.getAccount(),
478 contact.getJid(), false);
479 switchToConversation(conversation);
480 }
481
482 private void populateAccountSpinner(Spinner spinner) {
483 ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
484 android.R.layout.simple_spinner_item, mActivatedAccounts);
485 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
486 spinner.setAdapter(adapter);
487 }
488
489 @Override
490 public boolean onCreateOptionsMenu(Menu menu) {
491 this.mOptionsMenu = menu;
492 getMenuInflater().inflate(R.menu.start_conversation, menu);
493 MenuItem menuCreateContact = menu
494 .findItem(R.id.action_create_contact);
495 MenuItem menuCreateConference = menu
496 .findItem(R.id.action_join_conference);
497 mMenuSearchView = menu.findItem(R.id.action_search);
498 mMenuSearchView.setOnActionExpandListener(mOnActionExpandListener);
499 View mSearchView = mMenuSearchView.getActionView();
500 mSearchEditText = (EditText) mSearchView
501 .findViewById(R.id.search_field);
502 mSearchEditText.addTextChangedListener(mSearchTextWatcher);
503 if (getActionBar().getSelectedNavigationIndex() == 0) {
504 menuCreateConference.setVisible(false);
505 } else {
506 menuCreateContact.setVisible(false);
507 }
508 if (mInitialJid != null) {
509 mMenuSearchView.expandActionView();
510 mSearchEditText.append(mInitialJid);
511 filter(mInitialJid);
512 }
513 return true;
514 }
515
516 @Override
517 public boolean onOptionsItemSelected(MenuItem item) {
518 switch (item.getItemId()) {
519 case R.id.action_create_contact:
520 showCreateContactDialog(null,null);
521 return true;
522 case R.id.action_join_conference:
523 showJoinConferenceDialog(null);
524 return true;
525 case R.id.action_scan_qr_code:
526 new IntentIntegrator(this).initiateScan();
527 return true;
528 }
529 return super.onOptionsItemSelected(item);
530 }
531
532 @Override
533 public boolean onKeyUp(int keyCode, KeyEvent event) {
534 if (keyCode == KeyEvent.KEYCODE_SEARCH && !event.isLongPress()) {
535 mOptionsMenu.findItem(R.id.action_search).expandActionView();
536 return true;
537 }
538 return super.onKeyUp(keyCode, event);
539 }
540
541 @Override
542 public void onActivityResult(int requestCode, int resultCode, Intent intent) {
543 if ((requestCode & 0xFFFF) == IntentIntegrator.REQUEST_CODE) {
544 IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
545 if (scanResult != null && scanResult.getFormatName() != null) {
546 String data = scanResult.getContents();
547 Invite invite = new Invite(data);
548 if (xmppConnectionServiceBound) {
549 invite.invite();
550 } else if (invite.getJid() != null) {
551 this.mPendingInvite = invite;
552 } else {
553 this.mPendingInvite = null;
554 }
555 }
556 }
557 super.onActivityResult(requestCode, requestCode, intent);
558 }
559
560 @Override
561 protected void onBackendConnected() {
562 this.mActivatedAccounts.clear();
563 for (Account account : xmppConnectionService.getAccounts()) {
564 if (account.getStatus() != Account.State.DISABLED) {
565 this.mActivatedAccounts.add(account.getJid().toBareJid().toString());
566 }
567 }
568 this.mKnownHosts = xmppConnectionService.getKnownHosts();
569 this.mKnownConferenceHosts = xmppConnectionService
570 .getKnownConferenceHosts();
571 if (this.mPendingInvite != null) {
572 mPendingInvite.invite();
573 this.mPendingInvite = null;
574 } else if (!handleIntent(getIntent())) {
575 if (mSearchEditText != null) {
576 filter(mSearchEditText.getText().toString());
577 } else {
578 filter(null);
579 }
580 }
581 setIntent(null);
582 }
583
584 @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
585 Invite getInviteJellyBean(NdefRecord record) {
586 return new Invite(record.toUri());
587 }
588
589 protected boolean handleIntent(Intent intent) {
590 if (intent == null || intent.getAction() == null) {
591 return false;
592 }
593 switch (intent.getAction()) {
594 case Intent.ACTION_SENDTO:
595 case Intent.ACTION_VIEW:
596 Log.d(Config.LOGTAG, "received uri=" + intent.getData());
597 return new Invite(intent.getData()).invite();
598 case NfcAdapter.ACTION_NDEF_DISCOVERED:
599 for (Parcelable message : getIntent().getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)) {
600 if (message instanceof NdefMessage) {
601 Log.d(Config.LOGTAG, "received message=" + message);
602 for (NdefRecord record : ((NdefMessage) message).getRecords()) {
603 switch (record.getTnf()) {
604 case NdefRecord.TNF_WELL_KNOWN:
605 if (Arrays.equals(record.getType(), NdefRecord.RTD_URI)) {
606 if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
607 return getInviteJellyBean(record).invite();
608 } else {
609 byte[] payload = record.getPayload();
610 if (payload[0] == 0) {
611 return new Invite(Uri.parse(new String(Arrays.copyOfRange(
612 payload, 1, payload.length)))).invite();
613 }
614 }
615 }
616 }
617 }
618 }
619 }
620 }
621 return false;
622 }
623
624 private boolean handleJid(Invite invite) {
625 List<Contact> contacts = xmppConnectionService.findContacts(invite.getJid());
626 if (contacts.size() == 0) {
627 showCreateContactDialog(invite.getJid().toString(),invite.getFingerprint());
628 return false;
629 } else if (contacts.size() == 1) {
630 Contact contact = contacts.get(0);
631 if (invite.getFingerprint() != null) {
632 if (contact.addOtrFingerprint(invite.getFingerprint())) {
633 Log.d(Config.LOGTAG,"added new fingerprint");
634 xmppConnectionService.syncRosterToDisk(contact.getAccount());
635 }
636 }
637 switchToConversation(contact);
638 return true;
639 } else {
640 if (mMenuSearchView != null) {
641 mMenuSearchView.expandActionView();
642 mSearchEditText.setText("");
643 mSearchEditText.append(invite.getJid().toString());
644 filter(invite.getJid().toString());
645 } else {
646 mInitialJid = invite.getJid().toString();
647 }
648 return true;
649 }
650 }
651
652 protected void filter(String needle) {
653 if (xmppConnectionServiceBound) {
654 this.filterContacts(needle);
655 this.filterConferences(needle);
656 }
657 }
658
659 protected void filterContacts(String needle) {
660 this.contacts.clear();
661 for (Account account : xmppConnectionService.getAccounts()) {
662 if (account.getStatus() != Account.State.DISABLED) {
663 for (Contact contact : account.getRoster().getContacts()) {
664 if (contact.showInRoster() && contact.match(needle)) {
665 this.contacts.add(contact);
666 }
667 }
668 }
669 }
670 Collections.sort(this.contacts);
671 mContactsAdapter.notifyDataSetChanged();
672 }
673
674 protected void filterConferences(String needle) {
675 this.conferences.clear();
676 for (Account account : xmppConnectionService.getAccounts()) {
677 if (account.getStatus() != Account.State.DISABLED) {
678 for (Bookmark bookmark : account.getBookmarks()) {
679 if (bookmark.match(needle)) {
680 this.conferences.add(bookmark);
681 }
682 }
683 }
684 }
685 Collections.sort(this.conferences);
686 mConferenceAdapter.notifyDataSetChanged();
687 }
688
689 private void onTabChanged() {
690 invalidateOptionsMenu();
691 }
692
693 public static class MyListFragment extends ListFragment {
694 private AdapterView.OnItemClickListener mOnItemClickListener;
695 private int mResContextMenu;
696
697 public void setContextMenu(int res) {
698 this.mResContextMenu = res;
699 }
700
701 @Override
702 public void onListItemClick(ListView l, View v, int position, long id) {
703 if (mOnItemClickListener != null) {
704 mOnItemClickListener.onItemClick(l, v, position, id);
705 }
706 }
707
708 public void setOnListItemClickListener(AdapterView.OnItemClickListener l) {
709 this.mOnItemClickListener = l;
710 }
711
712 @Override
713 public void onViewCreated(View view, Bundle savedInstanceState) {
714 super.onViewCreated(view, savedInstanceState);
715 registerForContextMenu(getListView());
716 getListView().setFastScrollEnabled(true);
717 }
718
719 @Override
720 public void onCreateContextMenu(ContextMenu menu, View v,
721 ContextMenuInfo menuInfo) {
722 super.onCreateContextMenu(menu, v, menuInfo);
723 StartConversationActivity activity = (StartConversationActivity) getActivity();
724 activity.getMenuInflater().inflate(mResContextMenu, menu);
725 AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
726 if (mResContextMenu == R.menu.conference_context) {
727 activity.conference_context_id = acmi.position;
728 } else {
729 activity.contact_context_id = acmi.position;
730 }
731 }
732
733 @Override
734 public boolean onContextItemSelected(MenuItem item) {
735 StartConversationActivity activity = (StartConversationActivity) getActivity();
736 switch (item.getItemId()) {
737 case R.id.context_start_conversation:
738 activity.openConversationForContact();
739 break;
740 case R.id.context_contact_details:
741 activity.openDetailsForContact();
742 break;
743 case R.id.context_delete_contact:
744 activity.deleteContact();
745 break;
746 case R.id.context_join_conference:
747 activity.openConversationForBookmark();
748 break;
749 case R.id.context_delete_conference:
750 activity.deleteConference();
751 }
752 return true;
753 }
754 }
755
756 private class Invite extends XmppUri {
757
758 public Invite(Uri uri) {
759 super(uri);
760 }
761
762 public Invite(String uri) {
763 super(uri);
764 }
765
766 boolean invite() {
767 if (jid != null) {
768 if (muc) {
769 showJoinConferenceDialog(jid);
770 } else {
771 return handleJid(this);
772 }
773 }
774 return false;
775 }
776 }
777}