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