SlideEditorActivity.java revision 47471dad88703d5befcbf65abd9e0cf28872bcb3
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
18package com.android.mms.ui;
19
20import com.google.android.mms.ContentType;
21import com.android.mms.ExceedMessageSizeException;
22import com.google.android.mms.MmsException;
23import com.android.mms.MmsConfig;
24import com.android.mms.R;
25import com.android.mms.ResolutionException;
26import com.android.mms.UnsupportContentTypeException;
27import com.android.mms.model.IModelChangedObserver;
28import com.android.mms.model.LayoutModel;
29import com.android.mms.model.Model;
30import com.android.mms.model.SlideModel;
31import com.android.mms.model.SlideshowModel;
32import com.google.android.mms.pdu.PduBody;
33import com.google.android.mms.pdu.PduPart;
34import com.google.android.mms.pdu.PduPersister;
35import com.android.mms.ui.BasicSlideEditorView.OnTextChangedListener;
36import com.android.mms.ui.MessageUtils.ResizeImageResultCallback;
37
38import android.app.Activity;
39import android.app.AlertDialog;
40import android.content.ContentUris;
41import android.content.Context;
42import android.content.DialogInterface;
43import android.content.Intent;
44import android.content.res.Resources;
45import android.graphics.Bitmap;
46import android.media.RingtoneManager;
47import android.net.Uri;
48import android.os.Bundle;
49import android.os.Handler;
50import android.provider.MediaStore;
51import android.provider.Settings;
52import android.text.TextUtils;
53import android.util.Config;
54import android.util.Log;
55import android.view.Menu;
56import android.view.MenuItem;
57import android.view.SubMenu;
58import android.view.View;
59import android.view.View.OnClickListener;
60import android.widget.Button;
61import android.widget.ImageButton;
62import android.widget.Toast;
63
64/**
65 * This activity allows user to edit the contents of a slide.
66 */
67public 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
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
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
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
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
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
300    private void previewSlideshow() {
301        MessageUtils.viewMmsMessageAttachment(SlideEditorActivity.this, mUri, mSlideshowModel);
302    }
303
304    private void updateTitle() {
305        setTitle(getString(R.string.slide_show_part, (mPosition + 1), mSlideshowModel.size()));
306    }
307
308    @Override
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
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
457    private void setReplaceButtonText(int text) {
458        mReplaceImage.setText(text);
459    }
460
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
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
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
678    private String getResourcesString(int id, String mediaName) {
679        Resources r = getResources();
680        return r.getString(id, mediaName);
681    }
682
683    private String getResourcesString(int id) {
684        Resources r = getResources();
685        return r.getString(id);
686    }
687
688    private String getAudioString() {
689        return getResourcesString(R.string.type_audio);
690    }
691
692    private String getPictureString() {
693        return getResourcesString(R.string.type_picture);
694    }
695
696    private String getVideoString() {
697        return getResourcesString(R.string.type_video);
698    }
699
700    private void notifyUser(String message) {
701        if (LOCAL_LOGV) {
702            Log.v(TAG, "notifyUser: message=" + message);
703        }
704    }
705
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