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