| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "ios/chrome/browser/ui/bookmarks/bookmark_home_handset_view_controller.h
" | 5 #import "ios/chrome/browser/ui/bookmarks/bookmark_home_handset_view_controller.h
" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #import "base/ios/weak_nsobject.h" | 9 #import "base/ios/weak_nsobject.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/mac/objc_property_releaser.h" | 11 #include "base/mac/objc_property_releaser.h" |
| 12 #include "base/mac/scoped_nsobject.h" | 12 #include "base/mac/scoped_nsobject.h" |
| 13 #include "base/metrics/user_metrics.h" | 13 #include "base/metrics/user_metrics.h" |
| 14 #include "base/metrics/user_metrics_action.h" | 14 #include "base/metrics/user_metrics_action.h" |
| 15 #include "base/strings/sys_string_conversions.h" | 15 #include "base/strings/sys_string_conversions.h" |
| 16 #include "components/bookmarks/browser/bookmark_model.h" | 16 #include "components/bookmarks/browser/bookmark_model.h" |
| 17 #include "components/strings/grit/components_strings.h" | 17 #include "components/strings/grit/components_strings.h" |
| 18 #include "google_apis/gaia/google_service_auth_error.h" | 18 #include "google_apis/gaia/google_service_auth_error.h" |
| 19 #include "ios/chrome/browser/bookmarks/bookmarks_utils.h" | 19 #include "ios/chrome/browser/bookmarks/bookmarks_utils.h" |
| 20 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" | 20 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" |
| 21 #import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h" | 21 #import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h" |
| 22 #import "ios/chrome/browser/ui/bookmarks/bars/bookmark_editing_bar.h" | 22 #import "ios/chrome/browser/ui/bookmarks/bars/bookmark_editing_bar.h" |
| 23 #import "ios/chrome/browser/ui/bookmarks/bars/bookmark_navigation_bar.h" | 23 #import "ios/chrome/browser/ui/bookmarks/bars/bookmark_navigation_bar.h" |
| 24 #import "ios/chrome/browser/ui/bookmarks/bookmark_all_collection_view.h" |
| 24 #import "ios/chrome/browser/ui/bookmarks/bookmark_collection_cells.h" | 25 #import "ios/chrome/browser/ui/bookmarks/bookmark_collection_cells.h" |
| 25 #import "ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h" | 26 #import "ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h" |
| 26 #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_collection_view.h" | 27 #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_collection_view.h" |
| 27 #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.
h" | 28 #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.
h" |
| 28 #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.h" | 29 #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.h" |
| 29 #import "ios/chrome/browser/ui/bookmarks/bookmark_home_primary_view.h" | 30 #import "ios/chrome/browser/ui/bookmarks/bookmark_home_primary_view.h" |
| 30 #import "ios/chrome/browser/ui/bookmarks/bookmark_home_waiting_view.h" | 31 #import "ios/chrome/browser/ui/bookmarks/bookmark_home_waiting_view.h" |
| 31 #import "ios/chrome/browser/ui/bookmarks/bookmark_menu_item.h" | 32 #import "ios/chrome/browser/ui/bookmarks/bookmark_menu_item.h" |
| 32 #import "ios/chrome/browser/ui/bookmarks/bookmark_menu_view.h" | 33 #import "ios/chrome/browser/ui/bookmarks/bookmark_menu_view.h" |
| 33 #include "ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.h" | 34 #include "ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.h" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 60 // Bridge to register for bookmark changes. | 61 // Bridge to register for bookmark changes. |
| 61 std::unique_ptr<bookmarks::BookmarkModelBridge> _bridge; | 62 std::unique_ptr<bookmarks::BookmarkModelBridge> _bridge; |
| 62 base::mac::ObjCPropertyReleaser | 63 base::mac::ObjCPropertyReleaser |
| 63 _propertyReleaser_BookmarkHomeHandsetViewController; | 64 _propertyReleaser_BookmarkHomeHandsetViewController; |
| 64 } | 65 } |
| 65 | 66 |
| 66 // This views holds the primary content of this view controller. At any point in | 67 // This views holds the primary content of this view controller. At any point in |
| 67 // time, it contains exactly one of the BookmarkCollectionView subclasses. | 68 // time, it contains exactly one of the BookmarkCollectionView subclasses. |
| 68 @property(nonatomic, retain) UIView* contentView; | 69 @property(nonatomic, retain) UIView* contentView; |
| 69 // The possible views that can be shown from the menu. | 70 // The possible views that can be shown from the menu. |
| 71 @property(nonatomic, retain) BookmarkAllCollectionView* allItemsView; |
| 70 @property(nonatomic, retain) BookmarkFolderCollectionView* folderView; | 72 @property(nonatomic, retain) BookmarkFolderCollectionView* folderView; |
| 71 // This view is created and used if the model is not fully loaded yet by the | 73 // This view is created and used if the model is not fully loaded yet by the |
| 72 // time this controller starts. | 74 // time this controller starts. |
| 73 @property(nonatomic, retain) BookmarkHomeWaitingView* waitForModelView; | 75 @property(nonatomic, retain) BookmarkHomeWaitingView* waitForModelView; |
| 74 | 76 |
| 75 // The menu with all the folders and special entries. | 77 // The menu with all the folders and special entries. |
| 76 @property(nonatomic, retain) BookmarkMenuView* menuView; | 78 @property(nonatomic, retain) BookmarkMenuView* menuView; |
| 77 // At any point in time, there is exactly one collection view whose view is part | 79 // At any point in time, there is exactly one collection view whose view is part |
| 78 // of the view hierarchy. This property determine which collection view is | 80 // of the view hierarchy. This property determine which collection view is |
| 79 // visible. Not by accident, this property also reflects the selected menu item | 81 // visible. Not by accident, this property also reflects the selected menu item |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 | 114 |
| 113 #pragma mark View loading and switching | 115 #pragma mark View loading and switching |
| 114 // This method is called if the view needs to be loaded and the model is not | 116 // This method is called if the view needs to be loaded and the model is not |
| 115 // ready yet. | 117 // ready yet. |
| 116 - (void)loadWaitingView; | 118 - (void)loadWaitingView; |
| 117 // This method should be called at most once in the life-cycle of the | 119 // This method should be called at most once in the life-cycle of the |
| 118 // class. It should be called at the soonest possible time after the | 120 // class. It should be called at the soonest possible time after the |
| 119 // view has been loaded, and the bookmark model is loaded. | 121 // view has been loaded, and the bookmark model is loaded. |
| 120 - (void)loadBookmarkViews; | 122 - (void)loadBookmarkViews; |
| 121 // If the view doesn't exist, create it. | 123 // If the view doesn't exist, create it. |
| 124 - (void)ensureAllViewExists; |
| 122 - (void)ensureFolderViewExists; | 125 - (void)ensureFolderViewExists; |
| 123 // Updates the property 'primaryMenuItem'. | 126 // Updates the property 'primaryMenuItem'. |
| 124 // Updates the UI to reflect the new state of 'primaryMenuItem'. | 127 // Updates the UI to reflect the new state of 'primaryMenuItem'. |
| 125 - (void)updatePrimaryMenuItem:(BookmarkMenuItem*)menuItem | 128 - (void)updatePrimaryMenuItem:(BookmarkMenuItem*)menuItem |
| 126 animated:(BOOL)animated; | 129 animated:(BOOL)animated; |
| 127 | 130 |
| 128 #pragma mark Editing related methods | 131 #pragma mark Editing related methods |
| 129 // This method statelessly updates the editing top bar from |_editNodes| and | 132 // This method statelessly updates the editing top bar from |_editNodes| and |
| 130 // |editing|. | 133 // |editing|. |
| 131 - (void)updateEditingStateAnimated:(BOOL)animated; | 134 - (void)updateEditingStateAnimated:(BOOL)animated; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 // Saves the current position and asks the delegate to open the url. | 212 // Saves the current position and asks the delegate to open the url. |
| 210 - (void)delegateDismiss:(const GURL&)url; | 213 - (void)delegateDismiss:(const GURL&)url; |
| 211 | 214 |
| 212 // TODO(crbug.com/450646): This should not be needed but require refactoring of | 215 // TODO(crbug.com/450646): This should not be needed but require refactoring of |
| 213 // the BookmarkCollectionViewDelegate. | 216 // the BookmarkCollectionViewDelegate. |
| 214 - (NSIndexPath*)indexPathForCell:(UICollectionViewCell*)cell; | 217 - (NSIndexPath*)indexPathForCell:(UICollectionViewCell*)cell; |
| 215 | 218 |
| 216 @end | 219 @end |
| 217 | 220 |
| 218 @implementation BookmarkHomeHandsetViewController | 221 @implementation BookmarkHomeHandsetViewController |
| 222 @synthesize allItemsView = _allItemsView; |
| 219 @synthesize contentView = _contentView; | 223 @synthesize contentView = _contentView; |
| 220 @synthesize folderView = _folderView; | 224 @synthesize folderView = _folderView; |
| 221 @synthesize waitForModelView = _waitForModelView; | 225 @synthesize waitForModelView = _waitForModelView; |
| 222 | 226 |
| 223 @synthesize menuView = _menuView; | 227 @synthesize menuView = _menuView; |
| 224 @synthesize primaryMenuItem = _primaryMenuItem; | 228 @synthesize primaryMenuItem = _primaryMenuItem; |
| 225 @synthesize cachedContentPosition = _cachedContentPosition; | 229 @synthesize cachedContentPosition = _cachedContentPosition; |
| 226 @synthesize navigationBar = _navigationBar; | 230 @synthesize navigationBar = _navigationBar; |
| 227 @synthesize editingBar = _editingBar; | 231 @synthesize editingBar = _editingBar; |
| 228 | 232 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 246 // It is important to initialize the promo controller with the browser state | 250 // It is important to initialize the promo controller with the browser state |
| 247 // passed in, as it could be incognito. | 251 // passed in, as it could be incognito. |
| 248 _bookmarkPromoController = | 252 _bookmarkPromoController = |
| 249 [[BookmarkPromoController alloc] initWithBrowserState:browserState | 253 [[BookmarkPromoController alloc] initWithBrowserState:browserState |
| 250 delegate:self]; | 254 delegate:self]; |
| 251 } | 255 } |
| 252 return self; | 256 return self; |
| 253 } | 257 } |
| 254 | 258 |
| 255 - (void)dealloc { | 259 - (void)dealloc { |
| 260 _allItemsView.delegate = nil; |
| 256 _folderView.delegate = nil; | 261 _folderView.delegate = nil; |
| 257 | 262 |
| 258 _menuView.delegate = nil; | 263 _menuView.delegate = nil; |
| 259 | 264 |
| 260 _editViewController.delegate = nil; | 265 _editViewController.delegate = nil; |
| 261 _folderSelector.delegate = nil; | 266 _folderSelector.delegate = nil; |
| 262 | 267 |
| 263 _panelView.delegate = nil; | 268 _panelView.delegate = nil; |
| 264 [super dealloc]; | 269 [super dealloc]; |
| 265 } | 270 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 if (self.view.window) { | 373 if (self.view.window) { |
| 369 [[self primaryView] applyContentPosition:position]; | 374 [[self primaryView] applyContentPosition:position]; |
| 370 } else { | 375 } else { |
| 371 // Otherwise, save the position to be applied once the view has been laid | 376 // Otherwise, save the position to be applied once the view has been laid |
| 372 // out. | 377 // out. |
| 373 self.cachedContentPosition = [NSNumber numberWithFloat:position]; | 378 self.cachedContentPosition = [NSNumber numberWithFloat:position]; |
| 374 } | 379 } |
| 375 } | 380 } |
| 376 } | 381 } |
| 377 | 382 |
| 383 - (void)ensureAllViewExists { |
| 384 if (self.allItemsView) |
| 385 return; |
| 386 |
| 387 base::scoped_nsobject<BookmarkAllCollectionView> view( |
| 388 [[BookmarkAllCollectionView alloc] |
| 389 initWithBrowserState:self.browserState |
| 390 frame:[self frameForPrimaryView]]); |
| 391 self.allItemsView = view; |
| 392 self.allItemsView.delegate = self; |
| 393 [self.allItemsView setEditing:self.editing animated:NO]; |
| 394 self.allItemsView.autoresizingMask = |
| 395 UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; |
| 396 } |
| 397 |
| 378 - (void)ensureFolderViewExists { | 398 - (void)ensureFolderViewExists { |
| 379 if (self.folderView) | 399 if (self.folderView) |
| 380 return; | 400 return; |
| 381 | 401 |
| 382 base::scoped_nsobject<BookmarkFolderCollectionView> view( | 402 base::scoped_nsobject<BookmarkFolderCollectionView> view( |
| 383 [[BookmarkFolderCollectionView alloc] | 403 [[BookmarkFolderCollectionView alloc] |
| 384 initWithBrowserState:self.browserState | 404 initWithBrowserState:self.browserState |
| 385 frame:[self frameForPrimaryView]]); | 405 frame:[self frameForPrimaryView]]); |
| 386 self.folderView = view; | 406 self.folderView = view; |
| 387 self.folderView.delegate = self; | 407 self.folderView.delegate = self; |
| 388 [self.folderView setEditing:self.editing animated:NO]; | 408 [self.folderView setEditing:self.editing animated:NO]; |
| 389 self.folderView.autoresizingMask = | 409 self.folderView.autoresizingMask = |
| 390 UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; | 410 UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; |
| 391 } | 411 } |
| 392 | 412 |
| 393 - (void)updatePrimaryMenuItem:(BookmarkMenuItem*)menuItem | 413 - (void)updatePrimaryMenuItem:(BookmarkMenuItem*)menuItem |
| 394 animated:(BOOL)animated { | 414 animated:(BOOL)animated { |
| 395 if ([self.primaryMenuItem isEqual:menuItem]) | 415 if ([self.primaryMenuItem isEqual:menuItem]) |
| 396 return; | 416 return; |
| 397 | 417 |
| 398 // Disable editing on previous primary view before dismissing it. No need to | 418 // Disable editing on previous primary view before dismissing it. No need to |
| 399 // animate because this view is immediately removed from hierarchy. | 419 // animate because this view is immediately removed from hierarchy. |
| 400 [self.primaryView setEditing:NO animated:NO]; | 420 [self.primaryView setEditing:NO animated:NO]; |
| 401 | 421 |
| 402 [[self primaryView] removeFromSuperview]; | 422 [[self primaryView] removeFromSuperview]; |
| 403 self.primaryMenuItem = menuItem; | 423 self.primaryMenuItem = menuItem; |
| 404 | 424 |
| 405 switch (self.primaryMenuItem.type) { | 425 switch (self.primaryMenuItem.type) { |
| 426 case bookmarks::MenuItemAll: |
| 427 [self ensureAllViewExists]; |
| 428 break; |
| 406 case bookmarks::MenuItemFolder: | 429 case bookmarks::MenuItemFolder: |
| 407 [self ensureFolderViewExists]; | 430 [self ensureFolderViewExists]; |
| 408 [self.folderView resetFolder:self.primaryMenuItem.folder]; | 431 [self.folderView resetFolder:self.primaryMenuItem.folder]; |
| 409 [self.folderView promoStateChangedAnimated:NO]; | 432 [self.folderView promoStateChangedAnimated:NO]; |
| 410 break; | 433 break; |
| 411 case bookmarks::MenuItemDivider: | 434 case bookmarks::MenuItemDivider: |
| 412 case bookmarks::MenuItemSectionHeader: | 435 case bookmarks::MenuItemSectionHeader: |
| 413 NOTREACHED(); | 436 NOTREACHED(); |
| 414 break; | 437 break; |
| 415 } | 438 } |
| 416 | 439 |
| 417 UIView* primaryView = [self primaryView]; | 440 UIView* primaryView = [self primaryView]; |
| 418 [[self primaryView] changeOrientation:GetInterfaceOrientation()]; | 441 [[self primaryView] changeOrientation:GetInterfaceOrientation()]; |
| 419 [[self primaryView] setScrollsToTop:!self.scrollingMenuToTop]; | 442 [[self primaryView] setScrollsToTop:!self.scrollingMenuToTop]; |
| 420 | 443 |
| 421 [self.contentView insertSubview:primaryView atIndex:0]; | 444 [self.contentView insertSubview:primaryView atIndex:0]; |
| 422 primaryView.frame = self.contentView.bounds; | 445 primaryView.frame = self.contentView.bounds; |
| 423 | 446 |
| 424 [self updateNavigationBarAnimated:animated | 447 [self updateNavigationBarAnimated:animated |
| 425 orientation:GetInterfaceOrientation()]; | 448 orientation:GetInterfaceOrientation()]; |
| 426 | 449 |
| 427 [self.menuView updatePrimaryMenuItem:self.primaryMenuItem]; | 450 [self.menuView updatePrimaryMenuItem:self.primaryMenuItem]; |
| 428 } | 451 } |
| 429 | 452 |
| 430 - (UIView<BookmarkHomePrimaryView>*)primaryView { | 453 - (UIView<BookmarkHomePrimaryView>*)primaryView { |
| 431 switch (self.primaryMenuItem.type) { | 454 switch (self.primaryMenuItem.type) { |
| 455 case bookmarks::MenuItemAll: |
| 456 return self.allItemsView; |
| 432 case bookmarks::MenuItemFolder: | 457 case bookmarks::MenuItemFolder: |
| 433 return self.folderView; | 458 return self.folderView; |
| 434 case bookmarks::MenuItemDivider: | 459 case bookmarks::MenuItemDivider: |
| 435 case bookmarks::MenuItemSectionHeader: | 460 case bookmarks::MenuItemSectionHeader: |
| 436 NOTREACHED(); | 461 NOTREACHED(); |
| 437 return nil; | 462 return nil; |
| 438 } | 463 } |
| 439 } | 464 } |
| 440 | 465 |
| 441 #pragma mark - Editing bar methods. | 466 #pragma mark - Editing bar methods. |
| (...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1125 [[self primaryView] contentPositionInPortraitOrientation], | 1150 [[self primaryView] contentPositionInPortraitOrientation], |
| 1126 [self primaryMenuItem]); | 1151 [self primaryMenuItem]); |
| 1127 } | 1152 } |
| 1128 [self.delegate bookmarkHomeViewControllerWantsDismissal:self | 1153 [self.delegate bookmarkHomeViewControllerWantsDismissal:self |
| 1129 navigationToUrl:url]; | 1154 navigationToUrl:url]; |
| 1130 } | 1155 } |
| 1131 | 1156 |
| 1132 #pragma mark - BookmarkPromoControllerDelegate | 1157 #pragma mark - BookmarkPromoControllerDelegate |
| 1133 | 1158 |
| 1134 - (void)promoStateChanged:(BOOL)promoEnabled { | 1159 - (void)promoStateChanged:(BOOL)promoEnabled { |
| 1160 [self.allItemsView.collectionView reloadData]; |
| 1161 // This is required to workaround a crash seen once on iOS 7.1 when |
| 1162 // the collection gets two reloadData without getting a call to layout |
| 1163 // subviews, the collection view will reuse some cached data for the perfoming |
| 1164 // the layout which are invalid after the second call to reloadData. |
| 1165 // Forcing the layout invalidation after each reloadData seems to fix the |
| 1166 // issue. |
| 1167 [self.allItemsView.collectionView.collectionViewLayout invalidateLayout]; |
| 1168 |
| 1135 [self.folderView | 1169 [self.folderView |
| 1136 promoStateChangedAnimated:self.folderView == [self primaryView]]; | 1170 promoStateChangedAnimated:self.folderView == [self primaryView]]; |
| 1137 } | 1171 } |
| 1138 | 1172 |
| 1139 - (NSIndexPath*)indexPathForCell:(UICollectionViewCell*)cell { | 1173 - (NSIndexPath*)indexPathForCell:(UICollectionViewCell*)cell { |
| 1140 DCHECK([self primaryView].collectionView); | 1174 DCHECK([self primaryView].collectionView); |
| 1141 NSIndexPath* indexPath = | 1175 NSIndexPath* indexPath = |
| 1142 [[self primaryView].collectionView indexPathForCell:cell]; | 1176 [[self primaryView].collectionView indexPathForCell:cell]; |
| 1143 return indexPath; | 1177 return indexPath; |
| 1144 } | 1178 } |
| 1145 | 1179 |
| 1146 @end | 1180 @end |
| OLD | NEW |