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