1package eu.siacs.conversations.ui;
2
3import java.util.ArrayList;
4import java.util.HashMap;
5import java.util.List;
6import java.util.Set;
7
8import net.java.otr4j.session.SessionStatus;
9import eu.siacs.conversations.R;
10import eu.siacs.conversations.crypto.PgpEngine;
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.MucOptions.OnRenameListener;
16import eu.siacs.conversations.services.ImageProvider;
17import eu.siacs.conversations.services.XmppConnectionService;
18import eu.siacs.conversations.utils.UIHelper;
19import eu.siacs.conversations.xmpp.jingle.JingleConnection;
20import android.app.AlertDialog;
21import android.app.Fragment;
22import android.app.PendingIntent;
23import android.content.Context;
24import android.content.DialogInterface;
25import android.content.Intent;
26import android.content.IntentSender;
27import android.content.SharedPreferences;
28import android.content.IntentSender.SendIntentException;
29import android.graphics.Bitmap;
30import android.graphics.Typeface;
31import android.os.Bundle;
32import android.preference.PreferenceManager;
33import android.text.Editable;
34import android.text.Selection;
35import android.util.DisplayMetrics;
36import android.util.Log;
37import android.view.LayoutInflater;
38import android.view.View;
39import android.view.View.OnClickListener;
40import android.view.ViewGroup;
41import android.widget.ArrayAdapter;
42import android.widget.Button;
43import android.widget.EditText;
44import android.widget.LinearLayout;
45import android.widget.ListView;
46import android.widget.ImageButton;
47import android.widget.ImageView;
48import android.widget.TextView;
49import android.widget.Toast;
50
51public class ConversationFragment extends Fragment {
52
53 protected Conversation conversation;
54 protected ListView messagesView;
55 protected LayoutInflater inflater;
56 protected List<Message> messageList = new ArrayList<Message>();
57 protected ArrayAdapter<Message> messageListAdapter;
58 protected Contact contact;
59 protected BitmapCache mBitmapCache = new BitmapCache();
60
61 protected String queuedPqpMessage = null;
62
63 private EditText chatMsg;
64 private String pastedText = null;
65
66 protected Bitmap selfBitmap;
67
68 private boolean useSubject = true;
69
70 private IntentSender askForPassphraseIntent = null;
71
72 private OnClickListener sendMsgListener = new OnClickListener() {
73
74 @Override
75 public void onClick(View v) {
76 if (chatMsg.getText().length() < 1)
77 return;
78 Message message = new Message(conversation, chatMsg.getText()
79 .toString(), conversation.getNextEncryption());
80 if (conversation.getNextEncryption() == Message.ENCRYPTION_OTR) {
81 sendOtrMessage(message);
82 } else if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) {
83 sendPgpMessage(message);
84 } else {
85 sendPlainTextMessage(message);
86 }
87 }
88 };
89 protected OnClickListener clickToDecryptListener = new OnClickListener() {
90
91 @Override
92 public void onClick(View v) {
93 if (askForPassphraseIntent != null) {
94 try {
95 getActivity().startIntentSenderForResult(
96 askForPassphraseIntent,
97 ConversationActivity.REQUEST_DECRYPT_PGP, null, 0,
98 0, 0);
99 } catch (SendIntentException e) {
100 Log.d("xmppService", "couldnt fire intent");
101 }
102 }
103 }
104 };
105
106 private LinearLayout pgpInfo;
107 private LinearLayout mucError;
108 private TextView mucErrorText;
109 private OnClickListener clickToMuc = new OnClickListener() {
110
111 @Override
112 public void onClick(View v) {
113 Intent intent = new Intent(getActivity(), MucDetailsActivity.class);
114 intent.setAction(MucDetailsActivity.ACTION_VIEW_MUC);
115 intent.putExtra("uuid", conversation.getUuid());
116 startActivity(intent);
117 }
118 };
119 private ConversationActivity activity;
120
121 public void hidePgpPassphraseBox() {
122 pgpInfo.setVisibility(View.GONE);
123 }
124
125 public void updateChatMsgHint() {
126 if (conversation.getMode() == Conversation.MODE_MULTI) {
127 chatMsg.setHint(getString(R.string.send_message_to_conference));
128 } else {
129 switch (conversation.getNextEncryption()) {
130 case Message.ENCRYPTION_NONE:
131 chatMsg.setHint(getString(R.string.send_plain_text_message));
132 break;
133 case Message.ENCRYPTION_OTR:
134 chatMsg.setHint(getString(R.string.send_otr_message));
135 break;
136 case Message.ENCRYPTION_PGP:
137 chatMsg.setHint(getString(R.string.send_pgp_message));
138 break;
139 default:
140 break;
141 }
142 }
143 }
144
145 @Override
146 public View onCreateView(final LayoutInflater inflater,
147 ViewGroup container, Bundle savedInstanceState) {
148
149 final DisplayMetrics metrics = getResources().getDisplayMetrics();
150
151 this.inflater = inflater;
152
153 final View view = inflater.inflate(R.layout.fragment_conversation,
154 container, false);
155 chatMsg = (EditText) view.findViewById(R.id.textinput);
156
157 ImageButton sendButton = (ImageButton) view
158 .findViewById(R.id.textSendButton);
159 sendButton.setOnClickListener(this.sendMsgListener);
160
161 pgpInfo = (LinearLayout) view.findViewById(R.id.pgp_keyentry);
162 pgpInfo.setOnClickListener(clickToDecryptListener);
163 mucError = (LinearLayout) view.findViewById(R.id.muc_error);
164 mucError.setOnClickListener(clickToMuc);
165 mucErrorText = (TextView) view.findViewById(R.id.muc_error_msg);
166
167 messagesView = (ListView) view.findViewById(R.id.messages_view);
168
169 messageListAdapter = new ArrayAdapter<Message>(this.getActivity()
170 .getApplicationContext(), R.layout.message_sent,
171 this.messageList) {
172
173 private static final int SENT = 0;
174 private static final int RECIEVED = 1;
175
176 @Override
177 public int getViewTypeCount() {
178 return 2;
179 }
180
181 @Override
182 public int getItemViewType(int position) {
183 if (getItem(position).getStatus() <= Message.STATUS_RECIEVED) {
184 return RECIEVED;
185 } else {
186 return SENT;
187 }
188 }
189
190 private void displayStatus(ViewHolder viewHolder, Message message) {
191 String filesize = null;
192 String info = null;
193 boolean error = false;
194 if (message.getType() == Message.TYPE_IMAGE) {
195 String[] fileParams = message.getBody().split(",");
196 try {
197 long size = Long.parseLong(fileParams[0]);
198 filesize = size / 1024 + " KB";
199 } catch (NumberFormatException e) {
200 filesize = "0 KB";
201 }
202 }
203 switch (message.getStatus()) {
204 case Message.STATUS_UNSEND:
205 info = getString(R.string.sending);
206 break;
207 case Message.STATUS_OFFERED:
208 info = getString(R.string.offering);
209 break;
210 case Message.STATUS_SEND_FAILED:
211 info = getString(R.string.send_failed);
212 error = true;
213 break;
214 case Message.STATUS_SEND_REJECTED:
215 info = getString(R.string.send_rejected);
216 error = true;
217 break;
218 default:
219 if ((message.getConversation().getMode() == Conversation.MODE_MULTI)
220 && (message.getStatus() <= Message.STATUS_RECIEVED)) {
221 info = message.getCounterpart();
222 }
223 break;
224 }
225 if (error) {
226 viewHolder.time.setTextColor(0xFFe92727);
227 } else {
228 viewHolder.time.setTextColor(0xFF8e8e8e);
229 }
230 if (message.getEncryption() == Message.ENCRYPTION_NONE) {
231 viewHolder.indicator.setVisibility(View.GONE);
232 } else {
233 viewHolder.indicator.setVisibility(View.VISIBLE);
234 }
235
236 String formatedTime = UIHelper.readableTimeDifference(getContext(), message
237 .getTimeSent());
238 if (message.getStatus() <= Message.STATUS_RECIEVED) {
239 if ((filesize != null) && (info != null)) {
240 viewHolder.time.setText(filesize + " \u00B7 " + info);
241 } else if ((filesize == null) && (info != null)) {
242 viewHolder.time.setText(formatedTime + " \u00B7 "
243 + info);
244 } else if ((filesize != null) && (info == null)) {
245 viewHolder.time.setText(formatedTime + " \u00B7 "
246 + filesize);
247 } else {
248 viewHolder.time.setText(formatedTime);
249 }
250 } else {
251 if ((filesize != null) && (info != null)) {
252 viewHolder.time.setText(filesize + " \u00B7 " + info);
253 } else if ((filesize == null) && (info != null)) {
254 viewHolder.time.setText(info + " \u00B7 "
255 + formatedTime);
256 } else if ((filesize != null) && (info == null)) {
257 viewHolder.time.setText(filesize + " \u00B7 "
258 + formatedTime);
259 } else {
260 viewHolder.time.setText(formatedTime);
261 }
262 }
263 }
264
265 private void displayInfoMessage(ViewHolder viewHolder, int r) {
266 if (viewHolder.download_button != null) {
267 viewHolder.download_button.setVisibility(View.GONE);
268 }
269 viewHolder.image.setVisibility(View.GONE);
270 viewHolder.messageBody.setVisibility(View.VISIBLE);
271 viewHolder.messageBody.setText(getString(r));
272 viewHolder.messageBody.setTextColor(0xff33B5E5);
273 viewHolder.messageBody.setTypeface(null, Typeface.ITALIC);
274 }
275
276 private void displayDecryptionFailed(ViewHolder viewHolder) {
277 viewHolder.download_button.setVisibility(View.GONE);
278 viewHolder.image.setVisibility(View.GONE);
279 viewHolder.messageBody.setVisibility(View.VISIBLE);
280 viewHolder.messageBody
281 .setText(getString(R.string.decryption_failed));
282 viewHolder.messageBody.setTextColor(0xFFe92727);
283 viewHolder.messageBody.setTypeface(null, Typeface.NORMAL);
284 }
285
286 private void displayTextMessage(ViewHolder viewHolder, String text) {
287 if (viewHolder.download_button != null) {
288 viewHolder.download_button.setVisibility(View.GONE);
289 }
290 viewHolder.image.setVisibility(View.GONE);
291 viewHolder.messageBody.setVisibility(View.VISIBLE);
292 if (text != null) {
293 viewHolder.messageBody.setText(text.trim());
294 } else {
295 viewHolder.messageBody.setText("");
296 }
297 viewHolder.messageBody.setTextColor(0xff333333);
298 viewHolder.messageBody.setTypeface(null, Typeface.NORMAL);
299 }
300
301 private void displayImageMessage(ViewHolder viewHolder,
302 final Message message) {
303 if (viewHolder.download_button != null) {
304 viewHolder.download_button.setVisibility(View.GONE);
305 }
306 viewHolder.messageBody.setVisibility(View.GONE);
307 viewHolder.image.setVisibility(View.VISIBLE);
308 String[] fileParams = message.getBody().split(",");
309 if (fileParams.length == 3) {
310 double target = metrics.density * 288;
311 int w = Integer.parseInt(fileParams[1]);
312 int h = Integer.parseInt(fileParams[2]);
313 int scalledW;
314 int scalledH;
315 if (w <= h) {
316 scalledW = (int) (w / ((double) h / target));
317 scalledH = (int) target;
318 } else {
319 scalledW = (int) target;
320 scalledH = (int) (h / ((double) w / target));
321 }
322 viewHolder.image
323 .setLayoutParams(new LinearLayout.LayoutParams(
324 scalledW, scalledH));
325 }
326 activity.loadBitmap(message, viewHolder.image);
327 viewHolder.image.setOnClickListener(new OnClickListener() {
328
329 @Override
330 public void onClick(View v) {
331 Intent intent = new Intent(Intent.ACTION_VIEW);
332 intent.setDataAndType(
333 ImageProvider.getContentUri(message), "image/*");
334 startActivity(intent);
335 }
336 });
337 }
338
339 @Override
340 public View getView(int position, View view, ViewGroup parent) {
341 final Message item = getItem(position);
342 int type = getItemViewType(position);
343 ViewHolder viewHolder;
344 if (view == null) {
345 viewHolder = new ViewHolder();
346 switch (type) {
347 case SENT:
348 view = (View) inflater.inflate(R.layout.message_sent,
349 null);
350 viewHolder.contact_picture = (ImageView) view
351 .findViewById(R.id.message_photo);
352 viewHolder.contact_picture.setImageBitmap(selfBitmap);
353 break;
354 case RECIEVED:
355 view = (View) inflater.inflate(
356 R.layout.message_recieved, null);
357 viewHolder.contact_picture = (ImageView) view
358 .findViewById(R.id.message_photo);
359
360 viewHolder.download_button = (Button) view
361 .findViewById(R.id.download_button);
362
363 if (item.getConversation().getMode() == Conversation.MODE_SINGLE) {
364
365 viewHolder.contact_picture
366 .setImageBitmap(mBitmapCache.get(
367 item.getConversation().getName(
368 useSubject), item
369 .getConversation()
370 .getContact(),
371 getActivity()
372 .getApplicationContext()));
373
374 }
375 break;
376 default:
377 viewHolder = null;
378 break;
379 }
380 viewHolder.indicator = (ImageView) view
381 .findViewById(R.id.security_indicator);
382 viewHolder.image = (ImageView) view
383 .findViewById(R.id.message_image);
384 viewHolder.messageBody = (TextView) view
385 .findViewById(R.id.message_body);
386 viewHolder.time = (TextView) view
387 .findViewById(R.id.message_time);
388 view.setTag(viewHolder);
389 } else {
390 viewHolder = (ViewHolder) view.getTag();
391 }
392
393 if (type == RECIEVED) {
394 if (item.getConversation().getMode() == Conversation.MODE_MULTI) {
395 viewHolder.contact_picture.setImageBitmap(mBitmapCache
396 .get(item.getCounterpart(), null, getActivity()
397 .getApplicationContext()));
398 viewHolder.contact_picture
399 .setOnClickListener(new OnClickListener() {
400
401 @Override
402 public void onClick(View v) {
403 highlightInConference(item.getCounterpart());
404 }
405 });
406 }
407 }
408
409 if (item.getType() == Message.TYPE_IMAGE) {
410 if (item.getStatus() == Message.STATUS_RECIEVING) {
411 displayInfoMessage(viewHolder, R.string.receiving_image);
412 } else if (item.getStatus() == Message.STATUS_RECEIVED_OFFER) {
413 viewHolder.image.setVisibility(View.GONE);
414 viewHolder.messageBody.setVisibility(View.GONE);
415 viewHolder.download_button.setVisibility(View.VISIBLE);
416 viewHolder.download_button
417 .setOnClickListener(new OnClickListener() {
418
419 @Override
420 public void onClick(View v) {
421 JingleConnection connection = item
422 .getJingleConnection();
423 if (connection != null) {
424 connection.accept();
425 } else {
426 Log.d("xmppService",
427 "attached jingle connection was null");
428 }
429 }
430 });
431 } else if ((item.getEncryption() == Message.ENCRYPTION_DECRYPTED)
432 || (item.getEncryption() == Message.ENCRYPTION_NONE)) {
433 displayImageMessage(viewHolder, item);
434 } else if (item.getEncryption() == Message.ENCRYPTION_PGP) {
435 displayInfoMessage(viewHolder,
436 R.string.encrypted_message);
437 } else {
438 displayDecryptionFailed(viewHolder);
439 }
440 } else {
441 if (item.getEncryption() == Message.ENCRYPTION_PGP) {
442 displayInfoMessage(viewHolder,
443 R.string.encrypted_message);
444 } else if (item.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) {
445 displayDecryptionFailed(viewHolder);
446 } else {
447 displayTextMessage(viewHolder, item.getBody());
448 }
449 }
450
451 displayStatus(viewHolder, item);
452
453 return view;
454 }
455 };
456 messagesView.setAdapter(messageListAdapter);
457
458 return view;
459 }
460
461 protected void highlightInConference(String nick) {
462 String oldString = chatMsg.getText().toString().trim();
463 if (oldString.isEmpty()) {
464 chatMsg.setText(nick+": ");
465 } else {
466 chatMsg.setText(oldString+" "+nick+" ");
467 }
468 int position = chatMsg.length();
469 Editable etext = chatMsg.getText();
470 Selection.setSelection(etext, position);
471 }
472
473 protected Bitmap findSelfPicture() {
474 SharedPreferences sharedPref = PreferenceManager
475 .getDefaultSharedPreferences(getActivity()
476 .getApplicationContext());
477 boolean showPhoneSelfContactPicture = sharedPref.getBoolean(
478 "show_phone_selfcontact_picture", true);
479
480 return UIHelper.getSelfContactPicture(conversation.getAccount(), 48,
481 showPhoneSelfContactPicture, getActivity());
482 }
483
484 @Override
485 public void onStart() {
486 super.onStart();
487 this.activity = (ConversationActivity) getActivity();
488 SharedPreferences preferences = PreferenceManager
489 .getDefaultSharedPreferences(activity);
490 this.useSubject = preferences.getBoolean("use_subject_in_muc", true);
491 if (activity.xmppConnectionServiceBound) {
492 this.onBackendConnected();
493 }
494 }
495
496 @Override
497 public void onStop() {
498 super.onStop();
499 if (this.conversation != null) {
500 this.conversation.setNextMessage(chatMsg.getText().toString());
501 }
502 }
503
504 public void onBackendConnected() {
505 this.conversation = activity.getSelectedConversation();
506 if (this.conversation == null) {
507 return;
508 }
509 String oldString = conversation.getNextMessage().trim();
510 if (this.pastedText == null) {
511 this.chatMsg.setText(oldString);
512 } else {
513
514 if (oldString.isEmpty()) {
515 chatMsg.setText(pastedText);
516 } else {
517 chatMsg.setText(oldString + " " + pastedText);
518 }
519 pastedText = null;
520 }
521 int position = chatMsg.length();
522 Editable etext = chatMsg.getText();
523 Selection.setSelection(etext, position);
524 this.selfBitmap = findSelfPicture();
525 updateMessages();
526 if (activity.getSlidingPaneLayout().isSlideable()) {
527 if (!activity.shouldPaneBeOpen()) {
528 activity.getSlidingPaneLayout().closePane();
529 activity.getActionBar().setDisplayHomeAsUpEnabled(true);
530 activity.getActionBar().setHomeButtonEnabled(true);
531 activity.getActionBar().setTitle(
532 conversation.getName(useSubject));
533 activity.invalidateOptionsMenu();
534
535 }
536 }
537 if (conversation.getMode() == Conversation.MODE_MULTI) {
538 activity.xmppConnectionService
539 .setOnRenameListener(new OnRenameListener() {
540
541 @Override
542 public void onRename(final boolean success) {
543 activity.xmppConnectionService
544 .updateConversation(conversation);
545 getActivity().runOnUiThread(new Runnable() {
546
547 @Override
548 public void run() {
549 if (success) {
550 Toast.makeText(
551 getActivity(),
552 getString(R.string.your_nick_has_been_changed),
553 Toast.LENGTH_SHORT).show();
554 } else {
555 Toast.makeText(
556 getActivity(),
557 getString(R.string.nick_in_use),
558 Toast.LENGTH_SHORT).show();
559 }
560 }
561 });
562 }
563 });
564 }
565 }
566
567 private void decryptMessage(final Message message) {
568 PgpEngine engine = activity.xmppConnectionService.getPgpEngine();
569 if (engine != null) {
570 engine.decrypt(message, new UiCallback() {
571
572 @Override
573 public void userInputRequried(PendingIntent pi) {
574 askForPassphraseIntent = pi.getIntentSender();
575 pgpInfo.setVisibility(View.VISIBLE);
576 }
577
578 @Override
579 public void success() {
580 activity.xmppConnectionService.databaseBackend
581 .updateMessage(message);
582 updateMessages();
583 }
584
585 @Override
586 public void error(int error) {
587 message.setEncryption(Message.ENCRYPTION_DECRYPTION_FAILED);
588 // updateMessages();
589 }
590 });
591 } else {
592 pgpInfo.setVisibility(View.VISIBLE);
593 }
594 }
595
596 public void updateMessages() {
597 if (getView() == null) {
598 return;
599 }
600 ConversationActivity activity = (ConversationActivity) getActivity();
601 if (this.conversation != null) {
602 for (Message message : this.conversation.getMessages()) {
603 if ((message.getEncryption() == Message.ENCRYPTION_PGP)
604 && ((message.getStatus() == Message.STATUS_RECIEVED) || (message
605 .getStatus() == Message.STATUS_SEND))) {
606 decryptMessage(message);
607 break;
608 }
609 }
610 this.messageList.clear();
611 this.messageList.addAll(this.conversation.getMessages());
612 this.messageListAdapter.notifyDataSetChanged();
613 if (conversation.getMode() == Conversation.MODE_SINGLE) {
614 if (messageList.size() >= 1) {
615 makeFingerprintWarning(conversation.getLatestEncryption());
616 }
617 } else {
618 if (conversation.getMucOptions().getError() != 0) {
619 mucError.setVisibility(View.VISIBLE);
620 if (conversation.getMucOptions().getError() == MucOptions.ERROR_NICK_IN_USE) {
621 mucErrorText.setText(getString(R.string.nick_in_use));
622 }
623 } else {
624 mucError.setVisibility(View.GONE);
625 }
626 }
627 getActivity().invalidateOptionsMenu();
628 updateChatMsgHint();
629 int size = this.messageList.size();
630 if (size >= 1)
631 messagesView.setSelection(size - 1);
632 if (!activity.shouldPaneBeOpen()) {
633 conversation.markRead();
634 // TODO update notifications
635 UIHelper.updateNotification(getActivity(),
636 activity.getConversationList(), null, false);
637 activity.updateConversationList();
638 }
639 }
640 }
641
642 protected void makeFingerprintWarning(int latestEncryption) {
643 final LinearLayout fingerprintWarning = (LinearLayout) getView()
644 .findViewById(R.id.new_fingerprint);
645 Set<String> knownFingerprints = conversation.getContact()
646 .getOtrFingerprints();
647 if ((latestEncryption == Message.ENCRYPTION_OTR)
648 && (conversation.hasValidOtrSession()
649 && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) && (!knownFingerprints
650 .contains(conversation.getOtrFingerprint())))) {
651 fingerprintWarning.setVisibility(View.VISIBLE);
652 TextView fingerprint = (TextView) getView().findViewById(
653 R.id.otr_fingerprint);
654 fingerprint.setText(conversation.getOtrFingerprint());
655 fingerprintWarning.setOnClickListener(new OnClickListener() {
656
657 @Override
658 public void onClick(View v) {
659 AlertDialog dialog = UIHelper.getVerifyFingerprintDialog(
660 (ConversationActivity) getActivity(), conversation,
661 fingerprintWarning);
662 dialog.show();
663 }
664 });
665 } else {
666 fingerprintWarning.setVisibility(View.GONE);
667 }
668 }
669
670 protected void sendPlainTextMessage(Message message) {
671 ConversationActivity activity = (ConversationActivity) getActivity();
672 activity.xmppConnectionService.sendMessage(message, null);
673 chatMsg.setText("");
674 }
675
676 protected void sendPgpMessage(final Message message) {
677 activity.pendingMessage = message;
678 final ConversationActivity activity = (ConversationActivity) getActivity();
679 final XmppConnectionService xmppService = activity.xmppConnectionService;
680 final Contact contact = message.getConversation().getContact();
681 if (activity.hasPgp()) {
682 if (conversation.getMode() == Conversation.MODE_SINGLE) {
683 if (contact.getPgpKeyId() != 0) {
684 xmppService.getPgpEngine().hasKey(contact, new UiCallback() {
685
686 @Override
687 public void userInputRequried(PendingIntent pi) {
688 activity.runIntent(pi,
689 ConversationActivity.REQUEST_ENCRYPT_MESSAGE);
690 }
691
692 @Override
693 public void success() {
694 activity.encryptTextMessage();
695 }
696
697 @Override
698 public void error(int error) {
699
700 }
701 });
702
703 } else {
704 showNoPGPKeyDialog(false,new DialogInterface.OnClickListener() {
705
706 @Override
707 public void onClick(DialogInterface dialog, int which) {
708 conversation.setNextEncryption(Message.ENCRYPTION_NONE);
709 message.setEncryption(Message.ENCRYPTION_NONE);
710 xmppService.sendMessage(message, null);
711 chatMsg.setText("");
712 }
713 });
714 }
715 } else {
716 if (conversation.getMucOptions().pgpKeysInUse()) {
717 activity.encryptTextMessage();
718 } else {
719 showNoPGPKeyDialog(true,new DialogInterface.OnClickListener() {
720
721 @Override
722 public void onClick(DialogInterface dialog, int which) {
723 conversation.setNextEncryption(Message.ENCRYPTION_NONE);
724 message.setEncryption(Message.ENCRYPTION_NONE);
725 xmppService.sendMessage(message, null);
726 chatMsg.setText("");
727 }
728 });
729 }
730 }
731 }
732 }
733
734 public void showNoPGPKeyDialog(boolean plural, DialogInterface.OnClickListener listener) {
735 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
736 builder.setIconAttribute(android.R.attr.alertDialogIcon);
737 if (plural) {
738 builder.setTitle(getString(R.string.no_pgp_keys));
739 builder.setMessage(getText(R.string.contacts_have_no_pgp_keys));
740 } else {
741 builder.setTitle(getString(R.string.no_pgp_key));
742 builder.setMessage(getText(R.string.contact_has_no_pgp_key));
743 }
744 builder.setNegativeButton(getString(R.string.cancel), null);
745 builder.setPositiveButton(getString(R.string.send_unencrypted),
746 listener);
747 builder.create().show();
748 }
749
750 protected void sendOtrMessage(final Message message) {
751 ConversationActivity activity = (ConversationActivity) getActivity();
752 final XmppConnectionService xmppService = activity.xmppConnectionService;
753 if (conversation.hasValidOtrSession()) {
754 activity.xmppConnectionService.sendMessage(message, null);
755 chatMsg.setText("");
756 } else {
757 activity.selectPresence(message.getConversation(),
758 new OnPresenceSelected() {
759
760 @Override
761 public void onPresenceSelected(boolean success,
762 String presence) {
763 if (success) {
764 xmppService.sendMessage(message, presence);
765 chatMsg.setText("");
766 }
767 }
768
769 @Override
770 public void onSendPlainTextInstead() {
771 message.setEncryption(Message.ENCRYPTION_NONE);
772 xmppService.sendMessage(message, null);
773 chatMsg.setText("");
774 }
775 }, "otr");
776 }
777 }
778
779 private static class ViewHolder {
780
781 protected Button download_button;
782 protected ImageView image;
783 protected ImageView indicator;
784 protected TextView time;
785 protected TextView messageBody;
786 protected ImageView contact_picture;
787
788 }
789
790 private class BitmapCache {
791 private HashMap<String, Bitmap> bitmaps = new HashMap<String, Bitmap>();
792
793 public Bitmap get(String name, Contact contact, Context context) {
794 if (bitmaps.containsKey(name)) {
795 return bitmaps.get(name);
796 } else {
797 Bitmap bm;
798 if (contact != null) {
799 bm = UIHelper
800 .getContactPicture(contact, 48, context, false);
801 } else {
802 bm = UIHelper.getContactPicture(name, 48, context, false);
803 }
804 bitmaps.put(name, bm);
805 return bm;
806 }
807 }
808 }
809
810 public void setText(String text) {
811 this.pastedText = text;
812 }
813
814 public void clearInputField() {
815 this.chatMsg.setText("");
816 }
817}