aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/eu/siacs/conversations/ui/ConversationFragment.java')
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConversationFragment.java336
1 files changed, 205 insertions, 131 deletions
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
index 0edc6b6f..93a4cc7e 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
@@ -103,7 +103,9 @@ public class ConversationFragment extends Fragment {
private RelativeLayout snackbar;
private TextView snackbarMessage;
private TextView snackbarAction;
- private boolean messagesLoaded = false;
+ private boolean messagesLoaded = true;
+ private Toast messageLoaderToast;
+
private OnScrollListener mOnScrollListener = new OnScrollListener() {
@Override
@@ -114,20 +116,69 @@ public class ConversationFragment extends Fragment {
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
- int visibleItemCount, int totalItemCount) {
+ int visibleItemCount, int totalItemCount) {
synchronized (ConversationFragment.this.messageList) {
- if (firstVisibleItem == 0 && messagesLoaded) {
+ if (firstVisibleItem < 5 && messagesLoaded && messageList.size() > 0) {
long timestamp = ConversationFragment.this.messageList.get(0).getTimeSent();
messagesLoaded = false;
- int size = activity.xmppConnectionService.loadMoreMessages(conversation, timestamp);
- ConversationFragment.this.messageList.clear();
- ConversationFragment.this.messageList.addAll(conversation.getMessages());
- updateStatusMessages();
- messageListAdapter.notifyDataSetChanged();
- if (size != 0) {
- messagesLoaded = true;
- }
- messagesView.setSelectionFromTop(size + 1, 0);
+ activity.xmppConnectionService.loadMoreMessages(conversation, timestamp, new XmppConnectionService.OnMoreMessagesLoaded() {
+ @Override
+ public void onMoreMessagesLoaded(final int count, Conversation conversation) {
+ if (ConversationFragment.this.conversation != conversation) {
+ return;
+ }
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ final int oldPosition = messagesView.getFirstVisiblePosition();
+ View v = messagesView.getChildAt(0);
+ final int pxOffset = (v == null) ? 0 : v.getTop();
+ ConversationFragment.this.conversation.populateWithMessages(ConversationFragment.this.messageList);
+ updateStatusMessages();
+ messageListAdapter.notifyDataSetChanged();
+ if (count != 0) {
+ final int newPosition = oldPosition + count;
+ int offset = 0;
+ try {
+ Message tmpMessage = messageList.get(newPosition);
+
+ while(tmpMessage.wasMergedIntoPrevious()) {
+ offset++;
+ tmpMessage = tmpMessage.prev();
+ }
+ } catch (final IndexOutOfBoundsException ignored) {
+
+ }
+ messagesView.setSelectionFromTop(newPosition - offset, pxOffset);
+ messagesLoaded = true;
+ if (messageLoaderToast != null) {
+ messageLoaderToast.cancel();
+ }
+ }
+ }
+ });
+ }
+
+ @Override
+ public void informUser(final int resId) {
+
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (messageLoaderToast != null) {
+ messageLoaderToast.cancel();
+ }
+ if (ConversationFragment.this.conversation != conversation) {
+ return;
+ }
+ messageLoaderToast = Toast.makeText(activity,resId,Toast.LENGTH_LONG);
+ messageLoaderToast.show();
+ }
+ });
+
+ }
+ });
+
}
}
}
@@ -153,13 +204,7 @@ public class ConversationFragment extends Fragment {
@Override
public void onClick(View v) {
- if (conversation.getOtrFingerprint() != null) {
- Intent intent = new Intent(getActivity(), VerifyOTRActivity.class);
- intent.setAction(VerifyOTRActivity.ACTION_VERIFY_CONTACT);
- intent.putExtra("contact", conversation.getContact().getJid().toBareJid().toString());
- intent.putExtra("account", conversation.getAccount().getJid().toBareJid().toString());
- startActivity(intent);
- }
+ activity.verifyOtrSessionDialog(conversation,v);
}
};
private ConcurrentLinkedQueue<Message> mEncryptedMessages = new ConcurrentLinkedQueue<>();
@@ -170,7 +215,7 @@ public class ConversationFragment extends Fragment {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEND) {
InputMethodManager imm = (InputMethodManager) v.getContext()
- .getSystemService(Context.INPUT_METHOD_SERVICE);
+ .getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
sendMessage();
return true;
@@ -213,7 +258,7 @@ public class ConversationFragment extends Fragment {
}
Message message = new Message(conversation, mEditMessage.getText()
.toString(), conversation.getNextEncryption(activity
- .forceEncryption()));
+ .forceEncryption()));
if (conversation.getMode() == Conversation.MODE_MULTI) {
if (conversation.getNextCounterpart() != null) {
message.setCounterpart(conversation.getNextCounterpart());
@@ -234,13 +279,13 @@ public class ConversationFragment extends Fragment {
if (conversation.getMode() == Conversation.MODE_MULTI
&& conversation.getNextCounterpart() != null) {
this.mEditMessage.setHint(getString(
- R.string.send_private_message_to,
- conversation.getNextCounterpart().getResourcepart()));
+ R.string.send_private_message_to,
+ conversation.getNextCounterpart().getResourcepart()));
} else {
switch (conversation.getNextEncryption(activity.forceEncryption())) {
case Message.ENCRYPTION_NONE:
mEditMessage
- .setHint(getString(R.string.send_plain_text_message));
+ .setHint(getString(R.string.send_plain_text_message));
break;
case Message.ENCRYPTION_OTR:
mEditMessage.setHint(getString(R.string.send_otr_message));
@@ -256,7 +301,7 @@ public class ConversationFragment extends Fragment {
@Override
public View onCreateView(final LayoutInflater inflater,
- ViewGroup container, Bundle savedInstanceState) {
+ ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_conversation,
container, false);
mEditMessage = (EditMessage) view.findViewById(R.id.textinput);
@@ -289,49 +334,51 @@ public class ConversationFragment extends Fragment {
messageListAdapter = new MessageAdapter((ConversationActivity) getActivity(), this.messageList);
messageListAdapter.setOnContactPictureClicked(new OnContactPictureClicked() {
- @Override
- public void onContactPictureClicked(Message message) {
- if (message.getStatus() <= Message.STATUS_RECEIVED) {
- if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
- if (message.getCounterpart() != null) {
- if (!message.getCounterpart().isBareJid()) {
- highlightInConference(message.getCounterpart().getResourcepart());
- } else {
- highlightInConference(message.getCounterpart().toString());
- }
- }
+ @Override
+ public void onContactPictureClicked(Message message) {
+ if (message.getStatus() <= Message.STATUS_RECEIVED) {
+ if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
+ if (message.getCounterpart() != null) {
+ if (!message.getCounterpart().isBareJid()) {
+ highlightInConference(message.getCounterpart().getResourcepart());
} else {
- Contact contact = message.getConversation()
- .getContact();
- if (contact.showInRoster()) {
- activity.switchToContactDetails(contact);
- } else {
- activity.showAddToRosterDialog(message
- .getConversation());
- }
+ highlightInConference(message.getCounterpart().toString());
}
+ }
+ } else {
+ Contact contact = message.getConversation()
+ .getContact();
+ if (contact.showInRoster()) {
+ activity.switchToContactDetails(contact);
} else {
- Account account = message.getConversation().getAccount();
- Intent intent = new Intent(activity, EditAccountActivity.class);
- intent.putExtra("jid", account.getJid().toBareJid().toString());
- startActivity(intent);
+ activity.showAddToRosterDialog(message
+ .getConversation());
}
}
- });
+ } else {
+ Account account = message.getConversation().getAccount();
+ Intent intent = new Intent(activity, EditAccountActivity.class);
+ intent.putExtra("jid", account.getJid().toBareJid().toString());
+ startActivity(intent);
+ }
+ }
+ });
messageListAdapter
- .setOnContactPictureLongClicked(new OnContactPictureLongClicked() {
+ .setOnContactPictureLongClicked(new OnContactPictureLongClicked() {
- @Override
- public void onContactPictureLongClicked(Message message) {
- if (message.getStatus() <= Message.STATUS_RECEIVED) {
- if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
- if (message.getCounterpart() != null) {
- privateMessageWith(message.getCounterpart());
- }
+ @Override
+ public void onContactPictureLongClicked(Message message) {
+ if (message.getStatus() <= Message.STATUS_RECEIVED) {
+ if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
+ if (message.getCounterpart() != null) {
+ privateMessageWith(message.getCounterpart());
}
}
+ } else {
+ activity.showQrCode();
}
- });
+ }
+ });
messagesView.setAdapter(messageListAdapter);
registerForContextMenu(messagesView);
@@ -341,7 +388,7 @@ public class ConversationFragment extends Fragment {
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
- ContextMenuInfo menuInfo) {
+ ContextMenuInfo menuInfo) {
synchronized (this.messageList) {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
@@ -351,7 +398,8 @@ public class ConversationFragment extends Fragment {
}
private void populateContextMenu(ContextMenu menu) {
- if (this.selectedMessage.getType() != Message.TYPE_STATUS) {
+ final Message m = this.selectedMessage;
+ if (m.getType() != Message.TYPE_STATUS) {
activity.getMenuInflater().inflate(R.menu.message_context, menu);
menu.setHeaderTitle(R.string.message_options);
MenuItem copyText = menu.findItem(R.id.copy_text);
@@ -360,29 +408,26 @@ public class ConversationFragment extends Fragment {
MenuItem copyUrl = menu.findItem(R.id.copy_url);
MenuItem downloadImage = menu.findItem(R.id.download_image);
MenuItem cancelTransmission = menu.findItem(R.id.cancel_transmission);
- if (this.selectedMessage.getType() != Message.TYPE_TEXT
- || this.selectedMessage.getDownloadable() != null) {
+ if (m.getType() != Message.TYPE_TEXT || m.getDownloadable() != null) {
copyText.setVisible(false);
}
- if (this.selectedMessage.getType() != Message.TYPE_IMAGE
- || this.selectedMessage.getDownloadable() != null) {
+ if (m.getType() != Message.TYPE_IMAGE || m.getDownloadable() != null) {
shareImage.setVisible(false);
}
- if (this.selectedMessage.getStatus() != Message.STATUS_SEND_FAILED) {
+ if (m.getStatus() != Message.STATUS_SEND_FAILED) {
sendAgain.setVisible(false);
}
- if ((this.selectedMessage.getType() != Message.TYPE_IMAGE && this.selectedMessage
- .getDownloadable() == null)
- || this.selectedMessage.getImageParams().url == null) {
+ if ((m.getType() != Message.TYPE_IMAGE && m.getDownloadable() == null)
+ || m.getImageParams().url == null) {
copyUrl.setVisible(false);
}
- if (this.selectedMessage.getType() != Message.TYPE_TEXT
- || this.selectedMessage.getDownloadable() != null
- || !this.selectedMessage.bodyContainsDownloadable()) {
+ if (m.getType() != Message.TYPE_TEXT
+ || m.getDownloadable() != null
+ || !m.bodyContainsDownloadable()) {
downloadImage.setVisible(false);
}
- if (this.selectedMessage.getDownloadable() == null
- || this.selectedMessage.getDownloadable() instanceof DownloadablePlaceholder) {
+ if (!((m.getDownloadable() != null && !(m.getDownloadable() instanceof DownloadablePlaceholder))
+ || (m.isFileOrImage() && m.getStatus() == Message.STATUS_WAITING))) {
cancelTransmission.setVisible(false);
}
}
@@ -419,16 +464,16 @@ public class ConversationFragment extends Fragment {
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM,
activity.xmppConnectionService.getFileBackend()
- .getJingleFileUri(message));
+ .getJingleFileUri(message));
shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.setType("image/webp");
activity.startActivity(Intent.createChooser(shareIntent,
- getText(R.string.share_with)));
+ getText(R.string.share_with)));
}
private void copyText(Message message) {
if (activity.copyTextToClipboard(message.getMergedBody(),
- R.string.message_text)) {
+ R.string.message_text)) {
Toast.makeText(activity, R.string.message_copied_to_clipboard,
Toast.LENGTH_SHORT).show();
}
@@ -448,21 +493,23 @@ public class ConversationFragment extends Fragment {
private void copyUrl(Message message) {
if (activity.copyTextToClipboard(
- message.getImageParams().url.toString(), R.string.image_url)) {
+ message.getImageParams().url.toString(), R.string.image_url)) {
Toast.makeText(activity, R.string.url_copied_to_clipboard,
Toast.LENGTH_SHORT).show();
- }
+ }
}
private void downloadImage(Message message) {
activity.xmppConnectionService.getHttpConnectionManager()
- .createNewConnection(message);
+ .createNewConnection(message);
}
private void cancelTransmission(Message message) {
Downloadable downloadable = message.getDownloadable();
if (downloadable!=null) {
downloadable.cancel();
+ } else {
+ activity.xmppConnectionService.markMessage(message,Message.STATUS_SEND_FAILED);
}
}
@@ -478,9 +525,9 @@ public class ConversationFragment extends Fragment {
mEditMessage.getText().insert(0, nick + ": ");
} else {
if (mEditMessage.getText().charAt(
- mEditMessage.getSelectionStart() - 1) != ' ') {
+ mEditMessage.getSelectionStart() - 1) != ' ') {
nick = " " + nick;
- }
+ }
mEditMessage.getText().insert(mEditMessage.getSelectionStart(),
nick + " ");
}
@@ -501,6 +548,7 @@ public class ConversationFragment extends Fragment {
}
if (this.conversation != null) {
this.conversation.setNextMessage(mEditMessage.getText().toString());
+ this.conversation.trim();
}
this.activity = (ConversationActivity) getActivity();
this.conversation = conversation;
@@ -511,8 +559,13 @@ public class ConversationFragment extends Fragment {
}
this.mEditMessage.setText("");
this.mEditMessage.append(this.conversation.getNextMessage());
- this.messagesView.invalidate();
+ this.messagesView.invalidateViews();
updateMessages();
+ this.messagesLoaded = true;
+ int size = this.messageList.size();
+ if (size > 0) {
+ messagesView.setSelection(size - 1);
+ }
}
public void updateMessages() {
@@ -524,12 +577,30 @@ public class ConversationFragment extends Fragment {
final ConversationActivity activity = (ConversationActivity) getActivity();
if (this.conversation != null) {
final Contact contact = this.conversation.getContact();
- if (this.conversation.isMuted()) {
+ if (this.conversation.isBlocked()) {
+ showSnackbar(R.string.contact_blocked, R.string.unblock,
+ new OnClickListener() {
+ @Override
+ public void onClick(final View v) {
+ v.post(new Runnable() {
+ @Override
+ public void run() {
+ v.setVisibility(View.INVISIBLE);
+ }
+ });
+ if (conversation.isDomainBlocked()) {
+ BlockContactDialog.show(getActivity(), ((ConversationActivity) getActivity()).xmppConnectionService, conversation);
+ } else {
+ ((ConversationActivity) getActivity()).unblockConversation(conversation);
+ }
+ }
+ });
+ } else if (this.conversation.isMuted()) {
showSnackbar(R.string.notifications_disabled, R.string.enable,
new OnClickListener() {
@Override
- public void onClick(View v) {
+ public void onClick(final View v) {
activity.unmuteConversation(conversation);
}
});
@@ -542,7 +613,7 @@ public class ConversationFragment extends Fragment {
@Override
public void onClick(View v) {
activity.xmppConnectionService
- .createContact(contact);
+ .createContact(contact);
activity.switchToContactDetails(contact);
}
});
@@ -579,31 +650,24 @@ public class ConversationFragment extends Fragment {
default:
break;
}
- }
- this.messageList.clear();
- if (this.conversation.getMessages().size() == 0) {
- messagesLoaded = false;
- } else {
- this.messageList.addAll(this.conversation.getMessages());
- messagesLoaded = true;
- for (Message message : this.messageList) {
- if (message.getEncryption() == Message.ENCRYPTION_PGP
- && (message.getStatus() == Message.STATUS_RECEIVED || message
+ }
+ conversation.populateWithMessages(ConversationFragment.this.messageList);
+ for (Message message : this.messageList) {
+ if (message.getEncryption() == Message.ENCRYPTION_PGP
+ && (message.getStatus() == Message.STATUS_RECEIVED || message
.getStatus() >= Message.STATUS_SEND)
- && message.getDownloadable() == null) {
- if (!mEncryptedMessages.contains(message)) {
- mEncryptedMessages.add(message);
- }
+ && message.getDownloadable() == null) {
+ if (!mEncryptedMessages.contains(message)) {
+ mEncryptedMessages.add(message);
}
- }
- decryptNext();
- updateStatusMessages();
+ }
}
+ decryptNext();
+ updateStatusMessages();
this.messageListAdapter.notifyDataSetChanged();
updateChatMsgHint();
if (!activity.isConversationsOverviewVisable() || !activity.isConversationsOverviewHideable()) {
- activity.xmppConnectionService.markRead(conversation, true);
- activity.updateConversationList();
+ activity.sendReadMarkerIfNecessary(conversation);
}
this.updateSendButton();
}
@@ -667,44 +731,44 @@ public class ConversationFragment extends Fragment {
switch (c.getContact().getMostAvailableStatus()) {
case Presences.CHAT:
this.mSendButton
- .setImageResource(R.drawable.ic_action_send_now_online);
+ .setImageResource(R.drawable.ic_action_send_now_online);
break;
case Presences.ONLINE:
this.mSendButton
- .setImageResource(R.drawable.ic_action_send_now_online);
+ .setImageResource(R.drawable.ic_action_send_now_online);
break;
case Presences.AWAY:
this.mSendButton
- .setImageResource(R.drawable.ic_action_send_now_away);
+ .setImageResource(R.drawable.ic_action_send_now_away);
break;
case Presences.XA:
this.mSendButton
- .setImageResource(R.drawable.ic_action_send_now_away);
+ .setImageResource(R.drawable.ic_action_send_now_away);
break;
case Presences.DND:
this.mSendButton
- .setImageResource(R.drawable.ic_action_send_now_dnd);
+ .setImageResource(R.drawable.ic_action_send_now_dnd);
break;
default:
this.mSendButton
- .setImageResource(R.drawable.ic_action_send_now_offline);
+ .setImageResource(R.drawable.ic_action_send_now_offline);
break;
}
} else if (c.getMode() == Conversation.MODE_MULTI) {
if (c.getMucOptions().online()) {
this.mSendButton
- .setImageResource(R.drawable.ic_action_send_now_online);
+ .setImageResource(R.drawable.ic_action_send_now_online);
} else {
this.mSendButton
- .setImageResource(R.drawable.ic_action_send_now_offline);
+ .setImageResource(R.drawable.ic_action_send_now_offline);
}
} else {
this.mSendButton
- .setImageResource(R.drawable.ic_action_send_now_offline);
+ .setImageResource(R.drawable.ic_action_send_now_offline);
}
} else {
this.mSendButton
- .setImageResource(R.drawable.ic_action_send_now_offline);
+ .setImageResource(R.drawable.ic_action_send_now_offline);
}
}
@@ -716,8 +780,7 @@ public class ConversationFragment extends Fragment {
return;
} else {
if (this.messageList.get(i).getStatus() == Message.STATUS_SEND_DISPLAYED) {
- this.messageList.add(i + 1,
- Message.createStatusMessage(conversation));
+ this.messageList.add(i + 1,Message.createStatusMessage(conversation));
return;
}
}
@@ -728,19 +791,30 @@ public class ConversationFragment extends Fragment {
protected void makeFingerprintWarning() {
if (conversation.smpRequested()) {
- showSnackbar(R.string.smp_requested, R.string.verify, clickToVerify);
+ showSnackbar(R.string.smp_requested, R.string.verify, new OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Intent intent = new Intent(activity, VerifyOTRActivity.class);
+ intent.setAction(VerifyOTRActivity.ACTION_VERIFY_CONTACT);
+ intent.putExtra("contact", conversation.getContact().getJid().toBareJid().toString());
+ intent.putExtra("account", conversation.getAccount().getJid().toBareJid().toString());
+ intent.putExtra("mode",VerifyOTRActivity.MODE_ANSWER_QUESTION);
+ startActivity(intent);
+ }
+ });
} else if (conversation.hasValidOtrSession() && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED)
&& (!conversation.isOtrFingerprintVerified())) {
showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify, clickToVerify);
- }
+ }
}
- protected void showSnackbar(int message, int action,
- OnClickListener clickListener) {
+ protected void showSnackbar(final int message, final int action,
+ final OnClickListener clickListener) {
snackbar.setVisibility(View.VISIBLE);
snackbar.setOnClickListener(null);
snackbarMessage.setText(message);
snackbarMessage.setOnClickListener(null);
+ snackbarAction.setVisibility(View.VISIBLE);
snackbarAction.setText(action);
snackbarAction.setOnClickListener(clickListener);
}
@@ -767,7 +841,7 @@ public class ConversationFragment extends Fragment {
@Override
public void userInputRequried(PendingIntent pi,
- Contact contact) {
+ Contact contact) {
activity.runIntent(
pi,
ConversationActivity.REQUEST_ENCRYPT_MESSAGE);
@@ -791,11 +865,11 @@ public class ConversationFragment extends Fragment {
@Override
public void onClick(DialogInterface dialog,
- int which) {
+ int which) {
conversation
- .setNextEncryption(Message.ENCRYPTION_NONE);
+ .setNextEncryption(Message.ENCRYPTION_NONE);
xmppService.databaseBackend
- .updateConversation(conversation);
+ .updateConversation(conversation);
message.setEncryption(Message.ENCRYPTION_NONE);
xmppService.sendMessage(message);
messageSent();
@@ -806,9 +880,9 @@ public class ConversationFragment extends Fragment {
if (conversation.getMucOptions().pgpKeysInUse()) {
if (!conversation.getMucOptions().everybodyHasKeys()) {
Toast warning = Toast
- .makeText(getActivity(),
- R.string.missing_public_keys,
- Toast.LENGTH_LONG);
+ .makeText(getActivity(),
+ R.string.missing_public_keys,
+ Toast.LENGTH_LONG);
warning.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
warning.show();
}
@@ -820,12 +894,12 @@ public class ConversationFragment extends Fragment {
@Override
public void onClick(DialogInterface dialog,
- int which) {
+ int which) {
conversation
- .setNextEncryption(Message.ENCRYPTION_NONE);
+ .setNextEncryption(Message.ENCRYPTION_NONE);
message.setEncryption(Message.ENCRYPTION_NONE);
xmppService.databaseBackend
- .updateConversation(conversation);
+ .updateConversation(conversation);
xmppService.sendMessage(message);
messageSent();
}
@@ -838,7 +912,7 @@ public class ConversationFragment extends Fragment {
}
public void showNoPGPKeyDialog(boolean plural,
- DialogInterface.OnClickListener listener) {
+ DialogInterface.OnClickListener listener) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setIconAttribute(android.R.attr.alertDialogIcon);
if (plural) {