PhotoPage.java revision 61f94714c3702115d2f89bb5f8829697be0c3680
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.gallery3d.app; 18 19import android.app.ActionBar.OnMenuVisibilityListener; 20import android.app.Activity; 21import android.content.ActivityNotFoundException; 22import android.content.Context; 23import android.content.Intent; 24import android.graphics.Rect; 25import android.net.Uri; 26import android.nfc.NfcAdapter; 27import android.os.Bundle; 28import android.os.Handler; 29import android.os.Message; 30import android.view.Menu; 31import android.view.MenuInflater; 32import android.view.MenuItem; 33import android.view.View; 34import android.view.WindowManager; 35import android.widget.ShareActionProvider; 36import android.widget.Toast; 37 38import com.android.gallery3d.R; 39import com.android.gallery3d.data.DataManager; 40import com.android.gallery3d.data.MediaDetails; 41import com.android.gallery3d.data.MediaItem; 42import com.android.gallery3d.data.MediaObject; 43import com.android.gallery3d.data.MediaSet; 44import com.android.gallery3d.data.MtpDevice; 45import com.android.gallery3d.data.Path; 46import com.android.gallery3d.data.SnailSource; 47import com.android.gallery3d.picasasource.PicasaSource; 48import com.android.gallery3d.ui.DetailsHelper; 49import com.android.gallery3d.ui.DetailsHelper.CloseListener; 50import com.android.gallery3d.ui.DetailsHelper.DetailsSource; 51import com.android.gallery3d.ui.GLCanvas; 52import com.android.gallery3d.ui.GLView; 53import com.android.gallery3d.ui.ImportCompleteListener; 54import com.android.gallery3d.ui.MenuExecutor; 55import com.android.gallery3d.ui.PhotoView; 56import com.android.gallery3d.ui.ScreenNail; 57import com.android.gallery3d.ui.SelectionManager; 58import com.android.gallery3d.ui.SynchronizedHandler; 59import com.android.gallery3d.util.GalleryUtils; 60 61public class PhotoPage extends ActivityState implements 62 PhotoView.Listener, OrientationManager.Listener, AppBridge.Server { 63 private static final String TAG = "PhotoPage"; 64 65 private static final int MSG_HIDE_BARS = 1; 66 private static final int MSG_LOCK_ORIENTATION = 2; 67 private static final int MSG_UNLOCK_ORIENTATION = 3; 68 private static final int MSG_ON_FULL_SCREEN_CHANGED = 4; 69 private static final int MSG_UPDATE_ACTION_BAR = 5; 70 71 private static final int HIDE_BARS_TIMEOUT = 3500; 72 73 private static final int REQUEST_SLIDESHOW = 1; 74 private static final int REQUEST_CROP = 2; 75 private static final int REQUEST_CROP_PICASA = 3; 76 private static final int REQUEST_EDIT = 4; 77 78 public static final String KEY_MEDIA_SET_PATH = "media-set-path"; 79 public static final String KEY_MEDIA_ITEM_PATH = "media-item-path"; 80 public static final String KEY_INDEX_HINT = "index-hint"; 81 public static final String KEY_OPEN_ANIMATION_RECT = "open-animation-rect"; 82 public static final String KEY_APP_BRIDGE = "app-bridge"; 83 84 public static final String KEY_RETURN_INDEX_HINT = "return-index-hint"; 85 86 private GalleryApp mApplication; 87 private SelectionManager mSelectionManager; 88 89 private PhotoView mPhotoView; 90 private PhotoPage.Model mModel; 91 private DetailsHelper mDetailsHelper; 92 private boolean mShowDetails; 93 private Path mPendingSharePath; 94 95 // mMediaSet could be null if there is no KEY_MEDIA_SET_PATH supplied. 96 // E.g., viewing a photo in gmail attachment 97 private MediaSet mMediaSet; 98 private Menu mMenu; 99 100 private int mCurrentIndex = 0; 101 private Handler mHandler; 102 private boolean mShowBars = true; 103 private volatile boolean mActionBarAllowed = true; 104 private GalleryActionBar mActionBar; 105 private MyMenuVisibilityListener mMenuVisibilityListener; 106 private boolean mIsMenuVisible; 107 private MediaItem mCurrentPhoto = null; 108 private MenuExecutor mMenuExecutor; 109 private boolean mIsActive; 110 private ShareActionProvider mShareActionProvider; 111 private String mSetPathString; 112 // This is the original mSetPathString before adding the camera preview item. 113 private String mOriginalSetPathString; 114 private AppBridge mAppBridge; 115 private ScreenNail mScreenNail; 116 private MediaItem mScreenNailItem; 117 private OrientationManager mOrientationManager; 118 119 private NfcAdapter mNfcAdapter; 120 121 public static interface Model extends PhotoView.Model { 122 public void resume(); 123 public void pause(); 124 public boolean isEmpty(); 125 public MediaItem getCurrentMediaItem(); 126 public void setCurrentPhoto(Path path, int indexHint); 127 } 128 129 private class MyMenuVisibilityListener implements OnMenuVisibilityListener { 130 @Override 131 public void onMenuVisibilityChanged(boolean isVisible) { 132 mIsMenuVisible = isVisible; 133 refreshHidingMessage(); 134 } 135 } 136 137 private final GLView mRootPane = new GLView() { 138 139 @Override 140 protected void renderBackground(GLCanvas view) { 141 view.clearBuffer(); 142 } 143 144 @Override 145 protected void onLayout( 146 boolean changed, int left, int top, int right, int bottom) { 147 mPhotoView.layout(0, 0, right - left, bottom - top); 148 if (mShowDetails) { 149 mDetailsHelper.layout(left, mActionBar.getHeight(), right, bottom); 150 } 151 } 152 153 @Override 154 protected void orient(int displayRotation, int compensation) { 155 displayRotation = mOrientationManager.getDisplayRotation(); 156 Log.d(TAG, "orient -- display rotation " + displayRotation 157 + ", compensation = " + compensation); 158 super.orient(displayRotation, compensation); 159 } 160 }; 161 162 @Override 163 public void onCreate(Bundle data, Bundle restoreState) { 164 mActionBar = mActivity.getGalleryActionBar(); 165 mSelectionManager = new SelectionManager(mActivity, false); 166 mMenuExecutor = new MenuExecutor(mActivity, mSelectionManager); 167 168 mPhotoView = new PhotoView(mActivity); 169 mPhotoView.setListener(this); 170 mRootPane.addComponent(mPhotoView); 171 mApplication = (GalleryApp)((Activity) mActivity).getApplication(); 172 mOrientationManager = mActivity.getOrientationManager(); 173 mOrientationManager.addListener(this); 174 175 mSetPathString = data.getString(KEY_MEDIA_SET_PATH); 176 mOriginalSetPathString = mSetPathString; 177 mNfcAdapter = NfcAdapter.getDefaultAdapter(mActivity.getAndroidContext()); 178 Path itemPath = Path.fromString(data.getString(KEY_MEDIA_ITEM_PATH)); 179 180 if (mSetPathString != null) { 181 mAppBridge = (AppBridge) data.getParcelable(KEY_APP_BRIDGE); 182 if (mAppBridge != null) { 183 mOrientationManager.lockOrientation(); 184 185 // Get the ScreenNail from AppBridge and register it. 186 mScreenNail = mAppBridge.attachScreenNail(); 187 int id = SnailSource.registerScreenNail(mScreenNail); 188 Path screenNailSetPath = SnailSource.getSetPath(id); 189 Path screenNailItemPath = SnailSource.getItemPath(id); 190 mScreenNailItem = (MediaItem) mActivity.getDataManager() 191 .getMediaObject(screenNailItemPath); 192 193 // Combine the original MediaSet with the one for CameraScreenNail. 194 mSetPathString = "/combo/item/{" + screenNailSetPath + 195 "," + mSetPathString + "}"; 196 197 // Start from the screen nail. 198 itemPath = screenNailItemPath; 199 200 // Action bar should not be displayed when camera starts. 201 mFlags |= FLAG_HIDE_ACTION_BAR; 202 mShowBars = false; 203 } 204 205 mMediaSet = mActivity.getDataManager().getMediaSet(mSetPathString); 206 mCurrentIndex = data.getInt(KEY_INDEX_HINT, 0); 207 if (mMediaSet == null) { 208 Log.w(TAG, "failed to restore " + mSetPathString); 209 } 210 PhotoDataAdapter pda = new PhotoDataAdapter( 211 mActivity, mPhotoView, mMediaSet, itemPath, mCurrentIndex, 212 mAppBridge == null ? -1 : 0); 213 mModel = pda; 214 mPhotoView.setModel(mModel); 215 216 pda.setDataListener(new PhotoDataAdapter.DataListener() { 217 218 @Override 219 public void onPhotoChanged(int index, Path item) { 220 mCurrentIndex = index; 221 if (item != null) { 222 MediaItem photo = mModel.getCurrentMediaItem(); 223 if (photo != null) updateCurrentPhoto(photo); 224 } 225 updateBars(); 226 } 227 228 @Override 229 public void onLoadingFinished() { 230 GalleryUtils.setSpinnerVisibility((Activity) mActivity, false); 231 if (!mModel.isEmpty()) { 232 MediaItem photo = mModel.getCurrentMediaItem(); 233 if (photo != null) updateCurrentPhoto(photo); 234 } else if (mIsActive) { 235 mActivity.getStateManager().finishState(PhotoPage.this); 236 } 237 } 238 239 @Override 240 public void onLoadingStarted() { 241 GalleryUtils.setSpinnerVisibility((Activity) mActivity, true); 242 } 243 }); 244 } else { 245 // Get default media set by the URI 246 MediaItem mediaItem = (MediaItem) 247 mActivity.getDataManager().getMediaObject(itemPath); 248 mModel = new SinglePhotoDataAdapter(mActivity, mPhotoView, mediaItem); 249 mPhotoView.setModel(mModel); 250 updateCurrentPhoto(mediaItem); 251 } 252 253 mHandler = new SynchronizedHandler(mActivity.getGLRoot()) { 254 @Override 255 public void handleMessage(Message message) { 256 switch (message.what) { 257 case MSG_HIDE_BARS: { 258 hideBars(); 259 break; 260 } 261 case MSG_LOCK_ORIENTATION: { 262 mOrientationManager.lockOrientation(); 263 break; 264 } 265 case MSG_UNLOCK_ORIENTATION: { 266 mOrientationManager.unlockOrientation(); 267 break; 268 } 269 case MSG_ON_FULL_SCREEN_CHANGED: { 270 mAppBridge.onFullScreenChanged(message.arg1 == 1); 271 break; 272 } 273 case MSG_UPDATE_ACTION_BAR: { 274 updateBars(); 275 break; 276 } 277 default: throw new AssertionError(message.what); 278 } 279 } 280 }; 281 282 // start the opening animation only if it's not restored. 283 if (restoreState == null) { 284 mPhotoView.setOpenAnimationRect((Rect) data.getParcelable(KEY_OPEN_ANIMATION_RECT)); 285 } 286 } 287 288 private void updateShareURI(Path path) { 289 if (mShareActionProvider != null) { 290 DataManager manager = mActivity.getDataManager(); 291 int type = manager.getMediaType(path); 292 Intent intent = new Intent(Intent.ACTION_SEND); 293 intent.setType(MenuExecutor.getMimeType(type)); 294 intent.putExtra(Intent.EXTRA_STREAM, manager.getContentUri(path)); 295 mShareActionProvider.setShareIntent(intent); 296 if (mNfcAdapter != null) { 297 mNfcAdapter.setBeamPushUris(new Uri[]{manager.getContentUri(path)}, 298 (Activity)mActivity); 299 } 300 mPendingSharePath = null; 301 } else { 302 // This happens when ActionBar is not created yet. 303 mPendingSharePath = path; 304 } 305 } 306 307 private void updateCurrentPhoto(MediaItem photo) { 308 if (mCurrentPhoto == photo) return; 309 mCurrentPhoto = photo; 310 if (mCurrentPhoto == null) return; 311 updateMenuOperations(); 312 updateTitle(); 313 if (mShowDetails) { 314 mDetailsHelper.reloadDetails(mModel.getCurrentIndex()); 315 } 316 mPhotoView.showVideoPlayIcon( 317 photo.getMediaType() == MediaObject.MEDIA_TYPE_VIDEO); 318 319 if ((photo.getSupportedOperations() & MediaItem.SUPPORT_SHARE) != 0) { 320 updateShareURI(photo.getPath()); 321 } 322 } 323 324 private void updateTitle() { 325 if (mCurrentPhoto == null) return; 326 boolean showTitle = mActivity.getAndroidContext().getResources().getBoolean( 327 R.bool.show_action_bar_title); 328 if (showTitle && mCurrentPhoto.getName() != null) 329 mActionBar.setTitle(mCurrentPhoto.getName()); 330 else 331 mActionBar.setTitle(""); 332 } 333 334 private void updateMenuOperations() { 335 if (mMenu == null) return; 336 MenuItem item = mMenu.findItem(R.id.action_slideshow); 337 if (item != null) { 338 item.setVisible(canDoSlideShow()); 339 } 340 if (mCurrentPhoto == null) return; 341 int supportedOperations = mCurrentPhoto.getSupportedOperations(); 342 if (!GalleryUtils.isEditorAvailable((Context) mActivity, "image/*")) { 343 supportedOperations &= ~MediaObject.SUPPORT_EDIT; 344 } 345 346 MenuExecutor.updateMenuOperation(mMenu, supportedOperations); 347 } 348 349 private boolean canDoSlideShow() { 350 if (mMediaSet == null || mCurrentPhoto == null) { 351 return false; 352 } 353 if (mCurrentPhoto.getMediaType() != MediaObject.MEDIA_TYPE_IMAGE) { 354 return false; 355 } 356 if (mMediaSet instanceof MtpDevice) { 357 return false; 358 } 359 return true; 360 } 361 362 ////////////////////////////////////////////////////////////////////////// 363 // Action Bar show/hide management 364 ////////////////////////////////////////////////////////////////////////// 365 366 private void showBars() { 367 if (mShowBars) return; 368 mShowBars = true; 369 mActionBar.show(); 370 WindowManager.LayoutParams params = 371 ((Activity) mActivity).getWindow().getAttributes(); 372 params.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE; 373 ((Activity) mActivity).getWindow().setAttributes(params); 374 refreshHidingMessage(); 375 } 376 377 private void hideBars() { 378 if (!mShowBars) return; 379 mShowBars = false; 380 mActionBar.hide(); 381 WindowManager.LayoutParams params = 382 ((Activity) mActivity).getWindow().getAttributes(); 383 params.systemUiVisibility = View. SYSTEM_UI_FLAG_LOW_PROFILE; 384 ((Activity) mActivity).getWindow().setAttributes(params); 385 mHandler.removeMessages(MSG_HIDE_BARS); 386 } 387 388 private void refreshHidingMessage() { 389 mHandler.removeMessages(MSG_HIDE_BARS); 390 if (!mIsMenuVisible) { 391 mHandler.sendEmptyMessageDelayed(MSG_HIDE_BARS, HIDE_BARS_TIMEOUT); 392 } 393 } 394 395 private void toggleBars() { 396 if (mShowBars) { 397 hideBars(); 398 } else if (canShowBars()) { 399 showBars(); 400 } 401 } 402 403 private void updateBars() { 404 if (canShowBars()) { 405 showBars(); 406 } else { 407 hideBars(); 408 } 409 } 410 411 private boolean canShowBars() { 412 boolean atCamera = mAppBridge != null && mCurrentIndex == 0; 413 return mActionBarAllowed && !atCamera; 414 } 415 416 @Override 417 public void onOrientationCompensationChanged(int degrees) { 418 mActivity.getGLRoot().setOrientationCompensation(degrees); 419 } 420 421 @Override 422 protected void onBackPressed() { 423 if (mShowDetails) { 424 hideDetails(); 425 } else if (mScreenNail == null 426 || !switchWithCaptureAnimation(-1)) { 427 // We are leaving this page. Set the result now. 428 setResult(); 429 super.onBackPressed(); 430 } 431 } 432 433 private void onUpPressed() { 434 if (mActivity.getStateManager().getStateCount() > 1) { 435 super.onBackPressed(); 436 } else if (mOriginalSetPathString != null) { 437 // We're in view mode so set up the stacks on our own. 438 Bundle data = new Bundle(getData()); 439 data.putString(AlbumPage.KEY_MEDIA_PATH, mOriginalSetPathString); 440 data.putString(AlbumPage.KEY_PARENT_MEDIA_PATH, 441 mActivity.getDataManager().getTopSetPath( 442 DataManager.INCLUDE_ALL)); 443 mActivity.getStateManager().switchState(this, AlbumPage.class, data); 444 } 445 } 446 447 private void setResult() { 448 Intent result = null; 449 if (!mPhotoView.getFilmMode()) { 450 result = new Intent(); 451 result.putExtra(KEY_RETURN_INDEX_HINT, mCurrentIndex); 452 } 453 setStateResult(Activity.RESULT_OK, result); 454 } 455 456 ////////////////////////////////////////////////////////////////////////// 457 // AppBridge.Server interface 458 ////////////////////////////////////////////////////////////////////////// 459 460 @Override 461 public void setCameraNaturalFrame(Rect frame) { 462 mPhotoView.setCameraNaturalFrame(frame); 463 } 464 465 @Override 466 public boolean switchWithCaptureAnimation(int offset) { 467 return mPhotoView.switchWithCaptureAnimation(offset); 468 } 469 470 @Override 471 protected boolean onCreateActionBar(Menu menu) { 472 MenuInflater inflater = ((Activity) mActivity).getMenuInflater(); 473 inflater.inflate(R.menu.photo, menu); 474 mShareActionProvider = GalleryActionBar.initializeShareActionProvider(menu); 475 if (mPendingSharePath != null) updateShareURI(mPendingSharePath); 476 mMenu = menu; 477 updateMenuOperations(); 478 updateTitle(); 479 return true; 480 } 481 482 @Override 483 protected boolean onItemSelected(MenuItem item) { 484 MediaItem current = mModel.getCurrentMediaItem(); 485 486 if (current == null) { 487 // item is not ready, ignore 488 return true; 489 } 490 491 int currentIndex = mModel.getCurrentIndex(); 492 Path path = current.getPath(); 493 494 DataManager manager = mActivity.getDataManager(); 495 int action = item.getItemId(); 496 boolean needsConfirm = false; 497 switch (action) { 498 case android.R.id.home: { 499 onUpPressed(); 500 return true; 501 } 502 case R.id.action_slideshow: { 503 Bundle data = new Bundle(); 504 data.putString(SlideshowPage.KEY_SET_PATH, mMediaSet.getPath().toString()); 505 data.putString(SlideshowPage.KEY_ITEM_PATH, path.toString()); 506 data.putInt(SlideshowPage.KEY_PHOTO_INDEX, currentIndex); 507 data.putBoolean(SlideshowPage.KEY_REPEAT, true); 508 mActivity.getStateManager().startStateForResult( 509 SlideshowPage.class, REQUEST_SLIDESHOW, data); 510 return true; 511 } 512 case R.id.action_crop: { 513 Activity activity = (Activity) mActivity; 514 Intent intent = new Intent(CropImage.CROP_ACTION); 515 intent.setClass(activity, CropImage.class); 516 intent.setData(manager.getContentUri(path)); 517 activity.startActivityForResult(intent, PicasaSource.isPicasaImage(current) 518 ? REQUEST_CROP_PICASA 519 : REQUEST_CROP); 520 return true; 521 } 522 case R.id.action_edit: { 523 Intent intent = new Intent(Intent.ACTION_EDIT) 524 .setData(manager.getContentUri(path)) 525 .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 526 ((Activity) mActivity).startActivityForResult(Intent.createChooser(intent, null), 527 REQUEST_EDIT); 528 return true; 529 } 530 case R.id.action_details: { 531 if (mShowDetails) { 532 hideDetails(); 533 } else { 534 showDetails(currentIndex); 535 } 536 return true; 537 } 538 case R.id.action_delete: 539 needsConfirm = true; 540 case R.id.action_setas: 541 case R.id.action_rotate_ccw: 542 case R.id.action_rotate_cw: 543 case R.id.action_show_on_map: 544 mSelectionManager.deSelectAll(); 545 mSelectionManager.toggle(path); 546 mMenuExecutor.onMenuClicked(item, needsConfirm, null); 547 return true; 548 case R.id.action_import: 549 mSelectionManager.deSelectAll(); 550 mSelectionManager.toggle(path); 551 mMenuExecutor.onMenuClicked(item, needsConfirm, 552 new ImportCompleteListener(mActivity)); 553 return true; 554 default : 555 return false; 556 } 557 } 558 559 private void hideDetails() { 560 mShowDetails = false; 561 mDetailsHelper.hide(); 562 } 563 564 private void showDetails(int index) { 565 mShowDetails = true; 566 if (mDetailsHelper == null) { 567 mDetailsHelper = new DetailsHelper(mActivity, mRootPane, new MyDetailsSource()); 568 mDetailsHelper.setCloseListener(new CloseListener() { 569 @Override 570 public void onClose() { 571 hideDetails(); 572 } 573 }); 574 } 575 mDetailsHelper.reloadDetails(index); 576 mDetailsHelper.show(); 577 } 578 579 //////////////////////////////////////////////////////////////////////////// 580 // Callbacks from PhotoView 581 //////////////////////////////////////////////////////////////////////////// 582 @Override 583 public void onSingleTapUp(int x, int y) { 584 if (mAppBridge != null) { 585 if (mAppBridge.onSingleTapUp(x, y)) return; 586 } 587 588 MediaItem item = mModel.getCurrentMediaItem(); 589 if (item == null || item == mScreenNailItem) { 590 // item is not ready or it is camera preview, ignore 591 return; 592 } 593 594 boolean playVideo = 595 (item.getSupportedOperations() & MediaItem.SUPPORT_PLAY) != 0; 596 597 if (playVideo) { 598 // determine if the point is at center (1/6) of the photo view. 599 // (The position of the "play" icon is at center (1/6) of the photo) 600 int w = mPhotoView.getWidth(); 601 int h = mPhotoView.getHeight(); 602 playVideo = (Math.abs(x - w / 2) * 12 <= w) 603 && (Math.abs(y - h / 2) * 12 <= h); 604 } 605 606 if (playVideo) { 607 playVideo((Activity) mActivity, item.getPlayUri(), item.getName()); 608 } else { 609 toggleBars(); 610 } 611 } 612 613 @Override 614 public void lockOrientation() { 615 mHandler.sendEmptyMessage(MSG_LOCK_ORIENTATION); 616 } 617 618 @Override 619 public void unlockOrientation() { 620 mHandler.sendEmptyMessage(MSG_UNLOCK_ORIENTATION); 621 } 622 623 @Override 624 public void onActionBarAllowed(boolean allowed) { 625 mActionBarAllowed = allowed; 626 mHandler.sendEmptyMessage(MSG_UPDATE_ACTION_BAR); 627 } 628 629 @Override 630 public void onFullScreenChanged(boolean full) { 631 Message m = mHandler.obtainMessage( 632 MSG_ON_FULL_SCREEN_CHANGED, full ? 1 : 0, 0); 633 m.sendToTarget(); 634 } 635 636 public static void playVideo(Activity activity, Uri uri, String title) { 637 try { 638 Intent intent = new Intent(Intent.ACTION_VIEW) 639 .setDataAndType(uri, "video/*"); 640 intent.putExtra(Intent.EXTRA_TITLE, title); 641 activity.startActivity(intent); 642 } catch (ActivityNotFoundException e) { 643 Toast.makeText(activity, activity.getString(R.string.video_err), 644 Toast.LENGTH_SHORT).show(); 645 } 646 } 647 648 private void setCurrentPhotoByIntent(Intent intent) { 649 if (intent == null) return; 650 Path path = mApplication.getDataManager() 651 .findPathByUri(intent.getData(), intent.getType()); 652 if (path != null) { 653 mModel.setCurrentPhoto(path, mCurrentIndex); 654 } 655 } 656 657 @Override 658 protected void onStateResult(int requestCode, int resultCode, Intent data) { 659 switch (requestCode) { 660 case REQUEST_EDIT: 661 setCurrentPhotoByIntent(data); 662 break; 663 case REQUEST_CROP: 664 if (resultCode == Activity.RESULT_OK) { 665 setCurrentPhotoByIntent(data); 666 } 667 break; 668 case REQUEST_CROP_PICASA: { 669 if (resultCode == Activity.RESULT_OK) { 670 Context context = mActivity.getAndroidContext(); 671 // TODO: Use crop_saved instead of photo_saved after its new translation is done. 672 String message = context.getString(R.string.photo_saved, 673 context.getString(R.string.folder_download)); 674 Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); 675 } 676 break; 677 } 678 case REQUEST_SLIDESHOW: { 679 if (data == null) break; 680 String path = data.getStringExtra(SlideshowPage.KEY_ITEM_PATH); 681 int index = data.getIntExtra(SlideshowPage.KEY_PHOTO_INDEX, 0); 682 if (path != null) { 683 mModel.setCurrentPhoto(Path.fromString(path), index); 684 } 685 } 686 } 687 } 688 689 @Override 690 public void onPause() { 691 super.onPause(); 692 mIsActive = false; 693 if (mAppBridge != null) mAppBridge.setServer(null); 694 DetailsHelper.pause(); 695 mPhotoView.pause(); 696 mModel.pause(); 697 mHandler.removeMessages(MSG_HIDE_BARS); 698 mActionBar.removeOnMenuVisibilityListener(mMenuVisibilityListener); 699 700 mMenuExecutor.pause(); 701 } 702 703 @Override 704 protected void onResume() { 705 super.onResume(); 706 mIsActive = true; 707 setContentPane(mRootPane); 708 709 mModel.resume(); 710 mPhotoView.resume(); 711 if (mMenuVisibilityListener == null) { 712 mMenuVisibilityListener = new MyMenuVisibilityListener(); 713 } 714 mActionBar.setDisplayOptions(mSetPathString != null, true); 715 mActionBar.addOnMenuVisibilityListener(mMenuVisibilityListener); 716 717 if (mAppBridge != null) { 718 mAppBridge.setServer(this); 719 mPhotoView.resetToFirstPicture(); 720 } 721 } 722 723 @Override 724 protected void onDestroy() { 725 if (mAppBridge != null) { 726 // Unregister the ScreenNail and notify mAppBridge. 727 SnailSource.unregisterScreenNail(mScreenNail); 728 mAppBridge.detachScreenNail(); 729 mAppBridge = null; 730 mScreenNail = null; 731 } 732 mOrientationManager.removeListener(this); 733 super.onDestroy(); 734 } 735 736 private class MyDetailsSource implements DetailsSource { 737 private int mIndex; 738 739 @Override 740 public MediaDetails getDetails() { 741 return mModel.getCurrentMediaItem().getDetails(); 742 } 743 744 @Override 745 public int size() { 746 return mMediaSet != null ? mMediaSet.getMediaItemCount() : 1; 747 } 748 749 @Override 750 public int findIndex(int indexHint) { 751 mIndex = indexHint; 752 return indexHint; 753 } 754 755 @Override 756 public int getIndex() { 757 return mIndex; 758 } 759 } 760} 761