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