• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 Esmertec AG.
3  * Copyright (C) 2008 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package com.android.mms.ui;
19 
20 import com.google.android.mms.ContentType;
21 import com.android.mms.ExceedMessageSizeException;
22 import com.google.android.mms.MmsException;
23 import com.android.mms.MmsConfig;
24 import com.android.mms.R;
25 import com.android.mms.ResolutionException;
26 import com.android.mms.UnsupportContentTypeException;
27 import com.android.mms.model.IModelChangedObserver;
28 import com.android.mms.model.LayoutModel;
29 import com.android.mms.model.Model;
30 import com.android.mms.model.SlideModel;
31 import com.android.mms.model.SlideshowModel;
32 import com.google.android.mms.pdu.PduBody;
33 import com.google.android.mms.pdu.PduPart;
34 import com.google.android.mms.pdu.PduPersister;
35 import com.android.mms.ui.BasicSlideEditorView.OnTextChangedListener;
36 import com.android.mms.ui.MessageUtils.ResizeImageResultCallback;
37 
38 import android.app.Activity;
39 import android.app.AlertDialog;
40 import android.content.ContentUris;
41 import android.content.Context;
42 import android.content.DialogInterface;
43 import android.content.Intent;
44 import android.content.res.Resources;
45 import android.graphics.Bitmap;
46 import android.media.RingtoneManager;
47 import android.net.Uri;
48 import android.os.Bundle;
49 import android.os.Handler;
50 import android.provider.MediaStore;
51 import android.provider.Settings;
52 import android.text.TextUtils;
53 import android.util.Config;
54 import android.util.Log;
55 import android.view.Menu;
56 import android.view.MenuItem;
57 import android.view.SubMenu;
58 import android.view.View;
59 import android.view.View.OnClickListener;
60 import android.widget.Button;
61 import android.widget.ImageButton;
62 import android.widget.Toast;
63 
64 /**
65  * This activity allows user to edit the contents of a slide.
66  */
67 public class SlideEditorActivity extends Activity {
68     private static final String TAG = "SlideEditorActivity";
69     private static final boolean DEBUG = false;
70     private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
71 
72     // Key for extra data.
73     public static final String SLIDE_INDEX = "slide_index";
74 
75     // Menu ids.
76     private final static int MENU_REMOVE_TEXT       = 0;
77     private final static int MENU_ADD_PICTURE       = 1;
78     private final static int MENU_TAKE_PICTURE      = 2;
79     private final static int MENU_DEL_PICTURE       = 3;
80     private final static int MENU_ADD_AUDIO         = 4;
81     private final static int MENU_DEL_AUDIO         = 5;
82     private final static int MENU_ADD_VIDEO         = 6;
83     private final static int MENU_ADD_SLIDE         = 7;
84     private final static int MENU_DEL_VIDEO         = 8;
85     private final static int MENU_LAYOUT            = 9;
86     private final static int MENU_DURATION          = 10;
87     private final static int MENU_PREVIEW_SLIDESHOW = 11;
88     private final static int MENU_RECORD_SOUND      = 12;
89     private final static int MENU_SUB_AUDIO         = 13;
90 
91     // Request code.
92     private final static int REQUEST_CODE_EDIT_TEXT          = 0;
93     private final static int REQUEST_CODE_CHANGE_PICTURE     = 1;
94     private final static int REQUEST_CODE_TAKE_PICTURE       = 2;
95     private final static int REQUEST_CODE_CHANGE_MUSIC       = 3;
96     private final static int REQUEST_CODE_RECORD_SOUND       = 4;
97     private final static int REQUEST_CODE_CHANGE_VIDEO       = 5;
98     private final static int REQUEST_CODE_CHANGE_DURATION    = 6;
99 
100     // number of items in the duration selector dialog that directly map from
101     // item index to duration in seconds (duration = index + 1)
102     private final static int NUM_DIRECT_DURATIONS = 10;
103 
104     private ImageButton mNextSlide;
105     private ImageButton mPreSlide;
106     private Button mPreview;
107     private Button mReplaceImage;
108     private Button mRemoveSlide;
109     private Button mDone;
110     private BasicSlideEditorView mSlideView;
111 
112     private SlideshowModel mSlideshowModel;
113     private SlideshowEditor mSlideshowEditor;
114     private SlideshowPresenter mPresenter;
115     private boolean mDirty;
116 
117     private int mPosition;
118     private Uri mUri;
119 
120     private final static String MESSAGE_URI = "message_uri";
121 
122     @Override
onCreate(Bundle savedInstanceState)123     protected void onCreate(Bundle savedInstanceState) {
124         super.onCreate(savedInstanceState);
125         setContentView(R.layout.edit_slide_activity);
126 
127         mSlideView = (BasicSlideEditorView) findViewById(R.id.slide_editor_view);
128         mSlideView.setOnTextChangedListener(mOnTextChangedListener);
129 
130         mPreSlide = (ImageButton) findViewById(R.id.pre_slide_button);
131         mPreSlide.setOnClickListener(mOnNavigateBackward);
132 
133         mNextSlide = (ImageButton) findViewById(R.id.next_slide_button);
134         mNextSlide.setOnClickListener(mOnNavigateForward);
135 
136         mPreview = (Button) findViewById(R.id.preview_button);
137         mPreview.setOnClickListener(mOnPreview);
138 
139         mReplaceImage = (Button) findViewById(R.id.replace_image_button);
140         mReplaceImage.setOnClickListener(mOnReplaceImage);
141 
142         mRemoveSlide = (Button) findViewById(R.id.remove_slide_button);
143         mRemoveSlide.setOnClickListener(mOnRemoveSlide);
144 
145         mDone = (Button) findViewById(R.id.done_button);
146         mDone.setOnClickListener(mDoneClickListener);
147 
148         initActivityState(savedInstanceState, getIntent());
149 
150         try {
151             mSlideshowModel = SlideshowModel.createFromMessageUri(this, mUri);
152             // Register an observer to watch whether the data model is changed.
153             mSlideshowModel.registerModelChangedObserver(mModelChangedObserver);
154             mSlideshowEditor = new SlideshowEditor(this, mSlideshowModel);
155             mPresenter = (SlideshowPresenter) PresenterFactory.getPresenter(
156                     "SlideshowPresenter", this, mSlideView, mSlideshowModel);
157 
158             // Sanitize mPosition
159             if (mPosition >= mSlideshowModel.size()) {
160                 mPosition = Math.max(0, mSlideshowModel.size() - 1);
161             } else if (mPosition < 0) {
162                 mPosition = 0;
163             }
164 
165             showCurrentSlide();
166         } catch (MmsException e) {
167             Log.e(TAG, "Create SlideshowModel failed!", e);
168             finish();
169             return;
170         }
171     }
172 
initActivityState(Bundle savedInstanceState, Intent intent)173     private void initActivityState(Bundle savedInstanceState, Intent intent) {
174         if (savedInstanceState != null) {
175             mUri = (Uri) savedInstanceState.getParcelable(MESSAGE_URI);
176             mPosition = savedInstanceState.getInt(SLIDE_INDEX, 0);
177         } else {
178             mUri = intent.getData();
179             mPosition = intent.getIntExtra(SLIDE_INDEX, 0);
180         }
181     }
182 
183     @Override
onSaveInstanceState(Bundle outState)184     protected void onSaveInstanceState(Bundle outState) {
185         super.onSaveInstanceState(outState);
186 
187         outState.putInt(SLIDE_INDEX, mPosition);
188         outState.putParcelable(MESSAGE_URI, mUri);
189     }
190 
191     @Override
onPause()192     protected void onPause()  {
193         super.onPause();
194 
195         synchronized (this) {
196             if (mDirty) {
197                 try {
198                     PduBody pb = mSlideshowModel.toPduBody();
199                     PduPersister.getPduPersister(this).updateParts(mUri, pb);
200                     mSlideshowModel.sync(pb);
201                 }  catch (MmsException e) {
202                     Log.e(TAG, "Cannot update the message: " + mUri, e);
203                 }
204             }
205         }
206     }
207 
208     @Override
onDestroy()209     protected void onDestroy() {
210         super.onDestroy();
211 
212         if (mSlideshowModel != null) {
213             mSlideshowModel.unregisterModelChangedObserver(
214                     mModelChangedObserver);
215         }
216     }
217 
218     private final IModelChangedObserver mModelChangedObserver =
219         new IModelChangedObserver() {
220             public void onModelChanged(Model model, boolean dataChanged) {
221                 synchronized (SlideEditorActivity.this) {
222                     mDirty = true;
223                 }
224                 setResult(RESULT_OK);
225             }
226         };
227 
228     private final OnClickListener mOnRemoveSlide = new OnClickListener() {
229         public void onClick(View v) {
230             // Validate mPosition
231             if (mPosition >= 0 && mPosition < mSlideshowModel.size()) {
232                 mSlideshowEditor.removeSlide(mPosition);
233                 int size = mSlideshowModel.size();
234                 if (size > 0) {
235                     if (mPosition >= size) {
236                         mPosition--;
237                     }
238                     showCurrentSlide();
239                 } else {
240                     finish();
241                     return;
242                 }
243             }
244         }
245     };
246 
247     private final OnTextChangedListener mOnTextChangedListener = new OnTextChangedListener() {
248         public void onTextChanged(String s) {
249             mSlideshowEditor.changeText(mPosition, s);
250         }
251     };
252 
253     private final OnClickListener mOnPreview = new OnClickListener() {
254         public void onClick(View v) {
255             previewSlideshow();
256         }
257     };
258 
259     private final OnClickListener mOnReplaceImage = new OnClickListener() {
260         public void onClick(View v) {
261             SlideModel slide = mSlideshowModel.get(mPosition);
262             if (slide.hasVideo()) {
263                 Toast.makeText(SlideEditorActivity.this, R.string.cannot_add_picture_and_video,
264                         Toast.LENGTH_SHORT).show();
265                 return;
266             }
267             Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
268             intent.setType(ContentType.IMAGE_UNSPECIFIED);
269             startActivityForResult(intent, REQUEST_CODE_CHANGE_PICTURE);
270         }
271     };
272 
273     private final OnClickListener mOnNavigateBackward = new OnClickListener() {
274         public void onClick(View v) {
275             if (mPosition > 0) {
276                 mPosition --;
277                 showCurrentSlide();
278             }
279         }
280     };
281 
282     private final OnClickListener mOnNavigateForward = new OnClickListener() {
283         public void onClick(View v) {
284             if (mPosition < mSlideshowModel.size() - 1) {
285                 mPosition ++;
286                 showCurrentSlide();
287             }
288         }
289     };
290 
291     private final OnClickListener mDoneClickListener = new OnClickListener() {
292         public void onClick(View v) {
293             Intent data = new Intent();
294             data.putExtra("done", true);
295             setResult(RESULT_OK, data);
296             finish();
297         }
298     };
299 
previewSlideshow()300     private void previewSlideshow() {
301         MessageUtils.viewMmsMessageAttachment(SlideEditorActivity.this, mUri, mSlideshowModel);
302     }
303 
updateTitle()304     private void updateTitle() {
305         setTitle(getString(R.string.slide_show_part, (mPosition + 1), mSlideshowModel.size()));
306     }
307 
308     @Override
onPrepareOptionsMenu(Menu menu)309     public boolean onPrepareOptionsMenu(Menu menu) {
310         menu.clear();
311 
312         SlideModel slide = mSlideshowModel.get(mPosition);
313 
314         // Preview slideshow.
315         menu.add(0, MENU_PREVIEW_SLIDESHOW, 0, R.string.preview_slideshow).setIcon(
316                 com.android.internal.R.drawable.ic_menu_play_clip);
317 
318         // Text
319         if (slide.hasText() && !TextUtils.isEmpty(slide.getText().getText())) {
320             //"Change text" if text is set.
321             menu.add(0, MENU_REMOVE_TEXT, 0, R.string.remove_text).setIcon(
322                     R.drawable.ic_menu_remove_text);
323         }
324 
325         // Picture
326         if (slide.hasImage()) {
327             menu.add(0, MENU_DEL_PICTURE, 0, R.string.remove_picture).setIcon(
328                     R.drawable.ic_menu_remove_picture);
329         } else if (!slide.hasVideo()) {
330             menu.add(0, MENU_ADD_PICTURE, 0, R.string.add_picture).setIcon(
331                     R.drawable.ic_menu_picture);
332             menu.add(0, MENU_TAKE_PICTURE, 0, R.string.attach_take_photo).setIcon(
333                     R.drawable.ic_menu_picture);
334         }
335 
336         // Music
337         if (slide.hasAudio()) {
338             menu.add(0, MENU_DEL_AUDIO, 0, R.string.remove_music).setIcon(
339                     R.drawable.ic_menu_remove_sound);
340         } else if (!slide.hasVideo()) {
341             if (MmsConfig.getAllowAttachAudio()) {
342                 SubMenu subMenu = menu.addSubMenu(0, MENU_SUB_AUDIO, 0, R.string.add_music)
343                     .setIcon(R.drawable.ic_menu_add_sound);
344                 subMenu.add(0, MENU_ADD_AUDIO, 0, R.string.attach_sound);
345                 subMenu.add(0, MENU_RECORD_SOUND, 0, R.string.attach_record_sound);
346             } else {
347                 menu.add(0, MENU_RECORD_SOUND, 0, R.string.attach_record_sound)
348                     .setIcon(R.drawable.ic_menu_add_sound);
349             }
350         }
351 
352         // Video
353         if (slide.hasVideo()) {
354             menu.add(0, MENU_DEL_VIDEO, 0, R.string.remove_video).setIcon(
355                     R.drawable.ic_menu_remove_video);
356         } else if (!slide.hasAudio() && !slide.hasImage()) {
357             menu.add(0, MENU_ADD_VIDEO, 0, R.string.add_video).setIcon(R.drawable.ic_menu_movie);
358         }
359 
360         // Add slide
361         menu.add(0, MENU_ADD_SLIDE, 0, R.string.add_slide).setIcon(
362                 R.drawable.ic_menu_add_slide);
363 
364         // Slide duration
365         String duration = getResources().getString(R.string.duration_sec);
366         menu.add(0, MENU_DURATION, 0,
367                 duration.replace("%s", String.valueOf(slide.getDuration() / 1000))).setIcon(
368                         R.drawable.ic_menu_duration);
369 
370         // Slide layout
371         int resId;
372         if (mSlideshowModel.getLayout().getLayoutType() == LayoutModel.LAYOUT_TOP_TEXT) {
373             resId = R.string.layout_top;
374         } else {
375             resId = R.string.layout_bottom;
376         }
377         // FIXME: set correct icon when layout icon is available.
378         menu.add(0, MENU_LAYOUT, 0, resId).setIcon(R.drawable.ic_menu_picture);
379         return true;
380     }
381 
382     @Override
onOptionsItemSelected(MenuItem item)383     public boolean onOptionsItemSelected(MenuItem item) {
384         switch (item.getItemId()) {
385             case MENU_PREVIEW_SLIDESHOW:
386                 previewSlideshow();
387                 break;
388 
389             case MENU_REMOVE_TEXT:
390                 SlideModel slide = mSlideshowModel.get(mPosition);
391                 slide.removeText();
392                 break;
393 
394             case MENU_ADD_PICTURE:
395                 Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
396                 intent.setType(ContentType.IMAGE_UNSPECIFIED);
397                 startActivityForResult(intent, REQUEST_CODE_CHANGE_PICTURE);
398                 break;
399 
400             case MENU_TAKE_PICTURE:
401                 intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
402                 startActivityForResult(intent, REQUEST_CODE_TAKE_PICTURE);
403                 break;
404 
405             case MENU_DEL_PICTURE:
406                 mSlideshowEditor.removeImage(mPosition);
407                 setReplaceButtonText(R.string.add_picture);
408                 break;
409 
410             case MENU_ADD_AUDIO:
411                 MessageUtils.selectAudio(this, REQUEST_CODE_CHANGE_MUSIC);
412                 break;
413 
414             case MENU_RECORD_SOUND:
415                 MessageUtils.recordSound(this, REQUEST_CODE_RECORD_SOUND);
416                 break;
417 
418             case MENU_DEL_AUDIO:
419                 mSlideshowEditor.removeAudio(mPosition);
420                 break;
421 
422             case MENU_ADD_VIDEO:
423                 intent = new Intent(Intent.ACTION_GET_CONTENT);
424                 intent.setType(ContentType.VIDEO_UNSPECIFIED);
425                 startActivityForResult(intent, REQUEST_CODE_CHANGE_VIDEO);
426                 break;
427 
428             case MENU_DEL_VIDEO:
429                 mSlideshowEditor.removeVideo(mPosition);
430                 break;
431 
432             case MENU_ADD_SLIDE:
433                 mPosition++;
434                 if ( mSlideshowEditor.addNewSlide(mPosition) ) {
435                     // add successfully
436                     showCurrentSlide();
437                 } else {
438                     // move position back
439                     mPosition--;
440                     Toast.makeText(this, R.string.cannot_add_slide_anymore,
441                             Toast.LENGTH_SHORT).show();
442                 }
443                 break;
444 
445             case MENU_LAYOUT:
446                 showLayoutSelectorDialog();
447                 break;
448 
449             case MENU_DURATION:
450                 showDurationDialog();
451                 break;
452         }
453 
454         return true;
455     }
456 
setReplaceButtonText(int text)457     private void setReplaceButtonText(int text) {
458         mReplaceImage.setText(text);
459     }
460 
showDurationDialog()461     private void showDurationDialog() {
462         AlertDialog.Builder builder = new AlertDialog.Builder(this);
463         builder.setIcon(R.drawable.ic_mms_duration);
464         String title = getResources().getString(R.string.duration_selector_title);
465         builder.setTitle(title + (mPosition + 1) + "/" + mSlideshowModel.size());
466 
467         builder.setItems(R.array.select_dialog_items,
468                 new DialogInterface.OnClickListener() {
469             public void onClick(DialogInterface dialog, int which) {
470                 if ((which >= 0) && (which < NUM_DIRECT_DURATIONS)) {
471                     mSlideshowEditor.changeDuration(
472                             mPosition, (which + 1) * 1000);
473                 } else {
474                     Intent intent = new Intent(SlideEditorActivity.this,
475                             EditSlideDurationActivity.class);
476                     intent.putExtra(EditSlideDurationActivity.SLIDE_INDEX, mPosition);
477                     intent.putExtra(EditSlideDurationActivity.SLIDE_TOTAL,
478                             mSlideshowModel.size());
479                     intent.putExtra(EditSlideDurationActivity.SLIDE_DUR,
480                             mSlideshowModel.get(mPosition).getDuration() / 1000); // in seconds
481                     startActivityForResult(intent, REQUEST_CODE_CHANGE_DURATION);
482                 }
483             }
484         });
485 
486         builder.show();
487     }
488 
showLayoutSelectorDialog()489     private void showLayoutSelectorDialog() {
490         AlertDialog.Builder builder = new AlertDialog.Builder(this);
491         builder.setIcon(R.drawable.ic_mms_layout);
492 
493         String title = getResources().getString(R.string.layout_selector_title);
494         builder.setTitle(title + (mPosition + 1) + "/" + mSlideshowModel.size());
495 
496         LayoutSelectorAdapter adapter = new LayoutSelectorAdapter(this);
497         builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
498             public void onClick(DialogInterface dialog, int which) {
499                 switch (which) {
500                     case 0: // Top text.
501                         mSlideshowEditor.changeLayout(LayoutModel.LAYOUT_TOP_TEXT);
502                         break;
503                     case 1: // Bottom text.
504                         mSlideshowEditor.changeLayout(LayoutModel.LAYOUT_BOTTOM_TEXT);
505                         break;
506                 }
507             }
508         });
509 
510         builder.show();
511     }
512 
513     @Override
onActivityResult(int requestCode, int resultCode, Intent data)514     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
515         if (resultCode != RESULT_OK) {
516             return;
517         }
518 
519         switch(requestCode) {
520             case REQUEST_CODE_EDIT_TEXT:
521                 // XXX where does this come from?  Action is probably not the
522                 // right place to have the text...
523                 mSlideshowEditor.changeText(mPosition, data.getAction());
524                 break;
525 
526             case REQUEST_CODE_TAKE_PICTURE:
527                 Bitmap bitmap = (Bitmap) data.getParcelableExtra("data");
528                 if (bitmap == null) {
529                     Toast.makeText(this,
530                             getResourcesString(R.string.failed_to_add_media, getPictureString()),
531                             Toast.LENGTH_SHORT).show();
532                     return;
533                 }
534 
535                 try {
536                     mSlideshowEditor.changeImage(mPosition,
537                             MessageUtils.saveBitmapAsPart(this, mUri, bitmap));
538 
539                     setReplaceButtonText(R.string.replace_image);
540                 } catch (MmsException e) {
541                     Log.e(TAG, "add image failed", e);
542                     notifyUser("add picture failed");
543                     Toast.makeText(SlideEditorActivity.this,
544                             getResourcesString(R.string.failed_to_add_media, getPictureString()),
545                             Toast.LENGTH_SHORT).show();
546                 } catch (UnsupportContentTypeException e) {
547                     MessageUtils.showErrorDialog(SlideEditorActivity.this,
548                             getResourcesString(R.string.unsupported_media_format, getPictureString()),
549                             getResourcesString(R.string.select_different_media, getPictureString()));
550                 } catch (ResolutionException e) {
551                     MessageUtils.resizeImageAsync(this, data.getData(), new Handler(),
552                             mResizeImageCallback, false);
553                 } catch (ExceedMessageSizeException e) {
554                     MessageUtils.resizeImageAsync(this, data.getData(), new Handler(),
555                             mResizeImageCallback, false);
556                 }
557                 break;
558 
559             case REQUEST_CODE_CHANGE_PICTURE:
560                 try {
561                     mSlideshowEditor.changeImage(mPosition, data.getData());
562                     setReplaceButtonText(R.string.replace_image);
563                 } catch (MmsException e) {
564                     Log.e(TAG, "add image failed", e);
565                     notifyUser("add picture failed");
566                     Toast.makeText(SlideEditorActivity.this,
567                             getResourcesString(R.string.failed_to_add_media, getPictureString()),
568                             Toast.LENGTH_SHORT).show();
569                 } catch (UnsupportContentTypeException e) {
570                     MessageUtils.showErrorDialog(SlideEditorActivity.this,
571                             getResourcesString(R.string.unsupported_media_format, getPictureString()),
572                             getResourcesString(R.string.select_different_media, getPictureString()));
573                 } catch (ResolutionException e) {
574                     MessageUtils.resizeImageAsync(this, data.getData(), new Handler(),
575                             mResizeImageCallback, false);
576                 } catch (ExceedMessageSizeException e) {
577                     MessageUtils.resizeImageAsync(this, data.getData(), new Handler(),
578                             mResizeImageCallback, false);
579                 }
580                 break;
581 
582             case REQUEST_CODE_CHANGE_MUSIC:
583             case REQUEST_CODE_RECORD_SOUND:
584                 Uri uri;
585                 if (requestCode == REQUEST_CODE_CHANGE_MUSIC) {
586                     uri = (Uri) data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
587                     if (Settings.System.DEFAULT_RINGTONE_URI.equals(uri)) {
588                         return;
589                     }
590                 } else {
591                     uri = data.getData();
592                 }
593 
594                 try {
595                     mSlideshowEditor.changeAudio(mPosition, uri);
596                 } catch (MmsException e) {
597                     Log.e(TAG, "add audio failed", e);
598                     notifyUser("add music failed");
599                     Toast.makeText(SlideEditorActivity.this,
600                             getResourcesString(R.string.failed_to_add_media, getAudioString()),
601                             Toast.LENGTH_SHORT).show();
602                 } catch (UnsupportContentTypeException e) {
603                     MessageUtils.showErrorDialog(SlideEditorActivity.this,
604                             getResourcesString(R.string.unsupported_media_format, getAudioString()),
605                             getResourcesString(R.string.select_different_media, getAudioString()));
606                 } catch (ExceedMessageSizeException e) {
607                     MessageUtils.showErrorDialog(SlideEditorActivity.this,
608                             getResourcesString(R.string.exceed_message_size_limitation),
609                             getResourcesString(R.string.failed_to_add_media, getAudioString()));
610                 }
611                 break;
612 
613             case REQUEST_CODE_CHANGE_VIDEO:
614                 try {
615                     mSlideshowEditor.changeVideo(mPosition, data.getData());
616                 } catch (MmsException e) {
617                     Log.e(TAG, "add video failed", e);
618                     notifyUser("add video failed");
619                     Toast.makeText(SlideEditorActivity.this,
620                             getResourcesString(R.string.failed_to_add_media, getVideoString()),
621                             Toast.LENGTH_SHORT).show();
622                 } catch (UnsupportContentTypeException e) {
623                     MessageUtils.showErrorDialog(SlideEditorActivity.this,
624                             getResourcesString(R.string.unsupported_media_format, getVideoString()),
625                             getResourcesString(R.string.select_different_media, getVideoString()));
626                 } catch (ExceedMessageSizeException e) {
627                     MessageUtils.showErrorDialog(SlideEditorActivity.this,
628                             getResourcesString(R.string.exceed_message_size_limitation),
629                             getResourcesString(R.string.failed_to_add_media, getVideoString()));
630                 }
631                 break;
632 
633             case REQUEST_CODE_CHANGE_DURATION:
634                 mSlideshowEditor.changeDuration(mPosition,
635                     Integer.valueOf(data.getAction()) * 1000);
636                 break;
637         }
638     }
639 
640     private final ResizeImageResultCallback mResizeImageCallback = new ResizeImageResultCallback() {
641         public void onResizeResult(PduPart part, boolean append) {
642             Context context = SlideEditorActivity.this;
643             if (part == null) {
644                 Toast.makeText(SlideEditorActivity.this,
645                         getResourcesString(R.string.failed_to_add_media, getPictureString()),
646                         Toast.LENGTH_SHORT).show();
647                 return;
648             }
649 
650             try {
651                 long messageId = ContentUris.parseId(mUri);
652                 PduPersister persister = PduPersister.getPduPersister(context);
653                 Uri newUri = persister.persistPart(part, messageId);
654                 mSlideshowEditor.changeImage(mPosition, newUri);
655 
656                 setReplaceButtonText(R.string.replace_image);
657             } catch (MmsException e) {
658                 notifyUser("add picture failed");
659                 Toast.makeText(SlideEditorActivity.this,
660                         getResourcesString(R.string.failed_to_add_media, getPictureString()),
661                         Toast.LENGTH_SHORT).show();
662             } catch (UnsupportContentTypeException e) {
663                 MessageUtils.showErrorDialog(SlideEditorActivity.this,
664                         getResourcesString(R.string.unsupported_media_format, getPictureString()),
665                         getResourcesString(R.string.select_different_media, getPictureString()));
666             } catch (ResolutionException e) {
667                 MessageUtils.showErrorDialog(SlideEditorActivity.this,
668                         getResourcesString(R.string.failed_to_resize_image),
669                         getResourcesString(R.string.resize_image_error_information));
670             } catch (ExceedMessageSizeException e) {
671                 MessageUtils.showErrorDialog(SlideEditorActivity.this,
672                         getResourcesString(R.string.exceed_message_size_limitation),
673                         getResourcesString(R.string.failed_to_add_media, getPictureString()));
674             }
675         }
676     };
677 
getResourcesString(int id, String mediaName)678     private String getResourcesString(int id, String mediaName) {
679         Resources r = getResources();
680         return r.getString(id, mediaName);
681     }
682 
getResourcesString(int id)683     private String getResourcesString(int id) {
684         Resources r = getResources();
685         return r.getString(id);
686     }
687 
getAudioString()688     private String getAudioString() {
689         return getResourcesString(R.string.type_audio);
690     }
691 
getPictureString()692     private String getPictureString() {
693         return getResourcesString(R.string.type_picture);
694     }
695 
getVideoString()696     private String getVideoString() {
697         return getResourcesString(R.string.type_video);
698     }
699 
notifyUser(String message)700     private void notifyUser(String message) {
701         if (LOCAL_LOGV) {
702             Log.v(TAG, "notifyUser: message=" + message);
703         }
704     }
705 
showCurrentSlide()706     private void showCurrentSlide() {
707         mPresenter.setLocation(mPosition);
708         mPresenter.present();
709         updateTitle();
710 
711         if (mSlideshowModel.get(mPosition).hasImage()) {
712             setReplaceButtonText(R.string.replace_image);
713         } else {
714             setReplaceButtonText(R.string.add_picture);
715         }
716     }
717 }
718