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