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