1package eu.siacs.conversations.ui.adapter;
2
3import android.content.ActivityNotFoundException;
4import android.content.Intent;
5import android.content.pm.PackageManager;
6import android.content.pm.ResolveInfo;
7import android.graphics.Typeface;
8import android.net.Uri;
9import android.text.Spannable;
10import android.text.SpannableString;
11import android.text.Spanned;
12import android.text.style.ForegroundColorSpan;
13import android.text.style.RelativeSizeSpan;
14import android.text.style.StyleSpan;
15import android.util.DisplayMetrics;
16import android.view.View;
17import android.view.View.OnClickListener;
18import android.view.View.OnLongClickListener;
19import android.view.ViewGroup;
20import android.widget.ArrayAdapter;
21import android.widget.Button;
22import android.widget.ImageView;
23import android.widget.LinearLayout;
24import android.widget.TextView;
25import android.widget.Toast;
26
27import java.util.List;
28
29import eu.siacs.conversations.R;
30import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession;
31import eu.siacs.conversations.entities.Account;
32import eu.siacs.conversations.entities.Contact;
33import eu.siacs.conversations.entities.Conversation;
34import eu.siacs.conversations.entities.DownloadableFile;
35import eu.siacs.conversations.entities.Message;
36import eu.siacs.conversations.entities.Message.FileParams;
37import eu.siacs.conversations.entities.Transferable;
38import eu.siacs.conversations.ui.ConversationActivity;
39import eu.siacs.conversations.utils.CryptoHelper;
40import eu.siacs.conversations.utils.GeoHelper;
41import eu.siacs.conversations.utils.UIHelper;
42
43public class MessageAdapter extends ArrayAdapter<Message> {
44
45 private static final int SENT = 0;
46 private static final int RECEIVED = 1;
47 private static final int STATUS = 2;
48
49 private ConversationActivity activity;
50
51 private DisplayMetrics metrics;
52
53 private OnContactPictureClicked mOnContactPictureClickedListener;
54 private OnContactPictureLongClicked mOnContactPictureLongClickedListener;
55
56 private OnLongClickListener openContextMenu = new OnLongClickListener() {
57
58 @Override
59 public boolean onLongClick(View v) {
60 v.showContextMenu();
61 return true;
62 }
63 };
64 private boolean mIndicateReceived = false;
65 private boolean mUseWhiteBackground = false;
66
67 public MessageAdapter(ConversationActivity activity, List<Message> messages) {
68 super(activity, 0, messages);
69 this.activity = activity;
70 metrics = getContext().getResources().getDisplayMetrics();
71 updatePreferences();
72 }
73
74 public void setOnContactPictureClicked(OnContactPictureClicked listener) {
75 this.mOnContactPictureClickedListener = listener;
76 }
77
78 public void setOnContactPictureLongClicked(
79 OnContactPictureLongClicked listener) {
80 this.mOnContactPictureLongClickedListener = listener;
81 }
82
83 @Override
84 public int getViewTypeCount() {
85 return 3;
86 }
87
88 public int getItemViewType(Message message) {
89 if (message.getType() == Message.TYPE_STATUS) {
90 return STATUS;
91 } else if (message.getStatus() <= Message.STATUS_RECEIVED) {
92 return RECEIVED;
93 }
94
95 return SENT;
96 }
97
98 @Override
99 public int getItemViewType(int position) {
100 return this.getItemViewType(getItem(position));
101 }
102
103 private int getMessageTextColor(boolean onDark, boolean primary) {
104 if (onDark) {
105 return activity.getResources().getColor(primary ? R.color.white : R.color.white70);
106 } else {
107 return activity.getResources().getColor(primary ? R.color.black87 : R.color.black54);
108 }
109 }
110
111 private void displayStatus(ViewHolder viewHolder, Message message, int type, boolean darkBackground) {
112 String filesize = null;
113 String info = null;
114 boolean error = false;
115 if (viewHolder.indicatorReceived != null) {
116 viewHolder.indicatorReceived.setVisibility(View.GONE);
117 }
118 boolean multiReceived = message.getConversation().getMode() == Conversation.MODE_MULTI
119 && message.getMergedStatus() <= Message.STATUS_RECEIVED;
120 if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE || message.getTransferable() != null) {
121 FileParams params = message.getFileParams();
122 if (params.size > (1.5 * 1024 * 1024)) {
123 filesize = params.size / (1024 * 1024)+ " MiB";
124 } else if (params.size > 0) {
125 filesize = params.size / 1024 + " KiB";
126 }
127 if (message.getTransferable() != null && message.getTransferable().getStatus() == Transferable.STATUS_FAILED) {
128 error = true;
129 }
130 }
131 switch (message.getMergedStatus()) {
132 case Message.STATUS_WAITING:
133 info = getContext().getString(R.string.waiting);
134 break;
135 case Message.STATUS_UNSEND:
136 Transferable d = message.getTransferable();
137 if (d!=null) {
138 info = getContext().getString(R.string.sending_file,d.getProgress());
139 } else {
140 info = getContext().getString(R.string.sending);
141 }
142 break;
143 case Message.STATUS_OFFERED:
144 info = getContext().getString(R.string.offering);
145 break;
146 case Message.STATUS_SEND_RECEIVED:
147 if (mIndicateReceived) {
148 viewHolder.indicatorReceived.setVisibility(View.VISIBLE);
149 }
150 break;
151 case Message.STATUS_SEND_DISPLAYED:
152 if (mIndicateReceived) {
153 viewHolder.indicatorReceived.setVisibility(View.VISIBLE);
154 }
155 break;
156 case Message.STATUS_SEND_FAILED:
157 info = getContext().getString(R.string.send_failed);
158 error = true;
159 break;
160 default:
161 if (multiReceived) {
162 info = UIHelper.getMessageDisplayName(message);
163 }
164 break;
165 }
166 if (error && type == SENT) {
167 viewHolder.time.setTextColor(activity.getWarningTextColor());
168 } else {
169 viewHolder.time.setTextColor(this.getMessageTextColor(darkBackground,false));
170 }
171 if (message.getEncryption() == Message.ENCRYPTION_NONE) {
172 viewHolder.indicator.setVisibility(View.GONE);
173 } else {
174 viewHolder.indicator.setImageResource(darkBackground ? R.drawable.ic_secure_indicator_white : R.drawable.ic_secure_indicator);
175 viewHolder.indicator.setVisibility(View.VISIBLE);
176 if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) {
177 XmppAxolotlSession.Trust trust = message.getConversation()
178 .getAccount().getAxolotlService().getFingerprintTrust(
179 message.getAxolotlFingerprint());
180
181 if(trust == null || trust != XmppAxolotlSession.Trust.TRUSTED) {
182 viewHolder.indicator.setColorFilter(activity.getWarningTextColor());
183 viewHolder.indicator.setAlpha(1.0f);
184 } else {
185 viewHolder.indicator.clearColorFilter();
186 if (darkBackground) {
187 viewHolder.indicator.setAlpha(0.7f);
188 } else {
189 viewHolder.indicator.setAlpha(0.57f);
190 }
191 }
192 } else {
193 viewHolder.indicator.clearColorFilter();
194 if (darkBackground) {
195 viewHolder.indicator.setAlpha(0.7f);
196 } else {
197 viewHolder.indicator.setAlpha(0.57f);
198 }
199 }
200 }
201
202 String formatedTime = UIHelper.readableTimeDifferenceFull(getContext(),
203 message.getMergedTimeSent());
204 if (message.getStatus() <= Message.STATUS_RECEIVED) {
205 if ((filesize != null) && (info != null)) {
206 viewHolder.time.setText(formatedTime + " \u00B7 " + filesize +" \u00B7 " + info);
207 } else if ((filesize == null) && (info != null)) {
208 viewHolder.time.setText(formatedTime + " \u00B7 " + info);
209 } else if ((filesize != null) && (info == null)) {
210 viewHolder.time.setText(formatedTime + " \u00B7 " + filesize);
211 } else {
212 viewHolder.time.setText(formatedTime);
213 }
214 } else {
215 if ((filesize != null) && (info != null)) {
216 viewHolder.time.setText(filesize + " \u00B7 " + info);
217 } else if ((filesize == null) && (info != null)) {
218 if (error) {
219 viewHolder.time.setText(info + " \u00B7 " + formatedTime);
220 } else {
221 viewHolder.time.setText(info);
222 }
223 } else if ((filesize != null) && (info == null)) {
224 viewHolder.time.setText(filesize + " \u00B7 " + formatedTime);
225 } else {
226 viewHolder.time.setText(formatedTime);
227 }
228 }
229 }
230
231 private void displayInfoMessage(ViewHolder viewHolder, String text, boolean darkBackground) {
232 if (viewHolder.download_button != null) {
233 viewHolder.download_button.setVisibility(View.GONE);
234 }
235 viewHolder.image.setVisibility(View.GONE);
236 viewHolder.messageBody.setVisibility(View.VISIBLE);
237 viewHolder.messageBody.setText(text);
238 viewHolder.messageBody.setTextColor(getMessageTextColor(darkBackground, false));
239 viewHolder.messageBody.setTypeface(null, Typeface.ITALIC);
240 viewHolder.messageBody.setTextIsSelectable(false);
241 }
242
243 private void displayDecryptionFailed(ViewHolder viewHolder, boolean darkBackground) {
244 if (viewHolder.download_button != null) {
245 viewHolder.download_button.setVisibility(View.GONE);
246 }
247 viewHolder.image.setVisibility(View.GONE);
248 viewHolder.messageBody.setVisibility(View.VISIBLE);
249 viewHolder.messageBody.setText(getContext().getString(
250 R.string.decryption_failed));
251 viewHolder.messageBody.setTextColor(getMessageTextColor(darkBackground, false));
252 viewHolder.messageBody.setTypeface(null, Typeface.NORMAL);
253 viewHolder.messageBody.setTextIsSelectable(false);
254 }
255
256 private void displayHeartMessage(final ViewHolder viewHolder, final String body) {
257 if (viewHolder.download_button != null) {
258 viewHolder.download_button.setVisibility(View.GONE);
259 }
260 viewHolder.image.setVisibility(View.GONE);
261 viewHolder.messageBody.setVisibility(View.VISIBLE);
262 viewHolder.messageBody.setIncludeFontPadding(false);
263 Spannable span = new SpannableString(body);
264 span.setSpan(new RelativeSizeSpan(4.0f), 0, body.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
265 span.setSpan(new ForegroundColorSpan(activity.getWarningTextColor()), 0, body.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
266 viewHolder.messageBody.setText(span);
267 }
268
269 private void displayTextMessage(final ViewHolder viewHolder, final Message message, boolean darkBackground) {
270 if (viewHolder.download_button != null) {
271 viewHolder.download_button.setVisibility(View.GONE);
272 }
273 viewHolder.image.setVisibility(View.GONE);
274 viewHolder.messageBody.setVisibility(View.VISIBLE);
275 viewHolder.messageBody.setIncludeFontPadding(true);
276 if (message.getBody() != null) {
277 final String nick = UIHelper.getMessageDisplayName(message);
278 String body;
279 try {
280 body = message.getMergedBody().replaceAll("^" + Message.ME_COMMAND, nick + " ");
281 } catch (ArrayIndexOutOfBoundsException e) {
282 body = message.getMergedBody();
283 }
284 final SpannableString formattedBody = new SpannableString(body);
285 int i = body.indexOf(Message.MERGE_SEPARATOR);
286 while(i >= 0) {
287 final int end = i + Message.MERGE_SEPARATOR.length();
288 formattedBody.setSpan(new RelativeSizeSpan(0.3f),i,end,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
289 i = body.indexOf(Message.MERGE_SEPARATOR,end);
290 }
291 if (message.getType() != Message.TYPE_PRIVATE) {
292 if (message.hasMeCommand()) {
293 final Spannable span = new SpannableString(formattedBody);
294 span.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 0, nick.length(),
295 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
296 viewHolder.messageBody.setText(span);
297 } else {
298 viewHolder.messageBody.setText(formattedBody);
299 }
300 } else {
301 String privateMarker;
302 if (message.getStatus() <= Message.STATUS_RECEIVED) {
303 privateMarker = activity
304 .getString(R.string.private_message);
305 } else {
306 final String to;
307 if (message.getCounterpart() != null) {
308 to = message.getCounterpart().getResourcepart();
309 } else {
310 to = "";
311 }
312 privateMarker = activity.getString(R.string.private_message_to, to);
313 }
314 final Spannable span = new SpannableString(privateMarker + " "
315 + formattedBody);
316 span.setSpan(new ForegroundColorSpan(getMessageTextColor(darkBackground,false)), 0, privateMarker
317 .length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
318 span.setSpan(new StyleSpan(Typeface.BOLD), 0,
319 privateMarker.length(),
320 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
321 if (message.hasMeCommand()) {
322 span.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), privateMarker.length() + 1,
323 privateMarker.length() + 1 + nick.length(),
324 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
325 }
326 viewHolder.messageBody.setText(span);
327 }
328 } else {
329 viewHolder.messageBody.setText("");
330 }
331 viewHolder.messageBody.setTextColor(this.getMessageTextColor(darkBackground, true));
332 viewHolder.messageBody.setLinkTextColor(this.getMessageTextColor(darkBackground, true));
333 viewHolder.messageBody.setHighlightColor(activity.getResources().getColor(darkBackground ? R.color.grey800 : R.color.grey500));
334 viewHolder.messageBody.setTypeface(null, Typeface.NORMAL);
335 viewHolder.messageBody.setTextIsSelectable(true);
336 }
337
338 private void displayDownloadableMessage(ViewHolder viewHolder,
339 final Message message, String text) {
340 viewHolder.image.setVisibility(View.GONE);
341 viewHolder.messageBody.setVisibility(View.GONE);
342 viewHolder.download_button.setVisibility(View.VISIBLE);
343 viewHolder.download_button.setText(text);
344 viewHolder.download_button.setOnClickListener(new OnClickListener() {
345
346 @Override
347 public void onClick(View v) {
348 startDownloadable(message);
349 }
350 });
351 viewHolder.download_button.setOnLongClickListener(openContextMenu);
352 }
353
354 private void displayOpenableMessage(ViewHolder viewHolder,final Message message) {
355 viewHolder.image.setVisibility(View.GONE);
356 viewHolder.messageBody.setVisibility(View.GONE);
357 viewHolder.download_button.setVisibility(View.VISIBLE);
358 viewHolder.download_button.setText(activity.getString(R.string.open_x_file, UIHelper.getFileDescriptionString(activity, message)));
359 viewHolder.download_button.setOnClickListener(new OnClickListener() {
360
361 @Override
362 public void onClick(View v) {
363 openDownloadable(message);
364 }
365 });
366 viewHolder.download_button.setOnLongClickListener(openContextMenu);
367 }
368
369 private void displayLocationMessage(ViewHolder viewHolder, final Message message) {
370 viewHolder.image.setVisibility(View.GONE);
371 viewHolder.messageBody.setVisibility(View.GONE);
372 viewHolder.download_button.setVisibility(View.VISIBLE);
373 viewHolder.download_button.setText(R.string.show_location);
374 viewHolder.download_button.setOnClickListener(new OnClickListener() {
375
376 @Override
377 public void onClick(View v) {
378 showLocation(message);
379 }
380 });
381 viewHolder.download_button.setOnLongClickListener(openContextMenu);
382 }
383
384 private void displayImageMessage(ViewHolder viewHolder,
385 final Message message) {
386 if (viewHolder.download_button != null) {
387 viewHolder.download_button.setVisibility(View.GONE);
388 }
389 viewHolder.messageBody.setVisibility(View.GONE);
390 viewHolder.image.setVisibility(View.VISIBLE);
391 FileParams params = message.getFileParams();
392 double target = metrics.density * 288;
393 int scalledW;
394 int scalledH;
395 if (params.width <= params.height) {
396 scalledW = (int) (params.width / ((double) params.height / target));
397 scalledH = (int) target;
398 } else {
399 scalledW = (int) target;
400 scalledH = (int) (params.height / ((double) params.width / target));
401 }
402 LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(scalledW, scalledH);
403 layoutParams.setMargins(0, (int) (metrics.density * 4), 0, (int) (metrics.density * 4));
404 viewHolder.image.setLayoutParams(layoutParams);
405 activity.loadBitmap(message, viewHolder.image);
406 viewHolder.image.setOnClickListener(new OnClickListener() {
407
408 @Override
409 public void onClick(View v) {
410 openDownloadable(message);
411 }
412 });
413 viewHolder.image.setOnLongClickListener(openContextMenu);
414 }
415
416 @Override
417 public View getView(int position, View view, ViewGroup parent) {
418 final Message message = getItem(position);
419 final boolean isInValidSession = message.isValidInSession();
420 final Conversation conversation = message.getConversation();
421 final Account account = conversation.getAccount();
422 final int type = getItemViewType(position);
423 ViewHolder viewHolder;
424 if (view == null) {
425 viewHolder = new ViewHolder();
426 switch (type) {
427 case SENT:
428 view = activity.getLayoutInflater().inflate(
429 R.layout.message_sent, parent, false);
430 viewHolder.message_box = (LinearLayout) view
431 .findViewById(R.id.message_box);
432 viewHolder.contact_picture = (ImageView) view
433 .findViewById(R.id.message_photo);
434 viewHolder.download_button = (Button) view
435 .findViewById(R.id.download_button);
436 viewHolder.indicator = (ImageView) view
437 .findViewById(R.id.security_indicator);
438 viewHolder.image = (ImageView) view
439 .findViewById(R.id.message_image);
440 viewHolder.messageBody = (TextView) view
441 .findViewById(R.id.message_body);
442 viewHolder.time = (TextView) view
443 .findViewById(R.id.message_time);
444 viewHolder.indicatorReceived = (ImageView) view
445 .findViewById(R.id.indicator_received);
446 break;
447 case RECEIVED:
448 view = activity.getLayoutInflater().inflate(
449 R.layout.message_received, parent, false);
450 viewHolder.message_box = (LinearLayout) view
451 .findViewById(R.id.message_box);
452 viewHolder.contact_picture = (ImageView) view
453 .findViewById(R.id.message_photo);
454 viewHolder.download_button = (Button) view
455 .findViewById(R.id.download_button);
456 viewHolder.indicator = (ImageView) view
457 .findViewById(R.id.security_indicator);
458 viewHolder.image = (ImageView) view
459 .findViewById(R.id.message_image);
460 viewHolder.messageBody = (TextView) view
461 .findViewById(R.id.message_body);
462 viewHolder.time = (TextView) view
463 .findViewById(R.id.message_time);
464 viewHolder.indicatorReceived = (ImageView) view
465 .findViewById(R.id.indicator_received);
466 viewHolder.encryption = (TextView) view.findViewById(R.id.message_encryption);
467 break;
468 case STATUS:
469 view = activity.getLayoutInflater().inflate(R.layout.message_status, parent, false);
470 viewHolder.contact_picture = (ImageView) view.findViewById(R.id.message_photo);
471 viewHolder.status_message = (TextView) view.findViewById(R.id.status_message);
472 break;
473 default:
474 viewHolder = null;
475 break;
476 }
477 view.setTag(viewHolder);
478 } else {
479 viewHolder = (ViewHolder) view.getTag();
480 if (viewHolder == null) {
481 return view;
482 }
483 }
484
485 boolean darkBackground = (type == RECEIVED && (!isInValidSession || !mUseWhiteBackground));
486
487 if (type == STATUS) {
488 if (conversation.getMode() == Conversation.MODE_SINGLE) {
489 viewHolder.contact_picture.setImageBitmap(activity
490 .avatarService().get(conversation.getContact(),
491 activity.getPixel(32)));
492 viewHolder.contact_picture.setAlpha(0.5f);
493 viewHolder.status_message.setText(message.getBody());
494 }
495 return view;
496 } else if (type == RECEIVED) {
497 Contact contact = message.getContact();
498 if (contact != null) {
499 viewHolder.contact_picture.setImageBitmap(activity.avatarService().get(contact, activity.getPixel(48)));
500 } else if (conversation.getMode() == Conversation.MODE_MULTI) {
501 viewHolder.contact_picture.setImageBitmap(activity.avatarService().get(
502 UIHelper.getMessageDisplayName(message),
503 activity.getPixel(48)));
504 }
505 } else if (type == SENT) {
506 viewHolder.contact_picture.setImageBitmap(activity.avatarService().get(account, activity.getPixel(48)));
507 }
508
509 viewHolder.contact_picture
510 .setOnClickListener(new OnClickListener() {
511
512 @Override
513 public void onClick(View v) {
514 if (MessageAdapter.this.mOnContactPictureClickedListener != null) {
515 MessageAdapter.this.mOnContactPictureClickedListener
516 .onContactPictureClicked(message);
517 }
518
519 }
520 });
521 viewHolder.contact_picture
522 .setOnLongClickListener(new OnLongClickListener() {
523
524 @Override
525 public boolean onLongClick(View v) {
526 if (MessageAdapter.this.mOnContactPictureLongClickedListener != null) {
527 MessageAdapter.this.mOnContactPictureLongClickedListener
528 .onContactPictureLongClicked(message);
529 return true;
530 } else {
531 return false;
532 }
533 }
534 });
535
536 final Transferable transferable = message.getTransferable();
537 if (transferable != null && transferable.getStatus() != Transferable.STATUS_UPLOADING) {
538 if (transferable.getStatus() == Transferable.STATUS_OFFER) {
539 displayDownloadableMessage(viewHolder,message,activity.getString(R.string.download_x_file, UIHelper.getFileDescriptionString(activity, message)));
540 } else if (transferable.getStatus() == Transferable.STATUS_OFFER_CHECK_FILESIZE) {
541 displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message)));
542 } else {
543 displayInfoMessage(viewHolder, UIHelper.getMessagePreview(activity, message).first,darkBackground);
544 }
545 } else if (message.getType() == Message.TYPE_IMAGE && message.getEncryption() != Message.ENCRYPTION_PGP && message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED) {
546 displayImageMessage(viewHolder, message);
547 } else if (message.getType() == Message.TYPE_FILE && message.getEncryption() != Message.ENCRYPTION_PGP && message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED) {
548 if (message.getFileParams().width > 0) {
549 displayImageMessage(viewHolder,message);
550 } else {
551 displayOpenableMessage(viewHolder, message);
552 }
553 } else if (message.getEncryption() == Message.ENCRYPTION_PGP) {
554 if (activity.hasPgp()) {
555 displayInfoMessage(viewHolder,activity.getString(R.string.encrypted_message),darkBackground);
556 } else {
557 displayInfoMessage(viewHolder,activity.getString(R.string.install_openkeychain),darkBackground);
558 if (viewHolder != null) {
559 viewHolder.message_box
560 .setOnClickListener(new OnClickListener() {
561
562 @Override
563 public void onClick(View v) {
564 activity.showInstallPgpDialog();
565 }
566 });
567 }
568 }
569 } else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) {
570 displayDecryptionFailed(viewHolder,darkBackground);
571 } else {
572 if (GeoHelper.isGeoUri(message.getBody())) {
573 displayLocationMessage(viewHolder,message);
574 } else if (message.bodyIsHeart()) {
575 displayHeartMessage(viewHolder, message.getBody().trim());
576 } else if (message.treatAsDownloadable() == Message.Decision.MUST) {
577 displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message)));
578 } else {
579 displayTextMessage(viewHolder, message, darkBackground);
580 }
581 }
582
583 if (type == RECEIVED) {
584 if(isInValidSession) {
585 if (mUseWhiteBackground) {
586 viewHolder.message_box.setBackgroundResource(R.drawable.message_bubble_received_white);
587 } else {
588 viewHolder.message_box.setBackgroundResource(R.drawable.message_bubble_received);
589 }
590 viewHolder.encryption.setVisibility(View.GONE);
591 } else {
592 viewHolder.message_box.setBackgroundResource(R.drawable.message_bubble_received_warning);
593 viewHolder.encryption.setVisibility(View.VISIBLE);
594 viewHolder.encryption.setText(CryptoHelper.encryptionTypeToText(message.getEncryption()));
595 }
596 }
597
598 displayStatus(viewHolder, message, type, darkBackground);
599
600 return view;
601 }
602
603 public void startDownloadable(Message message) {
604 Transferable transferable = message.getTransferable();
605 if (transferable != null) {
606 if (!transferable.start()) {
607 Toast.makeText(activity, R.string.not_connected_try_again,
608 Toast.LENGTH_SHORT).show();
609 }
610 } else if (message.treatAsDownloadable() != Message.Decision.NEVER) {
611 activity.xmppConnectionService.getHttpConnectionManager().createNewDownloadConnection(message, true);
612 }
613 }
614
615 public void openDownloadable(Message message) {
616 DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message);
617 if (!file.exists()) {
618 Toast.makeText(activity,R.string.file_deleted,Toast.LENGTH_SHORT).show();
619 return;
620 }
621 Intent openIntent = new Intent(Intent.ACTION_VIEW);
622 String mime = file.getMimeType();
623 if (mime == null) {
624 mime = "*/*";
625 }
626 openIntent.setDataAndType(Uri.fromFile(file), mime);
627 PackageManager manager = activity.getPackageManager();
628 List<ResolveInfo> infos = manager.queryIntentActivities(openIntent, 0);
629 if (infos.size() == 0) {
630 openIntent.setDataAndType(Uri.fromFile(file),"*/*");
631 }
632 try {
633 getContext().startActivity(openIntent);
634 return;
635 } catch (ActivityNotFoundException e) {
636 //ignored
637 }
638 Toast.makeText(activity,R.string.no_application_found_to_open_file,Toast.LENGTH_SHORT).show();
639 }
640
641 public void showLocation(Message message) {
642 for(Intent intent : GeoHelper.createGeoIntentsFromMessage(message)) {
643 if (intent.resolveActivity(getContext().getPackageManager()) != null) {
644 getContext().startActivity(intent);
645 return;
646 }
647 }
648 Toast.makeText(activity,R.string.no_application_found_to_display_location,Toast.LENGTH_SHORT).show();
649 }
650
651 public void updatePreferences() {
652 this.mIndicateReceived = activity.indicateReceived();
653 this.mUseWhiteBackground = activity.useWhiteBackground();
654 }
655
656 public interface OnContactPictureClicked {
657 void onContactPictureClicked(Message message);
658 }
659
660 public interface OnContactPictureLongClicked {
661 void onContactPictureLongClicked(Message message);
662 }
663
664 private static class ViewHolder {
665
666 protected LinearLayout message_box;
667 protected Button download_button;
668 protected ImageView image;
669 protected ImageView indicator;
670 protected ImageView indicatorReceived;
671 protected TextView time;
672 protected TextView messageBody;
673 protected ImageView contact_picture;
674 protected TextView status_message;
675 protected TextView encryption;
676 }
677}