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