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