ConversationFragment.java

  1package eu.siacs.conversations.ui;
  2
  3import java.util.ArrayList;
  4import java.util.List;
  5import java.util.Set;
  6
  7import net.java.otr4j.session.SessionStatus;
  8import eu.siacs.conversations.R;
  9import eu.siacs.conversations.crypto.PgpEngine;
 10import eu.siacs.conversations.entities.Account;
 11import eu.siacs.conversations.entities.Contact;
 12import eu.siacs.conversations.entities.Conversation;
 13import eu.siacs.conversations.entities.Message;
 14import eu.siacs.conversations.entities.MucOptions;
 15import eu.siacs.conversations.entities.Presences;
 16import eu.siacs.conversations.services.XmppConnectionService;
 17import eu.siacs.conversations.ui.EditMessage.OnEnterPressed;
 18import eu.siacs.conversations.ui.XmppActivity.OnPresenceSelected;
 19import eu.siacs.conversations.ui.XmppActivity.OnValueEdited;
 20import eu.siacs.conversations.ui.adapter.MessageAdapter;
 21import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureClicked;
 22import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureLongClicked;
 23import eu.siacs.conversations.utils.UIHelper;
 24import android.app.AlertDialog;
 25import android.app.Fragment;
 26import android.app.PendingIntent;
 27import android.content.Context;
 28import android.content.DialogInterface;
 29import android.content.Intent;
 30import android.content.IntentSender;
 31import android.content.IntentSender.SendIntentException;
 32import android.os.Bundle;
 33import android.text.Editable;
 34import android.text.Selection;
 35import android.view.Gravity;
 36import android.view.KeyEvent;
 37import android.view.LayoutInflater;
 38import android.view.View;
 39import android.view.View.OnClickListener;
 40import android.view.ViewGroup;
 41import android.view.inputmethod.EditorInfo;
 42import android.view.inputmethod.InputMethodManager;
 43import android.widget.AbsListView.OnScrollListener;
 44import android.widget.TextView.OnEditorActionListener;
 45import android.widget.AbsListView;
 46
 47import android.widget.ListView;
 48import android.widget.ImageButton;
 49import android.widget.RelativeLayout;
 50import android.widget.TextView;
 51import android.widget.Toast;
 52
 53public class ConversationFragment extends Fragment {
 54
 55	protected Conversation conversation;
 56	protected ListView messagesView;
 57	protected LayoutInflater inflater;
 58	protected List<Message> messageList = new ArrayList<Message>();
 59	protected MessageAdapter messageListAdapter;
 60	protected Contact contact;
 61
 62	protected String queuedPqpMessage = null;
 63
 64	private EditMessage mEditMessage;
 65	private ImageButton mSendButton;
 66	private String pastedText = null;
 67	private RelativeLayout snackbar;
 68	private TextView snackbarMessage;
 69	private TextView snackbarAction;
 70
 71	private boolean messagesLoaded = false;
 72
 73	private IntentSender askForPassphraseIntent = null;
 74
 75	private OnEditorActionListener mEditorActionListener = new OnEditorActionListener() {
 76
 77		@Override
 78		public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
 79			if (actionId == EditorInfo.IME_ACTION_SEND) {
 80				InputMethodManager imm = (InputMethodManager) v.getContext()
 81						.getSystemService(Context.INPUT_METHOD_SERVICE);
 82				imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
 83				sendMessage();
 84				return true;
 85			} else {
 86				return false;
 87			}
 88		}
 89	};
 90
 91	private OnClickListener mSendButtonListener = new OnClickListener() {
 92
 93		@Override
 94		public void onClick(View v) {
 95			sendMessage();
 96		}
 97	};
 98	protected OnClickListener clickToDecryptListener = new OnClickListener() {
 99
100		@Override
101		public void onClick(View v) {
102			if (activity.hasPgp() && askForPassphraseIntent != null) {
103				try {
104					getActivity().startIntentSenderForResult(
105							askForPassphraseIntent,
106							ConversationActivity.REQUEST_DECRYPT_PGP, null, 0,
107							0, 0);
108				} catch (SendIntentException e) {
109					//
110				}
111			}
112		}
113	};
114
115	private OnClickListener clickToMuc = new OnClickListener() {
116
117		@Override
118		public void onClick(View v) {
119			Intent intent = new Intent(getActivity(),
120					ConferenceDetailsActivity.class);
121			intent.setAction(ConferenceDetailsActivity.ACTION_VIEW_MUC);
122			intent.putExtra("uuid", conversation.getUuid());
123			startActivity(intent);
124		}
125	};
126
127	private OnClickListener leaveMuc = new OnClickListener() {
128
129		@Override
130		public void onClick(View v) {
131			activity.endConversation(conversation);
132		}
133	};
134
135	private OnClickListener enterPassword = new OnClickListener() {
136
137		@Override
138		public void onClick(View v) {
139			MucOptions muc = conversation.getMucOptions();
140			String password = muc.getPassword();
141			if (password == null) {
142				password = "";
143			}
144			activity.quickPasswordEdit(password, new OnValueEdited() {
145
146				@Override
147				public void onValueEdited(String value) {
148					activity.xmppConnectionService.providePasswordForMuc(
149							conversation, value);
150				}
151			});
152		}
153	};
154
155	private OnScrollListener mOnScrollListener = new OnScrollListener() {
156
157		@Override
158		public void onScrollStateChanged(AbsListView view, int scrollState) {
159			// TODO Auto-generated method stub
160
161		}
162
163		@Override
164		public void onScroll(AbsListView view, int firstVisibleItem,
165				int visibleItemCount, int totalItemCount) {
166			if (firstVisibleItem == 0 && messagesLoaded) {
167				long timestamp = messageList.get(0).getTimeSent();
168				messagesLoaded = false;
169				int size = activity.xmppConnectionService.loadMoreMessages(
170						conversation, timestamp);
171				messageList.clear();
172				messageList.addAll(conversation.getMessages());
173				updateStatusMessages();
174				messageListAdapter.notifyDataSetChanged();
175				if (size != 0) {
176					messagesLoaded = true;
177				}
178				messagesView.setSelectionFromTop(size + 1, 0);
179			}
180		}
181	};
182
183	private ConversationActivity activity;
184
185	private void sendMessage() {
186		if (this.conversation == null) {
187			return;
188		}
189		if (mEditMessage.getText().length() < 1) {
190			if (this.conversation.getMode() == Conversation.MODE_MULTI) {
191				conversation.setNextPresence(null);
192				updateChatMsgHint();
193			}
194			return;
195		}
196		Message message = new Message(conversation, mEditMessage.getText()
197				.toString(), conversation.getNextEncryption(activity
198				.forceEncryption()));
199		if (conversation.getMode() == Conversation.MODE_MULTI) {
200			if (conversation.getNextPresence() != null) {
201				message.setPresence(conversation.getNextPresence());
202				message.setType(Message.TYPE_PRIVATE);
203				conversation.setNextPresence(null);
204			}
205		}
206		if (conversation.getNextEncryption(activity.forceEncryption()) == Message.ENCRYPTION_OTR) {
207			sendOtrMessage(message);
208		} else if (conversation.getNextEncryption(activity.forceEncryption()) == Message.ENCRYPTION_PGP) {
209			sendPgpMessage(message);
210		} else {
211			sendPlainTextMessage(message);
212		}
213	}
214
215	public void updateChatMsgHint() {
216		if (conversation.getMode() == Conversation.MODE_MULTI
217				&& conversation.getNextPresence() != null) {
218			this.mEditMessage.setHint(getString(
219					R.string.send_private_message_to,
220					conversation.getNextPresence()));
221		} else {
222			switch (conversation.getNextEncryption(activity.forceEncryption())) {
223			case Message.ENCRYPTION_NONE:
224				mEditMessage
225						.setHint(getString(R.string.send_plain_text_message));
226				break;
227			case Message.ENCRYPTION_OTR:
228				mEditMessage.setHint(getString(R.string.send_otr_message));
229				break;
230			case Message.ENCRYPTION_PGP:
231				mEditMessage.setHint(getString(R.string.send_pgp_message));
232				break;
233			default:
234				break;
235			}
236		}
237	}
238
239	@Override
240	public View onCreateView(final LayoutInflater inflater,
241			ViewGroup container, Bundle savedInstanceState) {
242		final View view = inflater.inflate(R.layout.fragment_conversation,
243				container, false);
244		mEditMessage = (EditMessage) view.findViewById(R.id.textinput);
245		mEditMessage.setOnClickListener(new OnClickListener() {
246
247			@Override
248			public void onClick(View v) {
249				activity.hideConversationsOverview();
250			}
251		});
252		mEditMessage.setOnEditorActionListener(mEditorActionListener);
253		mEditMessage.setOnEnterPressedListener(new OnEnterPressed() {
254
255			@Override
256			public void onEnterPressed() {
257				sendMessage();
258			}
259		});
260
261		mSendButton = (ImageButton) view.findViewById(R.id.textSendButton);
262		mSendButton.setOnClickListener(this.mSendButtonListener);
263
264		snackbar = (RelativeLayout) view.findViewById(R.id.snackbar);
265		snackbarMessage = (TextView) view.findViewById(R.id.snackbar_message);
266		snackbarAction = (TextView) view.findViewById(R.id.snackbar_action);
267
268		messagesView = (ListView) view.findViewById(R.id.messages_view);
269		messagesView.setOnScrollListener(mOnScrollListener);
270		messagesView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
271		messageListAdapter = new MessageAdapter(
272				(ConversationActivity) getActivity(), this.messageList);
273		messageListAdapter
274				.setOnContactPictureClicked(new OnContactPictureClicked() {
275
276					@Override
277					public void onContactPictureClicked(Message message) {
278						if (message.getStatus() <= Message.STATUS_RECEIVED) {
279							if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
280								if (message.getPresence() != null) {
281									highlightInConference(message.getPresence());
282								} else {
283									highlightInConference(message
284											.getCounterpart());
285								}
286							} else {
287								Contact contact = message.getConversation()
288										.getContact();
289								if (contact.showInRoster()) {
290									activity.switchToContactDetails(contact);
291								} else {
292									activity.showAddToRosterDialog(message
293											.getConversation());
294								}
295							}
296						}
297					}
298				});
299		messageListAdapter
300				.setOnContactPictureLongClicked(new OnContactPictureLongClicked() {
301
302					@Override
303					public void onContactPictureLongClicked(Message message) {
304						if (message.getStatus() <= Message.STATUS_RECEIVED) {
305							if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
306								if (message.getPresence() != null) {
307									privateMessageWith(message.getPresence());
308								} else {
309									privateMessageWith(message.getCounterpart());
310								}
311							}
312						}
313					}
314				});
315		messagesView.setAdapter(messageListAdapter);
316
317		return view;
318	}
319
320	protected void privateMessageWith(String counterpart) {
321		this.mEditMessage.setText("");
322		this.conversation.setNextPresence(counterpart);
323		updateChatMsgHint();
324	}
325
326	protected void highlightInConference(String nick) {
327		String oldString = mEditMessage.getText().toString().trim();
328		if (oldString.isEmpty() || mEditMessage.getSelectionStart() == 0) {
329			mEditMessage.getText().insert(0, nick + ": ");
330		} else {
331			if (mEditMessage.getText().charAt(
332					mEditMessage.getSelectionStart() - 1) != ' ') {
333				nick = " " + nick;
334			}
335			mEditMessage.getText().insert(mEditMessage.getSelectionStart(),
336					nick + " ");
337		}
338	}
339
340	@Override
341	public void onStart() {
342		super.onStart();
343		this.activity = (ConversationActivity) getActivity();
344		if (activity.xmppConnectionServiceBound) {
345			this.onBackendConnected();
346		}
347	}
348
349	@Override
350	public void onStop() {
351		super.onStop();
352		if (this.conversation != null) {
353			this.conversation.setNextMessage(mEditMessage.getText().toString());
354		}
355	}
356
357	public void onBackendConnected() {
358		this.activity = (ConversationActivity) getActivity();
359		this.conversation = activity.getSelectedConversation();
360		if (this.conversation == null) {
361			return;
362		}
363		String oldString = conversation.getNextMessage().trim();
364		if (this.pastedText == null) {
365			this.mEditMessage.setText(oldString);
366		} else {
367
368			if (oldString.isEmpty()) {
369				mEditMessage.setText(pastedText);
370			} else {
371				mEditMessage.setText(oldString + " " + pastedText);
372			}
373			pastedText = null;
374		}
375		int position = mEditMessage.length();
376		Editable etext = mEditMessage.getText();
377		Selection.setSelection(etext, position);
378		if (activity.isConversationsOverviewHideable()) {
379			if (!activity.shouldPaneBeOpen()) {
380				activity.hideConversationsOverview();
381				activity.openConversation(conversation);
382			}
383		}
384		if (this.conversation.getMode() == Conversation.MODE_MULTI) {
385			conversation.setNextPresence(null);
386		}
387		updateMessages();
388	}
389
390	private void decryptMessage(Message message) {
391		PgpEngine engine = activity.xmppConnectionService.getPgpEngine();
392		if (engine != null) {
393			engine.decrypt(message, new UiCallback<Message>() {
394
395				@Override
396				public void userInputRequried(PendingIntent pi, Message message) {
397					askForPassphraseIntent = pi.getIntentSender();
398					showSnackbar(R.string.openpgp_messages_found,
399							R.string.decrypt, clickToDecryptListener);
400				}
401
402				@Override
403				public void success(Message message) {
404					activity.xmppConnectionService.databaseBackend
405							.updateMessage(message);
406					updateMessages();
407				}
408
409				@Override
410				public void error(int error, Message message) {
411					message.setEncryption(Message.ENCRYPTION_DECRYPTION_FAILED);
412					// updateMessages();
413				}
414			});
415		}
416	}
417
418	public void updateMessages() {
419		if (getView() == null) {
420			return;
421		}
422		hideSnackbar();
423		final ConversationActivity activity = (ConversationActivity) getActivity();
424		if (this.conversation != null) {
425			final Contact contact = this.conversation.getContact();
426			if (this.conversation.isMuted()) {
427				showSnackbar(R.string.notifications_disabled, R.string.enable,
428						new OnClickListener() {
429
430							@Override
431							public void onClick(View v) {
432								conversation.setMutedTill(0);
433								updateMessages();
434							}
435						});
436			} else if (!contact.showInRoster()
437					&& contact
438							.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
439				showSnackbar(R.string.contact_added_you, R.string.add_back,
440						new OnClickListener() {
441
442							@Override
443							public void onClick(View v) {
444								activity.xmppConnectionService
445										.createContact(contact);
446								activity.switchToContactDetails(contact);
447							}
448						});
449			}
450			for (Message message : this.conversation.getMessages()) {
451				if ((message.getEncryption() == Message.ENCRYPTION_PGP)
452						&& ((message.getStatus() == Message.STATUS_RECEIVED) || (message
453								.getStatus() == Message.STATUS_SEND))) {
454					decryptMessage(message);
455					break;
456				}
457			}
458			this.messageList.clear();
459			if (this.conversation.getMessages().size() == 0) {
460				messagesLoaded = false;
461			} else {
462				this.messageList.addAll(this.conversation.getMessages());
463				messagesLoaded = true;
464				updateStatusMessages();
465			}
466			this.messageListAdapter.notifyDataSetChanged();
467			if (conversation.getMode() == Conversation.MODE_SINGLE) {
468				if (messageList.size() >= 1) {
469					makeFingerprintWarning(conversation.getLatestEncryption());
470				}
471			} else {
472				if (!conversation.getMucOptions().online()
473						&& conversation.getAccount().getStatus() == Account.STATUS_ONLINE) {
474					int error = conversation.getMucOptions().getError();
475					switch (error) {
476					case MucOptions.ERROR_NICK_IN_USE:
477						showSnackbar(R.string.nick_in_use, R.string.edit,
478								clickToMuc);
479						break;
480					case MucOptions.ERROR_ROOM_NOT_FOUND:
481						showSnackbar(R.string.conference_not_found,
482								R.string.leave, leaveMuc);
483						break;
484					case MucOptions.ERROR_PASSWORD_REQUIRED:
485						showSnackbar(R.string.conference_requires_password,
486								R.string.enter_password, enterPassword);
487						break;
488					default:
489						break;
490					}
491				}
492			}
493			getActivity().invalidateOptionsMenu();
494			updateChatMsgHint();
495			if (!activity.shouldPaneBeOpen()) {
496				activity.xmppConnectionService.markRead(conversation,true);
497				activity.updateConversationList();
498			}
499			this.updateSendButton();
500		}
501	}
502
503	private void messageSent() {
504		int size = this.messageList.size();
505		if (size >= 1 && this.messagesView.getLastVisiblePosition() != size - 1) {
506			messagesView.setSelection(size - 1);
507		}
508		mEditMessage.setText("");
509		updateChatMsgHint();
510	}
511
512	public void updateSendButton() {
513		Conversation c = this.conversation;
514		if (activity.useSendButtonToIndicateStatus() && c != null
515				&& c.getAccount().getStatus() == Account.STATUS_ONLINE) {
516			if (c.getMode() == Conversation.MODE_SINGLE) {
517				switch (c.getContact().getMostAvailableStatus()) {
518				case Presences.CHAT:
519					this.mSendButton
520							.setImageResource(R.drawable.ic_action_send_now_online);
521					break;
522				case Presences.ONLINE:
523					this.mSendButton
524							.setImageResource(R.drawable.ic_action_send_now_online);
525					break;
526				case Presences.AWAY:
527					this.mSendButton
528							.setImageResource(R.drawable.ic_action_send_now_away);
529					break;
530				case Presences.XA:
531					this.mSendButton
532							.setImageResource(R.drawable.ic_action_send_now_away);
533					break;
534				case Presences.DND:
535					this.mSendButton
536							.setImageResource(R.drawable.ic_action_send_now_dnd);
537					break;
538				default:
539					this.mSendButton
540							.setImageResource(R.drawable.ic_action_send_now_offline);
541					break;
542				}
543			} else if (c.getMode() == Conversation.MODE_MULTI) {
544				if (c.getMucOptions().online()) {
545					this.mSendButton
546							.setImageResource(R.drawable.ic_action_send_now_online);
547				} else {
548					this.mSendButton
549							.setImageResource(R.drawable.ic_action_send_now_offline);
550				}
551			} else {
552				this.mSendButton
553						.setImageResource(R.drawable.ic_action_send_now_offline);
554			}
555		} else {
556			this.mSendButton
557					.setImageResource(R.drawable.ic_action_send_now_offline);
558		}
559	}
560
561	protected void updateStatusMessages() {
562		if (conversation.getMode() == Conversation.MODE_SINGLE) {
563			for (int i = this.messageList.size() - 1; i >= 0; --i) {
564				if (this.messageList.get(i).getStatus() == Message.STATUS_RECEIVED) {
565					return;
566				} else {
567					if (this.messageList.get(i).getStatus() == Message.STATUS_SEND_DISPLAYED) {
568						this.messageList.add(i + 1,
569								Message.createStatusMessage(conversation));
570						return;
571					}
572				}
573			}
574		}
575	}
576
577	protected void makeFingerprintWarning(int latestEncryption) {
578		Set<String> knownFingerprints = conversation.getContact()
579				.getOtrFingerprints();
580		if ((latestEncryption == Message.ENCRYPTION_OTR)
581				&& (conversation.hasValidOtrSession()
582						&& (!conversation.isMuted())
583						&& (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) && (!knownFingerprints
584							.contains(conversation.getOtrFingerprint())))) {
585			showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify,
586					new OnClickListener() {
587
588						@Override
589						public void onClick(View v) {
590							if (conversation.getOtrFingerprint() != null) {
591								AlertDialog dialog = UIHelper
592										.getVerifyFingerprintDialog(
593												(ConversationActivity) getActivity(),
594												conversation, snackbar);
595								dialog.show();
596							}
597						}
598					});
599		}
600	}
601
602	protected void showSnackbar(int message, int action,
603			OnClickListener clickListener) {
604		snackbar.setVisibility(View.VISIBLE);
605		snackbar.setOnClickListener(null);
606		snackbarMessage.setText(message);
607		snackbarMessage.setOnClickListener(null);
608		snackbarAction.setText(action);
609		snackbarAction.setOnClickListener(clickListener);
610	}
611
612	protected void hideSnackbar() {
613		snackbar.setVisibility(View.GONE);
614	}
615
616	protected void sendPlainTextMessage(Message message) {
617		ConversationActivity activity = (ConversationActivity) getActivity();
618		activity.xmppConnectionService.sendMessage(message);
619		messageSent();
620	}
621
622	protected void sendPgpMessage(final Message message) {
623		final ConversationActivity activity = (ConversationActivity) getActivity();
624		final XmppConnectionService xmppService = activity.xmppConnectionService;
625		final Contact contact = message.getConversation().getContact();
626		if (activity.hasPgp()) {
627			if (conversation.getMode() == Conversation.MODE_SINGLE) {
628				if (contact.getPgpKeyId() != 0) {
629					xmppService.getPgpEngine().hasKey(contact,
630							new UiCallback<Contact>() {
631
632								@Override
633								public void userInputRequried(PendingIntent pi,
634										Contact contact) {
635									activity.runIntent(
636											pi,
637											ConversationActivity.REQUEST_ENCRYPT_MESSAGE);
638								}
639
640								@Override
641								public void success(Contact contact) {
642									messageSent();
643									activity.encryptTextMessage(message);
644								}
645
646								@Override
647								public void error(int error, Contact contact) {
648
649								}
650							});
651
652				} else {
653					showNoPGPKeyDialog(false,
654							new DialogInterface.OnClickListener() {
655
656								@Override
657								public void onClick(DialogInterface dialog,
658										int which) {
659									conversation
660											.setNextEncryption(Message.ENCRYPTION_NONE);
661									xmppService.databaseBackend
662											.updateConversation(conversation);
663									message.setEncryption(Message.ENCRYPTION_NONE);
664									xmppService.sendMessage(message);
665									messageSent();
666								}
667							});
668				}
669			} else {
670				if (conversation.getMucOptions().pgpKeysInUse()) {
671					if (!conversation.getMucOptions().everybodyHasKeys()) {
672						Toast warning = Toast
673								.makeText(getActivity(),
674										R.string.missing_public_keys,
675										Toast.LENGTH_LONG);
676						warning.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
677						warning.show();
678					}
679					activity.encryptTextMessage(message);
680					messageSent();
681				} else {
682					showNoPGPKeyDialog(true,
683							new DialogInterface.OnClickListener() {
684
685								@Override
686								public void onClick(DialogInterface dialog,
687										int which) {
688									conversation
689											.setNextEncryption(Message.ENCRYPTION_NONE);
690									message.setEncryption(Message.ENCRYPTION_NONE);
691									xmppService.databaseBackend
692											.updateConversation(conversation);
693									xmppService.sendMessage(message);
694									messageSent();
695								}
696							});
697				}
698			}
699		} else {
700			activity.showInstallPgpDialog();
701		}
702	}
703
704	public void showNoPGPKeyDialog(boolean plural,
705			DialogInterface.OnClickListener listener) {
706		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
707		builder.setIconAttribute(android.R.attr.alertDialogIcon);
708		if (plural) {
709			builder.setTitle(getString(R.string.no_pgp_keys));
710			builder.setMessage(getText(R.string.contacts_have_no_pgp_keys));
711		} else {
712			builder.setTitle(getString(R.string.no_pgp_key));
713			builder.setMessage(getText(R.string.contact_has_no_pgp_key));
714		}
715		builder.setNegativeButton(getString(R.string.cancel), null);
716		builder.setPositiveButton(getString(R.string.send_unencrypted),
717				listener);
718		builder.create().show();
719	}
720
721	protected void sendOtrMessage(final Message message) {
722		final ConversationActivity activity = (ConversationActivity) getActivity();
723		final XmppConnectionService xmppService = activity.xmppConnectionService;
724		if (conversation.hasValidOtrSession()) {
725			activity.xmppConnectionService.sendMessage(message);
726			messageSent();
727		} else {
728			activity.selectPresence(message.getConversation(),
729					new OnPresenceSelected() {
730
731						@Override
732						public void onPresenceSelected() {
733							message.setPresence(conversation.getNextPresence());
734							xmppService.sendMessage(message);
735							messageSent();
736						}
737					});
738		}
739	}
740
741	public void setText(String text) {
742		this.pastedText = text;
743	}
744
745	public void clearInputField() {
746		this.mEditMessage.setText("");
747	}
748}